Skip to content

Commit

Permalink
[CSS] CSSSelectorList class should have a const_iterator
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=271672
rdar://125373236

Reviewed by Antti Koivisto.

CSSSelectorList is an optimized contiguous memory
representation of a list.
This patch adds a forward const iterator interface to it
to be able to use range based for-loop.

* Source/WebCore/css/CSSSelectorList.cpp:
(WebCore::forEachTagSelector):
(WebCore::forEachSelector):
(WebCore::CSSSelectorList::hasExplicitNestingParent const):
* Source/WebCore/css/CSSSelectorList.h:
(WebCore::CSSSelectorList::const_iterator::operator* const):
(WebCore::CSSSelectorList::const_iterator::operator-> const):
(WebCore::CSSSelectorList::const_iterator::operator!= const):
(WebCore::CSSSelectorList::const_iterator::const_iterator):
(WebCore::CSSSelectorList::const_iterator::operator++):
(WebCore::CSSSelectorList::begin const):
(WebCore::CSSSelectorList::end const):
* Source/WebCore/cssjit/SelectorCompiler.cpp:
(WebCore::SelectorCompiler::addNthChildType):
(WebCore::SelectorCompiler::addPseudoClassType):

Canonical link: https://commits.webkit.org/276697@main
  • Loading branch information
mdubet committed Mar 26, 2024
1 parent 0827d78 commit ade1396
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 12 deletions.
12 changes: 6 additions & 6 deletions Source/WebCore/css/CSSSelectorList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,8 @@ static bool forEachTagSelector(Functor& functor, const CSSSelector* selector)
if (functor(selector))
return true;
if (const CSSSelectorList* selectorList = selector->selectorList()) {
for (const CSSSelector* subSelector = selectorList->first(); subSelector; subSelector = CSSSelectorList::next(subSelector)) {
if (forEachTagSelector(functor, subSelector))
for (const auto& subSelector : *selectorList) {
if (forEachTagSelector(functor, &subSelector))
return true;
}
}
Expand All @@ -143,10 +143,10 @@ static bool forEachTagSelector(Functor& functor, const CSSSelector* selector)
}

template <typename Functor>
static bool forEachSelector(Functor& functor, const CSSSelectorList* selectorList)
static bool forEachSelector(Functor& functor, const CSSSelectorList& selectorList)
{
for (const CSSSelector* selector = selectorList->first(); selector; selector = CSSSelectorList::next(selector)) {
if (forEachTagSelector(functor, selector))
for (const auto& selector : selectorList) {
if (forEachTagSelector(functor, &selector))
return true;
}

Expand All @@ -159,7 +159,7 @@ bool CSSSelectorList::hasExplicitNestingParent() const
return selector->hasExplicitNestingParent();
};

return forEachSelector(functor, this);
return forEachSelector(functor, *this);
}

bool CSSSelectorList::hasOnlyNestingSelector() const
Expand Down
24 changes: 24 additions & 0 deletions Source/WebCore/css/CSSSelectorList.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#pragma once

#include "CSSSelector.h"
#include <iterator>
#include <memory>
#include <wtf/UniqueArray.h>

Expand Down Expand Up @@ -58,6 +59,29 @@ class CSSSelectorList {
return current - m_selectorArray.get();
}

struct const_iterator {
friend class CSSSelectorList;
using value_type = CSSSelector;
using difference_type = std::ptrdiff_t;
using pointer = const CSSSelector*;
using reference = const CSSSelector&;
using iterator_category = std::forward_iterator_tag;
reference operator*() const { return *m_ptr; }
pointer operator->() const { return m_ptr; }
bool operator!=(const const_iterator& other) const { return m_ptr != other.m_ptr; }
const_iterator() = default;
const_iterator(pointer ptr) : m_ptr(ptr) { };
const_iterator& operator++()
{
m_ptr = CSSSelectorList::next(m_ptr);
return *this;
}
private:
pointer m_ptr = nullptr;
};
const_iterator begin() const { return { first() }; };
const_iterator end() const { return { }; }

bool hasExplicitNestingParent() const;
bool hasOnlyNestingSelector() const;

Expand Down
13 changes: 7 additions & 6 deletions Source/WebCore/cssjit/SelectorCompiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -709,14 +709,14 @@ static FunctionType addNthChildType(const CSSSelector& selector, SelectorContext
globalFunctionType = FunctionType::SelectorCheckerWithCheckingContext;

SelectorFragmentList* selectorFragments = nullptr;
for (const CSSSelector* subselector = selectorList->first(); subselector; subselector = CSSSelectorList::next(subselector)) {
for (const auto& subselector : *selectorList) {
if (!selectorFragments) {
nthChildOfSelectorInfo.selectorList.append(SelectorFragmentList());
selectorFragments = &nthChildOfSelectorInfo.selectorList.last();
}

VisitedMode ignoreVisitedMode = VisitedMode::None;
FunctionType functionType = constructFragments(subselector, selectorContext, *selectorFragments, FragmentsLevel::InFunctionalPseudoType, positionInRootFragments, visitedMatchEnabled, ignoreVisitedMode, PseudoElementMatchingBehavior::NeverMatch);
FunctionType functionType = constructFragments(&subselector, selectorContext, *selectorFragments, FragmentsLevel::InFunctionalPseudoType, positionInRootFragments, visitedMatchEnabled, ignoreVisitedMode, PseudoElementMatchingBehavior::NeverMatch);
ASSERT_WITH_MESSAGE(ignoreVisitedMode == VisitedMode::None, ":visited is disabled in the functional pseudo classes");
switch (functionType) {
case FunctionType::SimpleSelectorChecker:
Expand Down Expand Up @@ -1261,14 +1261,14 @@ static inline FunctionType addPseudoClassType(const CSSSelector& selector, Selec

FunctionType functionType = FunctionType::SimpleSelectorChecker;
SelectorFragmentList* selectorFragments = nullptr;
for (const CSSSelector* subselector = selectorList->first(); subselector; subselector = CSSSelectorList::next(subselector)) {
for (const auto& subselector : *selectorList) {
if (!selectorFragments) {
fragment.notFilters.append(SelectorFragmentList());
selectorFragments = &fragment.notFilters.last();
}

VisitedMode ignoreVisitedMode = VisitedMode::None;
FunctionType localFunctionType = constructFragments(subselector, selectorContext, *selectorFragments, FragmentsLevel::InFunctionalPseudoType, positionInRootFragments, visitedMatchEnabled, ignoreVisitedMode, PseudoElementMatchingBehavior::NeverMatch);
FunctionType localFunctionType = constructFragments(&subselector, selectorContext, *selectorFragments, FragmentsLevel::InFunctionalPseudoType, positionInRootFragments, visitedMatchEnabled, ignoreVisitedMode, PseudoElementMatchingBehavior::NeverMatch);
ASSERT_WITH_MESSAGE(ignoreVisitedMode == VisitedMode::None, ":visited is disabled in the functional pseudo classes");

// Since this is not pseudo class filter, CannotMatchAnything implies this filter always passes.
Expand Down Expand Up @@ -1312,16 +1312,17 @@ static inline FunctionType addPseudoClassType(const CSSSelector& selector, Selec
{
SelectorList matchesList;
const CSSSelectorList* selectorList = selector.selectorList();
ASSERT(selectorList);
FunctionType functionType = FunctionType::SimpleSelectorChecker;
SelectorFragmentList* selectorFragments = nullptr;
for (const CSSSelector* subselector = selectorList->first(); subselector; subselector = CSSSelectorList::next(subselector)) {
for (const auto& subselector : *selectorList) {
if (!selectorFragments) {
matchesList.append(SelectorFragmentList());
selectorFragments = &matchesList.last();
}

VisitedMode ignoreVisitedMode = VisitedMode::None;
FunctionType localFunctionType = constructFragments(subselector, selectorContext, *selectorFragments, FragmentsLevel::InFunctionalPseudoType, positionInRootFragments, visitedMatchEnabled, ignoreVisitedMode, pseudoElementMatchingBehavior);
FunctionType localFunctionType = constructFragments(&subselector, selectorContext, *selectorFragments, FragmentsLevel::InFunctionalPseudoType, positionInRootFragments, visitedMatchEnabled, ignoreVisitedMode, pseudoElementMatchingBehavior);
ASSERT_WITH_MESSAGE(ignoreVisitedMode == VisitedMode::None, ":visited is disabled in the functional pseudo classes");

// Since this fragment never matches against the element, don't insert it to matchesList.
Expand Down

0 comments on commit ade1396

Please sign in to comment.