User scripts don't work when scripts are disabled.
authorDaniel Carl <danielcarl@gmx.de>
Tue, 11 Apr 2017 22:32:29 +0000 (00:32 +0200)
committerDaniel Carl <danielcarl@gmx.de>
Tue, 11 Apr 2017 22:32:29 +0000 (00:32 +0200)
In case the scripts are injected from the ui, they are not processed in
case JavaScript is disabled in vimb. So use the previous dbus logic to
observe dom focus changes and use the script messaging system to inform
the ui process.

src/main.c
src/scripts/vimb_util.js [deleted file]
src/webextension/ext-main.c

index 8ae8f52..0486d6f 100644 (file)
@@ -1556,13 +1556,6 @@ static WebKitWebView *webview_new(Client *c, WebKitWebView *webview)
         webkit_user_script_unref(script);
     }
 
-    /* Inject the global utility script. */
-    script = webkit_user_script_new(VIMB_UTIL,
-            WEBKIT_USER_CONTENT_INJECT_ALL_FRAMES,
-            WEBKIT_USER_SCRIPT_INJECT_AT_DOCUMENT_END, NULL, NULL);
-    webkit_user_content_manager_add_script(ucm, script);
-    webkit_user_script_unref(script);
-
     /* Setup script message handlers. */
     webkit_user_content_manager_register_script_message_handler(ucm, "focus");
     g_signal_connect(ucm, "script-message-received::focus", G_CALLBACK(on_script_message_focus), c);
diff --git a/src/scripts/vimb_util.js b/src/scripts/vimb_util.js
deleted file mode 100644 (file)
index df747fa..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Utility object injected into all frames. */
-var vimb = Object.freeze((function(){
-    'use strict';
-    /* Checks if given element is editable */
-    function isEditable(e) {
-        if (e) {
-            var name = e.tagName.toLowerCase();
-            return e.isContentEditable
-                || name == "textarea"
-                || (name == "input" && /^(?:color|date|datetime|datetime-local|email|month|number|password|search|tel|text|time|url|week)$/i.test(e.type));
-        }
-        return false;
-    }
-
-    return {
-        init: function() {
-            var b = document.body;
-            b.addEventListener(
-                "focus",
-                function(ev) {
-                    var e = ev.target, n;
-                    if (isEditable(e)) {
-                        window.webkit.messageHandlers.focus.postMessage(1);
-                    }
-                },
-                true
-            );
-            b.addEventListener(
-                "blur",
-                function() {
-                    window.webkit.messageHandlers.focus.postMessage(0);
-                },
-                true
-            );
-        }
-    };
-})());
-vimb.init();
index 97e4261..3abf4bf 100644 (file)
@@ -43,6 +43,8 @@ static void dbus_emit_signal(const char *name, WebKitWebExtension* extension,
 static void dbus_handle_method_call(GDBusConnection *conn, const char *sender,
         const char *object_path, const char *interface_name, const char *method,
         GVariant *parameters, GDBusMethodInvocation *invocation, gpointer data);
+static void on_editable_change_focus(WebKitDOMEventTarget *target,
+        WebKitDOMEvent *event, WebKitWebExtension *extension);
 static void on_page_created(WebKitWebExtension *ext, WebKitWebPage *webpage, gpointer data);
 static void on_web_page_document_loaded(WebKitWebPage *webpage, gpointer extension);
 static gboolean on_web_page_send_request(WebKitWebPage *webpage, WebKitURIRequest *request,
@@ -177,7 +179,6 @@ static void on_dbus_connection_created(GObject *source_object,
 static void add_onload_event_observers(WebKitDOMDocument *doc,
         WebKitWebExtension *extension)
 {
-#if 0 /* might soon be use for some events */
     WebKitDOMEventTarget *target;
 
     /* Add the document to the table of known documents or if already exists
@@ -190,7 +191,15 @@ static void add_onload_event_observers(WebKitDOMDocument *doc,
      * function is called with content document of an iframe. Else the event
      * observing does not work. */
     target = WEBKIT_DOM_EVENT_TARGET(webkit_dom_document_get_default_view(doc));
-#endif
+
+    webkit_dom_event_target_add_event_listener(target, "focus",
+            G_CALLBACK(on_editable_change_focus), TRUE, extension);
+    webkit_dom_event_target_add_event_listener(target, "blur",
+            G_CALLBACK(on_editable_change_focus), TRUE, extension);
+    /* Check for focused editable elements also if they where focused before
+     * the event observer where set up. */
+    /* TODO this is not needed for strict-focus=on */
+    on_editable_change_focus(target, NULL, extension);
 }
 
 /**
@@ -296,6 +305,63 @@ static void dbus_handle_method_call(GDBusConnection *conn, const char *sender,
     }
 }
 
+/**
+ * Callback called if a editable element changes it focus state.
+ * Event target may be a WebKitDOMDocument (in case of iframe) or a
+ * WebKitDOMDOMWindow.
+ */
+static void on_editable_change_focus(WebKitDOMEventTarget *target,
+        WebKitDOMEvent *event, WebKitWebExtension *extension)
+{
+    gboolean input_focus;
+    WebKitDOMDocument *doc;
+    WebKitDOMDOMWindow *dom_window;
+    WebKitDOMElement *active;
+
+    if (WEBKIT_DOM_IS_DOM_WINDOW(target)) {
+        g_object_get(target, "document", &doc, NULL);
+    } else {
+        /* target is a doc document */
+        doc = WEBKIT_DOM_DOCUMENT(target);
+    }
+
+    dom_window = webkit_dom_document_get_default_view(doc);
+    if (!dom_window) {
+        return;
+    }
+
+    active = webkit_dom_document_get_active_element(doc);
+    /* Don't do anything if there is no active element or the active element
+     * is the same as before. */
+    if (!active || active == ext.active) {
+        return;
+    }
+    if (WEBKIT_DOM_IS_HTML_IFRAME_ELEMENT(active)) {
+        WebKitDOMHTMLIFrameElement *iframe;
+        WebKitDOMDocument *subdoc;
+
+        iframe = WEBKIT_DOM_HTML_IFRAME_ELEMENT(active);
+        subdoc = webkit_dom_html_iframe_element_get_content_document(iframe);
+        add_onload_event_observers(subdoc, extension);
+        return;
+    }
+
+    ext.active = active;
+
+    /* Check if the active element is an editable element. */
+    input_focus = ext_dom_is_editable(active);
+    if (input_focus != ext.input_focus) {
+        ext.input_focus = input_focus;
+
+        webkit_dom_document_get_default_view(doc);
+        if (!webkit_dom_dom_window_webkit_message_handlers_post_message(dom_window, "focus", input_focus ? "1" : "0")) {
+            g_warning("Error sending focus message");
+            return;
+        }
+    }
+    g_object_unref(dom_window);
+}
+
 /**
  * Callback for web extensions page-created signal.
  */