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 |