OLD | NEW |
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 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 #include "core/css/CSSReflectValue.h" | 47 #include "core/css/CSSReflectValue.h" |
48 #include "core/css/CSSSVGDocumentValue.h" | 48 #include "core/css/CSSSVGDocumentValue.h" |
49 #include "core/css/CSSShadowValue.h" | 49 #include "core/css/CSSShadowValue.h" |
50 #include "core/css/CSSTimingFunctionValue.h" | 50 #include "core/css/CSSTimingFunctionValue.h" |
51 #include "core/css/CSSValuePair.h" | 51 #include "core/css/CSSValuePair.h" |
52 #include "core/css/CSSValuePool.h" | 52 #include "core/css/CSSValuePool.h" |
53 #include "core/css/HashTools.h" | 53 #include "core/css/HashTools.h" |
54 #include "core/css/parser/CSSParserFastPaths.h" | 54 #include "core/css/parser/CSSParserFastPaths.h" |
55 #include "core/css/parser/CSSParserValues.h" | 55 #include "core/css/parser/CSSParserValues.h" |
56 #include "core/frame/UseCounter.h" | 56 #include "core/frame/UseCounter.h" |
57 #include "core/layout/LayoutTheme.h" | |
58 #include "core/style/GridCoordinate.h" | 57 #include "core/style/GridCoordinate.h" |
59 #include "core/svg/SVGPathUtilities.h" | 58 #include "core/svg/SVGPathUtilities.h" |
60 #include "platform/RuntimeEnabledFeatures.h" | 59 #include "platform/RuntimeEnabledFeatures.h" |
61 | 60 |
62 namespace blink { | 61 namespace blink { |
63 | 62 |
64 template <unsigned N> | 63 template <unsigned N> |
65 static bool equalIgnoringCase(const CSSParserString& a, const char (&b)[N]) | 64 static bool equalIgnoringCase(const CSSParserString& a, const char (&b)[N]) |
66 { | 65 { |
67 unsigned length = N - 1; // Ignore the trailing null character | 66 unsigned length = N - 1; // Ignore the trailing null character |
(...skipping 1208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1276 // <border-style>{1,4} | inherit | 1275 // <border-style>{1,4} | inherit |
1277 return parse4Values(propId, borderStyleShorthand().properties(), importa
nt); | 1276 return parse4Values(propId, borderStyleShorthand().properties(), importa
nt); |
1278 case CSSPropertyMargin: | 1277 case CSSPropertyMargin: |
1279 // <margin-width>{1,4} | inherit | 1278 // <margin-width>{1,4} | inherit |
1280 return parse4Values(propId, marginShorthand().properties(), important); | 1279 return parse4Values(propId, marginShorthand().properties(), important); |
1281 case CSSPropertyPadding: | 1280 case CSSPropertyPadding: |
1282 // <padding-width>{1,4} | inherit | 1281 // <padding-width>{1,4} | inherit |
1283 return parse4Values(propId, paddingShorthand().properties(), important); | 1282 return parse4Values(propId, paddingShorthand().properties(), important); |
1284 case CSSPropertyFlexFlow: | 1283 case CSSPropertyFlexFlow: |
1285 return parseShorthand(propId, flexFlowShorthand(), important); | 1284 return parseShorthand(propId, flexFlowShorthand(), important); |
1286 case CSSPropertyFont: | |
1287 // [ [ 'font-style' || 'font-variant' || 'font-weight' ]? 'font-size' [
/ 'line-height' ]? | |
1288 // 'font-family' ] | caption | icon | menu | message-box | small-caption
| status-bar | inherit | |
1289 if (id >= CSSValueCaption && id <= CSSValueStatusBar) | |
1290 return parseSystemFont(important); | |
1291 return parseFont(important); | |
1292 case CSSPropertyListStyle: | 1285 case CSSPropertyListStyle: |
1293 return parseShorthand(propId, listStyleShorthand(), important); | 1286 return parseShorthand(propId, listStyleShorthand(), important); |
1294 case CSSPropertyWebkitColumns: | 1287 case CSSPropertyWebkitColumns: |
1295 return parseColumnsShorthand(important); | 1288 return parseColumnsShorthand(important); |
1296 case CSSPropertyWebkitColumnRule: | 1289 case CSSPropertyWebkitColumnRule: |
1297 return parseShorthand(propId, webkitColumnRuleShorthand(), important); | 1290 return parseShorthand(propId, webkitColumnRuleShorthand(), important); |
1298 case CSSPropertyWebkitTextStroke: | 1291 case CSSPropertyWebkitTextStroke: |
1299 return parseShorthand(propId, webkitTextStrokeShorthand(), important); | 1292 return parseShorthand(propId, webkitTextStrokeShorthand(), important); |
1300 case CSSPropertyAnimation: | 1293 case CSSPropertyAnimation: |
1301 return parseAnimationShorthand(unresolvedProperty == CSSPropertyAliasWeb
kitAnimation, important); | 1294 return parseAnimationShorthand(unresolvedProperty == CSSPropertyAliasWeb
kitAnimation, important); |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1379 case CSSPropertyWebkitFontFeatureSettings: | 1372 case CSSPropertyWebkitFontFeatureSettings: |
1380 case CSSPropertyFontVariant: | 1373 case CSSPropertyFontVariant: |
1381 case CSSPropertyFontFamily: | 1374 case CSSPropertyFontFamily: |
1382 case CSSPropertyFontWeight: | 1375 case CSSPropertyFontWeight: |
1383 case CSSPropertyLetterSpacing: | 1376 case CSSPropertyLetterSpacing: |
1384 case CSSPropertyWordSpacing: | 1377 case CSSPropertyWordSpacing: |
1385 case CSSPropertyTabSize: | 1378 case CSSPropertyTabSize: |
1386 case CSSPropertyFontSize: | 1379 case CSSPropertyFontSize: |
1387 case CSSPropertyLineHeight: | 1380 case CSSPropertyLineHeight: |
1388 case CSSPropertyRotate: | 1381 case CSSPropertyRotate: |
| 1382 case CSSPropertyFont: |
1389 validPrimitive = false; | 1383 validPrimitive = false; |
1390 break; | 1384 break; |
1391 | 1385 |
1392 case CSSPropertyScrollSnapPointsX: | 1386 case CSSPropertyScrollSnapPointsX: |
1393 case CSSPropertyScrollSnapPointsY: | 1387 case CSSPropertyScrollSnapPointsY: |
1394 parsedValue = parseScrollSnapPoints(); | 1388 parsedValue = parseScrollSnapPoints(); |
1395 break; | 1389 break; |
1396 case CSSPropertyScrollSnapCoordinate: | 1390 case CSSPropertyScrollSnapCoordinate: |
1397 parsedValue = parseScrollSnapCoordinate(); | 1391 parsedValue = parseScrollSnapCoordinate(); |
1398 break; | 1392 break; |
(...skipping 2956 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4355 shape = parseBasicShapeInset(args); | 4349 shape = parseBasicShapeInset(args); |
4356 | 4350 |
4357 if (!shape) | 4351 if (!shape) |
4358 return nullptr; | 4352 return nullptr; |
4359 | 4353 |
4360 m_valueList->next(); | 4354 m_valueList->next(); |
4361 | 4355 |
4362 return shape.release(); | 4356 return shape.release(); |
4363 } | 4357 } |
4364 | 4358 |
4365 // [ 'font-style' || 'font-variant' || 'font-weight' ]? 'font-size' [ / 'line-he
ight' ]? 'font-family' | |
4366 bool CSSPropertyParser::parseFont(bool important) | |
4367 { | |
4368 // Let's check if there is an inherit or initial somewhere in the shorthand. | |
4369 for (unsigned i = 0; i < m_valueList->size(); ++i) { | |
4370 if (m_valueList->valueAt(i)->id == CSSValueInherit || m_valueList->value
At(i)->id == CSSValueInitial) | |
4371 return false; | |
4372 } | |
4373 | |
4374 ShorthandScope scope(this, CSSPropertyFont); | |
4375 // Optional font-style, font-variant and font-weight. | |
4376 bool fontStyleParsed = false; | |
4377 bool fontVariantParsed = false; | |
4378 bool fontWeightParsed = false; | |
4379 bool fontStretchParsed = false; | |
4380 CSSParserValue* value = m_valueList->current(); | |
4381 for (; value; value = m_valueList->next()) { | |
4382 if (!fontStyleParsed && CSSParserFastPaths::isValidKeywordPropertyAndVal
ue(CSSPropertyFontStyle, value->id)) { | |
4383 addProperty(CSSPropertyFontStyle, cssValuePool().createIdentifierVal
ue(value->id), important); | |
4384 fontStyleParsed = true; | |
4385 } else if (!fontVariantParsed && (value->id == CSSValueNormal || value->
id == CSSValueSmallCaps)) { | |
4386 // Font variant in the shorthand is particular, it only accepts norm
al or small-caps. | |
4387 addProperty(CSSPropertyFontVariant, cssValuePool().createIdentifierV
alue(value->id), important); | |
4388 fontVariantParsed = true; | |
4389 } else if (!fontWeightParsed && parseFontWeight(important)) { | |
4390 fontWeightParsed = true; | |
4391 } else if (!fontStretchParsed && CSSParserFastPaths::isValidKeywordPrope
rtyAndValue(CSSPropertyFontStretch, value->id)) { | |
4392 addProperty(CSSPropertyFontStretch, cssValuePool().createIdentifierV
alue(value->id), important); | |
4393 fontStretchParsed = true; | |
4394 } else { | |
4395 break; | |
4396 } | |
4397 } | |
4398 | |
4399 if (!value) | |
4400 return false; | |
4401 | |
4402 if (!fontStyleParsed) | |
4403 addProperty(CSSPropertyFontStyle, cssValuePool().createIdentifierValue(C
SSValueNormal), important, true); | |
4404 if (!fontVariantParsed) | |
4405 addProperty(CSSPropertyFontVariant, cssValuePool().createIdentifierValue
(CSSValueNormal), important, true); | |
4406 if (!fontWeightParsed) | |
4407 addProperty(CSSPropertyFontWeight, cssValuePool().createIdentifierValue(
CSSValueNormal), important, true); | |
4408 if (!fontStretchParsed) | |
4409 addProperty(CSSPropertyFontStretch, cssValuePool().createIdentifierValue
(CSSValueNormal), important, true); | |
4410 | |
4411 // Now a font size _must_ come. | |
4412 // <absolute-size> | <relative-size> | <length> | <percentage> | inherit | |
4413 if (!parseFontSize(important)) | |
4414 return false; | |
4415 | |
4416 value = m_valueList->current(); | |
4417 if (!value) | |
4418 return false; | |
4419 | |
4420 if (isForwardSlashOperator(value)) { | |
4421 // The line-height property. | |
4422 value = m_valueList->next(); | |
4423 if (!value) | |
4424 return false; | |
4425 RefPtrWillBeRawPtr<CSSPrimitiveValue> lineHeight = parseLineHeight(); | |
4426 if (!lineHeight) | |
4427 return false; | |
4428 addProperty(CSSPropertyLineHeight, lineHeight.release(), important); | |
4429 } else { | |
4430 addProperty(CSSPropertyLineHeight, cssValuePool().createIdentifierValue(
CSSValueNormal), important, true); | |
4431 } | |
4432 | |
4433 // Font family must come now. | |
4434 RefPtrWillBeRawPtr<CSSValue> parsedFamilyValue = parseFontFamily(); | |
4435 if (!parsedFamilyValue) | |
4436 return false; | |
4437 | |
4438 addProperty(CSSPropertyFontFamily, parsedFamilyValue.release(), important); | |
4439 | |
4440 // FIXME: http://www.w3.org/TR/2011/WD-css3-fonts-20110324/#font-prop requir
es that | |
4441 // "font-stretch", "font-size-adjust", and "font-kerning" be reset to their
initial values | |
4442 // but we don't seem to support them at the moment. They should also be adde
d here once implemented. | |
4443 if (m_valueList->current()) | |
4444 return false; | |
4445 | |
4446 return true; | |
4447 } | |
4448 | |
4449 bool CSSPropertyParser::parseSystemFont(bool important) | |
4450 { | |
4451 CSSValueID systemFontID = m_valueList->valueAt(0)->id; | |
4452 ASSERT(systemFontID >= CSSValueCaption && systemFontID <= CSSValueStatusBar)
; | |
4453 if (m_valueList->next()) | |
4454 return false; | |
4455 | |
4456 FontStyle fontStyle = FontStyleNormal; | |
4457 FontWeight fontWeight = FontWeightNormal; | |
4458 float fontSize = 0; | |
4459 AtomicString fontFamily; | |
4460 LayoutTheme::theme().systemFont(systemFontID, fontStyle, fontWeight, fontSiz
e, fontFamily); | |
4461 | |
4462 ShorthandScope scope(this, CSSPropertyFont); | |
4463 addProperty(CSSPropertyFontStyle, cssValuePool().createIdentifierValue(fontS
tyle == FontStyleItalic ? CSSValueItalic : CSSValueNormal), important); | |
4464 addProperty(CSSPropertyFontWeight, cssValuePool().createValue(fontWeight), i
mportant); | |
4465 addProperty(CSSPropertyFontSize, cssValuePool().createValue(fontSize, CSSPri
mitiveValue::UnitType::Pixels), important); | |
4466 RefPtrWillBeRawPtr<CSSValueList> fontFamilyList = CSSValueList::createCommaS
eparated(); | |
4467 fontFamilyList->append(cssValuePool().createFontFamilyValue(fontFamily)); | |
4468 addProperty(CSSPropertyFontFamily, fontFamilyList.release(), important); | |
4469 | |
4470 addProperty(CSSPropertyFontStretch, cssValuePool().createIdentifierValue(CSS
ValueNormal), important); | |
4471 addProperty(CSSPropertyFontVariant, cssValuePool().createIdentifierValue(CSS
ValueNormal), important); | |
4472 addProperty(CSSPropertyLineHeight, cssValuePool().createIdentifierValue(CSSV
alueNormal), important); | |
4473 return true; | |
4474 } | |
4475 | |
4476 class FontFamilyValueBuilder { | |
4477 STACK_ALLOCATED(); | |
4478 public: | |
4479 FontFamilyValueBuilder(CSSValueList* list) | |
4480 : m_list(list) | |
4481 { | |
4482 } | |
4483 | |
4484 void add(const CSSParserString& string) | |
4485 { | |
4486 if (!m_builder.isEmpty()) | |
4487 m_builder.append(' '); | |
4488 | |
4489 if (string.is8Bit()) { | |
4490 m_builder.append(string.characters8(), string.length()); | |
4491 return; | |
4492 } | |
4493 | |
4494 m_builder.append(string.characters16(), string.length()); | |
4495 } | |
4496 | |
4497 void commit() | |
4498 { | |
4499 if (m_builder.isEmpty()) | |
4500 return; | |
4501 m_list->append(cssValuePool().createFontFamilyValue(m_builder.toString()
)); | |
4502 m_builder.clear(); | |
4503 } | |
4504 | |
4505 private: | |
4506 StringBuilder m_builder; | |
4507 RawPtrWillBeMember<CSSValueList> m_list; | |
4508 }; | |
4509 | |
4510 PassRefPtrWillBeRawPtr<CSSValueList> CSSPropertyParser::parseFontFamily() | |
4511 { | |
4512 RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated()
; | |
4513 CSSParserValue* value = m_valueList->current(); | |
4514 | |
4515 FontFamilyValueBuilder familyBuilder(list.get()); | |
4516 bool inFamily = false; | |
4517 | |
4518 while (value) { | |
4519 CSSParserValue* nextValue = m_valueList->next(); | |
4520 bool nextValBreaksFont = !nextValue || isComma(nextValue); | |
4521 bool nextValIsFontName = nextValue && | |
4522 ((nextValue->id >= CSSValueSerif && nextValue->id <= CSSValueWebkitB
ody) || | |
4523 (nextValue->unit() == CSSPrimitiveValue::UnitType::String || nextVal
ue->m_unit == CSSParserValue::Identifier)); | |
4524 | |
4525 if (isCSSWideKeyword(*value) && !inFamily) { | |
4526 if (nextValBreaksFont) | |
4527 return nullptr; | |
4528 else if (nextValIsFontName) | |
4529 value = nextValue; | |
4530 continue; | |
4531 } | |
4532 | |
4533 if (value->id >= CSSValueSerif && value->id <= CSSValueWebkitBody) { | |
4534 if (inFamily) | |
4535 familyBuilder.add(value->string); | |
4536 else if (nextValBreaksFont || !nextValIsFontName) | |
4537 list->append(cssValuePool().createIdentifierValue(value->id)); | |
4538 else { | |
4539 familyBuilder.commit(); | |
4540 familyBuilder.add(value->string); | |
4541 inFamily = true; | |
4542 } | |
4543 } else if (value->unit() == CSSPrimitiveValue::UnitType::String) { | |
4544 // Strings never share in a family name. | |
4545 inFamily = false; | |
4546 familyBuilder.commit(); | |
4547 list->append(cssValuePool().createFontFamilyValue(value->string)); | |
4548 } else if (value->m_unit == CSSParserValue::Identifier) { | |
4549 if (inFamily) | |
4550 familyBuilder.add(value->string); | |
4551 else if (nextValBreaksFont || !nextValIsFontName) | |
4552 list->append(cssValuePool().createFontFamilyValue(value->string)
); | |
4553 else { | |
4554 familyBuilder.commit(); | |
4555 familyBuilder.add(value->string); | |
4556 inFamily = true; | |
4557 } | |
4558 } else { | |
4559 break; | |
4560 } | |
4561 | |
4562 if (!nextValue) | |
4563 break; | |
4564 | |
4565 if (nextValBreaksFont) { | |
4566 value = m_valueList->next(); | |
4567 familyBuilder.commit(); | |
4568 inFamily = false; | |
4569 } | |
4570 else if (nextValIsFontName) | |
4571 value = nextValue; | |
4572 else | |
4573 break; | |
4574 } | |
4575 familyBuilder.commit(); | |
4576 if (!list->length() || (m_ruleType == StyleRule::FontFace && list->length()
> 1)) | |
4577 list = nullptr; | |
4578 return list.release(); | |
4579 } | |
4580 | |
4581 PassRefPtrWillBeRawPtr<CSSPrimitiveValue> CSSPropertyParser::parseLineHeight() | |
4582 { | |
4583 CSSParserValue* value = m_valueList->current(); | |
4584 CSSValueID id = value->id; | |
4585 | |
4586 // normal | <number> | <length> | <percentage> | inherit | |
4587 if (id == CSSValueNormal) { | |
4588 m_valueList->next(); | |
4589 return cssValuePool().createIdentifierValue(id); | |
4590 } | |
4591 | |
4592 if (!validUnit(value, FNumber | FLength | FPercent | FNonNeg)) | |
4593 return nullptr; | |
4594 // The line-height property can accept both percents and numbers but additiv
e opertaions are | |
4595 // not permitted on them in calc() expressions. | |
4596 if (m_parsedCalculation && m_parsedCalculation->category() == CalcPercentNum
ber) { | |
4597 m_parsedCalculation.release(); | |
4598 return nullptr; | |
4599 } | |
4600 m_valueList->next(); | |
4601 return createPrimitiveNumericValue(value); | |
4602 } | |
4603 | |
4604 bool CSSPropertyParser::parseFontSize(bool important) | |
4605 { | |
4606 CSSParserValue* value = m_valueList->current(); | |
4607 CSSValueID id = value->id; | |
4608 bool validPrimitive = false; | |
4609 // <absolute-size> | <relative-size> | <length> | <percentage> | inherit | |
4610 if (id >= CSSValueXxSmall && id <= CSSValueLarger) | |
4611 validPrimitive = true; | |
4612 else | |
4613 validPrimitive = validUnit(value, FLength | FPercent | FNonNeg | (inShor
thand() ? FUnknown : FUnitlessQuirk)); | |
4614 if (validPrimitive && (!m_valueList->next() || inShorthand())) | |
4615 addProperty(CSSPropertyFontSize, parseValidPrimitive(id, value), importa
nt); | |
4616 return validPrimitive; | |
4617 } | |
4618 | |
4619 bool CSSPropertyParser::parseFontWeight(bool important) | |
4620 { | |
4621 CSSParserValue* value = m_valueList->current(); | |
4622 if (value->id >= CSSValueNormal && value->id <= CSSValueLighter) { | |
4623 addProperty(CSSPropertyFontWeight, cssValuePool().createIdentifierValue(
value->id), important); | |
4624 return true; | |
4625 } | |
4626 if (value->unit() == CSSPrimitiveValue::UnitType::Number) { | |
4627 int weight = static_cast<int>(value->fValue); | |
4628 if (!(weight % 100) && weight >= 100 && weight <= 900) { | |
4629 addProperty(CSSPropertyFontWeight, cssValuePool().createIdentifierVa
lue(static_cast<CSSValueID>(CSSValue100 + weight / 100 - 1)), important); | |
4630 return true; | |
4631 } | |
4632 } | |
4633 return false; | |
4634 } | |
4635 | |
4636 inline int CSSPropertyParser::colorIntFromValue(CSSParserValue* v) | 4359 inline int CSSPropertyParser::colorIntFromValue(CSSParserValue* v) |
4637 { | 4360 { |
4638 bool isPercent; | 4361 bool isPercent; |
4639 double value; | 4362 double value; |
4640 | 4363 |
4641 if (m_parsedCalculation) { | 4364 if (m_parsedCalculation) { |
4642 isPercent = m_parsedCalculation->category() == CalcPercent; | 4365 isPercent = m_parsedCalculation->category() == CalcPercent; |
4643 value = m_parsedCalculation->doubleValue(); | 4366 value = m_parsedCalculation->doubleValue(); |
4644 m_parsedCalculation.release(); | 4367 m_parsedCalculation.release(); |
4645 } else { | 4368 } else { |
(...skipping 2791 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7437 } | 7160 } |
7438 } | 7161 } |
7439 | 7162 |
7440 if (!list->length()) | 7163 if (!list->length()) |
7441 return nullptr; | 7164 return nullptr; |
7442 | 7165 |
7443 return list.release(); | 7166 return list.release(); |
7444 } | 7167 } |
7445 | 7168 |
7446 } // namespace blink | 7169 } // namespace blink |
OLD | NEW |