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()));
}
Example #2
0
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);
}
Example #3
0
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);
}
Example #4
0
void CSSParserSelector::adoptSelectorVector(Vector<OwnPtr<CSSParserSelector> >& selectorVector)
{
    CSSSelectorList* selectorList = fastNew<CSSSelectorList>();
    selectorList->adoptSelectorVector(selectorVector);
    m_selector->setSelectorList(adoptPtr(selectorList));
}