diff --git a/common/content/modes.js b/common/content/modes.js index 33c60cdd..e5028297 100644 --- a/common/content/modes.js +++ b/common/content/modes.js @@ -93,6 +93,8 @@ var Modes = Module("modes", { modes.pop(); else if (!stack.pop && !this.pref) this.pref = true; + if (!stack.pop) + buffer.resetCaret(); }, leave: function (stack) { diff --git a/common/locale/en-US/developer.xml b/common/locale/en-US/developer.xml index 43fb99ed..869d4c43 100644 --- a/common/locale/en-US/developer.xml +++ b/common/locale/en-US/developer.xml @@ -187,7 +187,7 @@ use strict; XML.ignoreWhitespace = false; XML.prettyPrinting = false; -var INFO = +var INFO = <plugin nameflashblock version1.0 diff --git a/common/modules/buffer.jsm b/common/modules/buffer.jsm index 9788c22c..cdc2a179 100644 --- a/common/modules/buffer.jsm +++ b/common/modules/buffer.jsm @@ -485,6 +485,75 @@ var Buffer = Module("Buffer", { }); }, + /** + * Resets the caret position so that it resides within the current + * viewport. + */ + resetCaret: function resetCaret() { + function visible(range) util.intersection(DOM(range).rect, viewport); + + function getRanges(rect) { + let nodes = win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils) + .nodesFromRect(rect.x, rect.y, 0, rect.width, rect.height, 0, false, false); + return Array.filter(nodes, function (n) n instanceof Ci.nsIDOMText) + .map(RangeFind.nodeContents); + } + + let win = this.focusedFrame; + let sel = win.getSelection(); + let viewport = DOM(win).rect; + + if (sel.rangeCount) { + var range = sel.getRangeAt(0); + + let vis = visible(range); + if (vis.width > 0 && vis.height > 0) + return; + + var { rect } = DOM(range); + var reverse = rect.bottom > win.innerHeight; + + rect = { x: rect.left, y: 0, width: rect.width, height: win.innerHeight }; + } + else { + rect = { x: 0, y: 0, width: win.innerWidth, height: 0 }; + } + + var reduce = function (a, b) DOM(a).rect.top < DOM(b).rect.top ? a : b; + var dir = "forward"; + var y = 0; + if (reverse) { + reduce = function (a, b) DOM(b).rect.bottom > DOM(a).rect.bottom ? b : a; + dir = "backward"; + y = win.innerHeight - 1; + } + + let ranges = getRanges(rect); + if (!ranges.length) + ranges = getRanges({ x: 0, y: y, width: win.innerWidth, height: 0 }); + if (!ranges.length) + return; + + range = ranges.reduce(reduce); + + if (range) { + range.collapse(!reverse); + sel.removeAllRanges(); + sel.addRange(range); + do { + if (visible(range).height > 0) + break; + + var { startContainer, startOffset } = range; + sel.modify("move", dir, "line"); + range = sel.getRangeAt(0); + } + while (startContainer != range.startContainer || startOffset != range.startOffset); + + sel.modify("move", reverse ? "forward" : "backward", "lineboundary"); + } + }, + /** * @property {nsISelectionController} The current document's selection * controller. @@ -887,7 +956,7 @@ var Buffer = Module("Buffer", { * @param {boolean} useExternalEditor View the source in the external editor. */ viewSource: function viewSource(loc, useExternalEditor) { - let { dactyl, history, options } = this.modules; + let { dactyl, editor, history, options } = this.modules; let window = this.topWindow; @@ -940,6 +1009,8 @@ var Buffer = Module("Buffer", { init: function init(doc, callback) { this.callback = callable(callback) ? callback : function (file, temp) { + let { editor } = overlay.activeModules; + editor.editFileExternally(update({ file: file.path }, callback || {}), function () { temp && file.remove(false); }); return true; diff --git a/common/modules/dom.jsm b/common/modules/dom.jsm index 3a954f67..5c490dd5 100644 --- a/common/modules/dom.jsm +++ b/common/modules/dom.jsm @@ -326,7 +326,13 @@ var DOM = Class("DOM", { }), }), - get rect() this[0] ? this[0].getBoundingClientRect() : {}, + get rect() this[0] instanceof Ci.nsIDOMWindow ? { get width() this.innerWidth, + get height() this.innerHeight, + get bottom() this.height, + get right() this.width, + top: 0, left: 0, + __proto__: this[0] } : + this[0] ? this[0].getBoundingClientRect() : {}, get viewport() { let r = this.rect; diff --git a/common/modules/finder.jsm b/common/modules/finder.jsm index fc99f31f..dbd1530d 100644 --- a/common/modules/finder.jsm +++ b/common/modules/finder.jsm @@ -10,6 +10,7 @@ defineModule("finder", { require: ["prefs"] }, this); +this.lazyRequire("buffer", ["Buffer"]); this.lazyRequire("overlay", ["overlay"]); function equals(a, b) XPCNativeWrapper(a) == XPCNativeWrapper(b); @@ -56,6 +57,8 @@ var RangeFinder = Module("rangefinder", { this.commandline; this.CommandMode(mode, this.content).open(); + Buffer(this.content).resetCaret(); + if (this.rangeFind && equals(this.rangeFind.window.get(), this.window)) this.rangeFind.reset(); this.find("", mode == this.modes.FIND_BACKWARD); diff --git a/common/skin/help-styles.css b/common/skin/help-styles.css index 9c7289c9..60c8a2e5 100644 --- a/common/skin/help-styles.css +++ b/common/skin/help-styles.css @@ -177,18 +177,21 @@ HelpType;;;FontCode /* An option type */ \ HelpWarning /* The indicator for a warning */ \ color: red; font-weight: bold; -HelpXML;;;FontCode { - /* Highlighted XML */ +HelpXMLBase;;;FontCode { white-space: pre; - display: inline-block; color: #C5F779; background-color: #444444; - border: 1px dashed #aaaaaa; font-family: Terminus, Fixed, monospace; } -HelpXMLBlock;;;HelpXML { +HelpXML;;;HelpXMLBase { + /* Highlighted XML */ + display: inline-block; + border: 1px dashed #aaaaaa; +} +HelpXMLBlock;;;HelpXMLBase { display: block; margin-left: 2em; + border: 1px dashed #aaaaaa; } HelpXMLAttribute color: #C5F779; HelpXMLAttribute::after color: #E5E5E5; content: "="; diff --git a/pentadactyl/TODO b/pentadactyl/TODO index 8685a188..cbe8780e 100644 --- a/pentadactyl/TODO +++ b/pentadactyl/TODO @@ -24,7 +24,6 @@ FEATURES: 8 add support for filename special characters such as % 8 :redir and 'verbosefile' 8 middleclick in content == p, and if command line is open, paste there the clipboard buffer -8 all search commands should start searching from the top of the visible viewport 8 Add information to dactyl/HACKING file about testing and optimization 7 describe-key command (prompt for a key and display its binding with documentation) 7 use ctrl-n/p in insert mode for word completion