Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(145)

Side by Side Diff: Source/core/dom/Element.cpp

Issue 129633003: Add a first pass of a class descendant invalidator, and a containing RuleSetAnalyzer (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Implement tree walk for descendant class invalidation. Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/core/dom/Element.h ('k') | Source/core/dom/Node.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « Source/core/dom/Element.h ('k') | Source/core/dom/Node.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698