PassRefPtrWillBeRawPtr<StyleRulePage> CSSParserImpl::consumePageRule(CSSParserTokenRange prelude, CSSParserTokenRange block) { // We only support a small subset of the css-page spec. prelude.consumeWhitespace(); AtomicString typeSelector; if (prelude.peek().type() == IdentToken) typeSelector = prelude.consume().value(); AtomicString pseudo; if (prelude.peek().type() == ColonToken) { prelude.consume(); if (prelude.peek().type() != IdentToken) return nullptr; // Parse error; expected ident token following colon in @page header pseudo = prelude.consume().value(); } prelude.consumeWhitespace(); if (!prelude.atEnd()) return nullptr; // Parse error; extra tokens in @page header OwnPtr<CSSParserSelector> selector; if (!typeSelector.isNull() && pseudo.isNull()) { selector = CSSParserSelector::create(QualifiedName(nullAtom, typeSelector, m_styleSheet->defaultNamespace())); } else { selector = CSSParserSelector::create(); if (!pseudo.isNull()) { selector->setMatch(CSSSelector::PagePseudoClass); selector->updatePseudoType(pseudo.lower()); if (selector->pseudoType() == CSSSelector::PseudoUnknown) return nullptr; // Parse error; unknown page pseudo-class } if (!typeSelector.isNull()) selector->prependTagSelector(QualifiedName(nullAtom, typeSelector, m_styleSheet->defaultNamespace())); } if (m_observerWrapper) { unsigned endOffset = m_observerWrapper->endOffset(prelude); m_observerWrapper->observer().startRuleHeader(StyleRule::Page, m_observerWrapper->startOffset(prelude)); m_observerWrapper->observer().endRuleHeader(endOffset); } selector->setForPage(); Vector<OwnPtr<CSSParserSelector>> selectorVector; selectorVector.append(selector.release()); CSSSelectorList selectorList; selectorList.adoptSelectorVector(selectorVector); consumeDeclarationList(block, StyleRule::Style); return StyleRulePage::create(selectorList, createStylePropertySet(m_parsedProperties, m_context.mode())); }
void CSSSelectorParser::consumeComplexSelectorList(CSSParserTokenRange& range, CSSSelectorList& output) { Vector<OwnPtr<CSSParserSelector>> selectorList; OwnPtr<CSSParserSelector> selector = consumeComplexSelector(range); if (!selector) return; selectorList.append(selector.release()); while (!range.atEnd() && range.peek().type() == CommaToken) { range.consumeIncludingWhitespace(); selector = consumeComplexSelector(range); if (!selector) return; selectorList.append(selector.release()); } if (!m_failedParsing) output.adoptSelectorVector(selectorList); }
void CSSSelectorParser::consumeCompoundSelectorList(CSSParserTokenRange& range, CSSSelectorList& output) { Vector<OwnPtr<CSSParserSelector>> selectorList; OwnPtr<CSSParserSelector> selector = consumeCompoundSelector(range); range.consumeWhitespace(); if (!selector) return; selectorList.append(selector.release()); while (!range.atEnd() && range.peek().type() == CommaToken) { // FIXME: This differs from the spec grammar: // Spec: compound_selector S* [ COMMA S* compound_selector ]* S* // Impl: compound_selector S* [ COMMA S* compound_selector S* ]* range.consumeIncludingWhitespace(); selector = consumeCompoundSelector(range); range.consumeWhitespace(); if (!selector) return; selectorList.append(selector.release()); } if (!m_failedParsing) output.adoptSelectorVector(selectorList); }
void CSSParserSelector::adoptSelectorVector(Vector<OwnPtr<CSSParserSelector> >& selectorVector) { CSSSelectorList* selectorList = fastNew<CSSSelectorList>(); selectorList->adoptSelectorVector(selectorVector); m_selector->setSelectorList(adoptPtr(selectorList)); }