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 Apple Inc. All rights
reserved. | 7 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 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 1074 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1085 void Element::recalcStyle(StyleChange change) | 1085 void Element::recalcStyle(StyleChange change) |
1086 { | 1086 { |
1087 if (hasCustomWillOrDidRecalcStyle()) { | 1087 if (hasCustomWillOrDidRecalcStyle()) { |
1088 if (!willRecalcStyle(change)) | 1088 if (!willRecalcStyle(change)) |
1089 return; | 1089 return; |
1090 } | 1090 } |
1091 | 1091 |
1092 // Ref currentStyle in case it would otherwise be deleted when setRenderStyl
e() is called. | 1092 // Ref currentStyle in case it would otherwise be deleted when setRenderStyl
e() is called. |
1093 RefPtr<RenderStyle> currentStyle(renderStyle()); | 1093 RefPtr<RenderStyle> currentStyle(renderStyle()); |
1094 bool hasParentStyle = parentNodeForRenderingAndStyle() ? static_cast<bool>(p
arentNodeForRenderingAndStyle()->renderStyle()) : false; | 1094 bool hasParentStyle = parentNodeForRenderingAndStyle() ? static_cast<bool>(p
arentNodeForRenderingAndStyle()->renderStyle()) : false; |
| 1095 bool hasDirectAdjacentRules = currentStyle && currentStyle->childrenAffected
ByDirectAdjacentRules(); |
1095 bool hasIndirectAdjacentRules = currentStyle && currentStyle->childrenAffect
edByForwardPositionalRules(); | 1096 bool hasIndirectAdjacentRules = currentStyle && currentStyle->childrenAffect
edByForwardPositionalRules(); |
1096 | 1097 |
1097 if ((change > NoChange || needsStyleRecalc())) { | 1098 if ((change > NoChange || needsStyleRecalc())) { |
1098 if (hasRareData()) { | 1099 if (hasRareData()) { |
1099 ElementRareData* data = rareData(); | 1100 ElementRareData* data = rareData(); |
1100 data->resetComputedStyle(); | 1101 data->resetComputedStyle(); |
1101 data->m_styleAffectedByEmpty = false; | 1102 data->m_styleAffectedByEmpty = false; |
1102 } | 1103 } |
1103 } | 1104 } |
1104 if (hasParentStyle && (change >= Inherit || needsStyleRecalc())) { | 1105 if (hasParentStyle && (change >= Inherit || needsStyleRecalc())) { |
(...skipping 21 matching lines...) Expand all Loading... |
1126 if (currentStyle->affectedByDragRules()) | 1127 if (currentStyle->affectedByDragRules()) |
1127 newStyle->setAffectedByDragRules(true); | 1128 newStyle->setAffectedByDragRules(true); |
1128 if (currentStyle->childrenAffectedByForwardPositionalRules()) | 1129 if (currentStyle->childrenAffectedByForwardPositionalRules()) |
1129 newStyle->setChildrenAffectedByForwardPositionalRules(); | 1130 newStyle->setChildrenAffectedByForwardPositionalRules(); |
1130 if (currentStyle->childrenAffectedByBackwardPositionalRules()) | 1131 if (currentStyle->childrenAffectedByBackwardPositionalRules()) |
1131 newStyle->setChildrenAffectedByBackwardPositionalRules(); | 1132 newStyle->setChildrenAffectedByBackwardPositionalRules(); |
1132 if (currentStyle->childrenAffectedByFirstChildRules()) | 1133 if (currentStyle->childrenAffectedByFirstChildRules()) |
1133 newStyle->setChildrenAffectedByFirstChildRules(); | 1134 newStyle->setChildrenAffectedByFirstChildRules(); |
1134 if (currentStyle->childrenAffectedByLastChildRules()) | 1135 if (currentStyle->childrenAffectedByLastChildRules()) |
1135 newStyle->setChildrenAffectedByLastChildRules(); | 1136 newStyle->setChildrenAffectedByLastChildRules(); |
1136 if (currentStyle->affectedByDirectAdjacentRules()) | 1137 if (currentStyle->childrenAffectedByDirectAdjacentRules()) |
1137 newStyle->setAffectedByDirectAdjacentRules(); | 1138 newStyle->setChildrenAffectedByDirectAdjacentRules(); |
1138 } | 1139 } |
1139 | 1140 |
1140 if (ch != NoChange || pseudoStyleCacheIsInvalid(currentStyle.get(), newS
tyle.get()) || (change == Force && renderer() && renderer()->requiresForcedStyle
RecalcPropagation())) { | 1141 if (ch != NoChange || pseudoStyleCacheIsInvalid(currentStyle.get(), newS
tyle.get()) || (change == Force && renderer() && renderer()->requiresForcedStyle
RecalcPropagation())) { |
1141 setRenderStyle(newStyle); | 1142 setRenderStyle(newStyle); |
1142 } else if (needsStyleRecalc() && styleChangeType() != SyntheticStyleChan
ge) { | 1143 } else if (needsStyleRecalc() && styleChangeType() != SyntheticStyleChan
ge) { |
1143 // Although no change occurred, we use the new style so that the cou
sin style sharing code won't get | 1144 // Although no change occurred, we use the new style so that the cou
sin style sharing code won't get |
1144 // fooled into believing this style is the same. | 1145 // fooled into believing this style is the same. |
1145 if (renderer()) | 1146 if (renderer()) |
1146 renderer()->setStyleInternal(newStyle.get()); | 1147 renderer()->setStyleInternal(newStyle.get()); |
1147 else | 1148 else |
1148 setRenderStyle(newStyle); | 1149 setRenderStyle(newStyle); |
1149 } else if (styleChangeType() == SyntheticStyleChange) | 1150 } else if (styleChangeType() == SyntheticStyleChange) |
1150 setRenderStyle(newStyle); | 1151 setRenderStyle(newStyle); |
1151 | 1152 |
1152 if (change != Force) { | 1153 if (change != Force) { |
1153 // If "rem" units are used anywhere in the document, and if the docu
ment element's font size changes, then go ahead and force font updating | 1154 // If "rem" units are used anywhere in the document, and if the docu
ment element's font size changes, then go ahead and force font updating |
1154 // all the way down the tree. This is simpler than having to mainta
in a cache of objects (and such font size changes should be rare anyway). | 1155 // all the way down the tree. This is simpler than having to mainta
in a cache of objects (and such font size changes should be rare anyway). |
1155 if (document()->usesRemUnits() && ch != NoChange && currentStyle &&
newStyle && currentStyle->fontSize() != newStyle->fontSize() && document()->docu
mentElement() == this) | 1156 if (document()->usesRemUnits() && ch != NoChange && currentStyle &&
newStyle && currentStyle->fontSize() != newStyle->fontSize() && document()->docu
mentElement() == this) |
1156 change = Force; | 1157 change = Force; |
1157 else if (styleChangeType() >= FullStyleChange) | 1158 else if (styleChangeType() >= FullStyleChange) |
1158 change = Force; | 1159 change = Force; |
1159 else | 1160 else |
1160 change = ch; | 1161 change = ch; |
1161 } | 1162 } |
1162 } | 1163 } |
1163 StyleSelectorParentPusher parentPusher(this); | 1164 StyleSelectorParentPusher parentPusher(this); |
1164 // FIXME: This check is good enough for :hover + foo, but it is not good eno
ugh for :hover + foo + bar. | 1165 // FIXME: This check is good enough for :hover + foo, but it is not good eno
ugh for :hover + foo + bar. |
1165 // For now we will just worry about the common case, since it's a lot tricki
er to get the second case right | 1166 // For now we will just worry about the common case, since it's a lot tricki
er to get the second case right |
1166 // without doing way too much re-resolution. | 1167 // without doing way too much re-resolution. |
1167 bool previousSiblingHadDirectAdjacentRules = false; | 1168 bool forceCheckOfNextElementSibling = false; |
1168 bool forceCheckOfAnyElementSibling = false; | 1169 bool forceCheckOfAnyElementSibling = false; |
1169 for (Node *n = firstChild(); n; n = n->nextSibling()) { | 1170 for (Node *n = firstChild(); n; n = n->nextSibling()) { |
1170 if (n->isTextNode()) { | 1171 if (n->isTextNode()) { |
1171 parentPusher.push(); | 1172 parentPusher.push(); |
1172 static_cast<Text*>(n)->recalcTextStyle(change); | 1173 static_cast<Text*>(n)->recalcTextStyle(change); |
1173 continue; | 1174 continue; |
1174 } | 1175 } |
1175 if (!n->isElementNode()) | 1176 if (!n->isElementNode()) |
1176 continue; | 1177 continue; |
1177 Element* element = static_cast<Element*>(n); | 1178 Element* element = static_cast<Element*>(n); |
1178 bool childRulesChanged = element->needsStyleRecalc() && element->styleCh
angeType() == FullStyleChange; | 1179 bool childRulesChanged = element->needsStyleRecalc() && element->styleCh
angeType() == FullStyleChange; |
1179 bool childAffectedByDirectAdjacentRules = element->renderStyle() ? eleme
nt->renderStyle()->affectedByDirectAdjacentRules() : previousSiblingHadDirectAdj
acentRules; | 1180 if ((forceCheckOfNextElementSibling || forceCheckOfAnyElementSibling)) |
1180 if (childAffectedByDirectAdjacentRules || forceCheckOfAnyElementSibling) | |
1181 element->setNeedsStyleRecalc(); | 1181 element->setNeedsStyleRecalc(); |
1182 if (change >= Inherit || element->childNeedsStyleRecalc() || element->ne
edsStyleRecalc()) { | 1182 if (change >= Inherit || element->childNeedsStyleRecalc() || element->ne
edsStyleRecalc()) { |
1183 parentPusher.push(); | 1183 parentPusher.push(); |
1184 element->recalcStyle(change); | 1184 element->recalcStyle(change); |
1185 } | 1185 } |
1186 previousSiblingHadDirectAdjacentRules = childAffectedByDirectAdjacentRul
es; | 1186 forceCheckOfNextElementSibling = childRulesChanged && hasDirectAdjacentR
ules; |
1187 forceCheckOfAnyElementSibling = forceCheckOfAnyElementSibling || (childR
ulesChanged && hasIndirectAdjacentRules); | 1187 forceCheckOfAnyElementSibling = forceCheckOfAnyElementSibling || (childR
ulesChanged && hasIndirectAdjacentRules); |
1188 } | 1188 } |
1189 // FIXME: This does not care about sibling combinators. Will be necessary in
XBL2 world. | 1189 // FIXME: This does not care about sibling combinators. Will be necessary in
XBL2 world. |
1190 if (ShadowRoot* shadow = shadowRoot()) { | 1190 if (ShadowRoot* shadow = shadowRoot()) { |
1191 if (change >= Inherit || shadow->childNeedsStyleRecalc() || shadow->need
sStyleRecalc()) { | 1191 if (change >= Inherit || shadow->childNeedsStyleRecalc() || shadow->need
sStyleRecalc()) { |
1192 parentPusher.push(); | 1192 parentPusher.push(); |
1193 shadow->recalcShadowTreeStyle(change); | 1193 shadow->recalcShadowTreeStyle(change); |
1194 } | 1194 } |
1195 } | 1195 } |
1196 | 1196 |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1363 if (newLastChild != lastElementBeforeInsertion && lastElementBeforeInser
tion && lastElementBeforeInsertion->attached() && | 1363 if (newLastChild != lastElementBeforeInsertion && lastElementBeforeInser
tion && lastElementBeforeInsertion->attached() && |
1364 lastElementBeforeInsertion->renderStyle() && lastElementBeforeInsert
ion->renderStyle()->lastChildState()) | 1364 lastElementBeforeInsertion->renderStyle() && lastElementBeforeInsert
ion->renderStyle()->lastChildState()) |
1365 lastElementBeforeInsertion->setNeedsStyleRecalc(); | 1365 lastElementBeforeInsertion->setNeedsStyleRecalc(); |
1366 | 1366 |
1367 // We also have to handle node removal. The parser callback case is sim
ilar to node removal as well in that we need to change the last child | 1367 // We also have to handle node removal. The parser callback case is sim
ilar to node removal as well in that we need to change the last child |
1368 // to match now. | 1368 // to match now. |
1369 if ((childCountDelta < 0 || finishedParsingCallback) && newLastChild ==
lastElementBeforeInsertion && newLastChild && newLastChild->renderStyle() && !ne
wLastChild->renderStyle()->lastChildState()) | 1369 if ((childCountDelta < 0 || finishedParsingCallback) && newLastChild ==
lastElementBeforeInsertion && newLastChild && newLastChild->renderStyle() && !ne
wLastChild->renderStyle()->lastChildState()) |
1370 newLastChild->setNeedsStyleRecalc(); | 1370 newLastChild->setNeedsStyleRecalc(); |
1371 } | 1371 } |
1372 | 1372 |
| 1373 // The + selector. We need to invalidate the first element following the in
sertion point. It is the only possible element |
| 1374 // that could be affected by this DOM change. |
| 1375 if (style->childrenAffectedByDirectAdjacentRules() && afterChange) { |
| 1376 Node* firstElementAfterInsertion = 0; |
| 1377 for (firstElementAfterInsertion = afterChange; |
| 1378 firstElementAfterInsertion && !firstElementAfterInsertion->isElemen
tNode(); |
| 1379 firstElementAfterInsertion = firstElementAfterInsertion->nextSiblin
g()) {}; |
| 1380 if (firstElementAfterInsertion && firstElementAfterInsertion->attached()
) |
| 1381 firstElementAfterInsertion->setNeedsStyleRecalc(); |
| 1382 } |
| 1383 |
1373 // Forward positional selectors include the ~ selector, nth-child, nth-of-ty
pe, first-of-type and only-of-type. | 1384 // Forward positional selectors include the ~ selector, nth-child, nth-of-ty
pe, first-of-type and only-of-type. |
1374 // Backward positional selectors include nth-last-child, nth-last-of-type, l
ast-of-type and only-of-type. | 1385 // Backward positional selectors include nth-last-child, nth-last-of-type, l
ast-of-type and only-of-type. |
1375 // We have to invalidate everything following the insertion point in the for
ward case, and everything before the insertion point in the | 1386 // We have to invalidate everything following the insertion point in the for
ward case, and everything before the insertion point in the |
1376 // backward case. | 1387 // backward case. |
1377 // |afterChange| is 0 in the parser callback case, so we won't do any work f
or the forward case if we don't have to. | 1388 // |afterChange| is 0 in the parser callback case, so we won't do any work f
or the forward case if we don't have to. |
1378 // For performance reasons we just mark the parent node as changed, since we
don't want to make childrenChanged O(n^2) by crawling all our kids | 1389 // For performance reasons we just mark the parent node as changed, since we
don't want to make childrenChanged O(n^2) by crawling all our kids |
1379 // here. recalcStyle will then force a walk of the children when it sees th
at this has happened. | 1390 // here. recalcStyle will then force a walk of the children when it sees th
at this has happened. |
1380 if ((style->childrenAffectedByForwardPositionalRules() && afterChange) || | 1391 if ((style->childrenAffectedByForwardPositionalRules() && afterChange) || |
1381 (style->childrenAffectedByBackwardPositionalRules() && beforeChange)) | 1392 (style->childrenAffectedByBackwardPositionalRules() && beforeChange)) |
1382 e->setNeedsStyleRecalc(); | 1393 e->setNeedsStyleRecalc(); |
(...skipping 649 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2032 #if ENABLE(SVG) | 2043 #if ENABLE(SVG) |
2033 if (isSVGElement()) | 2044 if (isSVGElement()) |
2034 return !SVGElement::isAnimatableAttribute(name); | 2045 return !SVGElement::isAnimatableAttribute(name); |
2035 #endif | 2046 #endif |
2036 | 2047 |
2037 return true; | 2048 return true; |
2038 } | 2049 } |
2039 #endif | 2050 #endif |
2040 | 2051 |
2041 } // namespace WebCore | 2052 } // namespace WebCore |
OLD | NEW |