diff --git a/common/content/buffer.js b/common/content/buffer.js index 3afb2bd7..cd46f3dc 100644 --- a/common/content/buffer.js +++ b/common/content/buffer.js @@ -797,6 +797,37 @@ var Buffer = Module("buffer", { return win; }, + /** + * Finds the next visible element for the node path in 'jumptags' + * for *arg*. + * + * @param {string} arg The element in 'jumptags' to use for the search. + * @param {number} count The number of elements to jump. + * @optional + * @param {boolean} reverse If true, search backwards. @optional + */ + findJump: function findJump(arg, count, reverse) { + const FUDGE = 10; + + let path = options["jumptags"][arg]; + dactyl.assert(path, _("error.invalidArgument", arg)); + + let distance = reverse ? function (rect) -rect.top : function (rect) rect.top; + let elems = [[e, distance(e.getBoundingClientRect())] for (e in path.matcher(this.focusedFrame.document))] + .filter(function (e) e[1] > FUDGE) + .sort(function (a, b) a[1] - b[1]) + + let idx = Math.min((count || 1) - 1, elems.length); + dactyl.assert(idx in elems); + + let elem = elems[idx][0]; + elem.scrollIntoView(true); + + let sel = elem.ownerDocument.defaultView.getSelection(); + sel.removeAllRanges(); + sel.addRange(RangeFind.endpoint(RangeFind.nodeRange(elem), true)); + }, + // TODO: allow callback for filtering out unwanted frames? User defined? /** * Shifts the focus to another frame within the buffer. Each buffer @@ -1742,6 +1773,26 @@ var Buffer = Module("buffer", { function (args) { buffer.shiftFrameFocus(-Math.max(args.count, 1)); }, { count: true }); + mappings.add([modes.NORMAL], ["["], + "Jump to the previous element as defined by 'jumptags'", + function (args) { buffer.findJump(args.arg, args.count, true); }, + { arg: true, count: true }); + + mappings.add([modes.NORMAL], ["]"], + "Jump to the next element as defined by 'jumptags'", + function (args) { buffer.findJump(args.arg, args.count, false); }, + { arg: true, count: true }); + + mappings.add([modes.NORMAL], ["{"], + "Jump to the previous paragraph", + function (args) { buffer.findJump("p", args.count, true); }, + { count: true }); + + mappings.add([modes.NORMAL], ["}"], + "Jump to the next paragraph", + function (args) { buffer.findJump("p", args.count, false); }, + { count: true }); + mappings.add([modes.NORMAL], ["]]", ""], "Follow the link labeled 'next' or '>' if it exists", function (args) { @@ -1937,6 +1988,23 @@ var Buffer = Module("buffer", { validator: function (value) RegExp(value) }); + options.add(["jumptags", "jt"], + "XPath or CSS selector strings of jumpable elements for extended hint modes", + "stringmap", { + "p": "p,table,ul,ol,blockquote", + "h": "h1,h2,h3,h4,h5,h6" + }, + { + keepQuotes: true, + setter: function (vals) { + for (let [k, v] in Iterator(vals)) + vals[k] = update(new String(v), { matcher: util.compileMatcher(Option.splitList(v)) }); + return vals; + }, + validator: function (value) util.validateMatcher.call(this, value) + && Object.keys(value).every(function (v) v.length == 1) + }); + options.add(["nextpattern"], "Patterns to use when guessing the next page in a document sequence", "regexplist", UTF8("'\\bnext\\b',^>$,^(>>|»)$,^(>|»),(>|»)$,'\\bmore\\b'"), diff --git a/common/content/dactyl.js b/common/content/dactyl.js index 24e58211..30f6c8c5 100644 --- a/common/content/dactyl.js +++ b/common/content/dactyl.js @@ -1016,6 +1016,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), { }; } else if (obj instanceof Option) { + tag = spec = function (name) <>'{name}'; link = function (opt, name) {name}; args = { value: "", values: [] }; } diff --git a/common/locale/en-US/buffer.xml b/common/locale/en-US/buffer.xml index 0f1ba37e..7f514a91 100644 --- a/common/locale/en-US/buffer.xml +++ b/common/locale/en-US/buffer.xml @@ -328,6 +328,39 @@ + + [h [p [ + count[arg + +

Jump to the previous element as defined by jumptags.

+
+
+ + + ]h ]p ] + count]arg + +

Jump to the next element as defined by jumptags.

+
+
+ + + { + count{ + +

Jump to the previous paragraph. Identical to [p.

+
+
+ + + } + count} + +

Jump to the next paragraph. Identical to ]p.

+
+
+ +

Zooming

diff --git a/common/locale/en-US/options.xml b/common/locale/en-US/options.xml index af8eb34b..3f7d40cc 100644 --- a/common/locale/en-US/options.xml +++ b/common/locale/en-US/options.xml @@ -987,6 +987,16 @@ + + 'jt' 'jumptags' + 'jumptags' + &option.jumptags.type; + &option.jumptags.default; + +

XPath or CSS selector strings of jumpable elements for extended hint modes.

+ + + 'lpl' 'loadplugins' 'loadplugins' 'lpl' diff --git a/common/modules/template.jsm b/common/modules/template.jsm index c66b39ec..d81ec595 100644 --- a/common/modules/template.jsm +++ b/common/modules/template.jsm @@ -247,7 +247,7 @@ var Template = Module("Template", { linkifyHelp: function linkifyHelp(str, help) { let re = util.regexp( [/\s]|^) - (?P '[\w-]+' | :(?:[\w-]+!?|!) | (?:._)?<[\w-]+>\w* | [a-zA-Z]_\w+ | \[[\w-]+\] | E\d{3} ) + (?P '[\w-]+' | :(?:[\w-]+!?|!) | (?:._)?<[\w-]+>\w* | \b[a-zA-Z]_(?:\w+|.) | \[[\w-]+\] | E\d{3} ) (?= [[\)!,:;./\s]|$) ]]>, "gx"); return this.highlightSubstrings(str, (function () { diff --git a/common/modules/util.jsm b/common/modules/util.jsm index 7129d620..194f66a0 100644 --- a/common/modules/util.jsm +++ b/common/modules/util.jsm @@ -620,7 +620,8 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), range.selectNode(node); node = range; } - let doc = (node.getRangeAt ? node.getRangeAt(0) : node).startContainer.ownerDocument; + let doc = (node.getRangeAt ? node.getRangeAt(0) : node).startContainer; + doc = doc.ownerDocument || doc; let encoder = services.HtmlEncoder(); encoder.init(doc, "text/unicode", encoder.OutputRaw|encoder.OutputPreformatted); diff --git a/pentadactyl/NEWS b/pentadactyl/NEWS index 848c357d..c8e58fba 100644 --- a/pentadactyl/NEWS +++ b/pentadactyl/NEWS @@ -75,6 +75,7 @@ - Added site-specific mapping groups and related command changes. [b6] - Added 'timeout' and 'timeoutlen' options. [b6] + - Added n_{, n_}, n_[, and n_] mappings. [b7] - Added to execute a builtin mapping. [b6] - Added l and s to aid in the construction of macros. [b6] @@ -185,11 +186,13 @@ - Added 'autocomplete' option for specifying which completion groups should be auto-completed. [b2] - Added 'banghist' option. [b1] + - Added 'cookies', 'cookieaccept', and 'cookielifetime' options. [b3] - Added 'downloadsort' option. [b7] - Replaced 'focuscontent' with 'strictfocus'. [b1] - Made 'strictfocus' a [sitemap]. [b7] - 'complete' now defaults to "slf" but file completion only triggers when the URL begins as above. [b1] + - Added 'jumptags' option. [b7] - Added 's' flag to 'pageinfo' and changed default value. [b7] - Added 'passkeys' option. [b3] - Added 'passunknown' option. [b7] @@ -197,7 +200,6 @@ - Added "passwords" and "venkman" dialogs to :dialog. [b2] - Make 'showmode' a [stringlist] option. [b7] - Added 'wildanchor' option. [b2] - - Added 'cookies', 'cookieaccept', and 'cookielifetime' options. [b3] • Added BookmarkChange, BookmarkRemove autocommands. [b2] • Removed the :source line at the end of files generated by :mkpentadactylrc. [b2] diff --git a/pentadactyl/TODO b/pentadactyl/TODO index 9e11e725..c9d4dae9 100644 --- a/pentadactyl/TODO +++ b/pentadactyl/TODO @@ -31,7 +31,6 @@ FEATURES: 8 all search commands should start searching from the top of the visible viewport 8 / should work as in Vim (i.e., save page positions as well as locations in the history list). -8 jump to the next heading with ]h, next image ]i, previous textbox [t and so on 7 clean up error message codes and document 7 add search capability to MOW 7 describe-key command (prompt for a key and display its binding with documentation) @@ -62,7 +61,6 @@ FEATURES: 5 make a command to search within google search results (http://gadelkareem.com/2007/01/28/using-google-ajax-api-as-an-array/) maybe impossible, needs a per-site key from google -4 } { should jump to the next paragraph of the page 3 A format for 'guitablabel' and 'statusline' 3 add a command-line window (:help cmdline-window in Vim). 3 Splitting Windows with [:sp :vsp ctrl-w,s ctrl-w,v] and closing with [ctrl-w,q], moving with [ctrl-w,w or tab]