Bug 1262184 - Block embed content loading when child of media element; r=bz a=lizzard
authorKyle Machulis <kyle@nonpolynomial.com>
Mon, 11 Apr 2016 10:58:08 -0700
changeset 323950 51ec91ed78a5cd33e600b82512f5b8357d524254
parent 323949 8298e05ae1bdbdfdba9b14632bf81226d6e38956
child 323951 6e15177d45741c5c4b00c343100d581a9014c723
push id5913
push userjlund@mozilla.com
push dateMon, 25 Apr 2016 16:57:49 +0000
treeherdermozilla-beta@dcaf0a6fa115 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz, lizzard
bugs1262184
milestone47.0a2
Bug 1262184 - Block embed content loading when child of media element; r=bz a=lizzard MozReview-Commit-ID: Dgwpsg9fum7
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