| 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 |