From 49d6841b0d41ee8a7285898f1dd316bd9f998670 Mon Sep 17 00:00:00 2001 From: Kris Maglione Date: Sun, 3 Oct 2010 15:04:11 -0400 Subject: [PATCH] Handle "gi" properly on frameset documents when no last focused element. --- common/content/buffer.js | 24 +++++++++++++++--------- common/modules/base.jsm | 2 +- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/common/content/buffer.js b/common/content/buffer.js index 0f81ae61..3a03e7ee 100644 --- a/common/content/buffer.js +++ b/common/content/buffer.js @@ -348,8 +348,8 @@ const Buffer = Module("buffer", { * @property {Node} The last focused input field in the buffer. Used * by the "gi" key binding. */ - get lastInputField() window.content.document.lastInputField || null, - set lastInputField(value) { window.content.document.lastInputField = value; }, + get lastInputField() this.localStore.lastInputField && this.localStore.lastInputField.get() || null, + set lastInputField(value) { this.localStore.lastInputField = value && Cu.getWeakReference(value); }, /** * @property {string} The current top-level document's URL. @@ -1609,24 +1609,30 @@ const Buffer = Module("buffer", { mappings.add(myModes, ["gi"], "Focus last used input field", function (count) { - if (count < 1 && buffer.lastInputField) - buffer.focusElement(buffer.lastInputField); - else { + let elem = buffer.lastInputField; + + if (count >= 1 || !elem || !Events.isContentNode(elem)) { let xpath = ["input", "textarea[not(@disabled) and not(@readonly)]"]; - let elements = [m for (m in util.evaluateXPath(xpath))].filter(function (elem) { + let frames = array([buffer.focusedFrame].concat( + buffer.allFrames().filter(function (f) f != buffer.focusedFrame))); + + let elements = frames.map(function (win) [m for (m in util.evaluateXPath(xpath, win.document))]) + .flatten().filter(function (elem) { + if (elem.readOnly || elem instanceof HTMLInputElement && !set.has(Events.editableInputs, elem.type)) return false; + let computedStyle = util.computedStyle(elem); return computedStyle.visibility != "hidden" && computedStyle.display != "none" && computedStyle.MozUserFocus != "ignore"; }); dactyl.assert(elements.length > 0); - let elem = elements[Math.constrain(count, 1, elements.length) - 1]; - buffer.focusElement(elem); - util.scrollIntoView(elem); + elem = elements[Math.constrain(count, 1, elements.length) - 1]; } + buffer.focusElement(elem); + util.scrollIntoView(elem); }, { count: true }); diff --git a/common/modules/base.jsm b/common/modules/base.jsm index 4d482888..72cfa994 100644 --- a/common/modules/base.jsm +++ b/common/modules/base.jsm @@ -962,7 +962,7 @@ const array = Class("array", Array, { }, array: ary, toString: function () this.array.toString(), - concat: function () this.array.concat.apply(this.array, arguments), + concat: function () this.__noSuchMethod__("concat", Array.slice(arguments)), filter: function () this.__noSuchMethod__("filter", Array.slice(arguments)), map: function () this.__noSuchMethod__("map", Array.slice(arguments)) };