mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-19 16:25:38 +00:00
Bug 966439 - BroadcastChannel API - patch 2 - close() method, r=smaug
This commit is contained in:
parent
65afdf13d8
commit
9a3e22bc9c
@ -219,6 +219,7 @@ BroadcastChannel::BroadcastChannel(nsPIDOMWindow* aWindow,
|
|||||||
, mChannel(aChannel)
|
, mChannel(aChannel)
|
||||||
, mIsKeptAlive(false)
|
, mIsKeptAlive(false)
|
||||||
, mInnerID(0)
|
, mInnerID(0)
|
||||||
|
, mState(StateActive)
|
||||||
{
|
{
|
||||||
// Window can be null in workers
|
// Window can be null in workers
|
||||||
}
|
}
|
||||||
@ -322,7 +323,18 @@ BroadcastChannel::Constructor(const GlobalObject& aGlobal,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
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) {
|
if (mActor) {
|
||||||
nsRefPtr<PostMessageRunnable> runnable =
|
nsRefPtr<PostMessageRunnable> runnable =
|
||||||
@ -338,6 +350,21 @@ BroadcastChannel::PostMessage(const nsAString& aMessage)
|
|||||||
mPendingMessages.AppendElement(aMessage);
|
mPendingMessages.AppendElement(aMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BroadcastChannel::Close()
|
||||||
|
{
|
||||||
|
if (mState != StateActive) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mPendingMessages.IsEmpty()) {
|
||||||
|
Shutdown();
|
||||||
|
} else {
|
||||||
|
MOZ_ASSERT(!mActor);
|
||||||
|
mState = StateClosing;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
BroadcastChannel::ActorFailed()
|
BroadcastChannel::ActorFailed()
|
||||||
{
|
{
|
||||||
@ -349,6 +376,10 @@ BroadcastChannel::ActorCreated(ipc::PBackgroundChild* aActor)
|
|||||||
{
|
{
|
||||||
MOZ_ASSERT(aActor);
|
MOZ_ASSERT(aActor);
|
||||||
|
|
||||||
|
if (mState == StateClosed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
PBroadcastChannelChild* actor =
|
PBroadcastChannelChild* actor =
|
||||||
aActor->SendPBroadcastChannelConstructor(mPrincipalInfo, mOrigin, mChannel);
|
aActor->SendPBroadcastChannelConstructor(mPrincipalInfo, mOrigin, mChannel);
|
||||||
|
|
||||||
@ -359,15 +390,21 @@ BroadcastChannel::ActorCreated(ipc::PBackgroundChild* aActor)
|
|||||||
|
|
||||||
// Flush pending messages.
|
// Flush pending messages.
|
||||||
for (uint32_t i = 0; i < mPendingMessages.Length(); ++i) {
|
for (uint32_t i = 0; i < mPendingMessages.Length(); ++i) {
|
||||||
PostMessage(mPendingMessages[i]);
|
PostMessageInternal(mPendingMessages[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
mPendingMessages.Clear();
|
mPendingMessages.Clear();
|
||||||
|
|
||||||
|
if (mState == StateClosing) {
|
||||||
|
Shutdown();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
BroadcastChannel::Shutdown()
|
BroadcastChannel::Shutdown()
|
||||||
{
|
{
|
||||||
|
mState = StateClosed;
|
||||||
|
|
||||||
// If shutdown() is called we have to release the reference if we still keep
|
// If shutdown() is called we have to release the reference if we still keep
|
||||||
// it.
|
// it.
|
||||||
if (mIsKeptAlive) {
|
if (mIsKeptAlive) {
|
||||||
|
@ -53,7 +53,9 @@ public:
|
|||||||
aName = mChannel;
|
aName = mChannel;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PostMessage(const nsAString& aMessage);
|
void PostMessage(const nsAString& aMessage, ErrorResult& aRv);
|
||||||
|
|
||||||
|
void Close();
|
||||||
|
|
||||||
EventHandlerNonNull* GetOnmessage();
|
EventHandlerNonNull* GetOnmessage();
|
||||||
void SetOnmessage(EventHandlerNonNull* aCallback);
|
void SetOnmessage(EventHandlerNonNull* aCallback);
|
||||||
@ -81,6 +83,8 @@ private:
|
|||||||
|
|
||||||
~BroadcastChannel();
|
~BroadcastChannel();
|
||||||
|
|
||||||
|
void PostMessageInternal(const nsAString& aMessage);
|
||||||
|
|
||||||
void UpdateMustKeepAlive();
|
void UpdateMustKeepAlive();
|
||||||
|
|
||||||
nsRefPtr<BroadcastChannelChild> mActor;
|
nsRefPtr<BroadcastChannelChild> mActor;
|
||||||
@ -95,6 +99,12 @@ private:
|
|||||||
bool mIsKeptAlive;
|
bool mIsKeptAlive;
|
||||||
|
|
||||||
uint64_t mInnerID;
|
uint64_t mInnerID;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
StateActive,
|
||||||
|
StateClosing,
|
||||||
|
StateClosed
|
||||||
|
} mState;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
|
@ -6,3 +6,4 @@ support-files =
|
|||||||
[test_broadcastchannel_basic.html]
|
[test_broadcastchannel_basic.html]
|
||||||
[test_broadcastchannel_self.html]
|
[test_broadcastchannel_self.html]
|
||||||
[test_broadcastchannel_worker.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 {
|
interface BroadcastChannel : EventTarget {
|
||||||
readonly attribute DOMString name;
|
readonly attribute DOMString name;
|
||||||
|
|
||||||
|
[Throws]
|
||||||
void postMessage(DOMString message);
|
void postMessage(DOMString message);
|
||||||
|
|
||||||
|
void close();
|
||||||
|
|
||||||
attribute EventHandler onmessage;
|
attribute EventHandler onmessage;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user