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 r
ights reserved. | 3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All r
ights reserved. |
4 * Copyright (C) 2011 Research In Motion Limited. All rights reserved. | 4 * Copyright (C) 2011 Research In Motion Limited. All rights reserved. |
5 * Copyright (C) 2013 Intel Corporation. All rights reserved. | 5 * Copyright (C) 2013 Intel Corporation. All rights reserved. |
6 * | 6 * |
7 * This library is free software; you can redistribute it and/or | 7 * This library is free software; you can redistribute it and/or |
8 * modify it under the terms of the GNU Library General Public | 8 * modify it under the terms of the GNU Library General Public |
9 * License as published by the Free Software Foundation; either | 9 * License as published by the Free Software Foundation; either |
10 * version 2 of the License, or (at your option) any later version. | 10 * version 2 of the License, or (at your option) any later version. |
11 * | 11 * |
12 * This library is distributed in the hope that it will be useful, | 12 * This library is distributed in the hope that it will be useful, |
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
15 * Library General Public License for more details. | 15 * Library General Public License for more details. |
16 * | 16 * |
17 * You should have received a copy of the GNU Library General Public License | 17 * You should have received a copy of the GNU Library General Public License |
18 * along with this library; see the file COPYING.LIB. If not, write to | 18 * along with this library; see the file COPYING.LIB. If not, write to |
19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
20 * Boston, MA 02110-1301, USA. | 20 * Boston, MA 02110-1301, USA. |
21 */ | 21 */ |
22 | 22 |
23 #include "core/css/StylePropertySerializer.h" | 23 #include "core/css/StylePropertySerializer.h" |
24 | 24 |
25 #include "core/CSSValueKeywords.h" | 25 #include "core/CSSValueKeywords.h" |
26 #include "core/StylePropertyShorthand.h" | 26 #include "core/StylePropertyShorthand.h" |
27 #include "core/css/CSSCustomPropertyDeclaration.h" | 27 #include "core/css/CSSCustomPropertyDeclaration.h" |
| 28 #include "core/css/CSSIdentifierValue.h" |
28 #include "core/css/CSSPendingSubstitutionValue.h" | 29 #include "core/css/CSSPendingSubstitutionValue.h" |
29 #include "core/css/CSSPropertyMetadata.h" | 30 #include "core/css/CSSPropertyMetadata.h" |
30 #include "core/css/CSSValuePool.h" | 31 #include "core/css/CSSValuePool.h" |
31 #include "wtf/StdLibExtras.h" | 32 #include "wtf/StdLibExtras.h" |
32 #include "wtf/text/StringBuilder.h" | 33 #include "wtf/text/StringBuilder.h" |
33 #include <bitset> | 34 #include <bitset> |
34 | 35 |
35 namespace blink { | 36 namespace blink { |
36 | 37 |
37 StylePropertySerializer::StylePropertySetForSerializer::StylePropertySetForSeria
lizer(const StylePropertySet& properties) | 38 StylePropertySerializer::StylePropertySetForSerializer::StylePropertySetForSeria
lizer(const StylePropertySet& properties) |
(...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
498 return horizontalValueCSSText; | 499 return horizontalValueCSSText; |
499 return horizontalValueCSSText + ' ' + verticalValueCSSText; | 500 return horizontalValueCSSText + ' ' + verticalValueCSSText; |
500 } | 501 } |
501 | 502 |
502 void StylePropertySerializer::appendFontLonghandValueIfNotNormal(CSSPropertyID p
ropertyID, StringBuilder& result) const | 503 void StylePropertySerializer::appendFontLonghandValueIfNotNormal(CSSPropertyID p
ropertyID, StringBuilder& result) const |
503 { | 504 { |
504 int foundPropertyIndex = m_propertySet.findPropertyIndex(propertyID); | 505 int foundPropertyIndex = m_propertySet.findPropertyIndex(propertyID); |
505 ASSERT(foundPropertyIndex != -1); | 506 ASSERT(foundPropertyIndex != -1); |
506 | 507 |
507 const CSSValue* val = m_propertySet.propertyAt(foundPropertyIndex).value(); | 508 const CSSValue* val = m_propertySet.propertyAt(foundPropertyIndex).value(); |
508 if (val->isPrimitiveValue() && toCSSPrimitiveValue(val)->getValueID() == CSS
ValueNormal) | 509 if (val->isIdentifierValue() && toCSSIdentifierValue(val)->getValueID() == C
SSValueNormal) |
509 return; | 510 return; |
510 | 511 |
511 char prefix = '\0'; | 512 char prefix = '\0'; |
512 switch (propertyID) { | 513 switch (propertyID) { |
513 case CSSPropertyFontStyle: | 514 case CSSPropertyFontStyle: |
514 break; // No prefix. | 515 break; // No prefix. |
515 case CSSPropertyFontFamily: | 516 case CSSPropertyFontFamily: |
516 case CSSPropertyFontStretch: | 517 case CSSPropertyFontStretch: |
517 case CSSPropertyFontVariantCaps: | 518 case CSSPropertyFontVariantCaps: |
518 case CSSPropertyFontVariantLigatures: | 519 case CSSPropertyFontVariantLigatures: |
519 case CSSPropertyFontVariantNumeric: | 520 case CSSPropertyFontVariantNumeric: |
520 case CSSPropertyFontWeight: | 521 case CSSPropertyFontWeight: |
521 prefix = ' '; | 522 prefix = ' '; |
522 break; | 523 break; |
523 case CSSPropertyLineHeight: | 524 case CSSPropertyLineHeight: |
524 prefix = '/'; | 525 prefix = '/'; |
525 break; | 526 break; |
526 default: | 527 default: |
527 ASSERT_NOT_REACHED(); | 528 ASSERT_NOT_REACHED(); |
528 } | 529 } |
529 | 530 |
530 if (prefix && !result.isEmpty()) | 531 if (prefix && !result.isEmpty()) |
531 result.append(prefix); | 532 result.append(prefix); |
532 | 533 |
533 String value; | 534 String value; |
534 // In the font-variant shorthand a "none" ligatures value needs to be expand
ed. | 535 // In the font-variant shorthand a "none" ligatures value needs to be expand
ed. |
535 if (propertyID == CSSPropertyFontVariantLigatures | 536 if (propertyID == CSSPropertyFontVariantLigatures |
536 && val->isPrimitiveValue() | 537 && val->isIdentifierValue() |
537 && toCSSPrimitiveValue(val)->getValueID() == CSSValueNone) { | 538 && toCSSIdentifierValue(val)->getValueID() == CSSValueNone) { |
538 value = "no-common-ligatures no-discretionary-ligatures no-historical-li
gatures no-contextual"; | 539 value = "no-common-ligatures no-discretionary-ligatures no-historical-li
gatures no-contextual"; |
539 } else { | 540 } else { |
540 value = m_propertySet.propertyAt(foundPropertyIndex).value()->cssText(); | 541 value = m_propertySet.propertyAt(foundPropertyIndex).value()->cssText(); |
541 } | 542 } |
542 | 543 |
543 result.append(value); | 544 result.append(value); |
544 } | 545 } |
545 | 546 |
546 String StylePropertySerializer::fontValue() const | 547 String StylePropertySerializer::fontValue() const |
547 { | 548 { |
(...skipping 10 matching lines...) Expand all Loading... |
558 | 559 |
559 PropertyValueForSerializer fontSizeProperty = m_propertySet.propertyAt(fontS
izePropertyIndex); | 560 PropertyValueForSerializer fontSizeProperty = m_propertySet.propertyAt(fontS
izePropertyIndex); |
560 PropertyValueForSerializer fontFamilyProperty = m_propertySet.propertyAt(fon
tFamilyPropertyIndex); | 561 PropertyValueForSerializer fontFamilyProperty = m_propertySet.propertyAt(fon
tFamilyPropertyIndex); |
561 PropertyValueForSerializer fontVariantCapsProperty = m_propertySet.propertyA
t(fontVariantCapsPropertyIndex); | 562 PropertyValueForSerializer fontVariantCapsProperty = m_propertySet.propertyA
t(fontVariantCapsPropertyIndex); |
562 PropertyValueForSerializer fontVariantLigaturesProperty = m_propertySet.prop
ertyAt(fontVariantLigaturesPropertyIndex); | 563 PropertyValueForSerializer fontVariantLigaturesProperty = m_propertySet.prop
ertyAt(fontVariantLigaturesPropertyIndex); |
563 PropertyValueForSerializer fontVariantNumericProperty = m_propertySet.proper
tyAt(fontVariantNumericPropertyIndex); | 564 PropertyValueForSerializer fontVariantNumericProperty = m_propertySet.proper
tyAt(fontVariantNumericPropertyIndex); |
564 | 565 |
565 // Check that non-initial font-variant subproperties are not conflicting wit
h this serialization. | 566 // Check that non-initial font-variant subproperties are not conflicting wit
h this serialization. |
566 const CSSValue* ligaturesValue = fontVariantLigaturesProperty.value(); | 567 const CSSValue* ligaturesValue = fontVariantLigaturesProperty.value(); |
567 const CSSValue* numericValue = fontVariantNumericProperty.value(); | 568 const CSSValue* numericValue = fontVariantNumericProperty.value(); |
568 if ((ligaturesValue->isPrimitiveValue() | 569 if ((ligaturesValue->isIdentifierValue() |
569 && toCSSPrimitiveValue(ligaturesValue)->getValueID() != CSSValueNormal) | 570 && toCSSIdentifierValue(ligaturesValue)->getValueID() != CSSValueNormal) |
570 || ligaturesValue->isValueList() | 571 || ligaturesValue->isValueList() |
571 || (numericValue->isPrimitiveValue() | 572 || (numericValue->isIdentifierValue() |
572 && toCSSPrimitiveValue(numericValue)->getValueID() != CSSValueNormal) | 573 && toCSSIdentifierValue(numericValue)->getValueID() != CSSValueNormal) |
573 || numericValue->isValueList()) | 574 || numericValue->isValueList()) |
574 return emptyString(); | 575 return emptyString(); |
575 | 576 |
576 StringBuilder result; | 577 StringBuilder result; |
577 appendFontLonghandValueIfNotNormal(CSSPropertyFontStyle, result); | 578 appendFontLonghandValueIfNotNormal(CSSPropertyFontStyle, result); |
578 | 579 |
579 const CSSValue* val = fontVariantCapsProperty.value(); | 580 const CSSValue* val = fontVariantCapsProperty.value(); |
580 if (val->isPrimitiveValue() | 581 if (val->isIdentifierValue() |
581 && (toCSSPrimitiveValue(val)->getValueID() != CSSValueSmallCaps | 582 && (toCSSIdentifierValue(val)->getValueID() != CSSValueSmallCaps |
582 && toCSSPrimitiveValue(val)->getValueID() != CSSValueNormal)) | 583 && toCSSIdentifierValue(val)->getValueID() != CSSValueNormal)) |
583 return emptyString(); | 584 return emptyString(); |
584 appendFontLonghandValueIfNotNormal(CSSPropertyFontVariantCaps, result); | 585 appendFontLonghandValueIfNotNormal(CSSPropertyFontVariantCaps, result); |
585 | 586 |
586 appendFontLonghandValueIfNotNormal(CSSPropertyFontWeight, result); | 587 appendFontLonghandValueIfNotNormal(CSSPropertyFontWeight, result); |
587 appendFontLonghandValueIfNotNormal(CSSPropertyFontStretch, result); | 588 appendFontLonghandValueIfNotNormal(CSSPropertyFontStretch, result); |
588 if (!result.isEmpty()) | 589 if (!result.isEmpty()) |
589 result.append(' '); | 590 result.append(' '); |
590 result.append(fontSizeProperty.value()->cssText()); | 591 result.append(fontSizeProperty.value()->cssText()); |
591 appendFontLonghandValueIfNotNormal(CSSPropertyLineHeight, result); | 592 appendFontLonghandValueIfNotNormal(CSSPropertyLineHeight, result); |
592 if (!result.isEmpty()) | 593 if (!result.isEmpty()) |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
702 if ((propertyIndex < size - 1 && m_propertySet.isPropertyImplicit(pr
operty)) | 703 if ((propertyIndex < size - 1 && m_propertySet.isPropertyImplicit(pr
operty)) |
703 && (property == CSSPropertyBackgroundRepeatX || property == CSSP
ropertyWebkitMaskRepeatX)) { | 704 && (property == CSSPropertyBackgroundRepeatX || property == CSSP
ropertyWebkitMaskRepeatX)) { |
704 ASSERT(shorthand.properties()[propertyIndex + 1] == CSSPropertyB
ackgroundRepeatY | 705 ASSERT(shorthand.properties()[propertyIndex + 1] == CSSPropertyB
ackgroundRepeatY |
705 || shorthand.properties()[propertyIndex + 1] == CSSPropertyW
ebkitMaskRepeatY); | 706 || shorthand.properties()[propertyIndex + 1] == CSSPropertyW
ebkitMaskRepeatY); |
706 const CSSValue& yValue = values[propertyIndex + 1]->isValueList(
) ? | 707 const CSSValue& yValue = values[propertyIndex + 1]->isValueList(
) ? |
707 toCSSValueList(values[propertyIndex + 1])->item(layer) : *va
lues[propertyIndex + 1]; | 708 toCSSValueList(values[propertyIndex + 1])->item(layer) : *va
lues[propertyIndex + 1]; |
708 | 709 |
709 | 710 |
710 // FIXME: At some point we need to fix this code to avoid return
ing an invalid shorthand, | 711 // FIXME: At some point we need to fix this code to avoid return
ing an invalid shorthand, |
711 // since some longhand combinations are not serializable into a
single shorthand. | 712 // since some longhand combinations are not serializable into a
single shorthand. |
712 if (!value->isPrimitiveValue() || !yValue.isPrimitiveValue()) | 713 if (!value->isIdentifierValue() || !yValue.isIdentifierValue()) |
713 continue; | 714 continue; |
714 | 715 |
715 CSSValueID xId = toCSSPrimitiveValue(value)->getValueID(); | 716 CSSValueID xId = toCSSIdentifierValue(value)->getValueID(); |
716 CSSValueID yId = toCSSPrimitiveValue(yValue).getValueID(); | 717 CSSValueID yId = toCSSIdentifierValue(yValue).getValueID(); |
717 // Maybe advance propertyIndex to look at the next CSSValue in t
he list for the checks below. | 718 // Maybe advance propertyIndex to look at the next CSSValue in t
he list for the checks below. |
718 if (xId == yId) { | 719 if (xId == yId) { |
719 useSingleWordShorthand = true; | 720 useSingleWordShorthand = true; |
720 property = shorthand.properties()[++propertyIndex]; | 721 property = shorthand.properties()[++propertyIndex]; |
721 } else if (xId == CSSValueRepeat && yId == CSSValueNoRepeat) { | 722 } else if (xId == CSSValueRepeat && yId == CSSValueNoRepeat) { |
722 useRepeatXShorthand = true; | 723 useRepeatXShorthand = true; |
723 property = shorthand.properties()[++propertyIndex]; | 724 property = shorthand.properties()[++propertyIndex]; |
724 } else if (xId == CSSValueNoRepeat && yId == CSSValueRepeat) { | 725 } else if (xId == CSSValueNoRepeat && yId == CSSValueRepeat) { |
725 useRepeatYShorthand = true; | 726 useRepeatYShorthand = true; |
726 property = shorthand.properties()[++propertyIndex]; | 727 property = shorthand.properties()[++propertyIndex]; |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
812 if (!result.isEmpty()) | 813 if (!result.isEmpty()) |
813 result.append(' '); | 814 result.append(' '); |
814 result.append(value); | 815 result.append(value); |
815 } | 816 } |
816 return result.isEmpty() ? String() : result.toString(); | 817 return result.isEmpty() ? String() : result.toString(); |
817 } | 818 } |
818 | 819 |
819 static void appendBackgroundRepeatValue(StringBuilder& builder, const CSSValue&
repeatXCSSValue, const CSSValue& repeatYCSSValue) | 820 static void appendBackgroundRepeatValue(StringBuilder& builder, const CSSValue&
repeatXCSSValue, const CSSValue& repeatYCSSValue) |
820 { | 821 { |
821 // FIXME: Ensure initial values do not appear in CSS_VALUE_LISTS. | 822 // FIXME: Ensure initial values do not appear in CSS_VALUE_LISTS. |
822 DEFINE_STATIC_LOCAL(CSSPrimitiveValue, initialRepeatValue, (CSSPrimitiveValu
e::createIdentifier(CSSValueRepeat))); | 823 DEFINE_STATIC_LOCAL(CSSIdentifierValue, initialRepeatValue, (CSSIdentifierVa
lue::createIdentifier(CSSValueRepeat))); |
823 const CSSPrimitiveValue& repeatX = repeatXCSSValue.isInitialValue() ? initia
lRepeatValue : toCSSPrimitiveValue(repeatXCSSValue); | 824 const CSSIdentifierValue& repeatX = repeatXCSSValue.isInitialValue() ? initi
alRepeatValue : toCSSIdentifierValue(repeatXCSSValue); |
824 const CSSPrimitiveValue& repeatY = repeatYCSSValue.isInitialValue() ? initia
lRepeatValue : toCSSPrimitiveValue(repeatYCSSValue); | 825 const CSSIdentifierValue& repeatY = repeatYCSSValue.isInitialValue() ? initi
alRepeatValue : toCSSIdentifierValue(repeatYCSSValue); |
825 CSSValueID repeatXValueId = repeatX.getValueID(); | 826 CSSValueID repeatXValueId = repeatX.getValueID(); |
826 CSSValueID repeatYValueId = repeatY.getValueID(); | 827 CSSValueID repeatYValueId = repeatY.getValueID(); |
827 if (repeatXValueId == repeatYValueId) { | 828 if (repeatXValueId == repeatYValueId) { |
828 builder.append(repeatX.cssText()); | 829 builder.append(repeatX.cssText()); |
829 } else if (repeatXValueId == CSSValueNoRepeat && repeatYValueId == CSSValueR
epeat) { | 830 } else if (repeatXValueId == CSSValueNoRepeat && repeatYValueId == CSSValueR
epeat) { |
830 builder.append("repeat-y"); | 831 builder.append("repeat-y"); |
831 } else if (repeatXValueId == CSSValueRepeat && repeatYValueId == CSSValueNoR
epeat) { | 832 } else if (repeatXValueId == CSSValueRepeat && repeatYValueId == CSSValueNoR
epeat) { |
832 builder.append("repeat-x"); | 833 builder.append("repeat-x"); |
833 } else { | 834 } else { |
834 builder.append(repeatX.cssText()); | 835 builder.append(repeatX.cssText()); |
835 builder.append(' '); | 836 builder.append(' '); |
836 builder.append(repeatY.cssText()); | 837 builder.append(repeatY.cssText()); |
837 } | 838 } |
838 } | 839 } |
839 | 840 |
840 String StylePropertySerializer::backgroundRepeatPropertyValue() const | 841 String StylePropertySerializer::backgroundRepeatPropertyValue() const |
841 { | 842 { |
842 const CSSValue& repeatX = *m_propertySet.getPropertyCSSValue(CSSPropertyBack
groundRepeatX); | 843 const CSSValue& repeatX = *m_propertySet.getPropertyCSSValue(CSSPropertyBack
groundRepeatX); |
843 const CSSValue& repeatY = *m_propertySet.getPropertyCSSValue(CSSPropertyBack
groundRepeatY); | 844 const CSSValue& repeatY = *m_propertySet.getPropertyCSSValue(CSSPropertyBack
groundRepeatY); |
844 | 845 |
845 const CSSValueList* repeatXList = 0; | 846 const CSSValueList* repeatXList = 0; |
846 int repeatXLength = 1; | 847 int repeatXLength = 1; |
847 if (repeatX.isValueList()) { | 848 if (repeatX.isValueList()) { |
848 repeatXList = &toCSSValueList(repeatX); | 849 repeatXList = &toCSSValueList(repeatX); |
849 repeatXLength = repeatXList->length(); | 850 repeatXLength = repeatXList->length(); |
850 } else if (!repeatX.isPrimitiveValue()) { | 851 } else if (!repeatX.isIdentifierValue()) { |
851 return String(); | 852 return String(); |
852 } | 853 } |
853 | 854 |
854 const CSSValueList* repeatYList = 0; | 855 const CSSValueList* repeatYList = 0; |
855 int repeatYLength = 1; | 856 int repeatYLength = 1; |
856 if (repeatY.isValueList()) { | 857 if (repeatY.isValueList()) { |
857 repeatYList = &toCSSValueList(repeatY); | 858 repeatYList = &toCSSValueList(repeatY); |
858 repeatYLength = repeatYList->length(); | 859 repeatYLength = repeatYList->length(); |
859 } else if (!repeatY.isPrimitiveValue()) { | 860 } else if (!repeatY.isIdentifierValue()) { |
860 return String(); | 861 return String(); |
861 } | 862 } |
862 | 863 |
863 size_t shorthandLength = lowestCommonMultiple(repeatXLength, repeatYLength); | 864 size_t shorthandLength = lowestCommonMultiple(repeatXLength, repeatYLength); |
864 StringBuilder builder; | 865 StringBuilder builder; |
865 for (size_t i = 0; i < shorthandLength; ++i) { | 866 for (size_t i = 0; i < shorthandLength; ++i) { |
866 if (i) | 867 if (i) |
867 builder.append(", "); | 868 builder.append(", "); |
868 | 869 |
869 const CSSValue& xValue = repeatXList ? repeatXList->item(i % repeatXList
->length()) : repeatX; | 870 const CSSValue& xValue = repeatXList ? repeatXList->item(i % repeatXList
->length()) : repeatX; |
870 const CSSValue& yValue = repeatYList ? repeatYList->item(i % repeatYList
->length()) : repeatY; | 871 const CSSValue& yValue = repeatYList ? repeatYList->item(i % repeatYList
->length()) : repeatY; |
871 appendBackgroundRepeatValue(builder, xValue, yValue); | 872 appendBackgroundRepeatValue(builder, xValue, yValue); |
872 } | 873 } |
873 return builder.toString(); | 874 return builder.toString(); |
874 } | 875 } |
875 | 876 |
876 } // namespace blink | 877 } // namespace blink |
OLD | NEW |