]> git.donarmstrong.com Git - dactyl.git/blobdiff - common/content/events.js
Imported Upstream version 1.1+hg7904
[dactyl.git] / common / content / events.js
index 8006c4cdb422a0aa203159400d69d58ed011c922..844a5b51216f471621adb15da5caa5b0b6e6167a 100644 (file)
@@ -1,6 +1,6 @@
 // Copyright (c) 2006-2008 by Martin Stubenschrott <stubenschrott@vimperator.org>
 // Copyright (c) 2007-2011 by Doug Kearns <dougkearns@gmail.com>
-// Copyright (c) 2008-2013 Kris Maglione <maglione.k at Gmail>
+// Copyright (c) 2008-2014 Kris Maglione <maglione.k at Gmail>
 //
 // This work is licensed for reuse under an MIT license. Details are
 // given in the LICENSE.txt file included with this file.
@@ -28,7 +28,7 @@ var EventHive = Class("EventHive", Contexts.Hive, {
         else
             [self, events] = [event, event[callback || "events"]];
 
-        if (Set.has(events, "input") && !Set.has(events, "dactyl-input"))
+        if (hasOwnProperty(events, "input") && !hasOwnProperty(events, "dactyl-input"))
             events["dactyl-input"] = events.input;
 
         return [self, events];
@@ -79,7 +79,7 @@ var EventHive = Class("EventHive", Contexts.Hive, {
             let elem = args[0].get();
             if (target == null || elem == target
                                && self == args[1].get()
-                               && Set.has(events, args[2])
+                               && hasOwnProperty(events, args[2])
                                && args[3].wrapped == events[args[2]]
                                && args[4] == capture) {
 
@@ -90,7 +90,7 @@ var EventHive = Class("EventHive", Contexts.Hive, {
         });
     },
 
-    get wrapListener() events.closure.wrapListener
+    get wrapListener() events.bound.wrapListener
 });
 
 /**
@@ -107,9 +107,9 @@ var Events = Module("events", {
                 ["window", { id: document.documentElement.id, xmlns: "xul" },
                     // http://developer.mozilla.org/en/docs/XUL_Tutorial:Updating_Commands
                     ["commandset", { id: "dactyl-onfocus", commandupdater: "true", events: "focus",
-                                     commandupdate: this.closure.onFocusChange }],
+                                     commandupdate: this.bound.onFocusChange }],
                     ["commandset", { id: "dactyl-onselect", commandupdater: "true", events: "select",
-                                     commandupdate: this.closure.onSelectionChange }]]]
+                                     commandupdate: this.bound.onSelectionChange }]]]
         });
 
         this._fullscreen = window.fullScreen;
@@ -188,6 +188,11 @@ var Events = Module("events", {
 
         this.listen(window, this, "events", true);
         this.listen(window, this.popups, "events", true);
+
+        this.grabFocus = 0;
+        this.grabFocusTimer = Timer(100, 10000, () => {
+            this.grabFocus = 0;
+        });
     },
 
     cleanup: function cleanup() {
@@ -206,13 +211,13 @@ var Events = Module("events", {
         }
     },
 
-    get listen() this.builtin.closure.listen,
+    get listen() this.builtin.bound.listen,
     addSessionListener: deprecated("events.listen", { get: function addSessionListener() this.listen }),
 
     /**
      * Wraps an event listener to ensure that errors are reported.
      */
-    wrapListener: function wrapListener(method, self = this) {
+    wrapListener: function wrapListener(method, self=this) {
         method.wrapper = wrappedListener;
         wrappedListener.wrapped = method;
         function wrappedListener(event) {
@@ -419,11 +424,11 @@ var Events = Module("events", {
         return true;
     },
 
-    canonicalKeys: deprecated("DOM.Event.canonicalKeys", { get: function canonicalKeys() DOM.Event.closure.canonicalKeys }),
+    canonicalKeys: deprecated("DOM.Event.canonicalKeys", { get: function canonicalKeys() DOM.Event.bound.canonicalKeys }),
     create:        deprecated("DOM.Event", function create() DOM.Event.apply(null, arguments)),
     dispatch:      deprecated("DOM.Event.dispatch", function dispatch() DOM.Event.dispatch.apply(DOM.Event, arguments)),
-    fromString:    deprecated("DOM.Event.parse", { get: function fromString() DOM.Event.closure.parse }),
-    iterKeys:      deprecated("DOM.Event.iterKeys", { get: function iterKeys() DOM.Event.closure.iterKeys }),
+    fromString:    deprecated("DOM.Event.parse", { get: function fromString() DOM.Event.bound.parse }),
+    iterKeys:      deprecated("DOM.Event.iterKeys", { get: function iterKeys() DOM.Event.bound.iterKeys }),
 
     toString: function toString() {
         if (!arguments.length)
@@ -571,7 +576,7 @@ var Events = Module("events", {
     events: {
         blur: function onBlur(event) {
             let elem = event.originalTarget;
-            if (DOM(elem).isEditable)
+            if (DOM(elem).editor)
                 util.trapErrors("removeEditActionListener",
                                 DOM(elem).editor, editor);
 
@@ -595,7 +600,7 @@ var Events = Module("events", {
         // TODO: Merge with onFocusChange
         focus: function onFocus(event) {
             let elem = event.originalTarget;
-            if (DOM(elem).isEditable)
+            if (DOM(elem).editor)
                 util.trapErrors("addEditActionListener",
                                 DOM(elem).editor, editor);
 
@@ -616,11 +621,15 @@ var Events = Module("events", {
                                      Ci.nsIDOMHTMLSelectElement,
                                      Ci.nsIDOMHTMLTextAreaElement,
                                      Ci.nsIDOMWindow])) {
-
-                if (elem.frameElement)
-                    dactyl.focusContent(true);
-                else if (!(elem instanceof Window) || Editor.getEditor(elem))
-                    dactyl.focus(window);
+                if (this.grabFocus++ > 5)
+                    ; // Something is fighting us. Give up.
+                else {
+                    this.grabFocusTimer.tell();
+                    if (elem.frameElement)
+                        dactyl.focusContent(true);
+                    else if (!(elem instanceof Window) || Editor.getEditor(elem))
+                        dactyl.focus(window);
+                }
             }
 
             if (elem instanceof Element)
@@ -711,7 +720,10 @@ var Events = Module("events", {
                     return Events.kill(event);
                 }
 
-                if (!this.processor) {
+                if (this.processor)
+                    events.dbg("ON KEYPRESS " + key + " processor: " + this.processor,
+                               event.originalTarget instanceof Element ? event.originalTarget : String(event.originalTarget));
+                else {
                     let mode = modes.getStack(0);
                     if (event.dactylMode)
                         mode = Modes.StackElement(event.dactylMode);
@@ -875,19 +887,23 @@ var Events = Module("events", {
             let haveInput = modes.stack.some(m => m.main.input);
 
             if (DOM(elem || win).isEditable) {
-                if (!haveInput)
-                    if (!isinstance(modes.main, [modes.INPUT, modes.TEXT_EDIT, modes.VISUAL]))
-                        if (options["insertmode"])
-                            modes.push(modes.INSERT);
-                        else {
-                            modes.push(modes.TEXT_EDIT);
-                            if (elem.selectionEnd - elem.selectionStart > 0)
-                                modes.push(modes.VISUAL);
-                        }
-
-                if (hasHTMLDocument(win))
-                    buffer.lastInputField = elem || win;
-                return;
+                let e = elem || win;
+                if (!(e instanceof Ci.nsIDOMWindow &&
+                        DOM(e.document.activeElement).style.MozUserModify != "read-write")) {
+                    if (!haveInput)
+                        if (!isinstance(modes.main, [modes.INPUT, modes.TEXT_EDIT, modes.VISUAL]))
+                            if (options["insertmode"])
+                                modes.push(modes.INSERT);
+                            else {
+                                modes.push(modes.TEXT_EDIT);
+                                if (elem.selectionEnd - elem.selectionStart > 0)
+                                    modes.push(modes.VISUAL);
+                            }
+
+                    if (hasHTMLDocument(win))
+                        buffer.lastInputField = elem || win;
+                    return;
+                }
             }
 
             if (elem && Events.isInputElement(elem)) {
@@ -969,7 +985,7 @@ var Events = Module("events", {
     },
 
     isInputElement: function isInputElement(elem) {
-        return DOM(elem).isEditable ||
+        return elem instanceof Ci.nsIDOMElement && DOM(elem).isEditable ||
                isinstance(elem, [Ci.nsIDOMHTMLEmbedElement,
                                  Ci.nsIDOMHTMLObjectElement,
                                  Ci.nsIDOMHTMLSelectElement]);
@@ -1124,12 +1140,12 @@ var Events = Module("events", {
             "sitemap", "", {
                 flush: function flush() {
                     memoize(this, "filters", function () this.value.filter(function (f) f(buffer.documentURI)));
-                    memoize(this, "pass", function () Set(array.flatten(this.filters.map(function (f) f.keys))));
+                    memoize(this, "pass", function () RealSet(array.flatten(this.filters.map(function (f) f.keys))));
                     memoize(this, "commandHive", function hive() Hive(this.filters, "command"));
                     memoize(this, "inputHive", function hive() Hive(this.filters, "input"));
                 },
 
-                has: function (key) Set.has(this.pass, key) || Set.has(this.commandHive.stack.mappings, key),
+                has: function (key) this.pass.has(key) || hasOwnProperty(this.commandHive.stack.mappings, key),
 
                 get pass() (this.flush(), this.pass),
 
@@ -1137,9 +1153,9 @@ var Events = Module("events", {
                     let value = parse.superapply(this, arguments);
                     value.forEach(function (filter) {
                         let vals = Option.splitList(filter.result);
-                        filter.keys = DOM.Event.parse(vals[0]).map(DOM.Event.closure.stringify);
+                        filter.keys = DOM.Event.parse(vals[0]).map(DOM.Event.bound.stringify);
 
-                        filter.commandKeys = vals.slice(1).map(DOM.Event.closure.canonicalKeys);
+                        filter.commandKeys = vals.slice(1).map(DOM.Event.bound.canonicalKeys);
                         filter.inputKeys = filter.commandKeys.filter(bind("test", /^<[ACM]-/));
                     });
                     return value;