Title: [125972] trunk/Source/WebKit2
Revision
125972
Author
carlo...@webkit.org
Date
2012-08-19 02:24:01 -0700 (Sun, 19 Aug 2012)

Log Message

[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().

Modified Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (125971 => 125972)


--- trunk/Source/WebKit2/ChangeLog	2012-08-19 00:57:38 UTC (rev 125971)
+++ trunk/Source/WebKit2/ChangeLog	2012-08-19 09:24:01 UTC (rev 125972)
@@ -1,3 +1,42 @@
+2012-08-18  Carlos Garcia Campos  <cgar...@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.pozdnya...@intel.com>
 
         [EFL][WK2] ewk_back_forward_list_item properties should be in sync with WebProcessProxy::m_backForwardListItemMap

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.cpp (125971 => 125972)


--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.cpp	2012-08-19 00:57:38 UTC (rev 125971)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.cpp	2012-08-19 09:24:01 UTC (rev 125972)
@@ -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>
@@ -518,6 +519,31 @@
 #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);

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.h (125971 => 125972)


--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.h	2012-08-19 00:57:38 UTC (rev 125971)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.h	2012-08-19 09:24:01 UTC (rev 125972)
@@ -146,6 +146,10 @@
 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

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt (125971 => 125972)


--- trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt	2012-08-19 00:57:38 UTC (rev 125971)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt	2012-08-19 09:24:01 UTC (rev 125972)
@@ -37,6 +37,7 @@
 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

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebContext.cpp (125971 => 125972)


--- trunk/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebContext.cpp	2012-08-19 00:57:38 UTC (rev 125971)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebContext.cpp	2012-08-19 09:24:01 UTC (rev 125972)
@@ -20,6 +20,7 @@
 #include "config.h"
 
 #include "LoadTrackingTest.h"
+#include "WebKitTestServer.h"
 #include <gtk/gtk.h>
 #include <webkit2/webkit2.h>
 #include <wtf/HashMap.h>
@@ -27,6 +28,8 @@
 #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.
@@ -165,35 +168,6 @@
         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 = "" 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;
 };
@@ -266,14 +240,57 @@
     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;
 }

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.cpp (125971 => 125972)


--- trunk/Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.cpp	2012-08-19 00:57:38 UTC (rev 125971)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.cpp	2012-08-19 09:24:01 UTC (rev 125972)
@@ -29,6 +29,7 @@
     , m_mainLoop(g_main_loop_new(0, TRUE))
     , m_parentWindow(0)
     , m_javascriptResult(0)
+    , m_resourceDataSize(0)
 {
     assertObjectIsDeletedWhenTestFinishes(G_OBJECT(m_webView));
 }
@@ -197,6 +198,33 @@
     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 = "" 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);

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.h (125971 => 125972)


--- trunk/Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.h	2012-08-19 00:57:38 UTC (rev 125971)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.h	2012-08-19 09:24:01 UTC (rev 125972)
@@ -48,6 +48,7 @@
     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);
@@ -69,6 +70,8 @@
     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);

Modified: trunk/Source/WebKit2/WebProcess/WebProcess.cpp (125971 => 125972)


--- trunk/Source/WebKit2/WebProcess/WebProcess.cpp	2012-08-19 00:57:38 UTC (rev 125971)
+++ trunk/Source/WebKit2/WebProcess/WebProcess.cpp	2012-08-19 09:24:01 UTC (rev 125972)
@@ -315,6 +315,7 @@
 void WebProcess::userPreferredLanguagesChanged(const Vector<String>& languages) const
 {
     overrideUserPreferredLanguages(languages);
+    languageDidChange();
 }
 
 void WebProcess::fullKeyboardAccessModeChanged(bool fullKeyboardAccessEnabled)

Modified: trunk/Source/WebKit2/WebProcess/gtk/WebProcessGtk.cpp (125971 => 125972)


--- trunk/Source/WebKit2/WebProcess/gtk/WebProcessGtk.cpp	2012-08-19 00:57:38 UTC (rev 125971)
+++ trunk/Source/WebKit2/WebProcess/gtk/WebProcessGtk.cpp	2012-08-19 09:24:01 UTC (rev 125972)
@@ -31,6 +31,7 @@
 
 #include "WebProcessCreationParameters.h"
 #include <WebCore/FileSystem.h>
+#include <WebCore/Language.h>
 #include <WebCore/MemoryCache.h>
 #include <WebCore/NotImplemented.h>
 #include <WebCore/PageCache.h>
@@ -38,6 +39,8 @@
 #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>
@@ -113,17 +116,72 @@
     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()
 {
     SoupSession* session = WebCore::ResourceHandle::defaultSession();
     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
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to