Bug 966439 - BroadcastChannel API - patch 5 - bfcache supported, r=smaug
☠☠ backed out by ec13e4c1e1d6 ☠ ☠
authorAndrea Marchesini <amarchesini@mozilla.com>
Wed, 14 Jan 2015 11:50:35 +0000
changeset 250875 2c29a52a03bdeae10f265891b1c26883866063b9
parent 250874 e4b0802a3f061d6748a1d80d013061282ce4acaa
child 250876 b82d1010c6b499971b70cbd8e53533adb1e27685
push id4610
push userjlund@mozilla.com
push dateMon, 30 Mar 2015 18:32:55 +0000
treeherdermozilla-beta@4df54044d9ef [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs966439
milestone38.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 966439 - BroadcastChannel API - patch 5 - bfcache supported, r=smaug
dom/broadcastchannel/BroadcastChannel.cpp
dom/broadcastchannel/BroadcastChannelChild.cpp
dom/broadcastchannel/BroadcastChannelChild.h
--- a/dom/broadcastchannel/BroadcastChannel.cpp
+++ b/dom/broadcastchannel/BroadcastChannel.cpp
@@ -120,16 +120,34 @@ public:
       return true;
     }
 
     GetOrigin(principal, mOrigin, mRv);
     if (NS_WARN_IF(mRv.Failed())) {
       return true;
     }
 
+    // Walk up to our containing page
+    WorkerPrivate* wp = mWorkerPrivate;
+    while (wp->GetParent()) {
+      wp = wp->GetParent();
+    }
+
+    // Window doesn't exist for some kind of workers (eg: SharedWorkers)
+    nsPIDOMWindow* window = wp->GetWindow();
+    if (!window) {
+      return true;
+    }
+
+    nsIDocument* doc = window->GetExtantDoc();
+    // No bfcache when BroadcastChannel is used.
+    if (doc) {
+      doc->DisallowBFCaching();
+    }
+
     return true;
   }
 
 private:
   WorkerPrivate* mWorkerPrivate;
   nsAString& mOrigin;
   PrincipalInfo& mPrincipalInfo;
   ErrorResult& mRv;
@@ -389,16 +407,21 @@ BroadcastChannel::Constructor(const Glob
 
     GetOrigin(principal, origin, aRv);
 
     aRv = PrincipalToPrincipalInfo(principal, &principalInfo);
     if (NS_WARN_IF(aRv.Failed())) {
       return nullptr;
     }
 
+    nsIDocument* doc = window->GetExtantDoc();
+    // No bfcache when BroadcastChannel is used.
+    if (doc) {
+      doc->DisallowBFCaching();
+    }
   } else {
     JSContext* cx = aGlobal.Context();
     workerPrivate = GetWorkerPrivateFromContext(cx);
     MOZ_ASSERT(workerPrivate);
 
     nsRefPtr<InitializeRunnable> runnable =
       new InitializeRunnable(workerPrivate, origin, principalInfo, aRv);
     runnable->Dispatch(cx);
@@ -495,17 +518,17 @@ BroadcastChannel::ActorCreated(ipc::PBac
   }
 
   PBroadcastChannelChild* actor =
     aActor->SendPBroadcastChannelConstructor(mPrincipalInfo, mOrigin, mChannel);
 
   mActor = static_cast<BroadcastChannelChild*>(actor);
   MOZ_ASSERT(mActor);
 
-  mActor->SetEventTarget(this);
+  mActor->SetParent(this);
 
   // Flush pending messages.
   for (uint32_t i = 0; i < mPendingMessages.Length(); ++i) {
     PostMessageInternal(mPendingMessages[i]);
   }
 
   mPendingMessages.Clear();
 
@@ -528,17 +551,17 @@ BroadcastChannel::Shutdown()
 
   if (mWorkerFeature) {
     WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
     workerPrivate->RemoveFeature(workerPrivate->GetJSContext(), mWorkerFeature);
     mWorkerFeature = nullptr;
   }
 
   if (mActor) {
-    mActor->SetEventTarget(nullptr);
+    mActor->SetParent(nullptr);
 
     nsRefPtr<TeardownRunnable> runnable = new TeardownRunnable(mActor);
     NS_DispatchToCurrentThread(runnable);
 
     mActor = nullptr;
   }
 }
 
--- a/dom/broadcastchannel/BroadcastChannelChild.cpp
+++ b/dom/broadcastchannel/BroadcastChannelChild.cpp
@@ -25,34 +25,39 @@ BroadcastChannelChild::BroadcastChannelC
   : mOrigin(aOrigin)
   , mChannel(aChannel)
   , mActorDestroyed(false)
 {
 }
 
 BroadcastChannelChild::~BroadcastChannelChild()
 {
-  MOZ_ASSERT(!mEventTarget);
+  MOZ_ASSERT(!mBC);
 }
 
 bool
 BroadcastChannelChild::RecvNotify(const nsString& aMessage)
 {
+  nsCOMPtr<DOMEventTargetHelper> helper = mBC;
+  nsCOMPtr<EventTarget> eventTarget = do_QueryInterface(helper);
+
   // This object is going to be deleted soon. No notify is required.
-  if (!mEventTarget) {
+  if (!eventTarget) {
+    return true;
+  }
+
+  // CheckInnerWindowCorrectness can be used also without a window when
+  // BroadcastChannel is running in a worker. In this case, it's a NOP.
+  if (NS_FAILED(mBC->CheckInnerWindowCorrectness())) {
     return true;
   }
 
   if (NS_IsMainThread()) {
-    DOMEventTargetHelper* deth =
-      DOMEventTargetHelper::FromSupports(mEventTarget);
-    MOZ_ASSERT(deth);
-
     AutoJSAPI autoJS;
-    if (!autoJS.Init(deth->GetParentObject())) {
+    if (!autoJS.Init(mBC->GetParentObject())) {
       NS_WARNING("Dropping message");
       return true;
     }
 
     Notify(autoJS.cx(), aMessage);
     return true;
   }
 
@@ -80,27 +85,26 @@ BroadcastChannelChild::Notify(JSContext*
   RootedDictionary<MessageEventInit> init(aCx);
   init.mBubbles = false;
   init.mCancelable = false;
   init.mOrigin.Construct(mOrigin);
   init.mData = value;
 
   ErrorResult rv;
   nsRefPtr<MessageEvent> event =
-    MessageEvent::Constructor(mEventTarget, NS_LITERAL_STRING("message"),
-                              init, rv);
+    MessageEvent::Constructor(mBC, NS_LITERAL_STRING("message"), init, rv);
   if (rv.Failed()) {
     NS_WARNING("Failed to create a MessageEvent object.");
     return;
   }
 
   event->SetTrusted(true);
 
   bool status;
-  mEventTarget->DispatchEvent(static_cast<Event*>(event.get()), &status);
+  mBC->DispatchEvent(static_cast<Event*>(event.get()), &status);
 }
 
 void
 BroadcastChannelChild::ActorDestroy(ActorDestroyReason aWhy)
 {
   mActorDestroyed = true;
 }
 
--- a/dom/broadcastchannel/BroadcastChannelChild.h
+++ b/dom/broadcastchannel/BroadcastChannelChild.h
@@ -1,38 +1,37 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_BroadcastChannelChild_h
 #define mozilla_dom_BroadcastChannelChild_h
 
-#include "mozilla/dom/EventTarget.h"
 #include "mozilla/dom/PBroadcastChannelChild.h"
 
 namespace mozilla {
 
 namespace ipc {
 class BackgroundChildImpl;
 }
 
 namespace dom {
 
-class EventTarget;
+class BroadcastChannel;
 
 class BroadcastChannelChild MOZ_FINAL : public PBroadcastChannelChild
 {
   friend class mozilla::ipc::BackgroundChildImpl;
 
 public:
   NS_INLINE_DECL_REFCOUNTING(BroadcastChannelChild)
 
-  void SetEventTarget(EventTarget* aEventTarget)
+  void SetParent(BroadcastChannel* aBC)
   {
-    mEventTarget = aEventTarget;
+    mBC = aBC;
   }
 
   virtual bool RecvNotify(const nsString& aMessage) MOZ_OVERRIDE;
 
   bool IsActorDestroyed() const
   {
     return mActorDestroyed;
   }
@@ -44,17 +43,17 @@ private:
   ~BroadcastChannelChild();
 
   void Notify(JSContext* aCx, const nsString& aMessage);
 
   void ActorDestroy(ActorDestroyReason aWhy);
 
   // This raw pointer is actually the parent object.
   // It's set to null when the parent object is deleted.
-  EventTarget* mEventTarget;
+  BroadcastChannel* mBC;
 
   nsString mOrigin;
   nsString mChannel;
 
   bool mActorDestroyed;
 };
 
 } // dom namespace