| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
| 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
| 4 * (C) 2001 Peter Kelly (pmk@post.com) | 4 * (C) 2001 Peter Kelly (pmk@post.com) |
| 5 * (C) 2001 Dirk Mueller (mueller@kde.org) | 5 * (C) 2001 Dirk Mueller (mueller@kde.org) |
| 6 * (C) 2007 David Smith (catfish.man@gmail.com) | 6 * (C) 2007 David Smith (catfish.man@gmail.com) |
| 7 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012, 2013 Apple Inc.
All rights reserved. | 7 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012, 2013 Apple Inc.
All rights reserved. |
| 8 * (C) 2007 Eric Seidel (eric@webkit.org) | 8 * (C) 2007 Eric Seidel (eric@webkit.org) |
| 9 * | 9 * |
| 10 * This library is free software; you can redistribute it and/or | 10 * This library is free software; you can redistribute it and/or |
| (...skipping 633 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 644 | 644 |
| 645 void Element::attributeChanged(const QualifiedName& name, const AtomicString& ne
wValue, AttributeModificationReason reason) | 645 void Element::attributeChanged(const QualifiedName& name, const AtomicString& ne
wValue, AttributeModificationReason reason) |
| 646 { | 646 { |
| 647 if (ElementShadow* parentElementShadow = shadowWhereNodeCanBeDistributed(*th
is)) { | 647 if (ElementShadow* parentElementShadow = shadowWhereNodeCanBeDistributed(*th
is)) { |
| 648 if (shouldInvalidateDistributionWhenAttributeChanged(parentElementShadow
, name, newValue)) | 648 if (shouldInvalidateDistributionWhenAttributeChanged(parentElementShadow
, name, newValue)) |
| 649 parentElementShadow->setNeedsDistributionRecalc(); | 649 parentElementShadow->setNeedsDistributionRecalc(); |
| 650 } | 650 } |
| 651 | 651 |
| 652 parseAttribute(name, newValue); | 652 parseAttribute(name, newValue); |
| 653 | 653 |
| 654 StyleResolver* styleResolver = document().styleResolver(); | 654 bool testShouldInvalidateStyle = inActiveDocument() && styleChangeType() < S
ubtreeStyleChange; |
| 655 bool testShouldInvalidateStyle = inActiveDocument() && styleResolver && styl
eChangeType() < SubtreeStyleChange; | |
| 656 | 655 |
| 657 if (isStyledElement() && name == HTMLNames::styleAttr) { | 656 if (isStyledElement() && name == HTMLNames::styleAttr) { |
| 658 styleAttributeChanged(newValue); | 657 styleAttributeChanged(newValue); |
| 659 } | 658 } |
| 660 | 659 |
| 661 if (name == HTMLNames::idAttr) { | 660 if (name == HTMLNames::idAttr) { |
| 662 AtomicString oldId = elementData()->idForStyleResolution(); | 661 AtomicString oldId = elementData()->idForStyleResolution(); |
| 663 AtomicString newId = newValue; | 662 AtomicString newId = newValue; |
| 664 if (newId != oldId) { | 663 if (newId != oldId) { |
| 665 elementData()->setIdForStyleResolution(newId); | 664 elementData()->setIdForStyleResolution(newId); |
| 666 if (testShouldInvalidateStyle && (affectedByIdSelector(oldId) || aff
ectedByIdSelector(newId))) | 665 if (testShouldInvalidateStyle && (affectedByIdSelector(oldId) || aff
ectedByIdSelector(newId))) |
| 667 setNeedsStyleRecalc(LocalStyleChange); | 666 setNeedsStyleRecalc(LocalStyleChange); |
| 668 } | 667 } |
| 669 } else if (name == HTMLNames::classAttr) { | 668 } else if (name == HTMLNames::classAttr) { |
| 670 classAttributeChanged(newValue); | 669 classAttributeChanged(newValue); |
| 671 } | 670 } |
| 672 | |
| 673 // If there is currently no StyleResolver, we can't be sure that this attrib
ute change won't affect style. | |
| 674 if (!styleResolver) | |
| 675 setNeedsStyleRecalc(SubtreeStyleChange); | |
| 676 } | 671 } |
| 677 | 672 |
| 678 inline void Element::attributeChangedFromParserOrByCloning(const QualifiedName&
name, const AtomicString& newValue, AttributeModificationReason reason) | 673 inline void Element::attributeChangedFromParserOrByCloning(const QualifiedName&
name, const AtomicString& newValue, AttributeModificationReason reason) |
| 679 { | 674 { |
| 680 attributeChanged(name, newValue, reason); | 675 attributeChanged(name, newValue, reason); |
| 681 } | 676 } |
| 682 | 677 |
| 683 void Element::classAttributeChanged(const AtomicString& newClassString) | 678 void Element::classAttributeChanged(const AtomicString& newClassString) |
| 684 { | 679 { |
| 685 StyleResolver* styleResolver = document().styleResolver(); | 680 bool testShouldInvalidateStyle = inActiveDocument() && styleChangeType() < S
ubtreeStyleChange; |
| 686 bool testShouldInvalidateStyle = inActiveDocument() && styleResolver && styl
eChangeType() < SubtreeStyleChange; | |
| 687 | 681 |
| 688 ASSERT(elementData()); | 682 ASSERT(elementData()); |
| 689 const SpaceSplitString oldClasses = elementData()->classNames(); | 683 const SpaceSplitString oldClasses = elementData()->classNames(); |
| 690 elementData()->setClass(newClassString, false); | 684 elementData()->setClass(newClassString, false); |
| 691 const SpaceSplitString& newClasses = elementData()->classNames(); | 685 const SpaceSplitString& newClasses = elementData()->classNames(); |
| 692 if (testShouldInvalidateStyle && classChangeNeedsStyleRecalc(oldClasses, new
Classes)) | 686 if (testShouldInvalidateStyle && classChangeNeedsStyleRecalc(oldClasses, new
Classes)) |
| 693 setNeedsStyleRecalc(LocalStyleChange); | 687 setNeedsStyleRecalc(LocalStyleChange); |
| 694 if (!newClasses.size()) | 688 if (!newClasses.size()) |
| 695 elementData()->clearClass(); | 689 elementData()->clearClass(); |
| 696 } | 690 } |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 898 | 892 |
| 899 PassRefPtr<RenderStyle> Element::styleForRenderer() | 893 PassRefPtr<RenderStyle> Element::styleForRenderer() |
| 900 { | 894 { |
| 901 ASSERT(document().inStyleRecalc()); | 895 ASSERT(document().inStyleRecalc()); |
| 902 | 896 |
| 903 // FIXME: Instead of clearing updates that may have been added from calls to
styleForElement | 897 // FIXME: Instead of clearing updates that may have been added from calls to
styleForElement |
| 904 // outside recalcStyle, we should just never set them if we're not inside re
calcStyle. | 898 // outside recalcStyle, we should just never set them if we're not inside re
calcStyle. |
| 905 if (ActiveAnimations* activeAnimations = this->activeAnimations()) | 899 if (ActiveAnimations* activeAnimations = this->activeAnimations()) |
| 906 activeAnimations->cssAnimations().setPendingUpdate(nullptr); | 900 activeAnimations->cssAnimations().setPendingUpdate(nullptr); |
| 907 | 901 |
| 908 RefPtr<RenderStyle> style = document().ensureStyleResolver().styleForElement
(this); | 902 RefPtr<RenderStyle> style = document().styleResolver().styleForElement(this)
; |
| 909 ASSERT(style); | 903 ASSERT(style); |
| 910 | 904 |
| 911 // styleForElement() might add active animations so we need to get it again. | 905 // styleForElement() might add active animations so we need to get it again. |
| 912 if (ActiveAnimations* activeAnimations = this->activeAnimations()) { | 906 if (ActiveAnimations* activeAnimations = this->activeAnimations()) { |
| 913 activeAnimations->cssAnimations().maybeApplyPendingUpdate(this); | 907 activeAnimations->cssAnimations().maybeApplyPendingUpdate(this); |
| 914 } | 908 } |
| 915 | 909 |
| 916 if (style->hasTransform()) { | 910 if (style->hasTransform()) { |
| 917 if (const StylePropertySet* inlineStyle = this->inlineStyle()) | 911 if (const StylePropertySet* inlineStyle = this->inlineStyle()) |
| 918 style->setHasInlineTransform(inlineStyle->hasProperty(CSSPropertyTra
nsform) || inlineStyle->hasProperty(CSSPropertyWebkitTransform)); | 912 style->setHasInlineTransform(inlineStyle->hasProperty(CSSPropertyTra
nsform) || inlineStyle->hasProperty(CSSPropertyWebkitTransform)); |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1003 if (change > Inherit || childNeedsStyleRecalc()) { | 997 if (change > Inherit || childNeedsStyleRecalc()) { |
| 1004 if (ShadowRoot* root = shadowRoot()) { | 998 if (ShadowRoot* root = shadowRoot()) { |
| 1005 if (root->shouldCallRecalcStyle(change)) | 999 if (root->shouldCallRecalcStyle(change)) |
| 1006 root->recalcStyle(change); | 1000 root->recalcStyle(change); |
| 1007 } | 1001 } |
| 1008 | 1002 |
| 1009 // This loop is deliberately backwards because we use insertBefore in th
e rendering tree, and want to avoid | 1003 // This loop is deliberately backwards because we use insertBefore in th
e rendering tree, and want to avoid |
| 1010 // a potentially n^2 loop to find the insertion point while resolving st
yle. Having us start from the last | 1004 // a potentially n^2 loop to find the insertion point while resolving st
yle. Having us start from the last |
| 1011 // child and work our way back means in the common case, we'll find the
insertion point in O(1) time. | 1005 // child and work our way back means in the common case, we'll find the
insertion point in O(1) time. |
| 1012 // See crbug.com/288225 | 1006 // See crbug.com/288225 |
| 1013 StyleResolver& styleResolver = document().ensureStyleResolver(); | 1007 StyleResolver& styleResolver = document().styleResolver(); |
| 1014 Text* lastTextNode = 0; | 1008 Text* lastTextNode = 0; |
| 1015 for (Node* child = lastChild(); child; child = child->previousSibling())
{ | 1009 for (Node* child = lastChild(); child; child = child->previousSibling())
{ |
| 1016 if (child->isTextNode()) { | 1010 if (child->isTextNode()) { |
| 1017 toText(child)->recalcTextStyle(change, lastTextNode); | 1011 toText(child)->recalcTextStyle(change, lastTextNode); |
| 1018 lastTextNode = toText(child); | 1012 lastTextNode = toText(child); |
| 1019 } else if (child->isElementNode()) { | 1013 } else if (child->isElementNode()) { |
| 1020 Element* element = toElement(child); | 1014 Element* element = toElement(child); |
| 1021 if (element->shouldCallRecalcStyle(change)) | 1015 if (element->shouldCallRecalcStyle(change)) |
| 1022 element->recalcStyle(change, lastTextNode); | 1016 element->recalcStyle(change, lastTextNode); |
| 1023 else if (element->supportsStyleSharing()) | 1017 else if (element->supportsStyleSharing()) |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1364 return usedStyle; | 1358 return usedStyle; |
| 1365 | 1359 |
| 1366 if (!inActiveDocument()) | 1360 if (!inActiveDocument()) |
| 1367 // FIXME: Try to do better than this. Ensure that styleForElement() work
s for elements that are not in the | 1361 // FIXME: Try to do better than this. Ensure that styleForElement() work
s for elements that are not in the |
| 1368 // document tree and figure out when to destroy the computed style for s
uch elements. | 1362 // document tree and figure out when to destroy the computed style for s
uch elements. |
| 1369 return 0; | 1363 return 0; |
| 1370 | 1364 |
| 1371 ElementRareData& rareData = ensureElementRareData(); | 1365 ElementRareData& rareData = ensureElementRareData(); |
| 1372 if (!rareData.computedStyle()) { | 1366 if (!rareData.computedStyle()) { |
| 1373 RenderStyle* parentStyle = parentNode() ? parentNode()->computedStyle()
: 0; | 1367 RenderStyle* parentStyle = parentNode() ? parentNode()->computedStyle()
: 0; |
| 1374 rareData.setComputedStyle(document().ensureStyleResolver().styleForEleme
nt(this, parentStyle)); | 1368 rareData.setComputedStyle(document().styleResolver().styleForElement(thi
s, parentStyle)); |
| 1375 } | 1369 } |
| 1376 return rareData.computedStyle(); | 1370 return rareData.computedStyle(); |
| 1377 } | 1371 } |
| 1378 | 1372 |
| 1379 AtomicString Element::computeInheritedLanguage() const | 1373 AtomicString Element::computeInheritedLanguage() const |
| 1380 { | 1374 { |
| 1381 const Node* n = this; | 1375 const Node* n = this; |
| 1382 AtomicString value; | 1376 AtomicString value; |
| 1383 // The language property is inherited, so we iterate over the parents to fin
d the first language. | 1377 // The language property is inherited, so we iterate over the parents to fin
d the first language. |
| 1384 do { | 1378 do { |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1535 scope.addElementById(newId, this); | 1529 scope.addElementById(newId, this); |
| 1536 } | 1530 } |
| 1537 | 1531 |
| 1538 void Element::willModifyAttribute(const QualifiedName& name, const AtomicString&
oldValue, const AtomicString& newValue) | 1532 void Element::willModifyAttribute(const QualifiedName& name, const AtomicString&
oldValue, const AtomicString& newValue) |
| 1539 { | 1533 { |
| 1540 if (name == HTMLNames::idAttr) { | 1534 if (name == HTMLNames::idAttr) { |
| 1541 updateId(oldValue, newValue); | 1535 updateId(oldValue, newValue); |
| 1542 } | 1536 } |
| 1543 | 1537 |
| 1544 if (oldValue != newValue) { | 1538 if (oldValue != newValue) { |
| 1545 if (inActiveDocument() && document().styleResolver() && styleChangeType(
) < SubtreeStyleChange && affectedByAttributeSelector(name.localName())) | 1539 if (inActiveDocument() && styleChangeType() < SubtreeStyleChange && affe
ctedByAttributeSelector(name.localName())) |
| 1546 setNeedsStyleRecalc(LocalStyleChange); | 1540 setNeedsStyleRecalc(LocalStyleChange); |
| 1547 | 1541 |
| 1548 if (isUpgradedCustomElement()) | 1542 if (isUpgradedCustomElement()) |
| 1549 CustomElement::attributeDidChange(this, name.localName(), oldValue,
newValue); | 1543 CustomElement::attributeDidChange(this, name.localName(), oldValue,
newValue); |
| 1550 } | 1544 } |
| 1551 | 1545 |
| 1552 if (OwnPtr<MutationObserverInterestGroup> recipients = MutationObserverInter
estGroup::createForAttributesMutation(*this, name)) | 1546 if (OwnPtr<MutationObserverInterestGroup> recipients = MutationObserverInter
estGroup::createForAttributesMutation(*this, name)) |
| 1553 recipients->enqueueMutationRecord(MutationRecord::createAttributes(this,
name, oldValue)); | 1547 recipients->enqueueMutationRecord(MutationRecord::createAttributes(this,
name, oldValue)); |
| 1554 } | 1548 } |
| 1555 | 1549 |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1805 // FIXME: Why does gaining a layer from outside the style system require dis
abling sharing? | 1799 // FIXME: Why does gaining a layer from outside the style system require dis
abling sharing? |
| 1806 if (isHTMLCanvasElement(*this)) | 1800 if (isHTMLCanvasElement(*this)) |
| 1807 return false; | 1801 return false; |
| 1808 return true; | 1802 return true; |
| 1809 } | 1803 } |
| 1810 | 1804 |
| 1811 bool Element::affectedByAttributeSelector(const AtomicString& attributeName) con
st | 1805 bool Element::affectedByAttributeSelector(const AtomicString& attributeName) con
st |
| 1812 { | 1806 { |
| 1813 if (attributeName.isEmpty()) | 1807 if (attributeName.isEmpty()) |
| 1814 return false; | 1808 return false; |
| 1815 // TODO(esprehn): This makes sure the style system is updated, eventually | |
| 1816 // we'll remove all the global lists and this won't be needed. | |
| 1817 document().ensureStyleResolver(); | |
| 1818 if (treeScope().scopedStyleResolver().features().hasSelectorForAttribute(att
ributeName)) | 1809 if (treeScope().scopedStyleResolver().features().hasSelectorForAttribute(att
ributeName)) |
| 1819 return true; | 1810 return true; |
| 1820 // Host rules could also have effects. | 1811 // Host rules could also have effects. |
| 1821 if (ShadowRoot* shadowRoot = this->shadowRoot()) | 1812 if (ShadowRoot* shadowRoot = this->shadowRoot()) |
| 1822 return shadowRoot->scopedStyleResolver().features().hasSelectorForAttrib
ute(attributeName); | 1813 return shadowRoot->scopedStyleResolver().features().hasSelectorForAttrib
ute(attributeName); |
| 1823 return false; | 1814 return false; |
| 1824 } | 1815 } |
| 1825 | 1816 |
| 1826 bool Element::affectedByClassSelector(const AtomicString& classValue) const | 1817 bool Element::affectedByClassSelector(const AtomicString& classValue) const |
| 1827 { | 1818 { |
| 1828 if (classValue.isEmpty()) | 1819 if (classValue.isEmpty()) |
| 1829 return false; | 1820 return false; |
| 1830 // TODO(esprehn): This makes sure the style system is updated, eventually | |
| 1831 // we'll remove all the global lists and this won't be needed. | |
| 1832 document().ensureStyleResolver(); | |
| 1833 if (treeScope().scopedStyleResolver().features().hasSelectorForClass(classVa
lue)) | 1821 if (treeScope().scopedStyleResolver().features().hasSelectorForClass(classVa
lue)) |
| 1834 return true; | 1822 return true; |
| 1835 // Host rules could also have effects. | 1823 // Host rules could also have effects. |
| 1836 if (ShadowRoot* shadowRoot = this->shadowRoot()) | 1824 if (ShadowRoot* shadowRoot = this->shadowRoot()) |
| 1837 return shadowRoot->scopedStyleResolver().features().hasSelectorForClass(
classValue); | 1825 return shadowRoot->scopedStyleResolver().features().hasSelectorForClass(
classValue); |
| 1838 return false; | 1826 return false; |
| 1839 } | 1827 } |
| 1840 | 1828 |
| 1841 bool Element::affectedByIdSelector(const AtomicString& idValue) const | 1829 bool Element::affectedByIdSelector(const AtomicString& idValue) const |
| 1842 { | 1830 { |
| 1843 if (idValue.isEmpty()) | 1831 if (idValue.isEmpty()) |
| 1844 return false; | 1832 return false; |
| 1845 // TODO(esprehn): This makes sure the style system is updated, eventually | |
| 1846 // we'll remove all the global lists and this won't be needed. | |
| 1847 document().ensureStyleResolver(); | |
| 1848 if (treeScope().scopedStyleResolver().features().hasSelectorForId(idValue)) | 1833 if (treeScope().scopedStyleResolver().features().hasSelectorForId(idValue)) |
| 1849 return true; | 1834 return true; |
| 1850 // Host rules could also have effects. | 1835 // Host rules could also have effects. |
| 1851 if (ShadowRoot* shadowRoot = this->shadowRoot()) | 1836 if (ShadowRoot* shadowRoot = this->shadowRoot()) |
| 1852 return shadowRoot->scopedStyleResolver().features().hasSelectorForId(idV
alue); | 1837 return shadowRoot->scopedStyleResolver().features().hasSelectorForId(idV
alue); |
| 1853 return false; | 1838 return false; |
| 1854 } | 1839 } |
| 1855 | 1840 |
| 1856 } // namespace blink | 1841 } // namespace blink |
| OLD | NEW |