Commit e8b7bce9 authored by Olli Pettay's avatar Olli Pettay
Browse files

Bug 1799354, replaceChildren should fire DOMNodeRemoved when needed (and not...

Bug 1799354, replaceChildren should fire DOMNodeRemoved when needed (and not assert about 'Want to fire DOMNodeRemoved event, but it's not safe'), r=peterv

Differential Revision: https://phabricator.services.mozilla.com/D161682
parent 4aff7080
Loading
Loading
Loading
Loading
+0 −15
Original line number Diff line number Diff line
@@ -2069,21 +2069,6 @@ void FragmentOrElement::SetInnerHTMLInternal(const nsAString& aInnerHTML,
  }
}

void FragmentOrElement::FireNodeRemovedForChildren() {
  Document* doc = OwnerDoc();
  // Optimize the common case
  if (!nsContentUtils::HasMutationListeners(
          doc, NS_EVENT_BITS_MUTATION_NODEREMOVED)) {
    return;
  }

  nsCOMPtr<nsINode> child;
  for (child = GetFirstChild(); child && child->GetParentNode() == this;
       child = child->GetNextSibling()) {
    nsContentUtils::MaybeFireNodeRemoved(child, this);
  }
}

void FragmentOrElement::AddSizeOfExcludingThis(nsWindowSizes& aSizes,
                                               size_t* aNodeSize) const {
  nsIContent::AddSizeOfExcludingThis(aSizes, aNodeSize);
+0 −6
Original line number Diff line number Diff line
@@ -119,12 +119,6 @@ class FragmentOrElement : public nsIContent {
  NS_DECL_CYCLE_COLLECTION_SKIPPABLE_WRAPPERCACHE_CLASS_INHERITED(
      FragmentOrElement, nsIContent)

  /**
   * Fire a DOMNodeRemoved mutation event for all children of this node
   * TODO: Convert this to MOZ_CAN_RUN_SCRIPT (bug 1415230)
   */
  MOZ_CAN_RUN_SCRIPT_BOUNDARY void FireNodeRemovedForChildren();

  static void ClearContentUnbinder();
  static bool CanSkip(nsINode* aNode, bool aRemovingAllowed);
  static bool CanSkipInCC(nsINode* aNode);
+34 −0
Original line number Diff line number Diff line
@@ -2139,12 +2139,31 @@ void nsINode::ReplaceChildren(nsINode* aNode, ErrorResult& aRv) {
      return;
    }
  }
  nsCOMPtr<nsINode> node = aNode;

  // Batch possible DOMSubtreeModified events.
  mozAutoSubtreeModified subtree(OwnerDoc(), nullptr);

  if (nsContentUtils::HasMutationListeners(
          OwnerDoc(), NS_EVENT_BITS_MUTATION_NODEREMOVED)) {
    FireNodeRemovedForChildren();
    if (node) {
      if (node->NodeType() == DOCUMENT_FRAGMENT_NODE) {
        node->FireNodeRemovedForChildren();
      } else if (nsCOMPtr<nsINode> parent = node->GetParentNode()) {
        nsContentUtils::MaybeFireNodeRemoved(node, parent);
      }
    }
  }

  // Needed when used in combination with contenteditable (maybe)
  mozAutoDocUpdate updateBatch(OwnerDoc(), true);

  nsAutoMutationBatch mb(this, true, true);

  // The code above explicitly dispatched DOMNodeRemoved events if needed.
  nsAutoScriptBlockerSuppressNodeRemoved scriptBlocker;

  // Replace all with node within this.
  while (mFirstChild) {
    RemoveChildNode(mFirstChild, true);
@@ -3558,6 +3577,21 @@ void nsINode::RemoveMutationObserver(
  }
}

void nsINode::FireNodeRemovedForChildren() {
  Document* doc = OwnerDoc();
  // Optimize the common case
  if (!nsContentUtils::HasMutationListeners(
          doc, NS_EVENT_BITS_MUTATION_NODEREMOVED)) {
    return;
  }

  nsCOMPtr<nsINode> child;
  for (child = GetFirstChild(); child && child->GetParentNode() == this;
       child = child->GetNextSibling()) {
    nsContentUtils::MaybeFireNodeRemoved(child, this);
  }
}

NS_IMPL_ISUPPORTS(nsNodeWeakReference, nsIWeakReference)

nsNodeWeakReference::nsNodeWeakReference(nsINode* aNode)
+6 −0
Original line number Diff line number Diff line
@@ -1645,6 +1645,12 @@ class nsINode : public mozilla::dom::EventTarget {

  bool UnoptimizableCCNode() const;

  /**
   * Fire a DOMNodeRemoved mutation event for all children of this node
   * TODO: Convert this to MOZ_CAN_RUN_SCRIPT (bug 1415230)
   */
  MOZ_CAN_RUN_SCRIPT_BOUNDARY void FireNodeRemovedForChildren();

 private:
  mozilla::dom::SVGUseElement* DoGetContainingSVGUseShadowHost() const;

+1 −0
Original line number Diff line number Diff line
@@ -271,6 +271,7 @@ skip-if = (os == "android" || headless) # See
support-files =
  bug1739957.sjs
[test_bug1784187.html]
[test_bug1799354.html]
[test_bug5141.html]
[test_bug28293.html]
[test_bug28293.xhtml]
Loading