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

Side by Side Diff: third_party/WebKit/Source/core/css/parser/LegacyCSSPropertyParser.cpp

Issue 1375753002: Move font shorthand handling into CSSPropertyParser (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Patch for landing Created 5 years, 2 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
« no previous file with comments | « third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp ('k') | no next file » | 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 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698