diff --git a/dom/base/CustomElementRegistry.cpp b/dom/base/CustomElementRegistry.cpp index 11ba39a67e..bb10f3ca80 100644 --- a/dom/base/CustomElementRegistry.cpp +++ b/dom/base/CustomElementRegistry.cpp @@ -1278,6 +1278,9 @@ CustomElementDefinition::CustomElementDefinition(nsIAtom* aType, mCallbacks(aCallbacks), mDocOrder(aDocOrder) { + for (uint32_t i = 0; i < mObservedAttributes.Length(); ++i) { + mObservedAttributesSet.PutEntry(mObservedAttributes[i]); + } } //----------------------------------------------------- diff --git a/dom/base/CustomElementRegistry.h b/dom/base/CustomElementRegistry.h index 06e5947dbc..53f58b5a9f 100644 --- a/dom/base/CustomElementRegistry.h +++ b/dom/base/CustomElementRegistry.h @@ -16,6 +16,8 @@ #include "mozilla/dom/WebComponentsBinding.h" #include "nsCycleCollectionParticipant.h" #include "nsGenericHTMLElement.h" +#include "nsHashKeys.h" +#include "nsTHashtable.h" #include "nsWrapperCache.h" class nsDocument; @@ -166,6 +168,9 @@ struct CustomElementDefinition // The list of attributes that this custom element observes. nsCOMArray mObservedAttributes; + // Hash set for O(1) lookup of observed attributes. + nsTHashtable mObservedAttributesSet; + // The prototype to use for new custom elements of this type. JS::Heap mPrototype; @@ -189,7 +194,7 @@ struct CustomElementDefinition return false; } - return mObservedAttributes.Contains(aName); + return mObservedAttributesSet.Contains(aName); } private: diff --git a/dom/base/ShadowRoot.cpp b/dom/base/ShadowRoot.cpp index f2ae953a0e..d2da59edbb 100644 --- a/dom/base/ShadowRoot.cpp +++ b/dom/base/ShadowRoot.cpp @@ -136,7 +136,7 @@ ShadowRoot::AddSlot(HTMLSlotElement* aSlot) MOZ_ASSERT(aSlot); // Note that if name attribute missing, the slot is a default slot. - nsAutoString name; + nsAutoString name; aSlot->GetName(name); nsTArray* currentSlots = mSlotMap.LookupOrAdd(name); @@ -162,25 +162,14 @@ ShadowRoot::AddSlot(HTMLSlotElement* aSlot) oldSlot->RemoveAssignedNode(assignedNode); currentSlot->AppendAssignedNode(assignedNode); - - Element* restyleElement; - if (assignedNode->IsElement()) { - restyleElement = assignedNode->AsElement(); - } else { - // This is likely a text node. Use the host instead. - restyleElement = GetHost(); - } - if (restyleElement) { - nsLayoutUtils::PostRestyleEvent( - restyleElement, eRestyle_Subtree, nsChangeHint(0)); - } - doEnqueueSlotChange = true; } if (doEnqueueSlotChange) { oldSlot->EnqueueSlotChangeEvent(); currentSlot->EnqueueSlotChangeEvent(); + nsLayoutUtils::PostRestyleEvent( + GetHost(), eRestyle_Subtree, nsChangeHint(0)); } } else { // Otherwise add appropriate nodes to this slot from the host. @@ -475,7 +464,10 @@ ShadowRoot::MaybeReassignElement(Element* aElement, void ShadowRoot::DistributionChanged() { - // FIXME(emilio): We could be more granular in a bunch of cases. + if (mSlotMap.IsEmpty()) { + return; + } + auto* host = GetHost(); if (!host || !host->IsInComposedDoc()) { return; @@ -551,8 +543,11 @@ ShadowRoot::AttributeChanged(nsIDocument* aDocument, return; } - //XXX optimize this! - shell->DestroyFramesForAndRestyle(aElement); + if (aElement->GetPrimaryFrame()) { + shell->DestroyFramesForAndRestyle(aElement); + } else { + nsLayoutUtils::PostRestyleEvent(aElement, eRestyle_Subtree, nsChangeHint(0)); + } } void @@ -564,7 +559,7 @@ ShadowRoot::ContentAppended(nsIDocument* aDocument, for (nsIContent* content = aFirstNewContent; content; content = content->GetNextSibling()) { - ContentInserted(aDocument, aContainer, aFirstNewContent, aNewIndexInContainer); + ContentInserted(aDocument, aContainer, content, aNewIndexInContainer); } }