Bug 1352389 -Don't push extra script blocker on stack when setting attributes

Tag #1375
This commit is contained in:
Matt A. Tobin 2020-04-17 05:05:28 -04:00 • committed by Roy Tam
commit 922cbf0217
4 changed files with 27 additions and 12 deletions

View file

@ -2492,7 +2492,8 @@ Element::SetAttr(int32_t aNamespaceID, nsIAtom* aName,
// Hold a script blocker while calling ParseAttribute since that can call // Hold a script blocker while calling ParseAttribute since that can call
// out to id-observers // 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 // Even the value was pre-parsed, we still need to call ParseAttribute because
// it can have side effects. // it can have side effects.
@ -2502,7 +2503,7 @@ Element::SetAttr(int32_t aNamespaceID, nsIAtom* aName,
return SetAttrAndNotify(aNamespaceID, aName, aPrefix, oldValue, return SetAttrAndNotify(aNamespaceID, aName, aPrefix, oldValue,
attrValue, modType, hasListeners, aNotify, attrValue, modType, hasListeners, aNotify,
kCallAfterSetAttr); kCallAfterSetAttr, document, updateBatch);
} }
nsresult nsresult
@ -2539,9 +2540,11 @@ Element::SetParsedAttr(int32_t aNamespaceID, nsIAtom* aName,
nsresult rv = BeforeSetAttr(aNamespaceID, aName, &value, aNotify); nsresult rv = BeforeSetAttr(aNamespaceID, aName, &value, aNotify);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
nsIDocument* document = GetComposedDoc();
mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL, aNotify);
return SetAttrAndNotify(aNamespaceID, aName, aPrefix, oldValue, return SetAttrAndNotify(aNamespaceID, aName, aPrefix, oldValue,
aParsedValue, modType, hasListeners, aNotify, aParsedValue, modType, hasListeners, aNotify,
kCallAfterSetAttr); kCallAfterSetAttr, document, updateBatch);
} }
nsresult nsresult
@ -2553,13 +2556,12 @@ Element::SetAttrAndNotify(int32_t aNamespaceID,
uint8_t aModType, uint8_t aModType,
bool aFireMutation, bool aFireMutation,
bool aNotify, bool aNotify,
bool aCallAfterSetAttr) bool aCallAfterSetAttr,
nsIDocument* aComposedDocument,
const mozAutoDocUpdate&)
{ {
nsresult rv; nsresult rv;
nsIDocument* document = GetComposedDoc();
mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL, aNotify);
nsMutationGuard::DidMutate(); nsMutationGuard::DidMutate();
// Copy aParsedValue for later use since it will be lost when we call // 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 // XXXbz Perhaps we should push up the attribute mapping function
// stuff to Element? // stuff to Element?
if (!IsAttributeMapped(aName) || if (!IsAttributeMapped(aName) ||
!SetMappedAttribute(document, aName, aParsedValue, &rv)) { !SetMappedAttribute(aComposedDocument, aName, aParsedValue, &rv)) {
rv = mAttrsAndChildren.SetAndSwapAttr(aName, aParsedValue); rv = mAttrsAndChildren.SetAndSwapAttr(aName, aParsedValue);
} }
} }
@ -2600,7 +2602,7 @@ Element::SetAttrAndNotify(int32_t aNamespaceID,
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
if (document || HasFlag(NODE_FORCE_XBL_BINDINGS)) { if (aComposedDocument || HasFlag(NODE_FORCE_XBL_BINDINGS)) {
RefPtr<nsXBLBinding> binding = GetXBLBinding(); RefPtr<nsXBLBinding> binding = GetXBLBinding();
if (binding) { if (binding) {
binding->AttributeChanged(aName, aNamespaceID, false, aNotify); binding->AttributeChanged(aName, aNamespaceID, false, aNotify);

View file

@ -41,6 +41,7 @@
#include "Units.h" #include "Units.h"
#include "DOMIntersectionObserver.h" #include "DOMIntersectionObserver.h"
class mozAutoDocUpdate;
class nsIFrame; class nsIFrame;
class nsIDOMMozNamedAttrMap; class nsIDOMMozNamedAttrMap;
class nsIURI; class nsIURI;
@ -1269,6 +1270,7 @@ protected:
* @param aFireMutation should mutation-events be fired? * @param aFireMutation should mutation-events be fired?
* @param aNotify should we notify document-observers? * @param aNotify should we notify document-observers?
* @param aCallAfterSetAttr should we call AfterSetAttr? * @param aCallAfterSetAttr should we call AfterSetAttr?
* @param aComposedDocument The current composed document of the element.
*/ */
nsresult SetAttrAndNotify(int32_t aNamespaceID, nsresult SetAttrAndNotify(int32_t aNamespaceID,
nsIAtom* aName, nsIAtom* aName,
@ -1278,7 +1280,9 @@ protected:
uint8_t aModType, uint8_t aModType,
bool aFireMutation, bool aFireMutation,
bool aNotify, bool aNotify,
bool aCallAfterSetAttr); bool aCallAfterSetAttr,
nsIDocument* aComposedDocument,
const mozAutoDocUpdate& aGuard);
/** /**
* Scroll to a new position using behavior evaluated from CSS and * Scroll to a new position using behavior evaluated from CSS and

View file

@ -5,6 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsStyledElement.h" #include "nsStyledElement.h"
#include "mozAutoDocUpdate.h"
#include "nsGkAtoms.h" #include "nsGkAtoms.h"
#include "nsAttrValue.h" #include "nsAttrValue.h"
#include "nsAttrValueInlines.h" #include "nsAttrValueInlines.h"
@ -88,9 +89,12 @@ nsStyledElement::SetInlineStyleDeclaration(DeclarationBlock* aDeclaration,
static_cast<uint8_t>(nsIDOMMutationEvent::MODIFICATION) : static_cast<uint8_t>(nsIDOMMutationEvent::MODIFICATION) :
static_cast<uint8_t>(nsIDOMMutationEvent::ADDITION); static_cast<uint8_t>(nsIDOMMutationEvent::ADDITION);
nsIDocument* document = GetComposedDoc();
mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL, aNotify);
return SetAttrAndNotify(kNameSpaceID_None, nsGkAtoms::style, nullptr, return SetAttrAndNotify(kNameSpaceID_None, nsGkAtoms::style, nullptr,
oldValue, attrValue, modType, hasListeners, oldValue, attrValue, modType, hasListeners,
aNotify, kDontCallAfterSetAttr); aNotify, kDontCallAfterSetAttr, document,
updateBatch);
} }
DeclarationBlock* DeclarationBlock*

View file

@ -18,6 +18,7 @@
#include "nsIDOMMutationEvent.h" #include "nsIDOMMutationEvent.h"
#include "nsSVGPathGeometryElement.h" #include "nsSVGPathGeometryElement.h"
#include "mozilla/InternalMutationEvent.h" #include "mozilla/InternalMutationEvent.h"
#include "mozAutoDocUpdate.h"
#include "nsError.h" #include "nsError.h"
#include "nsIPresShell.h" #include "nsIPresShell.h"
#include "nsGkAtoms.h" #include "nsGkAtoms.h"
@ -1509,9 +1510,13 @@ nsSVGElement::DidChangeValue(nsIAtom* aName,
uint8_t modType = HasAttr(kNameSpaceID_None, aName) uint8_t modType = HasAttr(kNameSpaceID_None, aName)
? static_cast<uint8_t>(nsIDOMMutationEvent::MODIFICATION) ? static_cast<uint8_t>(nsIDOMMutationEvent::MODIFICATION)
: static_cast<uint8_t>(nsIDOMMutationEvent::ADDITION); : static_cast<uint8_t>(nsIDOMMutationEvent::ADDITION);
nsIDocument* document = GetComposedDoc();
mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL,
kNotifyDocumentObservers);
SetAttrAndNotify(kNameSpaceID_None, aName, nullptr, aEmptyOrOldValue, SetAttrAndNotify(kNameSpaceID_None, aName, nullptr, aEmptyOrOldValue,
aNewValue, modType, hasListeners, kNotifyDocumentObservers, aNewValue, modType, hasListeners, kNotifyDocumentObservers,
kCallAfterSetAttr); kCallAfterSetAttr, document, updateBatch);
} }
void void