Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Speech JavaScript API: SpeechRecognition should hook up with ActiveDO…
…MObject more

https://bugs.webkit.org/show_bug.cgi?id=89217

Reviewed by Adam Barth.

Source/WebCore:

Previously, the SpeechRecognition was kept alive while waiting for
pending events by making the embedder hold a reference to the object.
We should do this by using ActiveDOMObject's setPendingActivity() instead.

Also, override ActiveDOMObject::stop() to get notified when the user
leaves the page.

Test: fast/speech/scripted/navigate-away.html

* Modules/speech/SpeechRecognition.cpp:
(WebCore::SpeechRecognition::start):
(WebCore::SpeechRecognition::didEnd):
(WebCore::SpeechRecognition::stop):
(WebCore):
* Modules/speech/SpeechRecognition.h:
(SpeechRecognition):

Tools:

Add a method for checking whether the mock speech
recognition was aborted.

Also redo the way the mock posts tasks. Instead of posting them all at once,
maintain an internal queue of task objects, and call postTask() for them
once at the time. This means that for example when the page is navigated
away and abort() is called, that call doesn't end up after a bunch
of previously posted events on the event loop.

* DumpRenderTree/chromium/LayoutTestController.cpp:
(LayoutTestController::LayoutTestController):
(LayoutTestController::wasMockSpeechRecognitionAborted):
* DumpRenderTree/chromium/LayoutTestController.h:
(LayoutTestController):
* DumpRenderTree/chromium/MockWebSpeechRecognizer.cpp:
(WebKit::ClientCallTask::ClientCallTask):
(WebKit::ResultTask::ResultTask):
(WebKit::NoMatchTask::NoMatchTask):
(WebKit::ErrorTask::ErrorTask):
(MockWebSpeechRecognizer::start):
(MockWebSpeechRecognizer::abort):
(MockWebSpeechRecognizer::setError):
(MockWebSpeechRecognizer::MockWebSpeechRecognizer):
(MockWebSpeechRecognizer::startTaskQueue):
(MockWebSpeechRecognizer::StepTask::runIfValid):
* DumpRenderTree/chromium/MockWebSpeechRecognizer.h:
(MockWebSpeechRecognizer::hasBeenAborted):
(MockWebSpeechRecognizer):
(MockWebSpeechRecognizer::taskList):
(Task):
(MockWebSpeechRecognizer::Task::Task):
(MockWebSpeechRecognizer::Task::~Task):
(StepTask):
(MockWebSpeechRecognizer::StepTask::StepTask):

LayoutTests:

Add a layout test to check that speech recognition gets aborted when
navigating away from the page.

* fast/speech/scripted/navigate-away-expected.txt: Added.
* fast/speech/scripted/navigate-away-iframe-expected.txt: Added.
* fast/speech/scripted/navigate-away-iframe.html: Added.
* fast/speech/scripted/navigate-away.html: Added.

Canonical link: https://commits.webkit.org/107503@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@120913 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
zmodem committed Jun 21, 2012
1 parent 8f8117f commit 0c76036
Show file tree
Hide file tree
Showing 13 changed files with 307 additions and 34 deletions.
15 changes: 15 additions & 0 deletions LayoutTests/ChangeLog
@@ -1,3 +1,18 @@
2012-06-20 Hans Wennborg <hans@chromium.org>

Speech JavaScript API: SpeechRecognition should hook up with ActiveDOMObject more
https://bugs.webkit.org/show_bug.cgi?id=89217

Reviewed by Adam Barth.

Add a layout test to check that speech recognition gets aborted when
navigating away from the page.

* fast/speech/scripted/navigate-away-expected.txt: Added.
* fast/speech/scripted/navigate-away-iframe-expected.txt: Added.
* fast/speech/scripted/navigate-away-iframe.html: Added.
* fast/speech/scripted/navigate-away.html: Added.

2012-06-21 Mikhail Pozdnyakov <mikhail.pozdnyakov@intel.com>

[EFL] Gardening after r120847
Expand Down
19 changes: 19 additions & 0 deletions LayoutTests/fast/speech/scripted/navigate-away-expected.txt
@@ -0,0 +1,19 @@
Test behaviour when navigating away from a page using the Speech JavaScript API

On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".


The iframe was loaded.
PASS 'webkitSpeechRecognition' in self is true
PASS webkitSpeechRecognition == null is false
PASS testRunner.wasMockSpeechRecognitionAborted() is false
iframe: Created SpeechRecognition
iframe: calling start()
iframe: onstart
iframe: navigating away
The iframe was navigated away.
PASS testRunner.wasMockSpeechRecognitionAborted() is true
PASS successfullyParsed is true

TEST COMPLETE

@@ -0,0 +1 @@
This file is meant to be used as part of the navigate-away.html test.
48 changes: 48 additions & 0 deletions LayoutTests/fast/speech/scripted/navigate-away-iframe.html
@@ -0,0 +1,48 @@
<!DOCTYPE HTML>
<html>
<head>
<script src="../../js/resources/js-test-pre.js"></script>
</head>
<body id="body">
<script type="text/javascript">

function log(msg) {
parent.postMessage(msg, '*');
}

function setDefaultHandlers(r) {
for (var prop in r) {
if (prop.match('^on')) {
r[prop] = function() {
log('unexpected ' + event.type + ' event!');
}
}
}
}

function run() {
if (window.top == window.self) {
// We are not in an iframe.
document.getElementById('body').innerHTML = 'This file is meant to be used as part of the navigate-away.html test.';
return;
}

window.speechreco = new webkitSpeechRecognition();
log('Created SpeechRecognition');
setDefaultHandlers(speechreco);

speechreco.onstart = function() {
log('onstart');
log('navigating away');
window.location = 'data:text/html,Navigated away.';
};

log('calling start()');
speechreco.start();
}

window.onload = run;
</script>
This iframe creates a speechreco object.
</html>

45 changes: 45 additions & 0 deletions LayoutTests/fast/speech/scripted/navigate-away.html
@@ -0,0 +1,45 @@
<!DOCTYPE HTML>
<html>
<head>
<script src="../../js/resources/js-test-pre.js"></script>
</head>
<body>
<script type="text/javascript">
description('Test behaviour when navigating away from a page using the Speech JavaScript API');

function run() {
// Check availability of constructors.
shouldBeTrue("'webkitSpeechRecognition' in self");
shouldBeFalse("webkitSpeechRecognition == null");

if (window.testRunner)
shouldBeFalse("testRunner.wasMockSpeechRecognitionAborted()");

window.onmessage = function() {
debug('iframe: ' + event.data);
};
}

window.iframeonloadcount = 0;
function iframeonload() {
++iframeonloadcount;

if (iframeonloadcount === 1) {
// The iframe has loaded for the first time.
debug('The iframe was loaded.');
return;
}

debug('The iframe was navigated away.');
if (window.testRunner)
shouldBeTrue("testRunner.wasMockSpeechRecognitionAborted()");
finishJSTest();
}

window.onload = run;
window.jsTestIsAsync = true;
</script>
<script src="../../js/resources/js-test-post.js"></script>
<iframe id="iframe" src="navigate-away-iframe.html" onload="iframeonload()" >
</body>
</html>
24 changes: 24 additions & 0 deletions Source/WebCore/ChangeLog
@@ -1,3 +1,27 @@
2012-06-20 Hans Wennborg <hans@chromium.org>

Speech JavaScript API: SpeechRecognition should hook up with ActiveDOMObject more
https://bugs.webkit.org/show_bug.cgi?id=89217

Reviewed by Adam Barth.

Previously, the SpeechRecognition was kept alive while waiting for
pending events by making the embedder hold a reference to the object.
We should do this by using ActiveDOMObject's setPendingActivity() instead.

Also, override ActiveDOMObject::stop() to get notified when the user
leaves the page.

Test: fast/speech/scripted/navigate-away.html

* Modules/speech/SpeechRecognition.cpp:
(WebCore::SpeechRecognition::start):
(WebCore::SpeechRecognition::didEnd):
(WebCore::SpeechRecognition::stop):
(WebCore):
* Modules/speech/SpeechRecognition.h:
(SpeechRecognition):

2012-06-21 Taiju Tsuiki <tzik@chromium.org>

Web Inspector: Move requestId allocation from FileSystem frontend to backend
Expand Down
12 changes: 11 additions & 1 deletion Source/WebCore/Modules/speech/SpeechRecognition.cpp
Expand Up @@ -46,7 +46,10 @@ PassRefPtr<SpeechRecognition> SpeechRecognition::create(ScriptExecutionContext*

void SpeechRecognition::start()
{
ASSERT(m_controller); // FIXME: Spec should say what to do if we are already started.
ASSERT(m_controller);
// FIXME: Spec should say what to do if we are already started.

setPendingActivity(this);
m_controller->start(this, m_grammars.get(), m_lang, m_continuous, m_maxAlternatives);
}

Expand Down Expand Up @@ -121,6 +124,7 @@ void SpeechRecognition::didStart()
void SpeechRecognition::didEnd()
{
dispatchEvent(Event::create(eventNames().endEvent, /*canBubble=*/false, /*cancelable=*/false));
unsetPendingActivity(this);
}

const AtomicString& SpeechRecognition::interfaceName() const
Expand All @@ -133,6 +137,12 @@ ScriptExecutionContext* SpeechRecognition::scriptExecutionContext() const
return ActiveDOMObject::scriptExecutionContext();
}

void SpeechRecognition::stop()
{
if (hasPendingActivity())
abort();
}

SpeechRecognition::SpeechRecognition(ScriptExecutionContext* context)
: ActiveDOMObject(context, this)
, m_grammars(SpeechGrammarList::create()) // FIXME: The spec is not clear on the default value for the grammars attribute.
Expand Down
9 changes: 5 additions & 4 deletions Source/WebCore/Modules/speech/SpeechRecognition.h
Expand Up @@ -49,15 +49,13 @@ class SpeechRecognition : public RefCounted<SpeechRecognition>, public ActiveDOM
static PassRefPtr<SpeechRecognition> create(ScriptExecutionContext*);
~SpeechRecognition();

// Attributes.
PassRefPtr<SpeechGrammarList> grammars() { return m_grammars; }
void setGrammars(PassRefPtr<SpeechGrammarList> grammars) { m_grammars = grammars; }

String lang() { return m_lang; }
void setLang(const String& lang) { m_lang = lang; }

bool continuous() { return m_continuous; }
void setContinuous(bool continuous) { m_continuous = continuous; }

unsigned long maxAlternatives() { return m_maxAlternatives; }
void setMaxAlternatives(unsigned long maxAlternatives) { m_maxAlternatives = maxAlternatives; }

Expand All @@ -80,10 +78,13 @@ class SpeechRecognition : public RefCounted<SpeechRecognition>, public ActiveDOM
void didStart();
void didEnd();

// EventTarget
// EventTarget.
virtual const AtomicString& interfaceName() const OVERRIDE;
virtual ScriptExecutionContext* scriptExecutionContext() const OVERRIDE;

// ActiveDOMObject.
virtual void stop() OVERRIDE;

using RefCounted<SpeechRecognition>::ref;
using RefCounted<SpeechRecognition>::deref;

Expand Down
42 changes: 42 additions & 0 deletions Tools/ChangeLog
@@ -1,3 +1,45 @@
2012-06-20 Hans Wennborg <hans@chromium.org>

Speech JavaScript API: SpeechRecognition should hook up with ActiveDOMObject more
https://bugs.webkit.org/show_bug.cgi?id=89217

Reviewed by Adam Barth.

Add a method for checking whether the mock speech
recognition was aborted.

Also redo the way the mock posts tasks. Instead of posting them all at once,
maintain an internal queue of task objects, and call postTask() for them
once at the time. This means that for example when the page is navigated
away and abort() is called, that call doesn't end up after a bunch
of previously posted events on the event loop.

* DumpRenderTree/chromium/LayoutTestController.cpp:
(LayoutTestController::LayoutTestController):
(LayoutTestController::wasMockSpeechRecognitionAborted):
* DumpRenderTree/chromium/LayoutTestController.h:
(LayoutTestController):
* DumpRenderTree/chromium/MockWebSpeechRecognizer.cpp:
(WebKit::ClientCallTask::ClientCallTask):
(WebKit::ResultTask::ResultTask):
(WebKit::NoMatchTask::NoMatchTask):
(WebKit::ErrorTask::ErrorTask):
(MockWebSpeechRecognizer::start):
(MockWebSpeechRecognizer::abort):
(MockWebSpeechRecognizer::setError):
(MockWebSpeechRecognizer::MockWebSpeechRecognizer):
(MockWebSpeechRecognizer::startTaskQueue):
(MockWebSpeechRecognizer::StepTask::runIfValid):
* DumpRenderTree/chromium/MockWebSpeechRecognizer.h:
(MockWebSpeechRecognizer::hasBeenAborted):
(MockWebSpeechRecognizer):
(MockWebSpeechRecognizer::taskList):
(Task):
(MockWebSpeechRecognizer::Task::Task):
(MockWebSpeechRecognizer::Task::~Task):
(StepTask):
(MockWebSpeechRecognizer::StepTask::StepTask):

2012-06-21 Mario Sanchez Prada <msanchez@igalia.com>

[GTK] Add support for window.showModalDialog in WebKit2GTK+
Expand Down
8 changes: 8 additions & 0 deletions Tools/DumpRenderTree/chromium/LayoutTestController.cpp
Expand Up @@ -118,6 +118,7 @@ LayoutTestController::LayoutTestController(TestShell* shell)
#if ENABLE(SCRIPTED_SPEECH)
bindMethod("addMockSpeechRecognitionResult", &LayoutTestController::addMockSpeechRecognitionResult);
bindMethod("setMockSpeechRecognitionError", &LayoutTestController::setMockSpeechRecognitionError);
bindMethod("wasMockSpeechRecognitionAborted", &LayoutTestController::wasMockSpeechRecognitionAborted);
#endif
bindMethod("addOriginAccessWhitelistEntry", &LayoutTestController::addOriginAccessWhitelistEntry);
bindMethod("addUserScript", &LayoutTestController::addUserScript);
Expand Down Expand Up @@ -1966,6 +1967,13 @@ void LayoutTestController::setMockSpeechRecognitionError(const CppArgumentList&
if (MockWebSpeechRecognizer* recognizer = m_shell->webViewHost()->mockSpeechRecognizer())
recognizer->setError(arguments[0].toInt32(), cppVariantToWebString(arguments[1]));
}

void LayoutTestController::wasMockSpeechRecognitionAborted(const CppArgumentList&, CppVariant* result)
{
result->set(false);
if (MockWebSpeechRecognizer* recognizer = m_shell->webViewHost()->mockSpeechRecognizer())
result->set(recognizer->wasAborted());
}
#endif

void LayoutTestController::startSpeechInput(const CppArgumentList& arguments, CppVariant* result)
Expand Down
1 change: 1 addition & 0 deletions Tools/DumpRenderTree/chromium/LayoutTestController.h
Expand Up @@ -375,6 +375,7 @@ class LayoutTestController : public CppBoundClass {
#if ENABLE(SCRIPTED_SPEECH)
void addMockSpeechRecognitionResult(const CppArgumentList&, CppVariant*);
void setMockSpeechRecognitionError(const CppArgumentList&, CppVariant*);
void wasMockSpeechRecognitionAborted(const CppArgumentList&, CppVariant*);
#endif
void startSpeechInput(const CppArgumentList&, CppVariant*);

Expand Down

0 comments on commit 0c76036

Please sign in to comment.