| 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 "config.h" | 23 #include "config.h" |
| 24 #include "core/css/StylePropertySerializer.h" | 24 #include "core/css/StylePropertySerializer.h" |
| 25 | 25 |
| 26 #include "core/CSSValueKeywords.h" | 26 #include "core/CSSValueKeywords.h" |
| 27 #include "core/StylePropertyShorthand.h" | 27 #include "core/StylePropertyShorthand.h" |
| 28 #include "core/css/CSSPropertyMetadata.h" | 28 #include "core/css/CSSPropertyMetadata.h" |
| 29 #include "core/css/CSSValuePool.h" |
| 29 #include "wtf/BitArray.h" | 30 #include "wtf/BitArray.h" |
| 30 #include "wtf/text/StringBuilder.h" | 31 #include "wtf/text/StringBuilder.h" |
| 31 | 32 |
| 32 namespace blink { | 33 namespace blink { |
| 33 | 34 |
| 34 static bool isInitialOrInherit(const String& value) | 35 static bool isInitialOrInherit(const String& value) |
| 35 { | 36 { |
| 36 DEFINE_STATIC_LOCAL(String, initial, ("initial")); | 37 DEFINE_STATIC_LOCAL(String, initial, ("initial")); |
| 37 DEFINE_STATIC_LOCAL(String, inherit, ("inherit")); | 38 DEFINE_STATIC_LOCAL(String, inherit, ("inherit")); |
| 38 return value.length() == 7 && (value == initial || value == inherit); | 39 return value.length() == 7 && (value == initial || value == inherit); |
| 39 } | 40 } |
| 40 | 41 |
| 42 StylePropertySerializer::StylePropertySetForSerializer::StylePropertySetForSeria
lizer(const StylePropertySet& properties) |
| 43 : m_propertySet(properties) |
| 44 , m_allIndex(m_propertySet.findPropertyIndex(CSSPropertyAll)) |
| 45 , m_needToExpandAll(false) |
| 46 { |
| 47 if (!hasAllProperty()) |
| 48 return; |
| 49 |
| 50 StylePropertySet::PropertyReference allProperty = m_propertySet.propertyAt(m
_allIndex); |
| 51 for (unsigned i = 0; i < m_propertySet.propertyCount(); ++i) { |
| 52 StylePropertySet::PropertyReference property = m_propertySet.propertyAt(
i); |
| 53 if (CSSProperty::isAffectedByAllProperty(property.id())) { |
| 54 if (allProperty.isImportant() && !property.isImportant()) |
| 55 continue; |
| 56 if (static_cast<unsigned>(m_allIndex) >= i) |
| 57 continue; |
| 58 if (property.value()->equals(*allProperty.value()) |
| 59 && property.isImportant() == allProperty.isImportant()) |
| 60 continue; |
| 61 m_needToExpandAll = true; |
| 62 } |
| 63 m_longhandPropertyUsed.set(property.id() - firstCSSProperty); |
| 64 } |
| 65 } |
| 66 |
| 67 unsigned StylePropertySerializer::StylePropertySetForSerializer::propertyCount()
const |
| 68 { |
| 69 if (!hasExpandedAllProperty()) |
| 70 return m_propertySet.propertyCount(); |
| 71 return lastCSSProperty - firstCSSProperty + 1; |
| 72 } |
| 73 |
| 74 StylePropertySerializer::PropertyValueForSerializer StylePropertySerializer::Sty
lePropertySetForSerializer::propertyAt(unsigned index) const |
| 75 { |
| 76 if (!hasExpandedAllProperty()) |
| 77 return StylePropertySerializer::PropertyValueForSerializer(m_propertySet
.propertyAt(index)); |
| 78 |
| 79 CSSPropertyID propertyID = static_cast<CSSPropertyID>(index + firstCSSProper
ty); |
| 80 ASSERT(firstCSSProperty <= propertyID && propertyID <= lastCSSProperty); |
| 81 if (m_longhandPropertyUsed.get(index)) { |
| 82 int index = m_propertySet.findPropertyIndex(propertyID); |
| 83 ASSERT(index != -1); |
| 84 return StylePropertySerializer::PropertyValueForSerializer(m_propertySet
.propertyAt(index)); |
| 85 } |
| 86 |
| 87 StylePropertySet::PropertyReference property = m_propertySet.propertyAt(m_al
lIndex); |
| 88 const CSSValue* value = property.value(); |
| 89 |
| 90 // FIXME: Firefox shows properties with "unset" when some cssRule has |
| 91 // expanded "all" with "unset". So we should use "unset" here. |
| 92 // After implementing "unset" value correctly, (i.e. StyleBuilder should |
| 93 // support "display: unset", "color: unset", ... and so on), |
| 94 // we should fix the following code. |
| 95 if (!value->isInitialValue() && !value->isInheritedValue()) { |
| 96 if (CSSPropertyMetadata::isInheritedProperty(propertyID)) |
| 97 value = cssValuePool().createInheritedValue().get(); |
| 98 else |
| 99 value = cssValuePool().createExplicitInitialValue().get(); |
| 100 } |
| 101 return StylePropertySerializer::PropertyValueForSerializer(propertyID, value
, property.isImportant()); |
| 102 } |
| 103 |
| 104 bool StylePropertySerializer::StylePropertySetForSerializer::shouldProcessProper
tyAt(unsigned index) const |
| 105 { |
| 106 // StylePropertySet has all valid longhands. We should process. |
| 107 if (!hasAllProperty()) |
| 108 return true; |
| 109 |
| 110 // If all is not expanded, we need to process "all" and properties which |
| 111 // are not overwritten by "all". |
| 112 if (!m_needToExpandAll) { |
| 113 StylePropertySet::PropertyReference property = m_propertySet.propertyAt(
index); |
| 114 if (property.id() == CSSPropertyAll || !CSSProperty::isAffectedByAllProp
erty(property.id())) |
| 115 return true; |
| 116 return m_longhandPropertyUsed.get(property.id() - firstCSSProperty); |
| 117 } |
| 118 |
| 119 CSSPropertyID propertyID = static_cast<CSSPropertyID>(index + firstCSSProper
ty); |
| 120 ASSERT(firstCSSProperty <= propertyID && propertyID <= lastCSSProperty); |
| 121 |
| 122 // Since "all" is expanded, we don't need to process "all". |
| 123 // We should not process expanded shorthands (e.g. font, background, |
| 124 // and so on) either. |
| 125 if (isExpandedShorthandForAll(propertyID) || propertyID == CSSPropertyAll) |
| 126 return false; |
| 127 // We should not serialize internal properties. |
| 128 if (isInternalProperty(propertyID)) |
| 129 return false; |
| 130 |
| 131 // The all property is a shorthand that resets all CSS properties except |
| 132 // direction and unicode-bidi. It only accepts the CSS-wide keywords. |
| 133 // c.f. http://dev.w3.org/csswg/css-cascade/#all-shorthand |
| 134 if (!CSSProperty::isAffectedByAllProperty(propertyID)) |
| 135 return m_longhandPropertyUsed.get(index); |
| 136 |
| 137 return true; |
| 138 } |
| 139 |
| 140 int StylePropertySerializer::StylePropertySetForSerializer::findPropertyIndex(CS
SPropertyID propertyID) const |
| 141 { |
| 142 if (!hasExpandedAllProperty()) |
| 143 return m_propertySet.findPropertyIndex(propertyID); |
| 144 return propertyID - firstCSSProperty; |
| 145 } |
| 146 |
| 147 const CSSValue* StylePropertySerializer::StylePropertySetForSerializer::getPrope
rtyCSSValue(CSSPropertyID propertyID) const |
| 148 { |
| 149 int index = findPropertyIndex(propertyID); |
| 150 if (index == -1) |
| 151 return 0; |
| 152 StylePropertySerializer::PropertyValueForSerializer value = propertyAt(index
); |
| 153 return value.value(); |
| 154 } |
| 155 |
| 156 String StylePropertySerializer::StylePropertySetForSerializer::getPropertyValue(
CSSPropertyID propertyID) const |
| 157 { |
| 158 if (!hasExpandedAllProperty()) |
| 159 return m_propertySet.getPropertyValue(propertyID); |
| 160 |
| 161 const CSSValue* value = getPropertyCSSValue(propertyID); |
| 162 if (!value) |
| 163 return String(); |
| 164 return value->cssText(); |
| 165 } |
| 166 |
| 167 bool StylePropertySerializer::StylePropertySetForSerializer::isPropertyImplicit(
CSSPropertyID propertyID) const |
| 168 { |
| 169 int index = findPropertyIndex(propertyID); |
| 170 if (index == -1) |
| 171 return false; |
| 172 StylePropertySerializer::PropertyValueForSerializer value = propertyAt(index
); |
| 173 return value.isImplicit(); |
| 174 } |
| 175 |
| 176 bool StylePropertySerializer::StylePropertySetForSerializer::propertyIsImportant
(CSSPropertyID propertyID) const |
| 177 { |
| 178 int index = findPropertyIndex(propertyID); |
| 179 if (index == -1) |
| 180 return false; |
| 181 StylePropertySerializer::PropertyValueForSerializer value = propertyAt(index
); |
| 182 return value.isImportant(); |
| 183 } |
| 184 |
| 41 StylePropertySerializer::StylePropertySerializer(const StylePropertySet& propert
ies) | 185 StylePropertySerializer::StylePropertySerializer(const StylePropertySet& propert
ies) |
| 42 : m_propertySet(properties) | 186 : m_propertySet(properties) |
| 43 { | 187 { |
| 44 } | 188 } |
| 45 | 189 |
| 46 String StylePropertySerializer::getPropertyText(CSSPropertyID propertyID, const
String& value, bool isImportant, bool isNotFirstDecl) const | 190 String StylePropertySerializer::getPropertyText(CSSPropertyID propertyID, const
String& value, bool isImportant, bool isNotFirstDecl) const |
| 47 { | 191 { |
| 48 StringBuilder result; | 192 StringBuilder result; |
| 49 if (isNotFirstDecl) | 193 if (isNotFirstDecl) |
| 50 result.append(' '); | 194 result.append(' '); |
| 51 result.append(getPropertyName(propertyID)); | 195 result.append(getPropertyName(propertyID)); |
| 52 result.appendLiteral(": "); | 196 result.appendLiteral(": "); |
| 53 result.append(value); | 197 result.append(value); |
| 54 if (isImportant) | 198 if (isImportant) |
| 55 result.appendLiteral(" !important"); | 199 result.appendLiteral(" !important"); |
| 56 result.append(';'); | 200 result.append(';'); |
| 57 return result.toString(); | 201 return result.toString(); |
| 58 } | 202 } |
| 59 | 203 |
| 60 String StylePropertySerializer::asText() const | 204 String StylePropertySerializer::asText() const |
| 61 { | 205 { |
| 62 StringBuilder result; | 206 StringBuilder result; |
| 63 | 207 |
| 64 BitArray<numCSSProperties> shorthandPropertyUsed; | 208 BitArray<numCSSProperties> shorthandPropertyUsed; |
| 65 BitArray<numCSSProperties> shorthandPropertyAppeared; | 209 BitArray<numCSSProperties> shorthandPropertyAppeared; |
| 66 | 210 |
| 67 unsigned size = m_propertySet.propertyCount(); | 211 unsigned size = m_propertySet.propertyCount(); |
| 68 unsigned numDecls = 0; | 212 unsigned numDecls = 0; |
| 69 for (unsigned n = 0; n < size; ++n) { | 213 for (unsigned n = 0; n < size; ++n) { |
| 70 StylePropertySet::PropertyReference property = m_propertySet.propertyAt(
n); | 214 if (!m_propertySet.shouldProcessPropertyAt(n)) |
| 215 continue; |
| 216 |
| 217 StylePropertySerializer::PropertyValueForSerializer property = m_propert
ySet.propertyAt(n); |
| 71 CSSPropertyID propertyID = property.id(); | 218 CSSPropertyID propertyID = property.id(); |
| 72 // Only enabled or internal properties should be part of the style. | 219 // Only enabled or internal properties should be part of the style. |
| 73 ASSERT(CSSPropertyMetadata::isEnabledProperty(propertyID) || isInternalP
roperty(propertyID)); | 220 ASSERT(CSSPropertyMetadata::isEnabledProperty(propertyID) || isInternalP
roperty(propertyID)); |
| 74 CSSPropertyID shorthandPropertyID = CSSPropertyInvalid; | 221 CSSPropertyID shorthandPropertyID = CSSPropertyInvalid; |
| 75 CSSPropertyID borderFallbackShorthandProperty = CSSPropertyInvalid; | 222 CSSPropertyID borderFallbackShorthandProperty = CSSPropertyInvalid; |
| 76 String value; | 223 String value; |
| 224 ASSERT(!isExpandedShorthandForAll(propertyID)); |
| 77 | 225 |
| 78 switch (propertyID) { | 226 switch (propertyID) { |
| 79 case CSSPropertyBackgroundAttachment: | 227 case CSSPropertyBackgroundAttachment: |
| 80 case CSSPropertyBackgroundClip: | 228 case CSSPropertyBackgroundClip: |
| 81 case CSSPropertyBackgroundColor: | 229 case CSSPropertyBackgroundColor: |
| 82 case CSSPropertyBackgroundImage: | 230 case CSSPropertyBackgroundImage: |
| 83 case CSSPropertyBackgroundOrigin: | 231 case CSSPropertyBackgroundOrigin: |
| 84 case CSSPropertyBackgroundPositionX: | 232 case CSSPropertyBackgroundPositionX: |
| 85 case CSSPropertyBackgroundPositionY: | 233 case CSSPropertyBackgroundPositionY: |
| 86 case CSSPropertyBackgroundSize: | 234 case CSSPropertyBackgroundSize: |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 202 case CSSPropertyWebkitMaskClip: | 350 case CSSPropertyWebkitMaskClip: |
| 203 case CSSPropertyWebkitMaskOrigin: | 351 case CSSPropertyWebkitMaskOrigin: |
| 204 shorthandPropertyID = CSSPropertyWebkitMask; | 352 shorthandPropertyID = CSSPropertyWebkitMask; |
| 205 break; | 353 break; |
| 206 case CSSPropertyWebkitTransitionProperty: | 354 case CSSPropertyWebkitTransitionProperty: |
| 207 case CSSPropertyWebkitTransitionDuration: | 355 case CSSPropertyWebkitTransitionDuration: |
| 208 case CSSPropertyWebkitTransitionTimingFunction: | 356 case CSSPropertyWebkitTransitionTimingFunction: |
| 209 case CSSPropertyWebkitTransitionDelay: | 357 case CSSPropertyWebkitTransitionDelay: |
| 210 shorthandPropertyID = CSSPropertyWebkitTransition; | 358 shorthandPropertyID = CSSPropertyWebkitTransition; |
| 211 break; | 359 break; |
| 360 case CSSPropertyAll: |
| 361 result.append(getPropertyText(propertyID, property.value()->cssText(
), property.isImportant(), numDecls++)); |
| 362 continue; |
| 212 default: | 363 default: |
| 213 break; | 364 break; |
| 214 } | 365 } |
| 215 | 366 |
| 216 unsigned shortPropertyIndex = shorthandPropertyID - firstCSSProperty; | 367 unsigned shortPropertyIndex = shorthandPropertyID - firstCSSProperty; |
| 217 if (shorthandPropertyID) { | 368 if (shorthandPropertyID) { |
| 218 if (shorthandPropertyUsed.get(shortPropertyIndex)) | 369 if (shorthandPropertyUsed.get(shortPropertyIndex)) |
| 219 continue; | 370 continue; |
| 220 if (!shorthandPropertyAppeared.get(shortPropertyIndex) && value.isNu
ll()) | 371 if (!shorthandPropertyAppeared.get(shortPropertyIndex) && value.isNu
ll()) |
| 221 value = m_propertySet.getPropertyValue(shorthandPropertyID); | 372 value = m_propertySet.getPropertyValue(shorthandPropertyID); |
| 222 shorthandPropertyAppeared.set(shortPropertyIndex); | 373 shorthandPropertyAppeared.set(shortPropertyIndex); |
| 223 } | 374 } |
| 224 | 375 |
| 225 if (!value.isNull()) { | 376 if (!value.isNull()) { |
| 226 if (shorthandPropertyID) { | 377 if (shorthandPropertyID) { |
| 227 propertyID = shorthandPropertyID; | 378 propertyID = shorthandPropertyID; |
| 228 shorthandPropertyUsed.set(shortPropertyIndex); | 379 shorthandPropertyUsed.set(shortPropertyIndex); |
| 229 } | 380 } |
| 230 } else | 381 } else { |
| 382 // We should not show "initial" when the "initial" is implicit. |
| 383 // If explicit "initial", we need to show. |
| 384 if (property.value()->isImplicitInitialValue()) |
| 385 continue; |
| 231 value = property.value()->cssText(); | 386 value = property.value()->cssText(); |
| 232 | 387 } |
| 233 if (value == "initial" && !CSSPropertyMetadata::isInheritedProperty(prop
ertyID)) | |
| 234 continue; | |
| 235 | 388 |
| 236 result.append(getPropertyText(propertyID, value, property.isImportant(),
numDecls++)); | 389 result.append(getPropertyText(propertyID, value, property.isImportant(),
numDecls++)); |
| 237 } | 390 } |
| 238 | 391 |
| 239 if (shorthandPropertyAppeared.get(CSSPropertyBackground - firstCSSProperty)) | 392 if (shorthandPropertyAppeared.get(CSSPropertyBackground - firstCSSProperty)) |
| 240 appendBackgroundPropertyAsText(result, numDecls); | 393 appendBackgroundPropertyAsText(result, numDecls); |
| 241 | 394 |
| 242 ASSERT(!numDecls ^ !result.isEmpty()); | 395 ASSERT(!numDecls ^ !result.isEmpty()); |
| 243 return result.toString(); | 396 return result.toString(); |
| 244 } | 397 } |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 311 return getLayeredShorthandValue(webkitMaskShorthand()); | 464 return getLayeredShorthandValue(webkitMaskShorthand()); |
| 312 case CSSPropertyWebkitTextEmphasis: | 465 case CSSPropertyWebkitTextEmphasis: |
| 313 return getShorthandValue(webkitTextEmphasisShorthand()); | 466 return getShorthandValue(webkitTextEmphasisShorthand()); |
| 314 case CSSPropertyWebkitTextStroke: | 467 case CSSPropertyWebkitTextStroke: |
| 315 return getShorthandValue(webkitTextStrokeShorthand()); | 468 return getShorthandValue(webkitTextStrokeShorthand()); |
| 316 case CSSPropertyWebkitTransition: | 469 case CSSPropertyWebkitTransition: |
| 317 return getLayeredShorthandValue(webkitTransitionShorthand(), true); | 470 return getLayeredShorthandValue(webkitTransitionShorthand(), true); |
| 318 case CSSPropertyWebkitAnimation: | 471 case CSSPropertyWebkitAnimation: |
| 319 return getLayeredShorthandValue(webkitAnimationShorthand(), true); | 472 return getLayeredShorthandValue(webkitAnimationShorthand(), true); |
| 320 case CSSPropertyMarker: { | 473 case CSSPropertyMarker: { |
| 321 RefPtrWillBeRawPtr<CSSValue> value = m_propertySet.getPropertyCSSValue(C
SSPropertyMarkerStart); | 474 if (const CSSValue* value = m_propertySet.getPropertyCSSValue(CSSPropert
yMarkerStart)) |
| 322 if (value) | |
| 323 return value->cssText(); | 475 return value->cssText(); |
| 324 return String(); | 476 return String(); |
| 325 } | 477 } |
| 326 case CSSPropertyBorderRadius: | 478 case CSSPropertyBorderRadius: |
| 327 return get4Values(borderRadiusShorthand()); | 479 return get4Values(borderRadiusShorthand()); |
| 328 default: | 480 default: |
| 329 return String(); | 481 return String(); |
| 330 } | 482 } |
| 331 } | 483 } |
| 332 | 484 |
| 333 String StylePropertySerializer::borderSpacingValue(const StylePropertyShorthand&
shorthand) const | 485 String StylePropertySerializer::borderSpacingValue(const StylePropertyShorthand&
shorthand) const |
| 334 { | 486 { |
| 335 RefPtrWillBeRawPtr<CSSValue> horizontalValue = m_propertySet.getPropertyCSSV
alue(shorthand.properties()[0]); | 487 const CSSValue* horizontalValue = m_propertySet.getPropertyCSSValue(shorthan
d.properties()[0]); |
| 336 RefPtrWillBeRawPtr<CSSValue> verticalValue = m_propertySet.getPropertyCSSVal
ue(shorthand.properties()[1]); | 488 const CSSValue* verticalValue = m_propertySet.getPropertyCSSValue(shorthand.
properties()[1]); |
| 337 | 489 |
| 338 // While standard border-spacing property does not allow specifying border-s
pacing-vertical without | 490 // While standard border-spacing property does not allow specifying border-s
pacing-vertical without |
| 339 // specifying border-spacing-horizontal <http://www.w3.org/TR/CSS21/tables.h
tml#separated-borders>, | 491 // specifying border-spacing-horizontal <http://www.w3.org/TR/CSS21/tables.h
tml#separated-borders>, |
| 340 // -webkit-border-spacing-vertical can be set without -webkit-border-spacing
-horizontal. | 492 // -webkit-border-spacing-vertical can be set without -webkit-border-spacing
-horizontal. |
| 341 if (!horizontalValue || !verticalValue) | 493 if (!horizontalValue || !verticalValue) |
| 342 return String(); | 494 return String(); |
| 343 | 495 |
| 344 String horizontalValueCSSText = horizontalValue->cssText(); | 496 String horizontalValueCSSText = horizontalValue->cssText(); |
| 345 String verticalValueCSSText = verticalValue->cssText(); | 497 String verticalValueCSSText = verticalValue->cssText(); |
| 346 if (horizontalValueCSSText == verticalValueCSSText) | 498 if (horizontalValueCSSText == verticalValueCSSText) |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 384 commonValue = String(); | 536 commonValue = String(); |
| 385 } | 537 } |
| 386 | 538 |
| 387 String StylePropertySerializer::fontValue() const | 539 String StylePropertySerializer::fontValue() const |
| 388 { | 540 { |
| 389 int fontSizePropertyIndex = m_propertySet.findPropertyIndex(CSSPropertyFontS
ize); | 541 int fontSizePropertyIndex = m_propertySet.findPropertyIndex(CSSPropertyFontS
ize); |
| 390 int fontFamilyPropertyIndex = m_propertySet.findPropertyIndex(CSSPropertyFon
tFamily); | 542 int fontFamilyPropertyIndex = m_propertySet.findPropertyIndex(CSSPropertyFon
tFamily); |
| 391 if (fontSizePropertyIndex == -1 || fontFamilyPropertyIndex == -1) | 543 if (fontSizePropertyIndex == -1 || fontFamilyPropertyIndex == -1) |
| 392 return emptyString(); | 544 return emptyString(); |
| 393 | 545 |
| 394 StylePropertySet::PropertyReference fontSizeProperty = m_propertySet.propert
yAt(fontSizePropertyIndex); | 546 PropertyValueForSerializer fontSizeProperty = m_propertySet.propertyAt(fontS
izePropertyIndex); |
| 395 StylePropertySet::PropertyReference fontFamilyProperty = m_propertySet.prope
rtyAt(fontFamilyPropertyIndex); | 547 PropertyValueForSerializer fontFamilyProperty = m_propertySet.propertyAt(fon
tFamilyPropertyIndex); |
| 396 if (fontSizeProperty.isImplicit() || fontFamilyProperty.isImplicit()) | 548 if (fontSizeProperty.isImplicit() || fontFamilyProperty.isImplicit()) |
| 397 return emptyString(); | 549 return emptyString(); |
| 398 | 550 |
| 399 String commonValue = fontSizeProperty.value()->cssText(); | 551 String commonValue = fontSizeProperty.value()->cssText(); |
| 400 StringBuilder result; | 552 StringBuilder result; |
| 401 appendFontLonghandValueIfExplicit(CSSPropertyFontStyle, result, commonValue)
; | 553 appendFontLonghandValueIfExplicit(CSSPropertyFontStyle, result, commonValue)
; |
| 402 appendFontLonghandValueIfExplicit(CSSPropertyFontVariant, result, commonValu
e); | 554 appendFontLonghandValueIfExplicit(CSSPropertyFontVariant, result, commonValu
e); |
| 403 appendFontLonghandValueIfExplicit(CSSPropertyFontWeight, result, commonValue
); | 555 appendFontLonghandValueIfExplicit(CSSPropertyFontWeight, result, commonValue
); |
| 404 appendFontLonghandValueIfExplicit(CSSPropertyFontStretch, result, commonValu
e); | 556 appendFontLonghandValueIfExplicit(CSSPropertyFontStretch, result, commonValu
e); |
| 405 if (!result.isEmpty()) | 557 if (!result.isEmpty()) |
| (...skipping 12 matching lines...) Expand all Loading... |
| 418 { | 570 { |
| 419 // Assume the properties are in the usual order top, right, bottom, left. | 571 // Assume the properties are in the usual order top, right, bottom, left. |
| 420 int topValueIndex = m_propertySet.findPropertyIndex(shorthand.properties()[0
]); | 572 int topValueIndex = m_propertySet.findPropertyIndex(shorthand.properties()[0
]); |
| 421 int rightValueIndex = m_propertySet.findPropertyIndex(shorthand.properties()
[1]); | 573 int rightValueIndex = m_propertySet.findPropertyIndex(shorthand.properties()
[1]); |
| 422 int bottomValueIndex = m_propertySet.findPropertyIndex(shorthand.properties(
)[2]); | 574 int bottomValueIndex = m_propertySet.findPropertyIndex(shorthand.properties(
)[2]); |
| 423 int leftValueIndex = m_propertySet.findPropertyIndex(shorthand.properties()[
3]); | 575 int leftValueIndex = m_propertySet.findPropertyIndex(shorthand.properties()[
3]); |
| 424 | 576 |
| 425 if (topValueIndex == -1 || rightValueIndex == -1 || bottomValueIndex == -1 |
| leftValueIndex == -1) | 577 if (topValueIndex == -1 || rightValueIndex == -1 || bottomValueIndex == -1 |
| leftValueIndex == -1) |
| 426 return String(); | 578 return String(); |
| 427 | 579 |
| 428 StylePropertySet::PropertyReference top = m_propertySet.propertyAt(topValueI
ndex); | 580 PropertyValueForSerializer top = m_propertySet.propertyAt(topValueIndex); |
| 429 StylePropertySet::PropertyReference right = m_propertySet.propertyAt(rightVa
lueIndex); | 581 PropertyValueForSerializer right = m_propertySet.propertyAt(rightValueIndex)
; |
| 430 StylePropertySet::PropertyReference bottom = m_propertySet.propertyAt(bottom
ValueIndex); | 582 PropertyValueForSerializer bottom = m_propertySet.propertyAt(bottomValueInde
x); |
| 431 StylePropertySet::PropertyReference left = m_propertySet.propertyAt(leftValu
eIndex); | 583 PropertyValueForSerializer left = m_propertySet.propertyAt(leftValueIndex); |
| 432 | 584 |
| 433 // All 4 properties must be specified. | 585 // All 4 properties must be specified. |
| 434 if (!top.value() || !right.value() || !bottom.value() || !left.value()) | 586 if (!top.value() || !right.value() || !bottom.value() || !left.value()) |
| 435 return String(); | 587 return String(); |
| 436 | 588 |
| 437 if (top.isInherited() && right.isInherited() && bottom.isInherited() && left
.isInherited()) | 589 if (top.isInherited() && right.isInherited() && bottom.isInherited() && left
.isInherited()) |
| 438 return getValueName(CSSValueInherit); | 590 return getValueName(CSSValueInherit); |
| 439 | 591 |
| 440 if (top.value()->isInitialValue() || right.value()->isInitialValue() || bott
om.value()->isInitialValue() || left.value()->isInitialValue()) { | 592 if (top.value()->isInitialValue() || right.value()->isInitialValue() || bott
om.value()->isInitialValue() || left.value()->isInitialValue()) { |
| 441 if (top.value()->isInitialValue() && right.value()->isInitialValue() &&
bottom.value()->isInitialValue() && left.value()->isInitialValue() && !top.isImp
licit()) { | 593 if (top.value()->isInitialValue() && right.value()->isInitialValue() &&
bottom.value()->isInitialValue() && left.value()->isInitialValue() && !top.isImp
licit()) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 467 } | 619 } |
| 468 return result.toString(); | 620 return result.toString(); |
| 469 } | 621 } |
| 470 | 622 |
| 471 String StylePropertySerializer::getLayeredShorthandValue(const StylePropertyShor
thand& shorthand, bool checkShorthandAvailable) const | 623 String StylePropertySerializer::getLayeredShorthandValue(const StylePropertyShor
thand& shorthand, bool checkShorthandAvailable) const |
| 472 { | 624 { |
| 473 StringBuilder result; | 625 StringBuilder result; |
| 474 | 626 |
| 475 const unsigned size = shorthand.length(); | 627 const unsigned size = shorthand.length(); |
| 476 // Begin by collecting the properties into an array. | 628 // Begin by collecting the properties into an array. |
| 477 WillBeHeapVector<RefPtrWillBeMember<CSSValue> > values(size); | 629 WillBeHeapVector<const CSSValue*> values(size); |
| 478 size_t numLayers = 0; | 630 size_t numLayers = 0; |
| 479 | 631 |
| 480 for (unsigned i = 0; i < size; ++i) { | 632 for (unsigned i = 0; i < size; ++i) { |
| 481 values[i] = m_propertySet.getPropertyCSSValue(shorthand.properties()[i])
; | 633 values[i] = m_propertySet.getPropertyCSSValue(shorthand.properties()[i])
; |
| 482 if (values[i]) { | 634 if (values[i]) { |
| 483 if (values[i]->isBaseValueList()) { | 635 if (values[i]->isBaseValueList()) { |
| 484 CSSValueList* valueList = toCSSValueList(values[i].get()); | 636 const CSSValueList* valueList = toCSSValueList(values[i]); |
| 485 numLayers = std::max(valueList->length(), numLayers); | 637 numLayers = std::max(valueList->length(), numLayers); |
| 486 } else { | 638 } else { |
| 487 numLayers = std::max<size_t>(1U, numLayers); | 639 numLayers = std::max<size_t>(1U, numLayers); |
| 488 } | 640 } |
| 489 } else if (checkShorthandAvailable) { | 641 } else if (checkShorthandAvailable) { |
| 490 return String(); | 642 return String(); |
| 491 } | 643 } |
| 492 } | 644 } |
| 493 | 645 |
| 494 | 646 |
| 495 String commonValue; | 647 String commonValue; |
| 496 bool commonValueInitialized = false; | 648 bool commonValueInitialized = false; |
| 497 | 649 |
| 498 // Now stitch the properties together. Implicit initial values are flagged a
s such and | 650 // Now stitch the properties together. Implicit initial values are flagged a
s such and |
| 499 // can safely be omitted. | 651 // can safely be omitted. |
| 500 for (size_t i = 0; i < numLayers; i++) { | 652 for (size_t i = 0; i < numLayers; i++) { |
| 501 StringBuilder layerResult; | 653 StringBuilder layerResult; |
| 502 bool useRepeatXShorthand = false; | 654 bool useRepeatXShorthand = false; |
| 503 bool useRepeatYShorthand = false; | 655 bool useRepeatYShorthand = false; |
| 504 bool useSingleWordShorthand = false; | 656 bool useSingleWordShorthand = false; |
| 505 bool foundPositionYCSSProperty = false; | 657 bool foundPositionYCSSProperty = false; |
| 506 for (unsigned j = 0; j < size; j++) { | 658 for (unsigned j = 0; j < size; j++) { |
| 507 RefPtrWillBeRawPtr<CSSValue> value = nullptr; | 659 const CSSValue* value = 0; |
| 508 if (values[j]) { | 660 if (values[j]) { |
| 509 if (values[j]->isBaseValueList()) { | 661 if (values[j]->isBaseValueList()) { |
| 510 value = toCSSValueList(values[j].get())->itemWithBoundsCheck
(i); | 662 value = toCSSValueList(values[j])->itemWithBoundsCheck(i); |
| 511 } else { | 663 } else { |
| 512 value = values[j]; | 664 value = values[j]; |
| 513 | 665 |
| 514 // Color only belongs in the last layer. | 666 // Color only belongs in the last layer. |
| 515 if (shorthand.properties()[j] == CSSPropertyBackgroundColor)
{ | 667 if (shorthand.properties()[j] == CSSPropertyBackgroundColor)
{ |
| 516 if (i != numLayers - 1) | 668 if (i != numLayers - 1) |
| 517 value = nullptr; | 669 value = 0; |
| 518 } else if (i) { | 670 } else if (i) { |
| 519 // Other singletons only belong in the first layer. | 671 // Other singletons only belong in the first layer. |
| 520 value = nullptr; | 672 value = 0; |
| 521 } | 673 } |
| 522 } | 674 } |
| 523 } | 675 } |
| 524 | 676 |
| 525 // We need to report background-repeat as it was written in the CSS.
If the property is implicit, | 677 // We need to report background-repeat as it was written in the CSS.
If the property is implicit, |
| 526 // then it was written with only one value. Here we figure out which
value that was so we can | 678 // then it was written with only one value. Here we figure out which
value that was so we can |
| 527 // report back correctly. | 679 // report back correctly. |
| 528 if ((shorthand.properties()[j] == CSSPropertyBackgroundRepeatX && m_
propertySet.isPropertyImplicit(shorthand.properties()[j])) | 680 if ((shorthand.properties()[j] == CSSPropertyBackgroundRepeatX && m_
propertySet.isPropertyImplicit(shorthand.properties()[j])) |
| 529 || (shorthand.properties()[j] == CSSPropertyWebkitMaskRepeatX &&
m_propertySet.isPropertyImplicit(shorthand.properties()[j]))) { | 681 || (shorthand.properties()[j] == CSSPropertyWebkitMaskRepeatX &&
m_propertySet.isPropertyImplicit(shorthand.properties()[j]))) { |
| 530 | 682 |
| 531 // BUG 49055: make sure the value was not reset in the layer che
ck just above. | 683 // BUG 49055: make sure the value was not reset in the layer che
ck just above. |
| 532 if ((j < size - 1 && shorthand.properties()[j + 1] == CSSPropert
yBackgroundRepeatY && value) | 684 if ((j < size - 1 && shorthand.properties()[j + 1] == CSSPropert
yBackgroundRepeatY && value) |
| 533 || (j < size - 1 && shorthand.properties()[j + 1] == CSSProp
ertyWebkitMaskRepeatY && value)) { | 685 || (j < size - 1 && shorthand.properties()[j + 1] == CSSProp
ertyWebkitMaskRepeatY && value)) { |
| 534 RefPtrWillBeRawPtr<CSSValue> yValue = nullptr; | 686 const CSSValue* yValue = 0; |
| 535 RefPtrWillBeRawPtr<CSSValue> nextValue = values[j + 1]; | 687 const CSSValue* nextValue = values[j + 1]; |
| 536 if (nextValue->isValueList()) | 688 if (nextValue->isValueList()) |
| 537 yValue = toCSSValueList(nextValue.get())->item(i); | 689 yValue = toCSSValueList(nextValue)->item(i); |
| 538 else | 690 else |
| 539 yValue = nextValue; | 691 yValue = nextValue; |
| 540 | 692 |
| 541 // background-repeat-x(y) or mask-repeat-x(y) may be like th
is : "initial, repeat". We can omit the implicit initial values | 693 // background-repeat-x(y) or mask-repeat-x(y) may be like th
is : "initial, repeat". We can omit the implicit initial values |
| 542 // before starting to compare their values. | 694 // before starting to compare their values. |
| 543 if (value->isImplicitInitialValue() || yValue->isImplicitIni
tialValue()) | 695 if (value->isImplicitInitialValue() || yValue->isImplicitIni
tialValue()) |
| 544 continue; | 696 continue; |
| 545 | 697 |
| 546 // FIXME: At some point we need to fix this code to avoid re
turning an invalid shorthand, | 698 // FIXME: At some point we need to fix this code to avoid re
turning an invalid shorthand, |
| 547 // since some longhand combinations are not serializable int
o a single shorthand. | 699 // since some longhand combinations are not serializable int
o a single shorthand. |
| 548 if (!value->isPrimitiveValue() || !yValue->isPrimitiveValue(
)) | 700 if (!value->isPrimitiveValue() || !yValue->isPrimitiveValue(
)) |
| 549 continue; | 701 continue; |
| 550 | 702 |
| 551 CSSValueID xId = toCSSPrimitiveValue(value.get())->getValueI
D(); | 703 CSSValueID xId = toCSSPrimitiveValue(value)->getValueID(); |
| 552 CSSValueID yId = toCSSPrimitiveValue(yValue.get())->getValue
ID(); | 704 CSSValueID yId = toCSSPrimitiveValue(yValue)->getValueID(); |
| 553 if (xId != yId) { | 705 if (xId != yId) { |
| 554 if (xId == CSSValueRepeat && yId == CSSValueNoRepeat) { | 706 if (xId == CSSValueRepeat && yId == CSSValueNoRepeat) { |
| 555 useRepeatXShorthand = true; | 707 useRepeatXShorthand = true; |
| 556 ++j; | 708 ++j; |
| 557 } else if (xId == CSSValueNoRepeat && yId == CSSValueRep
eat) { | 709 } else if (xId == CSSValueNoRepeat && yId == CSSValueRep
eat) { |
| 558 useRepeatYShorthand = true; | 710 useRepeatYShorthand = true; |
| 559 continue; | 711 continue; |
| 560 } | 712 } |
| 561 } else { | 713 } else { |
| 562 useSingleWordShorthand = true; | 714 useSingleWordShorthand = true; |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 621 return String(); | 773 return String(); |
| 622 return result.toString(); | 774 return result.toString(); |
| 623 } | 775 } |
| 624 | 776 |
| 625 String StylePropertySerializer::getShorthandValue(const StylePropertyShorthand&
shorthand) const | 777 String StylePropertySerializer::getShorthandValue(const StylePropertyShorthand&
shorthand) const |
| 626 { | 778 { |
| 627 String commonValue; | 779 String commonValue; |
| 628 StringBuilder result; | 780 StringBuilder result; |
| 629 for (unsigned i = 0; i < shorthand.length(); ++i) { | 781 for (unsigned i = 0; i < shorthand.length(); ++i) { |
| 630 if (!m_propertySet.isPropertyImplicit(shorthand.properties()[i])) { | 782 if (!m_propertySet.isPropertyImplicit(shorthand.properties()[i])) { |
| 631 RefPtrWillBeRawPtr<CSSValue> value = m_propertySet.getPropertyCSSVal
ue(shorthand.properties()[i]); | 783 const CSSValue* value = m_propertySet.getPropertyCSSValue(shorthand.
properties()[i]); |
| 632 if (!value) | 784 if (!value) |
| 633 return String(); | 785 return String(); |
| 634 String valueText = value->cssText(); | 786 String valueText = value->cssText(); |
| 635 if (!i) | 787 if (!i) |
| 636 commonValue = valueText; | 788 commonValue = valueText; |
| 637 else if (!commonValue.isNull() && commonValue != valueText) | 789 else if (!commonValue.isNull() && commonValue != valueText) |
| 638 commonValue = String(); | 790 commonValue = String(); |
| 639 if (value->isInitialValue()) | 791 if (value->isInitialValue()) |
| 640 continue; | 792 continue; |
| 641 if (!result.isEmpty()) | 793 if (!result.isEmpty()) |
| 642 result.append(' '); | 794 result.append(' '); |
| 643 result.append(valueText); | 795 result.append(valueText); |
| 644 } else | 796 } else |
| 645 commonValue = String(); | 797 commonValue = String(); |
| 646 } | 798 } |
| 647 if (isInitialOrInherit(commonValue)) | 799 if (isInitialOrInherit(commonValue)) |
| 648 return commonValue; | 800 return commonValue; |
| 649 if (result.isEmpty()) | 801 if (result.isEmpty()) |
| 650 return String(); | 802 return String(); |
| 651 return result.toString(); | 803 return result.toString(); |
| 652 } | 804 } |
| 653 | 805 |
| 654 // only returns a non-null value if all properties have the same, non-null value | 806 // only returns a non-null value if all properties have the same, non-null value |
| 655 String StylePropertySerializer::getCommonValue(const StylePropertyShorthand& sho
rthand) const | 807 String StylePropertySerializer::getCommonValue(const StylePropertyShorthand& sho
rthand) const |
| 656 { | 808 { |
| 657 String res; | 809 String res; |
| 658 bool lastPropertyWasImportant = false; | 810 bool lastPropertyWasImportant = false; |
| 659 for (unsigned i = 0; i < shorthand.length(); ++i) { | 811 for (unsigned i = 0; i < shorthand.length(); ++i) { |
| 660 RefPtrWillBeRawPtr<CSSValue> value = m_propertySet.getPropertyCSSValue(s
horthand.properties()[i]); | 812 const CSSValue* value = m_propertySet.getPropertyCSSValue(shorthand.prop
erties()[i]); |
| 661 // FIXME: CSSInitialValue::cssText should generate the right value. | 813 // FIXME: CSSInitialValue::cssText should generate the right value. |
| 662 if (!value) | 814 if (!value) |
| 663 return String(); | 815 return String(); |
| 664 String text = value->cssText(); | 816 String text = value->cssText(); |
| 665 if (text.isNull()) | 817 if (text.isNull()) |
| 666 return String(); | 818 return String(); |
| 667 if (res.isNull()) | 819 if (res.isNull()) |
| 668 res = text; | 820 res = text; |
| 669 else if (res != text) | 821 else if (res != text) |
| 670 return String(); | 822 return String(); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 721 builder.appendLiteral("repeat-x"); | 873 builder.appendLiteral("repeat-x"); |
| 722 } else { | 874 } else { |
| 723 builder.append(repeatX.cssText()); | 875 builder.append(repeatX.cssText()); |
| 724 builder.appendLiteral(" "); | 876 builder.appendLiteral(" "); |
| 725 builder.append(repeatY.cssText()); | 877 builder.append(repeatY.cssText()); |
| 726 } | 878 } |
| 727 } | 879 } |
| 728 | 880 |
| 729 String StylePropertySerializer::backgroundRepeatPropertyValue() const | 881 String StylePropertySerializer::backgroundRepeatPropertyValue() const |
| 730 { | 882 { |
| 731 RefPtrWillBeRawPtr<CSSValue> repeatX = m_propertySet.getPropertyCSSValue(CSS
PropertyBackgroundRepeatX); | 883 const CSSValue* repeatX = m_propertySet.getPropertyCSSValue(CSSPropertyBackg
roundRepeatX); |
| 732 RefPtrWillBeRawPtr<CSSValue> repeatY = m_propertySet.getPropertyCSSValue(CSS
PropertyBackgroundRepeatY); | 884 const CSSValue* repeatY = m_propertySet.getPropertyCSSValue(CSSPropertyBackg
roundRepeatY); |
| 733 if (!repeatX || !repeatY) | 885 if (!repeatX || !repeatY) |
| 734 return String(); | 886 return String(); |
| 735 if (m_propertySet.propertyIsImportant(CSSPropertyBackgroundRepeatX) != m_pro
pertySet.propertyIsImportant(CSSPropertyBackgroundRepeatY)) | 887 if (m_propertySet.propertyIsImportant(CSSPropertyBackgroundRepeatX) != m_pro
pertySet.propertyIsImportant(CSSPropertyBackgroundRepeatY)) |
| 736 return String(); | 888 return String(); |
| 737 if (repeatX->cssValueType() == repeatY->cssValueType() | 889 if (repeatX->cssValueType() == repeatY->cssValueType() |
| 738 && (repeatX->cssValueType() == CSSValue::CSS_INITIAL || repeatX->cssValu
eType() == CSSValue::CSS_INHERIT)) { | 890 && (repeatX->cssValueType() == CSSValue::CSS_INITIAL || repeatX->cssValu
eType() == CSSValue::CSS_INHERIT)) { |
| 739 return repeatX->cssText(); | 891 return repeatX->cssText(); |
| 740 } | 892 } |
| 741 | 893 |
| 742 RefPtrWillBeRawPtr<CSSValueList> repeatXList; | 894 const CSSValueList* repeatXList = 0; |
| 743 if (repeatX->cssValueType() == CSSValue::CSS_PRIMITIVE_VALUE) { | 895 int repeatXLength = 1; |
| 744 repeatXList = CSSValueList::createCommaSeparated(); | 896 if (repeatX->cssValueType() == CSSValue::CSS_VALUE_LIST) { |
| 745 repeatXList->append(repeatX); | 897 repeatXList = toCSSValueList(repeatX); |
| 746 } else if (repeatX->cssValueType() == CSSValue::CSS_VALUE_LIST) { | 898 repeatXLength = repeatXList->length(); |
| 747 repeatXList = toCSSValueList(repeatX.get()); | 899 } else if (repeatX->cssValueType() != CSSValue::CSS_PRIMITIVE_VALUE) { |
| 748 } else { | |
| 749 return String(); | 900 return String(); |
| 750 } | 901 } |
| 751 | 902 |
| 752 RefPtrWillBeRawPtr<CSSValueList> repeatYList; | 903 const CSSValueList* repeatYList = 0; |
| 753 if (repeatY->cssValueType() == CSSValue::CSS_PRIMITIVE_VALUE) { | 904 int repeatYLength = 1; |
| 754 repeatYList = CSSValueList::createCommaSeparated(); | 905 if (repeatY->cssValueType() == CSSValue::CSS_VALUE_LIST) { |
| 755 repeatYList->append(repeatY); | 906 repeatYList = toCSSValueList(repeatY); |
| 756 } else if (repeatY->cssValueType() == CSSValue::CSS_VALUE_LIST) { | 907 repeatYLength = repeatYList->length(); |
| 757 repeatYList = toCSSValueList(repeatY.get()); | 908 } else if (repeatY->cssValueType() != CSSValue::CSS_PRIMITIVE_VALUE) { |
| 758 } else { | |
| 759 return String(); | 909 return String(); |
| 760 } | 910 } |
| 761 | 911 |
| 762 size_t shorthandLength = lowestCommonMultiple(repeatXList->length(), repeatY
List->length()); | 912 size_t shorthandLength = lowestCommonMultiple(repeatXLength, repeatYLength); |
| 763 StringBuilder builder; | 913 StringBuilder builder; |
| 764 for (size_t i = 0; i < shorthandLength; ++i) { | 914 for (size_t i = 0; i < shorthandLength; ++i) { |
| 765 if (i) | 915 if (i) |
| 766 builder.appendLiteral(", "); | 916 builder.appendLiteral(", "); |
| 767 appendBackgroundRepeatValue(builder, | 917 |
| 768 *repeatXList->item(i % repeatXList->length()), | 918 const CSSValue* xValue = repeatXList ? repeatXList->item(i % repeatXList
->length()) : repeatX; |
| 769 *repeatYList->item(i % repeatYList->length())); | 919 const CSSValue* yValue = repeatYList ? repeatYList->item(i % repeatYList
->length()) : repeatY; |
| 920 appendBackgroundRepeatValue(builder, *xValue, *yValue); |
| 770 } | 921 } |
| 771 return builder.toString(); | 922 return builder.toString(); |
| 772 } | 923 } |
| 773 | 924 |
| 774 void StylePropertySerializer::appendBackgroundPropertyAsText(StringBuilder& resu
lt, unsigned& numDecls) const | 925 void StylePropertySerializer::appendBackgroundPropertyAsText(StringBuilder& resu
lt, unsigned& numDecls) const |
| 775 { | 926 { |
| 776 if (isPropertyShorthandAvailable(backgroundShorthand())) { | 927 if (isPropertyShorthandAvailable(backgroundShorthand())) { |
| 777 String backgroundValue = getPropertyValue(CSSPropertyBackground); | 928 String backgroundValue = getPropertyValue(CSSPropertyBackground); |
| 778 bool isImportant = m_propertySet.propertyIsImportant(CSSPropertyBackgrou
ndImage); | 929 bool isImportant = m_propertySet.propertyIsImportant(CSSPropertyBackgrou
ndImage); |
| 779 result.append(getPropertyText(CSSPropertyBackground, backgroundValue, is
Important, numDecls++)); | 930 result.append(getPropertyText(CSSPropertyBackground, backgroundValue, is
Important, numDecls++)); |
| 780 return; | 931 return; |
| 781 } | 932 } |
| 782 if (shorthandHasOnlyInitialOrInheritedValue(backgroundShorthand())) { | 933 if (shorthandHasOnlyInitialOrInheritedValue(backgroundShorthand())) { |
| 783 RefPtrWillBeRawPtr<CSSValue> value = m_propertySet.getPropertyCSSValue(C
SSPropertyBackgroundImage); | 934 const CSSValue* value = m_propertySet.getPropertyCSSValue(CSSPropertyBac
kgroundImage); |
| 784 bool isImportant = m_propertySet.propertyIsImportant(CSSPropertyBackgrou
ndImage); | 935 bool isImportant = m_propertySet.propertyIsImportant(CSSPropertyBackgrou
ndImage); |
| 785 result.append(getPropertyText(CSSPropertyBackground, value->cssText(), i
sImportant, numDecls++)); | 936 result.append(getPropertyText(CSSPropertyBackground, value->cssText(), i
sImportant, numDecls++)); |
| 786 return; | 937 return; |
| 787 } | 938 } |
| 788 | 939 |
| 789 // backgroundShorthandProperty without layered shorhand properties | 940 // backgroundShorthandProperty without layered shorhand properties |
| 790 const CSSPropertyID backgroundPropertyIds[] = { | 941 const CSSPropertyID backgroundPropertyIds[] = { |
| 791 CSSPropertyBackgroundImage, | 942 CSSPropertyBackgroundImage, |
| 792 CSSPropertyBackgroundAttachment, | 943 CSSPropertyBackgroundAttachment, |
| 793 CSSPropertyBackgroundColor, | 944 CSSPropertyBackgroundColor, |
| 794 CSSPropertyBackgroundSize, | 945 CSSPropertyBackgroundSize, |
| 795 CSSPropertyBackgroundOrigin, | 946 CSSPropertyBackgroundOrigin, |
| 796 CSSPropertyBackgroundClip | 947 CSSPropertyBackgroundClip |
| 797 }; | 948 }; |
| 798 | 949 |
| 799 for (unsigned i = 0; i < WTF_ARRAY_LENGTH(backgroundPropertyIds); ++i) { | 950 for (unsigned i = 0; i < WTF_ARRAY_LENGTH(backgroundPropertyIds); ++i) { |
| 800 CSSPropertyID propertyID = backgroundPropertyIds[i]; | 951 CSSPropertyID propertyID = backgroundPropertyIds[i]; |
| 801 RefPtrWillBeRawPtr<CSSValue> value = m_propertySet.getPropertyCSSValue(p
ropertyID); | 952 const CSSValue* value = m_propertySet.getPropertyCSSValue(propertyID); |
| 802 if (!value) | 953 if (!value) |
| 803 continue; | 954 continue; |
| 804 result.append(getPropertyText(propertyID, value->cssText(), m_propertySe
t.propertyIsImportant(propertyID), numDecls++)); | 955 result.append(getPropertyText(propertyID, value->cssText(), m_propertySe
t.propertyIsImportant(propertyID), numDecls++)); |
| 805 } | 956 } |
| 806 | 957 |
| 807 // FIXME: This is a not-so-nice way to turn x/y positions into single backgr
ound-position in output. | 958 // FIXME: This is a not-so-nice way to turn x/y positions into single backgr
ound-position in output. |
| 808 // It is required because background-position-x/y are non-standard propertie
s and WebKit generated output | 959 // It is required because background-position-x/y are non-standard propertie
s and WebKit generated output |
| 809 // would not work in Firefox (<rdar://problem/5143183>) | 960 // would not work in Firefox (<rdar://problem/5143183>) |
| 810 // It would be a better solution if background-position was CSS_PAIR. | 961 // It would be a better solution if background-position was CSS_PAIR. |
| 811 if (shorthandHasOnlyInitialOrInheritedValue(backgroundPositionShorthand()))
{ | 962 if (shorthandHasOnlyInitialOrInheritedValue(backgroundPositionShorthand()))
{ |
| 812 RefPtrWillBeRawPtr<CSSValue> value = m_propertySet.getPropertyCSSValue(C
SSPropertyBackgroundPositionX); | 963 const CSSValue* value = m_propertySet.getPropertyCSSValue(CSSPropertyBac
kgroundPositionX); |
| 813 bool isImportant = m_propertySet.propertyIsImportant(CSSPropertyBackgrou
ndPositionX); | 964 bool isImportant = m_propertySet.propertyIsImportant(CSSPropertyBackgrou
ndPositionX); |
| 814 result.append(getPropertyText(CSSPropertyBackgroundPosition, value->cssT
ext(), isImportant, numDecls++)); | 965 result.append(getPropertyText(CSSPropertyBackgroundPosition, value->cssT
ext(), isImportant, numDecls++)); |
| 815 } else if (isPropertyShorthandAvailable(backgroundPositionShorthand())) { | 966 } else if (isPropertyShorthandAvailable(backgroundPositionShorthand())) { |
| 816 String positionValue = m_propertySet.getPropertyValue(CSSPropertyBackgro
undPosition); | 967 String positionValue = m_propertySet.getPropertyValue(CSSPropertyBackgro
undPosition); |
| 817 bool isImportant = m_propertySet.propertyIsImportant(CSSPropertyBackgrou
ndPositionX); | 968 bool isImportant = m_propertySet.propertyIsImportant(CSSPropertyBackgrou
ndPositionX); |
| 818 if (!positionValue.isNull()) | 969 if (!positionValue.isNull()) |
| 819 result.append(getPropertyText(CSSPropertyBackgroundPosition, positio
nValue, isImportant, numDecls++)); | 970 result.append(getPropertyText(CSSPropertyBackgroundPosition, positio
nValue, isImportant, numDecls++)); |
| 820 } else { | 971 } else { |
| 821 // should check background-position-x or background-position-y. | 972 // should check background-position-x or background-position-y. |
| 822 if (RefPtrWillBeRawPtr<CSSValue> value = m_propertySet.getPropertyCSSVal
ue(CSSPropertyBackgroundPositionX)) { | 973 if (const CSSValue* value = m_propertySet.getPropertyCSSValue(CSSPropert
yBackgroundPositionX)) { |
| 823 if (!value->isImplicitInitialValue()) { | 974 if (!value->isImplicitInitialValue()) { |
| 824 bool isImportant = m_propertySet.propertyIsImportant(CSSProperty
BackgroundPositionX); | 975 bool isImportant = m_propertySet.propertyIsImportant(CSSProperty
BackgroundPositionX); |
| 825 result.append(getPropertyText(CSSPropertyBackgroundPositionX, va
lue->cssText(), isImportant, numDecls++)); | 976 result.append(getPropertyText(CSSPropertyBackgroundPositionX, va
lue->cssText(), isImportant, numDecls++)); |
| 826 } | 977 } |
| 827 } | 978 } |
| 828 if (RefPtrWillBeRawPtr<CSSValue> value = m_propertySet.getPropertyCSSVal
ue(CSSPropertyBackgroundPositionY)) { | 979 if (const CSSValue* value = m_propertySet.getPropertyCSSValue(CSSPropert
yBackgroundPositionY)) { |
| 829 if (!value->isImplicitInitialValue()) { | 980 if (!value->isImplicitInitialValue()) { |
| 830 bool isImportant = m_propertySet.propertyIsImportant(CSSProperty
BackgroundPositionY); | 981 bool isImportant = m_propertySet.propertyIsImportant(CSSProperty
BackgroundPositionY); |
| 831 result.append(getPropertyText(CSSPropertyBackgroundPositionY, va
lue->cssText(), isImportant, numDecls++)); | 982 result.append(getPropertyText(CSSPropertyBackgroundPositionY, va
lue->cssText(), isImportant, numDecls++)); |
| 832 } | 983 } |
| 833 } | 984 } |
| 834 } | 985 } |
| 835 | 986 |
| 836 String repeatValue = m_propertySet.getPropertyValue(CSSPropertyBackgroundRep
eat); | 987 String repeatValue = m_propertySet.getPropertyValue(CSSPropertyBackgroundRep
eat); |
| 837 if (!repeatValue.isNull()) | 988 if (!repeatValue.isNull()) |
| 838 result.append(getPropertyText(CSSPropertyBackgroundRepeat, repeatValue,
m_propertySet.propertyIsImportant(CSSPropertyBackgroundRepeatX), numDecls++)); | 989 result.append(getPropertyText(CSSPropertyBackgroundRepeat, repeatValue,
m_propertySet.propertyIsImportant(CSSPropertyBackgroundRepeatX), numDecls++)); |
| 839 } | 990 } |
| 840 | 991 |
| 841 bool StylePropertySerializer::isPropertyShorthandAvailable(const StylePropertySh
orthand& shorthand) const | 992 bool StylePropertySerializer::isPropertyShorthandAvailable(const StylePropertySh
orthand& shorthand) const |
| 842 { | 993 { |
| 843 ASSERT(shorthand.length() > 0); | 994 ASSERT(shorthand.length() > 0); |
| 844 | 995 |
| 845 bool isImportant = m_propertySet.propertyIsImportant(shorthand.properties()[
0]); | 996 bool isImportant = m_propertySet.propertyIsImportant(shorthand.properties()[
0]); |
| 846 for (unsigned i = 0; i < shorthand.length(); ++i) { | 997 for (unsigned i = 0; i < shorthand.length(); ++i) { |
| 847 RefPtrWillBeRawPtr<CSSValue> value = m_propertySet.getPropertyCSSValue(s
horthand.properties()[i]); | 998 const CSSValue* value = m_propertySet.getPropertyCSSValue(shorthand.prop
erties()[i]); |
| 848 if (!value || (value->isInitialValue() && !value->isImplicitInitialValue
()) || value->isInheritedValue()) | 999 if (!value || (value->isInitialValue() && !value->isImplicitInitialValue
()) || value->isInheritedValue()) |
| 849 return false; | 1000 return false; |
| 850 if (isImportant != m_propertySet.propertyIsImportant(shorthand.propertie
s()[i])) | 1001 if (isImportant != m_propertySet.propertyIsImportant(shorthand.propertie
s()[i])) |
| 851 return false; | 1002 return false; |
| 852 } | 1003 } |
| 853 return true; | 1004 return true; |
| 854 } | 1005 } |
| 855 | 1006 |
| 856 bool StylePropertySerializer::shorthandHasOnlyInitialOrInheritedValue(const Styl
ePropertyShorthand& shorthand) const | 1007 bool StylePropertySerializer::shorthandHasOnlyInitialOrInheritedValue(const Styl
ePropertyShorthand& shorthand) const |
| 857 { | 1008 { |
| 858 ASSERT(shorthand.length() > 0); | 1009 ASSERT(shorthand.length() > 0); |
| 859 bool isImportant = m_propertySet.propertyIsImportant(shorthand.properties()[
0]); | 1010 bool isImportant = m_propertySet.propertyIsImportant(shorthand.properties()[
0]); |
| 860 bool isInitialValue = true; | 1011 bool isInitialValue = true; |
| 861 bool isInheritedValue = true; | 1012 bool isInheritedValue = true; |
| 862 for (unsigned i = 0; i < shorthand.length(); ++i) { | 1013 for (unsigned i = 0; i < shorthand.length(); ++i) { |
| 863 RefPtrWillBeRawPtr<CSSValue> value = m_propertySet.getPropertyCSSValue(s
horthand.properties()[i]); | 1014 const CSSValue* value = m_propertySet.getPropertyCSSValue(shorthand.prop
erties()[i]); |
| 864 if (!value) | 1015 if (!value) |
| 865 return false; | 1016 return false; |
| 866 if (!value->isInitialValue()) | 1017 if (!value->isInitialValue()) |
| 867 isInitialValue = false; | 1018 isInitialValue = false; |
| 868 if (!value->isInheritedValue()) | 1019 if (!value->isInheritedValue()) |
| 869 isInheritedValue = false; | 1020 isInheritedValue = false; |
| 870 if (isImportant != m_propertySet.propertyIsImportant(shorthand.propertie
s()[i])) | 1021 if (isImportant != m_propertySet.propertyIsImportant(shorthand.propertie
s()[i])) |
| 871 return false; | 1022 return false; |
| 872 } | 1023 } |
| 873 return isInitialValue || isInheritedValue; | 1024 return isInitialValue || isInheritedValue; |
| 874 } | 1025 } |
| 875 | 1026 |
| 876 } | 1027 } |
| OLD | NEW |