diff --git a/common/content/buffer.js b/common/content/buffer.js index 78ada638..b41e81f9 100644 --- a/common/content/buffer.js +++ b/common/content/buffer.js @@ -348,7 +348,7 @@ var Buffer = Module("buffer", { * @property {number} The buffer's horizontal scroll percentile. */ get scrollXPercent() { - let elem = this.findScrollable(0, true); + let elem = Buffer.Scrollable(this.findScrollable(0, true)); if (elem.scrollWidth - elem.clientWidth === 0) return 0; return elem.scrollLeft * 100 / (elem.scrollWidth - elem.clientWidth); @@ -358,7 +358,7 @@ var Buffer = Module("buffer", { * @property {number} The buffer's vertical scroll percentile. */ get scrollYPercent() { - let elem = this.findScrollable(0, false); + let elem = Buffer.Scrollable(this.findScrollable(0, false)); if (elem.scrollHeight - elem.clientHeight === 0) return 0; return elem.scrollTop * 100 / (elem.scrollHeight - elem.clientHeight); @@ -788,25 +788,6 @@ var Buffer = Module("buffer", { if (Buffer.isScrollable(elem, dir, horizontal)) break; - if (!(elem instanceof Element)) - return { - __proto__: elem.documentElement || elem.ownerDocument.documentElement, - - win: elem.defaultView || elem.ownerDocument.defaultView, - - get clientWidth() this.win.innerWidth, - get clientHeight() this.win.innerHeight, - - get scrollWidth() this.win.scrollMaxX + this.win.innerWidth, - get scrollHeight() this.win.scrollMaxY + this.win.innerHeight, - - get scrollLeft() this.win.scrollX, - set scrollLeft(val) { this.win.scrollTo(val, this.win.scrollY) }, - - get scrollTop() this.win.scrollY, - set scrollTop(val) { this.win.scrollTo(this.win.scrollX, val) } - }; - return elem; } @@ -1213,6 +1194,30 @@ var Buffer = Module("buffer", { PageInfo: Struct("PageInfo", "name", "title", "action") .localize("title"), + Scrollable: function Scrollable(elem) { + if (elem instanceof Element) + return elem; + if (isinstance(elem, [Window, Document])) + return { + __proto__: elem.documentElement || elem.ownerDocument.documentElement, + + win: elem.defaultView || elem.ownerDocument.defaultView, + + get clientWidth() this.win.innerWidth, + get clientHeight() this.win.innerHeight, + + get scrollWidth() this.win.scrollMaxX + this.win.innerWidth, + get scrollHeight() this.win.scrollMaxY + this.win.innerHeight, + + get scrollLeft() this.win.scrollX, + set scrollLeft(val) { this.win.scrollTo(val, this.win.scrollY) }, + + get scrollTop() this.win.scrollY, + set scrollTop(val) { this.win.scrollTo(this.win.scrollX, val) } + }; + return elem; + }, + ZOOM_MIN: Class.Memoize(function () prefs.get("zoom.minPercent")), ZOOM_MAX: Class.Memoize(function () prefs.get("zoom.maxPercent")), @@ -1318,9 +1323,10 @@ var Buffer = Module("buffer", { * {@link marks.push}. @optional */ scrollTo: function scrollTo(elem, left, top, reason) { - if (elem.ownerDocument == buffer.focusedFrame.document) + if (~[elem, elem.document, elem.ownerDocument].indexOf(buffer.focusedFrame.document)) marks.push(reason); + elem = Buffer.Scrollable(elem); if (left != null) elem.scrollLeft = left; if (top != null) @@ -1346,6 +1352,8 @@ var Buffer = Module("buffer", { */ scrollHorizontal: function scrollHorizontal(elem, unit, number) { let fontSize = parseInt(DOM(elem).style.fontSize); + + elem = Buffer.Scrollable(elem); let increment; if (unit == "columns") increment = fontSize; // Good enough, I suppose. @@ -1376,6 +1384,8 @@ var Buffer = Module("buffer", { */ scrollVertical: function scrollVertical(elem, unit, number) { let fontSize = parseInt(DOM(elem).style.lineHeight); + + elem = Buffer.Scrollable(elem); let increment; if (unit == "lines") increment = fontSize; @@ -1405,6 +1415,7 @@ var Buffer = Module("buffer", { * scroll vertically. */ scrollToPercent: function scrollToPercent(elem, horizontal, vertical) { + elem = Buffer.Scrollable(elem); Buffer.scrollTo(elem, horizontal == null ? null : (elem.scrollWidth - elem.clientWidth) * (horizontal / 100), @@ -1423,7 +1434,7 @@ var Buffer = Module("buffer", { * column ordinal to scroll to. */ scrollToPosition: function scrollToPosition(elem, horizontal, vertical) { - let style = DOM(elem).style; + let style = DOM(elem.body || elem).style; Buffer.scrollTo(elem, horizontal == null ? null : horizontal == 0 ? 0 : this._exWidth(elem) * horizontal, @@ -1438,6 +1449,8 @@ var Buffer = Module("buffer", { */ getScrollPosition: function getPosition(elem) { let style = DOM(elem).style; + + elem = Buffer.Scrollable(elem); return { x: elem.scrollLeft && elem.scrollLeft / this._exWidth(elem), y: elem.scrollTop / parseFloat(style.lineHeight) @@ -1446,7 +1459,7 @@ var Buffer = Module("buffer", { _exWidth: function _exWidth(elem) { let div = DOM(, - elem.ownerDocument).appendTo(elem); + elem.ownerDocument).appendTo(elem.body || elem); try { return parseFloat(div.style.width); } @@ -1847,8 +1860,10 @@ var Buffer = Module("buffer", { args.count); if (elem) elem.scrollIntoView(true); + else if (args.count) + buffer.scrollToPosition(null, args.count); else - buffer.scrollToPercent(null, args.count != null ? args.count : 100); + buffer.scrollToPercent(null, 100); }, { count: true }); diff --git a/common/content/marks.js b/common/content/marks.js index 691ad192..a6eaa4be 100644 --- a/common/content/marks.js +++ b/common/content/marks.js @@ -32,7 +32,7 @@ var Marks = Module("marks", { this._urlMarks ).sort(function (a, b) String.localeCompare(a[0], b[0])), - get localURI() buffer.focusedFrame.document.documentURI, + get localURI() buffer.focusedFrame.document.documentURI.replace(/#.*/, ""), Mark: function Mark(params) { let win = buffer.focusedFrame; @@ -40,7 +40,7 @@ var Marks = Module("marks", { params = params || {}; - params.location = doc.documentURI, + params.location = doc.documentURI.replace(/#.*/, ""), params.offset = buffer.scrollPosition; params.path = DOM(buffer.findScrollable(0, params.offset.x)).xpath; params.timestamp = Date.now() * 1000; @@ -175,7 +175,7 @@ var Marks = Module("marks", { let tab = mark.tab && mark.tab.get(); if (!tab || !tab.linkedBrowser || tabs.allTabs.indexOf(tab) == -1) for ([, tab] in iter(tabs.visibleTabs, tabs.allTabs)) { - if (tab.linkedBrowser.contentDocument.documentURI === mark.location) + if (tab.linkedBrowser.contentDocument.documentURI.replace(/#.*/, "") === mark.location) break; tab = null; } @@ -183,7 +183,7 @@ var Marks = Module("marks", { if (tab) { tabs.select(tab); let doc = tab.linkedBrowser.contentDocument; - if (doc.documentURI == mark.location) { + if (doc.documentURI.replace(/#.*/, "") == mark.location) { dactyl.log(_("mark.jumpingToURL", Marks.markToString(char, mark)), 5); this._scrollTo(mark); } @@ -231,7 +231,8 @@ var Marks = Module("marks", { break; util.assert(node); - DOM(node).scrollIntoView(); + if (node instanceof Element) + DOM(node).scrollIntoView(); if (mark.offset) Buffer.scrollToPosition(node, mark.offset.x, mark.offset.y); diff --git a/common/locale/en-US/buffer.xml b/common/locale/en-US/buffer.xml index 21ac4bdc..fdb397d8 100644 --- a/common/locale/en-US/buffer.xml +++ b/common/locale/en-US/buffer.xml @@ -135,8 +135,7 @@

Go to the end of the document. With count, go to the countth line as determined by linenumbers, - or to the countth percent of the document if the line number - can't be determined. + or by the line height of the document body otherwise.

diff --git a/common/modules/dom.jsm b/common/modules/dom.jsm index df05d094..3110ecb0 100644 --- a/common/modules/dom.jsm +++ b/common/modules/dom.jsm @@ -372,6 +372,10 @@ var DOM = Class("DOM", { */ get style() { let node = this[0]; + if (node instanceof Ci.nsIDOMWindow) + node = node.document; + if (node instanceof Ci.nsIDOMDocument) + node = node.documentElement; while (node && !(node instanceof Ci.nsIDOMElement) && node.parentNode) node = node.parentNode; @@ -462,6 +466,8 @@ var DOM = Class("DOM", { */ get xpath() { function quote(val) "'" + val.replace(/[\\']/g, "\\$&") + "'"; + if (!this[0] instanceof Ci.nsIDOMElement) + return null; let res = []; let doc = this.document; diff --git a/common/modules/finder.jsm b/common/modules/finder.jsm index 14e5ebe7..782df595 100644 --- a/common/modules/finder.jsm +++ b/common/modules/finder.jsm @@ -484,10 +484,11 @@ var RangeFind = Class("RangeFind", { let saved = ["lastRange", "lastString", "range", "regexp"].map(function (s) [s, this[s]], this); let res; try { + let regexp = this.regexp && word != util.regexp.escape(word); this.lastRange = null; - if (this.regexp) { + this.regexp = false; + if (regexp) { let re = RegExp(word, "gm" + this.flags); - this.regexp = false; for (this.range in array.iterValues(this.ranges)) { for (let match in util.regexp.iterate(re, DOM.stringify(this.range.range, true))) { let lastRange = this.lastRange; @@ -635,8 +636,9 @@ var RangeFind = Class("RangeFind", { } let word = pattern; + let regexp = this.regexp && word != util.regexp.escape(word); - if (this.regexp) + if (regexp) try { RegExp(pattern); } @@ -661,7 +663,7 @@ var RangeFind = Class("RangeFind", { if (this.backward && !again) start = RangeFind.endpoint(this.startRange, false); - if (this.regexp) { + if (regexp) { let range = this.range.range.cloneRange(); range[this.backward ? "setEnd" : "setStart"]( start.startContainer, start.startOffset);