Bug 1440638 - Render error message for the Simplify Page document. r?mconley draft
authorMatheus Longaray <mlongaray@hp.com>
Wed, 07 Mar 2018 10:35:56 -0300
changeset 767060 fd409d669d41fa6b2b036371ea49a4ac3101bbe8
parent 763903 c7543a3e938d5ec408a7d0c93dc71b40607e7d5b
push id102501
push usermlongaray@hp.com
push dateTue, 13 Mar 2018 21:28:44 +0000
reviewersmconley
bugs1440638
milestone60.0a1
Bug 1440638 - Render error message for the Simplify Page document. r?mconley This patch renders error message for the Simplify Page document when Reader Mode fails to parse original document. This patch also adds a test to reliably produce a readable document that returns a parsing error when run through the readability library. MozReview-Commit-ID: 686mBkU9eVM
toolkit/components/printing/tests/browser.ini
toolkit/components/printing/tests/browser_preview_print_simplify_non_article.js
toolkit/components/printing/tests/simplifyNonArticleSample.html
toolkit/content/browser-content.js
--- a/toolkit/components/printing/tests/browser.ini
+++ b/toolkit/components/printing/tests/browser.ini
@@ -1,10 +1,15 @@
 [browser_page_change_print_original.js]
 support-files =
   file_page_change_print_original_1.html
   file_page_change_print_original_2.html
 skip-if = os == "mac"
 
+[browser_preview_print_simplify_non_article.js]
+support-files =
+    simplifyNonArticleSample.html
+skip-if = os == "mac"
+
 [browser_preview_switch_print_selected.js]
 support-files =
     simplifyArticleSample.html
 skip-if = os == "mac"
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/toolkit/components/printing/tests/browser_preview_print_simplify_non_article.js
@@ -0,0 +1,80 @@
+/**
+ * Verify if we recover from parsing errors of Reader Mode when
+ * Simplify Page checkbox is checked.
+ */
+
+const TEST_PATH = getRootDirectory(gTestPath)
+                    .replace("chrome://mochitests/content", "http://example.com");
+
+add_task(async function set_simplify_and_reader_pref() {
+  // Ensure we have the simplify page preference set
+  await SpecialPowers.pushPrefEnv({
+    set: [
+      ["print.use_simplify_page", true],
+      ["reader.parse-on-load.enabled", true]
+    ]
+  });
+});
+
+add_task(async function switch_print_preview_browsers() {
+  let url = TEST_PATH + "simplifyNonArticleSample.html";
+
+  // Can only do something if we have a print preview UI:
+  if (AppConstants.platform != "win" && AppConstants.platform != "linux") {
+    ok(false, "Can't test if there's no print preview.");
+    return;
+  }
+
+  // Ensure we get a browserStopped for this browser
+  let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, url, false, true);
+
+  // Trick browser to think loaded tab has isArticle property set as true
+  tab.linkedBrowser.isArticle = true;
+
+  // Enter print preview
+  let defaultPPBrowser = PrintPreviewListener.getPrintPreviewBrowser();
+  let defaultPPEntered = BrowserTestUtils
+                          .waitForMessage(defaultPPBrowser.messageManager,
+                                          "Printing:Preview:Entered");
+  document.getElementById("cmd_printPreview").doCommand();
+  await defaultPPEntered;
+
+  // Assert that we are showing the initial content on default print preview browser
+  await ContentTask.spawn(defaultPPBrowser, null, async function() {
+    is(content.document.title, "Non article title", "Should have initial content.");
+  });
+
+  // Here we call simplified mode
+  let simplifiedPPBrowser = PrintPreviewListener.getSimplifiedPrintPreviewBrowser();
+  let simplifiedPPEntered = BrowserTestUtils
+                              .waitForMessage(simplifiedPPBrowser.messageManager,
+                                              "Printing:Preview:Entered");
+  let printPreviewToolbar = document.getElementById("print-preview-toolbar");
+
+  // Wait for simplify page option enablement
+  await BrowserTestUtils.waitForCondition(() => {
+    return !printPreviewToolbar.mSimplifyPageCheckbox.disabled;
+  });
+
+  printPreviewToolbar.mSimplifyPageCheckbox.click();
+  await simplifiedPPEntered;
+
+  // Assert that simplify page option is checked
+  is(printPreviewToolbar.mSimplifyPageCheckbox.checked, true,
+     "Should have simplify page option checked");
+
+  // Assert that we are showing recovery content on simplified print preview browser
+  await ContentTask.spawn(simplifiedPPBrowser, null, async function() {
+    is(content.document.title, "Failed to load article from page", "Should have recovery content.");
+  });
+
+  // Assert that we are selecting simplified print preview browser, and not default one
+  is(gBrowser.selectedTab.linkedBrowser, simplifiedPPBrowser,
+     "Should have simplified print preview browser selected");
+  isnot(gBrowser.selectedTab.linkedBrowser, defaultPPBrowser,
+        "Should not have default print preview browser selected");
+
+  PrintUtils.exitPrintPreview();
+
+  await BrowserTestUtils.removeTab(tab);
+});
new file mode 100644
--- /dev/null
+++ b/toolkit/components/printing/tests/simplifyNonArticleSample.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Non article title</title>
+<meta name="description" content="This is the non-article description." />
+</head>
+<body>
+</body>
+</html>
\ No newline at end of file
--- a/toolkit/content/browser-content.js
+++ b/toolkit/content/browser-content.js
@@ -647,25 +647,22 @@ var Printing = {
         QueryInterface: XPCOMUtils.generateQI([
           Ci.nsIWebProgressListener,
           Ci.nsISupportsWeakReference,
           Ci.nsIObserver,
         ]),
       };
 
       // Here we QI the docShell into a nsIWebProgress passing our web progress listener in.
-      let webProgress =  docShell.QueryInterface(Ci.nsIInterfaceRequestor)
-                                 .getInterface(Ci.nsIWebProgress);
+      let webProgress = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
+                                .getInterface(Ci.nsIWebProgress);
       webProgress.addProgressListener(webProgressListener, Ci.nsIWebProgress.NOTIFY_STATE_REQUEST);
 
       content.document.head.innerHTML = "";
 
-      // Set title of document
-      content.document.title = article.title;
-
       // Set base URI of document. Print preview code will read this value to
       // populate the URL field in print settings so that it doesn't show
       // "about:blank" as its URI.
       let headBaseElement = content.document.createElement("base");
       headBaseElement.setAttribute("href", URL);
       content.document.head.appendChild(headBaseElement);
 
       // Create link element referencing aboutReader.css and append it to head
@@ -684,57 +681,78 @@ var Printing = {
 
       content.document.body.innerHTML = "";
 
       // Create container div (main element) and append it to body
       let containerElement = content.document.createElement("div");
       containerElement.setAttribute("id", "container");
       content.document.body.appendChild(containerElement);
 
-      // Create header div and append it to container
-      let headerElement = content.document.createElement("div");
-      headerElement.setAttribute("id", "reader-header");
-      headerElement.setAttribute("class", "header");
-      containerElement.appendChild(headerElement);
+      // Reader Mode might return null if there's a failure when parsing the document.
+      // We'll render the error message for the Simplify Page document when that happens.
+      if (article) {
+        // Set title of document
+        content.document.title = article.title;
+
+        // Create header div and append it to container
+        let headerElement = content.document.createElement("div");
+        headerElement.setAttribute("id", "reader-header");
+        headerElement.setAttribute("class", "header");
+        containerElement.appendChild(headerElement);
 
-      // Jam the article's title and byline into header div
-      let titleElement = content.document.createElement("h1");
-      titleElement.setAttribute("id", "reader-title");
-      titleElement.textContent = article.title;
-      headerElement.appendChild(titleElement);
+        // Jam the article's title and byline into header div
+        let titleElement = content.document.createElement("h1");
+        titleElement.setAttribute("id", "reader-title");
+        titleElement.textContent = article.title;
+        headerElement.appendChild(titleElement);
 
-      let bylineElement = content.document.createElement("div");
-      bylineElement.setAttribute("id", "reader-credits");
-      bylineElement.setAttribute("class", "credits");
-      bylineElement.textContent = article.byline;
-      headerElement.appendChild(bylineElement);
+        let bylineElement = content.document.createElement("div");
+        bylineElement.setAttribute("id", "reader-credits");
+        bylineElement.setAttribute("class", "credits");
+        bylineElement.textContent = article.byline;
+        headerElement.appendChild(bylineElement);
 
-      // Display header element
-      headerElement.style.display = "block";
+        // Display header element
+        headerElement.style.display = "block";
 
-      // Create content div and append it to container
-      let contentElement = content.document.createElement("div");
-      contentElement.setAttribute("class", "content");
-      containerElement.appendChild(contentElement);
+        // Create content div and append it to container
+        let contentElement = content.document.createElement("div");
+        contentElement.setAttribute("class", "content");
+        containerElement.appendChild(contentElement);
 
-      // Jam the article's content into content div
-      let readerContent = content.document.createElement("div");
-      readerContent.setAttribute("id", "moz-reader-content");
-      contentElement.appendChild(readerContent);
+        // Jam the article's content into content div
+        let readerContent = content.document.createElement("div");
+        readerContent.setAttribute("id", "moz-reader-content");
+        contentElement.appendChild(readerContent);
+
+        let articleUri = Services.io.newURI(article.url);
+        let parserUtils = Cc["@mozilla.org/parserutils;1"].getService(Ci.nsIParserUtils);
+        let contentFragment = parserUtils.parseFragment(article.content,
+          Ci.nsIParserUtils.SanitizerDropForms | Ci.nsIParserUtils.SanitizerAllowStyle,
+          false, articleUri, readerContent);
+
+        readerContent.appendChild(contentFragment);
 
-      let articleUri = Services.io.newURI(article.url);
-      let parserUtils = Cc["@mozilla.org/parserutils;1"].getService(Ci.nsIParserUtils);
-      let contentFragment = parserUtils.parseFragment(article.content,
-        Ci.nsIParserUtils.SanitizerDropForms | Ci.nsIParserUtils.SanitizerAllowStyle,
-        false, articleUri, readerContent);
+        // Display reader content element
+        readerContent.style.display = "block";
+      } else {
+        let aboutReaderStrings = Services.strings.createBundle("chrome://global/locale/aboutReader.properties");
+        let errorMessage = aboutReaderStrings.GetStringFromName("aboutReader.loadError");
+
+        content.document.title = errorMessage;
 
-      readerContent.appendChild(contentFragment);
+        // Create reader message div and append it to body
+        let readerMessageElement = content.document.createElement("div");
+        readerMessageElement.setAttribute("class", "reader-message");
+        readerMessageElement.textContent = errorMessage;
+        containerElement.appendChild(readerMessageElement);
 
-      // Display reader content element
-      readerContent.style.display = "block";
+        // Display reader message element
+        readerMessageElement.style.display = "block";
+      }
     });
   },
 
   enterPrintPreview(contentWindow, simplifiedMode, changingBrowsers, defaultPrinterName) {
     try {
       let printSettings = this.getPrintSettings(defaultPrinterName);
 
       // If we happen to be on simplified mode, we need to set docURL in order