PageRenderTime 68ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 3ms

/webview/native/Source/WebCore/css/CSSParser.cpp

https://bitbucket.org/rbair/rbair-controls-8
C++ | 10081 lines | 8704 code | 919 blank | 458 comment | 3195 complexity | 80fbb512e7a4d7e468ae0655bce3d67d MD5 | raw file
Possible License(s): BSD-3-Clause, LGPL-2.1, GPL-2.0, LGPL-2.0

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. * Copyright (C) 2003 Lars Knoll (knoll@kde.org)
  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.
  5. * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com>
  6. * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
  7. * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
  8. * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
  9. *
  10. * This library is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU Library General Public
  12. * License as published by the Free Software Foundation; either
  13. * version 2 of the License, or (at your option) any later version.
  14. *
  15. * This library is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  18. * Library General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU Library General Public License
  21. * along with this library; see the file COPYING.LIB. If not, write to
  22. * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  23. * Boston, MA 02110-1301, USA.
  24. */
  25. #include "config.h"
  26. #include "CSSParser.h"
  27. #include "CSSAspectRatioValue.h"
  28. #include "CSSBorderImage.h"
  29. #include "CSSCanvasValue.h"
  30. #include "CSSCrossfadeValue.h"
  31. #include "CSSCursorImageValue.h"
  32. #include "CSSFontFaceRule.h"
  33. #include "CSSFontFaceSrcValue.h"
  34. #include "CSSFunctionValue.h"
  35. #include "CSSGradientValue.h"
  36. #include "CSSImageValue.h"
  37. #include "CSSInheritedValue.h"
  38. #include "CSSInitialValue.h"
  39. #include "CSSLineBoxContainValue.h"
  40. #include "CSSMediaRule.h"
  41. #include "CSSPageRule.h"
  42. #include "CSSPrimitiveValue.h"
  43. #include "CSSProperty.h"
  44. #include "CSSPropertySourceData.h"
  45. #include "CSSReflectValue.h"
  46. #include "CSSSelector.h"
  47. #include "CSSTimingFunctionValue.h"
  48. #include "CSSUnicodeRangeValue.h"
  49. #include "CSSValueKeywords.h"
  50. #include "CSSValueList.h"
  51. #include "CSSValuePool.h"
  52. #if ENABLE(CSS_VARIABLES)
  53. #include "CSSVariableValue.h"
  54. #endif
  55. #include "CSSWrapShapes.h"
  56. #include "Counter.h"
  57. #include "Document.h"
  58. #include "FloatConversion.h"
  59. #include "FontFeatureValue.h"
  60. #include "FontValue.h"
  61. #include "HTMLParserIdioms.h"
  62. #include "HashTools.h"
  63. #include "MediaList.h"
  64. #include "MediaQueryExp.h"
  65. #include "Page.h"
  66. #include "Pair.h"
  67. #include "Rect.h"
  68. #include "RenderTheme.h"
  69. #include "RuntimeEnabledFeatures.h"
  70. #include "SVGParserUtilities.h"
  71. #include "Settings.h"
  72. #include "ShadowValue.h"
  73. #include "StylePropertySet.h"
  74. #include "StylePropertyShorthand.h"
  75. #include "StyleRule.h"
  76. #include "StyleRuleImport.h"
  77. #include "StyleSheetContents.h"
  78. #include "TextEncoding.h"
  79. #include "WebKitCSSKeyframeRule.h"
  80. #include "WebKitCSSKeyframesRule.h"
  81. #include "WebKitCSSRegionRule.h"
  82. #include "WebKitCSSTransformValue.h"
  83. #include <limits.h>
  84. #include <wtf/BitArray.h>
  85. #include <wtf/HexNumber.h>
  86. #include <wtf/dtoa.h>
  87. #include <wtf/text/StringBuffer.h>
  88. #include <wtf/text/StringBuilder.h>
  89. #if ENABLE(CSS_IMAGE_SET)
  90. #include "CSSImageSetValue.h"
  91. #endif
  92. #if ENABLE(CSS_FILTERS)
  93. #include "WebKitCSSFilterValue.h"
  94. #if ENABLE(SVG)
  95. #include "WebKitCSSSVGDocumentValue.h"
  96. #endif
  97. #endif
  98. #if ENABLE(CSS_SHADERS)
  99. #include "WebKitCSSShaderValue.h"
  100. #endif
  101. #if ENABLE(DASHBOARD_SUPPORT)
  102. #include "DashboardRegion.h"
  103. #endif
  104. #define YYDEBUG 0
  105. #if YYDEBUG > 0
  106. extern int cssyydebug;
  107. #endif
  108. extern int cssyyparse(WebCore::CSSParser*);
  109. using namespace std;
  110. using namespace WTF;
  111. namespace {
  112. enum PropertyType {
  113. PropertyExplicit,
  114. PropertyImplicit
  115. };
  116. class ImplicitScope {
  117. WTF_MAKE_NONCOPYABLE(ImplicitScope);
  118. public:
  119. ImplicitScope(WebCore::CSSParser* parser, PropertyType propertyType)
  120. : m_parser(parser)
  121. {
  122. m_parser->m_implicitShorthand = propertyType == PropertyImplicit;
  123. }
  124. ~ImplicitScope()
  125. {
  126. m_parser->m_implicitShorthand = false;
  127. }
  128. private:
  129. WebCore::CSSParser* m_parser;
  130. };
  131. } // namespace
  132. namespace WebCore {
  133. static const unsigned INVALID_NUM_PARSED_PROPERTIES = UINT_MAX;
  134. static const double MAX_SCALE = 1000000;
  135. static bool equal(const CSSParserString& a, const char* b)
  136. {
  137. for (int i = 0; i < a.length; ++i) {
  138. if (!b[i])
  139. return false;
  140. if (a.characters[i] != b[i])
  141. return false;
  142. }
  143. return !b[a.length];
  144. }
  145. static bool equalIgnoringCase(const CSSParserString& a, const char* b)
  146. {
  147. for (int i = 0; i < a.length; ++i) {
  148. if (!b[i])
  149. return false;
  150. ASSERT(!isASCIIUpper(b[i]));
  151. if (toASCIILower(a.characters[i]) != b[i])
  152. return false;
  153. }
  154. return !b[a.length];
  155. }
  156. static bool hasPrefix(const char* string, unsigned length, const char* prefix)
  157. {
  158. for (unsigned i = 0; i < length; ++i) {
  159. if (!prefix[i])
  160. return true;
  161. if (string[i] != prefix[i])
  162. return false;
  163. }
  164. return false;
  165. }
  166. const CSSParserContext& strictCSSParserContext()
  167. {
  168. DEFINE_STATIC_LOCAL(CSSParserContext, strictContext, (CSSStrictMode));
  169. return strictContext;
  170. }
  171. CSSParserContext::CSSParserContext(CSSParserMode mode, const KURL& baseURL)
  172. : baseURL(baseURL)
  173. , mode(mode)
  174. , isHTMLDocument(false)
  175. , isCSSCustomFilterEnabled(false)
  176. , isCSSRegionsEnabled(false)
  177. , isCSSGridLayoutEnabled(false)
  178. #if ENABLE(CSS_VARIABLES)
  179. , isCSSVariablesEnabled(false)
  180. #endif
  181. , needsSiteSpecificQuirks(false)
  182. , enforcesCSSMIMETypeInNoQuirksMode(true)
  183. {
  184. }
  185. CSSParserContext::CSSParserContext(Document* document, const KURL& baseURL, const String& charset)
  186. : baseURL(baseURL.isNull() ? document->baseURL() : baseURL)
  187. , charset(charset)
  188. , mode(document->inQuirksMode() ? CSSQuirksMode : CSSStrictMode)
  189. , isHTMLDocument(document->isHTMLDocument())
  190. , isCSSCustomFilterEnabled(document->settings() ? document->settings()->isCSSCustomFilterEnabled() : false)
  191. , isCSSRegionsEnabled(document->cssRegionsEnabled())
  192. , isCSSGridLayoutEnabled(document->cssGridLayoutEnabled())
  193. #if ENABLE(CSS_VARIABLES)
  194. , isCSSVariablesEnabled(document->settings() ? document->settings()->cssVariablesEnabled() : false)
  195. #endif
  196. , needsSiteSpecificQuirks(document->settings() ? document->settings()->needsSiteSpecificQuirks() : false)
  197. , enforcesCSSMIMETypeInNoQuirksMode(!document->settings() || document->settings()->enforceCSSMIMETypeInNoQuirksMode())
  198. {
  199. }
  200. bool operator==(const CSSParserContext& a, const CSSParserContext& b)
  201. {
  202. return a.baseURL == b.baseURL
  203. && a.charset == b.charset
  204. && a.mode == b.mode
  205. && a.isHTMLDocument == b.isHTMLDocument
  206. && a.isCSSCustomFilterEnabled == b.isCSSCustomFilterEnabled
  207. && a.isCSSRegionsEnabled == b.isCSSRegionsEnabled
  208. && a.isCSSGridLayoutEnabled == b.isCSSGridLayoutEnabled
  209. #if ENABLE(CSS_VARIABLES)
  210. && a.isCSSVariablesEnabled == b.isCSSVariablesEnabled
  211. #endif
  212. && a.needsSiteSpecificQuirks == b.needsSiteSpecificQuirks
  213. && a.enforcesCSSMIMETypeInNoQuirksMode == b.enforcesCSSMIMETypeInNoQuirksMode;
  214. }
  215. CSSParser::CSSParser(const CSSParserContext& context)
  216. : m_context(context)
  217. , m_important(false)
  218. , m_id(CSSPropertyInvalid)
  219. , m_styleSheet(0)
  220. , m_selectorListForParseSelector(0)
  221. , m_numParsedPropertiesBeforeMarginBox(INVALID_NUM_PARSED_PROPERTIES)
  222. , m_inParseShorthand(0)
  223. , m_currentShorthand(CSSPropertyInvalid)
  224. , m_implicitShorthand(false)
  225. , m_hasFontFaceOnlyValues(false)
  226. , m_hadSyntacticallyValidCSSRule(false)
  227. , m_defaultNamespace(starAtom)
  228. , m_parsedTextPrefixLength(0)
  229. , m_propertyRange(UINT_MAX, UINT_MAX)
  230. , m_ruleSourceDataResult(0)
  231. , m_parsingMode(NormalMode)
  232. , m_currentCharacter(0)
  233. , m_tokenStart(0)
  234. , m_token(0)
  235. , m_lineNumber(0)
  236. , m_lastSelectorLineNumber(0)
  237. , m_allowImportRules(true)
  238. , m_allowNamespaceDeclarations(true)
  239. {
  240. #if YYDEBUG > 0
  241. cssyydebug = 1;
  242. #endif
  243. CSSPropertySourceData::init();
  244. }
  245. CSSParser::~CSSParser()
  246. {
  247. clearProperties();
  248. fastDeleteAllValues(m_floatingSelectors);
  249. deleteAllValues(m_floatingSelectorVectors);
  250. deleteAllValues(m_floatingValueLists);
  251. deleteAllValues(m_floatingFunctions);
  252. }
  253. void CSSParserString::lower()
  254. {
  255. // FIXME: If we need Unicode lowercasing here, then we probably want the real kind
  256. // that can potentially change the length of the string rather than the character
  257. // by character kind. If we don't need Unicode lowercasing, it would be good to
  258. // simplify this function.
  259. if (charactersAreAllASCII(characters, length)) {
  260. // Fast case for all-ASCII.
  261. for (int i = 0; i < length; i++)
  262. characters[i] = toASCIILower(characters[i]);
  263. } else {
  264. for (int i = 0; i < length; i++)
  265. characters[i] = Unicode::toLower(characters[i]);
  266. }
  267. }
  268. void CSSParser::setupParser(const char* prefix, const String& string, const char* suffix)
  269. {
  270. m_parsedTextPrefixLength = strlen(prefix);
  271. int length = string.length() + m_parsedTextPrefixLength + strlen(suffix) + 1;
  272. m_dataStart = adoptArrayPtr(new UChar[length]);
  273. for (unsigned i = 0; i < m_parsedTextPrefixLength; i++)
  274. m_dataStart[i] = prefix[i];
  275. memcpy(m_dataStart.get() + m_parsedTextPrefixLength, string.characters(), string.length() * sizeof(UChar));
  276. unsigned start = m_parsedTextPrefixLength + string.length();
  277. unsigned end = start + strlen(suffix);
  278. for (unsigned i = start; i < end; i++)
  279. m_dataStart[i] = suffix[i - start];
  280. m_dataStart[length - 1] = 0;
  281. m_currentCharacter = m_tokenStart = m_dataStart.get();
  282. }
  283. void CSSParser::parseSheet(StyleSheetContents* sheet, const String& string, int startLineNumber, RuleSourceDataList* ruleSourceDataResult)
  284. {
  285. setStyleSheet(sheet);
  286. m_defaultNamespace = starAtom; // Reset the default namespace.
  287. if (ruleSourceDataResult)
  288. m_currentRuleDataStack = adoptPtr(new RuleSourceDataList());
  289. m_ruleSourceDataResult = ruleSourceDataResult;
  290. m_lineNumber = startLineNumber;
  291. setupParser("", string, "");
  292. cssyyparse(this);
  293. m_currentRuleDataStack.clear();
  294. m_ruleSourceDataResult = 0;
  295. m_rule = 0;
  296. }
  297. PassRefPtr<StyleRuleBase> CSSParser::parseRule(StyleSheetContents* sheet, const String& string)
  298. {
  299. setStyleSheet(sheet);
  300. m_allowNamespaceDeclarations = false;
  301. setupParser("@-webkit-rule{", string, "} ");
  302. cssyyparse(this);
  303. return m_rule.release();
  304. }
  305. PassRefPtr<StyleKeyframe> CSSParser::parseKeyframeRule(StyleSheetContents* sheet, const String& string)
  306. {
  307. setStyleSheet(sheet);
  308. setupParser("@-webkit-keyframe-rule{ ", string, "} ");
  309. cssyyparse(this);
  310. return m_keyframe.release();
  311. }
  312. static inline bool isColorPropertyID(CSSPropertyID propertyId)
  313. {
  314. switch (propertyId) {
  315. case CSSPropertyColor:
  316. case CSSPropertyBackgroundColor:
  317. case CSSPropertyBorderBottomColor:
  318. case CSSPropertyBorderLeftColor:
  319. case CSSPropertyBorderRightColor:
  320. case CSSPropertyBorderTopColor:
  321. case CSSPropertyOutlineColor:
  322. case CSSPropertyTextLineThroughColor:
  323. case CSSPropertyTextOverlineColor:
  324. case CSSPropertyTextUnderlineColor:
  325. case CSSPropertyWebkitBorderAfterColor:
  326. case CSSPropertyWebkitBorderBeforeColor:
  327. case CSSPropertyWebkitBorderEndColor:
  328. case CSSPropertyWebkitBorderStartColor:
  329. case CSSPropertyWebkitColumnRuleColor:
  330. case CSSPropertyWebkitTextEmphasisColor:
  331. case CSSPropertyWebkitTextFillColor:
  332. case CSSPropertyWebkitTextStrokeColor:
  333. return true;
  334. default:
  335. return false;
  336. }
  337. }
  338. static bool parseColorValue(StylePropertySet* declaration, CSSPropertyID propertyId, const String& string, bool important, CSSParserMode cssParserMode)
  339. {
  340. ASSERT(!string.isEmpty());
  341. bool strict = isStrictParserMode(cssParserMode);
  342. if (!isColorPropertyID(propertyId))
  343. return false;
  344. CSSParserString cssString;
  345. cssString.characters = const_cast<UChar*>(string.characters());
  346. cssString.length = string.length();
  347. int valueID = cssValueKeywordID(cssString);
  348. bool validPrimitive = false;
  349. if (valueID == CSSValueWebkitText)
  350. validPrimitive = true;
  351. else if (valueID == CSSValueCurrentcolor)
  352. validPrimitive = true;
  353. else if ((valueID >= CSSValueAqua && valueID <= CSSValueWindowtext) || valueID == CSSValueMenu
  354. || (valueID >= CSSValueWebkitFocusRingColor && valueID < CSSValueWebkitText && !strict)) {
  355. validPrimitive = true;
  356. }
  357. if (validPrimitive) {
  358. RefPtr<CSSValue> value = cssValuePool().createIdentifierValue(valueID);
  359. declaration->addParsedProperty(CSSProperty(propertyId, value.release(), important));
  360. return true;
  361. }
  362. RGBA32 color;
  363. if (!CSSParser::fastParseColor(color, string, strict && string[0] != '#'))
  364. return false;
  365. RefPtr<CSSValue> value = cssValuePool().createColorValue(color);
  366. declaration->addParsedProperty(CSSProperty(propertyId, value.release(), important));
  367. return true;
  368. }
  369. static inline bool isSimpleLengthPropertyID(CSSPropertyID propertyId, bool& acceptsNegativeNumbers)
  370. {
  371. switch (propertyId) {
  372. case CSSPropertyFontSize:
  373. case CSSPropertyHeight:
  374. case CSSPropertyWidth:
  375. case CSSPropertyMinHeight:
  376. case CSSPropertyMinWidth:
  377. case CSSPropertyPaddingBottom:
  378. case CSSPropertyPaddingLeft:
  379. case CSSPropertyPaddingRight:
  380. case CSSPropertyPaddingTop:
  381. case CSSPropertyWebkitLogicalWidth:
  382. case CSSPropertyWebkitLogicalHeight:
  383. case CSSPropertyWebkitMinLogicalWidth:
  384. case CSSPropertyWebkitMinLogicalHeight:
  385. case CSSPropertyWebkitPaddingAfter:
  386. case CSSPropertyWebkitPaddingBefore:
  387. case CSSPropertyWebkitPaddingEnd:
  388. case CSSPropertyWebkitPaddingStart:
  389. acceptsNegativeNumbers = false;
  390. return true;
  391. #if ENABLE(CSS_EXCLUSIONS)
  392. case CSSPropertyWebkitWrapMargin:
  393. case CSSPropertyWebkitWrapPadding:
  394. acceptsNegativeNumbers = false;
  395. return RuntimeEnabledFeatures::cssExclusionsEnabled();
  396. #endif
  397. case CSSPropertyBottom:
  398. case CSSPropertyLeft:
  399. case CSSPropertyMarginBottom:
  400. case CSSPropertyMarginLeft:
  401. case CSSPropertyMarginRight:
  402. case CSSPropertyMarginTop:
  403. case CSSPropertyRight:
  404. case CSSPropertyTextIndent:
  405. case CSSPropertyTop:
  406. case CSSPropertyWebkitMarginAfter:
  407. case CSSPropertyWebkitMarginBefore:
  408. case CSSPropertyWebkitMarginEnd:
  409. case CSSPropertyWebkitMarginStart:
  410. acceptsNegativeNumbers = true;
  411. return true;
  412. default:
  413. return false;
  414. }
  415. }
  416. template <typename CharType>
  417. static inline bool parseSimpleLength(const CharType* characters, unsigned& length, CSSPrimitiveValue::UnitTypes& unit, double& number)
  418. {
  419. if (length > 2 && (characters[length - 2] | 0x20) == 'p' && (characters[length - 1] | 0x20) == 'x') {
  420. length -= 2;
  421. unit = CSSPrimitiveValue::CSS_PX;
  422. } else if (length > 1 && characters[length - 1] == '%') {
  423. length -= 1;
  424. unit = CSSPrimitiveValue::CSS_PERCENTAGE;
  425. }
  426. // We rely on charactersToDouble for validation as well. The function
  427. // will set "ok" to "false" if the entire passed-in character range does
  428. // not represent a double.
  429. bool ok;
  430. number = charactersToDouble(characters, length, &ok);
  431. return ok;
  432. }
  433. static bool parseSimpleLengthValue(StylePropertySet* declaration, CSSPropertyID propertyId, const String& string, bool important, CSSParserMode cssParserMode)
  434. {
  435. ASSERT(!string.isEmpty());
  436. bool acceptsNegativeNumbers;
  437. if (!isSimpleLengthPropertyID(propertyId, acceptsNegativeNumbers))
  438. return false;
  439. unsigned length = string.length();
  440. double number;
  441. CSSPrimitiveValue::UnitTypes unit = CSSPrimitiveValue::CSS_NUMBER;
  442. if (string.is8Bit()) {
  443. if (!parseSimpleLength(string.characters8(), length, unit, number))
  444. return false;
  445. } else {
  446. if (!parseSimpleLength(string.characters16(), length, unit, number))
  447. return false;
  448. }
  449. if (unit == CSSPrimitiveValue::CSS_NUMBER) {
  450. if (number && isStrictParserMode(cssParserMode))
  451. return false;
  452. unit = CSSPrimitiveValue::CSS_PX;
  453. }
  454. if (number < 0 && !acceptsNegativeNumbers)
  455. return false;
  456. RefPtr<CSSValue> value = cssValuePool().createValue(number, unit);
  457. declaration->addParsedProperty(CSSProperty(propertyId, value.release(), important));
  458. return true;
  459. }
  460. static inline bool isValidKeywordPropertyAndValue(CSSPropertyID propertyId, int valueID, const CSSParserContext& parserContext)
  461. {
  462. if (!valueID)
  463. return false;
  464. switch (propertyId) {
  465. case CSSPropertyBorderCollapse: // collapse | separate | inherit
  466. if (valueID == CSSValueCollapse || valueID == CSSValueSeparate)
  467. return true;
  468. break;
  469. case CSSPropertyBorderTopStyle: // <border-style> | inherit
  470. case CSSPropertyBorderRightStyle: // Defined as: none | hidden | dotted | dashed |
  471. case CSSPropertyBorderBottomStyle: // solid | double | groove | ridge | inset | outset
  472. case CSSPropertyBorderLeftStyle:
  473. case CSSPropertyWebkitBorderAfterStyle:
  474. case CSSPropertyWebkitBorderBeforeStyle:
  475. case CSSPropertyWebkitBorderEndStyle:
  476. case CSSPropertyWebkitBorderStartStyle:
  477. case CSSPropertyWebkitColumnRuleStyle:
  478. if (valueID >= CSSValueNone && valueID <= CSSValueDouble)
  479. return true;
  480. break;
  481. case CSSPropertyBoxSizing:
  482. if (valueID == CSSValueBorderBox || valueID == CSSValueContentBox)
  483. return true;
  484. break;
  485. case CSSPropertyCaptionSide: // top | bottom | left | right | inherit
  486. if (valueID == CSSValueLeft || valueID == CSSValueRight || valueID == CSSValueTop || valueID == CSSValueBottom)
  487. return true;
  488. break;
  489. case CSSPropertyClear: // none | left | right | both | inherit
  490. if (valueID == CSSValueNone || valueID == CSSValueLeft || valueID == CSSValueRight || valueID == CSSValueBoth)
  491. return true;
  492. break;
  493. case CSSPropertyDirection: // ltr | rtl | inherit
  494. if (valueID == CSSValueLtr || valueID == CSSValueRtl)
  495. return true;
  496. break;
  497. case CSSPropertyDisplay:
  498. // inline | block | list-item | run-in | inline-block | table |
  499. // inline-table | table-row-group | table-header-group | table-footer-group | table-row |
  500. // table-column-group | table-column | table-cell | table-caption | -webkit-box | -webkit-inline-box | none | inherit
  501. // -webkit-flex | -webkit-inline-flex | -webkit-grid | -webkit-inline-grid
  502. if ((valueID >= CSSValueInline && valueID <= CSSValueWebkitInlineBox) || valueID == CSSValueNone)
  503. return true;
  504. #if ENABLE(CSS3_FLEXBOX)
  505. if (valueID == CSSValueWebkitFlex || valueID == CSSValueWebkitInlineFlex)
  506. return true;
  507. #endif
  508. if (parserContext.isCSSGridLayoutEnabled && (valueID == CSSValueWebkitGrid || valueID == CSSValueWebkitInlineGrid))
  509. return true;
  510. break;
  511. case CSSPropertyEmptyCells: // show | hide | inherit
  512. if (valueID == CSSValueShow || valueID == CSSValueHide)
  513. return true;
  514. break;
  515. case CSSPropertyFloat: // left | right | none | center (for buggy CSS, maps to none)
  516. if (valueID == CSSValueLeft || valueID == CSSValueRight || valueID == CSSValueNone || valueID == CSSValueCenter)
  517. return true;
  518. break;
  519. case CSSPropertyFontStyle: // normal | italic | oblique | inherit
  520. if (valueID == CSSValueNormal || valueID == CSSValueItalic || valueID == CSSValueOblique)
  521. return true;
  522. break;
  523. case CSSPropertyImageRendering: // auto | optimizeContrast
  524. if (valueID == CSSValueAuto || valueID == CSSValueWebkitOptimizeContrast)
  525. return true;
  526. break;
  527. case CSSPropertyListStylePosition: // inside | outside | inherit
  528. if (valueID == CSSValueInside || valueID == CSSValueOutside)
  529. return true;
  530. break;
  531. case CSSPropertyListStyleType:
  532. // See section CSS_PROP_LIST_STYLE_TYPE of file CSSValueKeywords.in
  533. // for the list of supported list-style-types.
  534. if ((valueID >= CSSValueDisc && valueID <= CSSValueKatakanaIroha) || valueID == CSSValueNone)
  535. return true;
  536. break;
  537. case CSSPropertyOutlineStyle: // (<border-style> except hidden) | auto | inherit
  538. if (valueID == CSSValueAuto || valueID == CSSValueNone || (valueID >= CSSValueInset && valueID <= CSSValueDouble))
  539. return true;
  540. break;
  541. case CSSPropertyOverflowX:
  542. case CSSPropertyOverflowY: // visible | hidden | scroll | auto | marquee | overlay | inherit
  543. if (valueID == CSSValueVisible || valueID == CSSValueHidden || valueID == CSSValueScroll || valueID == CSSValueAuto || valueID == CSSValueOverlay || valueID == CSSValueWebkitMarquee)
  544. return true;
  545. break;
  546. case CSSPropertyPageBreakAfter: // auto | always | avoid | left | right | inherit
  547. case CSSPropertyPageBreakBefore:
  548. case CSSPropertyWebkitColumnBreakAfter:
  549. case CSSPropertyWebkitColumnBreakBefore:
  550. if (valueID == CSSValueAuto || valueID == CSSValueAlways || valueID == CSSValueAvoid || valueID == CSSValueLeft || valueID == CSSValueRight)
  551. return true;
  552. break;
  553. case CSSPropertyPageBreakInside: // avoid | auto | inherit
  554. case CSSPropertyWebkitColumnBreakInside:
  555. if (valueID == CSSValueAuto || valueID == CSSValueAvoid)
  556. return true;
  557. break;
  558. case CSSPropertyPointerEvents:
  559. // none | visiblePainted | visibleFill | visibleStroke | visible |
  560. // painted | fill | stroke | auto | all | inherit
  561. if (valueID == CSSValueVisible || valueID == CSSValueNone || valueID == CSSValueAll || valueID == CSSValueAuto || (valueID >= CSSValueVisiblepainted && valueID <= CSSValueStroke))
  562. return true;
  563. break;
  564. case CSSPropertyPosition: // static | relative | absolute | fixed | inherit
  565. if (valueID == CSSValueStatic || valueID == CSSValueRelative || valueID == CSSValueAbsolute || valueID == CSSValueFixed)
  566. return true;
  567. break;
  568. case CSSPropertyResize: // none | both | horizontal | vertical | auto
  569. if (valueID == CSSValueNone || valueID == CSSValueBoth || valueID == CSSValueHorizontal || valueID == CSSValueVertical || valueID == CSSValueAuto)
  570. return true;
  571. break;
  572. case CSSPropertySpeak: // none | normal | spell-out | digits | literal-punctuation | no-punctuation | inherit
  573. if (valueID == CSSValueNone || valueID == CSSValueNormal || valueID == CSSValueSpellOut || valueID == CSSValueDigits || valueID == CSSValueLiteralPunctuation || valueID == CSSValueNoPunctuation)
  574. return true;
  575. break;
  576. case CSSPropertyTableLayout: // auto | fixed | inherit
  577. if (valueID == CSSValueAuto || valueID == CSSValueFixed)
  578. return true;
  579. break;
  580. case CSSPropertyTextLineThroughMode:
  581. case CSSPropertyTextOverlineMode:
  582. case CSSPropertyTextUnderlineMode:
  583. if (valueID == CSSValueContinuous || valueID == CSSValueSkipWhiteSpace)
  584. return true;
  585. break;
  586. case CSSPropertyTextLineThroughStyle:
  587. case CSSPropertyTextOverlineStyle:
  588. case CSSPropertyTextUnderlineStyle:
  589. if (valueID == CSSValueNone || valueID == CSSValueSolid || valueID == CSSValueDouble || valueID == CSSValueDashed || valueID == CSSValueDotDash || valueID == CSSValueDotDotDash || valueID == CSSValueWave)
  590. return true;
  591. break;
  592. case CSSPropertyTextOverflow: // clip | ellipsis
  593. if (valueID == CSSValueClip || valueID == CSSValueEllipsis)
  594. return true;
  595. break;
  596. case CSSPropertyTextRendering: // auto | optimizeSpeed | optimizeLegibility | geometricPrecision
  597. if (valueID == CSSValueAuto || valueID == CSSValueOptimizespeed || valueID == CSSValueOptimizelegibility || valueID == CSSValueGeometricprecision)
  598. return true;
  599. break;
  600. case CSSPropertyTextTransform: // capitalize | uppercase | lowercase | none | inherit
  601. if ((valueID >= CSSValueCapitalize && valueID <= CSSValueLowercase) || valueID == CSSValueNone)
  602. return true;
  603. break;
  604. case CSSPropertyVisibility: // visible | hidden | collapse | inherit
  605. if (valueID == CSSValueVisible || valueID == CSSValueHidden || valueID == CSSValueCollapse)
  606. return true;
  607. break;
  608. case CSSPropertyWebkitAppearance:
  609. if ((valueID >= CSSValueCheckbox && valueID <= CSSValueTextarea) || valueID == CSSValueNone)
  610. return true;
  611. break;
  612. case CSSPropertyWebkitBackfaceVisibility:
  613. if (valueID == CSSValueVisible || valueID == CSSValueHidden)
  614. return true;
  615. break;
  616. case CSSPropertyWebkitBorderFit:
  617. if (valueID == CSSValueBorder || valueID == CSSValueLines)
  618. return true;
  619. break;
  620. case CSSPropertyWebkitBoxAlign:
  621. if (valueID == CSSValueStretch || valueID == CSSValueStart || valueID == CSSValueEnd || valueID == CSSValueCenter || valueID == CSSValueBaseline)
  622. return true;
  623. break;
  624. #if ENABLE(CSS_BOX_DECORATION_BREAK)
  625. case CSSPropertyWebkitBoxDecorationBreak:
  626. if (valueID == CSSValueClone || valueID == CSSValueSlice)
  627. return true;
  628. break;
  629. #endif
  630. case CSSPropertyWebkitBoxDirection:
  631. if (valueID == CSSValueNormal || valueID == CSSValueReverse)
  632. return true;
  633. break;
  634. case CSSPropertyWebkitBoxLines:
  635. if (valueID == CSSValueSingle || valueID == CSSValueMultiple)
  636. return true;
  637. break;
  638. case CSSPropertyWebkitBoxOrient:
  639. if (valueID == CSSValueHorizontal || valueID == CSSValueVertical || valueID == CSSValueInlineAxis || valueID == CSSValueBlockAxis)
  640. return true;
  641. break;
  642. case CSSPropertyWebkitBoxPack:
  643. if (valueID == CSSValueStart || valueID == CSSValueEnd || valueID == CSSValueCenter || valueID == CSSValueJustify)
  644. return true;
  645. break;
  646. case CSSPropertyWebkitColorCorrection:
  647. if (valueID == CSSValueSrgb || valueID == CSSValueDefault)
  648. return true;
  649. break;
  650. #if ENABLE(CSS3_FLEXBOX)
  651. case CSSPropertyWebkitAlignContent:
  652. if (valueID == CSSValueFlexStart || valueID == CSSValueFlexEnd || valueID == CSSValueCenter || valueID == CSSValueSpaceBetween || valueID == CSSValueSpaceAround || valueID == CSSValueStretch)
  653. return true;
  654. break;
  655. case CSSPropertyWebkitAlignItems:
  656. if (valueID == CSSValueFlexStart || valueID == CSSValueFlexEnd || valueID == CSSValueCenter || valueID == CSSValueBaseline || valueID == CSSValueStretch)
  657. return true;
  658. break;
  659. case CSSPropertyWebkitAlignSelf:
  660. if (valueID == CSSValueAuto || valueID == CSSValueFlexStart || valueID == CSSValueFlexEnd || valueID == CSSValueCenter || valueID == CSSValueBaseline || valueID == CSSValueStretch)
  661. return true;
  662. break;
  663. case CSSPropertyWebkitFlexDirection:
  664. if (valueID == CSSValueRow || valueID == CSSValueRowReverse || valueID == CSSValueColumn || valueID == CSSValueColumnReverse)
  665. return true;
  666. break;
  667. case CSSPropertyWebkitFlexWrap:
  668. if (valueID == CSSValueNone || valueID == CSSValueWrap || valueID == CSSValueWrapReverse)
  669. return true;
  670. break;
  671. case CSSPropertyWebkitJustifyContent:
  672. if (valueID == CSSValueFlexStart || valueID == CSSValueFlexEnd || valueID == CSSValueCenter || valueID == CSSValueSpaceBetween || valueID == CSSValueSpaceAround)
  673. return true;
  674. break;
  675. #endif
  676. case CSSPropertyWebkitFontKerning:
  677. if (valueID == CSSValueAuto || valueID == CSSValueNormal || valueID == CSSValueNone)
  678. return true;
  679. break;
  680. case CSSPropertyWebkitFontSmoothing:
  681. if (valueID == CSSValueAuto || valueID == CSSValueNone || valueID == CSSValueAntialiased || valueID == CSSValueSubpixelAntialiased)
  682. return true;
  683. break;
  684. case CSSPropertyWebkitHyphens:
  685. if (valueID == CSSValueNone || valueID == CSSValueManual || valueID == CSSValueAuto)
  686. return true;
  687. break;
  688. case CSSPropertyWebkitLineAlign:
  689. if (valueID == CSSValueNone || valueID == CSSValueEdges)
  690. return true;
  691. break;
  692. case CSSPropertyWebkitLineBreak: // normal | after-white-space
  693. if (valueID == CSSValueNormal || valueID == CSSValueAfterWhiteSpace)
  694. return true;
  695. break;
  696. case CSSPropertyWebkitLineSnap:
  697. if (valueID == CSSValueNone || valueID == CSSValueBaseline || valueID == CSSValueContain)
  698. return true;
  699. break;
  700. case CSSPropertyWebkitMarginAfterCollapse:
  701. case CSSPropertyWebkitMarginBeforeCollapse:
  702. case CSSPropertyWebkitMarginBottomCollapse:
  703. case CSSPropertyWebkitMarginTopCollapse:
  704. if (valueID == CSSValueCollapse || valueID == CSSValueSeparate || valueID == CSSValueDiscard)
  705. return true;
  706. break;
  707. case CSSPropertyWebkitMarqueeDirection:
  708. if (valueID == CSSValueForwards || valueID == CSSValueBackwards || valueID == CSSValueAhead || valueID == CSSValueReverse || valueID == CSSValueLeft || valueID == CSSValueRight || valueID == CSSValueDown
  709. || valueID == CSSValueUp || valueID == CSSValueAuto)
  710. return true;
  711. break;
  712. case CSSPropertyWebkitMarqueeStyle:
  713. if (valueID == CSSValueNone || valueID == CSSValueSlide || valueID == CSSValueScroll || valueID == CSSValueAlternate)
  714. return true;
  715. break;
  716. case CSSPropertyWebkitNbspMode: // normal | space
  717. if (valueID == CSSValueNormal || valueID == CSSValueSpace)
  718. return true;
  719. break;
  720. #if ENABLE(OVERFLOW_SCROLLING)
  721. case CSSPropertyWebkitOverflowScrolling:
  722. if (valueID == CSSValueAuto || valueID == CSSValueTouch)
  723. return true;
  724. break;
  725. #endif
  726. case CSSPropertyWebkitPrintColorAdjust:
  727. if (valueID == CSSValueExact || valueID == CSSValueEconomy)
  728. return true;
  729. break;
  730. #if ENABLE(CSS_REGIONS)
  731. case CSSPropertyWebkitRegionBreakAfter:
  732. case CSSPropertyWebkitRegionBreakBefore:
  733. if (parserContext.isCSSRegionsEnabled && (valueID == CSSValueAuto || valueID == CSSValueAlways || valueID == CSSValueAvoid || valueID == CSSValueLeft || valueID == CSSValueRight))
  734. return true;
  735. break;
  736. case CSSPropertyWebkitRegionBreakInside:
  737. if (parserContext.isCSSRegionsEnabled && (valueID == CSSValueAuto || valueID == CSSValueAvoid))
  738. return true;
  739. break;
  740. case CSSPropertyWebkitRegionOverflow:
  741. if (parserContext.isCSSRegionsEnabled && (valueID == CSSValueAuto || valueID == CSSValueBreak))
  742. return true;
  743. break;
  744. #endif
  745. case CSSPropertyWebkitRtlOrdering:
  746. if (valueID == CSSValueLogical || valueID == CSSValueVisual)
  747. return true;
  748. break;
  749. case CSSPropertyWebkitTextCombine:
  750. if (valueID == CSSValueNone || valueID == CSSValueHorizontal)
  751. return true;
  752. break;
  753. case CSSPropertyWebkitTextEmphasisPosition:
  754. if (valueID == CSSValueOver || valueID == CSSValueUnder)
  755. return true;
  756. break;
  757. case CSSPropertyWebkitTextSecurity:
  758. // disc | circle | square | none | inherit
  759. if (valueID == CSSValueDisc || valueID == CSSValueCircle || valueID == CSSValueSquare || valueID == CSSValueNone)
  760. return true;
  761. break;
  762. case CSSPropertyWebkitTextSizeAdjust:
  763. if (valueID == CSSValueAuto || valueID == CSSValueNone)
  764. return true;
  765. break;
  766. case CSSPropertyWebkitTransformStyle:
  767. if (valueID == CSSValueFlat || valueID == CSSValuePreserve3d)
  768. return true;
  769. break;
  770. case CSSPropertyWebkitUserDrag: // auto | none | element
  771. if (valueID == CSSValueAuto || valueID == CSSValueNone || valueID == CSSValueElement)
  772. return true;
  773. break;
  774. case CSSPropertyWebkitUserModify: // read-only | read-write
  775. if (valueID == CSSValueReadOnly || valueID == CSSValueReadWrite || valueID == CSSValueReadWritePlaintextOnly)
  776. return true;
  777. break;
  778. case CSSPropertyWebkitUserSelect: // auto | none | text
  779. if (valueID == CSSValueAuto || valueID == CSSValueNone || valueID == CSSValueText)
  780. return true;
  781. break;
  782. #if ENABLE(CSS_EXCLUSIONS)
  783. case CSSPropertyWebkitWrapFlow:
  784. if (!RuntimeEnabledFeatures::cssExclusionsEnabled())
  785. return false;
  786. if (valueID == CSSValueAuto || valueID == CSSValueBoth || valueID == CSSValueStart || valueID == CSSValueEnd || valueID == CSSValueMaximum || valueID == CSSValueClear)
  787. return true;
  788. break;
  789. case CSSPropertyWebkitWrapThrough:
  790. if (!RuntimeEnabledFeatures::cssExclusionsEnabled())
  791. return false;
  792. if (valueID == CSSValueWrap || valueID == CSSValueNone)
  793. return true;
  794. break;
  795. #endif
  796. case CSSPropertyWebkitWritingMode:
  797. if (valueID >= CSSValueHorizontalTb && valueID <= CSSValueHorizontalBt)
  798. return true;
  799. break;
  800. case CSSPropertyWhiteSpace: // normal | pre | nowrap | inherit
  801. if (valueID == CSSValueNormal || valueID == CSSValuePre || valueID == CSSValuePreWrap || valueID == CSSValuePreLine || valueID == CSSValueNowrap)
  802. return true;
  803. break;
  804. case CSSPropertyWordBreak: // normal | break-all | break-word (this is a custom extension)
  805. if (valueID == CSSValueNormal || valueID == CSSValueBreakAll || valueID == CSSValueBreakWord)
  806. return true;
  807. break;
  808. case CSSPropertyWordWrap: // normal | break-word
  809. if (valueID == CSSValueNormal || valueID == CSSValueBreakWord)
  810. return true;
  811. break;
  812. default:
  813. ASSERT_NOT_REACHED();
  814. return false;
  815. }
  816. return false;
  817. }
  818. static inline bool isKeywordPropertyID(CSSPropertyID propertyId)
  819. {
  820. switch (propertyId) {
  821. case CSSPropertyBorderBottomStyle:
  822. case CSSPropertyBorderCollapse:
  823. case CSSPropertyBorderLeftStyle:
  824. case CSSPropertyBorderRightStyle:
  825. case CSSPropertyBorderTopStyle:
  826. case CSSPropertyBoxSizing:
  827. case CSSPropertyCaptionSide:
  828. case CSSPropertyClear:
  829. case CSSPropertyDirection:
  830. case CSSPropertyDisplay:
  831. case CSSPropertyEmptyCells:
  832. case CSSPropertyFloat:
  833. case CSSPropertyFontStyle:
  834. case CSSPropertyImageRendering:
  835. case CSSPropertyListStylePosition:
  836. case CSSPropertyListStyleType:
  837. case CSSPropertyOutlineStyle:
  838. case CSSPropertyOverflowX:
  839. case CSSPropertyOverflowY:
  840. case CSSPropertyPageBreakAfter:
  841. case CSSPropertyPageBreakBefore:
  842. case CSSPropertyPageBreakInside:
  843. case CSSPropertyPointerEvents:
  844. case CSSPropertyPosition:
  845. case CSSPropertyResize:
  846. case CSSPropertySpeak:
  847. case CSSPropertyTableLayout:
  848. case CSSPropertyTextLineThroughMode:
  849. case CSSPropertyTextLineThroughStyle:
  850. case CSSPropertyTextOverflow:
  851. case CSSPropertyTextOverlineMode:
  852. case CSSPropertyTextOverlineStyle:
  853. case CSSPropertyTextRendering:
  854. case CSSPropertyTextTransform:
  855. case CSSPropertyTextUnderlineMode:
  856. case CSSPropertyTextUnderlineStyle:
  857. case CSSPropertyVisibility:
  858. case CSSPropertyWebkitAppearance:
  859. case CSSPropertyWebkitBackfaceVisibility:
  860. case CSSPropertyWebkitBorderAfterStyle:
  861. case CSSPropertyWebkitBorderBeforeStyle:
  862. case CSSPropertyWebkitBorderEndStyle:
  863. case CSSPropertyWebkitBorderFit:
  864. case CSSPropertyWebkitBorderStartStyle:
  865. case CSSPropertyWebkitBoxAlign:
  866. #if ENABLE(CSS_BOX_DECORATION_BREAK)
  867. case CSSPropertyWebkitBoxDecorationBreak:
  868. #endif
  869. case CSSPropertyWebkitBoxDirection:
  870. case CSSPropertyWebkitBoxLines:
  871. case CSSPropertyWebkitBoxOrient:
  872. case CSSPropertyWebkitBoxPack:
  873. case CSSPropertyWebkitColorCorrection:
  874. case CSSPropertyWebkitColumnBreakAfter:
  875. case CSSPropertyWebkitColumnBreakBefore:
  876. case CSSPropertyWebkitColumnBreakInside:
  877. case CSSPropertyWebkitColumnRuleStyle:
  878. #if ENABLE(CSS3_FLEXBOX)
  879. case CSSPropertyWebkitAlignContent:
  880. case CSSPropertyWebkitAlignItems:
  881. case CSSPropertyWebkitAlignSelf:
  882. case CSSPropertyWebkitFlexDirection:
  883. case CSSPropertyWebkitFlexWrap:
  884. case CSSPropertyWebkitJustifyContent:
  885. #endif
  886. case CSSPropertyWebkitFontKerning:
  887. case CSSPropertyWebkitFontSmoothing:
  888. case CSSPropertyWebkitHyphens:
  889. case CSSPropertyWebkitLineAlign:
  890. case CSSPropertyWebkitLineBreak:
  891. case CSSPropertyWebkitLineSnap:
  892. case CSSPropertyWebkitMarginAfterCollapse:
  893. case CSSPropertyWebkitMarginBeforeCollapse:
  894. case CSSPropertyWebkitMarginBottomCollapse:
  895. case CSSPropertyWebkitMarginTopCollapse:
  896. case CSSPropertyWebkitMarqueeDirection:
  897. case CSSPropertyWebkitMarqueeStyle:
  898. case CSSPropertyWebkitNbspMode:
  899. #if ENABLE(OVERFLOW_SCROLLING)
  900. case CSSPropertyWebkitOverflowScrolling:
  901. #endif
  902. case CSSPropertyWebkitPrintColorAdjust:
  903. #if ENABLE(CSS_REGIONS)
  904. case CSSPropertyWebkitRegionBreakAfter:
  905. case CSSPropertyWebkitRegionBreakBefore:
  906. case CSSPropertyWebkitRegionBreakInside:
  907. case CSSPropertyWebkitRegionOverflow:
  908. #endif
  909. case CSSPropertyWebkitRtlOrdering:
  910. case CSSPropertyWebkitTextCombine:
  911. case CSSPropertyWebkitTextEmphasisPosition:
  912. case CSSPropertyWebkitTextSecurity:
  913. case CSSPropertyWebkitTextSizeAdjust:
  914. case CSSPropertyWebkitTransformStyle:
  915. case CSSPropertyWebkitUserDrag:
  916. case CSSPropertyWebkitUserModify:
  917. case CSSPropertyWebkitUserSelect:
  918. #if ENABLE(CSS_EXCLUSIONS)
  919. case CSSPropertyWebkitWrapFlow:
  920. case CSSPropertyWebkitWrapThrough:
  921. #endif
  922. case CSSPropertyWebkitWritingMode:
  923. case CSSPropertyWhiteSpace:
  924. case CSSPropertyWordBreak:
  925. case CSSPropertyWordWrap:
  926. return true;
  927. default:
  928. return false;
  929. }
  930. }
  931. static bool parseKeywordValue(StylePropertySet* declaration, CSSPropertyID propertyId, const String& string, bool important, const CSSParserContext& parserContext)
  932. {
  933. ASSERT(!string.isEmpty());
  934. if (!isKeywordPropertyID(propertyId))
  935. return false;
  936. CSSParserString cssString;
  937. cssString.characters = const_cast<UChar*>(string.characters());
  938. cssString.length = string.length();
  939. int valueID = cssValueKeywordID(cssString);
  940. if (!valueID)
  941. return false;
  942. RefPtr<CSSValue> value;
  943. if (valueID == CSSValueInherit)
  944. value = cssValuePool().createInheritedValue();
  945. else if (valueID == CSSValueInitial)
  946. value = cssValuePool().createExplicitInitialValue();
  947. else if (isValidKeywordPropertyAndValue(propertyId, valueID, parserContext))
  948. value = cssValuePool().createIdentifierValue(valueID);
  949. else
  950. return false;
  951. declaration->addParsedProperty(CSSProperty(propertyId, value.release(), important));
  952. return true;
  953. }
  954. template <typename CharType>
  955. static bool parseTransformArguments(WebKitCSSTransformValue* transformValue, CharType* characters, unsigned length, unsigned start, unsigned expectedCount)
  956. {
  957. while (expectedCount) {
  958. size_t end = WTF::find(characters, length, expectedCount == 1 ? ')' : ',', start);
  959. if (end == notFound || (expectedCount == 1 && end != length - 1))
  960. return false;
  961. unsigned argumentLength = end - start;
  962. CSSPrimitiveValue::UnitTypes unit = CSSPrimitiveValue::CSS_NUMBER;
  963. double number;
  964. if (!parseSimpleLength(characters + start, argumentLength, unit, number))
  965. return false;
  966. if (unit != CSSPrimitiveValue::CSS_PX && (number || unit != CSSPrimitiveValue::CSS_NUMBER))
  967. return false;
  968. transformValue->append(cssValuePool().createValue(number, unit));
  969. start = end + 1;
  970. --expectedCount;
  971. }
  972. return true;
  973. }
  974. static bool parseTransformValue(StylePropertySet* properties, CSSPropertyID propertyID, const String& string, bool important)
  975. {
  976. if (propertyID != CSSPropertyWebkitTransform)
  977. return false;
  978. static const unsigned shortestValidTransformStringLength = 12;
  979. static const unsigned likelyMultipartTransformStringLengthCutoff = 32;
  980. if (string.length() < shortestValidTransformStringLength || string.length() > likelyMultipartTransformStringLengthCutoff)
  981. return false;
  982. if (!string.startsWith("translate", false))
  983. return false;
  984. UChar c9 = toASCIILower(string[9]);
  985. UChar c10 = toASCIILower(string[10]);
  986. WebKitCSSTransformValue::TransformOperationType transformType;
  987. unsigned expectedArgumentCount = 1;
  988. unsigned argumentStart = 11;
  989. if (c9 == 'x' && c10 == '(')
  990. transformType = WebKitCSSTransformValue::TranslateXTransformOperation;
  991. else if (c9 == 'y' && c10 == '(')
  992. transformType = WebKitCSSTransformValue::TranslateYTransformOperation;
  993. else if (c9 == 'z' && c10 == '(')
  994. transformType = WebKitCSSTransformValue::TranslateZTransformOperation;
  995. else if (c9 == '(') {
  996. transformType = WebKitCSSTransformValue::TranslateTransformOperation;
  997. expectedArgumentCount = 2;
  998. argumentStart = 10;
  999. } else if (c9 == '3' && c10 == 'd' && string[11] == '(') {
  1000. transformType = WebKitCSSTransformValue::Translate3DTransformOperation;
  1001. expectedArgumentCount = 3;
  1002. argumentStart = 12;
  1003. } else
  1004. return false;
  1005. RefPtr<WebKitCSSTransformValue> transformValue = WebKitCSSTransformValue::create(transformType);
  1006. bool success;
  1007. if (string.is8Bit())
  1008. success = parseTransformArguments(transformValue.get(), string.characters8(), string.length(), argumentStart, expectedArgumentCount);
  1009. else
  1010. success = parseTransformArguments(transformValue.get(), string.characters16(), string.length(), argumentStart, expectedArgumentCount);
  1011. if (!success)
  1012. return false;
  1013. RefPtr<CSSValueList> result = CSSValueList::createSpaceSeparated();
  1014. result->append(transformValue.release());
  1015. properties->addParsedProperty(CSSProperty(CSSPropertyWebkitTransform, result.release(), important));
  1016. return true;
  1017. }
  1018. PassRefPtr<CSSValueList> CSSParser::parseFontFaceValue(const AtomicString& string)
  1019. {
  1020. if (string.isEmpty())
  1021. return 0;
  1022. RefPtr<StylePropertySet> dummyStyle = StylePropertySet::create();
  1023. if (!parseValue(dummyStyle.get(), CSSPropertyFontFamily, string, false, CSSQuirksMode, 0))
  1024. return 0;
  1025. return static_pointer_cast<CSSValueList>(dummyStyle->getPropertyCSSValue(CSSPropertyFontFamily));
  1026. }
  1027. #if ENABLE(CSS_VARIABLES)
  1028. bool CSSParser::parseValue(StylePropertySet* declaration, CSSPropertyID propertyID, const String& string, bool important, Document* document)
  1029. {
  1030. ASSERT(!string.isEmpty());
  1031. CSSParserContext context(document);
  1032. if (parseSimpleLengthValue(declaration, propertyID, string, important, context.mode))
  1033. return true;
  1034. if (parseColorValue(declaration, propertyID, string, important, context.mode))
  1035. return true;
  1036. if (parseKeywordValue(declaration, propertyID, string, important, context))
  1037. return true;
  1038. CSSParser parser(context);
  1039. return parser.parseValue(declaration, propertyID, string, important, static_cast<StyleSheetContents*>(0));
  1040. }
  1041. #endif
  1042. bool CSSParser::parseValue(StylePropertySet* declaration, CSSPropertyID propertyID, const String& string, bool important, CSSParserMode cssParserMode, StyleSheetContents* contextStyleSheet)
  1043. {
  1044. ASSERT(!string.isEmpty());
  1045. if (parseSimpleLengthValue(declaration, propertyID, string, important, cssParserMode))
  1046. return true;
  1047. if (parseColorValue(declaration, propertyID, string, important, cssParserMode))
  1048. return true;
  1049. if (parseKeywordValue(declaration, propertyID, string, important, contextStyleSheet->parserContext()))
  1050. return true;
  1051. if (parseTransformValue(declaration, propertyID, string, important))
  1052. return true;
  1053. CSSParserContext context(cssParserMode);
  1054. if (contextStyleSheet) {
  1055. context = contextStyleSheet->parserContext();
  1056. context.mode = cssParserMode;
  1057. }
  1058. CSSParser parser(context);
  1059. return parser.parseValue(declaration, propertyID, string, important, contextStyleSheet);
  1060. }
  1061. bool CSSParser::parseValue(StylePropertySet* declaration, CSSPropertyID propertyID, const String& string, bool important, StyleSheetContents* contextStyleSheet)
  1062. {
  1063. setStyleSheet(contextStyleSheet);
  1064. setupParser("@-webkit-value{", string, "} ");
  1065. m_id = propertyID;
  1066. m_important = important;
  1067. cssyyparse(this);
  1068. m_rule = 0;
  1069. bool ok = false;
  1070. if (m_hasFontFaceOnlyValues)
  1071. deleteFontFaceOnlyValues();
  1072. if (!m_parsedProperties.isEmpty()) {
  1073. ok = true;
  1074. declaration->addParsedProperties(m_parsedProperties);
  1075. clearProperties();
  1076. }
  1077. return ok;
  1078. }
  1079. // The color will only be changed when string contains a valid CSS color, so callers
  1080. // can set it to a default color and ignore the boolean result.
  1081. bool CSSParser::parseColor(RGBA32& color, const String& string, bool strict)
  1082. {
  1083. // First try creating a color specified by name, rgba(), rgb() or "#" syntax.
  1084. if (fastParseColor(color, string, strict))
  1085. return true;
  1086. CSSParser parser(CSSStrictMode);
  1087. // In case the fast-path parser didn't understand the color, try the full parser.
  1088. if (!parser.parseColor(string))
  1089. return false;
  1090. CSSValue* value = parser.m_parsedProperties.first().value();
  1091. if (!value->isPrimitiveValue())
  1092. return false;
  1093. CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
  1094. if (!primitiveValue->isRGBColor())
  1095. return false;
  1096. color = primitiveValue->getRGBA32Value();
  1097. return true;
  1098. }
  1099. bool CSSParser::parseColor(const String& string)
  1100. {
  1101. setupParser("@-webkit-decls{color:", string, "} ");
  1102. cssyyparse(this);
  1103. m_rule = 0;
  1104. return !m_parsedProperties.isEmpty() && m_parsedProperties.first().id() == CSSPropertyColor;
  1105. }
  1106. bool CSSParser::parseSystemColor(RGBA32& color, const String& string, Document* document)
  1107. {
  1108. if (!document || !document->page())
  1109. return false;
  1110. CSSParserString cssColor;
  1111. cssColor.characters = const_cast<UChar*>(string.characters());
  1112. cssColor.length = string.length();
  1113. int id = cssValueKeywordID(cssColor);
  1114. if (id <= 0)
  1115. return false;
  1116. color = document->page()->theme()->systemColor(id).rgb();
  1117. return true;
  1118. }
  1119. void CSSParser::parseSelector(const String& string, CSSSelectorList& selectorList)
  1120. {
  1121. m_selectorListForParseSelector = &selectorList;
  1122. setupParser("@-webkit-selector{", string, "}");
  1123. cssyyparse(this);
  1124. m_selectorListForParseSelector = 0;
  1125. }
  1126. bool CSSParser::parseDeclaration(StylePropertySet* declaration, const String& string, PassRefPtr<CSSRuleSourceData> prpRuleSourceData, StyleSheetContents* contextStyleSheet)
  1127. {
  1128. // Length of the "@-webkit-decls{" prefix.
  1129. static const unsigned prefixLength = 15;
  1130. setStyleSheet(contextStyleSheet);
  1131. RefPtr<CSSRuleSourceData> ruleSourceData = prpRuleSourceData;
  1132. if (ruleSourceData) {
  1133. m_currentRuleDataStack = adoptPtr(new RuleSourceDataList());
  1134. m_currentRuleDataStack->append(ruleSourceData);
  1135. }
  1136. setupParser("@-webkit-decls{", string, "} ");
  1137. cssyyparse(this);
  1138. m_rule = 0;
  1139. bool ok = false;
  1140. if (m_hasFontFaceOnlyValues)
  1141. deleteFontFaceOnlyValues();
  1142. if (!m_parsedProperties.isEmpty()) {
  1143. ok = true;
  1144. declaration->addParsedProperties(m_parsedProperties);
  1145. clearProperties();
  1146. }
  1147. if (ruleSourceData) {
  1148. ASSERT(m_currentRuleDataStack->size() == 1);
  1149. ruleSourceData->ruleBodyRange.start = 0;
  1150. ruleSourceData->ruleBodyRange.end = string.length();
  1151. for (size_t i = 0, size = ruleSourceData->styleSourceData->propertyData.size(); i < size; ++i) {
  1152. CSSPropertySourceData& propertyData = ruleSourceData->styleSourceData->propertyData.at(i);
  1153. propertyData.range.start -= prefixLength;
  1154. propertyData.range.end -= prefixLength;
  1155. }
  1156. fixUnparsedPropertyRanges(ruleSourceData.get());
  1157. m_currentRuleDataStack.clear();
  1158. }
  1159. return ok;
  1160. }
  1161. PassOwnPtr<MediaQuery> CSSParser::parseMediaQuery(const String& string)
  1162. {
  1163. if (string.isEmpty())
  1164. return nullptr;
  1165. ASSERT(!m_mediaQuery);
  1166. // can't use { because tokenizer state switches from mediaquery to initial state when it sees { token.
  1167. // instead insert one " " (which is WHITESPACE in CSSGrammar.y)
  1168. setupParser("@-webkit-mediaquery ", string, "} ");
  1169. cssyyparse(this);
  1170. return m_mediaQuery.release();
  1171. }
  1172. #if ENABLE(CSS_VARIABLES)
  1173. static inline void filterProperties(bool important, const CSSParser::ParsedPropertyVector& input, Vector<CSSProperty, 256>& output, size_t& unusedEntries, BitArray<numCSSProperties>& seenProperties, HashSet<AtomicString>& seenVariables)
  1174. #else
  1175. static inline void filterProperties(bool important, const CSSParser::ParsedPropertyVector& input, Vector<CSSProperty, 256>& output, size_t& unusedEntries, BitArray<numCSSProperties>& seenProperties)
  1176. #endif
  1177. {
  1178. // Add properties in reverse order so that highest priority definitions are reached first. Duplicate definitions can then be ignored when found.
  1179. for (int i = input.size() - 1; i >= 0; --i) {
  1180. const CSSProperty& property = input[i];
  1181. if (property.isImportant() != important)
  1182. continue;
  1183. #if ENABLE(CSS_VARIABLES)
  1184. if (property.id() == CSSPropertyVariable) {
  1185. const AtomicString& name = static_cast<CSSVariableValue*>(property.value())->name();
  1186. if (seenVariables.contains(name))
  1187. continue;
  1188. seenVariables.add(name);
  1189. output[--unusedEntries] = property;
  1190. continue;
  1191. }
  1192. #endif
  1193. const unsigned propertyIDIndex = property.id() - firstCSSProperty;
  1194. if (seenProperties.get(propertyIDIndex))
  1195. continue;

Large files files are truncated, but you can click here to view the full file