mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-26 00:57:30 +09:00
Issue #1375 - Part 2: customElements.define must upgrade custom element in shadow-including tree order
Based on https://bugzilla.mozilla.org/show_bug.cgi?id=1326028
This commit is contained in:
parent
53e2e5d8d6
commit
6781f5b6c5
1 changed files with 91 additions and 7 deletions
|
|
@ -416,6 +416,95 @@ CustomElementRegistry::EnqueueLifecycleCallback(nsIDocument::ElementCallbackType
|
||||||
reactionsStack->EnqueueCallbackReaction(aCustomElement, Move(callback));
|
reactionsStack->EnqueueCallbackReaction(aCustomElement, Move(callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class CandidateFinder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CandidateFinder(nsTArray<nsWeakPtr>&& aCandidates, nsIDocument* aDoc);
|
||||||
|
nsTArray<nsCOMPtr<Element>> OrderedCandidates();
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool Traverse(Element* aRoot, nsTArray<nsCOMPtr<Element>>& aOrderedElements);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDocument> mDoc;
|
||||||
|
nsInterfaceHashtable<nsPtrHashKey<Element>, Element> mCandidates;
|
||||||
|
};
|
||||||
|
|
||||||
|
CandidateFinder::CandidateFinder(nsTArray<nsWeakPtr>&& aCandidates,
|
||||||
|
nsIDocument* aDoc)
|
||||||
|
: mDoc(aDoc)
|
||||||
|
, mCandidates(aCandidates.Length())
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(mDoc);
|
||||||
|
for (auto& candidate : aCandidates) {
|
||||||
|
nsCOMPtr<Element> elem = do_QueryReferent(candidate);
|
||||||
|
if (!elem) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Element* key = elem.get();
|
||||||
|
mCandidates.Put(key, elem.forget());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nsTArray<nsCOMPtr<Element>>
|
||||||
|
CandidateFinder::OrderedCandidates()
|
||||||
|
{
|
||||||
|
if (mCandidates.Count() == 1) {
|
||||||
|
// Fast path for one candidate.
|
||||||
|
for (auto iter = mCandidates.Iter(); !iter.Done(); iter.Next()) {
|
||||||
|
nsTArray<nsCOMPtr<Element>> rval({ Move(iter.Data()) });
|
||||||
|
iter.Remove();
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nsTArray<nsCOMPtr<Element>> orderedElements(mCandidates.Count());
|
||||||
|
for (Element* child = mDoc->GetFirstElementChild(); child; child = child->GetNextElementSibling()) {
|
||||||
|
if (!Traverse(child->AsElement(), orderedElements)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return orderedElements;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CandidateFinder::Traverse(Element* aRoot, nsTArray<nsCOMPtr<Element>>& aOrderedElements)
|
||||||
|
{
|
||||||
|
nsCOMPtr<Element> elem = mCandidates.Get(aRoot);
|
||||||
|
if (elem) {
|
||||||
|
mCandidates.Remove(aRoot);
|
||||||
|
aOrderedElements.AppendElement(Move(elem));
|
||||||
|
if (mCandidates.Count() == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ShadowRoot* root = aRoot->GetShadowRoot()) {
|
||||||
|
// First iterate the children of the shadow root if aRoot is a shadow host.
|
||||||
|
for (Element* child = root->GetFirstElementChild(); child;
|
||||||
|
child = child->GetNextElementSibling()) {
|
||||||
|
if (!Traverse(child, aOrderedElements)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterate the explicit children of aRoot.
|
||||||
|
for (Element* child = aRoot->GetFirstElementChild(); child;
|
||||||
|
child = child->GetNextElementSibling()) {
|
||||||
|
if (!Traverse(child, aOrderedElements)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CustomElementRegistry::UpgradeCandidates(nsIAtom* aKey,
|
CustomElementRegistry::UpgradeCandidates(nsIAtom* aKey,
|
||||||
CustomElementDefinition* aDefinition,
|
CustomElementDefinition* aDefinition,
|
||||||
|
|
@ -427,18 +516,13 @@ CustomElementRegistry::UpgradeCandidates(nsIAtom* aKey,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Bug 1326028 - Upgrade custom element in shadow-including tree order
|
|
||||||
nsAutoPtr<nsTArray<nsWeakPtr>> candidates;
|
nsAutoPtr<nsTArray<nsWeakPtr>> candidates;
|
||||||
mCandidatesMap.RemoveAndForget(aKey, candidates);
|
mCandidatesMap.RemoveAndForget(aKey, candidates);
|
||||||
if (candidates) {
|
if (candidates) {
|
||||||
CustomElementReactionsStack* reactionsStack =
|
CustomElementReactionsStack* reactionsStack =
|
||||||
docGroup->CustomElementReactionsStack();
|
docGroup->CustomElementReactionsStack();
|
||||||
for (size_t i = 0; i < candidates->Length(); ++i) {
|
CandidateFinder finder(Move(*candidates), mWindow->GetExtantDoc());
|
||||||
nsCOMPtr<Element> elem = do_QueryReferent(candidates->ElementAt(i));
|
for (auto& elem : finder.OrderedCandidates()) {
|
||||||
if (!elem) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
reactionsStack->EnqueueUpgradeReaction(elem, aDefinition);
|
reactionsStack->EnqueueUpgradeReaction(elem, aDefinition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue