void CSSParserImpl::consumeDeclaration(CSSParserTokenRange range, StyleRule::Type ruleType)
{
    CSSParserTokenRange rangeCopy = range; // For inspector callbacks

    ASSERT(range.peek().type() == IdentToken);
    const CSSParserToken& token = range.consumeIncludingWhitespace();
    CSSPropertyID unresolvedProperty = token.parseAsUnresolvedCSSPropertyID();
    if (range.consume().type() != ColonToken)
        return; // Parse error

    bool important = false;
    const CSSParserToken* declarationValueEnd = range.end();
    const CSSParserToken* last = range.end() - 1;
    while (last->type() == WhitespaceToken)
        --last;
    if (last->type() == IdentToken && last->valueEqualsIgnoringCase("important")) {
        --last;
        while (last->type() == WhitespaceToken)
            --last;
        if (last->type() == DelimiterToken && last->delimiter() == '!') {
            important = true;
            declarationValueEnd = last;
        }
    }
    if (RuntimeEnabledFeatures::cssVariablesEnabled() && unresolvedProperty == CSSPropertyInvalid && CSSVariableParser::isValidVariableName(token)) {
        AtomicString variableName = token.value();
        consumeVariableDeclarationValue(range.makeSubRange(&range.peek(), declarationValueEnd), variableName, important);
        return;
    }

    if (important && (ruleType == StyleRule::FontFace || ruleType == StyleRule::Keyframes))
        return;

    if (m_observerWrapper && ruleType == StyleRule::Style) {
        size_t propertiesCount = m_parsedProperties.size();
        if (unresolvedProperty != CSSPropertyInvalid)
            consumeDeclarationValue(range.makeSubRange(&range.peek(), declarationValueEnd), unresolvedProperty, important, ruleType);
        m_observerWrapper->observer().observeProperty(
            m_observerWrapper->startOffset(rangeCopy), m_observerWrapper->endOffset(rangeCopy),
            important, m_parsedProperties.size() != propertiesCount);
        return;
    }

    if (unresolvedProperty == CSSPropertyInvalid)
        return;

    consumeDeclarationValue(range.makeSubRange(&range.peek(), declarationValueEnd), unresolvedProperty, important, ruleType);
}
void CSSParserImpl::consumeDeclaration(CSSParserTokenRange range, StyleRule::Type ruleType)
{
    CSSParserTokenRange rangeCopy = range; // For inspector callbacks

    ASSERT(range.peek().type() == IdentToken);
    CSSPropertyID unresolvedProperty = range.consumeIncludingWhitespace().parseAsUnresolvedCSSPropertyID();
    if (range.consume().type() != ColonToken)
        return; // Parse error

    // FIXME: We shouldn't allow !important in @keyframes or @font-face
    bool important = false;
    const CSSParserToken* declarationValueEnd = range.end();
    const CSSParserToken* last = range.end() - 1;
    while (last->type() == WhitespaceToken)
        --last;
    if (last->type() == IdentToken && last->valueEqualsIgnoringCase("important")) {
        --last;
        while (last->type() == WhitespaceToken)
            --last;
        if (last->type() == DelimiterToken && last->delimiter() == '!') {
            important = true;
            declarationValueEnd = last;
        }
    }

    if (m_observerWrapper && ruleType == StyleRule::Style) {
        size_t propertiesCount = m_parsedProperties.size();
        if (unresolvedProperty != CSSPropertyInvalid)
            consumeDeclarationValue(range.makeSubRange(&range.peek(), declarationValueEnd), unresolvedProperty, important, ruleType);
        m_observerWrapper->observer().startProperty(m_observerWrapper->startOffset(rangeCopy));
        m_observerWrapper->observer().endProperty(important,
            m_parsedProperties.size() != propertiesCount,
            m_observerWrapper->endOffset(rangeCopy), NoCSSError);
        return;
    }

    if (unresolvedProperty == CSSPropertyInvalid)
        return;

    consumeDeclarationValue(range.makeSubRange(&range.peek(), declarationValueEnd), unresolvedProperty, important, ruleType);
}