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 Dirk Mueller (mueller@kde.org) | 4 * (C) 2001 Dirk Mueller (mueller@kde.org) |
5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2013 Apple Inc. All rights reserved. | 5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2013 Apple Inc. All rights reserved. |
6 * | 6 * |
7 * This library is free software; you can redistribute it and/or | 7 * This library is free software; you can redistribute it and/or |
8 * modify it under the terms of the GNU Library General Public | 8 * modify it under the terms of the GNU Library General Public |
9 * License as published by the Free Software Foundation; either | 9 * License as published by the Free Software Foundation; either |
10 * version 2 of the License, or (at your option) any later version. | 10 * version 2 of the License, or (at your option) any later version. |
(...skipping 1203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1214 if (element->shouldCallRecalcStyle(change)) | 1214 if (element->shouldCallRecalcStyle(change)) |
1215 element->recalcStyle(change, lastTextNode); | 1215 element->recalcStyle(change, lastTextNode); |
1216 else if (element->supportsStyleSharing()) | 1216 else if (element->supportsStyleSharing()) |
1217 styleResolver.addToStyleSharingList(*element); | 1217 styleResolver.addToStyleSharingList(*element); |
1218 if (element->layoutObject()) | 1218 if (element->layoutObject()) |
1219 lastTextNode = nullptr; | 1219 lastTextNode = nullptr; |
1220 } | 1220 } |
1221 } | 1221 } |
1222 } | 1222 } |
1223 | 1223 |
1224 void ContainerNode::checkForSiblingStyleChanges(SiblingCheckType changeType, Nod e* changedNode, Node* nodeBeforeChange, Node* nodeAfterChange) | 1224 void ContainerNode::checkForSiblingStyleChanges(SiblingCheckType changeType, Ele ment* changedElement, Node* nodeBeforeChange, Node* nodeAfterChange) |
1225 { | 1225 { |
1226 if (!inActiveDocument() || document().hasPendingForcedStyleRecalc() || getSt yleChangeType() >= SubtreeStyleChange) | 1226 if (!inActiveDocument() || document().hasPendingForcedStyleRecalc() || getSt yleChangeType() >= SubtreeStyleChange) |
1227 return; | 1227 return; |
1228 | 1228 |
1229 // Forward positional selectors include nth-child, nth-of-type, first-of-typ e and only-of-type. | 1229 if (!hasRareData() || !rareData()->hasRestyleFlag(ChildrenAffectedByStructur alRules)) |
esprehn
2016/08/08 20:07:53
hasRestyleFlag is a method on ContainerNode which
rune
2016/08/08 20:21:57
Yup. Done.
| |
1230 // The indirect adjacent selector is the ~ selector. | 1230 return; |
1231 // Backward positional selectors include nth-last-child, nth-last-of-type, l ast-of-type and only-of-type. | 1231 |
1232 // We have to invalidate everything following the insertion point in the for ward and indirect adjacent case, | 1232 // Forward positional selectors include :nth-child, :nth-of-type, |
1233 // and everything before the insertion point in the backward case. | 1233 // :first-of-type, and only-of-type. The indirect adjacent selector is the ~ |
1234 // |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. | 1234 // selector. Backward positional selectors include :nth-last-child, |
1235 // 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 | 1235 // :nth-last-of-type, :last-of-type, and :only-of-type. We have to |
1236 // here. recalcStyle will then force a walk of the children when it sees tha t this has happened. | 1236 // invalidate everything following the insertion point in the forward and |
1237 // indirect adjacent case, and everything before the insertion point in the | |
1238 // backward case. |nodeAfterChange| is nullptr in the parser callback case, | |
1239 // so we won't do any work for the forward case if we don't have to. | |
1240 // For performance reasons we just mark the parent node as changed, since we | |
1241 // don't want to make childrenChanged O(n^2) by crawling all our kids here. | |
1242 // recalcStyle will then force a walk of the children when it sees that this | |
1243 // has happened. | |
1237 if ((childrenAffectedByForwardPositionalRules() && nodeAfterChange) | 1244 if ((childrenAffectedByForwardPositionalRules() && nodeAfterChange) |
1238 || (childrenAffectedByBackwardPositionalRules() && nodeBeforeChange)) { | 1245 || (childrenAffectedByBackwardPositionalRules() && nodeBeforeChange)) { |
1239 setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::cre ate(StyleChangeReason::SiblingSelector)); | 1246 setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::cre ate(StyleChangeReason::SiblingSelector)); |
1240 return; | 1247 return; |
1241 } | 1248 } |
1242 | 1249 |
1243 // :first-child. In the parser callback case, we don't have to check anythin g, since we were right the first time. | 1250 Element* elementAfterChange = !nodeAfterChange || nodeAfterChange->isElement Node() ? toElement(nodeAfterChange) : ElementTraversal::nextSibling(*nodeAfterCh ange); |
1244 // In the DOM case, we only need to do something if |afterChange| is not 0. | 1251 Element* elementBeforeChange = !nodeBeforeChange || nodeBeforeChange->isElem entNode() ? toElement(nodeBeforeChange) : ElementTraversal::previousSibling(*nod eBeforeChange); |
1245 // |afterChange| is 0 in the parser case, so it works out that we'll skip th is block. | 1252 |
1246 if (childrenAffectedByFirstChildRules() && nodeAfterChange) { | 1253 if (childrenAffectedByFirstChildRules() && !elementBeforeChange && elementAf terChange && elementAfterChange->affectedByFirstChildRules()) { |
1247 DCHECK_NE(changeType, FinishedParsingChildren); | 1254 DCHECK_NE(changeType, FinishedParsingChildren); |
1248 // Find our new first child element. | 1255 elementAfterChange->pseudoStateChanged(CSSSelector::PseudoFirstChild); |
1249 Element* firstChildElement = ElementTraversal::firstChild(*this); | 1256 elementAfterChange->pseudoStateChanged(CSSSelector::PseudoOnlyChild); |
1250 | |
1251 // Find the first element after the change. | |
1252 Element* elementAfterChange = nodeAfterChange->isElementNode() ? toEleme nt(nodeAfterChange) : ElementTraversal::nextSibling(*nodeAfterChange); | |
1253 | |
1254 // This is the element insertion as first child element case. | |
1255 if (changeType == SiblingElementInserted && elementAfterChange && firstC hildElement != elementAfterChange | |
1256 && (!nodeBeforeChange || !nodeBeforeChange->isElementNode()) && elem entAfterChange->affectedByFirstChildRules()) { | |
1257 elementAfterChange->setNeedsStyleRecalc(SubtreeStyleChange, StyleCha ngeReasonForTracing::create(StyleChangeReason::SiblingSelector)); | |
1258 } | |
1259 | |
1260 // This is the first child element removal case. | |
1261 if (changeType == SiblingElementRemoved && firstChildElement == elementA fterChange && firstChildElement && firstChildElement->affectedByFirstChildRules( )) | |
1262 firstChildElement->setNeedsStyleRecalc(SubtreeStyleChange, StyleChan geReasonForTracing::create(StyleChangeReason::SiblingSelector)); | |
1263 } | 1257 } |
1264 | 1258 |
1265 // :last-child. In the parser callback case, we don't have to check anything , since we were right the first time. | 1259 if (childrenAffectedByLastChildRules() && !elementAfterChange && elementBefo reChange && elementBeforeChange->affectedByLastChildRules()) { |
1266 // In the DOM case, we only need to do something if |afterChange| is not 0. | 1260 elementBeforeChange->pseudoStateChanged(CSSSelector::PseudoLastChild); |
1267 if (childrenAffectedByLastChildRules() && nodeBeforeChange) { | 1261 elementBeforeChange->pseudoStateChanged(CSSSelector::PseudoOnlyChild); |
1268 // Find our new last child element. | |
1269 Element* lastChildElement = ElementTraversal::lastChild(*this); | |
1270 | |
1271 // Find the last element before the change. | |
1272 Element* elementBeforeChange = nodeBeforeChange->isElementNode() ? toEle ment(nodeBeforeChange) : ElementTraversal::previousSibling(*nodeBeforeChange); | |
1273 | |
1274 // This is the element insertion as last child element case. | |
1275 if (changeType == SiblingElementInserted && elementBeforeChange && lastC hildElement != elementBeforeChange | |
1276 && (!nodeAfterChange || !nodeAfterChange->isElementNode()) && elemen tBeforeChange->affectedByLastChildRules()) { | |
1277 elementBeforeChange->setNeedsStyleRecalc(SubtreeStyleChange, StyleCh angeReasonForTracing::create(StyleChangeReason::SiblingSelector)); | |
1278 } | |
1279 | |
1280 // This is the last child element removal case. The parser callback case is similar to node removal as well in that we need to change the last child | |
1281 // to match now. | |
1282 if ((changeType == SiblingElementRemoved || changeType == FinishedParsin gChildren) && lastChildElement == elementBeforeChange && lastChildElement && las tChildElement->affectedByLastChildRules()) | |
1283 lastChildElement->setNeedsStyleRecalc(SubtreeStyleChange, StyleChang eReasonForTracing::create(StyleChangeReason::SiblingSelector)); | |
1284 } | 1262 } |
1285 | 1263 |
1286 // For ~ and + combinators, succeeding siblings may need style invalidation | 1264 // For ~ and + combinators, succeeding siblings may need style invalidation |
1287 // after an element is inserted or removed. | 1265 // after an element is inserted or removed. |
1288 | 1266 |
1289 if (!nodeAfterChange) | 1267 if (!elementAfterChange) |
1290 return; | 1268 return; |
1291 if (changeType != SiblingElementRemoved && changeType != SiblingElementInser ted) | 1269 |
1292 return; | |
1293 if (!childrenAffectedByIndirectAdjacentRules() && !childrenAffectedByDirectA djacentRules()) | 1270 if (!childrenAffectedByIndirectAdjacentRules() && !childrenAffectedByDirectA djacentRules()) |
1294 return; | 1271 return; |
1295 | 1272 |
1296 Element* elementAfterChange = nodeAfterChange->isElementNode() ? toElement(n odeAfterChange) : ElementTraversal::nextSibling(*nodeAfterChange); | 1273 if (changeType == SiblingElementInserted) { |
1297 if (!elementAfterChange) | 1274 document().styleEngine().scheduleInvalidationsForInsertedSibling(element BeforeChange, *changedElement); |
1298 return; | 1275 return; |
1299 Element* elementBeforeChange = nullptr; | 1276 } |
1300 if (nodeBeforeChange) | |
1301 elementBeforeChange = nodeBeforeChange->isElementNode() ? toElement(node BeforeChange) : ElementTraversal::previousSibling(*nodeBeforeChange); | |
1302 | 1277 |
1303 if (changeType == SiblingElementInserted) | 1278 DCHECK(changeType == SiblingElementRemoved); |
1304 document().styleEngine().scheduleInvalidationsForInsertedSibling(element BeforeChange, *toElement(changedNode)); | 1279 document().styleEngine().scheduleInvalidationsForRemovedSibling(elementBefor eChange, *changedElement, *elementAfterChange); |
1305 else | |
1306 document().styleEngine().scheduleInvalidationsForRemovedSibling(elementB eforeChange, *toElement(changedNode), *elementAfterChange); | |
1307 } | 1280 } |
1308 | 1281 |
1309 void ContainerNode::invalidateNodeListCachesInAncestors(const QualifiedName* att rName, Element* attributeOwnerElement) | 1282 void ContainerNode::invalidateNodeListCachesInAncestors(const QualifiedName* att rName, Element* attributeOwnerElement) |
1310 { | 1283 { |
1311 if (hasRareData() && (!attrName || isAttributeNode())) { | 1284 if (hasRareData() && (!attrName || isAttributeNode())) { |
1312 if (NodeListsNodeData* lists = rareData()->nodeLists()) { | 1285 if (NodeListsNodeData* lists = rareData()->nodeLists()) { |
1313 if (ChildNodeList* childNodeList = lists->childNodeList(*this)) | 1286 if (ChildNodeList* childNodeList = lists->childNodeList(*this)) |
1314 childNodeList->invalidateCache(); | 1287 childNodeList->invalidateCache(); |
1315 } | 1288 } |
1316 } | 1289 } |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1404 return true; | 1377 return true; |
1405 | 1378 |
1406 if (node->isElementNode() && toElement(node)->shadow()) | 1379 if (node->isElementNode() && toElement(node)->shadow()) |
1407 return true; | 1380 return true; |
1408 | 1381 |
1409 return false; | 1382 return false; |
1410 } | 1383 } |
1411 #endif | 1384 #endif |
1412 | 1385 |
1413 } // namespace blink | 1386 } // namespace blink |
OLD | NEW |