Bug 1298436 - Don't get caught in an endless loop when narrating last paragraph. r?jaws draft
authorEitan Isaacson <eitan@monotonous.org>
Sat, 27 Aug 2016 14:42:51 -0700
changeset 406473 4deb151646f698153c063ae318a855507060ffc1
parent 406450 1a5b53a831e5a6c20de1b081c774feb3ff76756c
child 529666 6eed677fc4217a774c008399c1517380bac4188e
push id27735
push userbmo:eitan@monotonous.org
push dateSat, 27 Aug 2016 21:45:21 +0000
reviewersjaws
bugs1298436
milestone51.0a1
Bug 1298436 - Don't get caught in an endless loop when narrating last paragraph. r?jaws MozReview-Commit-ID: 7SMh0MGusgM
toolkit/components/narrate/Narrator.jsm
toolkit/components/narrate/test/browser_narrate.js
--- a/toolkit/components/narrate/Narrator.jsm
+++ b/toolkit/components/narrate/Narrator.jsm
@@ -139,18 +139,18 @@ Narrator.prototype = {
     win.dispatchEvent(new win.CustomEvent(eventType,
       { detail: Cu.cloneInto(detail, win.document) }));
   },
 
   _speakInner: function() {
     this._win.speechSynthesis.cancel();
     let tw = this._treeWalker;
     let paragraph = tw.currentNode;
-    if (!paragraph) {
-      tw.currentNode = tw.root;
+    if (paragraph == tw.root) {
+      this._sendTestEvent("paragraphsdone", {});
       return Promise.resolve();
     }
 
     let utterance = new this._win.SpeechSynthesisUtterance(
       paragraph.textContent);
     utterance.rate = this._speechOptions.rate;
     if (this._speechOptions.voice) {
       utterance.voice = this._speechOptions.voice;
@@ -188,17 +188,17 @@ Narrator.prototype = {
         if (this._inTest) {
           this._sendTestEvent("paragraphend", {});
         }
 
         if (this._stopped) {
           // User pressed stopped.
           resolve();
         } else {
-          tw.nextNode();
+          tw.currentNode = tw.nextNode() || tw.root;
           this._speakInner().then(resolve, reject);
         }
       });
 
       utterance.addEventListener("error", () => {
         reject("speech synthesis failed");
       });
 
--- a/toolkit/components/narrate/test/browser_narrate.js
+++ b/toolkit/components/narrate/test/browser_narrate.js
@@ -113,16 +113,22 @@ add_task(function* testNarrate() {
     content.scrollBy(0, -10);
     yield promiseEvent;
     ok(NarrateTestUtils.isVisible(popup), "popup stays visible after scroll");
 
     toggle.click();
     ok(!NarrateTestUtils.isVisible(popup), "popup is dismissed while speaking");
     NarrateTestUtils.isStartedState(content, ok);
 
-    promiseEvent = ContentTaskUtils.waitForEvent(content, "paragraphend");
-    $(NarrateTestUtils.STOP).click();
-    yield promiseEvent;
+    // Go forward all the way to the end of the article. We should eventually
+    // stop.
+    do {
+      promiseEvent = Promise.race([
+        ContentTaskUtils.waitForEvent(content, "paragraphstart"),
+        ContentTaskUtils.waitForEvent(content, "paragraphsdone")]);
+      $(NarrateTestUtils.FORWARD).click();
+    } while ((yield promiseEvent).type == "paragraphstart");
+
     yield ContentTaskUtils.waitForCondition(
       () => !$(NarrateTestUtils.STOP), "transitioned to stopped state");
     NarrateTestUtils.isStoppedState(content, ok);
   });
 });