| 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. |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 if (isImportant) | 217 if (isImportant) |
| 218 result.appendLiteral(" !important"); | 218 result.appendLiteral(" !important"); |
| 219 result.append(';'); | 219 result.append(';'); |
| 220 return result.toString(); | 220 return result.toString(); |
| 221 } | 221 } |
| 222 | 222 |
| 223 String StylePropertySerializer::asText() const | 223 String StylePropertySerializer::asText() const |
| 224 { | 224 { |
| 225 StringBuilder result; | 225 StringBuilder result; |
| 226 | 226 |
| 227 std::bitset<numCSSProperties> shorthandPropertyUsed; | 227 std::bitset<numCSSProperties> longhandSerialized; |
| 228 std::bitset<numCSSProperties> shorthandPropertyAppeared; | 228 std::bitset<numCSSProperties> shorthandAppeared; |
| 229 |
| 230 bool backgroundLonghandSeen = false; |
| 229 | 231 |
| 230 unsigned size = m_propertySet.propertyCount(); | 232 unsigned size = m_propertySet.propertyCount(); |
| 231 unsigned numDecls = 0; | 233 unsigned numDecls = 0; |
| 232 for (unsigned n = 0; n < size; ++n) { | 234 for (unsigned n = 0; n < size; ++n) { |
| 233 if (!m_propertySet.shouldProcessPropertyAt(n)) | 235 if (!m_propertySet.shouldProcessPropertyAt(n)) |
| 234 continue; | 236 continue; |
| 235 | 237 |
| 236 StylePropertySerializer::PropertyValueForSerializer property = m_propert
ySet.propertyAt(n); | 238 StylePropertySerializer::PropertyValueForSerializer property = m_propert
ySet.propertyAt(n); |
| 237 CSSPropertyID propertyID = property.id(); | 239 CSSPropertyID propertyID = property.id(); |
| 238 // Only enabled properties should be part of the style. | 240 // Only enabled properties should be part of the style. |
| 239 ASSERT(CSSPropertyMetadata::isEnabledProperty(propertyID)); | 241 ASSERT(CSSPropertyMetadata::isEnabledProperty(propertyID)); |
| 240 CSSPropertyID shorthandPropertyID = CSSPropertyInvalid; | |
| 241 CSSPropertyID borderFallbackShorthandProperty = CSSPropertyInvalid; | |
| 242 String value; | |
| 243 // Shorthands with variable references are not expanded at parse time | 242 // Shorthands with variable references are not expanded at parse time |
| 244 // and hence may still be observed during serialization. | 243 // and hence may still be observed during serialization. |
| 245 ASSERT(!isShorthandProperty(propertyID) || property.value()->isVariableR
eferenceValue()); | 244 ASSERT(!isShorthandProperty(propertyID) || property.value()->isVariableR
eferenceValue()); |
| 246 | 245 |
| 247 switch (propertyID) { | 246 switch (propertyID) { |
| 248 case CSSPropertyBackgroundAttachment: | |
| 249 case CSSPropertyBackgroundClip: | |
| 250 case CSSPropertyBackgroundColor: | |
| 251 case CSSPropertyBackgroundImage: | |
| 252 case CSSPropertyBackgroundOrigin: | |
| 253 case CSSPropertyBackgroundPositionX: | |
| 254 case CSSPropertyBackgroundPositionY: | |
| 255 case CSSPropertyBackgroundSize: | |
| 256 case CSSPropertyBackgroundRepeatX: | |
| 257 case CSSPropertyBackgroundRepeatY: | |
| 258 shorthandPropertyAppeared.set(CSSPropertyBackground - firstCSSProper
ty); | |
| 259 continue; | |
| 260 case CSSPropertyBorderTopWidth: | |
| 261 case CSSPropertyBorderRightWidth: | |
| 262 case CSSPropertyBorderBottomWidth: | |
| 263 case CSSPropertyBorderLeftWidth: | |
| 264 if (!borderFallbackShorthandProperty) | |
| 265 borderFallbackShorthandProperty = CSSPropertyBorderWidth; | |
| 266 case CSSPropertyBorderTopStyle: | |
| 267 case CSSPropertyBorderRightStyle: | |
| 268 case CSSPropertyBorderBottomStyle: | |
| 269 case CSSPropertyBorderLeftStyle: | |
| 270 if (!borderFallbackShorthandProperty) | |
| 271 borderFallbackShorthandProperty = CSSPropertyBorderStyle; | |
| 272 case CSSPropertyBorderTopColor: | |
| 273 case CSSPropertyBorderRightColor: | |
| 274 case CSSPropertyBorderBottomColor: | |
| 275 case CSSPropertyBorderLeftColor: | |
| 276 if (!borderFallbackShorthandProperty) | |
| 277 borderFallbackShorthandProperty = CSSPropertyBorderColor; | |
| 278 | |
| 279 // FIXME: Deal with cases where only some of border-(top|right|botto
m|left) are specified. | |
| 280 if (!shorthandPropertyAppeared.test(CSSPropertyBorder - firstCSSProp
erty)) { | |
| 281 value = borderPropertyValue(); | |
| 282 if (value.isNull()) | |
| 283 shorthandPropertyAppeared.set(CSSPropertyBorder - firstCSSPr
operty); | |
| 284 else | |
| 285 shorthandPropertyID = CSSPropertyBorder; | |
| 286 } else if (shorthandPropertyUsed.test(CSSPropertyBorder - firstCSSPr
operty)) { | |
| 287 shorthandPropertyID = CSSPropertyBorder; | |
| 288 } | |
| 289 if (!shorthandPropertyID) | |
| 290 shorthandPropertyID = borderFallbackShorthandProperty; | |
| 291 break; | |
| 292 case CSSPropertyBorderTopLeftRadius: | |
| 293 case CSSPropertyBorderTopRightRadius: | |
| 294 case CSSPropertyBorderBottomLeftRadius: | |
| 295 case CSSPropertyBorderBottomRightRadius: | |
| 296 shorthandPropertyID = CSSPropertyBorderRadius; | |
| 297 break; | |
| 298 case CSSPropertyWebkitBorderHorizontalSpacing: | |
| 299 case CSSPropertyWebkitBorderVerticalSpacing: | |
| 300 shorthandPropertyID = CSSPropertyBorderSpacing; | |
| 301 break; | |
| 302 case CSSPropertyFontFamily: | |
| 303 case CSSPropertyLineHeight: | |
| 304 case CSSPropertyFontSize: | |
| 305 case CSSPropertyFontStretch: | |
| 306 case CSSPropertyFontStyle: | |
| 307 case CSSPropertyFontVariant: | |
| 308 case CSSPropertyFontWeight: | |
| 309 // Don't use CSSPropertyFont because old UAs can't recognize them bu
t are important for editing. | |
| 310 break; | |
| 311 case CSSPropertyListStyleType: | |
| 312 case CSSPropertyListStylePosition: | |
| 313 case CSSPropertyListStyleImage: | |
| 314 shorthandPropertyID = CSSPropertyListStyle; | |
| 315 break; | |
| 316 case CSSPropertyMarginTop: | |
| 317 case CSSPropertyMarginRight: | |
| 318 case CSSPropertyMarginBottom: | |
| 319 case CSSPropertyMarginLeft: | |
| 320 shorthandPropertyID = CSSPropertyMargin; | |
| 321 break; | |
| 322 case CSSPropertyMotionPath: | |
| 323 case CSSPropertyMotionOffset: | |
| 324 case CSSPropertyMotionRotation: | |
| 325 shorthandPropertyID = CSSPropertyMotion; | |
| 326 break; | |
| 327 case CSSPropertyOutlineWidth: | |
| 328 case CSSPropertyOutlineStyle: | |
| 329 case CSSPropertyOutlineColor: | |
| 330 shorthandPropertyID = CSSPropertyOutline; | |
| 331 break; | |
| 332 case CSSPropertyOverflowX: | |
| 333 case CSSPropertyOverflowY: | |
| 334 shorthandPropertyID = CSSPropertyOverflow; | |
| 335 break; | |
| 336 case CSSPropertyPaddingTop: | |
| 337 case CSSPropertyPaddingRight: | |
| 338 case CSSPropertyPaddingBottom: | |
| 339 case CSSPropertyPaddingLeft: | |
| 340 shorthandPropertyID = CSSPropertyPadding; | |
| 341 break; | |
| 342 case CSSPropertyTransitionProperty: | |
| 343 case CSSPropertyTransitionDuration: | |
| 344 case CSSPropertyTransitionTimingFunction: | |
| 345 case CSSPropertyTransitionDelay: | |
| 346 shorthandPropertyID = CSSPropertyTransition; | |
| 347 break; | |
| 348 case CSSPropertyAnimationName: | |
| 349 case CSSPropertyAnimationDuration: | |
| 350 case CSSPropertyAnimationTimingFunction: | |
| 351 case CSSPropertyAnimationDelay: | |
| 352 case CSSPropertyAnimationIterationCount: | |
| 353 case CSSPropertyAnimationDirection: | |
| 354 case CSSPropertyAnimationFillMode: | |
| 355 case CSSPropertyAnimationPlayState: | |
| 356 shorthandPropertyID = CSSPropertyAnimation; | |
| 357 break; | |
| 358 case CSSPropertyFlexDirection: | |
| 359 case CSSPropertyFlexWrap: | |
| 360 shorthandPropertyID = CSSPropertyFlexFlow; | |
| 361 break; | |
| 362 case CSSPropertyFlexBasis: | |
| 363 case CSSPropertyFlexGrow: | |
| 364 case CSSPropertyFlexShrink: | |
| 365 shorthandPropertyID = CSSPropertyFlex; | |
| 366 break; | |
| 367 case CSSPropertyWebkitMaskPositionX: | |
| 368 case CSSPropertyWebkitMaskPositionY: | |
| 369 case CSSPropertyWebkitMaskRepeatX: | |
| 370 case CSSPropertyWebkitMaskRepeatY: | |
| 371 case CSSPropertyWebkitMaskImage: | |
| 372 case CSSPropertyWebkitMaskRepeat: | |
| 373 case CSSPropertyWebkitMaskPosition: | |
| 374 case CSSPropertyWebkitMaskClip: | |
| 375 case CSSPropertyWebkitMaskOrigin: | |
| 376 shorthandPropertyID = CSSPropertyWebkitMask; | |
| 377 break; | |
| 378 case CSSPropertyVariable: | 247 case CSSPropertyVariable: |
| 379 result.append(getCustomPropertyText(property, numDecls++)); | 248 result.append(getCustomPropertyText(property, numDecls++)); |
| 380 continue; | 249 continue; |
| 381 case CSSPropertyAll: | 250 case CSSPropertyAll: |
| 382 result.append(getPropertyText(propertyID, property.value()->cssText(
), property.isImportant(), numDecls++)); | 251 result.append(getPropertyText(propertyID, property.value()->cssText(
), property.isImportant(), numDecls++)); |
| 383 continue; | 252 continue; |
| 384 case CSSPropertyApplyAtRule: | 253 case CSSPropertyApplyAtRule: |
| 385 result.append(getApplyAtRuleText(property.value(), numDecls++)); | 254 result.append(getApplyAtRuleText(property.value(), numDecls++)); |
| 386 continue; | 255 continue; |
| 387 default: | 256 default: |
| 388 break; | 257 break; |
| 389 } | 258 } |
| 259 if (longhandSerialized.test(propertyID - firstCSSProperty)) |
| 260 continue; |
| 390 | 261 |
| 391 unsigned shortPropertyIndex = shorthandPropertyID - firstCSSProperty; | 262 Vector<StylePropertyShorthand, 4> shorthands; |
| 392 if (shorthandPropertyID) { | 263 getMatchingShorthandsForLonghand(propertyID, &shorthands); |
| 393 if (shorthandPropertyUsed.test(shortPropertyIndex)) | 264 bool serializedAsShorthand = false; |
| 265 for (const StylePropertyShorthand& shorthand : shorthands) { |
| 266 // Some aliases are implemented as a shorthand, in which case |
| 267 // we prefer to not use the shorthand. |
| 268 if (shorthand.length() == 1) |
| 394 continue; | 269 continue; |
| 395 if (!shorthandPropertyAppeared.test(shortPropertyIndex) && value.isN
ull()) | 270 |
| 396 value = m_propertySet.getPropertyValue(shorthandPropertyID); | 271 CSSPropertyID shorthandProperty = shorthand.id(); |
| 397 shorthandPropertyAppeared.set(shortPropertyIndex); | 272 int shorthandPropertyIndex = shorthandProperty - firstCSSProperty; |
| 273 // TODO(timloh): Do we actually need this check? A previous comment |
| 274 // said "old UAs can't recognize them but are important for editing" |
| 275 // but Firefox doesn't do this. |
| 276 if (shorthandProperty == CSSPropertyFont) |
| 277 continue; |
| 278 // TODO(timloh): Why is background special? |
| 279 if (shorthandProperty == CSSPropertyBackground) { |
| 280 serializedAsShorthand = true; |
| 281 backgroundLonghandSeen = true; |
| 282 break; |
| 283 } |
| 284 // We already tried serializing as this shorthand |
| 285 if (shorthandAppeared.test(shorthandPropertyIndex)) |
| 286 continue; |
| 287 |
| 288 shorthandAppeared.set(shorthandPropertyIndex); |
| 289 bool serializedOtherLonghand = false; |
| 290 for (unsigned i = 0; i < shorthand.length(); i++) { |
| 291 if (longhandSerialized.test(shorthand.properties()[i] - firstCSS
Property)) { |
| 292 serializedOtherLonghand = true; |
| 293 break; |
| 294 } |
| 295 } |
| 296 if (serializedOtherLonghand) |
| 297 continue; |
| 298 |
| 299 String shorthandResult = StylePropertySerializer::getPropertyValue(s
horthandProperty); |
| 300 if (shorthandResult.isEmpty()) |
| 301 continue; |
| 302 |
| 303 result.append(getPropertyText(shorthandProperty, shorthandResult, pr
operty.isImportant(), numDecls++)); |
| 304 serializedAsShorthand = true; |
| 305 for (unsigned i = 0; i < shorthand.length(); i++) |
| 306 longhandSerialized.set(shorthand.properties()[i] - firstCSSPrope
rty); |
| 307 break; |
| 398 } | 308 } |
| 399 | 309 |
| 400 if (!value.isNull()) { | 310 if (serializedAsShorthand) |
| 401 if (shorthandPropertyID) { | 311 continue; |
| 402 propertyID = shorthandPropertyID; | |
| 403 shorthandPropertyUsed.set(shortPropertyIndex); | |
| 404 } | |
| 405 } else { | |
| 406 // We should not show "initial" when the "initial" is implicit. | |
| 407 // If explicit "initial", we need to show. | |
| 408 if (property.value()->isImplicitInitialValue()) | |
| 409 continue; | |
| 410 value = property.value()->cssText(); | |
| 411 } | |
| 412 | 312 |
| 413 result.append(getPropertyText(propertyID, value, property.isImportant(),
numDecls++)); | 313 // TODO(timloh): This is wrong and makes declarations not round-trip. |
| 314 if (property.value()->isImplicitInitialValue()) |
| 315 continue; |
| 316 |
| 317 result.append(getPropertyText(propertyID, property.value()->cssText(), p
roperty.isImportant(), numDecls++)); |
| 414 } | 318 } |
| 415 | 319 |
| 416 if (shorthandPropertyAppeared.test(CSSPropertyBackground - firstCSSProperty)
) | 320 if (backgroundLonghandSeen) |
| 417 appendBackgroundPropertyAsText(result, numDecls); | 321 appendBackgroundPropertyAsText(result, numDecls); |
| 418 | 322 |
| 419 ASSERT(!numDecls ^ !result.isEmpty()); | 323 ASSERT(!numDecls ^ !result.isEmpty()); |
| 420 return result.toString(); | 324 return result.toString(); |
| 421 } | 325 } |
| 422 | 326 |
| 423 String StylePropertySerializer::getPropertyValue(CSSPropertyID propertyID) const | 327 String StylePropertySerializer::getPropertyValue(CSSPropertyID propertyID) const |
| 424 { | 328 { |
| 425 // Shorthand and 4-values properties | 329 // Shorthand and 4-values properties |
| 426 switch (propertyID) { | 330 switch (propertyID) { |
| (...skipping 649 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1076 isInitialValue = false; | 980 isInitialValue = false; |
| 1077 if (!value->isInheritedValue()) | 981 if (!value->isInheritedValue()) |
| 1078 isInheritedValue = false; | 982 isInheritedValue = false; |
| 1079 if (isImportant != m_propertySet.propertyIsImportant(shorthand.propertie
s()[i])) | 983 if (isImportant != m_propertySet.propertyIsImportant(shorthand.propertie
s()[i])) |
| 1080 return false; | 984 return false; |
| 1081 } | 985 } |
| 1082 return isInitialValue || isInheritedValue; | 986 return isInitialValue || isInheritedValue; |
| 1083 } | 987 } |
| 1084 | 988 |
| 1085 } // namespace blink | 989 } // namespace blink |
| OLD | NEW |