1
0
mirror of https://github.com/gryf/pentadactyl-pm.git synced 2026-03-05 21:25:47 +01:00

Resurrect my range finder, Part IV: Links only, match case, and all that stuff no one uses.

This commit is contained in:
Kris Maglione
2009-11-13 04:22:11 -05:00
parent 12012af693
commit d749340ef3

View File

@@ -464,8 +464,7 @@ const RangeFinder = Module("rangefinder", {
requires: ["config"], requires: ["config"],
init: function () { init: function () {
this.lastSearchString = ""; this.lastSearchPattern = "";
this.lastSearchBackwards = false;
}, },
openPrompt: function (mode) { openPrompt: function (mode) {
@@ -475,23 +474,48 @@ const RangeFinder = Module("rangefinder", {
this.find("", backwards); this.find("", backwards);
}, },
find: function (str, backwards) { bootstrap: function (str, backward) {
let caseSensitive = false; let highlighted = this.rangeFind && this.rangeFind.highlighted;
let highlighted = this.rangeFind && this.rangeFind.highlighted; // Kludge? let matchCase = !(options["ignorecase"] || options["smartcase"] && !/[A-Z]/.test(str));
this.rangeFind = RangeFind(caseSensitive, backwards); let linksOnly = options["linksearch"];
this.rangeFind.highlighted = highlighted;
// All this ado is ludicrous.
str = str.replace(/\\(.|$)/g, function (m, n1) {
if (n1 == "l")
linksOnly = true;
else if (n1 == "L")
linksOnly = false;
else if (n1 == "c")
matchCase = false;
else if (n1 == "C")
matchCase = true;
else
return n1;
return "";
});
if (!this.rangeFind || linksOnly ^ !!this.rangeFind.elementPath ||
matchCase ^ this.rangeFind.matchCase || backward ^ this.rangeFind.reverse) {
if (this.rangeFind)
this.rangeFind.cancel();
this.rangeFind = RangeFind(matchCase, backward, linksOnly && options["hinttags"]);
this.rangeFind.highlighted = highlighted;
}
return str;
},
find: function (pattern, backwards) {
let str = this.bootstrap(pattern);
if (!this.rangeFind.search(str)) if (!this.rangeFind.search(str))
setTimeout(function () { liberator.echoerr("E486: Pattern not found: " + str); }, 0); setTimeout(function () { liberator.echoerr("E486: Pattern not found: " + pattern); }, 0);
return this.rangeFind.found; return this.rangeFind.found;
}, },
findAgain: function (reverse) { findAgain: function (reverse) {
if (!this.rangeFind) if (!this.rangeFind)
this.find(this.lastSearchString); this.find(this.lastSearchPattern);
else if (!this.rangeFind.search(null, reverse)) else if (!this.rangeFind.search(null, reverse))
liberator.echoerr("E486: Pattern not found: " + this.lastSearchString); liberator.echoerr("E486: Pattern not found: " + this.lastSearchPattern);
else if (this.rangeFind.wrapped) { else if (this.rangeFind.wrapped) {
// hack needed, because wrapping causes a "scroll" event which clears // hack needed, because wrapping causes a "scroll" event which clears
// our command line // our command line
@@ -502,7 +526,7 @@ const RangeFinder = Module("rangefinder", {
}, 0); }, 0);
} }
else else
commandline.echo((this.rangeFind.backward ? "?" : "/") + this.lastSearchString, null, commandline.FORCE_SINGLELINE); commandline.echo((this.rangeFind.backward ? "?" : "/") + this.lastSearchPattern, null, commandline.FORCE_SINGLELINE);
if (options["hlsearch"]) if (options["hlsearch"])
this.highlight(); this.highlight();
@@ -510,18 +534,19 @@ const RangeFinder = Module("rangefinder", {
// Called when the user types a key in the search dialog. Triggers a find attempt if 'incsearch' is set // Called when the user types a key in the search dialog. Triggers a find attempt if 'incsearch' is set
onKeyPress: function (command) { onKeyPress: function (command) {
if (options["incsearch"] && this.rangeFind) if (options["incsearch"]) {
command = this.bootstrap(command);
this.rangeFind.search(command); this.rangeFind.search(command);
}
}, },
onSubmit: function (command) { onSubmit: function (command) {
if (!options["incsearch"] || !this.rangeFind || !this.rangeFind.found) { if (!options["incsearch"] || !this.rangeFind || !this.rangeFind.found) {
this.clear(); this.clear();
this.find(command || this.lastSearchString, this.lastSearchBackwards); this.find(command || this.lastSearchPattern, modes.extended & modes.FIND_BACKWARD);
} }
this.lastSearchBackwards = this.rangeFind.backwards; this.lastSearchPattern = command;
this.lastSearchString = this.rangeFind.searchString;
if (options["hlsearch"]) if (options["hlsearch"])
this.highlight(); this.highlight();
@@ -614,9 +639,10 @@ const RangeFinder = Module("rangefinder", {
}); });
const RangeFind = Class("RangeFind", { const RangeFind = Class("RangeFind", {
init: function (matchCase, backward) { init: function (matchCase, backward, elementPath) {
this.elementPath = elementPath || null;
this.matchCase = Boolean(matchCase); this.matchCase = Boolean(matchCase);
this._backward = Boolean(backward); this.reverse = Boolean(backward);
this.finder = services.create("find"); this.finder = services.create("find");
this.finder.caseSensitive = this.matchCase; this.finder.caseSensitive = this.matchCase;
@@ -654,18 +680,39 @@ const RangeFind = Class("RangeFind", {
return ranges[0]; return ranges[0];
}, },
findSubRanges: function (range) {
let doc = range.startContainer.ownerDocument;
for (let elem in util.evaluateXPath(this.elementPath, doc)) {
let r = doc.createRange();
r.selectNode(elem);
if (range.compareBoundaryPoints(Range.START_TO_END, r) >= 0 &&
range.compareBoundaryPoints(Range.END_TO_START, r) <= 0)
yield r;
}
},
makeFrameList: function (win) { makeFrameList: function (win) {
const self = this;
win = win.top; win = win.top;
let frames = []; let frames = [];
let backup = null;
function pushRange(start, end) { function pushRange(start, end) {
frames.push(RangeFind.Range(start, end, frames.length)); let range = start.startContainer.ownerDocument.createRange();
range.setStart(start.startContainer, start.startOffset);
range.setEnd(end.startContainer, end.startOffset);
if (!self.elementPath)
frames.push(RangeFind.Range(range, frames.length));
else
for (let r in self.findSubRanges(range))
frames.push(RangeFind.Range(r, frames.length));
} }
function rec(win) { function rec(win) {
let doc = win.document; let doc = win.document;
let pageRange = doc.createRange(); let pageRange = doc.createRange();
pageRange.setStartBefore(doc.body || doc.documentElement.lastChild); pageRange.selectNode(doc.body || doc.documentElement.lastChild);
pageRange.setEndAfter(doc.body || doc.documentElement.lastChild); backup = backup || pageRange;
let pageStart = RangeFind.endpoint(pageRange, true); let pageStart = RangeFind.endpoint(pageRange, true);
let pageEnd = RangeFind.endpoint(pageRange, false); let pageEnd = RangeFind.endpoint(pageRange, false);
@@ -679,6 +726,8 @@ const RangeFind = Class("RangeFind", {
pushRange(pageStart, pageEnd); pushRange(pageStart, pageEnd);
} }
rec(win); rec(win);
if (frames.length == 0)
frames[0] = RangeFind.Range(RangeFind.endpoint(backup, true), 0);
return frames; return frames;
}, },
@@ -726,7 +775,7 @@ const RangeFind = Class("RangeFind", {
this.lastRange = null; this.lastRange = null;
this.lastString = word this.lastString = word
var res; var res;
while (res = this.search(null, this._backward, true)) while (res = this.search(null, this.reverse, true))
yield res; yield res;
} }
finally { finally {
@@ -736,7 +785,7 @@ const RangeFind = Class("RangeFind", {
search: function (word, reverse, private) { search: function (word, reverse, private) {
this.wrapped = false; this.wrapped = false;
this.finder.findBackwards = reverse ? !this._backward : this._backward; this.finder.findBackwards = reverse ? !this.reverse : this.reverse;
let again = word == null; let again = word == null;
if (again) if (again)
word = this.lastString; word = this.lastString;
@@ -769,7 +818,7 @@ const RangeFind = Class("RangeFind", {
for (let i in indices.call(this)) { for (let i in indices.call(this)) {
this.range = this.ranges[i]; this.range = this.ranges[i];
let start = this.sameDocument(this.lastRange, this.range.range) ? let start = this.sameDocument(this.lastRange, this.range.range) && this.range.intersects(this.lastRange) ?
RangeFind.endpoint(this.lastRange, !(again ^ this.backward)) : RangeFind.endpoint(this.lastRange, !(again ^ this.backward)) :
RangeFind.endpoint(this.range.range, !this.backward);; RangeFind.endpoint(this.range.range, !this.backward);;
if (this.backward && !again) if (this.backward && !again)
@@ -863,24 +912,25 @@ const RangeFind = Class("RangeFind", {
}, },
}, { }, {
Range: Class("RangeFind.Range", { Range: Class("RangeFind.Range", {
init: function (start, end, index) { init: function (range, index) {
if (start instanceof Ci.nsIDOMWindow) { // Kludge if (range instanceof Ci.nsIDOMWindow) { // Kludge
this.document = start.document; this.document = range.document;
return; return;
} }
this.index = index; this.index = index;
this.document = start.startContainer.ownerDocument; this.document = range.startContainer.ownerDocument;
this.window = this.document.defaultView; this.window = this.document.defaultView;
this.range = range;
this.range = this.document.createRange();
this.range.setStart(start.startContainer, start.startOffset);
this.range.setEnd(end.startContainer, end.startOffset);
this.save(); this.save();
}, },
intersects: function (range)
this.range.compareBoundaryPoints(Range.START_TO_END, range) >= 0 &&
this.range.compareBoundaryPoints(Range.END_TO_START, range) <= 0,
save: function () { save: function () {
this.scroll = Point(this.window.pageXOffset, this.window.pageYOffset); this.scroll = Point(this.window.pageXOffset, this.window.pageYOffset);