Skip to content

Commit f82ef2b

Browse files
Merge pull request #1492 from WebPlatformForEmbedded/pgorszkowski/2.38/SpeechSynthesis-Emit-error-event-for-all-cancelled-utterances
[SpeechSynthesis] Emit error event for all cancelled utterances
2 parents 98d6764 + 7f93d70 commit f82ef2b

3 files changed

Lines changed: 20 additions & 5 deletions

File tree

LayoutTests/fast/speechsynthesis/speech-synthesis-cancel-expected.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ Speech started
77
PASS speechSynthesis.pending is true
88
Speech error received because we cancelled and speech should no longer be pending.
99
PASS speechSynthesis.pending is false
10+
Speech error received because we cancelled and speech should no longer be pending.
11+
Speech error received because we cancelled and speech should no longer be pending.
1012
PASS successfullyParsed is true
1113

1214
TEST COMPLETE

LayoutTests/fast/speechsynthesis/speech-synthesis-cancel.html

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,24 @@
2727
u.onerror = function(event) {
2828
debug("Speech error received because we cancelled and speech should no longer be pending.");
2929
shouldBeFalse("speechSynthesis.pending");
30-
finishJSTest();
3130
}
3231

3332
// Queue the first job which will start speaking immediately.
3433
speechSynthesis.speak(u);
3534

3635
// Make a few more jobs, so that when we cancel, it will clear the entire queue.
3736
var u2 = new SpeechSynthesisUtterance("this is a second test");
37+
u2.onerror = function(event) {
38+
debug("Speech error received because we cancelled and speech should no longer be pending.");
39+
}
3840
speechSynthesis.speak(u2);
3941

4042
// Make a few more jobs, so that when we cancel, it will clear the entire queue.
4143
var u3 = new SpeechSynthesisUtterance("this is a third test");
44+
u3.onerror = function(event) {
45+
debug("Speech error received because we cancelled and speech should no longer be pending.");
46+
finishJSTest();
47+
}
4248
speechSynthesis.speak(u3);
4349

4450
// While we have two jobs, speech synthesis should report that it's pending.

Source/WebCore/Modules/speech/SpeechSynthesis.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -162,17 +162,24 @@ void SpeechSynthesis::cancel()
162162
// Remove all the items from the utterance queue.
163163
// Hold on to the current utterance so the platform synthesizer can have a chance to clean up.
164164
RefPtr<SpeechSynthesisUtterance> current = m_currentSpeechUtterance;
165-
m_utteranceQueue.clear();
165+
// Clear m_utteranceQueue before calling cancel to avoid picking up new utterances
166+
// on completion callback
167+
auto utteranceQueue = WTFMove(m_utteranceQueue);
166168
if (m_speechSynthesisClient) {
167169
m_speechSynthesisClient->cancel();
168170
// If we wait for cancel to callback speakingErrorOccurred, then m_currentSpeechUtterance will be null
169171
// and the event won't be processed. Instead we process the error immediately.
170172
speakingErrorOccurred(SpeechSynthesisErrorCode::Canceled);
171173
m_currentSpeechUtterance = nullptr;
172-
} else if (m_platformSpeechSynthesizer) {
174+
} else if (m_platformSpeechSynthesizer)
173175
m_platformSpeechSynthesizer->cancel();
174-
// The platform should have called back immediately and cleared the current utterance.
175-
ASSERT(!m_currentSpeechUtterance);
176+
177+
// Trigger canceled events for queued utterances
178+
while (!utteranceQueue.isEmpty()) {
179+
const auto utterance = utteranceQueue.takeFirst();
180+
// Current utterance is handled in platform cancel()
181+
if (current.get() != utterance.ptr())
182+
utterance.get().errorEventOccurred(eventNames().errorEvent, SpeechSynthesisErrorCode::Canceled);
176183
}
177184
current = nullptr;
178185
}

0 commit comments

Comments
 (0)