// http://www.w3.org/TR/css3-syntax/#consume-a-numeric-token MediaQueryToken MediaQueryTokenizer::consumeNumericToken() { MediaQueryToken token = consumeNumber(); if (nextCharsAreIdentifier()) token.convertToDimensionWithUnit(consumeName()); else if (consumeIfNext('%')) token.convertToPercentage(); return token; }
void MediaQueryBlockWatcher::handleToken(const MediaQueryToken& token) { if (token.blockType() == MediaQueryToken::BlockStart) { ++m_blockLevel; } else if (token.blockType() == MediaQueryToken::BlockEnd) { ASSERT(m_blockLevel); --m_blockLevel; } }
void MediaQueryParser::readFeatureValue(MediaQueryTokenType type, const MediaQueryToken& token) { if (type == DimensionToken && token.unitType() == CSSPrimitiveValue::CSS_UNKNOWN) { m_state = SkipUntilComma; } else { m_mediaQueryData.addParserValue(type, token); m_state = ReadFeatureEnd; } }
void MediaQueryParser::readFeature(MediaQueryTokenType type, const MediaQueryToken& token) { if (type == IdentToken) { m_mediaQueryData.setMediaFeature(token.value()); m_state = ReadFeatureColon; } else { m_state = SkipUntilComma; } }
void MediaQueryParser::processToken(const MediaQueryToken& token) { MediaQueryTokenType type = token.type(); handleBlocks(token); m_blockWatcher.handleToken(token); // Call the function that handles current state if (type != WhitespaceToken && type != CommentToken) ((this)->*(m_state))(type, token); }
void MediaQueryParser::readMediaType(MediaQueryTokenType type, const MediaQueryToken& token) { if (type == LeftParenthesisToken) { m_state = ReadFeature; } else if (type == IdentToken) { if (m_state == ReadRestrictor && equalIgnoringCase(token.value(), "not")) { setStateAndRestrict(ReadMediaType, MediaQuery::Not); } else if (m_state == ReadRestrictor && equalIgnoringCase(token.value(), "only")) { setStateAndRestrict(ReadMediaType, MediaQuery::Only); } else { m_mediaQueryData.setMediaType(token.value()); m_state = ReadAnd; } } else if (type == EOFToken && (!m_querySet->queryVector().size() || m_state != ReadRestrictor)) { m_state = Done; } else { m_state = SkipUntilComma; if (type == CommaToken) skipUntilComma(type, token); } }
void MediaQueryData::addParserValue(MediaQueryTokenType type, const MediaQueryToken& token) { CSSParserValue value; if (type == NumberToken || type == PercentageToken || type == DimensionToken) { value.setFromNumber(token.numericValue(), token.unitType()); value.isInt = (token.numericValueType() == IntegerValueType); } else if (type == DelimiterToken) { value.unit = CSSParserValue::Operator; value.iValue = token.delimiter(); value.id = CSSValueInvalid; value.isInt = false; } else { CSSParserString tokenValue; tokenValue.init(token.value()); value.unit = CSSPrimitiveValue::CSS_IDENT; value.string = tokenValue; value.id = cssValueKeywordID(tokenValue); value.isInt = false; } m_valueList.addValue(value); }
void MediaQueryTokenizer::tokenize(String string, Vector<MediaQueryToken>& outTokens) { // According to the spec, we should perform preprocessing here. // See: http://dev.w3.org/csswg/css-syntax/#input-preprocessing // // However, we can skip this step since: // * We're using HTML spaces (which accept \r and \f as a valid white space) // * Do not count white spaces // * consumeEscape replaces NULLs for replacement characters if (string.isEmpty()) return; MediaQueryInputStream input(string); MediaQueryTokenizer tokenizer(input); while (true) { MediaQueryToken token = tokenizer.nextToken(); outTokens.append(token); if (token.type() == EOFToken) return; } }
void MediaQueryParser::readAnd(MediaQueryTokenType type, const MediaQueryToken& token) { if (type == IdentToken && equalIgnoringCase(token.value(), "and")) { m_state = ReadFeatureStart; } else if (type == CommaToken) { m_querySet->addMediaQuery(m_mediaQueryData.takeMediaQuery()); m_state = ReadRestrictor; } else if (type == EOFToken) { m_state = Done; } else { m_state = SkipUntilComma; } }
void MediaQueryParser::readFeatureEnd(MediaQueryTokenType type, const MediaQueryToken& token) { if (type == RightParenthesisToken || type == EOFToken) { if (m_mediaQueryData.addExpression()) m_state = ReadAnd; else m_state = SkipUntilComma; } else if (type == DelimiterToken && token.delimiter() == '/') { m_mediaQueryData.addParserValue(type, token); m_state = ReadFeatureValue; } else { m_state = SkipUntilBlockEnd; } }
void MediaQueryData::addParserValue(MediaQueryTokenType type, const MediaQueryToken& token) { CSSParserValue value; if (type == NumberToken || type == PercentageToken || type == DimensionToken) { value.setFromNumber(token.numericValue(), token.unitType()); value.isInt = (token.numericValueType() == IntegerValueType); } else if (type == DelimiterToken) { value.unit = CSSParserValue::Operator; value.iValue = token.delimiter(); } else { CSSParserFunction* function = new CSSParserFunction; function->name.init(token.value()); value.setFromFunction(function); CSSParserString tokenValue; tokenValue.init(token.value()); value.id = cssValueKeywordID(tokenValue); } m_valueList.addValue(value); }
void MediaQueryParser::handleBlocks(const MediaQueryToken& token) { if (token.blockType() == MediaQueryToken::BlockStart && (token.type() != LeftParenthesisToken || m_blockWatcher.blockLevel())) m_state = SkipUntilBlockEnd; }
void MediaQueryParser::skipUntilBlockEnd(MediaQueryTokenType type, const MediaQueryToken& token) { if (token.blockType() == MediaQueryToken::BlockEnd && !m_blockWatcher.blockLevel()) m_state = SkipUntilComma; }