mirror of
https://github.com/gryf/pentadactyl-pm.git
synced 2025-12-19 16:27:58 +01:00
Try to move the caret within the viewport on entering Caret or Find mode. Closes issue #170.
This commit is contained in:
@@ -93,6 +93,8 @@ var Modes = Module("modes", {
|
|||||||
modes.pop();
|
modes.pop();
|
||||||
else if (!stack.pop && !this.pref)
|
else if (!stack.pop && !this.pref)
|
||||||
this.pref = true;
|
this.pref = true;
|
||||||
|
if (!stack.pop)
|
||||||
|
buffer.resetCaret();
|
||||||
},
|
},
|
||||||
|
|
||||||
leave: function (stack) {
|
leave: function (stack) {
|
||||||
|
|||||||
@@ -187,7 +187,7 @@
|
|||||||
<xml-block><escape><hl key="HelpXMLString">use strict</hl>;
|
<xml-block><escape><hl key="HelpXMLString">use strict</hl>;
|
||||||
XML.ignoreWhitespace = <hl key="Boolean">false</hl>;
|
XML.ignoreWhitespace = <hl key="Boolean">false</hl>;
|
||||||
XML.prettyPrinting = <hl key="Boolean">false</hl>;
|
XML.prettyPrinting = <hl key="Boolean">false</hl>;
|
||||||
<hl key="HelpXML">var</hl> INFO = <!-- Cursed manual XML highlighting! -->
|
<hl key="HelpXMLBase">var</hl> INFO = <!-- Cursed manual XML highlighting! -->
|
||||||
<hl key="HelpXMLTagStart"><plugin
|
<hl key="HelpXMLTagStart"><plugin
|
||||||
<hl key="HelpXMLAttribute">name</hl><hl key="HelpXMLString">flashblock</hl>
|
<hl key="HelpXMLAttribute">name</hl><hl key="HelpXMLString">flashblock</hl>
|
||||||
<hl key="HelpXMLAttribute">version</hl><hl key="HelpXMLString">1.0</hl>
|
<hl key="HelpXMLAttribute">version</hl><hl key="HelpXMLString">1.0</hl>
|
||||||
|
|||||||
@@ -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
|
* @property {nsISelectionController} The current document's selection
|
||||||
* controller.
|
* controller.
|
||||||
@@ -887,7 +956,7 @@ var Buffer = Module("Buffer", {
|
|||||||
* @param {boolean} useExternalEditor View the source in the external editor.
|
* @param {boolean} useExternalEditor View the source in the external editor.
|
||||||
*/
|
*/
|
||||||
viewSource: function viewSource(loc, useExternalEditor) {
|
viewSource: function viewSource(loc, useExternalEditor) {
|
||||||
let { dactyl, history, options } = this.modules;
|
let { dactyl, editor, history, options } = this.modules;
|
||||||
|
|
||||||
let window = this.topWindow;
|
let window = this.topWindow;
|
||||||
|
|
||||||
@@ -940,6 +1009,8 @@ var Buffer = Module("Buffer", {
|
|||||||
init: function init(doc, callback) {
|
init: function init(doc, callback) {
|
||||||
this.callback = callable(callback) ? callback :
|
this.callback = callable(callback) ? callback :
|
||||||
function (file, temp) {
|
function (file, temp) {
|
||||||
|
let { editor } = overlay.activeModules;
|
||||||
|
|
||||||
editor.editFileExternally(update({ file: file.path }, callback || {}),
|
editor.editFileExternally(update({ file: file.path }, callback || {}),
|
||||||
function () { temp && file.remove(false); });
|
function () { temp && file.remove(false); });
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -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() {
|
get viewport() {
|
||||||
let r = this.rect;
|
let r = this.rect;
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ defineModule("finder", {
|
|||||||
require: ["prefs"]
|
require: ["prefs"]
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
|
this.lazyRequire("buffer", ["Buffer"]);
|
||||||
this.lazyRequire("overlay", ["overlay"]);
|
this.lazyRequire("overlay", ["overlay"]);
|
||||||
|
|
||||||
function equals(a, b) XPCNativeWrapper(a) == XPCNativeWrapper(b);
|
function equals(a, b) XPCNativeWrapper(a) == XPCNativeWrapper(b);
|
||||||
@@ -56,6 +57,8 @@ var RangeFinder = Module("rangefinder", {
|
|||||||
this.commandline;
|
this.commandline;
|
||||||
this.CommandMode(mode, this.content).open();
|
this.CommandMode(mode, this.content).open();
|
||||||
|
|
||||||
|
Buffer(this.content).resetCaret();
|
||||||
|
|
||||||
if (this.rangeFind && equals(this.rangeFind.window.get(), this.window))
|
if (this.rangeFind && equals(this.rangeFind.window.get(), this.window))
|
||||||
this.rangeFind.reset();
|
this.rangeFind.reset();
|
||||||
this.find("", mode == this.modes.FIND_BACKWARD);
|
this.find("", mode == this.modes.FIND_BACKWARD);
|
||||||
|
|||||||
@@ -177,18 +177,21 @@ HelpType;;;FontCode /* An option type */ \
|
|||||||
HelpWarning /* The indicator for a warning */ \
|
HelpWarning /* The indicator for a warning */ \
|
||||||
color: red; font-weight: bold;
|
color: red; font-weight: bold;
|
||||||
|
|
||||||
HelpXML;;;FontCode {
|
HelpXMLBase;;;FontCode {
|
||||||
/* Highlighted XML */
|
|
||||||
white-space: pre;
|
white-space: pre;
|
||||||
display: inline-block;
|
|
||||||
color: #C5F779;
|
color: #C5F779;
|
||||||
background-color: #444444;
|
background-color: #444444;
|
||||||
border: 1px dashed #aaaaaa;
|
|
||||||
font-family: Terminus, Fixed, monospace;
|
font-family: Terminus, Fixed, monospace;
|
||||||
}
|
}
|
||||||
HelpXMLBlock;;;HelpXML {
|
HelpXML;;;HelpXMLBase {
|
||||||
|
/* Highlighted XML */
|
||||||
|
display: inline-block;
|
||||||
|
border: 1px dashed #aaaaaa;
|
||||||
|
}
|
||||||
|
HelpXMLBlock;;;HelpXMLBase {
|
||||||
display: block;
|
display: block;
|
||||||
margin-left: 2em;
|
margin-left: 2em;
|
||||||
|
border: 1px dashed #aaaaaa;
|
||||||
}
|
}
|
||||||
HelpXMLAttribute color: #C5F779;
|
HelpXMLAttribute color: #C5F779;
|
||||||
HelpXMLAttribute::after color: #E5E5E5; content: "=";
|
HelpXMLAttribute::after color: #E5E5E5; content: "=";
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ FEATURES:
|
|||||||
8 add support for filename special characters such as %
|
8 add support for filename special characters such as %
|
||||||
8 :redir and 'verbosefile'
|
8 :redir and 'verbosefile'
|
||||||
8 middleclick in content == p, and if command line is open, paste there the clipboard buffer
|
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
|
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 describe-key command (prompt for a key and display its binding with documentation)
|
||||||
7 use ctrl-n/p in insert mode for word completion
|
7 use ctrl-n/p in insert mode for word completion
|
||||||
|
|||||||
Reference in New Issue
Block a user