From f07f8aecb8a03d33d0b90d685d85960a29543c75 Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Fri, 17 Apr 2020 05:05:28 -0400 Subject: Bug 1352389 -Don't push extra script blocker on stack when setting attributes Tag #1375 --- dom/base/Element.cpp | 20 +++++++++++--------- dom/base/Element.h | 6 +++++- dom/base/nsStyledElement.cpp | 6 +++++- dom/svg/nsSVGElement.cpp | 7 ++++++- 4 files changed, 27 insertions(+), 12 deletions(-) (limited to 'dom') diff --git a/dom/base/Element.cpp b/dom/base/Element.cpp index 055746885..7c5029e2e 100644 --- a/dom/base/Element.cpp +++ b/dom/base/Element.cpp @@ -2492,7 +2492,8 @@ Element::SetAttr(int32_t aNamespaceID, nsIAtom* aName, // Hold a script blocker while calling ParseAttribute since that can call // out to id-observers - nsAutoScriptBlocker scriptBlocker; + nsIDocument* document = GetComposedDoc(); + mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL, aNotify); // Even the value was pre-parsed, we still need to call ParseAttribute because // it can have side effects. @@ -2502,7 +2503,7 @@ Element::SetAttr(int32_t aNamespaceID, nsIAtom* aName, return SetAttrAndNotify(aNamespaceID, aName, aPrefix, oldValue, attrValue, modType, hasListeners, aNotify, - kCallAfterSetAttr); + kCallAfterSetAttr, document, updateBatch); } nsresult @@ -2539,9 +2540,11 @@ Element::SetParsedAttr(int32_t aNamespaceID, nsIAtom* aName, nsresult rv = BeforeSetAttr(aNamespaceID, aName, &value, aNotify); NS_ENSURE_SUCCESS(rv, rv); + nsIDocument* document = GetComposedDoc(); + mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL, aNotify); return SetAttrAndNotify(aNamespaceID, aName, aPrefix, oldValue, aParsedValue, modType, hasListeners, aNotify, - kCallAfterSetAttr); + kCallAfterSetAttr, document, updateBatch); } nsresult @@ -2553,13 +2556,12 @@ Element::SetAttrAndNotify(int32_t aNamespaceID, uint8_t aModType, bool aFireMutation, bool aNotify, - bool aCallAfterSetAttr) + bool aCallAfterSetAttr, + nsIDocument* aComposedDocument, + const mozAutoDocUpdate&) { nsresult rv; - nsIDocument* document = GetComposedDoc(); - mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL, aNotify); - nsMutationGuard::DidMutate(); // Copy aParsedValue for later use since it will be lost when we call @@ -2581,7 +2583,7 @@ Element::SetAttrAndNotify(int32_t aNamespaceID, // XXXbz Perhaps we should push up the attribute mapping function // stuff to Element? if (!IsAttributeMapped(aName) || - !SetMappedAttribute(document, aName, aParsedValue, &rv)) { + !SetMappedAttribute(aComposedDocument, aName, aParsedValue, &rv)) { rv = mAttrsAndChildren.SetAndSwapAttr(aName, aParsedValue); } } @@ -2600,7 +2602,7 @@ Element::SetAttrAndNotify(int32_t aNamespaceID, NS_ENSURE_SUCCESS(rv, rv); - if (document || HasFlag(NODE_FORCE_XBL_BINDINGS)) { + if (aComposedDocument || HasFlag(NODE_FORCE_XBL_BINDINGS)) { RefPtr binding = GetXBLBinding(); if (binding) { binding->AttributeChanged(aName, aNamespaceID, false, aNotify); diff --git a/dom/base/Element.h b/dom/base/Element.h index aa917bffc..6b55cf8cd 100644 --- a/dom/base/Element.h +++ b/dom/base/Element.h @@ -41,6 +41,7 @@ #include "Units.h" #include "DOMIntersectionObserver.h" +class mozAutoDocUpdate; class nsIFrame; class nsIDOMMozNamedAttrMap; class nsIURI; @@ -1269,6 +1270,7 @@ protected: * @param aFireMutation should mutation-events be fired? * @param aNotify should we notify document-observers? * @param aCallAfterSetAttr should we call AfterSetAttr? + * @param aComposedDocument The current composed document of the element. */ nsresult SetAttrAndNotify(int32_t aNamespaceID, nsIAtom* aName, @@ -1278,7 +1280,9 @@ protected: uint8_t aModType, bool aFireMutation, bool aNotify, - bool aCallAfterSetAttr); + bool aCallAfterSetAttr, + nsIDocument* aComposedDocument, + const mozAutoDocUpdate& aGuard); /** * Scroll to a new position using behavior evaluated from CSS and diff --git a/dom/base/nsStyledElement.cpp b/dom/base/nsStyledElement.cpp index 03d1187ab..cdfa56461 100644 --- a/dom/base/nsStyledElement.cpp +++ b/dom/base/nsStyledElement.cpp @@ -5,6 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsStyledElement.h" +#include "mozAutoDocUpdate.h" #include "nsGkAtoms.h" #include "nsAttrValue.h" #include "nsAttrValueInlines.h" @@ -88,9 +89,12 @@ nsStyledElement::SetInlineStyleDeclaration(DeclarationBlock* aDeclaration, static_cast(nsIDOMMutationEvent::MODIFICATION) : static_cast(nsIDOMMutationEvent::ADDITION); + nsIDocument* document = GetComposedDoc(); + mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL, aNotify); return SetAttrAndNotify(kNameSpaceID_None, nsGkAtoms::style, nullptr, oldValue, attrValue, modType, hasListeners, - aNotify, kDontCallAfterSetAttr); + aNotify, kDontCallAfterSetAttr, document, + updateBatch); } DeclarationBlock* diff --git a/dom/svg/nsSVGElement.cpp b/dom/svg/nsSVGElement.cpp index 9099caaaa..df646fe7d 100644 --- a/dom/svg/nsSVGElement.cpp +++ b/dom/svg/nsSVGElement.cpp @@ -18,6 +18,7 @@ #include "nsIDOMMutationEvent.h" #include "nsSVGPathGeometryElement.h" #include "mozilla/InternalMutationEvent.h" +#include "mozAutoDocUpdate.h" #include "nsError.h" #include "nsIPresShell.h" #include "nsGkAtoms.h" @@ -1509,9 +1510,13 @@ nsSVGElement::DidChangeValue(nsIAtom* aName, uint8_t modType = HasAttr(kNameSpaceID_None, aName) ? static_cast(nsIDOMMutationEvent::MODIFICATION) : static_cast(nsIDOMMutationEvent::ADDITION); + + nsIDocument* document = GetComposedDoc(); + mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL, + kNotifyDocumentObservers); SetAttrAndNotify(kNameSpaceID_None, aName, nullptr, aEmptyOrOldValue, aNewValue, modType, hasListeners, kNotifyDocumentObservers, - kCallAfterSetAttr); + kCallAfterSetAttr, document, updateBatch); } void -- cgit v1.2.3