chromium/third_party/blink/renderer/core/css/parser/css_selector_parser.h

// 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_