| 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 1026 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1037 unsigned length = newClassString.length(); | 1037 unsigned length = newClassString.length(); |
| 1038 | 1038 |
| 1039 if (!length) | 1039 if (!length) |
| 1040 return false; | 1040 return false; |
| 1041 | 1041 |
| 1042 if (newClassString.is8Bit()) | 1042 if (newClassString.is8Bit()) |
| 1043 return classStringHasClassName(newClassString.characters8(), length); | 1043 return classStringHasClassName(newClassString.characters8(), length); |
| 1044 return classStringHasClassName(newClassString.characters16(), length); | 1044 return classStringHasClassName(newClassString.characters16(), length); |
| 1045 } | 1045 } |
| 1046 | 1046 |
| 1047 static bool debug = false; |
| 1048 |
| 1049 |
| 1047 template<typename Checker> | 1050 template<typename Checker> |
| 1048 static bool checkSelectorForClassChange(const SpaceSplitString& changedClasses,
const Checker& checker) | 1051 bool Element::checkSelectorForClassChange(const SpaceSplitString& changedClasses
, const Checker& checker) |
| 1049 { | 1052 { |
| 1050 unsigned changedSize = changedClasses.size(); | 1053 unsigned changedSize = changedClasses.size(); |
| 1051 for (unsigned i = 0; i < changedSize; ++i) { | 1054 for (unsigned i = 0; i < changedSize; ++i) { |
| 1052 if (checker.hasSelectorForClass(changedClasses[i])) | 1055 RuleSetAnalyzer* ruleSetAnalyzer = checker.getRuleSetAnalyzer(); |
| 1053 return true; | 1056 if (!ruleSetAnalyzer || !ruleSetAnalyzer->scheduleClassInvalidationForEl
ement(changedClasses[i], this)) { |
| 1057 if (debug) |
| 1058 printf("Fail!!"); |
| 1059 if (checker.hasSelectorForClass(changedClasses[i])) |
| 1060 return true; |
| 1061 } |
| 1054 } | 1062 } |
| 1055 return false; | 1063 return false; |
| 1056 } | 1064 } |
| 1057 | 1065 |
| 1058 template<typename Checker> | 1066 template<typename Checker> |
| 1059 static bool checkSelectorForClassChange(const SpaceSplitString& oldClasses, cons
t SpaceSplitString& newClasses, const Checker& checker) | 1067 bool Element::checkSelectorForClassChange(const SpaceSplitString& oldClasses, co
nst SpaceSplitString& newClasses, const Checker& checker) |
| 1060 { | 1068 { |
| 1061 if (!oldClasses.size()) | 1069 if (!oldClasses.size()) |
| 1062 return checkSelectorForClassChange(newClasses, checker); | 1070 return checkSelectorForClassChange(newClasses, checker); |
| 1063 | 1071 |
| 1064 // Class vectors tend to be very short. This is faster than using a hash tab
le. | 1072 // Class vectors tend to be very short. This is faster than using a hash tab
le. |
| 1065 BitVector remainingClassBits; | 1073 BitVector remainingClassBits; |
| 1066 remainingClassBits.ensureSize(oldClasses.size()); | 1074 remainingClassBits.ensureSize(oldClasses.size()); |
| 1075 RuleSetAnalyzer* ruleSetAnalyzer = checker.getRuleSetAnalyzer(); |
| 1067 | 1076 |
| 1068 for (unsigned i = 0; i < newClasses.size(); ++i) { | 1077 for (unsigned i = 0; i < newClasses.size(); ++i) { |
| 1069 bool found = false; | 1078 bool found = false; |
| 1070 for (unsigned j = 0; j < oldClasses.size(); ++j) { | 1079 for (unsigned j = 0; j < oldClasses.size(); ++j) { |
| 1071 if (newClasses[i] == oldClasses[j]) { | 1080 if (newClasses[i] == oldClasses[j]) { |
| 1072 // Mark each class that is still in the newClasses so we can ski
p doing | 1081 // Mark each class that is still in the newClasses so we can ski
p doing |
| 1073 // an n^2 search below when looking for removals. We can't break
from | 1082 // an n^2 search below when looking for removals. We can't break
from |
| 1074 // this loop early since a class can appear more than once. | 1083 // this loop early since a class can appear more than once. |
| 1075 remainingClassBits.quickSet(j); | 1084 remainingClassBits.quickSet(j); |
| 1076 found = true; | 1085 found = true; |
| 1077 } | 1086 } |
| 1078 } | 1087 } |
| 1079 // Class was added. | 1088 // Class was added. |
| 1080 if (!found && checker.hasSelectorForClass(newClasses[i])) | 1089 if (!found) { |
| 1081 return true; | 1090 if (!ruleSetAnalyzer || !ruleSetAnalyzer->scheduleClassInvalidationF
orElement(newClasses[i], this)) { |
| 1091 if (debug) |
| 1092 printf("Fail!!"); |
| 1093 |
| 1094 if (checker.hasSelectorForClass(newClasses[i])) |
| 1095 return true; |
| 1096 } |
| 1097 } |
| 1082 } | 1098 } |
| 1083 | 1099 |
| 1084 for (unsigned i = 0; i < oldClasses.size(); ++i) { | 1100 for (unsigned i = 0; i < oldClasses.size(); ++i) { |
| 1085 if (remainingClassBits.quickGet(i)) | 1101 if (remainingClassBits.quickGet(i)) |
| 1086 continue; | 1102 continue; |
| 1103 |
| 1087 // Class was removed. | 1104 // Class was removed. |
| 1088 if (checker.hasSelectorForClass(oldClasses[i])) | 1105 if (!ruleSetAnalyzer || !ruleSetAnalyzer->scheduleClassInvalidationForEl
ement(oldClasses[i], this)) { |
| 1089 return true; | 1106 if (debug) |
| 1107 printf("Fail!!"); |
| 1108 |
| 1109 if (checker.hasSelectorForClass(oldClasses[i])) |
| 1110 return true; |
| 1111 } |
| 1090 } | 1112 } |
| 1091 | 1113 |
| 1092 return false; | 1114 return false; |
| 1093 } | 1115 } |
| 1094 | 1116 |
| 1095 void Element::classAttributeChanged(const AtomicString& newClassString) | 1117 void Element::classAttributeChanged(const AtomicString& newClassString) |
| 1096 { | 1118 { |
| 1097 StyleResolver* styleResolver = document().styleResolver(); | 1119 StyleResolver* styleResolver = document().styleResolver(); |
| 1098 bool testShouldInvalidateStyle = inActiveDocument() && styleResolver && styl
eChangeType() < SubtreeStyleChange; | 1120 bool testShouldInvalidateStyle = inActiveDocument() && styleResolver && styl
eChangeType() < SubtreeStyleChange; |
| 1099 bool shouldInvalidateStyle = false; | 1121 bool shouldInvalidateStyle = false; |
| (...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1599 if (change == Reattach) | 1621 if (change == Reattach) |
| 1600 reattachWhitespaceSiblings(nextTextSibling); | 1622 reattachWhitespaceSiblings(nextTextSibling); |
| 1601 } | 1623 } |
| 1602 | 1624 |
| 1603 StyleRecalcChange Element::recalcOwnStyle(StyleRecalcChange change) | 1625 StyleRecalcChange Element::recalcOwnStyle(StyleRecalcChange change) |
| 1604 { | 1626 { |
| 1605 ASSERT(document().inStyleRecalc()); | 1627 ASSERT(document().inStyleRecalc()); |
| 1606 ASSERT(!parentOrShadowHostNode()->needsStyleRecalc()); | 1628 ASSERT(!parentOrShadowHostNode()->needsStyleRecalc()); |
| 1607 ASSERT(change >= Inherit || needsStyleRecalc()); | 1629 ASSERT(change >= Inherit || needsStyleRecalc()); |
| 1608 ASSERT(parentRenderStyle()); | 1630 ASSERT(parentRenderStyle()); |
| 1631 if (debug) |
| 1632 printf("recalcOwnStyle: outerHTML=%s", outerHTML().ascii().data()); |
| 1609 | 1633 |
| 1610 RefPtr<RenderStyle> oldStyle = renderStyle(); | 1634 RefPtr<RenderStyle> oldStyle = renderStyle(); |
| 1611 RefPtr<RenderStyle> newStyle = styleForRenderer(); | 1635 RefPtr<RenderStyle> newStyle = styleForRenderer(); |
| 1612 StyleRecalcChange localChange = RenderStyle::compare(oldStyle.get(), newStyl
e.get()); | 1636 StyleRecalcChange localChange = RenderStyle::compare(oldStyle.get(), newStyl
e.get()); |
| 1613 | 1637 if (debug) { |
| 1638 printf("localChange=%d\n", localChange); |
| 1639 printf("background color=%s\n", newStyle->backgroundColor().serialized()
.ascii().data()); |
| 1640 } |
| 1614 ASSERT(newStyle); | 1641 ASSERT(newStyle); |
| 1615 | 1642 |
| 1616 if (localChange == Reattach) { | 1643 if (localChange == Reattach) { |
| 1617 AttachContext reattachContext; | 1644 AttachContext reattachContext; |
| 1618 reattachContext.resolvedStyle = newStyle.get(); | 1645 reattachContext.resolvedStyle = newStyle.get(); |
| 1619 reattach(reattachContext); | 1646 reattach(reattachContext); |
| 1620 return Reattach; | 1647 return Reattach; |
| 1621 } | 1648 } |
| 1622 | 1649 |
| 1623 ASSERT(oldStyle); | 1650 ASSERT(oldStyle); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1683 for (Node* child = lastChild(); child; child = child->previousSibling()) { | 1710 for (Node* child = lastChild(); child; child = child->previousSibling()) { |
| 1684 if (child->isTextNode()) { | 1711 if (child->isTextNode()) { |
| 1685 toText(child)->recalcTextStyle(change, lastTextNode); | 1712 toText(child)->recalcTextStyle(change, lastTextNode); |
| 1686 lastTextNode = toText(child); | 1713 lastTextNode = toText(child); |
| 1687 } else if (child->isElementNode()) { | 1714 } else if (child->isElementNode()) { |
| 1688 Element* element = toElement(child); | 1715 Element* element = toElement(child); |
| 1689 if (shouldRecalcStyle(change, element)) { | 1716 if (shouldRecalcStyle(change, element)) { |
| 1690 parentPusher.push(); | 1717 parentPusher.push(); |
| 1691 element->recalcStyle(change, lastTextNode); | 1718 element->recalcStyle(change, lastTextNode); |
| 1692 } else if (element->supportsStyleSharing()) { | 1719 } else if (element->supportsStyleSharing()) { |
| 1720 if (debug) |
| 1721 printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!! style sharing for eleme
nt outerHTML=%s\n", element->outerHTML().ascii().data()); |
| 1693 styleResolver.addToStyleSharingList(*element); | 1722 styleResolver.addToStyleSharingList(*element); |
| 1694 } | 1723 } |
| 1695 if (element->renderer()) | 1724 if (element->renderer()) |
| 1696 lastTextNode = 0; | 1725 lastTextNode = 0; |
| 1697 } | 1726 } |
| 1698 } | 1727 } |
| 1699 | 1728 |
| 1700 if (shouldRecalcStyle(change, this)) { | 1729 if (shouldRecalcStyle(change, this)) { |
| 1701 updatePseudoElement(AFTER, change); | 1730 updatePseudoElement(AFTER, change); |
| 1702 updatePseudoElement(BACKDROP, change); | 1731 updatePseudoElement(BACKDROP, change); |
| (...skipping 832 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2535 // FIXME: Try to do better than this. Ensure that styleForElement() work
s for elements that are not in the | 2564 // FIXME: Try to do better than this. Ensure that styleForElement() work
s for elements that are not in the |
| 2536 // document tree and figure out when to destroy the computed style for s
uch elements. | 2565 // document tree and figure out when to destroy the computed style for s
uch elements. |
| 2537 return 0; | 2566 return 0; |
| 2538 | 2567 |
| 2539 ElementRareData& rareData = ensureElementRareData(); | 2568 ElementRareData& rareData = ensureElementRareData(); |
| 2540 if (!rareData.computedStyle()) | 2569 if (!rareData.computedStyle()) |
| 2541 rareData.setComputedStyle(document().styleForElementIgnoringPendingStyle
sheets(this)); | 2570 rareData.setComputedStyle(document().styleForElementIgnoringPendingStyle
sheets(this)); |
| 2542 return pseudoElementSpecifier ? rareData.computedStyle()->getCachedPseudoSty
le(pseudoElementSpecifier) : rareData.computedStyle(); | 2571 return pseudoElementSpecifier ? rareData.computedStyle()->getCachedPseudoSty
le(pseudoElementSpecifier) : rareData.computedStyle(); |
| 2543 } | 2572 } |
| 2544 | 2573 |
| 2574 bool Element::needsInvalidation() const |
| 2575 { |
| 2576 if (!document().styleResolver()) |
| 2577 return false; |
| 2578 |
| 2579 if (RuleSetAnalyzer* analyzer = document().styleResolver()->ensureRuleFeatur
eSet().getRuleSetAnalyzer()) |
| 2580 return analyzer->needsInvalidation(this); |
| 2581 return false; |
| 2582 } |
| 2583 |
| 2545 void Element::setStyleAffectedByEmpty() | 2584 void Element::setStyleAffectedByEmpty() |
| 2546 { | 2585 { |
| 2547 ensureElementRareData().setStyleAffectedByEmpty(true); | 2586 ensureElementRareData().setStyleAffectedByEmpty(true); |
| 2548 } | 2587 } |
| 2549 | 2588 |
| 2550 void Element::setChildrenAffectedByFocus() | 2589 void Element::setChildrenAffectedByFocus() |
| 2551 { | 2590 { |
| 2552 ensureElementRareData().setChildrenAffectedByFocus(true); | 2591 ensureElementRareData().setChildrenAffectedByFocus(true); |
| 2553 } | 2592 } |
| 2554 | 2593 |
| (...skipping 1082 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3637 // Before doing so, we need to resolve issues in HTMLSelectElement::recalcLi
stItems | 3676 // Before doing so, we need to resolve issues in HTMLSelectElement::recalcLi
stItems |
| 3638 // and RenderMenuList::setText. See also https://bugs.webkit.org/show_bug.cg
i?id=88405 | 3677 // and RenderMenuList::setText. See also https://bugs.webkit.org/show_bug.cg
i?id=88405 |
| 3639 if (hasTagName(optionTag) || hasTagName(optgroupTag)) | 3678 if (hasTagName(optionTag) || hasTagName(optgroupTag)) |
| 3640 return false; | 3679 return false; |
| 3641 if (FullscreenElementStack::isActiveFullScreenElement(this)) | 3680 if (FullscreenElementStack::isActiveFullScreenElement(this)) |
| 3642 return false; | 3681 return false; |
| 3643 return true; | 3682 return true; |
| 3644 } | 3683 } |
| 3645 | 3684 |
| 3646 } // namespace WebCore | 3685 } // namespace WebCore |
| OLD | NEW |