mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-30 00:01:50 +00:00
Bug 966439 - BroadcastChannel API - patch 2 - close() method, r=smaug
This commit is contained in:
parent
f36b9e5ced
commit
fd3e403cda
@ -225,6 +225,7 @@ BroadcastChannel::BroadcastChannel(nsPIDOMWindow* aWindow,
|
||||
, mChannel(aChannel)
|
||||
, mIsKeptAlive(false)
|
||||
, mInnerID(0)
|
||||
, mState(StateActive)
|
||||
{
|
||||
// Window can be null in workers
|
||||
}
|
||||
@ -328,7 +329,18 @@ BroadcastChannel::Constructor(const GlobalObject& aGlobal,
|
||||
}
|
||||
|
||||
void
|
||||
BroadcastChannel::PostMessage(const nsAString& aMessage)
|
||||
BroadcastChannel::PostMessage(const nsAString& aMessage, ErrorResult& aRv)
|
||||
{
|
||||
if (mState != StateActive) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
PostMessageInternal(aMessage);
|
||||
}
|
||||
|
||||
void
|
||||
BroadcastChannel::PostMessageInternal(const nsAString& aMessage)
|
||||
{
|
||||
if (mActor) {
|
||||
nsRefPtr<PostMessageRunnable> runnable =
|
||||
@ -344,6 +356,21 @@ BroadcastChannel::PostMessage(const nsAString& aMessage)
|
||||
mPendingMessages.AppendElement(aMessage);
|
||||
}
|
||||
|
||||
void
|
||||
BroadcastChannel::Close()
|
||||
{
|
||||
if (mState != StateActive) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mPendingMessages.IsEmpty()) {
|
||||
Shutdown();
|
||||
} else {
|
||||
MOZ_ASSERT(!mActor);
|
||||
mState = StateClosing;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BroadcastChannel::ActorFailed()
|
||||
{
|
||||
@ -355,6 +382,10 @@ BroadcastChannel::ActorCreated(ipc::PBackgroundChild* aActor)
|
||||
{
|
||||
MOZ_ASSERT(aActor);
|
||||
|
||||
if (mState == StateClosed) {
|
||||
return;
|
||||
}
|
||||
|
||||
PBroadcastChannelChild* actor =
|
||||
aActor->SendPBroadcastChannelConstructor(mPrincipalInfo, mOrigin, mChannel);
|
||||
|
||||
@ -365,15 +396,21 @@ BroadcastChannel::ActorCreated(ipc::PBackgroundChild* aActor)
|
||||
|
||||
// Flush pending messages.
|
||||
for (uint32_t i = 0; i < mPendingMessages.Length(); ++i) {
|
||||
PostMessage(mPendingMessages[i]);
|
||||
PostMessageInternal(mPendingMessages[i]);
|
||||
}
|
||||
|
||||
mPendingMessages.Clear();
|
||||
|
||||
if (mState == StateClosing) {
|
||||
Shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BroadcastChannel::Shutdown()
|
||||
{
|
||||
mState = StateClosed;
|
||||
|
||||
// If shutdown() is called we have to release the reference if we still keep
|
||||
// it.
|
||||
if (mIsKeptAlive) {
|
||||
|
@ -53,7 +53,9 @@ public:
|
||||
aName = mChannel;
|
||||
}
|
||||
|
||||
void PostMessage(const nsAString& aMessage);
|
||||
void PostMessage(const nsAString& aMessage, ErrorResult& aRv);
|
||||
|
||||
void Close();
|
||||
|
||||
EventHandlerNonNull* GetOnmessage();
|
||||
void SetOnmessage(EventHandlerNonNull* aCallback);
|
||||
@ -81,6 +83,8 @@ private:
|
||||
|
||||
~BroadcastChannel();
|
||||
|
||||
void PostMessageInternal(const nsAString& aMessage);
|
||||
|
||||
void UpdateMustKeepAlive();
|
||||
|
||||
nsRefPtr<BroadcastChannelChild> mActor;
|
||||
@ -95,6 +99,12 @@ private:
|
||||
bool mIsKeptAlive;
|
||||
|
||||
uint64_t mInnerID;
|
||||
|
||||
enum {
|
||||
StateActive,
|
||||
StateClosing,
|
||||
StateClosed
|
||||
} mState;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
@ -6,3 +6,4 @@ support-files =
|
||||
[test_broadcastchannel_basic.html]
|
||||
[test_broadcastchannel_self.html]
|
||||
[test_broadcastchannel_worker.html]
|
||||
[test_broadcastchannel_close.html]
|
||||
|
58
dom/broadcastchannel/tests/test_broadcastchannel_close.html
Normal file
58
dom/broadcastchannel/tests/test_broadcastchannel_close.html
Normal file
@ -0,0 +1,58 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for BroadcastChannel</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="content"></div>
|
||||
|
||||
<script type="application/javascript">
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var receiver = new BroadcastChannel('foo');
|
||||
var sequence = [ '2', 'done' ];
|
||||
receiver.onmessage = function(e) {
|
||||
if (!sequence.length) {
|
||||
ok (false, 'No more data is expected');
|
||||
return;
|
||||
}
|
||||
|
||||
var data = sequence.shift();
|
||||
is(e.data, data);
|
||||
|
||||
if (!sequence.length) {
|
||||
SimpleTest.executeSoon(function() {
|
||||
SimpleTest.finish();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
var x = new BroadcastChannel('foo');
|
||||
x.close();
|
||||
try {
|
||||
x.postMessage('1');
|
||||
ok(false, "PostMessage should throw if called after a close().");
|
||||
} catch(e) {
|
||||
ok(true, "PostMessage should throw if called after a close().");
|
||||
}
|
||||
|
||||
var y = new BroadcastChannel('foo');
|
||||
y.postMessage('2');
|
||||
y.close();
|
||||
try {
|
||||
y.postMessage('3');
|
||||
ok(false, "PostMessage should throw if called after a close().");
|
||||
} catch(e) {
|
||||
ok(true, "PostMessage should throw if called after a close().");
|
||||
}
|
||||
|
||||
var z = new BroadcastChannel('foo');
|
||||
z.postMessage('done');
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -12,7 +12,10 @@
|
||||
interface BroadcastChannel : EventTarget {
|
||||
readonly attribute DOMString name;
|
||||
|
||||
[Throws]
|
||||
void postMessage(DOMString message);
|
||||
|
||||
void close();
|
||||
|
||||
attribute EventHandler onmessage;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user