mirror of
https://github.com/gryf/pentadactyl-pm.git
synced 2025-12-21 20:57:59 +01:00
Add a hint mode for selecting scrollable elements.
Update issue 151 This should do what you want.
This commit is contained in:
@@ -519,10 +519,22 @@ const Buffer = Module("buffer", {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
elem.focus();
|
elem.focus();
|
||||||
if (elem instanceof Window && elem.getSelection() && !elem.getSelection().rangeCount)
|
if (elem instanceof Window) {
|
||||||
elem.getSelection().addRange(RangeFind.endpoint(
|
let sel = elem.getSelection();
|
||||||
RangeFind.nodeRange(elem.document.body || elem.document.documentElement),
|
if (sel && !sel.rangeCount)
|
||||||
true));
|
sel.addRange(RangeFind.endpoint(
|
||||||
|
RangeFind.nodeRange(elem.document.body || elem.document.documentElement),
|
||||||
|
true));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
let range = RangeFind.nodeRange(elem);
|
||||||
|
let sel = (elem.ownerDocument || elem).defaultView.getSelection();
|
||||||
|
if (!sel.rangeCount || !RangeFind.intersects(range, sel.getRangeAt(0))) {
|
||||||
|
range.collapse(true);
|
||||||
|
sel.removeAllRanges();
|
||||||
|
sel.addRange(range);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// for imagemap
|
// for imagemap
|
||||||
if (elem instanceof HTMLAreaElement) {
|
if (elem instanceof HTMLAreaElement) {
|
||||||
@@ -1109,9 +1121,13 @@ const Buffer = Module("buffer", {
|
|||||||
return elem;
|
return elem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var elem = buffer.focusedFrame.document.activeElement;
|
||||||
|
if (elem == elem.ownerDocument.body)
|
||||||
|
elem = null;
|
||||||
|
|
||||||
let sel = buffer.focusedFrame.getSelection();
|
let sel = buffer.focusedFrame.getSelection();
|
||||||
if (sel && sel.rangeCount)
|
if (!elem && sel && sel.rangeCount)
|
||||||
var elem = find(sel.getRangeAt(0).startContainer);
|
elem = find(sel.getRangeAt(0).startContainer);
|
||||||
|
|
||||||
if (!(elem instanceof Element)) {
|
if (!(elem instanceof Element)) {
|
||||||
let doc = Buffer.findScrollableWindow().document;
|
let doc = Buffer.findScrollableWindow().document;
|
||||||
|
|||||||
@@ -642,6 +642,9 @@ const RangeFind = Class("RangeFind", {
|
|||||||
contains: function (range, r)
|
contains: function (range, r)
|
||||||
range.compareBoundaryPoints(range.START_TO_END, r) >= 0 &&
|
range.compareBoundaryPoints(range.START_TO_END, r) >= 0 &&
|
||||||
range.compareBoundaryPoints(range.END_TO_START, r) <= 0,
|
range.compareBoundaryPoints(range.END_TO_START, r) <= 0,
|
||||||
|
intersects: function (range, r)
|
||||||
|
r.compareBoundaryPoints(range.START_TO_END, range) >= 0 &&
|
||||||
|
r.compareBoundaryPoints(range.END_TO_START, range) <= 0,
|
||||||
endpoint: function (range, before) {
|
endpoint: function (range, before) {
|
||||||
range = range.cloneRange();
|
range = range.cloneRange();
|
||||||
range.collapse(before);
|
range.collapse(before);
|
||||||
|
|||||||
@@ -48,11 +48,12 @@ const Hints = Module("hints", {
|
|||||||
options.get("extendedhinttags").getKey(this.name, this.tags()));
|
options.get("extendedhinttags").getKey(this.name, this.tags()));
|
||||||
|
|
||||||
this._hintModes = {};
|
this._hintModes = {};
|
||||||
this.addMode(";", "Focus hint", function (elem) buffer.focusElement(elem));
|
this.addMode(";", "Focus hint", buffer.closure.focusElement);
|
||||||
this.addMode("?", "Show information for hint", function (elem) buffer.showElementInfo(elem));
|
this.addMode("?", "Show information for hint", function (elem) buffer.showElementInfo(elem));
|
||||||
this.addMode("s", "Save hint", function (elem) buffer.saveLink(elem, true));
|
this.addMode("s", "Save hint", function (elem) buffer.saveLink(elem, true));
|
||||||
this.addMode("a", "Save hint with prompt", function (elem) buffer.saveLink(elem, false));
|
this.addMode("a", "Save hint with prompt", function (elem) buffer.saveLink(elem, false));
|
||||||
this.addMode("f", "Focus frame", function (elem) elem.ownerDocument.defaultView.focus(), function () ["body"]);
|
this.addMode("f", "Focus frame", function (elem) elem.ownerDocument.defaultView.focus(), function () ["body"]);
|
||||||
|
this.addMode("F", "Focus frame or pseudo-frame", buffer.closure.focusElement, null, isScrollable);
|
||||||
this.addMode("o", "Follow hint", function (elem) buffer.followLink(elem, dactyl.CURRENT_TAB));
|
this.addMode("o", "Follow hint", function (elem) buffer.followLink(elem, dactyl.CURRENT_TAB));
|
||||||
this.addMode("t", "Follow hint in a new tab", function (elem) buffer.followLink(elem, dactyl.NEW_TAB));
|
this.addMode("t", "Follow hint in a new tab", function (elem) buffer.followLink(elem, dactyl.NEW_TAB));
|
||||||
this.addMode("b", "Follow hint in a background tab", function (elem) buffer.followLink(elem, dactyl.NEW_BACKGROUND_TAB));
|
this.addMode("b", "Follow hint in a background tab", function (elem) buffer.followLink(elem, dactyl.NEW_BACKGROUND_TAB));
|
||||||
@@ -68,6 +69,9 @@ const Hints = Module("hints", {
|
|||||||
this.addMode("c", "Open context menu", function (elem) buffer.openContextMenu(elem));
|
this.addMode("c", "Open context menu", function (elem) buffer.openContextMenu(elem));
|
||||||
this.addMode("i", "Show image", function (elem) dactyl.open(elem.src));
|
this.addMode("i", "Show image", function (elem) dactyl.open(elem.src));
|
||||||
this.addMode("I", "Show image in a new tab", function (elem) dactyl.open(elem.src, dactyl.NEW_TAB));
|
this.addMode("I", "Show image in a new tab", function (elem) dactyl.open(elem.src, dactyl.NEW_TAB));
|
||||||
|
|
||||||
|
function isScrollable(elem) isinstance(elem, [HTMLFrameElement, HTMLIFrameElement]) ||
|
||||||
|
Buffer.isScrollable(elem, 0, true) || Buffer.isScrollable(elem, 0, false);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -285,7 +289,10 @@ const Hints = Module("hints", {
|
|||||||
|
|
||||||
let baseNodeAbsolute = util.xmlToDom(<span highlight="Hint"/>, doc);
|
let baseNodeAbsolute = util.xmlToDom(<span highlight="Hint"/>, doc);
|
||||||
|
|
||||||
let res = util.evaluateXPath(this._hintMode.xpath, doc, null, true);
|
let mode = this._hintMode;
|
||||||
|
let res = util.evaluateXPath(mode.xpath, doc, null, true);
|
||||||
|
if (mode.filter)
|
||||||
|
res = let (orig = res) (e for (e in orig) if (mode.filter(e)));
|
||||||
|
|
||||||
let fragment = util.xmlToDom(<div highlight="hints"/>, doc);
|
let fragment = util.xmlToDom(<div highlight="hints"/>, doc);
|
||||||
let start = this._pageHints.length;
|
let start = this._pageHints.length;
|
||||||
@@ -1078,7 +1085,7 @@ const Hints = Module("hints", {
|
|||||||
return -1;
|
return -1;
|
||||||
},
|
},
|
||||||
|
|
||||||
Mode: Struct("name", "prompt", "action", "tags")
|
Mode: Struct("name", "prompt", "action", "tags", "filter")
|
||||||
}, {
|
}, {
|
||||||
mappings: function () {
|
mappings: function () {
|
||||||
var myModes = config.browserModes;
|
var myModes = config.browserModes;
|
||||||
@@ -1105,13 +1112,13 @@ const Hints = Module("hints", {
|
|||||||
util.makeXPath(["input[not(@type='hidden')]", "a", "area", "iframe", "textarea", "button", "select",
|
util.makeXPath(["input[not(@type='hidden')]", "a", "area", "iframe", "textarea", "button", "select",
|
||||||
"*[@onclick or @onmouseover or @onmousedown or @onmouseup or @oncommand or @tabindex or @role='link' or @role='button']"]);
|
"*[@onclick or @onmouseover or @onmousedown or @onmouseup or @oncommand or @tabindex or @role='link' or @role='button']"]);
|
||||||
|
|
||||||
|
function xpath(arg) Option.quote(util.makeXPath(arg));
|
||||||
options.add(["extendedhinttags", "eht"],
|
options.add(["extendedhinttags", "eht"],
|
||||||
"XPath string of hintable elements activated by ';'",
|
"XPath string of hintable elements activated by ';'",
|
||||||
"regexpmap", "[iI]:" + Option.quote(util.makeXPath(["img"])) +
|
"regexpmap", "[iI]:" + xpath(["img"]) +
|
||||||
",[OTivVWy]:" + Option.quote(util.makeXPath(
|
",[OTivVWy]:" + xpath(["{a,area}[@href]", "{img,iframe}[@src]"]) +
|
||||||
["{a,area}[@href]", "{img,iframe}[@src]"])) +
|
",[F]:" + xpath(["div", "span", "p", "body", "html"]) +
|
||||||
",[S]:" + Option.quote(util.makeXPath(
|
",[S]:" + xpath(["input[not(@type='hidden')]", "textarea", "button", "select"]),
|
||||||
["input[not(@type='hidden')]", "textarea", "button", "select"])),
|
|
||||||
{ validator: Option.validateXPath });
|
{ validator: Option.validateXPath });
|
||||||
|
|
||||||
options.add(["hinttags", "ht"],
|
options.add(["hinttags", "ht"],
|
||||||
|
|||||||
@@ -97,6 +97,7 @@
|
|||||||
<li tag=";s"><em>s</em> to save its destination</li>
|
<li tag=";s"><em>s</em> to save its destination</li>
|
||||||
<li tag=";a"><em>a</em> to save its destination (prompting for save location)</li>
|
<li tag=";a"><em>a</em> to save its destination (prompting for save location)</li>
|
||||||
<li tag=";f"><em>f</em> to focus a frame</li>
|
<li tag=";f"><em>f</em> to focus a frame</li>
|
||||||
|
<li tag=";f"><em>f</em> to focus a frame or pseudo-frame</li>
|
||||||
<li tag=";o"><em>o</em> to open its location in the current tab</li>
|
<li tag=";o"><em>o</em> to open its location in the current tab</li>
|
||||||
<li tag=";t"><em>t</em> to open its location in a new tab</li>
|
<li tag=";t"><em>t</em> to open its location in a new tab</li>
|
||||||
<li tag=";b"><em>b</em> to open its location in a new background tab</li>
|
<li tag=";b"><em>b</em> to open its location in a new background tab</li>
|
||||||
|
|||||||
@@ -612,6 +612,11 @@
|
|||||||
//area[@href] | //xhtml:area[@href] |
|
//area[@href] | //xhtml:area[@href] |
|
||||||
//img[@src] | //xhtml:img[@src] |
|
//img[@src] | //xhtml:img[@src] |
|
||||||
//iframe[@src] | //xhtml:iframe[@src]',
|
//iframe[@src] | //xhtml:iframe[@src]',
|
||||||
|
[F]:'//div | //xhtml:div |
|
||||||
|
//span | //xhtml:span |
|
||||||
|
//p | //xhtml:p |
|
||||||
|
//body | //xhtml:body |
|
||||||
|
//html | //xhtml:html'
|
||||||
[S]:'//input[not(@type=''hidden'')] |
|
[S]:'//input[not(@type=''hidden'')] |
|
||||||
//xhtml:input[not(@type=''hidden'')] |
|
//xhtml:input[not(@type=''hidden'')] |
|
||||||
//textarea | //xhtml:textarea |
|
//textarea | //xhtml:textarea |
|
||||||
|
|||||||
Reference in New Issue
Block a user