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 1027 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |