| 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:: | 38 StylePropertySerializer::StylePropertySetForSerializer:: |
| (...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 527 return horizontalValueCSSText + ' ' + verticalValueCSSText; | 528 return horizontalValueCSSText + ' ' + verticalValueCSSText; |
| 528 } | 529 } |
| 529 | 530 |
| 530 void StylePropertySerializer::appendFontLonghandValueIfNotNormal( | 531 void StylePropertySerializer::appendFontLonghandValueIfNotNormal( |
| 531 CSSPropertyID propertyID, | 532 CSSPropertyID propertyID, |
| 532 StringBuilder& result) const { | 533 StringBuilder& result) const { |
| 533 int foundPropertyIndex = m_propertySet.findPropertyIndex(propertyID); | 534 int foundPropertyIndex = m_propertySet.findPropertyIndex(propertyID); |
| 534 ASSERT(foundPropertyIndex != -1); | 535 ASSERT(foundPropertyIndex != -1); |
| 535 | 536 |
| 536 const CSSValue* val = m_propertySet.propertyAt(foundPropertyIndex).value(); | 537 const CSSValue* val = m_propertySet.propertyAt(foundPropertyIndex).value(); |
| 537 if (val->isPrimitiveValue() && | 538 if (val->isIdentifierValue() && |
| 538 toCSSPrimitiveValue(val)->getValueID() == CSSValueNormal) | 539 toCSSIdentifierValue(val)->getValueID() == CSSValueNormal) |
| 539 return; | 540 return; |
| 540 | 541 |
| 541 char prefix = '\0'; | 542 char prefix = '\0'; |
| 542 switch (propertyID) { | 543 switch (propertyID) { |
| 543 case CSSPropertyFontStyle: | 544 case CSSPropertyFontStyle: |
| 544 break; // No prefix. | 545 break; // No prefix. |
| 545 case CSSPropertyFontFamily: | 546 case CSSPropertyFontFamily: |
| 546 case CSSPropertyFontStretch: | 547 case CSSPropertyFontStretch: |
| 547 case CSSPropertyFontVariantCaps: | 548 case CSSPropertyFontVariantCaps: |
| 548 case CSSPropertyFontVariantLigatures: | 549 case CSSPropertyFontVariantLigatures: |
| 549 case CSSPropertyFontVariantNumeric: | 550 case CSSPropertyFontVariantNumeric: |
| 550 case CSSPropertyFontWeight: | 551 case CSSPropertyFontWeight: |
| 551 prefix = ' '; | 552 prefix = ' '; |
| 552 break; | 553 break; |
| 553 case CSSPropertyLineHeight: | 554 case CSSPropertyLineHeight: |
| 554 prefix = '/'; | 555 prefix = '/'; |
| 555 break; | 556 break; |
| 556 default: | 557 default: |
| 557 ASSERT_NOT_REACHED(); | 558 ASSERT_NOT_REACHED(); |
| 558 } | 559 } |
| 559 | 560 |
| 560 if (prefix && !result.isEmpty()) | 561 if (prefix && !result.isEmpty()) |
| 561 result.append(prefix); | 562 result.append(prefix); |
| 562 | 563 |
| 563 String value; | 564 String value; |
| 564 // In the font-variant shorthand a "none" ligatures value needs to be expanded
. | 565 // In the font-variant shorthand a "none" ligatures value needs to be expanded
. |
| 565 if (propertyID == CSSPropertyFontVariantLigatures && | 566 if (propertyID == CSSPropertyFontVariantLigatures && |
| 566 val->isPrimitiveValue() && | 567 val->isIdentifierValue() && |
| 567 toCSSPrimitiveValue(val)->getValueID() == CSSValueNone) { | 568 toCSSIdentifierValue(val)->getValueID() == CSSValueNone) { |
| 568 value = | 569 value = |
| 569 "no-common-ligatures no-discretionary-ligatures " | 570 "no-common-ligatures no-discretionary-ligatures " |
| 570 "no-historical-ligatures no-contextual"; | 571 "no-historical-ligatures no-contextual"; |
| 571 } else { | 572 } else { |
| 572 value = m_propertySet.propertyAt(foundPropertyIndex).value()->cssText(); | 573 value = m_propertySet.propertyAt(foundPropertyIndex).value()->cssText(); |
| 573 } | 574 } |
| 574 | 575 |
| 575 result.append(value); | 576 result.append(value); |
| 576 } | 577 } |
| 577 | 578 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 599 PropertyValueForSerializer fontVariantCapsProperty = | 600 PropertyValueForSerializer fontVariantCapsProperty = |
| 600 m_propertySet.propertyAt(fontVariantCapsPropertyIndex); | 601 m_propertySet.propertyAt(fontVariantCapsPropertyIndex); |
| 601 PropertyValueForSerializer fontVariantLigaturesProperty = | 602 PropertyValueForSerializer fontVariantLigaturesProperty = |
| 602 m_propertySet.propertyAt(fontVariantLigaturesPropertyIndex); | 603 m_propertySet.propertyAt(fontVariantLigaturesPropertyIndex); |
| 603 PropertyValueForSerializer fontVariantNumericProperty = | 604 PropertyValueForSerializer fontVariantNumericProperty = |
| 604 m_propertySet.propertyAt(fontVariantNumericPropertyIndex); | 605 m_propertySet.propertyAt(fontVariantNumericPropertyIndex); |
| 605 | 606 |
| 606 // Check that non-initial font-variant subproperties are not conflicting with
this serialization. | 607 // Check that non-initial font-variant subproperties are not conflicting with
this serialization. |
| 607 const CSSValue* ligaturesValue = fontVariantLigaturesProperty.value(); | 608 const CSSValue* ligaturesValue = fontVariantLigaturesProperty.value(); |
| 608 const CSSValue* numericValue = fontVariantNumericProperty.value(); | 609 const CSSValue* numericValue = fontVariantNumericProperty.value(); |
| 609 if ((ligaturesValue->isPrimitiveValue() && | 610 if ((ligaturesValue->isIdentifierValue() && |
| 610 toCSSPrimitiveValue(ligaturesValue)->getValueID() != CSSValueNormal) || | 611 toCSSIdentifierValue(ligaturesValue)->getValueID() != CSSValueNormal) || |
| 611 ligaturesValue->isValueList() || | 612 ligaturesValue->isValueList() || |
| 612 (numericValue->isPrimitiveValue() && | 613 (numericValue->isIdentifierValue() && |
| 613 toCSSPrimitiveValue(numericValue)->getValueID() != CSSValueNormal) || | 614 toCSSIdentifierValue(numericValue)->getValueID() != CSSValueNormal) || |
| 614 numericValue->isValueList()) | 615 numericValue->isValueList()) |
| 615 return emptyString(); | 616 return emptyString(); |
| 616 | 617 |
| 617 StringBuilder result; | 618 StringBuilder result; |
| 618 appendFontLonghandValueIfNotNormal(CSSPropertyFontStyle, result); | 619 appendFontLonghandValueIfNotNormal(CSSPropertyFontStyle, result); |
| 619 | 620 |
| 620 const CSSValue* val = fontVariantCapsProperty.value(); | 621 const CSSValue* val = fontVariantCapsProperty.value(); |
| 621 if (val->isPrimitiveValue() && | 622 if (val->isIdentifierValue() && |
| 622 (toCSSPrimitiveValue(val)->getValueID() != CSSValueSmallCaps && | 623 (toCSSIdentifierValue(val)->getValueID() != CSSValueSmallCaps && |
| 623 toCSSPrimitiveValue(val)->getValueID() != CSSValueNormal)) | 624 toCSSIdentifierValue(val)->getValueID() != CSSValueNormal)) |
| 624 return emptyString(); | 625 return emptyString(); |
| 625 appendFontLonghandValueIfNotNormal(CSSPropertyFontVariantCaps, result); | 626 appendFontLonghandValueIfNotNormal(CSSPropertyFontVariantCaps, result); |
| 626 | 627 |
| 627 appendFontLonghandValueIfNotNormal(CSSPropertyFontWeight, result); | 628 appendFontLonghandValueIfNotNormal(CSSPropertyFontWeight, result); |
| 628 appendFontLonghandValueIfNotNormal(CSSPropertyFontStretch, result); | 629 appendFontLonghandValueIfNotNormal(CSSPropertyFontStretch, result); |
| 629 if (!result.isEmpty()) | 630 if (!result.isEmpty()) |
| 630 result.append(' '); | 631 result.append(' '); |
| 631 result.append(fontSizeProperty.value()->cssText()); | 632 result.append(fontSizeProperty.value()->cssText()); |
| 632 appendFontLonghandValueIfNotNormal(CSSPropertyLineHeight, result); | 633 appendFontLonghandValueIfNotNormal(CSSPropertyLineHeight, result); |
| 633 if (!result.isEmpty()) | 634 if (!result.isEmpty()) |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 755 CSSPropertyBackgroundRepeatY || | 756 CSSPropertyBackgroundRepeatY || |
| 756 shorthand.properties()[propertyIndex + 1] == | 757 shorthand.properties()[propertyIndex + 1] == |
| 757 CSSPropertyWebkitMaskRepeatY); | 758 CSSPropertyWebkitMaskRepeatY); |
| 758 const CSSValue& yValue = | 759 const CSSValue& yValue = |
| 759 values[propertyIndex + 1]->isValueList() | 760 values[propertyIndex + 1]->isValueList() |
| 760 ? toCSSValueList(values[propertyIndex + 1])->item(layer) | 761 ? toCSSValueList(values[propertyIndex + 1])->item(layer) |
| 761 : *values[propertyIndex + 1]; | 762 : *values[propertyIndex + 1]; |
| 762 | 763 |
| 763 // FIXME: At some point we need to fix this code to avoid returning an i
nvalid shorthand, | 764 // FIXME: At some point we need to fix this code to avoid returning an i
nvalid shorthand, |
| 764 // since some longhand combinations are not serializable into a single s
horthand. | 765 // since some longhand combinations are not serializable into a single s
horthand. |
| 765 if (!value->isPrimitiveValue() || !yValue.isPrimitiveValue()) | 766 if (!value->isIdentifierValue() || !yValue.isIdentifierValue()) |
| 766 continue; | 767 continue; |
| 767 | 768 |
| 768 CSSValueID xId = toCSSPrimitiveValue(value)->getValueID(); | 769 CSSValueID xId = toCSSIdentifierValue(value)->getValueID(); |
| 769 CSSValueID yId = toCSSPrimitiveValue(yValue).getValueID(); | 770 CSSValueID yId = toCSSIdentifierValue(yValue).getValueID(); |
| 770 // Maybe advance propertyIndex to look at the next CSSValue in the list
for the checks below. | 771 // Maybe advance propertyIndex to look at the next CSSValue in the list
for the checks below. |
| 771 if (xId == yId) { | 772 if (xId == yId) { |
| 772 useSingleWordShorthand = true; | 773 useSingleWordShorthand = true; |
| 773 property = shorthand.properties()[++propertyIndex]; | 774 property = shorthand.properties()[++propertyIndex]; |
| 774 } else if (xId == CSSValueRepeat && yId == CSSValueNoRepeat) { | 775 } else if (xId == CSSValueRepeat && yId == CSSValueNoRepeat) { |
| 775 useRepeatXShorthand = true; | 776 useRepeatXShorthand = true; |
| 776 property = shorthand.properties()[++propertyIndex]; | 777 property = shorthand.properties()[++propertyIndex]; |
| 777 } else if (xId == CSSValueNoRepeat && yId == CSSValueRepeat) { | 778 } else if (xId == CSSValueNoRepeat && yId == CSSValueRepeat) { |
| 778 useRepeatYShorthand = true; | 779 useRepeatYShorthand = true; |
| 779 property = shorthand.properties()[++propertyIndex]; | 780 property = shorthand.properties()[++propertyIndex]; |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 873 result.append(' '); | 874 result.append(' '); |
| 874 result.append(value); | 875 result.append(value); |
| 875 } | 876 } |
| 876 return result.isEmpty() ? String() : result.toString(); | 877 return result.isEmpty() ? String() : result.toString(); |
| 877 } | 878 } |
| 878 | 879 |
| 879 static void appendBackgroundRepeatValue(StringBuilder& builder, | 880 static void appendBackgroundRepeatValue(StringBuilder& builder, |
| 880 const CSSValue& repeatXCSSValue, | 881 const CSSValue& repeatXCSSValue, |
| 881 const CSSValue& repeatYCSSValue) { | 882 const CSSValue& repeatYCSSValue) { |
| 882 // FIXME: Ensure initial values do not appear in CSS_VALUE_LISTS. | 883 // FIXME: Ensure initial values do not appear in CSS_VALUE_LISTS. |
| 883 DEFINE_STATIC_LOCAL(CSSPrimitiveValue, initialRepeatValue, | 884 DEFINE_STATIC_LOCAL(CSSIdentifierValue, initialRepeatValue, |
| 884 (CSSPrimitiveValue::createIdentifier(CSSValueRepeat))); | 885 (CSSIdentifierValue::create(CSSValueRepeat))); |
| 885 const CSSPrimitiveValue& repeatX = repeatXCSSValue.isInitialValue() | 886 const CSSIdentifierValue& repeatX = |
| 886 ? initialRepeatValue | 887 repeatXCSSValue.isInitialValue() ? initialRepeatValue |
| 887 : toCSSPrimitiveValue(repeatXCSSValue); | 888 : toCSSIdentifierValue(repeatXCSSValue); |
| 888 const CSSPrimitiveValue& repeatY = repeatYCSSValue.isInitialValue() | 889 const CSSIdentifierValue& repeatY = |
| 889 ? initialRepeatValue | 890 repeatYCSSValue.isInitialValue() ? initialRepeatValue |
| 890 : toCSSPrimitiveValue(repeatYCSSValue); | 891 : toCSSIdentifierValue(repeatYCSSValue); |
| 891 CSSValueID repeatXValueId = repeatX.getValueID(); | 892 CSSValueID repeatXValueId = repeatX.getValueID(); |
| 892 CSSValueID repeatYValueId = repeatY.getValueID(); | 893 CSSValueID repeatYValueId = repeatY.getValueID(); |
| 893 if (repeatXValueId == repeatYValueId) { | 894 if (repeatXValueId == repeatYValueId) { |
| 894 builder.append(repeatX.cssText()); | 895 builder.append(repeatX.cssText()); |
| 895 } else if (repeatXValueId == CSSValueNoRepeat && | 896 } else if (repeatXValueId == CSSValueNoRepeat && |
| 896 repeatYValueId == CSSValueRepeat) { | 897 repeatYValueId == CSSValueRepeat) { |
| 897 builder.append("repeat-y"); | 898 builder.append("repeat-y"); |
| 898 } else if (repeatXValueId == CSSValueRepeat && | 899 } else if (repeatXValueId == CSSValueRepeat && |
| 899 repeatYValueId == CSSValueNoRepeat) { | 900 repeatYValueId == CSSValueNoRepeat) { |
| 900 builder.append("repeat-x"); | 901 builder.append("repeat-x"); |
| 901 } else { | 902 } else { |
| 902 builder.append(repeatX.cssText()); | 903 builder.append(repeatX.cssText()); |
| 903 builder.append(' '); | 904 builder.append(' '); |
| 904 builder.append(repeatY.cssText()); | 905 builder.append(repeatY.cssText()); |
| 905 } | 906 } |
| 906 } | 907 } |
| 907 | 908 |
| 908 String StylePropertySerializer::backgroundRepeatPropertyValue() const { | 909 String StylePropertySerializer::backgroundRepeatPropertyValue() const { |
| 909 const CSSValue& repeatX = | 910 const CSSValue& repeatX = |
| 910 *m_propertySet.getPropertyCSSValue(CSSPropertyBackgroundRepeatX); | 911 *m_propertySet.getPropertyCSSValue(CSSPropertyBackgroundRepeatX); |
| 911 const CSSValue& repeatY = | 912 const CSSValue& repeatY = |
| 912 *m_propertySet.getPropertyCSSValue(CSSPropertyBackgroundRepeatY); | 913 *m_propertySet.getPropertyCSSValue(CSSPropertyBackgroundRepeatY); |
| 913 | 914 |
| 914 const CSSValueList* repeatXList = 0; | 915 const CSSValueList* repeatXList = 0; |
| 915 int repeatXLength = 1; | 916 int repeatXLength = 1; |
| 916 if (repeatX.isValueList()) { | 917 if (repeatX.isValueList()) { |
| 917 repeatXList = &toCSSValueList(repeatX); | 918 repeatXList = &toCSSValueList(repeatX); |
| 918 repeatXLength = repeatXList->length(); | 919 repeatXLength = repeatXList->length(); |
| 919 } else if (!repeatX.isPrimitiveValue()) { | 920 } else if (!repeatX.isIdentifierValue()) { |
| 920 return String(); | 921 return String(); |
| 921 } | 922 } |
| 922 | 923 |
| 923 const CSSValueList* repeatYList = 0; | 924 const CSSValueList* repeatYList = 0; |
| 924 int repeatYLength = 1; | 925 int repeatYLength = 1; |
| 925 if (repeatY.isValueList()) { | 926 if (repeatY.isValueList()) { |
| 926 repeatYList = &toCSSValueList(repeatY); | 927 repeatYList = &toCSSValueList(repeatY); |
| 927 repeatYLength = repeatYList->length(); | 928 repeatYLength = repeatYList->length(); |
| 928 } else if (!repeatY.isPrimitiveValue()) { | 929 } else if (!repeatY.isIdentifierValue()) { |
| 929 return String(); | 930 return String(); |
| 930 } | 931 } |
| 931 | 932 |
| 932 size_t shorthandLength = lowestCommonMultiple(repeatXLength, repeatYLength); | 933 size_t shorthandLength = lowestCommonMultiple(repeatXLength, repeatYLength); |
| 933 StringBuilder builder; | 934 StringBuilder builder; |
| 934 for (size_t i = 0; i < shorthandLength; ++i) { | 935 for (size_t i = 0; i < shorthandLength; ++i) { |
| 935 if (i) | 936 if (i) |
| 936 builder.append(", "); | 937 builder.append(", "); |
| 937 | 938 |
| 938 const CSSValue& xValue = | 939 const CSSValue& xValue = |
| 939 repeatXList ? repeatXList->item(i % repeatXList->length()) : repeatX; | 940 repeatXList ? repeatXList->item(i % repeatXList->length()) : repeatX; |
| 940 const CSSValue& yValue = | 941 const CSSValue& yValue = |
| 941 repeatYList ? repeatYList->item(i % repeatYList->length()) : repeatY; | 942 repeatYList ? repeatYList->item(i % repeatYList->length()) : repeatY; |
| 942 appendBackgroundRepeatValue(builder, xValue, yValue); | 943 appendBackgroundRepeatValue(builder, xValue, yValue); |
| 943 } | 944 } |
| 944 return builder.toString(); | 945 return builder.toString(); |
| 945 } | 946 } |
| 946 | 947 |
| 947 } // namespace blink | 948 } // namespace blink |
| OLD | NEW |