| OLD | NEW |
| 1 /* | 1 /* |
| 2 * (C) 1999-2003 Lars Knoll (knoll@kde.org) | 2 * (C) 1999-2003 Lars Knoll (knoll@kde.org) |
| 3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All | 3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All |
| 4 * rights reserved. | 4 * rights reserved. |
| 5 * Copyright (C) 2011 Research In Motion Limited. All rights reserved. | 5 * Copyright (C) 2011 Research In Motion Limited. All rights reserved. |
| 6 * Copyright (C) 2013 Intel Corporation. All rights reserved. | 6 * Copyright (C) 2013 Intel Corporation. All rights reserved. |
| 7 * | 7 * |
| 8 * This library is free software; you can redistribute it and/or | 8 * This library is free software; you can redistribute it and/or |
| 9 * modify it under the terms of the GNU Library General Public | 9 * modify it under the terms of the GNU Library General Public |
| 10 * License as published by the Free Software Foundation; either | 10 * License as published by the Free Software Foundation; either |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 const CSSValue* | 146 const CSSValue* |
| 147 StylePropertySerializer::StylePropertySetForSerializer::getPropertyCSSValue( | 147 StylePropertySerializer::StylePropertySetForSerializer::getPropertyCSSValue( |
| 148 CSSPropertyID propertyID) const { | 148 CSSPropertyID propertyID) const { |
| 149 int index = findPropertyIndex(propertyID); | 149 int index = findPropertyIndex(propertyID); |
| 150 if (index == -1) | 150 if (index == -1) |
| 151 return nullptr; | 151 return nullptr; |
| 152 StylePropertySerializer::PropertyValueForSerializer value = propertyAt(index); | 152 StylePropertySerializer::PropertyValueForSerializer value = propertyAt(index); |
| 153 return value.value(); | 153 return value.value(); |
| 154 } | 154 } |
| 155 | 155 |
| 156 bool StylePropertySerializer::StylePropertySetForSerializer::isPropertyImplicit( | |
| 157 CSSPropertyID propertyID) const { | |
| 158 int index = findPropertyIndex(propertyID); | |
| 159 if (index == -1) | |
| 160 return false; | |
| 161 StylePropertySerializer::PropertyValueForSerializer value = propertyAt(index); | |
| 162 return value.isImplicit(); | |
| 163 } | |
| 164 | |
| 165 StylePropertySerializer::StylePropertySerializer( | 156 StylePropertySerializer::StylePropertySerializer( |
| 166 const StylePropertySet& properties) | 157 const StylePropertySet& properties) |
| 167 : m_propertySet(properties) {} | 158 : m_propertySet(properties) {} |
| 168 | 159 |
| 169 String StylePropertySerializer::getCustomPropertyText( | 160 String StylePropertySerializer::getCustomPropertyText( |
| 170 const PropertyValueForSerializer& property, | 161 const PropertyValueForSerializer& property, |
| 171 bool isNotFirstDecl) const { | 162 bool isNotFirstDecl) const { |
| 172 DCHECK_EQ(property.id(), CSSPropertyVariable); | 163 DCHECK_EQ(property.id(), CSSPropertyVariable); |
| 173 StringBuilder result; | 164 StringBuilder result; |
| 174 if (isNotFirstDecl) | 165 if (isNotFirstDecl) |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 312 // setting "missing" sub-properties to their initial values. This means | 303 // setting "missing" sub-properties to their initial values. This means |
| 313 // that a shorthand can never represent a list of subproperties where | 304 // that a shorthand can never represent a list of subproperties where |
| 314 // some are "initial" and some are not, and so serialization should | 305 // some are "initial" and some are not, and so serialization should |
| 315 // always fail in these cases (as per cssom). However we currently use | 306 // always fail in these cases (as per cssom). However we currently use |
| 316 // "initial" instead of the initial values for certain shorthands, so | 307 // "initial" instead of the initial values for certain shorthands, so |
| 317 // these are special-cased here. | 308 // these are special-cased here. |
| 318 // TODO(timloh): Don't use "initial" in shorthands and remove this | 309 // TODO(timloh): Don't use "initial" in shorthands and remove this |
| 319 // special-casing | 310 // special-casing |
| 320 static bool allowInitialInShorthand(CSSPropertyID propertyID) { | 311 static bool allowInitialInShorthand(CSSPropertyID propertyID) { |
| 321 switch (propertyID) { | 312 switch (propertyID) { |
| 313 case CSSPropertyBackground: |
| 322 case CSSPropertyBorder: | 314 case CSSPropertyBorder: |
| 323 case CSSPropertyBorderTop: | 315 case CSSPropertyBorderTop: |
| 324 case CSSPropertyBorderRight: | 316 case CSSPropertyBorderRight: |
| 325 case CSSPropertyBorderBottom: | 317 case CSSPropertyBorderBottom: |
| 326 case CSSPropertyBorderLeft: | 318 case CSSPropertyBorderLeft: |
| 327 case CSSPropertyOutline: | 319 case CSSPropertyOutline: |
| 328 case CSSPropertyColumnRule: | 320 case CSSPropertyColumnRule: |
| 329 case CSSPropertyColumns: | 321 case CSSPropertyColumns: |
| 330 case CSSPropertyFlex: | 322 case CSSPropertyFlex: |
| 331 case CSSPropertyFlexFlow: | 323 case CSSPropertyFlexFlow: |
| 332 case CSSPropertyGridColumn: | 324 case CSSPropertyGridColumn: |
| 333 case CSSPropertyGridRow: | 325 case CSSPropertyGridRow: |
| 334 case CSSPropertyGridArea: | 326 case CSSPropertyGridArea: |
| 335 case CSSPropertyGridGap: | 327 case CSSPropertyGridGap: |
| 328 case CSSPropertyListStyle: |
| 336 case CSSPropertyMotion: | 329 case CSSPropertyMotion: |
| 337 case CSSPropertyOffset: | 330 case CSSPropertyOffset: |
| 331 case CSSPropertyTextDecoration: |
| 338 case CSSPropertyWebkitMarginCollapse: | 332 case CSSPropertyWebkitMarginCollapse: |
| 339 case CSSPropertyListStyle: | 333 case CSSPropertyWebkitMask: |
| 340 case CSSPropertyTextDecoration: | |
| 341 case CSSPropertyWebkitTextEmphasis: | 334 case CSSPropertyWebkitTextEmphasis: |
| 342 case CSSPropertyWebkitTextStroke: | 335 case CSSPropertyWebkitTextStroke: |
| 343 return true; | 336 return true; |
| 344 default: | 337 default: |
| 345 return false; | 338 return false; |
| 346 } | 339 } |
| 347 } | 340 } |
| 348 | 341 |
| 349 // TODO(timloh): This should go away eventually, see crbug.com/471917 | |
| 350 static bool allowImplicitInitialInShorthand(CSSPropertyID propertyID) { | |
| 351 return propertyID == CSSPropertyBackground || | |
| 352 propertyID == CSSPropertyWebkitMask; | |
| 353 } | |
| 354 | |
| 355 String StylePropertySerializer::commonShorthandChecks( | 342 String StylePropertySerializer::commonShorthandChecks( |
| 356 const StylePropertyShorthand& shorthand) const { | 343 const StylePropertyShorthand& shorthand) const { |
| 357 int longhandCount = shorthand.length(); | 344 int longhandCount = shorthand.length(); |
| 358 DCHECK_LE(longhandCount, 17); | 345 DCHECK_LE(longhandCount, 17); |
| 359 const CSSValue* longhands[17] = {}; | 346 const CSSValue* longhands[17] = {}; |
| 360 | 347 |
| 361 bool hasImportant = false; | 348 bool hasImportant = false; |
| 362 bool hasNonImportant = false; | 349 bool hasNonImportant = false; |
| 363 | 350 |
| 364 for (int i = 0; i < longhandCount; i++) { | 351 for (int i = 0; i < longhandCount; i++) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 389 if (success) { | 376 if (success) { |
| 390 if (longhands[0]->isPendingSubstitutionValue()) | 377 if (longhands[0]->isPendingSubstitutionValue()) |
| 391 return toCSSPendingSubstitutionValue(longhands[0]) | 378 return toCSSPendingSubstitutionValue(longhands[0]) |
| 392 ->shorthandValue() | 379 ->shorthandValue() |
| 393 ->cssText(); | 380 ->cssText(); |
| 394 return longhands[0]->cssText(); | 381 return longhands[0]->cssText(); |
| 395 } | 382 } |
| 396 } | 383 } |
| 397 | 384 |
| 398 bool allowInitial = allowInitialInShorthand(shorthand.id()); | 385 bool allowInitial = allowInitialInShorthand(shorthand.id()); |
| 399 bool allowImplicitInitial = | |
| 400 allowInitial || allowImplicitInitialInShorthand(shorthand.id()); | |
| 401 for (int i = 0; i < longhandCount; i++) { | 386 for (int i = 0; i < longhandCount; i++) { |
| 402 const CSSValue& value = *longhands[i]; | 387 const CSSValue& value = *longhands[i]; |
| 403 if (value.isImplicitInitialValue()) { | |
| 404 if (allowImplicitInitial) | |
| 405 continue; | |
| 406 return emptyString(); | |
| 407 } | |
| 408 if (!allowInitial && value.isInitialValue()) | 388 if (!allowInitial && value.isInitialValue()) |
| 409 return emptyString(); | 389 return emptyString(); |
| 410 if (value.isInheritedValue() || value.isUnsetValue() || | 390 if (value.isInheritedValue() || value.isUnsetValue() || |
| 411 value.isPendingSubstitutionValue()) | 391 value.isPendingSubstitutionValue()) |
| 412 return emptyString(); | 392 return emptyString(); |
| 413 if (value.isVariableReferenceValue()) | 393 if (value.isVariableReferenceValue()) |
| 414 return emptyString(); | 394 return emptyString(); |
| 415 } | 395 } |
| 416 | 396 |
| 417 return String(); | 397 return String(); |
| (...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 706 | 686 |
| 707 String StylePropertySerializer::getLayeredShorthandValue( | 687 String StylePropertySerializer::getLayeredShorthandValue( |
| 708 const StylePropertyShorthand& shorthand) const { | 688 const StylePropertyShorthand& shorthand) const { |
| 709 const unsigned size = shorthand.length(); | 689 const unsigned size = shorthand.length(); |
| 710 | 690 |
| 711 // Begin by collecting the properties into a vector. | 691 // Begin by collecting the properties into a vector. |
| 712 HeapVector<Member<const CSSValue>> values(size); | 692 HeapVector<Member<const CSSValue>> values(size); |
| 713 // If the below loop succeeds, there should always be at minimum 1 layer. | 693 // If the below loop succeeds, there should always be at minimum 1 layer. |
| 714 size_t numLayers = 1U; | 694 size_t numLayers = 1U; |
| 715 | 695 |
| 696 // TODO(timloh): Shouldn't we fail if the lists are differently sized, with |
| 697 // the exception of background-color? |
| 716 for (size_t i = 0; i < size; i++) { | 698 for (size_t i = 0; i < size; i++) { |
| 717 values[i] = m_propertySet.getPropertyCSSValue(shorthand.properties()[i]); | 699 values[i] = m_propertySet.getPropertyCSSValue(shorthand.properties()[i]); |
| 718 if (values[i]->isBaseValueList()) { | 700 if (values[i]->isBaseValueList()) { |
| 719 const CSSValueList* valueList = toCSSValueList(values[i]); | 701 const CSSValueList* valueList = toCSSValueList(values[i]); |
| 720 numLayers = std::max(numLayers, valueList->length()); | 702 numLayers = std::max(numLayers, valueList->length()); |
| 721 } | 703 } |
| 722 } | 704 } |
| 723 | 705 |
| 724 StringBuilder result; | 706 StringBuilder result; |
| 725 | 707 |
| 726 // Now stitch the properties together. Implicit initial values are flagged as | 708 // Now stitch the properties together. |
| 727 // such and | |
| 728 // can safely be omitted. | |
| 729 for (size_t layer = 0; layer < numLayers; layer++) { | 709 for (size_t layer = 0; layer < numLayers; layer++) { |
| 730 StringBuilder layerResult; | 710 StringBuilder layerResult; |
| 731 bool useRepeatXShorthand = false; | 711 bool useRepeatXShorthand = false; |
| 732 bool useRepeatYShorthand = false; | 712 bool useRepeatYShorthand = false; |
| 733 bool useSingleWordShorthand = false; | 713 bool useSingleWordShorthand = false; |
| 734 bool foundPositionXCSSProperty = false; | 714 bool foundPositionXCSSProperty = false; |
| 735 bool foundPositionYCSSProperty = false; | 715 bool foundPositionYCSSProperty = false; |
| 736 | 716 |
| 737 for (unsigned propertyIndex = 0; propertyIndex < size; propertyIndex++) { | 717 for (unsigned propertyIndex = 0; propertyIndex < size; propertyIndex++) { |
| 738 const CSSValue* value = nullptr; | 718 const CSSValue* value = nullptr; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 749 property == CSSPropertyBackgroundColor)) { | 729 property == CSSPropertyBackgroundColor)) { |
| 750 // Singletons except background color belong in the 0th layer. | 730 // Singletons except background color belong in the 0th layer. |
| 751 // Background color belongs in the last layer. | 731 // Background color belongs in the last layer. |
| 752 value = values[propertyIndex]; | 732 value = values[propertyIndex]; |
| 753 } | 733 } |
| 754 // No point proceeding if there's not a value to look at. | 734 // No point proceeding if there's not a value to look at. |
| 755 if (!value) | 735 if (!value) |
| 756 continue; | 736 continue; |
| 757 | 737 |
| 758 // Special case for background-repeat. | 738 // Special case for background-repeat. |
| 759 if ((propertyIndex < size - 1 && | 739 if (property == CSSPropertyBackgroundRepeatX || |
| 760 m_propertySet.isPropertyImplicit(property)) && | 740 property == CSSPropertyWebkitMaskRepeatX) { |
| 761 (property == CSSPropertyBackgroundRepeatX || | |
| 762 property == CSSPropertyWebkitMaskRepeatX)) { | |
| 763 DCHECK(shorthand.properties()[propertyIndex + 1] == | 741 DCHECK(shorthand.properties()[propertyIndex + 1] == |
| 764 CSSPropertyBackgroundRepeatY || | 742 CSSPropertyBackgroundRepeatY || |
| 765 shorthand.properties()[propertyIndex + 1] == | 743 shorthand.properties()[propertyIndex + 1] == |
| 766 CSSPropertyWebkitMaskRepeatY); | 744 CSSPropertyWebkitMaskRepeatY); |
| 767 const CSSValue& yValue = | 745 const CSSValue& yValue = |
| 768 values[propertyIndex + 1]->isValueList() | 746 values[propertyIndex + 1]->isValueList() |
| 769 ? toCSSValueList(values[propertyIndex + 1])->item(layer) | 747 ? toCSSValueList(values[propertyIndex + 1])->item(layer) |
| 770 : *values[propertyIndex + 1]; | 748 : *values[propertyIndex + 1]; |
| 771 | 749 |
| 772 // FIXME: At some point we need to fix this code to avoid returning an | 750 // FIXME: At some point we need to fix this code to avoid returning an |
| (...skipping 11 matching lines...) Expand all Loading... |
| 784 property = shorthand.properties()[++propertyIndex]; | 762 property = shorthand.properties()[++propertyIndex]; |
| 785 } else if (xId == CSSValueRepeat && yId == CSSValueNoRepeat) { | 763 } else if (xId == CSSValueRepeat && yId == CSSValueNoRepeat) { |
| 786 useRepeatXShorthand = true; | 764 useRepeatXShorthand = true; |
| 787 property = shorthand.properties()[++propertyIndex]; | 765 property = shorthand.properties()[++propertyIndex]; |
| 788 } else if (xId == CSSValueNoRepeat && yId == CSSValueRepeat) { | 766 } else if (xId == CSSValueNoRepeat && yId == CSSValueRepeat) { |
| 789 useRepeatYShorthand = true; | 767 useRepeatYShorthand = true; |
| 790 property = shorthand.properties()[++propertyIndex]; | 768 property = shorthand.properties()[++propertyIndex]; |
| 791 } | 769 } |
| 792 } | 770 } |
| 793 | 771 |
| 794 if (!(value->isInitialValue() && | 772 if (!value->isInitialValue()) { |
| 795 toCSSInitialValue(value)->isImplicit())) { | |
| 796 if (property == CSSPropertyBackgroundSize || | 773 if (property == CSSPropertyBackgroundSize || |
| 797 property == CSSPropertyWebkitMaskSize) { | 774 property == CSSPropertyWebkitMaskSize) { |
| 798 if (foundPositionYCSSProperty || foundPositionXCSSProperty) | 775 if (foundPositionYCSSProperty || foundPositionXCSSProperty) |
| 799 layerResult.append(" / "); | 776 layerResult.append(" / "); |
| 800 else | 777 else |
| 801 layerResult.append(" 0% 0% / "); | 778 layerResult.append(" 0% 0% / "); |
| 802 } else if (!layerResult.isEmpty()) { | 779 } else if (!layerResult.isEmpty()) { |
| 803 // Do this second to avoid ending up with an extra space in the output | 780 // Do this second to avoid ending up with an extra space in the output |
| 804 // if we hit the continue above. | 781 // if we hit the continue above. |
| 805 layerResult.append(' '); | 782 layerResult.append(' '); |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 950 const CSSValue& xValue = | 927 const CSSValue& xValue = |
| 951 repeatXList ? repeatXList->item(i % repeatXList->length()) : repeatX; | 928 repeatXList ? repeatXList->item(i % repeatXList->length()) : repeatX; |
| 952 const CSSValue& yValue = | 929 const CSSValue& yValue = |
| 953 repeatYList ? repeatYList->item(i % repeatYList->length()) : repeatY; | 930 repeatYList ? repeatYList->item(i % repeatYList->length()) : repeatY; |
| 954 appendBackgroundRepeatValue(builder, xValue, yValue); | 931 appendBackgroundRepeatValue(builder, xValue, yValue); |
| 955 } | 932 } |
| 956 return builder.toString(); | 933 return builder.toString(); |
| 957 } | 934 } |
| 958 | 935 |
| 959 } // namespace blink | 936 } // namespace blink |
| OLD | NEW |