diff --git a/common/content/browser.js b/common/content/browser.js index 10bb482b..2db10105 100644 --- a/common/content/browser.js +++ b/common/content/browser.js @@ -21,12 +21,15 @@ var Browser = Module("browser", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), get siteSpecific() false, set siteSpecific(val) {} }); + + config.tabbrowser.addTabsProgressListener(this.tabsProgressListener); }, destroy: function () { this.cleanupProgressListener(); this.observe.unregister(); this._unoverlay(); + config.tabbrowser.removeTabsProgressListener(this.tabsProgressListener); }, observers: { @@ -108,7 +111,6 @@ var Browser = Module("browser", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), * @property {Object} The document loading progress listener. */ progressListener: { - // XXX: function may later be needed to detect a canceled synchronous openURL() onStateChange: util.wrapCallback(function onStateChange(webProgress, request, flags, status) { const L = Ci.nsIWebProgressListener; @@ -146,7 +148,6 @@ var Browser = Module("browser", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), onProgressChange.superapply(this, arguments); dactyl.applyTriggerObserver("browser.progressChange", arguments); }), - // happens when the users switches tabs onLocationChange: util.wrapCallback(function onLocationChange(webProgress, request, uri) { onLocationChange.superapply(this, arguments); @@ -187,6 +188,17 @@ var Browser = Module("browser", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), setOverLink.superapply(this, arguments); dactyl.triggerObserver("browser.overLink", link); }) + }, + + tabsProgressListener: { + onStateChange: function onStateChange(webProgress, request, flags, status) {}, + onSecurityChange: function onSecurityChange(webProgress, request, state) {}, + onStatusChange: function onStatusChange(webProgress, request, status, message) {}, + onProgressChange: function onProgressChange(webProgress, request, curSelfProgress, maxSelfProgress, curTotalProgress, maxTotalProgress) {}, + + onLocationChange: util.wrapCallback(function onLocationChange(browser) { + Buffer(browser.contentWindow).locationChanged(); + }), } }, { }, { diff --git a/common/modules/buffer.jsm b/common/modules/buffer.jsm index 21f4c56d..51879f3b 100644 --- a/common/modules/buffer.jsm +++ b/common/modules/buffer.jsm @@ -256,6 +256,16 @@ var Buffer = Module("Buffer", { */ get uri() util.newURI(this.win.location.href), + /** + * @property {nsIURI} The current top-level document's URI, sans + * fragment ID. + */ + get pageURI() { + let uri = this.uri; + uri.ref = ""; + return uri; + }, + /** * @property {nsIURI} The current top-level document's URI, sans any * fragment identifier. @@ -702,8 +712,17 @@ var Buffer = Module("Buffer", { util.reportError(e); } + let sane = link => { + let a = [link.href, this.pageURI.spec]; + let b = overlay.getData(link, "link-check"); + return !b + || a[0] == b[0] && a[1] == b[1] + || a[0] != b[0] && a[1] != b[1]; + } + let link = DOM("link[href][rev=canonical], \ link[href][rel=shortlink]", doc) + .filter(sane) .attr("href"); if (link) return hashify(link); @@ -711,6 +730,19 @@ var Buffer = Module("Buffer", { return null; }, + locationChanged: function locationChanged() { + // Store current URL to detect tomfoolery. Might go awry if + // links get updated before `history.pushState`, but better safe + // than whatever. + + DOM("link[href][rev=canonical], \ + link[href][rel=shortlink]", this.doc) + .each(elem => { + overlay.getData(elem, "link-check", + () => [elem.href, this.pageURI.spec]) + }); + }, + /** * Opens the appropriate context menu for *elem*. * @@ -2765,13 +2797,6 @@ Buffer.addPageInfoSection("s", "Security", function (verbose) { } }); -// internal navigation doesn't currently update link[rel='shortlink'] -Buffer.addURIShortener("youtube.com", (uri, doc) => { - let video = array.toObject(uri.query.split("&") - .map(p => p.split("="))).v; - return video ? util.newURI("http://youtu.be/" + video) : null; -}); - // catch(e){ if (!e.stack) e = Error(e); dump(e.fileName+":"+e.lineNumber+": "+e+"\n" + e.stack); } endModule();