Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[GTK] Add API to set preferred languages to WebKit2 GTK+
https://bugs.webkit.org/show_bug.cgi?id=90878

Reviewed by Martin Robinson.

* UIProcess/API/gtk/WebKitWebContext.cpp:
(webkit_web_context_set_preferred_languages): Public API to set a
list of preferred languages sorted from most desirable to least
desirable.
* UIProcess/API/gtk/WebKitWebContext.h:
* UIProcess/API/gtk/docs/webkit2gtk-sections.txt: Add new symbol.
* UIProcess/API/gtk/tests/TestWebKitWebContext.cpp:
(testWebContextLanguages):
(serverCallback):
(beforeAll):
(afterAll):
* UIProcess/API/gtk/tests/WebViewTest.cpp:
(resourceGetDataCallback):
(WebViewTest::mainResourceData): Moved from TestWebKitWebContext
to make it available to all WebViewTests.
* UIProcess/API/gtk/tests/WebViewTest.h:
* WebProcess/WebProcess.cpp:
(WebKit::WebProcess::userPreferredLanguagesChanged): Notify our
observer that the languages have been overriden.
* WebProcess/gtk/WebProcessGtk.cpp:
(WebKit::buildAcceptLanguages): Helper function to build the
accept languages as specified in RFC 2616.
(WebKit::setSoupSessionAcceptLanguage): Set the accept-language
property of the default SoupSession.
(WebKit::languageChanged): Update the preferred languages in
SoupSession.
(WebKit::WebProcess::platformInitializeWebProcess): Add an
observer to be notified when the list of preferred languages is
updated.
(WebKit::WebProcess::platformTerminate): Remove the observer added
in platformInitializeWebProcess().

Canonical link: https://commits.webkit.org/112221@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@125972 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
carlosgcampos committed Aug 19, 2012
1 parent bfac2bd commit 579dc8f
Show file tree
Hide file tree
Showing 9 changed files with 208 additions and 31 deletions.
39 changes: 39 additions & 0 deletions Source/WebKit2/ChangeLog
@@ -1,3 +1,42 @@
2012-08-18 Carlos Garcia Campos <cgarcia@igalia.com>

[GTK] Add API to set preferred languages to WebKit2 GTK+
https://bugs.webkit.org/show_bug.cgi?id=90878

Reviewed by Martin Robinson.

* UIProcess/API/gtk/WebKitWebContext.cpp:
(webkit_web_context_set_preferred_languages): Public API to set a
list of preferred languages sorted from most desirable to least
desirable.
* UIProcess/API/gtk/WebKitWebContext.h:
* UIProcess/API/gtk/docs/webkit2gtk-sections.txt: Add new symbol.
* UIProcess/API/gtk/tests/TestWebKitWebContext.cpp:
(testWebContextLanguages):
(serverCallback):
(beforeAll):
(afterAll):
* UIProcess/API/gtk/tests/WebViewTest.cpp:
(resourceGetDataCallback):
(WebViewTest::mainResourceData): Moved from TestWebKitWebContext
to make it available to all WebViewTests.
* UIProcess/API/gtk/tests/WebViewTest.h:
* WebProcess/WebProcess.cpp:
(WebKit::WebProcess::userPreferredLanguagesChanged): Notify our
observer that the languages have been overriden.
* WebProcess/gtk/WebProcessGtk.cpp:
(WebKit::buildAcceptLanguages): Helper function to build the
accept languages as specified in RFC 2616.
(WebKit::setSoupSessionAcceptLanguage): Set the accept-language
property of the default SoupSession.
(WebKit::languageChanged): Update the preferred languages in
SoupSession.
(WebKit::WebProcess::platformInitializeWebProcess): Add an
observer to be notified when the list of preferred languages is
updated.
(WebKit::WebProcess::platformTerminate): Remove the observer added
in platformInitializeWebProcess().

2012-08-18 Mikhail Pozdnyakov <mikhail.pozdnyakov@intel.com>

[EFL][WK2] ewk_back_forward_list_item properties should be in sync with WebProcessProxy::m_backForwardListItemMap
Expand Down
26 changes: 26 additions & 0 deletions Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.cpp
Expand Up @@ -32,6 +32,7 @@
#include "WebKitURISchemeRequestPrivate.h"
#include "WebKitWebContextPrivate.h"
#include <WebCore/FileSystem.h>
#include <WebCore/Language.h>
#include <wtf/HashMap.h>
#include <wtf/OwnPtr.h>
#include <wtf/gobject/GOwnPtr.h>
Expand Down Expand Up @@ -518,6 +519,31 @@ void webkit_web_context_set_spell_checking_languages(WebKitWebContext* context,
#endif
}

/**
* webkit_web_context_set_preferred_languages:
* @context: a #WebKitWebContext
* @languages: (element-type utf8): a #GList of language identifiers
*
* Set the list of preferred languages, sorted from most desirable
* to least desirable. The list will be used to build the "Accept-Language"
* header that will be included in the network requests started by
* the #WebKitWebContext.
*/
void webkit_web_context_set_preferred_languages(WebKitWebContext* context, GList* languageList)
{
g_return_if_fail(WEBKIT_IS_WEB_CONTEXT(context));

if (!languageList)
return;

Vector<String> languages;
for (GList* iter = languageList; iter; iter = g_list_next(iter))
languages.append(String::fromUTF8(static_cast<char*>(iter->data)).lower().replace("_", "-"));

WebCore::overrideUserPreferredLanguages(languages);
WebCore::languageDidChange();
}

WebKitDownload* webkitWebContextGetOrCreateDownload(WKDownloadRef wkDownload)
{
GRefPtr<WebKitDownload> download = downloadsMap().get(wkDownload);
Expand Down
4 changes: 4 additions & 0 deletions Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.h
Expand Up @@ -146,6 +146,10 @@ WEBKIT_API void
webkit_web_context_set_spell_checking_languages (WebKitWebContext *context,
const gchar *languages);

WEBKIT_API void
webkit_web_context_set_preferred_languages (WebKitWebContext *context,
GList *languages);

G_END_DECLS

#endif
Expand Up @@ -37,6 +37,7 @@ webkit_web_context_get_spell_checking_enabled
webkit_web_context_set_spell_checking_enabled
webkit_web_context_get_spell_checking_languages
webkit_web_context_set_spell_checking_languages
webkit_web_context_set_preferred_languages

<SUBSECTION URI Scheme>
WebKitURISchemeRequestCallback
Expand Down
75 changes: 46 additions & 29 deletions Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebContext.cpp
Expand Up @@ -20,13 +20,16 @@
#include "config.h"

#include "LoadTrackingTest.h"
#include "WebKitTestServer.h"
#include <gtk/gtk.h>
#include <webkit2/webkit2.h>
#include <wtf/HashMap.h>
#include <wtf/gobject/GOwnPtr.h>
#include <wtf/gobject/GRefPtr.h>
#include <wtf/text/StringHash.h>

static WebKitTestServer* kServer;

static void testWebContextDefault(Test* test, gconstpointer)
{
// Check there's a single instance of the default web context.
Expand Down Expand Up @@ -165,35 +168,6 @@ class URISchemeTest: public LoadTrackingTest {
webkit_web_context_register_uri_scheme(webkit_web_context_get_default(), scheme, uriSchemeRequestCallback, this);
}

static void resourceGetDataCallback(GObject* object, GAsyncResult* result, gpointer userData)
{
size_t dataSize;
GOwnPtr<GError> error;
unsigned char* data = webkit_web_resource_get_data_finish(WEBKIT_WEB_RESOURCE(object), result, &dataSize, &error.outPtr());
g_assert(data);

URISchemeTest* test = static_cast<URISchemeTest*>(userData);
test->m_resourceData.set(reinterpret_cast<char*>(data));
test->m_resourceDataSize = dataSize;
g_main_loop_quit(test->m_mainLoop);
}

const char* mainResourceData(size_t& mainResourceDataSize)
{
m_resourceDataSize = 0;
m_resourceData.clear();
WebKitWebResource* resource = webkit_web_view_get_main_resource(m_webView);
g_assert(resource);

webkit_web_resource_get_data(resource, 0, resourceGetDataCallback, this);
g_main_loop_run(m_mainLoop);

mainResourceDataSize = m_resourceDataSize;
return m_resourceData.get();
}

GOwnPtr<char> m_resourceData;
size_t m_resourceDataSize;
GRefPtr<WebKitURISchemeRequest> m_uriSchemeRequest;
HashMap<String, URISchemeHandler> m_handlersMap;
};
Expand Down Expand Up @@ -266,14 +240,57 @@ static void testWebContextSpellChecker(Test* test, gconstpointer)
g_assert(webkit_web_context_get_spell_checking_enabled(webContext));
}

static void testWebContextLanguages(WebViewTest* test, gconstpointer)
{
static const char* expectedDefaultLanguage = "en";
test->loadURI(kServer->getURIForPath("/").data());
test->waitUntilLoadFinished();
size_t mainResourceDataSize = 0;
const char* mainResourceData = test->mainResourceData(mainResourceDataSize);
g_assert_cmpuint(mainResourceDataSize, ==, strlen(expectedDefaultLanguage));
g_assert(!strncmp(mainResourceData, expectedDefaultLanguage, mainResourceDataSize));

GList* languages = g_list_prepend(0, const_cast<gpointer>(static_cast<const void*>("dE")));
languages = g_list_prepend(languages, const_cast<gpointer>(static_cast<const void*>("ES_es")));
languages = g_list_prepend(languages, const_cast<gpointer>(static_cast<const void*>("en")));
webkit_web_context_set_preferred_languages(webkit_web_context_get_default(), languages);
g_list_free(languages);

static const char* expectedLanguages = "en, es-es;q=0.90, de;q=0.80";
test->loadURI(kServer->getURIForPath("/").data());
test->waitUntilLoadFinished();
mainResourceDataSize = 0;
mainResourceData = test->mainResourceData(mainResourceDataSize);
g_assert_cmpuint(mainResourceDataSize, ==, strlen(expectedLanguages));
g_assert(!strncmp(mainResourceData, expectedLanguages, mainResourceDataSize));
}

static void serverCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer)
{
if (message->method != SOUP_METHOD_GET) {
soup_message_set_status(message, SOUP_STATUS_NOT_IMPLEMENTED);
return;
}

soup_message_set_status(message, SOUP_STATUS_OK);
const char* acceptLanguage = soup_message_headers_get_one(message->request_headers, "Accept-Language");
soup_message_body_append(message->response_body, SOUP_MEMORY_COPY, acceptLanguage, strlen(acceptLanguage));
soup_message_body_complete(message->response_body);
}

void beforeAll()
{
kServer = new WebKitTestServer();
kServer->run(serverCallback);

Test::add("WebKitWebContext", "default-context", testWebContextDefault);
PluginsTest::add("WebKitWebContext", "get-plugins", testWebContextGetPlugins);
URISchemeTest::add("WebKitWebContext", "uri-scheme", testWebContextURIScheme);
Test::add("WebKitWebContext", "spell-checker", testWebContextSpellChecker);
WebViewTest::add("WebKitWebContext", "languages", testWebContextLanguages);
}

void afterAll()
{
delete kServer;
}
28 changes: 28 additions & 0 deletions Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.cpp
Expand Up @@ -29,6 +29,7 @@ WebViewTest::WebViewTest()
, m_mainLoop(g_main_loop_new(0, TRUE))
, m_parentWindow(0)
, m_javascriptResult(0)
, m_resourceDataSize(0)
{
assertObjectIsDeletedWhenTestFinishes(G_OBJECT(m_webView));
}
Expand Down Expand Up @@ -197,6 +198,33 @@ void WebViewTest::resizeView(int width, int height)
gtk_widget_size_allocate(GTK_WIDGET(m_webView), &allocation);
}

static void resourceGetDataCallback(GObject* object, GAsyncResult* result, gpointer userData)
{
size_t dataSize;
GOwnPtr<GError> error;
unsigned char* data = webkit_web_resource_get_data_finish(WEBKIT_WEB_RESOURCE(object), result, &dataSize, &error.outPtr());
g_assert(data);

WebViewTest* test = static_cast<WebViewTest*>(userData);
test->m_resourceData.set(reinterpret_cast<char*>(data));
test->m_resourceDataSize = dataSize;
g_main_loop_quit(test->m_mainLoop);
}

const char* WebViewTest::mainResourceData(size_t& mainResourceDataSize)
{
m_resourceDataSize = 0;
m_resourceData.clear();
WebKitWebResource* resource = webkit_web_view_get_main_resource(m_webView);
g_assert(resource);

webkit_web_resource_get_data(resource, 0, resourceGetDataCallback, this);
g_main_loop_run(m_mainLoop);

mainResourceDataSize = m_resourceDataSize;
return m_resourceData.get();
}

void WebViewTest::mouseMoveTo(int x, int y, unsigned int mouseModifiers)
{
g_assert(m_parentWindow);
Expand Down
3 changes: 3 additions & 0 deletions Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.h
Expand Up @@ -48,6 +48,7 @@ class WebViewTest: public Test {
void waitUntilTitleChanged();
void showInWindowAndWaitUntilMapped(GtkWindowType = GTK_WINDOW_POPUP);
void resizeView(int width, int height);
const char* mainResourceData(size_t& mainResourceDataSize);

void mouseMoveTo(int x, int y, unsigned int mouseModifiers = 0);
void clickMouseButton(int x, int y, unsigned int button = 1, unsigned int mouseModifiers = 0);
Expand All @@ -69,6 +70,8 @@ class WebViewTest: public Test {
CString m_expectedTitle;
WebKitJavascriptResult* m_javascriptResult;
GError** m_javascriptError;
GOwnPtr<char> m_resourceData;
size_t m_resourceDataSize;

private:
void doMouseButtonEvent(GdkEventType, int, int, unsigned int, unsigned int);
Expand Down
1 change: 1 addition & 0 deletions Source/WebKit2/WebProcess/WebProcess.cpp
Expand Up @@ -315,6 +315,7 @@ void WebProcess::setShouldUseFontSmoothing(bool useFontSmoothing)
void WebProcess::userPreferredLanguagesChanged(const Vector<String>& languages) const
{
overrideUserPreferredLanguages(languages);
languageDidChange();
}

void WebProcess::fullKeyboardAccessModeChanged(bool fullKeyboardAccessEnabled)
Expand Down
62 changes: 60 additions & 2 deletions Source/WebKit2/WebProcess/gtk/WebProcessGtk.cpp
Expand Up @@ -31,13 +31,16 @@

#include "WebProcessCreationParameters.h"
#include <WebCore/FileSystem.h>
#include <WebCore/Language.h>
#include <WebCore/MemoryCache.h>
#include <WebCore/NotImplemented.h>
#include <WebCore/PageCache.h>
#include <WebCore/ResourceHandle.h>
#include <libsoup/soup-cache.h>
#include <wtf/gobject/GOwnPtr.h>
#include <wtf/gobject/GRefPtr.h>
#include <wtf/text/CString.h>
#include <wtf/text/StringBuilder.h>

#if !OS(WINDOWS)
#include <unistd.h>
Expand Down Expand Up @@ -113,9 +116,62 @@ void WebProcess::platformClearResourceCaches(ResourceCachesToClear cachesToClear
soup_cache_clear(SOUP_CACHE(soup_session_get_feature(session, SOUP_TYPE_CACHE)));
}

void WebProcess::platformInitializeWebProcess(const WebProcessCreationParameters&, CoreIPC::ArgumentDecoder*)
// This function is based on Epiphany code in ephy-embed-prefs.c.
static CString buildAcceptLanguages(Vector<String> languages)
{
notImplemented();
// Ignore "C" locale.
size_t position = languages.find("c");
if (position != notFound)
languages.remove(position);

// Fallback to "en" if the list is empty.
if (languages.isEmpty())
return "en";

// Calculate deltas for the quality values.
int delta;
if (languages.size() < 10)
delta = 10;
else if (languages.size() < 20)
delta = 5;
else
delta = 1;

// Set quality values for each language.
StringBuilder builder;
for (size_t i = 0; i < languages.size(); ++i) {
if (i)
builder.append(", ");

builder.append(languages[i]);

int quality = 100 - i * delta;
if (quality > 0 && quality < 100) {
char buffer[8];
g_ascii_formatd(buffer, 8, "%.2f", quality / 100.0);
builder.append(String::format(";q=%s", buffer));
}
}

return builder.toString().utf8();
}

static void setSoupSessionAcceptLanguage(Vector<String> languages)
{
g_object_set(WebCore::ResourceHandle::defaultSession(), "accept-language", buildAcceptLanguages(languages).data(), NULL);
}

static void languageChanged(void*)
{
setSoupSessionAcceptLanguage(WebCore::userPreferredLanguages());
}

void WebProcess::platformInitializeWebProcess(const WebProcessCreationParameters& parameters, CoreIPC::ArgumentDecoder*)
{
if (!parameters.languages.isEmpty())
setSoupSessionAcceptLanguage(parameters.languages);

WebCore::addLanguageChangeObserver(this, languageChanged);
}

void WebProcess::platformTerminate()
Expand All @@ -124,6 +180,8 @@ void WebProcess::platformTerminate()
SoupCache* cache = SOUP_CACHE(soup_session_get_feature(session, SOUP_TYPE_CACHE));
soup_cache_flush(cache);
soup_cache_dump(cache);

WebCore::removeLanguageChangeObserver(this);
}

} // namespace WebKit

0 comments on commit 579dc8f

Please sign in to comment.