OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2004 Zack Rusin <zack@kde.org> | 2 * Copyright (C) 2004 Zack Rusin <zack@kde.org> |
3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc.
All rights reserved. | 3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc.
All rights reserved. |
4 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> | 4 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> |
5 * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com> | 5 * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com> |
6 * Copyright (C) 2011 Sencha, Inc. All rights reserved. | 6 * Copyright (C) 2011 Sencha, Inc. All rights reserved. |
7 * | 7 * |
8 * This library is free software; you can redistribute it and/or | 8 * This library is free software; you can redistribute it and/or |
9 * modify it under the terms of the GNU Lesser General Public | 9 * modify it under the terms of the GNU Lesser General Public |
10 * License as published by the Free Software Foundation; either | 10 * License as published by the Free Software Foundation; either |
(...skipping 13 matching lines...) Expand all Loading... |
24 #include "config.h" | 24 #include "config.h" |
25 #include "core/css/CSSComputedStyleDeclaration.h" | 25 #include "core/css/CSSComputedStyleDeclaration.h" |
26 | 26 |
27 #include "bindings/core/v8/ExceptionState.h" | 27 #include "bindings/core/v8/ExceptionState.h" |
28 #include "core/CSSPropertyNames.h" | 28 #include "core/CSSPropertyNames.h" |
29 #include "core/animation/DocumentAnimations.h" | 29 #include "core/animation/DocumentAnimations.h" |
30 #include "core/css/CSSPrimitiveValueMappings.h" | 30 #include "core/css/CSSPrimitiveValueMappings.h" |
31 #include "core/css/CSSPropertyMetadata.h" | 31 #include "core/css/CSSPropertyMetadata.h" |
32 #include "core/css/CSSSelector.h" | 32 #include "core/css/CSSSelector.h" |
33 #include "core/css/CSSValuePool.h" | 33 #include "core/css/CSSValuePool.h" |
34 #include "core/css/LayoutStyleCSSValueMapping.h" | 34 #include "core/css/ComputedStyleCSSValueMapping.h" |
35 #include "core/css/parser/CSSParser.h" | 35 #include "core/css/parser/CSSParser.h" |
36 #include "core/css/resolver/StyleResolver.h" | 36 #include "core/css/resolver/StyleResolver.h" |
37 #include "core/dom/Document.h" | 37 #include "core/dom/Document.h" |
38 #include "core/dom/ExceptionCode.h" | 38 #include "core/dom/ExceptionCode.h" |
39 #include "core/dom/PseudoElement.h" | 39 #include "core/dom/PseudoElement.h" |
40 #include "core/layout/LayoutObject.h" | 40 #include "core/layout/LayoutObject.h" |
41 #include "core/layout/style/LayoutStyle.h" | 41 #include "core/layout/style/ComputedStyle.h" |
42 #include "wtf/text/StringBuilder.h" | 42 #include "wtf/text/StringBuilder.h" |
43 | 43 |
44 namespace blink { | 44 namespace blink { |
45 | 45 |
46 // List of all properties we know how to compute, omitting shorthands. | 46 // List of all properties we know how to compute, omitting shorthands. |
47 // NOTE: Do not use this list, use computableProperties() instead | 47 // NOTE: Do not use this list, use computableProperties() instead |
48 // to respect runtime enabling of CSS properties. | 48 // to respect runtime enabling of CSS properties. |
49 static const CSSPropertyID staticComputableProperties[] = { | 49 static const CSSPropertyID staticComputableProperties[] = { |
50 CSSPropertyAnimationDelay, | 50 CSSPropertyAnimationDelay, |
51 CSSPropertyAnimationDirection, | 51 CSSPropertyAnimationDirection, |
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
412 exceptionState.throwDOMException(NoModificationAllowedError, "These styles a
re computed, and therefore read-only."); | 412 exceptionState.throwDOMException(NoModificationAllowedError, "These styles a
re computed, and therefore read-only."); |
413 } | 413 } |
414 | 414 |
415 static CSSValueID cssIdentifierForFontSizeKeyword(int keywordSize) | 415 static CSSValueID cssIdentifierForFontSizeKeyword(int keywordSize) |
416 { | 416 { |
417 ASSERT_ARG(keywordSize, keywordSize); | 417 ASSERT_ARG(keywordSize, keywordSize); |
418 ASSERT_ARG(keywordSize, keywordSize <= 8); | 418 ASSERT_ARG(keywordSize, keywordSize <= 8); |
419 return static_cast<CSSValueID>(CSSValueXxSmall + keywordSize - 1); | 419 return static_cast<CSSValueID>(CSSValueXxSmall + keywordSize - 1); |
420 } | 420 } |
421 | 421 |
422 inline static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> zoomAdjustedPixelValue(d
ouble value, const LayoutStyle& style) | 422 inline static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> zoomAdjustedPixelValue(d
ouble value, const ComputedStyle& style) |
423 { | 423 { |
424 return cssValuePool().createValue(adjustFloatForAbsoluteZoom(value, style),
CSSPrimitiveValue::CSS_PX); | 424 return cssValuePool().createValue(adjustFloatForAbsoluteZoom(value, style),
CSSPrimitiveValue::CSS_PX); |
425 } | 425 } |
426 | 426 |
427 PassRefPtrWillBeRawPtr<CSSValue> CSSComputedStyleDeclaration::getFontSizeCSSValu
ePreferringKeyword() const | 427 PassRefPtrWillBeRawPtr<CSSValue> CSSComputedStyleDeclaration::getFontSizeCSSValu
ePreferringKeyword() const |
428 { | 428 { |
429 if (!m_node) | 429 if (!m_node) |
430 return nullptr; | 430 return nullptr; |
431 | 431 |
432 m_node->document().updateLayoutIgnorePendingStylesheets(); | 432 m_node->document().updateLayoutIgnorePendingStylesheets(); |
433 | 433 |
434 const LayoutStyle* style = m_node->computedStyle(m_pseudoElementSpecifier); | 434 const ComputedStyle* style = m_node->ensureComputedStyle(m_pseudoElementSpec
ifier); |
435 if (!style) | 435 if (!style) |
436 return nullptr; | 436 return nullptr; |
437 | 437 |
438 if (int keywordSize = style->fontDescription().keywordSize()) | 438 if (int keywordSize = style->fontDescription().keywordSize()) |
439 return cssValuePool().createIdentifierValue(cssIdentifierForFontSizeKeyw
ord(keywordSize)); | 439 return cssValuePool().createIdentifierValue(cssIdentifierForFontSizeKeyw
ord(keywordSize)); |
440 | 440 |
441 | 441 |
442 return zoomAdjustedPixelValue(style->fontDescription().computedPixelSize(),
*style); | 442 return zoomAdjustedPixelValue(style->fontDescription().computedPixelSize(),
*style); |
443 } | 443 } |
444 | 444 |
445 FixedPitchFontType CSSComputedStyleDeclaration::fixedPitchFontType() const | 445 FixedPitchFontType CSSComputedStyleDeclaration::fixedPitchFontType() const |
446 { | 446 { |
447 if (!m_node) | 447 if (!m_node) |
448 return VariablePitchFont; | 448 return VariablePitchFont; |
449 | 449 |
450 const LayoutStyle* style = m_node->computedStyle(m_pseudoElementSpecifier); | 450 const ComputedStyle* style = m_node->ensureComputedStyle(m_pseudoElementSpec
ifier); |
451 if (!style) | 451 if (!style) |
452 return VariablePitchFont; | 452 return VariablePitchFont; |
453 | 453 |
454 return style->fontDescription().fixedPitchFontType(); | 454 return style->fontDescription().fixedPitchFontType(); |
455 } | 455 } |
456 | 456 |
457 static void logUnimplementedPropertyID(CSSPropertyID propertyID) | 457 static void logUnimplementedPropertyID(CSSPropertyID propertyID) |
458 { | 458 { |
459 DEFINE_STATIC_LOCAL(HashSet<CSSPropertyID>, propertyIDSet, ()); | 459 DEFINE_STATIC_LOCAL(HashSet<CSSPropertyID>, propertyIDSet, ()); |
460 if (!propertyIDSet.add(propertyID).isNewEntry) | 460 if (!propertyIDSet.add(propertyID).isNewEntry) |
461 return; | 461 return; |
462 | 462 |
463 WTF_LOG_ERROR("WebKit does not yet implement getComputedStyle for '%s'.", ge
tPropertyName(propertyID)); | 463 WTF_LOG_ERROR("WebKit does not yet implement getComputedStyle for '%s'.", ge
tPropertyName(propertyID)); |
464 } | 464 } |
465 | 465 |
466 static bool isLayoutDependent(CSSPropertyID propertyID, const LayoutStyle* style
, LayoutObject* renderer) | 466 static bool isLayoutDependent(CSSPropertyID propertyID, const ComputedStyle* sty
le, LayoutObject* renderer) |
467 { | 467 { |
468 // Some properties only depend on layout in certain conditions which | 468 // Some properties only depend on layout in certain conditions which |
469 // are specified in the main switch statement below. So we can avoid | 469 // are specified in the main switch statement below. So we can avoid |
470 // forcing layout in those conditions. The conditions in this switch | 470 // forcing layout in those conditions. The conditions in this switch |
471 // statement must remain in sync with the conditions in the main switch. | 471 // statement must remain in sync with the conditions in the main switch. |
472 // FIXME: Some of these cases could be narrowed down or optimized better. | 472 // FIXME: Some of these cases could be narrowed down or optimized better. |
473 switch (propertyID) { | 473 switch (propertyID) { |
474 case CSSPropertyBottom: | 474 case CSSPropertyBottom: |
475 case CSSPropertyGridTemplateColumns: | 475 case CSSPropertyGridTemplateColumns: |
476 case CSSPropertyGridTemplateRows: | 476 case CSSPropertyGridTemplateRows: |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
512 return renderer && renderer->isBox() && (!style || !style->paddingLeft()
.isFixed()); | 512 return renderer && renderer->isBox() && (!style || !style->paddingLeft()
.isFixed()); |
513 case CSSPropertyPaddingRight: | 513 case CSSPropertyPaddingRight: |
514 return renderer && renderer->isBox() && (!style || !style->paddingRight(
).isFixed()); | 514 return renderer && renderer->isBox() && (!style || !style->paddingRight(
).isFixed()); |
515 case CSSPropertyPaddingTop: | 515 case CSSPropertyPaddingTop: |
516 return renderer && renderer->isBox() && (!style || !style->paddingTop().
isFixed()); | 516 return renderer && renderer->isBox() && (!style || !style->paddingTop().
isFixed()); |
517 default: | 517 default: |
518 return false; | 518 return false; |
519 } | 519 } |
520 } | 520 } |
521 | 521 |
522 const LayoutStyle* CSSComputedStyleDeclaration::computeLayoutStyle() const | 522 const ComputedStyle* CSSComputedStyleDeclaration::computeComputedStyle() const |
523 { | 523 { |
524 Node* styledNode = this->styledNode(); | 524 Node* styledNode = this->styledNode(); |
525 ASSERT(styledNode); | 525 ASSERT(styledNode); |
526 return styledNode->computedStyle(styledNode->isPseudoElement() ? NOPSEUDO :
m_pseudoElementSpecifier); | 526 return styledNode->ensureComputedStyle(styledNode->isPseudoElement() ? NOPSE
UDO : m_pseudoElementSpecifier); |
527 } | 527 } |
528 | 528 |
529 Node* CSSComputedStyleDeclaration::styledNode() const | 529 Node* CSSComputedStyleDeclaration::styledNode() const |
530 { | 530 { |
531 if (!m_node) | 531 if (!m_node) |
532 return 0; | 532 return 0; |
533 if (m_node->isElementNode()) { | 533 if (m_node->isElementNode()) { |
534 if (PseudoElement* element = toElement(m_node)->pseudoElement(m_pseudoEl
ementSpecifier)) | 534 if (PseudoElement* element = toElement(m_node)->pseudoElement(m_pseudoEl
ementSpecifier)) |
535 return element; | 535 return element; |
536 } | 536 } |
537 return m_node.get(); | 537 return m_node.get(); |
538 } | 538 } |
539 | 539 |
540 PassRefPtrWillBeRawPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValu
e(CSSPropertyID propertyID) const | 540 PassRefPtrWillBeRawPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValu
e(CSSPropertyID propertyID) const |
541 { | 541 { |
542 Node* styledNode = this->styledNode(); | 542 Node* styledNode = this->styledNode(); |
543 if (!styledNode) | 543 if (!styledNode) |
544 return nullptr; | 544 return nullptr; |
545 LayoutObject* renderer = styledNode->layoutObject(); | 545 LayoutObject* renderer = styledNode->layoutObject(); |
546 const LayoutStyle* style; | 546 const ComputedStyle* style; |
547 | 547 |
548 Document& document = styledNode->document(); | 548 Document& document = styledNode->document(); |
549 | 549 |
550 // A timing update may be required if a compositor animation is running. | 550 // A timing update may be required if a compositor animation is running. |
551 DocumentAnimations::updateAnimationTimingForGetComputedStyle(*styledNode, pr
opertyID); | 551 DocumentAnimations::updateAnimationTimingForGetComputedStyle(*styledNode, pr
opertyID); |
552 | 552 |
553 document.updateRenderTreeForNodeIfNeeded(styledNode); | 553 document.updateRenderTreeForNodeIfNeeded(styledNode); |
554 | 554 |
555 // The style recalc could have caused the styled node to be discarded or rep
laced | 555 // The style recalc could have caused the styled node to be discarded or rep
laced |
556 // if it was a PseudoElement so we need to update it. | 556 // if it was a PseudoElement so we need to update it. |
557 styledNode = this->styledNode(); | 557 styledNode = this->styledNode(); |
558 renderer = styledNode->layoutObject(); | 558 renderer = styledNode->layoutObject(); |
559 | 559 |
560 style = computeLayoutStyle(); | 560 style = computeComputedStyle(); |
561 | 561 |
562 bool forceFullLayout = isLayoutDependent(propertyID, style, renderer) | 562 bool forceFullLayout = isLayoutDependent(propertyID, style, renderer) |
563 || styledNode->isInShadowTree() | 563 || styledNode->isInShadowTree() |
564 || (document.ownerElement() && document.ensureStyleResolver().hasViewpor
tDependentMediaQueries()); | 564 || (document.ownerElement() && document.ensureStyleResolver().hasViewpor
tDependentMediaQueries()); |
565 | 565 |
566 if (forceFullLayout) { | 566 if (forceFullLayout) { |
567 document.updateLayoutIgnorePendingStylesheets(); | 567 document.updateLayoutIgnorePendingStylesheets(); |
568 styledNode = this->styledNode(); | 568 styledNode = this->styledNode(); |
569 style = computeLayoutStyle(); | 569 style = computeComputedStyle(); |
570 renderer = styledNode->layoutObject(); | 570 renderer = styledNode->layoutObject(); |
571 } | 571 } |
572 | 572 |
573 if (!style) | 573 if (!style) |
574 return nullptr; | 574 return nullptr; |
575 | 575 |
576 RefPtrWillBeRawPtr<CSSValue> value = LayoutStyleCSSValueMapping::get(propert
yID, *style, renderer, styledNode, m_allowVisitedStyle); | 576 RefPtrWillBeRawPtr<CSSValue> value = ComputedStyleCSSValueMapping::get(prope
rtyID, *style, renderer, styledNode, m_allowVisitedStyle); |
577 if (value) | 577 if (value) |
578 return value; | 578 return value; |
579 | 579 |
580 logUnimplementedPropertyID(propertyID); | 580 logUnimplementedPropertyID(propertyID); |
581 return nullptr; | 581 return nullptr; |
582 } | 582 } |
583 | 583 |
584 String CSSComputedStyleDeclaration::getPropertyValue(CSSPropertyID propertyID) c
onst | 584 String CSSComputedStyleDeclaration::getPropertyValue(CSSPropertyID propertyID) c
onst |
585 { | 585 { |
586 RefPtrWillBeRawPtr<CSSValue> value = getPropertyCSSValue(propertyID); | 586 RefPtrWillBeRawPtr<CSSValue> value = getPropertyCSSValue(propertyID); |
(...skipping 15 matching lines...) Expand all Loading... |
602 if (i >= length()) | 602 if (i >= length()) |
603 return ""; | 603 return ""; |
604 | 604 |
605 return getPropertyNameString(computableProperties()[i]); | 605 return getPropertyNameString(computableProperties()[i]); |
606 } | 606 } |
607 | 607 |
608 bool CSSComputedStyleDeclaration::cssPropertyMatches(CSSPropertyID propertyID, c
onst CSSValue* propertyValue) const | 608 bool CSSComputedStyleDeclaration::cssPropertyMatches(CSSPropertyID propertyID, c
onst CSSValue* propertyValue) const |
609 { | 609 { |
610 if (propertyID == CSSPropertyFontSize && propertyValue->isPrimitiveValue() &
& m_node) { | 610 if (propertyID == CSSPropertyFontSize && propertyValue->isPrimitiveValue() &
& m_node) { |
611 m_node->document().updateLayoutIgnorePendingStylesheets(); | 611 m_node->document().updateLayoutIgnorePendingStylesheets(); |
612 const LayoutStyle* style = m_node->computedStyle(m_pseudoElementSpecifie
r); | 612 const ComputedStyle* style = m_node->ensureComputedStyle(m_pseudoElement
Specifier); |
613 if (style && style->fontDescription().keywordSize()) { | 613 if (style && style->fontDescription().keywordSize()) { |
614 CSSValueID sizeValue = cssIdentifierForFontSizeKeyword(style->fontDe
scription().keywordSize()); | 614 CSSValueID sizeValue = cssIdentifierForFontSizeKeyword(style->fontDe
scription().keywordSize()); |
615 const CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(proper
tyValue); | 615 const CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(proper
tyValue); |
616 if (primitiveValue->isValueID() && primitiveValue->getValueID() == s
izeValue) | 616 if (primitiveValue->isValueID() && primitiveValue->getValueID() == s
izeValue) |
617 return true; | 617 return true; |
618 } | 618 } |
619 } | 619 } |
620 RefPtrWillBeRawPtr<CSSValue> value = getPropertyCSSValue(propertyID); | 620 RefPtrWillBeRawPtr<CSSValue> value = getPropertyCSSValue(propertyID); |
621 return value && propertyValue && value->equals(*propertyValue); | 621 return value && propertyValue && value->equals(*propertyValue); |
622 } | 622 } |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
694 exceptionState.throwDOMException(NoModificationAllowedError, "These styles a
re computed, and therefore the '" + getPropertyNameString(id) + "' property is r
ead-only."); | 694 exceptionState.throwDOMException(NoModificationAllowedError, "These styles a
re computed, and therefore the '" + getPropertyNameString(id) + "' property is r
ead-only."); |
695 } | 695 } |
696 | 696 |
697 DEFINE_TRACE(CSSComputedStyleDeclaration) | 697 DEFINE_TRACE(CSSComputedStyleDeclaration) |
698 { | 698 { |
699 visitor->trace(m_node); | 699 visitor->trace(m_node); |
700 CSSStyleDeclaration::trace(visitor); | 700 CSSStyleDeclaration::trace(visitor); |
701 } | 701 } |
702 | 702 |
703 } // namespace blink | 703 } // namespace blink |
OLD | NEW |