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

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: Removed extra line. 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
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 1027 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 template<typename Checker> 1047 template<typename Checker>
1048 static bool checkSelectorForClassChange(const SpaceSplitString& changedClasses, const Checker& checker) 1048 static bool checkSelectorForClassChange(const SpaceSplitString& changedClasses, const Checker& checker, Element* element)
1049 { 1049 {
1050 unsigned changedSize = changedClasses.size(); 1050 unsigned changedSize = changedClasses.size();
1051 for (unsigned i = 0; i < changedSize; ++i) { 1051 for (unsigned i = 0; i < changedSize; ++i) {
1052 if (checker.hasSelectorForClass(changedClasses[i])) 1052 const RuleSetAnalyzer* ruleSetAnalyzer = checker.getRuleSetAnalyzer();
1053 if (ruleSetAnalyzer)
1054 ruleSetAnalyzer->invalidateElementSubtreeForClassChange(changedClass es[i], element);
esprehn 2014/01/14 21:32:56 I had envisioned doing this in a single pass, not
esprehn 2014/01/14 21:32:56 You ignore the return value of invalidateElementSu
chrishtr 2014/01/14 23:33:00 Done.
chrishtr 2014/01/14 23:33:00 Done.
1055 else if (checker.hasSelectorForClass(changedClasses[i]))
1053 return true; 1056 return true;
1054 } 1057 }
1055 return false; 1058 return false;
1056 } 1059 }
1057 1060
1058 template<typename Checker> 1061 template<typename Checker>
1059 static bool checkSelectorForClassChange(const SpaceSplitString& oldClasses, cons t SpaceSplitString& newClasses, const Checker& checker) 1062 static bool checkSelectorForClassChange(const SpaceSplitString& oldClasses, cons t SpaceSplitString& newClasses, const Checker& checker, Element* element)
1060 { 1063 {
1061 if (!oldClasses.size()) 1064 if (!oldClasses.size())
1062 return checkSelectorForClassChange(newClasses, checker); 1065 return checkSelectorForClassChange(newClasses, checker, element);
1063 1066
1064 // Class vectors tend to be very short. This is faster than using a hash tab le. 1067 // Class vectors tend to be very short. This is faster than using a hash tab le.
1065 BitVector remainingClassBits; 1068 BitVector remainingClassBits;
1066 remainingClassBits.ensureSize(oldClasses.size()); 1069 remainingClassBits.ensureSize(oldClasses.size());
1067 1070
1068 for (unsigned i = 0; i < newClasses.size(); ++i) { 1071 for (unsigned i = 0; i < newClasses.size(); ++i) {
1069 bool found = false; 1072 bool found = false;
1070 for (unsigned j = 0; j < oldClasses.size(); ++j) { 1073 for (unsigned j = 0; j < oldClasses.size(); ++j) {
1071 if (newClasses[i] == oldClasses[j]) { 1074 if (newClasses[i] == oldClasses[j]) {
1072 // Mark each class that is still in the newClasses so we can ski p doing 1075 // 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 1076 // 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. 1077 // this loop early since a class can appear more than once.
1075 remainingClassBits.quickSet(j); 1078 remainingClassBits.quickSet(j);
1076 found = true; 1079 found = true;
1077 } 1080 }
1078 } 1081 }
1079 // Class was added. 1082 // Class was added.
1080 if (!found && checker.hasSelectorForClass(newClasses[i])) 1083
1081 return true; 1084 if (!found) {
1085 const RuleSetAnalyzer* ruleSetAnalyzer = checker.getRuleSetAnalyzer( );
1086 if (ruleSetAnalyzer)
esprehn 2014/01/14 21:32:56 Combing if and get, if (const RuleSet.... = checke
chrishtr 2014/01/14 23:33:00 Done.
1087 ruleSetAnalyzer->invalidateElementSubtreeForClassChange(newClass es[i], element);
1088 else if (checker.hasSelectorForClass(newClasses[i]))
1089 return true;
1090 }
1082 } 1091 }
1083 1092
1084 for (unsigned i = 0; i < oldClasses.size(); ++i) { 1093 for (unsigned i = 0; i < oldClasses.size(); ++i) {
1085 if (remainingClassBits.quickGet(i)) 1094 if (remainingClassBits.quickGet(i))
1086 continue; 1095 continue;
1096
1087 // Class was removed. 1097 // Class was removed.
1088 if (checker.hasSelectorForClass(oldClasses[i])) 1098 const RuleSetAnalyzer* ruleSetAnalyzer = checker.getRuleSetAnalyzer();
1099 if (ruleSetAnalyzer)
1100 ruleSetAnalyzer->invalidateElementSubtreeForClassChange(oldClasses[i ], element);
1101 else if (checker.hasSelectorForClass(oldClasses[i]))
1089 return true; 1102 return true;
1090 } 1103 }
1091 1104
1092 return false; 1105 return false;
1093 } 1106 }
1094 1107
1095 void Element::classAttributeChanged(const AtomicString& newClassString) 1108 void Element::classAttributeChanged(const AtomicString& newClassString)
1096 { 1109 {
1097 StyleResolver* styleResolver = document().styleResolver(); 1110 StyleResolver* styleResolver = document().styleResolver();
1098 bool testShouldInvalidateStyle = inActiveDocument() && styleResolver && styl eChangeType() < SubtreeStyleChange; 1111 bool testShouldInvalidateStyle = inActiveDocument() && styleResolver && styl eChangeType() < SubtreeStyleChange;
1099 bool shouldInvalidateStyle = false; 1112 bool shouldInvalidateStyle = false;
1100 1113
1101 if (classStringHasClassName(newClassString)) { 1114 if (classStringHasClassName(newClassString)) {
1102 const bool shouldFoldCase = document().inQuirksMode(); 1115 const bool shouldFoldCase = document().inQuirksMode();
1103 const SpaceSplitString oldClasses = ensureUniqueElementData()->className s(); 1116 const SpaceSplitString oldClasses = ensureUniqueElementData()->className s();
1104 elementData()->setClass(newClassString, shouldFoldCase); 1117 elementData()->setClass(newClassString, shouldFoldCase);
1105 const SpaceSplitString& newClasses = elementData()->classNames(); 1118 const SpaceSplitString& newClasses = elementData()->classNames();
1106 shouldInvalidateStyle = testShouldInvalidateStyle && checkSelectorForCla ssChange(oldClasses, newClasses, styleResolver->ensureRuleFeatureSet()); 1119 shouldInvalidateStyle = testShouldInvalidateStyle && checkSelectorForCla ssChange(oldClasses, newClasses, styleResolver->ensureRuleFeatureSet(), this);
1107 } else if (elementData()) { 1120 } else if (elementData()) {
1108 const SpaceSplitString& oldClasses = elementData()->classNames(); 1121 const SpaceSplitString& oldClasses = elementData()->classNames();
1109 shouldInvalidateStyle = testShouldInvalidateStyle && checkSelectorForCla ssChange(oldClasses, styleResolver->ensureRuleFeatureSet()); 1122 shouldInvalidateStyle = testShouldInvalidateStyle && checkSelectorForCla ssChange(oldClasses, styleResolver->ensureRuleFeatureSet(), this);
1110 elementData()->clearClass(); 1123 elementData()->clearClass();
1111 } 1124 }
1112 1125
1113 if (hasRareData()) 1126 if (hasRareData())
1114 elementRareData()->clearClassListValueForQuirksMode(); 1127 elementRareData()->clearClassListValueForQuirksMode();
1115 1128
1116 if (shouldInvalidateStyle) 1129 if (shouldInvalidateStyle)
1117 setNeedsStyleRecalc(); 1130 setNeedsStyleRecalc();
1118 } 1131 }
1119 1132
(...skipping 12 matching lines...) Expand all
1132 return true; 1145 return true;
1133 } 1146 }
1134 } 1147 }
1135 1148
1136 if (name == HTMLNames::classAttr) { 1149 if (name == HTMLNames::classAttr) {
1137 const AtomicString& newClassString = newValue; 1150 const AtomicString& newClassString = newValue;
1138 if (classStringHasClassName(newClassString)) { 1151 if (classStringHasClassName(newClassString)) {
1139 const bool shouldFoldCase = document().inQuirksMode(); 1152 const bool shouldFoldCase = document().inQuirksMode();
1140 const SpaceSplitString& oldClasses = elementData()->classNames(); 1153 const SpaceSplitString& oldClasses = elementData()->classNames();
1141 const SpaceSplitString newClasses(newClassString, shouldFoldCase); 1154 const SpaceSplitString newClasses(newClassString, shouldFoldCase);
1142 if (checkSelectorForClassChange(oldClasses, newClasses, featureSet)) 1155 if (checkSelectorForClassChange(oldClasses, newClasses, featureSet, this))
1143 return true; 1156 return true;
1144 } else { 1157 } else {
1145 const SpaceSplitString& oldClasses = elementData()->classNames(); 1158 const SpaceSplitString& oldClasses = elementData()->classNames();
1146 if (checkSelectorForClassChange(oldClasses, featureSet)) 1159 if (checkSelectorForClassChange(oldClasses, featureSet, this))
esprehn 2014/01/14 21:32:56 These should be methods now, don't pass |this|, ju
chrishtr 2014/01/14 23:33:00 Done.
1147 return true; 1160 return true;
1148 } 1161 }
1149 } 1162 }
1150 1163
1151 return featureSet.hasSelectorForAttribute(name.localName()); 1164 return featureSet.hasSelectorForAttribute(name.localName());
1152 } 1165 }
1153 1166
1154 // Returns true is the given attribute is an event handler. 1167 // Returns true is the given attribute is an event handler.
1155 // We consider an event handler any attribute that begins with "on". 1168 // We consider an event handler any attribute that begins with "on".
1156 // It is a simple solution that has the advantage of not requiring any 1169 // It is a simple solution that has the advantage of not requiring any
(...skipping 2480 matching lines...) Expand 10 before | Expand all | Expand 10 after
3637 // Before doing so, we need to resolve issues in HTMLSelectElement::recalcLi stItems 3650 // 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 3651 // and RenderMenuList::setText. See also https://bugs.webkit.org/show_bug.cg i?id=88405
3639 if (hasTagName(optionTag) || hasTagName(optgroupTag)) 3652 if (hasTagName(optionTag) || hasTagName(optgroupTag))
3640 return false; 3653 return false;
3641 if (FullscreenElementStack::isActiveFullScreenElement(this)) 3654 if (FullscreenElementStack::isActiveFullScreenElement(this))
3642 return false; 3655 return false;
3643 return true; 3656 return true;
3644 } 3657 }
3645 3658
3646 } // namespace WebCore 3659 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698