diff --git a/bridge/core/css/css_selector.cc b/bridge/core/css/css_selector.cc index 8dc8d4e2e..1acdc3500 100644 --- a/bridge/core/css/css_selector.cc +++ b/bridge/core/css/css_selector.cc @@ -720,7 +720,7 @@ void CSSSelector::UpdatePseudoPage(const AtomicString& value, const Document* document) { DCHECK_EQ(Match(), kPagePseudoClass); SetValue(value); - PseudoType type = CSSSelectorParser::ParsePseudoType(value.ToStdString(), false, document); + PseudoType type = CSSSelectorParser::ParsePseudoType(value, false, document); if (type != kPseudoFirstPage && type != kPseudoLeftPage && type != kPseudoRightPage) { type = kPseudoUnknown; @@ -735,7 +735,7 @@ void CSSSelector::UpdatePseudoType(const AtomicString& value, DCHECK(Match() == kPseudoClass || Match() == kPseudoElement); AtomicString lower_value = value.LowerASCII(); PseudoType pseudo_type = CSSSelectorParser::ParsePseudoType( - lower_value.ToStdString(), has_arguments, context.GetDocument()); + lower_value, has_arguments, context.GetDocument()); SetPseudoType(pseudo_type); SetValue(pseudo_type == kPseudoStateDeprecatedSyntax ? value : lower_value); diff --git a/bridge/core/css/parser/css_lazy_parsing_test.cc b/bridge/core/css/parser/css_lazy_parsing_test.cc index e05ff9a93..86f1ee0b4 100644 --- a/bridge/core/css/parser/css_lazy_parsing_test.cc +++ b/bridge/core/css/parser/css_lazy_parsing_test.cc @@ -15,7 +15,9 @@ class CSSLazyParsingTest : public testing::Test { public: bool HasParsedProperties(StyleRule* rule) { return rule->HasParsedProperties(); } - StyleRule* RuleAt(StyleSheetContents* sheet, size_t index) { return To(sheet->ChildRules()[index].get()); } + StyleRule* RuleAt(StyleSheetContents* sheet, size_t index) { + return To(sheet->ChildRules()[index].get()); + } protected: std::shared_ptr cached_contents_; diff --git a/bridge/core/css/parser/css_parser_impl.cc b/bridge/core/css/parser/css_parser_impl.cc index fc87aeb54..5d1f2a792 100644 --- a/bridge/core/css/parser/css_parser_impl.cc +++ b/bridge/core/css/parser/css_parser_impl.cc @@ -363,7 +363,6 @@ static CSSParserImpl::AllowedRulesType ComputeNewAllowedRules(CSSParserImpl::All return CSSParserImpl::kRegularRules; } -// TODO:当前进度[ConsumeQualifiedRule] template bool CSSParserImpl::ConsumeRuleList(CSSParserTokenStream& stream, RuleListType rule_list_type, diff --git a/bridge/core/css/parser/css_selector_parser.cc b/bridge/core/css/parser/css_selector_parser.cc index 4ff739242..48f3bf11d 100644 --- a/bridge/core/css/parser/css_selector_parser.cc +++ b/bridge/core/css/parser/css_selector_parser.cc @@ -903,7 +903,7 @@ bool CSSSelectorParser::ConsumePartialComplexSelector(CSSParserTokenStream& stre } // static -CSSSelector::PseudoType CSSSelectorParser::ParsePseudoType(const std::string& name, +CSSSelector::PseudoType CSSSelectorParser::ParsePseudoType(const AtomicString& name, bool has_arguments, const Document* document) { CSSSelector::PseudoType pseudo_type = CSSSelector::NameToPseudoType(name, has_arguments, document); @@ -912,10 +912,10 @@ CSSSelector::PseudoType CSSSelectorParser::ParsePseudoType(const std::string& na return pseudo_type; } - if (name.compare(0, 8, "-webkit-") == 0) { + if (name.StartsWith("-webkit-")) { return CSSSelector::PseudoType::kPseudoWebKitCustomElement; } - if (name.compare(0, 10, "-internal-") == 0) { + if (name.StartsWith("-internal-")) { return CSSSelector::PseudoType::kPseudoBlinkInternalElement; } return CSSSelector::PseudoType::kPseudoUnknown; @@ -949,7 +949,7 @@ PseudoId CSSSelectorParser::ParsePseudoElement(const std::string& selector_strin } CSSSelector::PseudoType pseudo_type = - ParsePseudoType(std::string(selector_name_token.Value()), + ParsePseudoType(AtomicString(selector_name_token.Value()), /*has_arguments=*/false, parent ? &parent->GetDocument() : nullptr); PseudoId pseudo_id = CSSSelector::GetPseudoId(pseudo_type); diff --git a/bridge/core/css/parser/css_selector_parser.h b/bridge/core/css/parser/css_selector_parser.h index bc2323011..4eadd563a 100644 --- a/bridge/core/css/parser/css_selector_parser.h +++ b/bridge/core/css/parser/css_selector_parser.h @@ -58,7 +58,7 @@ class CSSSelectorParser { static bool SupportsComplexSelector(CSSParserTokenStream&, std::shared_ptr); - static CSSSelector::PseudoType ParsePseudoType(const std::string& name, + static CSSSelector::PseudoType ParsePseudoType(const AtomicString& name, bool has_arguments, const Document*); diff --git a/bridge/foundation/atomic_string.h b/bridge/foundation/atomic_string.h index 9c1d29bd5..e7ec5db9c 100644 --- a/bridge/foundation/atomic_string.h +++ b/bridge/foundation/atomic_string.h @@ -64,7 +64,7 @@ class AtomicString { const char* Characters8() const; const char16_t* Characters16() const; - std::string GetString() const { return string_->Characters8(); } + std::string GetString() const { return std::string(string_->Characters8(), string_->length()); } AtomicString RemoveCharacters(CharacterMatchFunctionPtr); @@ -85,6 +85,12 @@ class AtomicString { return string_->Find(match_function, start); } + bool StartsWith( + const std::string_view& prefix, + TextCaseSensitivity case_sensitivity = kTextCaseSensitive) const { + return string_->StartsWith(prefix); + } + inline bool ContainsOnlyLatin1OrEmpty() const { if (empty()) return true; diff --git a/bridge/foundation/string_impl.cc b/bridge/foundation/string_impl.cc index e561a7bf9..0be2ff909 100644 --- a/bridge/foundation/string_impl.cc +++ b/bridge/foundation/string_impl.cc @@ -14,6 +14,25 @@ namespace webf { DEFINE_GLOBAL(StringImpl, g_global_empty); DEFINE_GLOBAL(StringImpl, g_global_empty16_bit); +ALWAYS_INLINE bool Equal(const char* a, const char16_t* b, size_t length) { + for (size_t i = 0; i < length; ++i) { + if (a[i] != b[i]) + return false; + } + return true; +} + +ALWAYS_INLINE bool Equal(const char16_t* a, const char* b, size_t length) { + return Equal(b, a, length); +} + +template +ALWAYS_INLINE bool Equal(const CharType* a, + const CharType* b, + size_t length) { + return std::equal(a, a + length, b); +} + // Callers need the global empty strings to be non-const. StringImpl* StringImpl::empty_ = const_cast(&g_global_empty); StringImpl* StringImpl::empty16_bit_ = @@ -154,6 +173,19 @@ size_t StringImpl::Find(CharacterMatchFunctionPtr match_function, return internal::Find(Characters16(), length_, match_function, start); } +bool StringImpl::StartsWith(char character) const { + return length_ && (*this)[0] == character; +} + +bool StringImpl::StartsWith(const std::string_view& prefix) const { + if (prefix.length() > length()) + return false; + if (Is8Bit()) { + return Equal(Characters8(), prefix.data(), prefix.length()); + } + return Equal(Characters16(), prefix.data(), prefix.length()); +} + std::shared_ptr StringImpl::Substring(size_t start, size_t length) const { if (start >= length_) diff --git a/bridge/foundation/string_impl.h b/bridge/foundation/string_impl.h index 45b4ff579..7085738c2 100644 --- a/bridge/foundation/string_impl.h +++ b/bridge/foundation/string_impl.h @@ -128,10 +128,10 @@ class StringImpl : public std::enable_shared_from_this { static StringImpl* empty_; static StringImpl* empty16_bit_; - FORCE_INLINE static std::shared_ptr empty_shared() { + ALWAYS_INLINE static std::shared_ptr empty_shared() { return std::shared_ptr(empty_, [](StringImpl*) {}); } - FORCE_INLINE static std::shared_ptr empty16_shared() { + ALWAYS_INLINE static std::shared_ptr empty16_shared() { return std::shared_ptr(empty16_bit_, [](StringImpl*) {}); } @@ -209,6 +209,9 @@ class StringImpl : public std::enable_shared_from_this { // size_t Find(base::RepeatingCallback match_callback, // wtf_size_t index = 0) const; + bool StartsWith(char) const; + bool StartsWith(const std::string_view&) const; + std::shared_ptr Substring(size_t pos, size_t len = UINT_MAX) const; // The high bits of 'hash' are always empty, but we prefer to store our