Bug 1298436 - Don't get caught in an endless loop when narrating last paragraph. r?jaws
MozReview-Commit-ID: 7SMh0MGusgM
--- 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);
});
});