Bug 1262184 - Block embed content loading when child of media element; r=bz
authorKyle Machulis <kyle@nonpolynomial.com>
Mon, 11 Apr 2016 10:58:08 -0700
changeset 330978 f95bb4a2a46ddc64770060ce2967e7ba7695fd9f
parent 330977 1085ea32229e7ef6df1a36ef98272fd06d5a4925
child 330979 6fcbec37ca271ac92d10d5603ea8099d30ca9e35
push id6048
push userkmoir@mozilla.com
push dateMon, 06 Jun 2016 19:02:08 +0000
treeherdermozilla-beta@46d72a56c57d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs1262184
milestone48.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 1262184 - Block embed content loading when child of media element; r=bz
dom/html/HTMLObjectElement.h
dom/html/HTMLSharedObjectElement.cpp
dom/html/HTMLSharedObjectElement.h
--- a/dom/html/HTMLObjectElement.h
+++ b/dom/html/HTMLObjectElement.h
@@ -23,16 +23,17 @@ class HTMLObjectElement final : public n
 {
 public:
   explicit HTMLObjectElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
                              FromParser aFromParser = NOT_FROM_PARSER);
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
+  NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLObjectElement, object)
   virtual int32_t TabIndexDefault() override;
 
 #ifdef XP_MACOSX
   // nsIDOMEventTarget
   NS_IMETHOD PostHandleEvent(EventChainPostVisitor& aVisitor) override;
   // Helper methods
   static void OnFocusBlurPlugin(Element* aElement, bool aFocus);
   static void HandleFocusBlurPlugin(Element* aElement, WidgetEvent* aEvent);
--- a/dom/html/HTMLSharedObjectElement.cpp
+++ b/dom/html/HTMLSharedObjectElement.cpp
@@ -18,16 +18,17 @@
 #include "nsIWidget.h"
 #include "nsContentUtils.h"
 #ifdef XP_MACOSX
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/dom/Event.h"
 #include "mozilla/dom/HTMLObjectElement.h"
 #endif
 
+
 NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(SharedObject)
 
 namespace mozilla {
 namespace dom {
 
 HTMLSharedObjectElement::HTMLSharedObjectElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
                                                  FromParser aFromParser)
   : nsGenericHTMLElement(aNodeInfo),
@@ -187,17 +188,18 @@ HTMLSharedObjectElement::SetAttr(int32_t
   // if aNotify is false, we are coming from the parser or some such place;
   // we'll get bound after all the attributes have been set, so we'll do the
   // object load from BindToTree/DoneAddingChildren.
   // Skip the LoadObject call in that case.
   // We also don't want to start loading the object when we're not yet in
   // a document, just in case that the caller wants to set additional
   // attributes before inserting the node into the document.
   if (aNotify && IsInComposedDoc() && mIsDoneAddingChildren &&
-      aNameSpaceID == kNameSpaceID_None && aName == URIAttrName()) {
+      aNameSpaceID == kNameSpaceID_None && aName == URIAttrName()
+      && !BlockEmbedContentLoading()) {
     return LoadObject(aNotify, true);
   }
 
   return NS_OK;
 }
 
 bool
 HTMLSharedObjectElement::IsHTMLFocusable(bool aWithMouse,
@@ -319,17 +321,18 @@ HTMLSharedObjectElement::GetAttributeMap
   return &MapAttributesIntoRule;
 }
 
 void
 HTMLSharedObjectElement::StartObjectLoad(bool aNotify)
 {
   // BindToTree can call us asynchronously, and we may be removed from the tree
   // in the interim
-  if (!IsInComposedDoc() || !OwnerDoc()->IsActive()) {
+  if (!IsInComposedDoc() || !OwnerDoc()->IsActive() ||
+      BlockEmbedContentLoading()) {
     return;
   }
 
   LoadObject(aNotify);
   SetIsNetworkCreated(false);
 }
 
 EventStates
@@ -395,10 +398,27 @@ HTMLSharedObjectElement::GetContentPolic
     // through RequestContext yet.
     return nsIContentPolicy::TYPE_INTERNAL_OBJECT;
   } else {
     MOZ_ASSERT(mNodeInfo->Equals(nsGkAtoms::embed));
     return nsIContentPolicy::TYPE_INTERNAL_EMBED;
   }
 }
 
+bool
+HTMLSharedObjectElement::BlockEmbedContentLoading()
+{
+  // Only check on embed elements
+  if (!IsHTMLElement(nsGkAtoms::embed)) {
+    return false;
+  }
+  // Traverse up the node tree to see if we have any ancestors that may block us
+  // from loading
+  for (nsIContent* parent = GetParent(); parent; parent = parent->GetParent()) {
+    if (parent->IsAnyOfHTMLElements(nsGkAtoms::video, nsGkAtoms::audio)) {
+      return true;
+    }
+  }
+  return false;
+}
+
 } // namespace dom
 } // namespace mozilla
--- a/dom/html/HTMLSharedObjectElement.h
+++ b/dom/html/HTMLSharedObjectElement.h
@@ -215,14 +215,27 @@ private:
 
   virtual void GetItemValueText(DOMString& text) override;
   virtual void SetItemValueText(const nsAString& text) override;
 
   virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) override;
 
   static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
                                     nsRuleData* aData);
+
+  /**
+   * Decides whether we should load embed node content.
+   *
+   * If this is an embed node there are cases in which we should not try to load
+   * the content:
+   *
+   * - If the embed node is the child of a media element
+   *
+   * In these cases, this function will return false, which will cause
+   * us to skip calling LoadObject.
+   */
+  bool BlockEmbedContentLoading();
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_HTMLSharedObjectElement_h