tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 3619619d0ac9f0654ce57e9cd137487f978413f5
parent ddafaa057aca13f8875b3a4b8f33fd4aab7dfea8
Author: Cristina Horotan <chorotan@mozilla.com>
Date:   Fri,  2 Jan 2026 07:11:26 +0200

Revert "Bug 2007958 - Use SetParsedAttr for XUL prototype cache. r=smaug" for causing wpt failures on /custom-elements and /content-security-policy

This reverts commit 6705c65b1100b61e5750d1da21cbd9e35a623e06.

Revert "Bug 2007958 - Don't enqueue attribute change callbacks for aNotify=false changes. r=smaug"

This reverts commit bb9a8fea44ee0ea26f90efaa808e4ea4bc03a9fb.

Diffstat:
Mdom/base/Element.cpp | 4++--
Mdom/xul/nsXULElement.cpp | 66+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
Mdom/xul/nsXULElement.h | 7+++++++
Mdom/xul/nsXULPrototypeDocument.cpp | 8++++----
4 files changed, 72 insertions(+), 13 deletions(-)

diff --git a/dom/base/Element.cpp b/dom/base/Element.cpp @@ -3232,8 +3232,8 @@ nsresult Element::SetAttrAndNotify( } } - if (const CustomElementData* data = GetCustomElementData(); - data && data->mState == CustomElementData::State::eCustom && aNotify) { + const CustomElementData* data = GetCustomElementData(); + if (data && data->mState == CustomElementData::State::eCustom) { CustomElementDefinition* definition = data->GetCustomElementDefinition(); MOZ_ASSERT(definition, "Should have a valid CustomElementDefinition"); diff --git a/dom/xul/nsXULElement.cpp b/dom/xul/nsXULElement.cpp @@ -235,7 +235,26 @@ already_AddRefed<Element> nsXULElement::CreateFromPrototype( } nsXULElement* element = FromNode(baseElement); + + if (aPrototype->mHasIdAttribute) { + element->SetHasID(); + } + if (aPrototype->mHasClassAttribute) { + element->SetMayHaveClass(); + } + if (aPrototype->mHasStyleAttribute) { + element->SetMayHaveStyle(); + } + element->MakeHeavyweight(aPrototype); + + // Check each attribute on the prototype to see if we need to do + // any additional processing and hookup that would otherwise be + // done 'automagically' by SetAttr(). + for (const auto& attribute : aPrototype->mAttributes) { + element->AddListenerForAttributeIfNeeded(attribute.mName); + } + return baseElement.forget(); } @@ -501,6 +520,12 @@ void nsXULElement::AddListenerForAttributeIfNeeded(nsAtom* aLocalName) { } } +void nsXULElement::AddListenerForAttributeIfNeeded(const nsAttrName& aName) { + if (aName.IsAtom()) { + AddListenerForAttributeIfNeeded(aName.Atom()); + } +} + class XULInContentErrorReporter : public Runnable { public: explicit XULInContentErrorReporter(Document& aDocument) @@ -995,12 +1020,37 @@ nsresult nsXULElement::AddPopupListener(nsAtom* aName) { //---------------------------------------------------------------------- nsresult nsXULElement::MakeHeavyweight(nsXULPrototypeElement* aPrototype) { - MOZ_ASSERT(aPrototype); - for (const auto& protoattr : aPrototype->mAttributes) { - nsAttrValue value(protoattr.mValue); - MOZ_TRY(SetParsedAttr( - protoattr.mName.NamespaceID(), protoattr.mName.LocalName(), - protoattr.mName.GetPrefix(), value, /* aNotify = */ false)); + if (!aPrototype) { + return NS_OK; + } + + size_t i; + nsresult rv; + for (i = 0; i < aPrototype->mAttributes.Length(); ++i) { + nsXULPrototypeAttribute* protoattr = &aPrototype->mAttributes[i]; + nsAttrValue attrValue; + + // Style rules need to be cloned. + if (protoattr->mValue.Type() == nsAttrValue::eCSSDeclaration) { + DeclarationBlock* decl = protoattr->mValue.GetCSSDeclarationValue(); + RefPtr<DeclarationBlock> declClone = decl->Clone(); + + nsString stringValue; + protoattr->mValue.ToString(stringValue); + + attrValue.SetTo(declClone.forget(), &stringValue); + } else { + attrValue.SetTo(protoattr->mValue); + } + + bool oldValueSet; + // XXX we might wanna have a SetAndTakeAttr that takes an nsAttrName + if (protoattr->mName.IsAtom()) { + rv = SetAndSwapAttr(protoattr->mName.Atom(), attrValue, &oldValueSet); + } else { + rv = SetAndSwapAttr(protoattr->mName.NodeInfo(), attrValue, &oldValueSet); + } + NS_ENSURE_SUCCESS(rv, rv); } return NS_OK; } @@ -1328,6 +1378,7 @@ nsresult nsXULPrototypeElement::SetAttrAt(uint32_t aPos, } if (mAttributes[aPos].mName.Equals(nsGkAtoms::id) && !aValue.IsEmpty()) { + mHasIdAttribute = true; // Store id as atom. // id="" means that the element has no id. Not that it has // emptystring as id. @@ -1345,11 +1396,13 @@ nsresult nsXULPrototypeElement::SetAttrAt(uint32_t aPos, return NS_OK; } else if (mAttributes[aPos].mName.Equals(nsGkAtoms::_class)) { + mHasClassAttribute = true; // Compute the element's class list mAttributes[aPos].mValue.ParseAtomArray(aValue); return NS_OK; } else if (mAttributes[aPos].mName.Equals(nsGkAtoms::style)) { + mHasStyleAttribute = true; // Parse the element's 'style' attribute // This is basically duplicating what nsINode::NodePrincipal() does @@ -1366,7 +1419,6 @@ nsresult nsXULPrototypeElement::SetAttrAt(uint32_t aPos, aValue, data, eCompatibility_FullStandards, nullptr, StyleCssRuleType::Style); if (declaration) { - declaration->SetImmutable(); mAttributes[aPos].mValue.SetTo(declaration.forget(), &aValue); return NS_OK; diff --git a/dom/xul/nsXULElement.h b/dom/xul/nsXULElement.h @@ -168,6 +168,9 @@ class nsXULPrototypeElement : public nsXULPrototypeNode { explicit nsXULPrototypeElement(mozilla::dom::NodeInfo* aNodeInfo = nullptr) : nsXULPrototypeNode(eType_Element), mNodeInfo(aNodeInfo), + mHasIdAttribute(false), + mHasClassAttribute(false), + mHasStyleAttribute(false), mIsAtom(nullptr) {} private: @@ -199,6 +202,9 @@ class nsXULPrototypeElement : public nsXULPrototypeNode { RefPtr<mozilla::dom::NodeInfo> mNodeInfo; + uint32_t mHasIdAttribute : 1; + uint32_t mHasClassAttribute : 1; + uint32_t mHasStyleAttribute : 1; nsTArray<nsXULPrototypeAttribute> mAttributes; // [OWNER] RefPtr<nsAtom> mIsAtom; }; @@ -518,6 +524,7 @@ class nsXULElement : public nsStyledElement { /** * Add a listener for the specified attribute, if appropriate. */ + void AddListenerForAttributeIfNeeded(const nsAttrName& aName); void AddListenerForAttributeIfNeeded(nsAtom* aLocalName); protected: diff --git a/dom/xul/nsXULPrototypeDocument.cpp b/dom/xul/nsXULPrototypeDocument.cpp @@ -420,6 +420,9 @@ void nsXULPrototypeDocument::SetIsL10nCached(bool aIsCached) { void nsXULPrototypeDocument::RebuildPrototypeFromElement( nsXULPrototypeElement* aPrototype, Element* aElement, bool aDeep) { + aPrototype->mHasIdAttribute = aElement->HasID(); + aPrototype->mHasClassAttribute = aElement->MayHaveClass(); + aPrototype->mHasStyleAttribute = aElement->MayHaveStyle(); NodeInfo* oldNodeInfo = aElement->NodeInfo(); RefPtr<NodeInfo> newNodeInfo = mNodeInfoManager->GetNodeInfo( oldNodeInfo->NameAtom(), oldNodeInfo->GetPrefixAtom(), @@ -445,10 +448,7 @@ void nsXULPrototypeDocument::RebuildPrototypeFromElement( protoAttr->mName.SetTo(newNodeInfo); } protoAttr->mValue.SetTo(*attr.mValue); - if (protoAttr->mValue.Type() == nsAttrValue::eCSSDeclaration) { - // Ensure declarations get copied-on-write if needed. - protoAttr->mValue.GetCSSDeclarationValue()->SetImmutable(); - } + protoAttr++; }