Bug 1332956 - stop loading the source if parent node is media element. draft
authorAlastor Wu <alwu@mozilla.com>
Tue, 24 Jan 2017 14:47:08 +0800
changeset 465556 8a53597b19c0dd3f8fd2cfc0b6c8ddf16144a0a7
parent 464873 dd49da50cb91a47bde92ff3fca320760dedc1ede
child 543160 dcdaee6a4b1dfe9dc0ca5cbfcbd5c69a1dfae554
push id42614
push useralwu@mozilla.com
push dateTue, 24 Jan 2017 06:46:11 +0000
bugs1332956
milestone53.0a1
Bug 1332956 - stop loading the source if parent node is media element. According to the spec, if the parent node is media element, we should not load the source. MozReview-Commit-ID: AK3eGDi9VtJ
dom/html/HTMLObjectElement.cpp
dom/html/HTMLObjectElement.h
--- a/dom/html/HTMLObjectElement.cpp
+++ b/dom/html/HTMLObjectElement.cpp
@@ -305,16 +305,17 @@ HTMLObjectElement::SetAttr(int32_t aName
   // 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 &&
+      !IsBlockContentLoading() &&
       aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::data) {
     return LoadObject(aNotify, true);
   }
 
   return NS_OK;
 }
 
 nsresult
@@ -322,24 +323,38 @@ HTMLObjectElement::UnsetAttr(int32_t aNa
                              bool aNotify)
 {
   nsresult rv = nsGenericHTMLFormElement::UnsetAttr(aNameSpaceID,
                                                     aAttribute, aNotify);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // See comment in SetAttr
   if (aNotify && IsInComposedDoc() && mIsDoneAddingChildren &&
+      !IsBlockContentLoading() &&
       aNameSpaceID == kNameSpaceID_None && aAttribute == nsGkAtoms::data) {
     return LoadObject(aNotify, true);
   }
 
   return NS_OK;
 }
 
 bool
+HTMLObjectElement::IsBlockContentLoading() const
+{
+  // 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;
+}
+
+bool
 HTMLObjectElement::IsFocusableForTabIndex()
 {
   nsIDocument* doc = GetComposedDoc();
   if (!doc || doc->HasFlag(NODE_IS_EDITABLE)) {
     return false;
   }
 
   return IsEditableRoot() ||
@@ -538,16 +553,20 @@ void
 HTMLObjectElement::StartObjectLoad(bool aNotify)
 {
   // BindToTree can call us asynchronously, and we may be removed from the tree
   // in the interim
   if (!IsInComposedDoc() || !OwnerDoc()->IsActive()) {
     return;
   }
 
+  if (IsBlockContentLoading()) {
+    return;
+  }
+
   LoadObject(aNotify);
   SetIsNetworkCreated(false);
 }
 
 EventStates
 HTMLObjectElement::IntrinsicState() const
 {
   return nsGenericHTMLFormElement::IntrinsicState() | ObjectState();
--- a/dom/html/HTMLObjectElement.h
+++ b/dom/html/HTMLObjectElement.h
@@ -265,16 +265,17 @@ private:
   }
 
   virtual ~HTMLObjectElement();
 
   virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) override;
 
   static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
                                     nsRuleData* aData);
+  bool IsBlockContentLoading() const;
 
   bool mIsDoneAddingChildren;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_HTMLObjectElement_h