mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 933193 part 1. Factor out the id selector fast-path from querySelector(All) so we can reuse it a bit more broadly. r=smaug
This commit is contained in:
parent
fdcb4e1cac
commit
2ff0889188
@ -2319,6 +2319,59 @@ AddScopeElements(TreeMatchContext& aMatchContext,
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
struct SelectorMatchInfo {
|
||||
nsCSSSelectorList* const mSelectorList;
|
||||
TreeMatchContext& mMatchContext;
|
||||
};
|
||||
}
|
||||
|
||||
// Given an id, find elements with that id under aRoot that match aMatchInfo if
|
||||
// any is provided. If no SelectorMatchInfo is provided, just find the ones
|
||||
// with the given id. aRoot must be in the document.
|
||||
template<bool onlyFirstMatch, class T>
|
||||
inline static void
|
||||
FindMatchingElementsWithId(const nsAString& aId, nsINode* aRoot,
|
||||
SelectorMatchInfo* aMatchInfo,
|
||||
T& aList)
|
||||
{
|
||||
MOZ_ASSERT(aRoot->IsInDoc(),
|
||||
"Don't call me if the root is not in the document");
|
||||
MOZ_ASSERT(aRoot->IsElement() || aRoot->IsNodeOfType(nsINode::eDOCUMENT),
|
||||
"The optimization below to check ContentIsDescendantOf only for "
|
||||
"elements depends on aRoot being either an element or a "
|
||||
"document if it's in the document. Note that document fragments "
|
||||
"can't be IsInDoc(), so should never show up here.");
|
||||
|
||||
const nsSmallVoidArray* elements = aRoot->OwnerDoc()->GetAllElementsForId(aId);
|
||||
|
||||
if (!elements) {
|
||||
// Nothing to do; we're done
|
||||
return;
|
||||
}
|
||||
|
||||
// XXXbz: Should we fall back to the tree walk if aRoot is not the
|
||||
// document and |elements| is long, for some value of "long"?
|
||||
for (int32_t i = 0; i < elements->Count(); ++i) {
|
||||
Element *element = static_cast<Element*>(elements->ElementAt(i));
|
||||
if (!aRoot->IsElement() ||
|
||||
(element != aRoot &&
|
||||
nsContentUtils::ContentIsDescendantOf(element, aRoot))) {
|
||||
// We have an element with the right id and it's a strict descendant
|
||||
// of aRoot. Make sure it really matches the selector.
|
||||
if (!aMatchInfo ||
|
||||
nsCSSRuleProcessor::SelectorListMatches(element,
|
||||
aMatchInfo->mMatchContext,
|
||||
aMatchInfo->mSelectorList)) {
|
||||
aList.AppendElement(element);
|
||||
if (onlyFirstMatch) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Actually find elements matching aSelectorList (which must not be
|
||||
// null) and which are descendants of aRoot and put them in aList. If
|
||||
// onlyFirstMatch, then stop once the first one is found.
|
||||
@ -2326,7 +2379,6 @@ template<bool onlyFirstMatch, class Collector, class T>
|
||||
MOZ_ALWAYS_INLINE static nsresult
|
||||
FindMatchingElements(nsINode* aRoot, const nsAString& aSelector, T &aList)
|
||||
{
|
||||
|
||||
nsIDocument* doc = aRoot->OwnerDoc();
|
||||
nsIDocument::SelectorCache& cache = doc->GetSelectorCache();
|
||||
nsCSSSelectorList* selectorList = nullptr;
|
||||
@ -2380,32 +2432,9 @@ FindMatchingElements(nsINode* aRoot, const nsAString& aSelector, T &aList)
|
||||
!selectorList->mNext &&
|
||||
selectorList->mSelectors->mIDList) {
|
||||
nsIAtom* id = selectorList->mSelectors->mIDList->mAtom;
|
||||
const nsSmallVoidArray* elements =
|
||||
doc->GetAllElementsForId(nsDependentAtomString(id));
|
||||
|
||||
// XXXbz: Should we fall back to the tree walk if aRoot is not the
|
||||
// document and |elements| is long, for some value of "long"?
|
||||
if (elements) {
|
||||
for (int32_t i = 0; i < elements->Count(); ++i) {
|
||||
Element *element = static_cast<Element*>(elements->ElementAt(i));
|
||||
if (!aRoot->IsElement() ||
|
||||
(element != aRoot &&
|
||||
nsContentUtils::ContentIsDescendantOf(element, aRoot))) {
|
||||
// We have an element with the right id and it's a strict descendant
|
||||
// of aRoot. Make sure it really matches the selector.
|
||||
if (nsCSSRuleProcessor::SelectorListMatches(element, matchingContext,
|
||||
selectorList)) {
|
||||
aList.AppendElement(element);
|
||||
if (onlyFirstMatch) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// No elements with this id, or none of them are our descendants,
|
||||
// or none of them match. We're done here.
|
||||
SelectorMatchInfo info = { selectorList, matchingContext };
|
||||
FindMatchingElementsWithId<onlyFirstMatch, T>(nsDependentAtomString(id),
|
||||
aRoot, &info, aList);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user