void CSSSelectorWatch::watchCSSSelectors(const Vector<String>& selectors) { m_watchedCallbackSelectors.clear(); CSSParserContext context(UASheetMode); BisonCSSParser parser(context); const CSSProperty callbackProperty(CSSPropertyInternalCallback, CSSPrimitiveValue::createIdentifier(CSSValueInternalPresence)); const RefPtr<StylePropertySet> callbackPropertySet = ImmutableStylePropertySet::create(&callbackProperty, 1, UASheetMode); CSSSelectorList selectorList; for (unsigned i = 0; i < selectors.size(); ++i) { parser.parseSelector(selectors[i], selectorList); if (!selectorList.isValid()) continue; // Only accept Compound Selectors, since they're cheaper to match. if (!allCompound(selectorList)) continue; RefPtr<StyleRule> rule = StyleRule::create(); rule->wrapperAdoptSelectorList(selectorList); rule->setProperties(callbackPropertySet); m_watchedCallbackSelectors.append(rule.release()); } m_document.changedSelectorWatch(); }
static bool isValidSelector(const String& selector) { CSSParserContext context(HTMLQuirksMode); CSSParser parser(context); CSSSelectorList selectorList; parser.parseSelector(selector, selectorList); return selectorList.isValid(); }
void CSSPageRule::setSelectorText(const String& selectorText) { CSSParserContext context(parserContext(), nullptr); CSSSelectorList selectorList = CSSParser::parsePageSelector(context, parentStyleSheet() ? parentStyleSheet()->contents() : nullptr, selectorText); if (!selectorList.isValid()) return; CSSStyleSheet::RuleMutationScope mutationScope(this); m_pageRule->wrapperAdoptSelectorList(std::move(selectorList)); }
void CSSSelectorParser::parseSelector(CSSParserTokenRange range, const CSSParserContext& context, const AtomicString& defaultNamespace, StyleSheetContents* styleSheet, CSSSelectorList& output) { CSSSelectorParser parser(context, defaultNamespace, styleSheet); range.consumeWhitespace(); CSSSelectorList result; parser.consumeComplexSelectorList(range, result); if (range.atEnd()) { output.adopt(result); recordSelectorStats(context, output); } ASSERT(!(output.isValid() && parser.m_failedParsing)); }
PassRefPtrWillBeRawPtr<StyleRule> CSSParserImpl::consumeStyleRule(CSSParserTokenRange prelude, CSSParserTokenRange block) { CSSSelectorList selectorList; CSSSelectorParser::parseSelector(prelude, m_context, m_styleSheet, selectorList); if (!selectorList.isValid()) return nullptr; // Parse error, invalid selector list if (m_observerWrapper) observeSelectors(*m_observerWrapper, prelude); consumeDeclarationList(block, StyleRule::Style); return StyleRule::create(selectorList, createStylePropertySet(m_parsedProperties, m_context.mode())); }
void CSSStyleRule::setSelectorText(const String& selectorText) { CSSParserContext context(parserContext(), 0); CSSSelectorList selectorList = CSSParser::parseSelector(context, parentStyleSheet() ? parentStyleSheet()->contents() : nullptr, selectorText); if (!selectorList.isValid()) return; CSSStyleSheet::RuleMutationScope mutationScope(this); m_styleRule->wrapperAdoptSelectorList(std::move(selectorList)); if (hasCachedSelectorText()) { selectorTextCache().remove(this); setHasCachedSelectorText(false); } }
void CSSStyleRule::setSelectorText(const String& selectorText) { CSSParser p(parserContext()); CSSSelectorList selectorList; p.parseSelector(selectorText, selectorList); if (!selectorList.isValid()) return; CSSStyleSheet::RuleMutationScope mutationScope(this); m_styleRule->wrapperAdoptSelectorList(selectorList); if (hasCachedSelectorText()) { selectorTextCache().remove(this); setHasCachedSelectorText(false); } }
void CSSStyleRule::setSelectorText(const String& selectorText) { CSSParser p(parserContext()); CSSSelectorList selectorList; p.parseSelector(selectorText, selectorList); if (!selectorList.isValid()) return; // NOTE: The selector list has to fit into RuleData. <http://webkit.org/b/118369> if (selectorList.componentCount() > RuleData::maximumSelectorComponentCount) return; CSSStyleSheet::RuleMutationScope mutationScope(this); m_styleRule->wrapperAdoptSelectorList(selectorList); if (hasCachedSelectorText()) { selectorTextCache().remove(this); setHasCachedSelectorText(false); } }
void CSSSelectorWatch::watchCSSSelectors(const Vector<String>& selectors) { m_watchedCallbackSelectors.clear(); const RefPtrWillBeRawPtr<StylePropertySet> callbackPropertySet = ImmutableStylePropertySet::create(nullptr, 0, UASheetMode); CSSSelectorList selectorList; for (unsigned i = 0; i < selectors.size(); ++i) { CSSParser::parseSelector(CSSParserContext(UASheetMode, 0), selectors[i], selectorList); if (!selectorList.isValid()) continue; // Only accept Compound Selectors, since they're cheaper to match. if (!allCompound(selectorList)) continue; RefPtrWillBeRawPtr<StyleRule> rule = StyleRule::create(); rule->wrapperAdoptSelectorList(selectorList); rule->setProperties(callbackPropertySet); m_watchedCallbackSelectors.append(rule.release()); } document().changedSelectorWatch(); }
PassOwnPtr<CSSParserSelector> CSSSelectorParser::consumePseudo(CSSParserTokenRange& range) { ASSERT(range.peek().type() == ColonToken); range.consume(); int colons = 1; if (range.peek().type() == ColonToken) { range.consume(); colons++; } const CSSParserToken& token = range.peek(); if (token.type() != IdentToken && token.type() != FunctionToken) return nullptr; OwnPtr<CSSParserSelector> selector = CSSParserSelector::create(); selector->setMatch(colons == 1 ? CSSSelector::PseudoClass : CSSSelector::PseudoElement); selector->setValue(AtomicString(String(token.value()).lower())); if (token.type() == IdentToken) { range.consume(); if (selector->pseudoType() == CSSSelector::PseudoUnknown) return nullptr; return selector.release(); } CSSParserTokenRange block = range.consumeBlock(); block.consumeWhitespace(); if ((colons == 1 && (token.valueEqualsIgnoringCase("host") || token.valueEqualsIgnoringCase("host-context") || token.valueEqualsIgnoringCase("-webkit-any"))) || (colons == 2 && token.valueEqualsIgnoringCase("cue"))) { CSSSelectorList* selectorList = new CSSSelectorList(); consumeCompoundSelectorList(block, *selectorList); if (!selectorList->isValid() || !block.atEnd()) return nullptr; selector->setSelectorList(adoptPtr(selectorList)); selector->pseudoType(); // FIXME: Do we need to force the pseudo type to be cached? ASSERT(selector->pseudoType() != CSSSelector::PseudoUnknown); return selector.release(); } if (colons == 1 && token.valueEqualsIgnoringCase("not")) { OwnPtr<CSSParserSelector> innerSelector = consumeCompoundSelector(block); if (!innerSelector || !innerSelector->isSimple() || !block.atEnd()) return nullptr; Vector<OwnPtr<CSSParserSelector>> selectorVector; selectorVector.append(innerSelector.release()); selector->adoptSelectorVector(selectorVector); return selector.release(); } if (colons == 1 && token.valueEqualsIgnoringCase("lang")) { // FIXME: CSS Selectors Level 4 allows :lang(*-foo) const CSSParserToken& ident = block.consumeIncludingWhitespace(); if (ident.type() != IdentToken || !block.atEnd()) return nullptr; selector->setArgument(ident.value()); selector->pseudoType(); // FIXME: Do we need to force the pseudo type to be cached? ASSERT(selector->pseudoType() == CSSSelector::PseudoLang); return selector.release(); } if (colons == 1 && (token.valueEqualsIgnoringCase("nth-child") || token.valueEqualsIgnoringCase("nth-last-child") || token.valueEqualsIgnoringCase("nth-of-type") || token.valueEqualsIgnoringCase("nth-last-of-type"))) { std::pair<int, int> ab; if (!consumeANPlusB(block, ab)) return nullptr; block.consumeWhitespace(); if (!block.atEnd()) return nullptr; // FIXME: We shouldn't serialize here and reparse in CSSSelector! // Serialization should be in CSSSelector::selectorText instead. int a = ab.first; int b = ab.second; String string; if (a == 0 && b == 0) string = "0"; else if (a == 0) string = String::number(b); else if (b == 0) string = String::format("%dn", a); else if (ab.second < 0) string = String::format("%dn%d", a, b); else string = String::format("%dn+%d", a, b); selector->setArgument(AtomicString(string)); selector->pseudoType(); // FIXME: Do we need to force the pseudo type to be cached? ASSERT(selector->pseudoType() != CSSSelector::PseudoUnknown); return selector.release(); } return nullptr; }