DeferredStyleGroupRuleList::DeferredStyleGroupRuleList(const CSSParserTokenRange& range, CSSDeferredParser& parser) : m_parser(parser) { size_t length = range.end() - range.begin(); m_tokens.reserveCapacity(length); m_tokens.append(range.begin(), length); }
CSSLazyPropertyParserImpl::CSSLazyPropertyParserImpl(CSSParserTokenRange block, CSSLazyParsingState* state) : CSSLazyPropertyParser(), m_lazyState(state) { // Reserve capacity to minimize heap bloat. size_t length = block.end() - block.begin(); m_tokens.reserveCapacity(length); m_tokens.append(block.begin(), length); }
bool CSSLazyParsingState::shouldLazilyParseProperties( const CSSSelectorList& selectors, const CSSParserTokenRange& block) const { // Simple heuristic for an empty block. Note that |block| here does not // include {} brackets. We avoid lazy parsing empty blocks so we can avoid // considering them when possible for matching. Lazy blocks must always be // considered. Three tokens is a reasonable minimum for a block: // ident ':' <value>. if (block.end() - block.begin() <= 2) return false; // Disallow lazy parsing for blocks which have before/after in their selector // list. This ensures we don't cause a collectFeatures() when we trigger // parsing for attr() functions which would trigger expensive invalidation // propagation. for (const auto* s = selectors.first(); s; s = CSSSelectorList::next(*s)) { for (const CSSSelector* current = s; current; current = current->tagHistory()) { const CSSSelector::PseudoType type(current->getPseudoType()); if (type == CSSSelector::PseudoBefore || type == CSSSelector::PseudoAfter) return false; if (current->relation() != CSSSelector::SubSelector) break; } } return true; }
void CSSVariableResolver::resolveApplyAtRule(CSSParserTokenRange& range, Vector<CSSParserToken>& result) { ASSERT(range.peek().type() == AtKeywordToken && range.peek().valueEqualsIgnoringASCIICase("apply")); range.consumeIncludingWhitespace(); const CSSParserToken& variableName = range.consumeIncludingWhitespace(); // TODO(timloh): Should we actually be consuming this? if (range.peek().type() == SemicolonToken) range.consume(); CSSVariableData* variableData = valueForCustomProperty(variableName.value()); if (!variableData) return; // Invalid custom property CSSParserTokenRange rule = variableData->tokenRange(); rule.consumeWhitespace(); if (rule.peek().type() != LeftBraceToken) return; CSSParserTokenRange ruleContents = rule.consumeBlock(); rule.consumeWhitespace(); if (!rule.atEnd()) return; result.appendRange(ruleContents.begin(), ruleContents.end()); }
void CSSParserObserverWrapper::skipCommentsBefore(const CSSParserTokenRange& range, bool leaveDirectlyBefore) { unsigned startIndex = range.begin() - m_firstParserToken; if (!leaveDirectlyBefore) startIndex++; while (m_commentIterator < m_commentOffsets.end() && m_commentIterator->tokensBefore < startIndex) m_commentIterator++; }
void CSSParserObserverWrapper::yieldCommentsBefore(const CSSParserTokenRange& range) { unsigned startIndex = range.begin() - m_firstParserToken; while (m_commentIterator < m_commentOffsets.end() && m_commentIterator->tokensBefore <= startIndex) { m_observer.startComment(m_commentIterator->startOffset); m_observer.endComment(m_commentIterator->endOffset); m_commentIterator++; } }
unsigned CSSParserObserverWrapper::previousTokenStartOffset(const CSSParserTokenRange& range) { if (range.begin() == m_firstParserToken) return 0; return m_tokenOffsets[range.begin() - m_firstParserToken - 1]; }
unsigned CSSParserObserverWrapper::startOffset(const CSSParserTokenRange& range) { return m_tokenOffsets[range.begin() - m_firstParserToken]; }