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 |