Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(92)

Side by Side Diff: Source/core/css/CSSParser.cpp

Issue 15660004: Reporing invalid CSS selectors. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/core/css/CSSParser.h ('k') | Source/core/css/CSSParserValues.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2003 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 2003 Lars Knoll (knoll@kde.org)
3 * Copyright (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) 3 * Copyright (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com)
4 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved. 4 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved.
5 * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com> 5 * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com>
6 * Copyright (C) 2008 Eric Seidel <eric@webkit.org> 6 * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
7 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmo bile.com/) 7 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmo bile.com/)
8 * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved. 8 * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
9 * Copyright (C) 2012 Intel Corporation. All rights reserved. 9 * Copyright (C) 2012 Intel Corporation. All rights reserved.
10 * 10 *
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 , m_styleSheet(0) 246 , m_styleSheet(0)
247 , m_supportsCondition(false) 247 , m_supportsCondition(false)
248 , m_selectorListForParseSelector(0) 248 , m_selectorListForParseSelector(0)
249 , m_numParsedPropertiesBeforeMarginBox(INVALID_NUM_PARSED_PROPERTIES) 249 , m_numParsedPropertiesBeforeMarginBox(INVALID_NUM_PARSED_PROPERTIES)
250 , m_inParseShorthand(0) 250 , m_inParseShorthand(0)
251 , m_currentShorthand(CSSPropertyInvalid) 251 , m_currentShorthand(CSSPropertyInvalid)
252 , m_implicitShorthand(false) 252 , m_implicitShorthand(false)
253 , m_hasFontFaceOnlyValues(false) 253 , m_hasFontFaceOnlyValues(false)
254 , m_hadSyntacticallyValidCSSRule(false) 254 , m_hadSyntacticallyValidCSSRule(false)
255 , m_logErrors(false) 255 , m_logErrors(false)
256 , m_ignoreErrorsInDeclaration(false) 256 , m_ignoreErrors(false)
257 , m_inFilterRule(false) 257 , m_inFilterRule(false)
258 , m_defaultNamespace(starAtom) 258 , m_defaultNamespace(starAtom)
259 , m_parsedTextPrefixLength(0) 259 , m_parsedTextPrefixLength(0)
260 , m_parsedTextSuffixLength(0) 260 , m_parsedTextSuffixLength(0)
261 , m_sourceDataHandler(0) 261 , m_sourceDataHandler(0)
262 , m_parsingMode(NormalMode) 262 , m_parsingMode(NormalMode)
263 , m_is8BitSource(false) 263 , m_is8BitSource(false)
264 , m_currentCharacter8(0) 264 , m_currentCharacter8(0)
265 , m_currentCharacter16(0) 265 , m_currentCharacter16(0)
266 , m_source(0) 266 , m_source(0)
267 , m_length(0) 267 , m_length(0)
268 , m_token(0) 268 , m_token(0)
269 , m_lineNumber(0) 269 , m_lineNumber(0)
270 , m_tokenStartLineNumber(0) 270 , m_tokenStartLineNumber(0)
271 , m_lastSelectorLineNumber(0) 271 , m_lastSelectorLineNumber(0)
272 , m_ruleHeaderType(CSSRuleSourceData::UNKNOWN_RULE)
272 , m_allowImportRules(true) 273 , m_allowImportRules(true)
273 , m_allowNamespaceDeclarations(true) 274 , m_allowNamespaceDeclarations(true)
274 #if ENABLE(CSS_DEVICE_ADAPTATION) 275 #if ENABLE(CSS_DEVICE_ADAPTATION)
275 , m_inViewport(false) 276 , m_inViewport(false)
276 #endif 277 #endif
277 , m_useCounter(counter) 278 , m_useCounter(counter)
278 { 279 {
279 #if YYDEBUG > 0 280 #if YYDEBUG > 0
280 cssyydebug = 1; 281 cssyydebug = 1;
281 #endif 282 #endif
(...skipping 13 matching lines...) Expand all
295 296
296 AtomicString CSSParserString::atomicSubstring(unsigned position, unsigned length ) const 297 AtomicString CSSParserString::atomicSubstring(unsigned position, unsigned length ) const
297 { 298 {
298 ASSERT(m_length >= position + length); 299 ASSERT(m_length >= position + length);
299 300
300 if (is8Bit()) 301 if (is8Bit())
301 return AtomicString(characters8() + position, length); 302 return AtomicString(characters8() + position, length);
302 return AtomicString(characters16() + position, length); 303 return AtomicString(characters16() + position, length);
303 } 304 }
304 305
306 void CSSParserString::trimTrailingWhitespace()
307 {
308 if (is8Bit()) {
309 while (m_length > 0 && isHTMLSpace(m_data.characters8[m_length - 1]))
310 --m_length;
311 } else {
312 while (m_length > 0 && isHTMLSpace(m_data.characters16[m_length - 1]))
313 --m_length;
314 }
315 }
316
305 void CSSParser::setupParser(const char* prefix, unsigned prefixLength, const Str ing& string, const char* suffix, unsigned suffixLength) 317 void CSSParser::setupParser(const char* prefix, unsigned prefixLength, const Str ing& string, const char* suffix, unsigned suffixLength)
306 { 318 {
307 m_parsedTextPrefixLength = prefixLength; 319 m_parsedTextPrefixLength = prefixLength;
308 m_parsedTextSuffixLength = suffixLength; 320 m_parsedTextSuffixLength = suffixLength;
309 unsigned stringLength = string.length(); 321 unsigned stringLength = string.length();
310 unsigned length = stringLength + m_parsedTextPrefixLength + m_parsedTextSuff ixLength + 1; 322 unsigned length = stringLength + m_parsedTextPrefixLength + m_parsedTextSuff ixLength + 1;
311 m_length = length; 323 m_length = length;
312 324
313 if (!stringLength || string.is8Bit()) { 325 if (!stringLength || string.is8Bit()) {
314 m_dataStart8 = adoptArrayPtr(new LChar[length]); 326 m_dataStart8 = adoptArrayPtr(new LChar[length]);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
352 setTokenStart<UChar>(m_currentCharacter16); 364 setTokenStart<UChar>(m_currentCharacter16);
353 m_lexFunc = &CSSParser::realLex<UChar>; 365 m_lexFunc = &CSSParser::realLex<UChar>;
354 } 366 }
355 367
356 void CSSParser::parseSheet(StyleSheetContents* sheet, const String& string, int startLineNumber, SourceDataHandler* sourceDataHandler, bool logErrors) 368 void CSSParser::parseSheet(StyleSheetContents* sheet, const String& string, int startLineNumber, SourceDataHandler* sourceDataHandler, bool logErrors)
357 { 369 {
358 setStyleSheet(sheet); 370 setStyleSheet(sheet);
359 m_defaultNamespace = starAtom; // Reset the default namespace. 371 m_defaultNamespace = starAtom; // Reset the default namespace.
360 m_sourceDataHandler = sourceDataHandler; 372 m_sourceDataHandler = sourceDataHandler;
361 m_logErrors = logErrors && sheet->singleOwnerDocument() && !sheet->baseURL() .isEmpty() && sheet->singleOwnerDocument()->page(); 373 m_logErrors = logErrors && sheet->singleOwnerDocument() && !sheet->baseURL() .isEmpty() && sheet->singleOwnerDocument()->page();
362 m_ignoreErrorsInDeclaration = false; 374 m_ignoreErrors = false;
363 m_lineNumber = startLineNumber; 375 m_lineNumber = startLineNumber;
364 m_source = &string; 376 m_source = &string;
365 setupParser("", string, ""); 377 setupParser("", string, "");
366 cssyyparse(this); 378 cssyyparse(this);
367 sheet->shrinkToFit(); 379 sheet->shrinkToFit();
368 m_source = 0; 380 m_source = 0;
369 m_sourceDataHandler = 0; 381 m_sourceDataHandler = 0;
370 m_rule = 0; 382 m_rule = 0;
371 m_ignoreErrorsInDeclaration = false; 383 m_ignoreErrors = false;
372 m_logErrors = false; 384 m_logErrors = false;
373 } 385 }
374 386
375 PassRefPtr<StyleRuleBase> CSSParser::parseRule(StyleSheetContents* sheet, const String& string) 387 PassRefPtr<StyleRuleBase> CSSParser::parseRule(StyleSheetContents* sheet, const String& string)
376 { 388 {
377 setStyleSheet(sheet); 389 setStyleSheet(sheet);
378 m_allowNamespaceDeclarations = false; 390 m_allowNamespaceDeclarations = false;
379 setupParser("@-internal-rule{", string, "} "); 391 setupParser("@-internal-rule{", string, "} ");
380 cssyyparse(this); 392 cssyyparse(this);
381 return m_rule.release(); 393 return m_rule.release();
(...skipping 9014 matching lines...) Expand 10 before | Expand all | Expand 10 after
9396 inline UChar* CSSParser::tokenStart<UChar>() 9408 inline UChar* CSSParser::tokenStart<UChar>()
9397 { 9409 {
9398 return m_tokenStart.ptr16; 9410 return m_tokenStart.ptr16;
9399 } 9411 }
9400 9412
9401 CSSParserLocation CSSParser::currentLocation() 9413 CSSParserLocation CSSParser::currentLocation()
9402 { 9414 {
9403 CSSParserLocation location; 9415 CSSParserLocation location;
9404 location.lineNumber = m_tokenStartLineNumber; 9416 location.lineNumber = m_tokenStartLineNumber;
9405 if (is8BitSource()) 9417 if (is8BitSource())
9406 location.content.init(tokenStart<LChar>(), currentCharacter<LChar>() - t okenStart<LChar>()); 9418 location.token.init(tokenStart<LChar>(), currentCharacter<LChar>() - tok enStart<LChar>());
9407 else 9419 else
9408 location.content.init(tokenStart<UChar>(), currentCharacter<UChar>() - t okenStart<UChar>()); 9420 location.token.init(tokenStart<UChar>(), currentCharacter<UChar>() - tok enStart<UChar>());
9409 return location; 9421 return location;
9410 } 9422 }
9411 9423
9412 CSSParserLocation CSSParser::getSource(const CSSParserLocation& begin, const CSS ParserLocation& end) const
9413 {
9414 if (!m_source)
9415 return begin;
9416
9417 CSSParserLocation location;
9418 location.lineNumber = begin.lineNumber;
9419 if (is8BitSource())
9420 location.content.init(*m_source, begin.content.characters8() - m_dataSta rt8.get(), end.content.characters8() - begin.content.characters8());
9421 else
9422 location.content.init(*m_source, begin.content.characters16() - m_dataSt art16.get(), end.content.characters16() - begin.content.characters16());
9423 return location;
9424 }
9425
9426 template <typename CharacterType> 9424 template <typename CharacterType>
9427 inline bool CSSParser::isIdentifierStart() 9425 inline bool CSSParser::isIdentifierStart()
9428 { 9426 {
9429 // Check whether an identifier is started. 9427 // Check whether an identifier is started.
9430 return isIdentifierStartAfterDash((*currentCharacter<CharacterType>() != '-' ) ? currentCharacter<CharacterType>() : currentCharacter<CharacterType>() + 1); 9428 return isIdentifierStartAfterDash((*currentCharacter<CharacterType>() != '-' ) ? currentCharacter<CharacterType>() : currentCharacter<CharacterType>() + 1);
9431 } 9429 }
9432 9430
9433 template <typename CharacterType> 9431 template <typename CharacterType>
9434 static inline CharacterType* checkAndSkipString(CharacterType* currentCharacter, int quote) 9432 static inline CharacterType* checkAndSkipString(CharacterType* currentCharacter, int quote)
9435 { 9433 {
(...skipping 1492 matching lines...) Expand 10 before | Expand all | Expand 10 after
10928 size_t length = token.length(); 10926 size_t length = token.length();
10929 if (is8BitSource()) { 10927 if (is8BitSource()) {
10930 size_t offset = token.characters8() - m_dataStart8.get(); 10928 size_t offset = token.characters8() - m_dataStart8.get();
10931 makeLower(token.characters8(), m_dataStart8.get() + offset, length); 10929 makeLower(token.characters8(), m_dataStart8.get() + offset, length);
10932 } else { 10930 } else {
10933 size_t offset = token.characters16() - m_dataStart16.get(); 10931 size_t offset = token.characters16() - m_dataStart16.get();
10934 makeLower(token.characters16(), m_dataStart16.get() + offset, length); 10932 makeLower(token.characters16(), m_dataStart16.get() + offset, length);
10935 } 10933 }
10936 } 10934 }
10937 10935
10936 void CSSParser::endInvalidRuleHeader()
10937 {
10938 if (m_ruleHeaderType == CSSRuleSourceData::UNKNOWN_RULE)
10939 return;
10940
10941 CSSParserLocation location;
10942 location.lineNumber = m_ruleHeaderStartLineNumber;
10943 if (is8BitSource())
10944 location.token.init(m_dataStart8.get() + m_ruleHeaderStartOffset, 0);
10945 else
10946 location.token.init(m_dataStart16.get() + m_ruleHeaderStartOffset, 0);
10947
10948 reportError(location, m_ruleHeaderType == CSSRuleSourceData::STYLE_RULE ? In validSelectorError : InvalidRuleError);
10949
10950 endRuleHeader();
10951 }
10952
10938 void CSSParser::reportError(const CSSParserLocation& location, ErrorType error) 10953 void CSSParser::reportError(const CSSParserLocation& location, ErrorType error)
10939 { 10954 {
10940 if (!isLoggingErrors()) 10955 if (!isLoggingErrors())
10941 return; 10956 return;
10942 10957
10943 m_ignoreErrorsInDeclaration = true; 10958 m_ignoreErrors = true;
10944 if (!InspectorInstrumentation::cssErrorFilter(location, m_id, error)) 10959 CSSParserString content = location.token;
10960 if (error == InvalidPropertyValueError || error == InvalidSelectorError) {
10961 if (m_source) {
10962 if (is8BitSource())
10963 content.init(*m_source, location.token.characters8() - m_dataSta rt8.get(), tokenStart<LChar>() - location.token.characters8());
10964 else
10965 content.init(*m_source, location.token.characters16() - m_dataSt art16.get(), tokenStart<UChar>() - location.token.characters16());
10966 content.trimTrailingWhitespace();
10967 }
10968 }
10969
10970 if (!InspectorInstrumentation::cssErrorFilter(content, m_id, error))
10945 return; 10971 return;
10946 10972
10947 StringBuilder builder; 10973 StringBuilder builder;
10948 switch (error) { 10974 switch (error) {
10949 case PropertyDeclarationError: 10975 case PropertyDeclarationError:
10950 builder.appendLiteral("Invalid CSS property declaration at: "); 10976 builder.appendLiteral("Invalid CSS property declaration at: ");
10951 break; 10977 break;
10952 10978
10953 case InvalidPropertyValueError: 10979 case InvalidPropertyValueError:
10954 builder.appendLiteral("Invalid CSS property value: "); 10980 builder.appendLiteral("Invalid CSS property value: ");
10955 break; 10981 break;
10956 10982
10957 case InvalidPropertyError: 10983 case InvalidPropertyError:
10958 builder.appendLiteral("Invalid CSS property name: "); 10984 builder.appendLiteral("Invalid CSS property name: ");
10959 break; 10985 break;
10960 10986
10987 case InvalidSelectorError:
10988 builder.appendLiteral("Invalid CSS selector: ");
10989 break;
10990
10991 case InvalidRuleError:
10992 builder.appendLiteral("Invalid CSS rule: ");
10993 break;
10994
10961 default: 10995 default:
10962 builder.appendLiteral("Unexpected CSS token: "); 10996 builder.appendLiteral("Unexpected CSS token: ");
10963 } 10997 }
10964 10998
10965 if (location.content.is8Bit()) 10999 if (content.is8Bit())
10966 builder.append(location.content.characters8(), location.content.length() ); 11000 builder.append(content.characters8(), content.length());
10967 else 11001 else
10968 builder.append(location.content.characters16(), location.content.length( )); 11002 builder.append(content.characters16(), content.length());
10969 11003
10970 logError(builder.toString(), location.lineNumber); 11004 logError(builder.toString(), location.lineNumber);
10971 } 11005 }
10972 11006
10973 bool CSSParser::isLoggingErrors() 11007 bool CSSParser::isLoggingErrors()
10974 { 11008 {
10975 return m_logErrors && !m_ignoreErrorsInDeclaration; 11009 return m_logErrors && !m_ignoreErrors;
10976 } 11010 }
10977 11011
10978 void CSSParser::logError(const String& message, int lineNumber) 11012 void CSSParser::logError(const String& message, int lineNumber)
10979 { 11013 {
10980 PageConsole* console = m_styleSheet->singleOwnerDocument()->page()->console( ); 11014 PageConsole* console = m_styleSheet->singleOwnerDocument()->page()->console( );
10981 console->addMessage(CSSMessageSource, WarningMessageLevel, message, m_styleS heet->baseURL().string(), lineNumber + 1); 11015 console->addMessage(CSSMessageSource, WarningMessageLevel, message, m_styleS heet->baseURL().string(), lineNumber + 1);
10982 } 11016 }
10983 11017
10984 StyleRuleKeyframes* CSSParser::createKeyframesRule(const String& name, PassOwnPt r<Vector<RefPtr<StyleKeyframe> > > popKeyframes) 11018 StyleRuleKeyframes* CSSParser::createKeyframesRule(const String& name, PassOwnPt r<Vector<RefPtr<StyleKeyframe> > > popKeyframes)
10985 { 11019 {
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after
11289 m_lastSelectorLineNumber = m_lineNumber; 11323 m_lastSelectorLineNumber = m_lineNumber;
11290 } 11324 }
11291 11325
11292 void CSSParser::updateLastMediaLine(MediaQuerySet* media) 11326 void CSSParser::updateLastMediaLine(MediaQuerySet* media)
11293 { 11327 {
11294 media->setLastLine(m_lineNumber); 11328 media->setLastLine(m_lineNumber);
11295 } 11329 }
11296 11330
11297 void CSSParser::startRuleHeader(CSSRuleSourceData::Type ruleType) 11331 void CSSParser::startRuleHeader(CSSRuleSourceData::Type ruleType)
11298 { 11332 {
11333 m_ruleHeaderType = ruleType;
11334 m_ruleHeaderStartOffset = safeUserStringTokenOffset();
11335 m_ruleHeaderStartLineNumber = m_tokenStartLineNumber;
11299 if (m_sourceDataHandler) 11336 if (m_sourceDataHandler)
11300 m_sourceDataHandler->startRuleHeader(ruleType, safeUserStringTokenOffset ()); 11337 m_sourceDataHandler->startRuleHeader(ruleType, m_ruleHeaderStartOffset);
11301 } 11338 }
11302 11339
11303 void CSSParser::endRuleHeader() 11340 void CSSParser::endRuleHeader()
11304 { 11341 {
11342 m_ruleHeaderType = CSSRuleSourceData::UNKNOWN_RULE;
11305 if (m_sourceDataHandler) 11343 if (m_sourceDataHandler)
11306 m_sourceDataHandler->endRuleHeader(safeUserStringTokenOffset()); 11344 m_sourceDataHandler->endRuleHeader(safeUserStringTokenOffset());
11307 } 11345 }
11308 11346
11309 void CSSParser::startSelector() 11347 void CSSParser::startSelector()
11310 { 11348 {
11311 if (m_sourceDataHandler) 11349 if (m_sourceDataHandler)
11312 m_sourceDataHandler->startSelector(safeUserStringTokenOffset()); 11350 m_sourceDataHandler->startSelector(safeUserStringTokenOffset());
11313 } 11351 }
11314 11352
(...skipping 10 matching lines...) Expand all
11325 } 11363 }
11326 11364
11327 void CSSParser::endRuleBody(bool discard) 11365 void CSSParser::endRuleBody(bool discard)
11328 { 11366 {
11329 if (m_sourceDataHandler) 11367 if (m_sourceDataHandler)
11330 m_sourceDataHandler->endRuleBody(safeUserStringTokenOffset(), discard); 11368 m_sourceDataHandler->endRuleBody(safeUserStringTokenOffset(), discard);
11331 } 11369 }
11332 11370
11333 void CSSParser::startProperty() 11371 void CSSParser::startProperty()
11334 { 11372 {
11335 m_ignoreErrorsInDeclaration = false; 11373 resumeErrorLogging();
11336 if (m_sourceDataHandler) 11374 if (m_sourceDataHandler)
11337 m_sourceDataHandler->startProperty(safeUserStringTokenOffset()); 11375 m_sourceDataHandler->startProperty(safeUserStringTokenOffset());
11338 } 11376 }
11339 11377
11340 void CSSParser::endProperty(bool isImportantFound, bool isPropertyParsed, ErrorT ype errorType) 11378 void CSSParser::endProperty(bool isImportantFound, bool isPropertyParsed, ErrorT ype errorType)
11341 { 11379 {
11342 m_id = CSSPropertyInvalid; 11380 m_id = CSSPropertyInvalid;
11343 if (m_sourceDataHandler) 11381 if (m_sourceDataHandler)
11344 m_sourceDataHandler->endProperty(isImportantFound, isPropertyParsed, saf eUserStringTokenOffset(), errorType); 11382 m_sourceDataHandler->endProperty(isImportantFound, isPropertyParsed, saf eUserStringTokenOffset(), errorType);
11345 } 11383 }
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after
11698 bool isValidNthToken(const CSSParserString& token) 11736 bool isValidNthToken(const CSSParserString& token)
11699 { 11737 {
11700 // The tokenizer checks for the construct of an+b. 11738 // The tokenizer checks for the construct of an+b.
11701 // However, since the {ident} rule precedes the {nth} rule, some of those 11739 // However, since the {ident} rule precedes the {nth} rule, some of those
11702 // tokens are identified as string literal. Furthermore we need to accept 11740 // tokens are identified as string literal. Furthermore we need to accept
11703 // "odd" and "even" which does not match to an+b. 11741 // "odd" and "even" which does not match to an+b.
11704 return equalIgnoringCase(token, "odd") || equalIgnoringCase(token, "even") 11742 return equalIgnoringCase(token, "odd") || equalIgnoringCase(token, "even")
11705 || equalIgnoringCase(token, "n") || equalIgnoringCase(token, "-n"); 11743 || equalIgnoringCase(token, "n") || equalIgnoringCase(token, "-n");
11706 } 11744 }
11707 11745
11708 CSSParserLocation CSSParserLocation::trimTrailingWhitespace() const
11709 {
11710 CSSParserLocation result;
11711 result.lineNumber = lineNumber;
11712 result.content = content;
11713 size_t newLength = content.length();
11714 while (newLength > 0 && isHTMLSpace(result.content[newLength - 1]))
11715 --newLength;
11716 result.content.setLength(newLength);
11717 return result;
11718 } 11746 }
11719
11720 }
OLDNEW
« no previous file with comments | « Source/core/css/CSSParser.h ('k') | Source/core/css/CSSParserValues.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698