Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(24)

Side by Side Diff: third_party/WebKit/Source/core/css/StylePropertySerializer.cpp

Issue 1988013003: Move generic shorthand serialization checks out of specific routines (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@shorthand1
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 15 matching lines...) Expand all
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/CSSPropertyMetadata.h" 28 #include "core/css/CSSPropertyMetadata.h"
29 #include "core/css/CSSValuePool.h" 29 #include "core/css/CSSValuePool.h"
30 #include "wtf/StdLibExtras.h" 30 #include "wtf/StdLibExtras.h"
31 #include "wtf/text/StringBuilder.h" 31 #include "wtf/text/StringBuilder.h"
32 #include <bitset> 32 #include <bitset>
33 33
34 namespace blink { 34 namespace blink {
35 35
36 static bool isInitialOrInherit(const String& value)
37 {
38 return value.length() == 7 && (value == "initial" || value == "inherit");
39 }
40
41 StylePropertySerializer::StylePropertySetForSerializer::StylePropertySetForSeria lizer(const StylePropertySet& properties) 36 StylePropertySerializer::StylePropertySetForSerializer::StylePropertySetForSeria lizer(const StylePropertySet& properties)
42 : m_propertySet(&properties) 37 : m_propertySet(&properties)
43 , m_allIndex(m_propertySet->findPropertyIndex(CSSPropertyAll)) 38 , m_allIndex(m_propertySet->findPropertyIndex(CSSPropertyAll))
44 , m_needToExpandAll(false) 39 , m_needToExpandAll(false)
45 { 40 {
46 if (!hasAllProperty()) 41 if (!hasAllProperty())
47 return; 42 return;
48 43
49 StylePropertySet::PropertyReference allProperty = m_propertySet->propertyAt( m_allIndex); 44 StylePropertySet::PropertyReference allProperty = m_propertySet->propertyAt( m_allIndex);
50 for (unsigned i = 0; i < m_propertySet->propertyCount(); ++i) { 45 for (unsigned i = 0; i < m_propertySet->propertyCount(); ++i) {
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 return result.toString(); 215 return result.toString();
221 } 216 }
222 217
223 String StylePropertySerializer::asText() const 218 String StylePropertySerializer::asText() const
224 { 219 {
225 StringBuilder result; 220 StringBuilder result;
226 221
227 std::bitset<numCSSProperties> longhandSerialized; 222 std::bitset<numCSSProperties> longhandSerialized;
228 std::bitset<numCSSProperties> shorthandAppeared; 223 std::bitset<numCSSProperties> shorthandAppeared;
229 224
230 bool backgroundLonghandSeen = false;
231
232 unsigned size = m_propertySet.propertyCount(); 225 unsigned size = m_propertySet.propertyCount();
233 unsigned numDecls = 0; 226 unsigned numDecls = 0;
234 for (unsigned n = 0; n < size; ++n) { 227 for (unsigned n = 0; n < size; ++n) {
235 if (!m_propertySet.shouldProcessPropertyAt(n)) 228 if (!m_propertySet.shouldProcessPropertyAt(n))
236 continue; 229 continue;
237 230
238 StylePropertySerializer::PropertyValueForSerializer property = m_propert ySet.propertyAt(n); 231 StylePropertySerializer::PropertyValueForSerializer property = m_propert ySet.propertyAt(n);
239 CSSPropertyID propertyID = property.id(); 232 CSSPropertyID propertyID = property.id();
240 // Only enabled properties should be part of the style. 233 // Only enabled properties should be part of the style.
241 ASSERT(CSSPropertyMetadata::isEnabledProperty(propertyID)); 234 ASSERT(CSSPropertyMetadata::isEnabledProperty(propertyID));
(...skipping 26 matching lines...) Expand all
268 if (shorthand.length() == 1) 261 if (shorthand.length() == 1)
269 continue; 262 continue;
270 263
271 CSSPropertyID shorthandProperty = shorthand.id(); 264 CSSPropertyID shorthandProperty = shorthand.id();
272 int shorthandPropertyIndex = shorthandProperty - firstCSSProperty; 265 int shorthandPropertyIndex = shorthandProperty - firstCSSProperty;
273 // TODO(timloh): Do we actually need this check? A previous comment 266 // TODO(timloh): Do we actually need this check? A previous comment
274 // said "old UAs can't recognize them but are important for editing" 267 // said "old UAs can't recognize them but are important for editing"
275 // but Firefox doesn't do this. 268 // but Firefox doesn't do this.
276 if (shorthandProperty == CSSPropertyFont) 269 if (shorthandProperty == CSSPropertyFont)
277 continue; 270 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 271 // We already tried serializing as this shorthand
285 if (shorthandAppeared.test(shorthandPropertyIndex)) 272 if (shorthandAppeared.test(shorthandPropertyIndex))
286 continue; 273 continue;
287 274
288 shorthandAppeared.set(shorthandPropertyIndex); 275 shorthandAppeared.set(shorthandPropertyIndex);
289 bool serializedOtherLonghand = false; 276 bool serializedOtherLonghand = false;
290 for (unsigned i = 0; i < shorthand.length(); i++) { 277 for (unsigned i = 0; i < shorthand.length(); i++) {
291 if (longhandSerialized.test(shorthand.properties()[i] - firstCSS Property)) { 278 if (longhandSerialized.test(shorthand.properties()[i] - firstCSS Property)) {
292 serializedOtherLonghand = true; 279 serializedOtherLonghand = true;
293 break; 280 break;
294 } 281 }
295 } 282 }
296 if (serializedOtherLonghand) 283 if (serializedOtherLonghand)
297 continue; 284 continue;
298 285
299 String shorthandResult = StylePropertySerializer::getPropertyValue(s horthandProperty); 286 String shorthandResult = StylePropertySerializer::getPropertyValue(s horthandProperty);
300 if (shorthandResult.isEmpty()) 287 if (shorthandResult.isEmpty())
301 continue; 288 continue;
302 289
303 result.append(getPropertyText(shorthandProperty, shorthandResult, pr operty.isImportant(), numDecls++)); 290 result.append(getPropertyText(shorthandProperty, shorthandResult, pr operty.isImportant(), numDecls++));
304 serializedAsShorthand = true; 291 serializedAsShorthand = true;
305 for (unsigned i = 0; i < shorthand.length(); i++) 292 for (unsigned i = 0; i < shorthand.length(); i++)
306 longhandSerialized.set(shorthand.properties()[i] - firstCSSPrope rty); 293 longhandSerialized.set(shorthand.properties()[i] - firstCSSPrope rty);
307 break; 294 break;
308 } 295 }
309 296
310 if (serializedAsShorthand) 297 if (serializedAsShorthand)
311 continue; 298 continue;
312 299
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++)); 300 result.append(getPropertyText(propertyID, property.value()->cssText(), p roperty.isImportant(), numDecls++));
318 } 301 }
319 302
320 if (backgroundLonghandSeen)
321 appendBackgroundPropertyAsText(result, numDecls);
322
323 ASSERT(!numDecls ^ !result.isEmpty()); 303 ASSERT(!numDecls ^ !result.isEmpty());
324 return result.toString(); 304 return result.toString();
325 } 305 }
326 306
307 // As per css-cascade, shorthands do not expand longhands to the value
308 // "initial", except when the shorthand is set to "initial", instead
309 // setting "missing" sub-properties to their initial values. This means
310 // that a shorthand can never represent a list of subproperties where
311 // some are "initial" and some are not, and so serialization should
312 // always fail in these cases (as per cssom). However we currently use
313 // "initial" instead of the initial values for certain shorthands, so
314 // these are special-cased here.
315 // TODO(timloh): Don't use "initial" in shorthands and remove this
316 // special-casing
317 static bool allowInitialInShorthand(CSSPropertyID propertyID)
318 {
319 switch (propertyID) {
320 case CSSPropertyBorder:
321 case CSSPropertyBorderTop:
322 case CSSPropertyBorderRight:
323 case CSSPropertyBorderBottom:
324 case CSSPropertyBorderLeft:
325 case CSSPropertyOutline:
326 case CSSPropertyColumnRule:
327 case CSSPropertyColumns:
328 case CSSPropertyFlex:
329 case CSSPropertyFlexFlow:
330 case CSSPropertyGridColumn:
331 case CSSPropertyGridRow:
332 case CSSPropertyGridArea:
333 case CSSPropertyGridGap:
334 case CSSPropertyMotion:
335 case CSSPropertyWebkitMarginCollapse:
336 case CSSPropertyListStyle:
337 case CSSPropertyWebkitTextEmphasis:
338 case CSSPropertyWebkitTextStroke:
339 return true;
340 default:
341 return false;
342 }
343 }
344
345 // TODO(timloh): This should go away eventually, see crbug.com/471917
346 static bool allowImplicitInitialInShorthand(CSSPropertyID propertyID)
347 {
348 return propertyID == CSSPropertyBackground || propertyID == CSSPropertyWebki tMask;
349 }
350
351 StylePropertySerializer::CommonCheckResult StylePropertySerializer::commonShorth andChecks(const StylePropertyShorthand& shorthand, String& result) const
352 {
353 int longhandCount = shorthand.length();
354 DCHECK_LE(longhandCount, 17);
355 const CSSValue* longhands[17] = {};
356
357 bool hasImportant = false;
358 bool hasNonImportant = false;
359
360 for (int i = 0; i < longhandCount; i++) {
361 int index = m_propertySet.findPropertyIndex(shorthand.properties()[i]);
362 if (index == -1)
363 return Invalid;
364 PropertyValueForSerializer value = m_propertySet.propertyAt(index);
365
366 hasImportant |= value.isImportant();
367 hasNonImportant |= !value.isImportant();
368 longhands[i] = value.value();
369 }
370
371 if (hasImportant && hasNonImportant)
372 return Invalid;
373
374 // TODO(timloh): This should be isCSSWideKeyword()
375 if (longhands[0]->isInitialValue() || longhands[0]->isInheritedValue()) {
376 bool success = true;
377 for (int i = 1; i < longhandCount; i++) {
378 if (!longhands[i]->equals(*longhands[0])) {
379 // This should just return Invalid but some shorthands currently
380 // allow 'initial' for their longhands.
381 success = false;
382 break;
383 }
384 }
385 if (success) {
386 result = longhands[0]->cssText();
387 return Valid;
388 }
389 }
390
391 bool allowInitial = allowInitialInShorthand(shorthand.id());
392 bool allowImplicitInitial = allowInitial || allowImplicitInitialInShorthand( shorthand.id());
393 for (int i = 0; i < longhandCount; i++) {
394 const CSSValue& value = *longhands[i];
395 if (value.isImplicitInitialValue()) {
396 if (allowImplicitInitial)
397 continue;
398 return Invalid;
399 }
400 if (!allowInitial && value.isInitialValue())
401 return Invalid;
402 // TODO(timloh): This should also check unset
403 if (value.isInheritedValue())
404 return Invalid;
405 }
406
407 return Unknown;
408 }
409
327 String StylePropertySerializer::getPropertyValue(CSSPropertyID propertyID) const 410 String StylePropertySerializer::getPropertyValue(CSSPropertyID propertyID) const
328 { 411 {
329 // Shorthand and 4-values properties 412 const StylePropertyShorthand& shorthand = shorthandForProperty(propertyID);
413 // TODO(timloh): This is weird, why do we call this with non-shorthands at a ll?
414 if (!shorthand.length())
415 return String();
416
417 String result;
418 CommonCheckResult commonCheckResult = commonShorthandChecks(shorthand, resul t);
419 if (commonCheckResult == Valid)
420 return result;
421 if (commonCheckResult == Invalid)
422 return String();
423
330 switch (propertyID) { 424 switch (propertyID) {
331 case CSSPropertyAnimation: 425 case CSSPropertyAnimation:
332 return getLayeredShorthandValue(animationShorthand()); 426 return getLayeredShorthandValue(animationShorthand());
333 case CSSPropertyBorderSpacing: 427 case CSSPropertyBorderSpacing:
334 return borderSpacingValue(borderSpacingShorthand()); 428 return borderSpacingValue(borderSpacingShorthand());
335 case CSSPropertyBackgroundPosition: 429 case CSSPropertyBackgroundPosition:
336 return getLayeredShorthandValue(backgroundPositionShorthand()); 430 return getLayeredShorthandValue(backgroundPositionShorthand());
337 case CSSPropertyBackgroundRepeat: 431 case CSSPropertyBackgroundRepeat:
338 return backgroundRepeatPropertyValue(); 432 return backgroundRepeatPropertyValue();
339 case CSSPropertyBackground: 433 case CSSPropertyBackground:
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
410 default: 504 default:
411 return String(); 505 return String();
412 } 506 }
413 } 507 }
414 508
415 String StylePropertySerializer::borderSpacingValue(const StylePropertyShorthand& shorthand) const 509 String StylePropertySerializer::borderSpacingValue(const StylePropertyShorthand& shorthand) const
416 { 510 {
417 const CSSValue* horizontalValue = m_propertySet.getPropertyCSSValue(shorthan d.properties()[0]); 511 const CSSValue* horizontalValue = m_propertySet.getPropertyCSSValue(shorthan d.properties()[0]);
418 const CSSValue* verticalValue = m_propertySet.getPropertyCSSValue(shorthand. properties()[1]); 512 const CSSValue* verticalValue = m_propertySet.getPropertyCSSValue(shorthand. properties()[1]);
419 513
420 // While standard border-spacing property does not allow specifying border-s pacing-vertical without
421 // specifying border-spacing-horizontal <http://www.w3.org/TR/CSS21/tables.h tml#separated-borders>,
422 // -webkit-border-spacing-vertical can be set without -webkit-border-spacing -horizontal.
423 if (!horizontalValue || !verticalValue)
424 return String();
425
426 String horizontalValueCSSText = horizontalValue->cssText(); 514 String horizontalValueCSSText = horizontalValue->cssText();
427 String verticalValueCSSText = verticalValue->cssText(); 515 String verticalValueCSSText = verticalValue->cssText();
428 if (horizontalValueCSSText == verticalValueCSSText) 516 if (horizontalValueCSSText == verticalValueCSSText)
429 return horizontalValueCSSText; 517 return horizontalValueCSSText;
430 return horizontalValueCSSText + ' ' + verticalValueCSSText; 518 return horizontalValueCSSText + ' ' + verticalValueCSSText;
431 } 519 }
432 520
433 void StylePropertySerializer::appendFontLonghandValueIfNotNormal(CSSPropertyID p ropertyID, StringBuilder& result, String& commonValue) const 521 void StylePropertySerializer::appendFontLonghandValueIfNotNormal(CSSPropertyID p ropertyID, StringBuilder& result) const
434 { 522 {
435 int foundPropertyIndex = m_propertySet.findPropertyIndex(propertyID); 523 int foundPropertyIndex = m_propertySet.findPropertyIndex(propertyID);
436 ASSERT(foundPropertyIndex != -1); 524 ASSERT(foundPropertyIndex != -1);
437 525
438 const CSSValue* val = m_propertySet.propertyAt(foundPropertyIndex).value(); 526 const CSSValue* val = m_propertySet.propertyAt(foundPropertyIndex).value();
439 if (val->isPrimitiveValue() && toCSSPrimitiveValue(val)->getValueID() == CSS ValueNormal) { 527 if (val->isPrimitiveValue() && toCSSPrimitiveValue(val)->getValueID() == CSS ValueNormal)
440 commonValue = String();
441 return; 528 return;
442 }
443 529
444 char prefix = '\0'; 530 char prefix = '\0';
445 switch (propertyID) { 531 switch (propertyID) {
446 case CSSPropertyFontStyle: 532 case CSSPropertyFontStyle:
447 break; // No prefix. 533 break; // No prefix.
448 case CSSPropertyFontFamily: 534 case CSSPropertyFontFamily:
449 case CSSPropertyFontStretch: 535 case CSSPropertyFontStretch:
450 case CSSPropertyFontVariantCaps: 536 case CSSPropertyFontVariantCaps:
451 case CSSPropertyFontVariantLigatures: 537 case CSSPropertyFontVariantLigatures:
452 case CSSPropertyFontVariantNumeric: 538 case CSSPropertyFontVariantNumeric:
(...skipping 14 matching lines...) Expand all
467 // In the font-variant shorthand a "none" ligatures value needs to be expand ed. 553 // In the font-variant shorthand a "none" ligatures value needs to be expand ed.
468 if (propertyID == CSSPropertyFontVariantLigatures 554 if (propertyID == CSSPropertyFontVariantLigatures
469 && val->isPrimitiveValue() 555 && val->isPrimitiveValue()
470 && toCSSPrimitiveValue(val)->getValueID() == CSSValueNone) { 556 && toCSSPrimitiveValue(val)->getValueID() == CSSValueNone) {
471 value = "no-common-ligatures no-discretionary-ligatures no-historical-li gatures no-contextual"; 557 value = "no-common-ligatures no-discretionary-ligatures no-historical-li gatures no-contextual";
472 } else { 558 } else {
473 value = m_propertySet.propertyAt(foundPropertyIndex).value()->cssText(); 559 value = m_propertySet.propertyAt(foundPropertyIndex).value()->cssText();
474 } 560 }
475 561
476 result.append(value); 562 result.append(value);
477 if (!commonValue.isNull() && commonValue != value)
478 commonValue = String();
479 } 563 }
480 564
481 String StylePropertySerializer::fontValue() const 565 String StylePropertySerializer::fontValue() const
482 { 566 {
483 if (!isPropertyShorthandAvailable(fontShorthand()) && !shorthandHasOnlyIniti alOrInheritedValue(fontShorthand()))
484 return emptyString();
485
486 int fontSizePropertyIndex = m_propertySet.findPropertyIndex(CSSPropertyFontS ize); 567 int fontSizePropertyIndex = m_propertySet.findPropertyIndex(CSSPropertyFontS ize);
487 int fontFamilyPropertyIndex = m_propertySet.findPropertyIndex(CSSPropertyFon tFamily); 568 int fontFamilyPropertyIndex = m_propertySet.findPropertyIndex(CSSPropertyFon tFamily);
488 int fontVariantCapsPropertyIndex = m_propertySet.findPropertyIndex(CSSProper tyFontVariantCaps); 569 int fontVariantCapsPropertyIndex = m_propertySet.findPropertyIndex(CSSProper tyFontVariantCaps);
489 int fontVariantLigaturesPropertyIndex = m_propertySet.findPropertyIndex(CSSP ropertyFontVariantLigatures); 570 int fontVariantLigaturesPropertyIndex = m_propertySet.findPropertyIndex(CSSP ropertyFontVariantLigatures);
490 int fontVariantNumericPropertyIndex = m_propertySet.findPropertyIndex(CSSPro pertyFontVariantNumeric); 571 int fontVariantNumericPropertyIndex = m_propertySet.findPropertyIndex(CSSPro pertyFontVariantNumeric);
491 DCHECK_NE(fontSizePropertyIndex, -1); 572 DCHECK_NE(fontSizePropertyIndex, -1);
492 DCHECK_NE(fontFamilyPropertyIndex, -1); 573 DCHECK_NE(fontFamilyPropertyIndex, -1);
493 DCHECK_NE(fontVariantCapsPropertyIndex, -1); 574 DCHECK_NE(fontVariantCapsPropertyIndex, -1);
494 DCHECK_NE(fontVariantLigaturesPropertyIndex, -1); 575 DCHECK_NE(fontVariantLigaturesPropertyIndex, -1);
495 DCHECK_NE(fontVariantNumericPropertyIndex, -1); 576 DCHECK_NE(fontVariantNumericPropertyIndex, -1);
496 577
497 PropertyValueForSerializer fontSizeProperty = m_propertySet.propertyAt(fontS izePropertyIndex); 578 PropertyValueForSerializer fontSizeProperty = m_propertySet.propertyAt(fontS izePropertyIndex);
498 PropertyValueForSerializer fontFamilyProperty = m_propertySet.propertyAt(fon tFamilyPropertyIndex); 579 PropertyValueForSerializer fontFamilyProperty = m_propertySet.propertyAt(fon tFamilyPropertyIndex);
499 PropertyValueForSerializer fontVariantCapsProperty = m_propertySet.propertyA t(fontVariantCapsPropertyIndex); 580 PropertyValueForSerializer fontVariantCapsProperty = m_propertySet.propertyA t(fontVariantCapsPropertyIndex);
500 PropertyValueForSerializer fontVariantLigaturesProperty = m_propertySet.prop ertyAt(fontVariantLigaturesPropertyIndex); 581 PropertyValueForSerializer fontVariantLigaturesProperty = m_propertySet.prop ertyAt(fontVariantLigaturesPropertyIndex);
501 PropertyValueForSerializer fontVariantNumericProperty = m_propertySet.proper tyAt(fontVariantNumericPropertyIndex); 582 PropertyValueForSerializer fontVariantNumericProperty = m_propertySet.proper tyAt(fontVariantNumericPropertyIndex);
502 583
503 // Check that non-initial font-variant subproperties are not conflicting wit h this serialization. 584 // Check that non-initial font-variant subproperties are not conflicting wit h this serialization.
504 const CSSValue* ligaturesValue = fontVariantLigaturesProperty.value(); 585 const CSSValue* ligaturesValue = fontVariantLigaturesProperty.value();
505 const CSSValue* numericValue = fontVariantNumericProperty.value(); 586 const CSSValue* numericValue = fontVariantNumericProperty.value();
506 if ((ligaturesValue->isPrimitiveValue() 587 if ((ligaturesValue->isPrimitiveValue()
507 && toCSSPrimitiveValue(ligaturesValue)->getValueID() != CSSValueNormal) 588 && toCSSPrimitiveValue(ligaturesValue)->getValueID() != CSSValueNormal)
508 || ligaturesValue->isValueList() 589 || ligaturesValue->isValueList()
509 || (numericValue->isPrimitiveValue() 590 || (numericValue->isPrimitiveValue()
510 && toCSSPrimitiveValue(numericValue)->getValueID() != CSSValueNormal) 591 && toCSSPrimitiveValue(numericValue)->getValueID() != CSSValueNormal)
511 || numericValue->isValueList()) 592 || numericValue->isValueList())
512 return emptyString(); 593 return emptyString();
513 594
514 String commonValue = fontSizeProperty.value()->cssText();
515 StringBuilder result; 595 StringBuilder result;
516 appendFontLonghandValueIfNotNormal(CSSPropertyFontStyle, result, commonValue ); 596 appendFontLonghandValueIfNotNormal(CSSPropertyFontStyle, result);
517 597
518 const CSSValue* val = fontVariantCapsProperty.value(); 598 const CSSValue* val = fontVariantCapsProperty.value();
519 if (val->isPrimitiveValue() 599 if (val->isPrimitiveValue()
520 && (toCSSPrimitiveValue(val)->getValueID() != CSSValueSmallCaps 600 && (toCSSPrimitiveValue(val)->getValueID() != CSSValueSmallCaps
521 && toCSSPrimitiveValue(val)->getValueID() != CSSValueNormal)) 601 && toCSSPrimitiveValue(val)->getValueID() != CSSValueNormal))
522 return emptyString(); 602 return emptyString();
523 appendFontLonghandValueIfNotNormal(CSSPropertyFontVariantCaps, result, commo nValue); 603 appendFontLonghandValueIfNotNormal(CSSPropertyFontVariantCaps, result);
524 604
525 appendFontLonghandValueIfNotNormal(CSSPropertyFontWeight, result, commonValu e); 605 appendFontLonghandValueIfNotNormal(CSSPropertyFontWeight, result);
526 appendFontLonghandValueIfNotNormal(CSSPropertyFontStretch, result, commonVal ue); 606 appendFontLonghandValueIfNotNormal(CSSPropertyFontStretch, result);
527 if (!result.isEmpty()) 607 if (!result.isEmpty())
528 result.append(' '); 608 result.append(' ');
529 result.append(fontSizeProperty.value()->cssText()); 609 result.append(fontSizeProperty.value()->cssText());
530 appendFontLonghandValueIfNotNormal(CSSPropertyLineHeight, result, commonValu e); 610 appendFontLonghandValueIfNotNormal(CSSPropertyLineHeight, result);
531 if (!result.isEmpty()) 611 if (!result.isEmpty())
532 result.append(' '); 612 result.append(' ');
533 result.append(fontFamilyProperty.value()->cssText()); 613 result.append(fontFamilyProperty.value()->cssText());
534 if (isInitialOrInherit(commonValue))
535 return commonValue;
536 return result.toString(); 614 return result.toString();
537 } 615 }
538 616
539 String StylePropertySerializer::fontVariantValue() const 617 String StylePropertySerializer::fontVariantValue() const
540 { 618 {
541 if (!isPropertyShorthandAvailable(fontVariantShorthand())) {
542 if (!shorthandHasOnlyInitialOrInheritedValue(fontVariantShorthand()))
543 return String();
544 return m_propertySet.getPropertyValue(CSSPropertyFontVariantLigatures);
545 }
546
547 StringBuilder result; 619 StringBuilder result;
548 620
549 // TODO(drott): Decide how we want to return ligature values in shorthands, reduced to "none" or 621 // TODO(drott): Decide how we want to return ligature values in shorthands, reduced to "none" or
550 // spelled out, filed as W3C bug: 622 // spelled out, filed as W3C bug:
551 // https://www.w3.org/Bugs/Public/show_bug.cgi?id=29594 623 // https://www.w3.org/Bugs/Public/show_bug.cgi?id=29594
552 String dummyCommonValue; 624 appendFontLonghandValueIfNotNormal(CSSPropertyFontVariantLigatures, result);
553 appendFontLonghandValueIfNotNormal(CSSPropertyFontVariantLigatures, result, dummyCommonValue); 625 appendFontLonghandValueIfNotNormal(CSSPropertyFontVariantCaps, result);
554 appendFontLonghandValueIfNotNormal(CSSPropertyFontVariantCaps, result, dummy CommonValue); 626 appendFontLonghandValueIfNotNormal(CSSPropertyFontVariantNumeric, result);
555 appendFontLonghandValueIfNotNormal(CSSPropertyFontVariantNumeric, result, du mmyCommonValue);
556 627
557 if (result.isEmpty()) { 628 if (result.isEmpty()) {
558 return "normal"; 629 return "normal";
559 } 630 }
560 631
561 return result.toString(); 632 return result.toString();
562 } 633 }
563 634
564 String StylePropertySerializer::get4Values(const StylePropertyShorthand& shortha nd) const 635 String StylePropertySerializer::get4Values(const StylePropertyShorthand& shortha nd) const
565 { 636 {
566 // Assume the properties are in the usual order top, right, bottom, left. 637 // Assume the properties are in the usual order top, right, bottom, left.
567 int topValueIndex = m_propertySet.findPropertyIndex(shorthand.properties()[0 ]); 638 int topValueIndex = m_propertySet.findPropertyIndex(shorthand.properties()[0 ]);
568 int rightValueIndex = m_propertySet.findPropertyIndex(shorthand.properties() [1]); 639 int rightValueIndex = m_propertySet.findPropertyIndex(shorthand.properties() [1]);
569 int bottomValueIndex = m_propertySet.findPropertyIndex(shorthand.properties( )[2]); 640 int bottomValueIndex = m_propertySet.findPropertyIndex(shorthand.properties( )[2]);
570 int leftValueIndex = m_propertySet.findPropertyIndex(shorthand.properties()[ 3]); 641 int leftValueIndex = m_propertySet.findPropertyIndex(shorthand.properties()[ 3]);
571 642
572 if (topValueIndex == -1 || rightValueIndex == -1 || bottomValueIndex == -1 | | leftValueIndex == -1) 643 if (topValueIndex == -1 || rightValueIndex == -1 || bottomValueIndex == -1 | | leftValueIndex == -1)
573 return String(); 644 return String();
574 645
575 PropertyValueForSerializer top = m_propertySet.propertyAt(topValueIndex); 646 PropertyValueForSerializer top = m_propertySet.propertyAt(topValueIndex);
576 PropertyValueForSerializer right = m_propertySet.propertyAt(rightValueIndex) ; 647 PropertyValueForSerializer right = m_propertySet.propertyAt(rightValueIndex) ;
577 PropertyValueForSerializer bottom = m_propertySet.propertyAt(bottomValueInde x); 648 PropertyValueForSerializer bottom = m_propertySet.propertyAt(bottomValueInde x);
578 PropertyValueForSerializer left = m_propertySet.propertyAt(leftValueIndex); 649 PropertyValueForSerializer left = m_propertySet.propertyAt(leftValueIndex);
579 650
580 // All 4 properties must be specified.
581 if (!top.value() || !right.value() || !bottom.value() || !left.value())
582 return String();
583
584 if (top.isImportant() != right.isImportant() || right.isImportant() != botto m.isImportant() || bottom.isImportant() != left.isImportant())
585 return String();
586
587 if (top.isInherited() && right.isInherited() && bottom.isInherited() && left .isInherited())
588 return getValueName(CSSValueInherit);
589
590 unsigned numInitial = top.value()->isInitialValue() + right.value()->isIniti alValue() + bottom.value()->isInitialValue() + left.value()->isInitialValue();
591 if (numInitial == 4)
592 return getValueName(CSSValueInitial);
593 if (numInitial > 0)
594 return String();
595
596 bool showLeft = !right.value()->equals(*left.value()); 651 bool showLeft = !right.value()->equals(*left.value());
597 bool showBottom = !top.value()->equals(*bottom.value()) || showLeft; 652 bool showBottom = !top.value()->equals(*bottom.value()) || showLeft;
598 bool showRight = !top.value()->equals(*right.value()) || showBottom; 653 bool showRight = !top.value()->equals(*right.value()) || showBottom;
599 654
600 StringBuilder result; 655 StringBuilder result;
601 result.append(top.value()->cssText()); 656 result.append(top.value()->cssText());
602 if (showRight) { 657 if (showRight) {
603 result.append(' '); 658 result.append(' ');
604 result.append(right.value()->cssText()); 659 result.append(right.value()->cssText());
605 } 660 }
(...skipping 12 matching lines...) Expand all
618 { 673 {
619 const unsigned size = shorthand.length(); 674 const unsigned size = shorthand.length();
620 675
621 // Begin by collecting the properties into a vector. 676 // Begin by collecting the properties into a vector.
622 HeapVector<Member<const CSSValue>> values(size); 677 HeapVector<Member<const CSSValue>> values(size);
623 // If the below loop succeeds, there should always be at minimum 1 layer. 678 // If the below loop succeeds, there should always be at minimum 1 layer.
624 size_t numLayers = 1U; 679 size_t numLayers = 1U;
625 680
626 for (size_t i = 0; i < size; i++) { 681 for (size_t i = 0; i < size; i++) {
627 values[i] = m_propertySet.getPropertyCSSValue(shorthand.properties()[i]) ; 682 values[i] = m_propertySet.getPropertyCSSValue(shorthand.properties()[i]) ;
628 // A shorthand is not available if getPropertyCSSValue didn't resolve to anything.
629 if (!values[i])
630 return String();
631 if (values[i]->isBaseValueList()) { 683 if (values[i]->isBaseValueList()) {
632 const CSSValueList* valueList = toCSSValueList(values[i]); 684 const CSSValueList* valueList = toCSSValueList(values[i]);
633 numLayers = std::max(numLayers, valueList->length()); 685 numLayers = std::max(numLayers, valueList->length());
634 } 686 }
635 } 687 }
636 688
637 StringBuilder result; 689 StringBuilder result;
638 // Tracks whether or not all the values are initial or all the values are in herit.
639 // Start out assuming there is a common value. It will get set to false belo w if there isn't one.
640 bool hasCommonValue = true;
641 const CSSValue* commonValue = nullptr;
642 690
643 // Now stitch the properties together. Implicit initial values are flagged a s such and 691 // Now stitch the properties together. Implicit initial values are flagged a s such and
644 // can safely be omitted. 692 // can safely be omitted.
645 for (size_t layer = 0; layer < numLayers; layer++) { 693 for (size_t layer = 0; layer < numLayers; layer++) {
646 StringBuilder layerResult; 694 StringBuilder layerResult;
647 bool useRepeatXShorthand = false; 695 bool useRepeatXShorthand = false;
648 bool useRepeatYShorthand = false; 696 bool useRepeatYShorthand = false;
649 bool useSingleWordShorthand = false; 697 bool useSingleWordShorthand = false;
650 bool foundPositionXCSSProperty = false; 698 bool foundPositionXCSSProperty = false;
651 bool foundPositionYCSSProperty = false; 699 bool foundPositionYCSSProperty = false;
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
717 if (useSingleWordShorthand) 765 if (useSingleWordShorthand)
718 useSingleWordShorthand = false; 766 useSingleWordShorthand = false;
719 layerResult.append(value->cssText()); 767 layerResult.append(value->cssText());
720 } 768 }
721 if (property == CSSPropertyBackgroundPositionX || property == CS SPropertyWebkitMaskPositionX) 769 if (property == CSSPropertyBackgroundPositionX || property == CS SPropertyWebkitMaskPositionX)
722 foundPositionXCSSProperty = true; 770 foundPositionXCSSProperty = true;
723 if (property == CSSPropertyBackgroundPositionY || property == CS SPropertyWebkitMaskPositionY) { 771 if (property == CSSPropertyBackgroundPositionY || property == CS SPropertyWebkitMaskPositionY) {
724 foundPositionYCSSProperty = true; 772 foundPositionYCSSProperty = true;
725 // background-position is a special case. If only the first offset is specified, 773 // background-position is a special case. If only the first offset is specified,
726 // the second one defaults to "center", not the same value. 774 // the second one defaults to "center", not the same value.
727 if (hasCommonValue && !value->isInitialValue() && !value->is InheritedValue())
728 hasCommonValue = false;
729 } 775 }
730 } 776 }
731
732 if (hasCommonValue && !commonValue)
733 commonValue = value;
734 else if (!value->equals(*commonValue))
735 hasCommonValue = false;
736 } 777 }
737 if (!layerResult.isEmpty()) { 778 if (!layerResult.isEmpty()) {
738 if (!result.isEmpty()) 779 if (!result.isEmpty())
739 result.appendLiteral(", "); 780 result.appendLiteral(", ");
740 result.append(layerResult); 781 result.append(layerResult);
741 } 782 }
742 } 783 }
743 784
744 if (hasCommonValue && (commonValue->isInitialValue() || commonValue->isInher itedValue()))
745 return commonValue->cssText();
746
747 return result.toString(); 785 return result.toString();
748 } 786 }
749 787
750 String StylePropertySerializer::getShorthandValue(const StylePropertyShorthand& shorthand, String separator) const 788 String StylePropertySerializer::getShorthandValue(const StylePropertyShorthand& shorthand, String separator) const
751 { 789 {
752 String commonValue;
753 StringBuilder result; 790 StringBuilder result;
754 for (unsigned i = 0; i < shorthand.length(); ++i) { 791 for (unsigned i = 0; i < shorthand.length(); ++i) {
755 const CSSValue* value = m_propertySet.getPropertyCSSValue(shorthand.prop erties()[i]); 792 const CSSValue* value = m_propertySet.getPropertyCSSValue(shorthand.prop erties()[i]);
756 if (!value)
757 return String();
758 String valueText = value->cssText(); 793 String valueText = value->cssText();
759 if (!i)
760 commonValue = valueText;
761 else if (!commonValue.isNull() && commonValue != valueText)
762 commonValue = String();
763 if (value->isInitialValue()) 794 if (value->isInitialValue())
764 continue; 795 continue;
765 if (!result.isEmpty()) 796 if (!result.isEmpty())
766 result.append(separator); 797 result.append(separator);
767 result.append(valueText); 798 result.append(valueText);
768 } 799 }
769 if (isInitialOrInherit(commonValue))
770 return commonValue;
771 return result.toString(); 800 return result.toString();
772 } 801 }
773 802
774 // only returns a non-null value if all properties have the same, non-null value 803 // only returns a non-null value if all properties have the same, non-null value
775 String StylePropertySerializer::getCommonValue(const StylePropertyShorthand& sho rthand) const 804 String StylePropertySerializer::getCommonValue(const StylePropertyShorthand& sho rthand) const
776 { 805 {
777 String res; 806 String res;
778 bool lastPropertyWasImportant = false;
779 for (unsigned i = 0; i < shorthand.length(); ++i) { 807 for (unsigned i = 0; i < shorthand.length(); ++i) {
780 const CSSValue* value = m_propertySet.getPropertyCSSValue(shorthand.prop erties()[i]); 808 const CSSValue* value = m_propertySet.getPropertyCSSValue(shorthand.prop erties()[i]);
781 // FIXME: CSSInitialValue::cssText should generate the right value. 809 // FIXME: CSSInitialValue::cssText should generate the right value.
782 if (!value)
783 return String();
784 String text = value->cssText(); 810 String text = value->cssText();
785 if (text.isNull())
786 return String();
787 if (res.isNull()) 811 if (res.isNull())
788 res = text; 812 res = text;
789 else if (res != text) 813 else if (res != text)
790 return String(); 814 return String();
791
792 bool currentPropertyIsImportant = m_propertySet.propertyIsImportant(shor thand.properties()[i]);
793 if (i && lastPropertyWasImportant != currentPropertyIsImportant)
794 return String();
795 lastPropertyWasImportant = currentPropertyIsImportant;
796 } 815 }
797 return res; 816 return res;
798 } 817 }
799 818
800 String StylePropertySerializer::borderPropertyValue() const 819 String StylePropertySerializer::borderPropertyValue() const
801 { 820 {
802 const StylePropertyShorthand properties[3] = { borderWidthShorthand(), borde rStyleShorthand(), borderColorShorthand() }; 821 const StylePropertyShorthand properties[3] = { borderWidthShorthand(), borde rStyleShorthand(), borderColorShorthand() };
803 String commonValue;
804 StringBuilder result; 822 StringBuilder result;
805 for (size_t i = 0; i < WTF_ARRAY_LENGTH(properties); ++i) { 823 for (size_t i = 0; i < WTF_ARRAY_LENGTH(properties); ++i) {
806 String value = getCommonValue(properties[i]); 824 String value = getCommonValue(properties[i]);
807 if (value.isNull()) 825 if (value.isNull())
808 return String(); 826 return String();
809 if (!i)
810 commonValue = value;
811 else if (!commonValue.isNull() && commonValue != value)
812 commonValue = String();
813 if (value == "initial") 827 if (value == "initial")
814 continue; 828 continue;
815 if (!result.isEmpty()) 829 if (!result.isEmpty())
816 result.append(' '); 830 result.append(' ');
817 result.append(value); 831 result.append(value);
818 } 832 }
819 if (isInitialOrInherit(commonValue))
820 return commonValue;
821 return result.isEmpty() ? String() : result.toString(); 833 return result.isEmpty() ? String() : result.toString();
822 } 834 }
823 835
824 static void appendBackgroundRepeatValue(StringBuilder& builder, const CSSValue& repeatXCSSValue, const CSSValue& repeatYCSSValue) 836 static void appendBackgroundRepeatValue(StringBuilder& builder, const CSSValue& repeatXCSSValue, const CSSValue& repeatYCSSValue)
825 { 837 {
826 // FIXME: Ensure initial values do not appear in CSS_VALUE_LISTS. 838 // FIXME: Ensure initial values do not appear in CSS_VALUE_LISTS.
827 DEFINE_STATIC_LOCAL(CSSPrimitiveValue, initialRepeatValue, (CSSPrimitiveValu e::createIdentifier(CSSValueRepeat))); 839 DEFINE_STATIC_LOCAL(CSSPrimitiveValue, initialRepeatValue, (CSSPrimitiveValu e::createIdentifier(CSSValueRepeat)));
828 const CSSPrimitiveValue& repeatX = repeatXCSSValue.isInitialValue() ? initia lRepeatValue : toCSSPrimitiveValue(repeatXCSSValue); 840 const CSSPrimitiveValue& repeatX = repeatXCSSValue.isInitialValue() ? initia lRepeatValue : toCSSPrimitiveValue(repeatXCSSValue);
829 const CSSPrimitiveValue& repeatY = repeatYCSSValue.isInitialValue() ? initia lRepeatValue : toCSSPrimitiveValue(repeatYCSSValue); 841 const CSSPrimitiveValue& repeatY = repeatYCSSValue.isInitialValue() ? initia lRepeatValue : toCSSPrimitiveValue(repeatYCSSValue);
830 CSSValueID repeatXValueId = repeatX.getValueID(); 842 CSSValueID repeatXValueId = repeatX.getValueID();
831 CSSValueID repeatYValueId = repeatY.getValueID(); 843 CSSValueID repeatYValueId = repeatY.getValueID();
832 if (repeatXValueId == repeatYValueId) { 844 if (repeatXValueId == repeatYValueId) {
833 builder.append(repeatX.cssText()); 845 builder.append(repeatX.cssText());
834 } else if (repeatXValueId == CSSValueNoRepeat && repeatYValueId == CSSValueR epeat) { 846 } else if (repeatXValueId == CSSValueNoRepeat && repeatYValueId == CSSValueR epeat) {
835 builder.appendLiteral("repeat-y"); 847 builder.appendLiteral("repeat-y");
836 } else if (repeatXValueId == CSSValueRepeat && repeatYValueId == CSSValueNoR epeat) { 848 } else if (repeatXValueId == CSSValueRepeat && repeatYValueId == CSSValueNoR epeat) {
837 builder.appendLiteral("repeat-x"); 849 builder.appendLiteral("repeat-x");
838 } else { 850 } else {
839 builder.append(repeatX.cssText()); 851 builder.append(repeatX.cssText());
840 builder.appendLiteral(" "); 852 builder.appendLiteral(" ");
841 builder.append(repeatY.cssText()); 853 builder.append(repeatY.cssText());
842 } 854 }
843 } 855 }
844 856
845 String StylePropertySerializer::backgroundRepeatPropertyValue() const 857 String StylePropertySerializer::backgroundRepeatPropertyValue() const
846 { 858 {
847 const CSSValue* repeatX = m_propertySet.getPropertyCSSValue(CSSPropertyBackg roundRepeatX); 859 const CSSValue* repeatX = m_propertySet.getPropertyCSSValue(CSSPropertyBackg roundRepeatX);
848 const CSSValue* repeatY = m_propertySet.getPropertyCSSValue(CSSPropertyBackg roundRepeatY); 860 const CSSValue* repeatY = m_propertySet.getPropertyCSSValue(CSSPropertyBackg roundRepeatY);
849 if (!repeatX || !repeatY)
850 return String();
851 if (m_propertySet.propertyIsImportant(CSSPropertyBackgroundRepeatX) != m_pro pertySet.propertyIsImportant(CSSPropertyBackgroundRepeatY))
852 return String();
853 if ((repeatX->isInitialValue() && repeatY->isInitialValue()) || (repeatX->is InheritedValue() && repeatY->isInheritedValue()))
854 return repeatX->cssText();
855 861
856 const CSSValueList* repeatXList = 0; 862 const CSSValueList* repeatXList = 0;
857 int repeatXLength = 1; 863 int repeatXLength = 1;
858 if (repeatX->isValueList()) { 864 if (repeatX->isValueList()) {
859 repeatXList = toCSSValueList(repeatX); 865 repeatXList = toCSSValueList(repeatX);
860 repeatXLength = repeatXList->length(); 866 repeatXLength = repeatXList->length();
861 } else if (!repeatX->isPrimitiveValue()) { 867 } else if (!repeatX->isPrimitiveValue()) {
862 return String(); 868 return String();
863 } 869 }
864 870
(...skipping 12 matching lines...) Expand all
877 if (i) 883 if (i)
878 builder.appendLiteral(", "); 884 builder.appendLiteral(", ");
879 885
880 const CSSValue* xValue = repeatXList ? repeatXList->item(i % repeatXList ->length()) : repeatX; 886 const CSSValue* xValue = repeatXList ? repeatXList->item(i % repeatXList ->length()) : repeatX;
881 const CSSValue* yValue = repeatYList ? repeatYList->item(i % repeatYList ->length()) : repeatY; 887 const CSSValue* yValue = repeatYList ? repeatYList->item(i % repeatYList ->length()) : repeatY;
882 appendBackgroundRepeatValue(builder, *xValue, *yValue); 888 appendBackgroundRepeatValue(builder, *xValue, *yValue);
883 } 889 }
884 return builder.toString(); 890 return builder.toString();
885 } 891 }
886 892
887 void StylePropertySerializer::appendBackgroundPropertyAsText(StringBuilder& resu lt, unsigned& numDecls) const
888 {
889 if (isPropertyShorthandAvailable(backgroundShorthand())) {
890 String backgroundValue = getPropertyValue(CSSPropertyBackground);
891 bool isImportant = m_propertySet.propertyIsImportant(CSSPropertyBackgrou ndImage);
892 result.append(getPropertyText(CSSPropertyBackground, backgroundValue, is Important, numDecls++));
893 return;
894 }
895 if (shorthandHasOnlyInitialOrInheritedValue(backgroundShorthand())) {
896 const CSSValue* value = m_propertySet.getPropertyCSSValue(CSSPropertyBac kgroundImage);
897 bool isImportant = m_propertySet.propertyIsImportant(CSSPropertyBackgrou ndImage);
898 result.append(getPropertyText(CSSPropertyBackground, value->cssText(), i sImportant, numDecls++));
899 return;
900 }
901
902 // backgroundShorthandProperty without layered shorhand properties
903 const CSSPropertyID backgroundPropertyIds[] = {
904 CSSPropertyBackgroundImage,
905 CSSPropertyBackgroundAttachment,
906 CSSPropertyBackgroundColor,
907 CSSPropertyBackgroundSize,
908 CSSPropertyBackgroundOrigin,
909 CSSPropertyBackgroundClip
910 };
911
912 for (unsigned i = 0; i < WTF_ARRAY_LENGTH(backgroundPropertyIds); ++i) {
913 CSSPropertyID propertyID = backgroundPropertyIds[i];
914 const CSSValue* value = m_propertySet.getPropertyCSSValue(propertyID);
915 if (!value)
916 continue;
917 result.append(getPropertyText(propertyID, value->cssText(), m_propertySe t.propertyIsImportant(propertyID), numDecls++));
918 }
919
920 // FIXME: This is a not-so-nice way to turn x/y positions into single backgr ound-position in output.
921 // It is required because background-position-x/y are non-standard propertie s and WebKit generated output
922 // would not work in Firefox (<rdar://problem/5143183>)
923 // It would be a better solution if background-position was UnitType::Pair.
924 if (shorthandHasOnlyInitialOrInheritedValue(backgroundPositionShorthand())) {
925 const CSSValue* value = m_propertySet.getPropertyCSSValue(CSSPropertyBac kgroundPositionX);
926 bool isImportant = m_propertySet.propertyIsImportant(CSSPropertyBackgrou ndPositionX);
927 result.append(getPropertyText(CSSPropertyBackgroundPosition, value->cssT ext(), isImportant, numDecls++));
928 } else if (isPropertyShorthandAvailable(backgroundPositionShorthand())) {
929 String positionValue = m_propertySet.getPropertyValue(CSSPropertyBackgro undPosition);
930 bool isImportant = m_propertySet.propertyIsImportant(CSSPropertyBackgrou ndPositionX);
931 if (!positionValue.isNull())
932 result.append(getPropertyText(CSSPropertyBackgroundPosition, positio nValue, isImportant, numDecls++));
933 } else {
934 // should check background-position-x or background-position-y.
935 if (const CSSValue* value = m_propertySet.getPropertyCSSValue(CSSPropert yBackgroundPositionX)) {
936 if (!value->isImplicitInitialValue()) {
937 bool isImportant = m_propertySet.propertyIsImportant(CSSProperty BackgroundPositionX);
938 result.append(getPropertyText(CSSPropertyBackgroundPositionX, va lue->cssText(), isImportant, numDecls++));
939 }
940 }
941 if (const CSSValue* value = m_propertySet.getPropertyCSSValue(CSSPropert yBackgroundPositionY)) {
942 if (!value->isImplicitInitialValue()) {
943 bool isImportant = m_propertySet.propertyIsImportant(CSSProperty BackgroundPositionY);
944 result.append(getPropertyText(CSSPropertyBackgroundPositionY, va lue->cssText(), isImportant, numDecls++));
945 }
946 }
947 }
948
949 String repeatValue = m_propertySet.getPropertyValue(CSSPropertyBackgroundRep eat);
950 if (!repeatValue.isNull())
951 result.append(getPropertyText(CSSPropertyBackgroundRepeat, repeatValue, m_propertySet.propertyIsImportant(CSSPropertyBackgroundRepeatX), numDecls++));
952 }
953
954 bool StylePropertySerializer::isPropertyShorthandAvailable(const StylePropertySh orthand& shorthand) const
955 {
956 ASSERT(shorthand.length() > 0);
957
958 bool isImportant = m_propertySet.propertyIsImportant(shorthand.properties()[ 0]);
959 for (unsigned i = 0; i < shorthand.length(); ++i) {
960 const CSSValue* value = m_propertySet.getPropertyCSSValue(shorthand.prop erties()[i]);
961 if (!value || (value->isInitialValue() && !value->isImplicitInitialValue ()) || value->isInheritedValue())
962 return false;
963 if (isImportant != m_propertySet.propertyIsImportant(shorthand.propertie s()[i]))
964 return false;
965 }
966 return true;
967 }
968
969 bool StylePropertySerializer::shorthandHasOnlyInitialOrInheritedValue(const Styl ePropertyShorthand& shorthand) const
970 {
971 ASSERT(shorthand.length() > 0);
972 bool isImportant = m_propertySet.propertyIsImportant(shorthand.properties()[ 0]);
973 bool isInitialValue = true;
974 bool isInheritedValue = true;
975 for (unsigned i = 0; i < shorthand.length(); ++i) {
976 const CSSValue* value = m_propertySet.getPropertyCSSValue(shorthand.prop erties()[i]);
977 if (!value)
978 return false;
979 if (!value->isInitialValue())
980 isInitialValue = false;
981 if (!value->isInheritedValue())
982 isInheritedValue = false;
983 if (isImportant != m_propertySet.propertyIsImportant(shorthand.propertie s()[i]))
984 return false;
985 }
986 return isInitialValue || isInheritedValue;
987 }
988
989 } // namespace blink 893 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698