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 unsigned length = newClassString.length(); | 1038 unsigned length = newClassString.length(); |
1039 | 1039 |
1040 if (!length) | 1040 if (!length) |
1041 return false; | 1041 return false; |
1042 | 1042 |
1043 if (newClassString.is8Bit()) | 1043 if (newClassString.is8Bit()) |
1044 return classStringHasClassName(newClassString.characters8(), length); | 1044 return classStringHasClassName(newClassString.characters8(), length); |
1045 return classStringHasClassName(newClassString.characters16(), length); | 1045 return classStringHasClassName(newClassString.characters16(), length); |
1046 } | 1046 } |
1047 | 1047 |
1048 template<typename Checker> | |
1049 static bool checkSelectorForClassChange(const SpaceSplitString& changedClasses,
const Checker& checker) | |
1050 { | |
1051 unsigned changedSize = changedClasses.size(); | |
1052 for (unsigned i = 0; i < changedSize; ++i) { | |
1053 if (checker.hasSelectorForClass(changedClasses[i])) | |
1054 return true; | |
1055 } | |
1056 return false; | |
1057 } | |
1058 | |
1059 template<typename Checker> | |
1060 static bool checkSelectorForClassChange(const SpaceSplitString& oldClasses, cons
t SpaceSplitString& newClasses, const Checker& checker) | |
1061 { | |
1062 if (!oldClasses.size()) | |
1063 return checkSelectorForClassChange(newClasses, checker); | |
1064 | |
1065 // Class vectors tend to be very short. This is faster than using a hash tab
le. | |
1066 BitVector remainingClassBits; | |
1067 remainingClassBits.ensureSize(oldClasses.size()); | |
1068 | |
1069 for (unsigned i = 0; i < newClasses.size(); ++i) { | |
1070 bool found = false; | |
1071 for (unsigned j = 0; j < oldClasses.size(); ++j) { | |
1072 if (newClasses[i] == oldClasses[j]) { | |
1073 // Mark each class that is still in the newClasses so we can ski
p doing | |
1074 // an n^2 search below when looking for removals. We can't break
from | |
1075 // this loop early since a class can appear more than once. | |
1076 remainingClassBits.quickSet(j); | |
1077 found = true; | |
1078 } | |
1079 } | |
1080 // Class was added. | |
1081 if (!found && checker.hasSelectorForClass(newClasses[i])) | |
1082 return true; | |
1083 } | |
1084 | |
1085 for (unsigned i = 0; i < oldClasses.size(); ++i) { | |
1086 if (remainingClassBits.quickGet(i)) | |
1087 continue; | |
1088 // Class was removed. | |
1089 if (checker.hasSelectorForClass(oldClasses[i])) | |
1090 return true; | |
1091 } | |
1092 | |
1093 return false; | |
1094 } | |
1095 | |
1096 void Element::classAttributeChanged(const AtomicString& newClassString) | 1048 void Element::classAttributeChanged(const AtomicString& newClassString) |
1097 { | 1049 { |
1098 StyleResolver* styleResolver = document().styleResolver(); | 1050 StyleResolver* styleResolver = document().styleResolver(); |
1099 bool testShouldInvalidateStyle = inActiveDocument() && styleResolver && styl
eChangeType() < SubtreeStyleChange; | 1051 bool testShouldInvalidateStyle = inActiveDocument() && styleResolver && styl
eChangeType() < SubtreeStyleChange; |
1100 bool shouldInvalidateStyle = false; | |
1101 | 1052 |
1102 if (classStringHasClassName(newClassString)) { | 1053 if (classStringHasClassName(newClassString)) { |
1103 const bool shouldFoldCase = document().inQuirksMode(); | 1054 const bool shouldFoldCase = document().inQuirksMode(); |
1104 const SpaceSplitString oldClasses = elementData()->classNames(); | 1055 const SpaceSplitString oldClasses = elementData()->classNames(); |
1105 elementData()->setClass(newClassString, shouldFoldCase); | 1056 elementData()->setClass(newClassString, shouldFoldCase); |
1106 const SpaceSplitString& newClasses = elementData()->classNames(); | 1057 const SpaceSplitString& newClasses = elementData()->classNames(); |
1107 shouldInvalidateStyle = testShouldInvalidateStyle && checkSelectorForCla
ssChange(oldClasses, newClasses, styleResolver->ensureRuleFeatureSet()); | 1058 if (testShouldInvalidateStyle) |
| 1059 styleResolver->ensureRuleFeatureSet().scheduleStyleInvalidationForCl
assChange(oldClasses, newClasses, this); |
1108 } else { | 1060 } else { |
1109 const SpaceSplitString& oldClasses = elementData()->classNames(); | 1061 const SpaceSplitString& oldClasses = elementData()->classNames(); |
1110 shouldInvalidateStyle = testShouldInvalidateStyle && checkSelectorForCla
ssChange(oldClasses, styleResolver->ensureRuleFeatureSet()); | 1062 if (testShouldInvalidateStyle) |
| 1063 styleResolver->ensureRuleFeatureSet().scheduleStyleInvalidationForCl
assChange(oldClasses, this); |
1111 elementData()->clearClass(); | 1064 elementData()->clearClass(); |
1112 } | 1065 } |
1113 | 1066 |
1114 if (hasRareData()) | 1067 if (hasRareData()) |
1115 elementRareData()->clearClassListValueForQuirksMode(); | 1068 elementRareData()->clearClassListValueForQuirksMode(); |
1116 | |
1117 if (shouldInvalidateStyle) | |
1118 setNeedsStyleRecalc(); | |
1119 } | 1069 } |
1120 | 1070 |
1121 bool Element::shouldInvalidateDistributionWhenAttributeChanged(ElementShadow* el
ementShadow, const QualifiedName& name, const AtomicString& newValue) | 1071 bool Element::shouldInvalidateDistributionWhenAttributeChanged(ElementShadow* el
ementShadow, const QualifiedName& name, const AtomicString& newValue) |
1122 { | 1072 { |
1123 ASSERT(elementShadow); | 1073 ASSERT(elementShadow); |
1124 const SelectRuleFeatureSet& featureSet = elementShadow->ensureSelectFeatureS
et(); | 1074 const SelectRuleFeatureSet& featureSet = elementShadow->ensureSelectFeatureS
et(); |
1125 | 1075 |
1126 if (isIdAttributeName(name)) { | 1076 if (isIdAttributeName(name)) { |
1127 AtomicString oldId = elementData()->idForStyleResolution(); | 1077 AtomicString oldId = elementData()->idForStyleResolution(); |
1128 AtomicString newId = makeIdForStyleResolution(newValue, document().inQui
rksMode()); | 1078 AtomicString newId = makeIdForStyleResolution(newValue, document().inQui
rksMode()); |
1129 if (newId != oldId) { | 1079 if (newId != oldId) { |
1130 if (!oldId.isEmpty() && featureSet.hasSelectorForId(oldId)) | 1080 if (!oldId.isEmpty() && featureSet.hasSelectorForId(oldId)) |
1131 return true; | 1081 return true; |
1132 if (!newId.isEmpty() && featureSet.hasSelectorForId(newId)) | 1082 if (!newId.isEmpty() && featureSet.hasSelectorForId(newId)) |
1133 return true; | 1083 return true; |
1134 } | 1084 } |
1135 } | 1085 } |
1136 | 1086 |
1137 if (name == HTMLNames::classAttr) { | 1087 if (name == HTMLNames::classAttr) { |
1138 const AtomicString& newClassString = newValue; | 1088 const AtomicString& newClassString = newValue; |
1139 if (classStringHasClassName(newClassString)) { | 1089 if (classStringHasClassName(newClassString)) { |
1140 const bool shouldFoldCase = document().inQuirksMode(); | 1090 const bool shouldFoldCase = document().inQuirksMode(); |
1141 const SpaceSplitString& oldClasses = elementData()->classNames(); | 1091 const SpaceSplitString& oldClasses = elementData()->classNames(); |
1142 const SpaceSplitString newClasses(newClassString, shouldFoldCase); | 1092 const SpaceSplitString newClasses(newClassString, shouldFoldCase); |
1143 if (checkSelectorForClassChange(oldClasses, newClasses, featureSet)) | 1093 if (featureSet.checkSelectorsForClassChange(oldClasses, newClasses)) |
1144 return true; | 1094 return true; |
1145 } else { | 1095 } else { |
1146 const SpaceSplitString& oldClasses = elementData()->classNames(); | 1096 const SpaceSplitString& oldClasses = elementData()->classNames(); |
1147 if (checkSelectorForClassChange(oldClasses, featureSet)) | 1097 if (featureSet.checkSelectorsForClassChange(oldClasses)) |
1148 return true; | 1098 return true; |
1149 } | 1099 } |
1150 } | 1100 } |
1151 | 1101 |
1152 return featureSet.hasSelectorForAttribute(name.localName()); | 1102 return featureSet.hasSelectorForAttribute(name.localName()); |
1153 } | 1103 } |
1154 | 1104 |
1155 // Returns true is the given attribute is an event handler. | 1105 // Returns true is the given attribute is an event handler. |
1156 // We consider an event handler any attribute that begins with "on". | 1106 // We consider an event handler any attribute that begins with "on". |
1157 // It is a simple solution that has the advantage of not requiring any | 1107 // It is a simple solution that has the advantage of not requiring any |
(...skipping 2462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3620 // Before doing so, we need to resolve issues in HTMLSelectElement::recalcLi
stItems | 3570 // Before doing so, we need to resolve issues in HTMLSelectElement::recalcLi
stItems |
3621 // and RenderMenuList::setText. See also https://bugs.webkit.org/show_bug.cg
i?id=88405 | 3571 // and RenderMenuList::setText. See also https://bugs.webkit.org/show_bug.cg
i?id=88405 |
3622 if (hasTagName(optionTag) || hasTagName(optgroupTag)) | 3572 if (hasTagName(optionTag) || hasTagName(optgroupTag)) |
3623 return false; | 3573 return false; |
3624 if (FullscreenElementStack::isActiveFullScreenElement(this)) | 3574 if (FullscreenElementStack::isActiveFullScreenElement(this)) |
3625 return false; | 3575 return false; |
3626 return true; | 3576 return true; |
3627 } | 3577 } |
3628 | 3578 |
3629 } // namespace WebCore | 3579 } // namespace WebCore |
OLD | NEW |