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

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: actually fix test 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 String StylePropertySerializer::commonShorthandChecks(const StylePropertyShortha nd& shorthand) 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 emptyString();
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 emptyString();
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 emptyString() but some shorthands cur rently
380 // allow 'initial' for their longhands.
381 success = false;
382 break;
383 }
384 }
385 if (success)
386 return longhands[0]->cssText();
387 }
388
389 bool allowInitial = allowInitialInShorthand(shorthand.id());
390 bool allowImplicitInitial = allowInitial || allowImplicitInitialInShorthand( shorthand.id());
391 for (int i = 0; i < longhandCount; i++) {
392 const CSSValue& value = *longhands[i];
393 if (value.isImplicitInitialValue()) {
394 if (allowImplicitInitial)
395 continue;
396 return emptyString();
397 }
398 if (!allowInitial && value.isInitialValue())
399 return emptyString();
400 // TODO(timloh): This should also check unset
401 if (value.isInheritedValue())
402 return emptyString();
403 }
404
405 return String();
406 }
407
327 String StylePropertySerializer::getPropertyValue(CSSPropertyID propertyID) const 408 String StylePropertySerializer::getPropertyValue(CSSPropertyID propertyID) const
328 { 409 {
329 // Shorthand and 4-values properties 410 const StylePropertyShorthand& shorthand = shorthandForProperty(propertyID);
411 // TODO(timloh): This is weird, why do we call this with non-shorthands at a ll?
412 if (!shorthand.length())
413 return String();
414
415 String result = commonShorthandChecks(shorthand);
416 if (!result.isNull())
417 return result;
418
330 switch (propertyID) { 419 switch (propertyID) {
331 case CSSPropertyAnimation: 420 case CSSPropertyAnimation:
332 return getLayeredShorthandValue(animationShorthand()); 421 return getLayeredShorthandValue(animationShorthand());
333 case CSSPropertyBorderSpacing: 422 case CSSPropertyBorderSpacing:
334 return borderSpacingValue(borderSpacingShorthand()); 423 return borderSpacingValue(borderSpacingShorthand());
335 case CSSPropertyBackgroundPosition: 424 case CSSPropertyBackgroundPosition:
336 return getLayeredShorthandValue(backgroundPositionShorthand()); 425 return getLayeredShorthandValue(backgroundPositionShorthand());
337 case CSSPropertyBackgroundRepeat: 426 case CSSPropertyBackgroundRepeat:
338 return backgroundRepeatPropertyValue(); 427 return backgroundRepeatPropertyValue();
339 case CSSPropertyBackground: 428 case CSSPropertyBackground:
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
410 default: 499 default:
411 return String(); 500 return String();
412 } 501 }
413 } 502 }
414 503
415 String StylePropertySerializer::borderSpacingValue(const StylePropertyShorthand& shorthand) const 504 String StylePropertySerializer::borderSpacingValue(const StylePropertyShorthand& shorthand) const
416 { 505 {
417 const CSSValue* horizontalValue = m_propertySet.getPropertyCSSValue(shorthan d.properties()[0]); 506 const CSSValue* horizontalValue = m_propertySet.getPropertyCSSValue(shorthan d.properties()[0]);
418 const CSSValue* verticalValue = m_propertySet.getPropertyCSSValue(shorthand. properties()[1]); 507 const CSSValue* verticalValue = m_propertySet.getPropertyCSSValue(shorthand. properties()[1]);
419 508
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(); 509 String horizontalValueCSSText = horizontalValue->cssText();
427 String verticalValueCSSText = verticalValue->cssText(); 510 String verticalValueCSSText = verticalValue->cssText();
428 if (horizontalValueCSSText == verticalValueCSSText) 511 if (horizontalValueCSSText == verticalValueCSSText)
429 return horizontalValueCSSText; 512 return horizontalValueCSSText;
430 return horizontalValueCSSText + ' ' + verticalValueCSSText; 513 return horizontalValueCSSText + ' ' + verticalValueCSSText;
431 } 514 }
432 515
433 void StylePropertySerializer::appendFontLonghandValueIfNotNormal(CSSPropertyID p ropertyID, StringBuilder& result, String& commonValue) const 516 void StylePropertySerializer::appendFontLonghandValueIfNotNormal(CSSPropertyID p ropertyID, StringBuilder& result) const
434 { 517 {
435 int foundPropertyIndex = m_propertySet.findPropertyIndex(propertyID); 518 int foundPropertyIndex = m_propertySet.findPropertyIndex(propertyID);
436 ASSERT(foundPropertyIndex != -1); 519 ASSERT(foundPropertyIndex != -1);
437 520
438 const CSSValue* val = m_propertySet.propertyAt(foundPropertyIndex).value(); 521 const CSSValue* val = m_propertySet.propertyAt(foundPropertyIndex).value();
439 if (val->isPrimitiveValue() && toCSSPrimitiveValue(val)->getValueID() == CSS ValueNormal) { 522 if (val->isPrimitiveValue() && toCSSPrimitiveValue(val)->getValueID() == CSS ValueNormal)
440 commonValue = String();
441 return; 523 return;
442 }
443 524
444 char prefix = '\0'; 525 char prefix = '\0';
445 switch (propertyID) { 526 switch (propertyID) {
446 case CSSPropertyFontStyle: 527 case CSSPropertyFontStyle:
447 break; // No prefix. 528 break; // No prefix.
448 case CSSPropertyFontFamily: 529 case CSSPropertyFontFamily:
449 case CSSPropertyFontStretch: 530 case CSSPropertyFontStretch:
450 case CSSPropertyFontVariantCaps: 531 case CSSPropertyFontVariantCaps:
451 case CSSPropertyFontVariantLigatures: 532 case CSSPropertyFontVariantLigatures:
452 case CSSPropertyFontVariantNumeric: 533 case CSSPropertyFontVariantNumeric:
(...skipping 14 matching lines...) Expand all
467 // In the font-variant shorthand a "none" ligatures value needs to be expand ed. 548 // In the font-variant shorthand a "none" ligatures value needs to be expand ed.
468 if (propertyID == CSSPropertyFontVariantLigatures 549 if (propertyID == CSSPropertyFontVariantLigatures
469 && val->isPrimitiveValue() 550 && val->isPrimitiveValue()
470 && toCSSPrimitiveValue(val)->getValueID() == CSSValueNone) { 551 && toCSSPrimitiveValue(val)->getValueID() == CSSValueNone) {
471 value = "no-common-ligatures no-discretionary-ligatures no-historical-li gatures no-contextual"; 552 value = "no-common-ligatures no-discretionary-ligatures no-historical-li gatures no-contextual";
472 } else { 553 } else {
473 value = m_propertySet.propertyAt(foundPropertyIndex).value()->cssText(); 554 value = m_propertySet.propertyAt(foundPropertyIndex).value()->cssText();
474 } 555 }
475 556
476 result.append(value); 557 result.append(value);
477 if (!commonValue.isNull() && commonValue != value)
478 commonValue = String();
479 } 558 }
480 559
481 String StylePropertySerializer::fontValue() const 560 String StylePropertySerializer::fontValue() const
482 { 561 {
483 if (!isPropertyShorthandAvailable(fontShorthand()) && !shorthandHasOnlyIniti alOrInheritedValue(fontShorthand()))
484 return emptyString();
485
486 int fontSizePropertyIndex = m_propertySet.findPropertyIndex(CSSPropertyFontS ize); 562 int fontSizePropertyIndex = m_propertySet.findPropertyIndex(CSSPropertyFontS ize);
487 int fontFamilyPropertyIndex = m_propertySet.findPropertyIndex(CSSPropertyFon tFamily); 563 int fontFamilyPropertyIndex = m_propertySet.findPropertyIndex(CSSPropertyFon tFamily);
488 int fontVariantCapsPropertyIndex = m_propertySet.findPropertyIndex(CSSProper tyFontVariantCaps); 564 int fontVariantCapsPropertyIndex = m_propertySet.findPropertyIndex(CSSProper tyFontVariantCaps);
489 int fontVariantLigaturesPropertyIndex = m_propertySet.findPropertyIndex(CSSP ropertyFontVariantLigatures); 565 int fontVariantLigaturesPropertyIndex = m_propertySet.findPropertyIndex(CSSP ropertyFontVariantLigatures);
490 int fontVariantNumericPropertyIndex = m_propertySet.findPropertyIndex(CSSPro pertyFontVariantNumeric); 566 int fontVariantNumericPropertyIndex = m_propertySet.findPropertyIndex(CSSPro pertyFontVariantNumeric);
491 DCHECK_NE(fontSizePropertyIndex, -1); 567 DCHECK_NE(fontSizePropertyIndex, -1);
492 DCHECK_NE(fontFamilyPropertyIndex, -1); 568 DCHECK_NE(fontFamilyPropertyIndex, -1);
493 DCHECK_NE(fontVariantCapsPropertyIndex, -1); 569 DCHECK_NE(fontVariantCapsPropertyIndex, -1);
494 DCHECK_NE(fontVariantLigaturesPropertyIndex, -1); 570 DCHECK_NE(fontVariantLigaturesPropertyIndex, -1);
495 DCHECK_NE(fontVariantNumericPropertyIndex, -1); 571 DCHECK_NE(fontVariantNumericPropertyIndex, -1);
496 572
497 PropertyValueForSerializer fontSizeProperty = m_propertySet.propertyAt(fontS izePropertyIndex); 573 PropertyValueForSerializer fontSizeProperty = m_propertySet.propertyAt(fontS izePropertyIndex);
498 PropertyValueForSerializer fontFamilyProperty = m_propertySet.propertyAt(fon tFamilyPropertyIndex); 574 PropertyValueForSerializer fontFamilyProperty = m_propertySet.propertyAt(fon tFamilyPropertyIndex);
499 PropertyValueForSerializer fontVariantCapsProperty = m_propertySet.propertyA t(fontVariantCapsPropertyIndex); 575 PropertyValueForSerializer fontVariantCapsProperty = m_propertySet.propertyA t(fontVariantCapsPropertyIndex);
500 PropertyValueForSerializer fontVariantLigaturesProperty = m_propertySet.prop ertyAt(fontVariantLigaturesPropertyIndex); 576 PropertyValueForSerializer fontVariantLigaturesProperty = m_propertySet.prop ertyAt(fontVariantLigaturesPropertyIndex);
501 PropertyValueForSerializer fontVariantNumericProperty = m_propertySet.proper tyAt(fontVariantNumericPropertyIndex); 577 PropertyValueForSerializer fontVariantNumericProperty = m_propertySet.proper tyAt(fontVariantNumericPropertyIndex);
502 578
503 // Check that non-initial font-variant subproperties are not conflicting wit h this serialization. 579 // Check that non-initial font-variant subproperties are not conflicting wit h this serialization.
504 const CSSValue* ligaturesValue = fontVariantLigaturesProperty.value(); 580 const CSSValue* ligaturesValue = fontVariantLigaturesProperty.value();
505 const CSSValue* numericValue = fontVariantNumericProperty.value(); 581 const CSSValue* numericValue = fontVariantNumericProperty.value();
506 if ((ligaturesValue->isPrimitiveValue() 582 if ((ligaturesValue->isPrimitiveValue()
507 && toCSSPrimitiveValue(ligaturesValue)->getValueID() != CSSValueNormal) 583 && toCSSPrimitiveValue(ligaturesValue)->getValueID() != CSSValueNormal)
508 || ligaturesValue->isValueList() 584 || ligaturesValue->isValueList()
509 || (numericValue->isPrimitiveValue() 585 || (numericValue->isPrimitiveValue()
510 && toCSSPrimitiveValue(numericValue)->getValueID() != CSSValueNormal) 586 && toCSSPrimitiveValue(numericValue)->getValueID() != CSSValueNormal)
511 || numericValue->isValueList()) 587 || numericValue->isValueList())
512 return emptyString(); 588 return emptyString();
513 589
514 String commonValue = fontSizeProperty.value()->cssText();
515 StringBuilder result; 590 StringBuilder result;
516 appendFontLonghandValueIfNotNormal(CSSPropertyFontStyle, result, commonValue ); 591 appendFontLonghandValueIfNotNormal(CSSPropertyFontStyle, result);
517 592
518 const CSSValue* val = fontVariantCapsProperty.value(); 593 const CSSValue* val = fontVariantCapsProperty.value();
519 if (val->isPrimitiveValue() 594 if (val->isPrimitiveValue()
520 && (toCSSPrimitiveValue(val)->getValueID() != CSSValueSmallCaps 595 && (toCSSPrimitiveValue(val)->getValueID() != CSSValueSmallCaps
521 && toCSSPrimitiveValue(val)->getValueID() != CSSValueNormal)) 596 && toCSSPrimitiveValue(val)->getValueID() != CSSValueNormal))
522 return emptyString(); 597 return emptyString();
523 appendFontLonghandValueIfNotNormal(CSSPropertyFontVariantCaps, result, commo nValue); 598 appendFontLonghandValueIfNotNormal(CSSPropertyFontVariantCaps, result);
524 599
525 appendFontLonghandValueIfNotNormal(CSSPropertyFontWeight, result, commonValu e); 600 appendFontLonghandValueIfNotNormal(CSSPropertyFontWeight, result);
526 appendFontLonghandValueIfNotNormal(CSSPropertyFontStretch, result, commonVal ue); 601 appendFontLonghandValueIfNotNormal(CSSPropertyFontStretch, result);
527 if (!result.isEmpty()) 602 if (!result.isEmpty())
528 result.append(' '); 603 result.append(' ');
529 result.append(fontSizeProperty.value()->cssText()); 604 result.append(fontSizeProperty.value()->cssText());
530 appendFontLonghandValueIfNotNormal(CSSPropertyLineHeight, result, commonValu e); 605 appendFontLonghandValueIfNotNormal(CSSPropertyLineHeight, result);
531 if (!result.isEmpty()) 606 if (!result.isEmpty())
532 result.append(' '); 607 result.append(' ');
533 result.append(fontFamilyProperty.value()->cssText()); 608 result.append(fontFamilyProperty.value()->cssText());
534 if (isInitialOrInherit(commonValue))
535 return commonValue;
536 return result.toString(); 609 return result.toString();
537 } 610 }
538 611
539 String StylePropertySerializer::fontVariantValue() const 612 String StylePropertySerializer::fontVariantValue() const
540 { 613 {
541 if (!isPropertyShorthandAvailable(fontVariantShorthand())) {
542 if (!shorthandHasOnlyInitialOrInheritedValue(fontVariantShorthand()))
543 return String();
544 return m_propertySet.getPropertyValue(CSSPropertyFontVariantLigatures);
545 }
546
547 StringBuilder result; 614 StringBuilder result;
548 615
549 // TODO(drott): Decide how we want to return ligature values in shorthands, reduced to "none" or 616 // TODO(drott): Decide how we want to return ligature values in shorthands, reduced to "none" or
550 // spelled out, filed as W3C bug: 617 // spelled out, filed as W3C bug:
551 // https://www.w3.org/Bugs/Public/show_bug.cgi?id=29594 618 // https://www.w3.org/Bugs/Public/show_bug.cgi?id=29594
552 String dummyCommonValue; 619 appendFontLonghandValueIfNotNormal(CSSPropertyFontVariantLigatures, result);
553 appendFontLonghandValueIfNotNormal(CSSPropertyFontVariantLigatures, result, dummyCommonValue); 620 appendFontLonghandValueIfNotNormal(CSSPropertyFontVariantCaps, result);
554 appendFontLonghandValueIfNotNormal(CSSPropertyFontVariantCaps, result, dummy CommonValue); 621 appendFontLonghandValueIfNotNormal(CSSPropertyFontVariantNumeric, result);
555 appendFontLonghandValueIfNotNormal(CSSPropertyFontVariantNumeric, result, du mmyCommonValue);
556 622
557 if (result.isEmpty()) { 623 if (result.isEmpty()) {
558 return "normal"; 624 return "normal";
559 } 625 }
560 626
561 return result.toString(); 627 return result.toString();
562 } 628 }
563 629
564 String StylePropertySerializer::get4Values(const StylePropertyShorthand& shortha nd) const 630 String StylePropertySerializer::get4Values(const StylePropertyShorthand& shortha nd) const
565 { 631 {
566 // Assume the properties are in the usual order top, right, bottom, left. 632 // Assume the properties are in the usual order top, right, bottom, left.
567 int topValueIndex = m_propertySet.findPropertyIndex(shorthand.properties()[0 ]); 633 int topValueIndex = m_propertySet.findPropertyIndex(shorthand.properties()[0 ]);
568 int rightValueIndex = m_propertySet.findPropertyIndex(shorthand.properties() [1]); 634 int rightValueIndex = m_propertySet.findPropertyIndex(shorthand.properties() [1]);
569 int bottomValueIndex = m_propertySet.findPropertyIndex(shorthand.properties( )[2]); 635 int bottomValueIndex = m_propertySet.findPropertyIndex(shorthand.properties( )[2]);
570 int leftValueIndex = m_propertySet.findPropertyIndex(shorthand.properties()[ 3]); 636 int leftValueIndex = m_propertySet.findPropertyIndex(shorthand.properties()[ 3]);
571 637
572 if (topValueIndex == -1 || rightValueIndex == -1 || bottomValueIndex == -1 | | leftValueIndex == -1) 638 if (topValueIndex == -1 || rightValueIndex == -1 || bottomValueIndex == -1 | | leftValueIndex == -1)
573 return String(); 639 return String();
574 640
575 PropertyValueForSerializer top = m_propertySet.propertyAt(topValueIndex); 641 PropertyValueForSerializer top = m_propertySet.propertyAt(topValueIndex);
576 PropertyValueForSerializer right = m_propertySet.propertyAt(rightValueIndex) ; 642 PropertyValueForSerializer right = m_propertySet.propertyAt(rightValueIndex) ;
577 PropertyValueForSerializer bottom = m_propertySet.propertyAt(bottomValueInde x); 643 PropertyValueForSerializer bottom = m_propertySet.propertyAt(bottomValueInde x);
578 PropertyValueForSerializer left = m_propertySet.propertyAt(leftValueIndex); 644 PropertyValueForSerializer left = m_propertySet.propertyAt(leftValueIndex);
579 645
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()); 646 bool showLeft = !right.value()->equals(*left.value());
597 bool showBottom = !top.value()->equals(*bottom.value()) || showLeft; 647 bool showBottom = !top.value()->equals(*bottom.value()) || showLeft;
598 bool showRight = !top.value()->equals(*right.value()) || showBottom; 648 bool showRight = !top.value()->equals(*right.value()) || showBottom;
599 649
600 StringBuilder result; 650 StringBuilder result;
601 result.append(top.value()->cssText()); 651 result.append(top.value()->cssText());
602 if (showRight) { 652 if (showRight) {
603 result.append(' '); 653 result.append(' ');
604 result.append(right.value()->cssText()); 654 result.append(right.value()->cssText());
605 } 655 }
(...skipping 12 matching lines...) Expand all
618 { 668 {
619 const unsigned size = shorthand.length(); 669 const unsigned size = shorthand.length();
620 670
621 // Begin by collecting the properties into a vector. 671 // Begin by collecting the properties into a vector.
622 HeapVector<Member<const CSSValue>> values(size); 672 HeapVector<Member<const CSSValue>> values(size);
623 // If the below loop succeeds, there should always be at minimum 1 layer. 673 // If the below loop succeeds, there should always be at minimum 1 layer.
624 size_t numLayers = 1U; 674 size_t numLayers = 1U;
625 675
626 for (size_t i = 0; i < size; i++) { 676 for (size_t i = 0; i < size; i++) {
627 values[i] = m_propertySet.getPropertyCSSValue(shorthand.properties()[i]) ; 677 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()) { 678 if (values[i]->isBaseValueList()) {
632 const CSSValueList* valueList = toCSSValueList(values[i]); 679 const CSSValueList* valueList = toCSSValueList(values[i]);
633 numLayers = std::max(numLayers, valueList->length()); 680 numLayers = std::max(numLayers, valueList->length());
634 } 681 }
635 } 682 }
636 683
637 StringBuilder result; 684 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 685
643 // Now stitch the properties together. Implicit initial values are flagged a s such and 686 // Now stitch the properties together. Implicit initial values are flagged a s such and
644 // can safely be omitted. 687 // can safely be omitted.
645 for (size_t layer = 0; layer < numLayers; layer++) { 688 for (size_t layer = 0; layer < numLayers; layer++) {
646 StringBuilder layerResult; 689 StringBuilder layerResult;
647 bool useRepeatXShorthand = false; 690 bool useRepeatXShorthand = false;
648 bool useRepeatYShorthand = false; 691 bool useRepeatYShorthand = false;
649 bool useSingleWordShorthand = false; 692 bool useSingleWordShorthand = false;
650 bool foundPositionXCSSProperty = false; 693 bool foundPositionXCSSProperty = false;
651 bool foundPositionYCSSProperty = false; 694 bool foundPositionYCSSProperty = false;
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
717 if (useSingleWordShorthand) 760 if (useSingleWordShorthand)
718 useSingleWordShorthand = false; 761 useSingleWordShorthand = false;
719 layerResult.append(value->cssText()); 762 layerResult.append(value->cssText());
720 } 763 }
721 if (property == CSSPropertyBackgroundPositionX || property == CS SPropertyWebkitMaskPositionX) 764 if (property == CSSPropertyBackgroundPositionX || property == CS SPropertyWebkitMaskPositionX)
722 foundPositionXCSSProperty = true; 765 foundPositionXCSSProperty = true;
723 if (property == CSSPropertyBackgroundPositionY || property == CS SPropertyWebkitMaskPositionY) { 766 if (property == CSSPropertyBackgroundPositionY || property == CS SPropertyWebkitMaskPositionY) {
724 foundPositionYCSSProperty = true; 767 foundPositionYCSSProperty = true;
725 // background-position is a special case. If only the first offset is specified, 768 // background-position is a special case. If only the first offset is specified,
726 // the second one defaults to "center", not the same value. 769 // the second one defaults to "center", not the same value.
727 if (hasCommonValue && !value->isInitialValue() && !value->is InheritedValue())
728 hasCommonValue = false;
729 } 770 }
730 } 771 }
731
732 if (hasCommonValue && !commonValue)
733 commonValue = value;
734 else if (!value->equals(*commonValue))
735 hasCommonValue = false;
736 } 772 }
737 if (!layerResult.isEmpty()) { 773 if (!layerResult.isEmpty()) {
738 if (!result.isEmpty()) 774 if (!result.isEmpty())
739 result.appendLiteral(", "); 775 result.appendLiteral(", ");
740 result.append(layerResult); 776 result.append(layerResult);
741 } 777 }
742 } 778 }
743 779
744 if (hasCommonValue && (commonValue->isInitialValue() || commonValue->isInher itedValue()))
745 return commonValue->cssText();
746
747 return result.toString(); 780 return result.toString();
748 } 781 }
749 782
750 String StylePropertySerializer::getShorthandValue(const StylePropertyShorthand& shorthand, String separator) const 783 String StylePropertySerializer::getShorthandValue(const StylePropertyShorthand& shorthand, String separator) const
751 { 784 {
752 String commonValue;
753 StringBuilder result; 785 StringBuilder result;
754 for (unsigned i = 0; i < shorthand.length(); ++i) { 786 for (unsigned i = 0; i < shorthand.length(); ++i) {
755 const CSSValue* value = m_propertySet.getPropertyCSSValue(shorthand.prop erties()[i]); 787 const CSSValue* value = m_propertySet.getPropertyCSSValue(shorthand.prop erties()[i]);
756 if (!value)
757 return String();
758 String valueText = value->cssText(); 788 String valueText = value->cssText();
759 if (!i)
760 commonValue = valueText;
761 else if (!commonValue.isNull() && commonValue != valueText)
762 commonValue = String();
763 if (value->isInitialValue()) 789 if (value->isInitialValue())
764 continue; 790 continue;
765 if (!result.isEmpty()) 791 if (!result.isEmpty())
766 result.append(separator); 792 result.append(separator);
767 result.append(valueText); 793 result.append(valueText);
768 } 794 }
769 if (isInitialOrInherit(commonValue))
770 return commonValue;
771 return result.toString(); 795 return result.toString();
772 } 796 }
773 797
774 // only returns a non-null value if all properties have the same, non-null value 798 // only returns a non-null value if all properties have the same, non-null value
775 String StylePropertySerializer::getCommonValue(const StylePropertyShorthand& sho rthand) const 799 String StylePropertySerializer::getCommonValue(const StylePropertyShorthand& sho rthand) const
776 { 800 {
777 String res; 801 String res;
778 bool lastPropertyWasImportant = false;
779 for (unsigned i = 0; i < shorthand.length(); ++i) { 802 for (unsigned i = 0; i < shorthand.length(); ++i) {
780 const CSSValue* value = m_propertySet.getPropertyCSSValue(shorthand.prop erties()[i]); 803 const CSSValue* value = m_propertySet.getPropertyCSSValue(shorthand.prop erties()[i]);
781 // FIXME: CSSInitialValue::cssText should generate the right value. 804 // FIXME: CSSInitialValue::cssText should generate the right value.
782 if (!value)
783 return String();
784 String text = value->cssText(); 805 String text = value->cssText();
785 if (text.isNull())
786 return String();
787 if (res.isNull()) 806 if (res.isNull())
788 res = text; 807 res = text;
789 else if (res != text) 808 else if (res != text)
790 return String(); 809 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 } 810 }
797 return res; 811 return res;
798 } 812 }
799 813
800 String StylePropertySerializer::borderPropertyValue() const 814 String StylePropertySerializer::borderPropertyValue() const
801 { 815 {
802 const StylePropertyShorthand properties[3] = { borderWidthShorthand(), borde rStyleShorthand(), borderColorShorthand() }; 816 const StylePropertyShorthand properties[3] = { borderWidthShorthand(), borde rStyleShorthand(), borderColorShorthand() };
803 String commonValue;
804 StringBuilder result; 817 StringBuilder result;
805 for (size_t i = 0; i < WTF_ARRAY_LENGTH(properties); ++i) { 818 for (size_t i = 0; i < WTF_ARRAY_LENGTH(properties); ++i) {
806 String value = getCommonValue(properties[i]); 819 String value = getCommonValue(properties[i]);
807 if (value.isNull()) 820 if (value.isNull())
808 return String(); 821 return String();
809 if (!i)
810 commonValue = value;
811 else if (!commonValue.isNull() && commonValue != value)
812 commonValue = String();
813 if (value == "initial") 822 if (value == "initial")
814 continue; 823 continue;
815 if (!result.isEmpty()) 824 if (!result.isEmpty())
816 result.append(' '); 825 result.append(' ');
817 result.append(value); 826 result.append(value);
818 } 827 }
819 if (isInitialOrInherit(commonValue))
820 return commonValue;
821 return result.isEmpty() ? String() : result.toString(); 828 return result.isEmpty() ? String() : result.toString();
822 } 829 }
823 830
824 static void appendBackgroundRepeatValue(StringBuilder& builder, const CSSValue& repeatXCSSValue, const CSSValue& repeatYCSSValue) 831 static void appendBackgroundRepeatValue(StringBuilder& builder, const CSSValue& repeatXCSSValue, const CSSValue& repeatYCSSValue)
825 { 832 {
826 // FIXME: Ensure initial values do not appear in CSS_VALUE_LISTS. 833 // FIXME: Ensure initial values do not appear in CSS_VALUE_LISTS.
827 DEFINE_STATIC_LOCAL(CSSPrimitiveValue, initialRepeatValue, (CSSPrimitiveValu e::createIdentifier(CSSValueRepeat))); 834 DEFINE_STATIC_LOCAL(CSSPrimitiveValue, initialRepeatValue, (CSSPrimitiveValu e::createIdentifier(CSSValueRepeat)));
828 const CSSPrimitiveValue& repeatX = repeatXCSSValue.isInitialValue() ? initia lRepeatValue : toCSSPrimitiveValue(repeatXCSSValue); 835 const CSSPrimitiveValue& repeatX = repeatXCSSValue.isInitialValue() ? initia lRepeatValue : toCSSPrimitiveValue(repeatXCSSValue);
829 const CSSPrimitiveValue& repeatY = repeatYCSSValue.isInitialValue() ? initia lRepeatValue : toCSSPrimitiveValue(repeatYCSSValue); 836 const CSSPrimitiveValue& repeatY = repeatYCSSValue.isInitialValue() ? initia lRepeatValue : toCSSPrimitiveValue(repeatYCSSValue);
830 CSSValueID repeatXValueId = repeatX.getValueID(); 837 CSSValueID repeatXValueId = repeatX.getValueID();
831 CSSValueID repeatYValueId = repeatY.getValueID(); 838 CSSValueID repeatYValueId = repeatY.getValueID();
832 if (repeatXValueId == repeatYValueId) { 839 if (repeatXValueId == repeatYValueId) {
833 builder.append(repeatX.cssText()); 840 builder.append(repeatX.cssText());
834 } else if (repeatXValueId == CSSValueNoRepeat && repeatYValueId == CSSValueR epeat) { 841 } else if (repeatXValueId == CSSValueNoRepeat && repeatYValueId == CSSValueR epeat) {
835 builder.appendLiteral("repeat-y"); 842 builder.appendLiteral("repeat-y");
836 } else if (repeatXValueId == CSSValueRepeat && repeatYValueId == CSSValueNoR epeat) { 843 } else if (repeatXValueId == CSSValueRepeat && repeatYValueId == CSSValueNoR epeat) {
837 builder.appendLiteral("repeat-x"); 844 builder.appendLiteral("repeat-x");
838 } else { 845 } else {
839 builder.append(repeatX.cssText()); 846 builder.append(repeatX.cssText());
840 builder.appendLiteral(" "); 847 builder.appendLiteral(" ");
841 builder.append(repeatY.cssText()); 848 builder.append(repeatY.cssText());
842 } 849 }
843 } 850 }
844 851
845 String StylePropertySerializer::backgroundRepeatPropertyValue() const 852 String StylePropertySerializer::backgroundRepeatPropertyValue() const
846 { 853 {
847 const CSSValue* repeatX = m_propertySet.getPropertyCSSValue(CSSPropertyBackg roundRepeatX); 854 const CSSValue* repeatX = m_propertySet.getPropertyCSSValue(CSSPropertyBackg roundRepeatX);
848 const CSSValue* repeatY = m_propertySet.getPropertyCSSValue(CSSPropertyBackg roundRepeatY); 855 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 856
856 const CSSValueList* repeatXList = 0; 857 const CSSValueList* repeatXList = 0;
857 int repeatXLength = 1; 858 int repeatXLength = 1;
858 if (repeatX->isValueList()) { 859 if (repeatX->isValueList()) {
859 repeatXList = toCSSValueList(repeatX); 860 repeatXList = toCSSValueList(repeatX);
860 repeatXLength = repeatXList->length(); 861 repeatXLength = repeatXList->length();
861 } else if (!repeatX->isPrimitiveValue()) { 862 } else if (!repeatX->isPrimitiveValue()) {
862 return String(); 863 return String();
863 } 864 }
864 865
(...skipping 12 matching lines...) Expand all
877 if (i) 878 if (i)
878 builder.appendLiteral(", "); 879 builder.appendLiteral(", ");
879 880
880 const CSSValue* xValue = repeatXList ? repeatXList->item(i % repeatXList ->length()) : repeatX; 881 const CSSValue* xValue = repeatXList ? repeatXList->item(i % repeatXList ->length()) : repeatX;
881 const CSSValue* yValue = repeatYList ? repeatYList->item(i % repeatYList ->length()) : repeatY; 882 const CSSValue* yValue = repeatYList ? repeatYList->item(i % repeatYList ->length()) : repeatY;
882 appendBackgroundRepeatValue(builder, *xValue, *yValue); 883 appendBackgroundRepeatValue(builder, *xValue, *yValue);
883 } 884 }
884 return builder.toString(); 885 return builder.toString();
885 } 886 }
886 887
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 888 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/css/StylePropertySerializer.h ('k') | third_party/WebKit/Source/web/tests/WebViewTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698