Bug 1146666 - fix reader mode button's dealing with history.pushState, r=margaret a=readinglist
authorGijs Kruitbosch <gijskruitbosch@gmail.com>
Wed, 25 Mar 2015 00:33:16 +0000
changeset 248473 ee9b3d01d1c2b5f5477047545b80316d028953e4
parent 248472 5a005b821daee4994d7a1e895dea23066eb79fee
child 248474 e700ba708c291e9b7bded685ad96faffecc1199d
push id7837
push userjwein@mozilla.com
push dateFri, 27 Mar 2015 00:27:16 +0000
treeherdermozilla-aurora@cb0db44ce60e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmargaret, readinglist
bugs1146666
milestone38.0a2
Bug 1146666 - fix reader mode button's dealing with history.pushState, r=margaret a=readinglist
browser/base/content/browser.js
browser/base/content/content.js
toolkit/components/reader/ReaderMode.jsm
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -4538,18 +4538,22 @@ var TabsProgressListener = {
       }, true);
     }
   },
 
   onLocationChange: function (aBrowser, aWebProgress, aRequest, aLocationURI,
                               aFlags) {
     // Filter out location changes caused by anchor navigation
     // or history.push/pop/replaceState.
-    if (aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_SAME_DOCUMENT)
+    if (aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_SAME_DOCUMENT) {
+      // Reader mode actually cares about these:
+      let mm = gBrowser.selectedBrowser.messageManager;
+      mm.sendAsyncMessage("Reader:PushState");
       return;
+    }
 
     // Filter out location changes in sub documents.
     if (!aWebProgress.isTopLevel)
       return;
 
     // Only need to call locationChange if the PopupNotifications object
     // for this window has already been initialized (i.e. its getter no
     // longer exists)
--- a/browser/base/content/content.js
+++ b/browser/base/content/content.js
@@ -484,24 +484,29 @@ let AboutReaderListener = {
   _articlePromise: null,
 
   init: function() {
     addEventListener("AboutReaderContentLoaded", this, false, true);
     addEventListener("DOMContentLoaded", this, false);
     addEventListener("pageshow", this, false);
     addEventListener("pagehide", this, false);
     addMessageListener("Reader:ParseDocument", this);
+    addMessageListener("Reader:PushState", this);
   },
 
   receiveMessage: function(message) {
     switch (message.name) {
       case "Reader:ParseDocument":
         this._articlePromise = ReaderMode.parseDocument(content.document).catch(Cu.reportError);
         content.document.location = "about:reader?url=" + encodeURIComponent(message.data.url);
         break;
+
+      case "Reader:PushState":
+        this.updateReaderButton();
+        break;
     }
   },
 
   get isAboutReader() {
     return content.document.documentURI.startsWith("about:reader");
   },
 
   handleEvent: function(aEvent) {
@@ -525,29 +530,33 @@ let AboutReaderListener = {
 
       case "pagehide":
         sendAsyncMessage("Reader:UpdateReaderButton", { isArticle: false });
         break;
 
       case "pageshow":
         // If a page is loaded from the bfcache, we won't get a "DOMContentLoaded"
         // event, so we need to rely on "pageshow" in this case.
-        if (!aEvent.persisted) {
-          break;
+        if (aEvent.persisted) {
+          this.updateReaderButton();
         }
-        // Fall through.
+        break;
       case "DOMContentLoaded":
-        if (!ReaderMode.isEnabledForParseOnLoad || this.isAboutReader) {
-          return;
-        }
+        this.updateReaderButton();
+        break;
 
-        let isArticle = ReaderMode.isProbablyReaderable(content.document);
-        sendAsyncMessage("Reader:UpdateReaderButton", { isArticle: isArticle });
     }
-  }
+  },
+  updateReaderButton: function() {
+    if (!ReaderMode.isEnabledForParseOnLoad || this.isAboutReader) {
+      return;
+    }
+    let isArticle = ReaderMode.isProbablyReaderable(content.document);
+    sendAsyncMessage("Reader:UpdateReaderButton", { isArticle: isArticle });
+  },
 };
 AboutReaderListener.init();
 
 // An event listener for custom "WebChannelMessageToChrome" events on pages
 addEventListener("WebChannelMessageToChrome", function (e) {
   // if target is window then we want the document principal, otherwise fallback to target itself.
   let principal = e.target.nodePrincipal ? e.target.nodePrincipal : e.target.document.nodePrincipal;
 
--- a/toolkit/components/reader/ReaderMode.jsm
+++ b/toolkit/components/reader/ReaderMode.jsm
@@ -63,17 +63,17 @@ this.ReaderMode = {
 
   /**
    * Decides whether or not a document is reader-able without parsing the whole thing.
    *
    * @param doc A document to parse.
    * @return boolean Whether or not we should show the reader mode button.
    */
   isProbablyReaderable: function(doc) {
-    let uri = Services.io.newURI(doc.documentURI, null, null);
+    let uri = Services.io.newURI(doc.location.href, null, null);
 
     if (!this._shouldCheckUri(uri)) {
       return false;
     }
 
     let REGEXPS = {
       unlikelyCandidates: /combx|comment|community|disqus|extra|foot|header|menu|remark|rss|shoutbox|sidebar|sponsor|ad-break|agegate|pagination|pager|popup|tweet|twitter/i,
       okMaybeItsACandidate: /and|article|body|column|main|shadow/i,