diff --git a/common/content/history.js b/common/content/history.js index 36d052f9..cbd62a94 100644 --- a/common/content/history.js +++ b/common/content/history.js @@ -50,10 +50,14 @@ var History = Module("history", { }, get session() { - let sh = window.getWebNavigation().sessionHistory; + let webNav = window.getWebNavigation() + let sh = webNav.sessionHistory; + let obj = []; - obj.index = sh.index; + obj.__defineGetter__("index", function () sh.index); + obj.__defineSetter__("index", function (val) { webNav.gotoIndex(val) }); obj.__iterator__ = function () array.iterItems(this); + for (let i in util.range(0, sh.count)) { obj[i] = update(Object.create(sh.getEntryAtIndex(i, false)), { index: i }); @@ -77,19 +81,46 @@ var History = Module("history", { if (steps == 0) return; - let start = 0; - let end = window.getWebNavigation().sessionHistory.count - 1; - let current = window.getWebNavigation().sessionHistory.index; + let sh = this.session; + dactyl.assert(steps > 0 && sh.index < sh.length - 1 || steps < 0 && sh.index > 0); - if (current == start && steps < 0 || current == end && steps > 0) - dactyl.beep(); - else { - let index = Math.constrain(current + steps, start, end); - try { - window.getWebNavigation().gotoIndex(index); - } - catch (e) {} // We get NS_ERROR_FILE_NOT_FOUND if files in history don't exist + try { + sh.index = Math.constrain(sh.index + steps, 0, sh.length - 1); } + catch (e) {} // We get NS_ERROR_FILE_NOT_FOUND if files in history don't exist + }, + + /** + * Search for the *steps*th next *item* in the history list. + * + * @param {string} item The nebulously defined item to search for. + * @param {number} steps The number of steps to step. + */ + search: function search(item, steps) { + var ctxt; + var filter = function (item) true; + if (item == "domain") + var filter = function (item) { + let res = item.URI.hostPort != ctxt; + ctxt = item.URI.hostPort; + return res; + }; + + let sh = this.session; + let idx; + let sign = steps / Math.abs(steps); + + filter(sh[sh.index]); + for (let i = sh.index + sign; steps && i >= 0 && i < sh.length; i += sign) + if (filter(sh[i])) { + idx = i; + steps -= sign; + } + + util.dump(idx, sh.index, sh.length, steps); + + dactyl.assert(idx != null); + sh.index = idx; }, goToStart: function goToStart() { @@ -283,27 +314,31 @@ var History = Module("history", { completion.addUrlCompleter("h", "History", completion.history); }, mappings: function () { - var myModes = config.browserModes; + function bind() mappings.add.apply(mappings, [config.browserModes].concat(Array.slice(arguments))); - mappings.add(myModes, - [""], "Go to an older position in the jump list", - function (args) { history.stepTo(-Math.max(args.count, 1), true); }, - { count: true }); + bind([""], "Go to an older position in the jump list", + function ({ count }) { history.stepTo(-Math.max(count, 1), true); }, + { count: true }); - mappings.add(myModes, - [""], "Go to a newer position in the jump list", - function (args) { history.stepTo(Math.max(args.count, 1), true); }, - { count: true }); + bind([""], "Go to a newer position in the jump list", + function ({ count }) { history.stepTo(Math.max(count, 1), true); }, + { count: true }); - mappings.add(myModes, - ["H", "", ""], "Go back in the browser history", - function (args) { history.stepTo(-Math.max(args.count, 1)); }, - { count: true }); + bind(["H", "", ""], "Go back in the browser history", + function ({ count }) { history.stepTo(-Math.max(count, 1)); }, + { count: true }); - mappings.add(myModes, - ["L", "", ""], "Go forward in the browser history", - function (args) { history.stepTo(Math.max(args.count, 1)); }, - { count: true }); + bind(["L", "", ""], "Go forward in the browser history", + function ({ count }) { history.stepTo(Math.max(count, 1)); }, + { count: true }); + + bind(["[d"], "Go back to the previous domain in the browser history", + function ({ count }) { history.search("domain", -Math.max(count, 1)) }, + { count: true }); + + bind(["]d"], "Go forward to the next domain in the browser history", + function ({ count }) { history.search("domain", Math.max(count, 1)) }, + { count: true }); } }); diff --git a/common/locale/en-US/browsing.xml b/common/locale/en-US/browsing.xml index 4b249c57..c6382569 100644 --- a/common/locale/en-US/browsing.xml +++ b/common/locale/en-US/browsing.xml @@ -291,6 +291,26 @@ want to bypass &dactyl.appName;'s key handling and pass keys directly to + + + count[d + +

+ Go to the countth previous domain in the history stack. +

+
+
+ + + + count]d + +

+ Go to the countth next domain in the history stack. +

+
+
+ ]]> count<C-o> diff --git a/pentadactyl/NEWS b/pentadactyl/NEWS index b9f8f311..2799d229 100644 --- a/pentadactyl/NEWS +++ b/pentadactyl/NEWS @@ -83,6 +83,7 @@ changes. [b6] - Added 'timeout' and 'timeoutlen' options. [b6] - Added n_{, n_}, n_[, n_], and n_g] mappings. [b7] + - Added n_[d and n_]d. [b8] - Added to execute a builtin mapping. [b6] - Added l and s to aid in the construction of macros. [b6] diff --git a/pentadactyl/TODO b/pentadactyl/TODO index 4a4abe47..05f510e4 100644 --- a/pentadactyl/TODO +++ b/pentadactyl/TODO @@ -21,22 +21,13 @@ FEATURES: 8 add search capability to MOW 8 registers 8 Document Caret and Visual modes. -8 replace global variables with plugin scoped user options -8 adaptive timeout for auto-completions, :set completions can be updated more often than - :open foo 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 Specify all INSERT mode mappings rather than falling through to the host apps - mystery meat mappings. 7 use ctrl-n/p in insert mode for word completion -7 implement QuickFix window based on ItemList -7 [d could go to the last domain in the history stack. So if I browse from - google to another page and click 10 links there, [d would take me back to the google page - opera's fast forward does something like this 7 make an option to disable session saving by default when you close Firefox 7 :grep support (needs location list) 6 :mksession