// Copyright 2014 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifdef UNSAFE_BUFFERS_BUILD // TODO(crbug.com/351564777): Remove this and convert code to safer constructs. #pragma allow_unsafe_buffers #endif #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_PARSER_CSS_SELECTOR_PARSER_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_PARSER_CSS_SELECTOR_PARSER_H_ #include <memory> #include <optional> #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/css/css_selector.h" #include "third_party/blink/renderer/core/css/parser/css_nesting_type.h" #include "third_party/blink/renderer/core/css/parser/css_parser_token_stream.h" #include "third_party/blink/renderer/core/dom/qualified_name.h" namespace blink { class CSSParserContext; class CSSParserTokenStream; class CSSParserObserver; class CSSSelectorList; class Node; class StyleRule; class StyleSheetContents; // CSSSelectorParser parses a CSS selector (or a comma-separated list of them) // into a set of CSSSelector objects, in the order and format the rest of the // code expects (see CSSSelector for details). After this, the selector array // produced will typically be copied into a StyleRule or a CSSSelectorList, // by means of CSSSelectorList::AdoptSelectorVector(). // // In order to be light on memory allocation, CSSSelectorParser uses a scheme // akin to an arena; as we parse the simple selectors that make up a compound // (and in turn, a full complex selector), they are being pushed onto a // HeapVector<CSSSelector>. Then, the required reorderings will be done // in-place. When we're done parsing, the correct data is pulled out of the // vector (by the caller), whose memory can then be reused with no further // allocations for parsing the next selectors. (When doing so, it is important // to use resize(0) instead of clear(), as clear() deallocates the backing.) // // Sometimes, we may need to parse sub-lists of selectors before we're done // parsing the entire list; e.g. if we have something like div:is(.a, .b):focus // (or for that matter, just :not(.a)). If so, we can still use the same vector; // we just notice how many elements were added by the parent, parse the // sub-list, and then clean up after us when we're done using the vector (the // sub-list is made into a CSSSelectorList with its own heap allocation). In // this aspect, we use it a bit like a stack. ResetVectorAfterScope is a helper // that makes sure we never leave anything we shouldn't, especially in error // situations. class CORE_EXPORT CSSSelectorParser { … }; // If we are in nesting context, semicolons abort selector parsing // (so that e.g. “//color: red; font-size: 10px;” stops at the first // semicolon instead of eating the entire rest of the block -- the // standard chooses to parse pretty much everything except an ident // as a qualified rule and thus a selector). However, at the top level, // due to web-compat reasons, semicolons should _not_ do so, // and instead keep consuming the selector up until the block. // // This function only deals with semicolons, not other things that would // abort selector parsing (such as EOF). static inline bool AbortsNestedSelectorParsing( CSSParserTokenType token_type, bool semicolon_aborts_nested_selector, CSSNestingType nesting_type) { … } } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_PARSER_CSS_SELECTOR_PARSER_H_