tor-browser

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

commit 6a509e8b2df638b3d2e6a20085dcdd1e17baf52c
parent 38b2bf6eb66ba1d401d211873670ff4c8ae59059
Author: Sandor Molnar <smolnar@mozilla.com>
Date:   Tue, 30 Dec 2025 23:42:24 +0200

Revert "Bug 2007958 - Deal with attributeChangedCallback before init. r=tabbrowser-reviewers,jswinarton,sthompson" for causing Mn failures.

This reverts commit 8e2ce9cb378d9cf2dd174e85dd69b8b149fbf0e6.

Revert "Bug 2007958 - Drive-by simplifications in nsXULPrototypeDocument. r=smaug"

This reverts commit 7435a65e04367e5b24165369fe256735fac148dc.

Revert "Bug 2007958 - Use SetParsedAttr for XUL prototype cache. r=smaug"

This reverts commit d1564869fee9301fce0674f44c01bee6d9be10cd.

Diffstat:
Mbrowser/components/tabbrowser/content/tabs.js | 21++++++++++++---------
Mdom/xul/nsXULElement.cpp | 66+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
Mdom/xul/nsXULElement.h | 7+++++++
Mdom/xul/nsXULPrototypeDocument.cpp | 31++++++++++++++++++++-----------
4 files changed, 98 insertions(+), 27 deletions(-)

diff --git a/browser/components/tabbrowser/content/tabs.js b/browser/components/tabbrowser/content/tabs.js @@ -71,10 +71,6 @@ this.pinnedTabsContainer = document.getElementById( "pinned-tabs-container" ); - this.pinnedTabsContainer.setAttribute( - "orient", - this.getAttribute("orient") - ); // Override arrowscrollbox.js method, since our scrollbox's children are // inherited from the scrollbox binding parent (this). @@ -249,13 +245,20 @@ } attributeChangedCallback(name, oldValue, newValue) { - if (name == "orient") { - // reset this attribute so we don't have incorrect styling for vertical tabs + if (name != "orient") { + return; + } + + if (this.overflowing) { + // reset this value so we don't have incorrect styling for vertical tabs this.removeAttribute("overflow"); - this.#updateTabMinWidth(); - this.#updateTabMinHeight(); - this.pinnedTabsContainer?.setAttribute("orient", newValue); } + + this.#updateTabMinWidth(); + this.#updateTabMinHeight(); + + this.pinnedTabsContainer.setAttribute("orient", newValue); + super.attributeChangedCallback(name, oldValue, newValue); } 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 @@ -204,16 +204,17 @@ nsXULPrototypeDocument::Read(nsIObjectInputStream* aStream) { return NotifyLoadDone(); } -static void GetNodeInfos(nsXULPrototypeElement* aPrototype, - nsTArray<RefPtr<mozilla::dom::NodeInfo>>& aArray) { +static nsresult GetNodeInfos(nsXULPrototypeElement* aPrototype, + nsTArray<RefPtr<mozilla::dom::NodeInfo>>& aArray) { if (aArray.IndexOf(aPrototype->mNodeInfo) == aArray.NoIndex) { aArray.AppendElement(aPrototype->mNodeInfo); } // Search attributes - for (nsXULPrototypeAttribute& attr : aPrototype->mAttributes) { + size_t i; + for (i = 0; i < aPrototype->mAttributes.Length(); ++i) { RefPtr<mozilla::dom::NodeInfo> ni; - nsAttrName* name = &attr.mName; + nsAttrName* name = &aPrototype->mAttributes[i].mName; if (name->IsAtom()) { ni = aPrototype->mNodeInfo->NodeInfoManager()->GetNodeInfo( name->Atom(), nullptr, kNameSpaceID_None, nsINode::ATTRIBUTE_NODE); @@ -227,11 +228,16 @@ static void GetNodeInfos(nsXULPrototypeElement* aPrototype, } // Search children - for (nsXULPrototypeNode* child : aPrototype->mChildren) { + for (i = 0; i < aPrototype->mChildren.Length(); ++i) { + nsXULPrototypeNode* child = aPrototype->mChildren[i]; if (child->mType == nsXULPrototypeNode::eType_Element) { - GetNodeInfos(static_cast<nsXULPrototypeElement*>(child), aArray); + nsresult rv = + GetNodeInfos(static_cast<nsXULPrototypeElement*>(child), aArray); + NS_ENSURE_SUCCESS(rv, rv); } } + + return NS_OK; } NS_IMETHODIMP @@ -264,7 +270,10 @@ nsXULPrototypeDocument::Write(nsIObjectOutputStream* aStream) { // mozilla::dom::NodeInfo table nsTArray<RefPtr<mozilla::dom::NodeInfo>> nodeInfos; if (mRoot) { - GetNodeInfos(mRoot, nodeInfos); + tmp = GetNodeInfos(mRoot, nodeInfos); + if (NS_FAILED(tmp)) { + rv = tmp; + } } uint32_t nodeInfoCount = nodeInfos.Length(); @@ -420,6 +429,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 +457,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++; }