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 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
400 return child; | 400 return child; |
401 } | 401 } |
402 | 402 |
403 void ContainerNode::willRemoveChild(Node& child) | 403 void ContainerNode::willRemoveChild(Node& child) |
404 { | 404 { |
405 DCHECK_EQ(child.parentNode(), this); | 405 DCHECK_EQ(child.parentNode(), this); |
406 ChildListMutationScope(*this).willRemoveChild(child); | 406 ChildListMutationScope(*this).willRemoveChild(child); |
407 child.notifyMutationObserversNodeWillDetach(); | 407 child.notifyMutationObserversNodeWillDetach(); |
408 dispatchChildRemovalEvents(child); | 408 dispatchChildRemovalEvents(child); |
409 ChildFrameDisconnector(child).disconnect(); | 409 ChildFrameDisconnector(child).disconnect(); |
| 410 document().styleEngine().willRemoveChild(child); |
410 if (document() != child.document()) { | 411 if (document() != child.document()) { |
411 // |child| was moved another document by DOM mutation event handler. | 412 // |child| was moved another document by DOM mutation event handler. |
412 return; | 413 return; |
413 } | 414 } |
414 | 415 |
415 // |nodeWillBeRemoved()| must be run after |ChildFrameDisconnector|, because | 416 // |nodeWillBeRemoved()| must be run after |ChildFrameDisconnector|, because |
416 // |ChildFrameDisconnector| can run script which may cause state that is to | 417 // |ChildFrameDisconnector| can run script which may cause state that is to |
417 // be invalidated by removing the node. | 418 // be invalidated by removing the node. |
418 ScriptForbiddenScope scriptForbiddenScope; | 419 ScriptForbiddenScope scriptForbiddenScope; |
419 EventDispatchForbiddenScope assertNoEventDispatch; | 420 EventDispatchForbiddenScope assertNoEventDispatch; |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
581 { | 582 { |
582 EventDispatchForbiddenScope assertNoEventDispatch; | 583 EventDispatchForbiddenScope assertNoEventDispatch; |
583 ScriptForbiddenScope forbidScript; | 584 ScriptForbiddenScope forbidScript; |
584 | 585 |
585 while (Node* child = m_firstChild) { | 586 while (Node* child = m_firstChild) { |
586 removeBetween(0, child->nextSibling(), *child); | 587 removeBetween(0, child->nextSibling(), *child); |
587 notifyNodeRemoved(*child); | 588 notifyNodeRemoved(*child); |
588 } | 589 } |
589 } | 590 } |
590 | 591 |
591 ChildrenChange change = {AllChildrenRemoved, nullptr, nullptr, ChildrenC
hangeSourceAPI}; | 592 ChildrenChange change = {AllChildrenRemoved, nullptr, nullptr, nullptr,
ChildrenChangeSourceAPI}; |
592 childrenChanged(change); | 593 childrenChanged(change); |
593 } | 594 } |
594 | 595 |
595 if (action == DispatchSubtreeModifiedEvent) | 596 if (action == DispatchSubtreeModifiedEvent) |
596 dispatchSubtreeModifiedEvent(); | 597 dispatchSubtreeModifiedEvent(); |
597 } | 598 } |
598 | 599 |
599 Node* ContainerNode::appendChild(Node* newChild, ExceptionState& exceptionState) | 600 Node* ContainerNode::appendChild(Node* newChild, ExceptionState& exceptionState) |
600 { | 601 { |
601 | 602 |
(...skipping 607 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1209 if (element->shouldCallRecalcStyle(change)) | 1210 if (element->shouldCallRecalcStyle(change)) |
1210 element->recalcStyle(change, lastTextNode); | 1211 element->recalcStyle(change, lastTextNode); |
1211 else if (element->supportsStyleSharing()) | 1212 else if (element->supportsStyleSharing()) |
1212 styleResolver.addToStyleSharingList(*element); | 1213 styleResolver.addToStyleSharingList(*element); |
1213 if (element->layoutObject()) | 1214 if (element->layoutObject()) |
1214 lastTextNode = nullptr; | 1215 lastTextNode = nullptr; |
1215 } | 1216 } |
1216 } | 1217 } |
1217 } | 1218 } |
1218 | 1219 |
1219 void ContainerNode::checkForSiblingStyleChanges(SiblingCheckType changeType, Nod
e* nodeBeforeChange, Node* nodeAfterChange) | 1220 void ContainerNode::checkForSiblingStyleChanges(SiblingCheckType changeType, Nod
e* changedNode, Node* nodeBeforeChange, Node* nodeAfterChange) |
1220 { | 1221 { |
1221 if (!inActiveDocument() || document().hasPendingForcedStyleRecalc() || getSt
yleChangeType() >= SubtreeStyleChange) | 1222 if (!inActiveDocument() || document().hasPendingForcedStyleRecalc() || getSt
yleChangeType() >= SubtreeStyleChange) |
1222 return; | 1223 return; |
1223 | 1224 |
1224 // Forward positional selectors include nth-child, nth-of-type, first-of-typ
e and only-of-type. | 1225 // Forward positional selectors include nth-child, nth-of-type, first-of-typ
e and only-of-type. |
1225 // The indirect adjacent selector is the ~ selector. | 1226 // The indirect adjacent selector is the ~ selector. |
1226 // Backward positional selectors include nth-last-child, nth-last-of-type, l
ast-of-type and only-of-type. | 1227 // Backward positional selectors include nth-last-child, nth-last-of-type, l
ast-of-type and only-of-type. |
1227 // We have to invalidate everything following the insertion point in the for
ward and indirect adjacent case, | 1228 // We have to invalidate everything following the insertion point in the for
ward and indirect adjacent case, |
1228 // and everything before the insertion point in the backward case. | 1229 // and everything before the insertion point in the backward case. |
1229 // |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. | 1230 // |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. |
1230 // 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 | 1231 // 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 |
1231 // here. recalcStyle will then force a walk of the children when it sees tha
t this has happened. | 1232 // here. recalcStyle will then force a walk of the children when it sees tha
t this has happened. |
1232 if (((childrenAffectedByForwardPositionalRules() || childrenAffectedByIndire
ctAdjacentRules()) && nodeAfterChange) | 1233 if ((childrenAffectedByForwardPositionalRules() && nodeAfterChange) |
1233 || (childrenAffectedByBackwardPositionalRules() && nodeBeforeChange)) { | 1234 || (childrenAffectedByBackwardPositionalRules() && nodeBeforeChange)) { |
1234 setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::cre
ate(StyleChangeReason::SiblingSelector)); | 1235 setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::cre
ate(StyleChangeReason::SiblingSelector)); |
1235 return; | 1236 return; |
1236 } | 1237 } |
1237 | 1238 |
1238 // :first-child. In the parser callback case, we don't have to check anythin
g, since we were right the first time. | 1239 // :first-child. In the parser callback case, we don't have to check anythin
g, since we were right the first time. |
1239 // In the DOM case, we only need to do something if |afterChange| is not 0. | 1240 // In the DOM case, we only need to do something if |afterChange| is not 0. |
1240 // |afterChange| is 0 in the parser case, so it works out that we'll skip th
is block. | 1241 // |afterChange| is 0 in the parser case, so it works out that we'll skip th
is block. |
1241 if (childrenAffectedByFirstChildRules() && nodeAfterChange) { | 1242 if (childrenAffectedByFirstChildRules() && nodeAfterChange) { |
1242 DCHECK_NE(changeType, FinishedParsingChildren); | 1243 DCHECK_NE(changeType, FinishedParsingChildren); |
(...skipping 28 matching lines...) Expand all Loading... |
1271 && (!nodeAfterChange || !nodeAfterChange->isElementNode()) && elemen
tBeforeChange->affectedByLastChildRules()) { | 1272 && (!nodeAfterChange || !nodeAfterChange->isElementNode()) && elemen
tBeforeChange->affectedByLastChildRules()) { |
1272 elementBeforeChange->setNeedsStyleRecalc(SubtreeStyleChange, StyleCh
angeReasonForTracing::create(StyleChangeReason::SiblingSelector)); | 1273 elementBeforeChange->setNeedsStyleRecalc(SubtreeStyleChange, StyleCh
angeReasonForTracing::create(StyleChangeReason::SiblingSelector)); |
1273 } | 1274 } |
1274 | 1275 |
1275 // 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 | 1276 // 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 |
1276 // to match now. | 1277 // to match now. |
1277 if ((changeType == SiblingElementRemoved || changeType == FinishedParsin
gChildren) && lastChildElement == elementBeforeChange && lastChildElement && las
tChildElement->affectedByLastChildRules()) | 1278 if ((changeType == SiblingElementRemoved || changeType == FinishedParsin
gChildren) && lastChildElement == elementBeforeChange && lastChildElement && las
tChildElement->affectedByLastChildRules()) |
1278 lastChildElement->setNeedsStyleRecalc(SubtreeStyleChange, StyleChang
eReasonForTracing::create(StyleChangeReason::SiblingSelector)); | 1279 lastChildElement->setNeedsStyleRecalc(SubtreeStyleChange, StyleChang
eReasonForTracing::create(StyleChangeReason::SiblingSelector)); |
1279 } | 1280 } |
1280 | 1281 |
1281 // The + selector. We need to invalidate the first element following the cha
nge. It is the only possible element | 1282 // For ~ and + combinators, succeeding siblings may need style invalidation |
1282 // that could be affected by this DOM change. | 1283 // after an element is inserted or removed. |
1283 if (childrenAffectedByDirectAdjacentRules() && nodeAfterChange) { | 1284 |
1284 Element* elementAfterChange = nodeAfterChange->isElementNode() ? toEleme
nt(nodeAfterChange) : ElementTraversal::nextSibling(*nodeAfterChange); | 1285 if (!nodeAfterChange) |
1285 for (unsigned i = document().styleEngine().maxDirectAdjacentSelectors();
i && elementAfterChange; --i, elementAfterChange = ElementTraversal::nextSiblin
g(*elementAfterChange)) | 1286 return; |
1286 elementAfterChange->setNeedsStyleRecalc(SubtreeStyleChange, StyleCha
ngeReasonForTracing::create(StyleChangeReason::SiblingSelector)); | 1287 if (changeType != SiblingElementRemoved && changeType != SiblingElementInser
ted) |
1287 } | 1288 return; |
| 1289 if (!childrenAffectedByIndirectAdjacentRules() && !childrenAffectedByDirectA
djacentRules()) |
| 1290 return; |
| 1291 |
| 1292 Element* elementAfterChange = nodeAfterChange->isElementNode() ? toElement(n
odeAfterChange) : ElementTraversal::nextSibling(*nodeAfterChange); |
| 1293 if (!elementAfterChange) |
| 1294 return; |
| 1295 Element* elementBeforeChange = nullptr; |
| 1296 if (nodeBeforeChange) |
| 1297 elementBeforeChange = nodeBeforeChange->isElementNode() ? toElement(node
BeforeChange) : ElementTraversal::previousSibling(*nodeBeforeChange); |
| 1298 |
| 1299 if (changeType == SiblingElementInserted) |
| 1300 document().styleEngine().scheduleInvalidationsForInsertedSibling(element
BeforeChange, *toElement(changedNode)); |
| 1301 else |
| 1302 document().styleEngine().scheduleInvalidationsForRemovedSibling(elementB
eforeChange, *toElement(changedNode), *elementAfterChange); |
1288 } | 1303 } |
1289 | 1304 |
1290 void ContainerNode::invalidateNodeListCachesInAncestors(const QualifiedName* att
rName, Element* attributeOwnerElement) | 1305 void ContainerNode::invalidateNodeListCachesInAncestors(const QualifiedName* att
rName, Element* attributeOwnerElement) |
1291 { | 1306 { |
1292 if (hasRareData() && (!attrName || isAttributeNode())) { | 1307 if (hasRareData() && (!attrName || isAttributeNode())) { |
1293 if (NodeListsNodeData* lists = rareData()->nodeLists()) { | 1308 if (NodeListsNodeData* lists = rareData()->nodeLists()) { |
1294 if (ChildNodeList* childNodeList = lists->childNodeList(*this)) | 1309 if (ChildNodeList* childNodeList = lists->childNodeList(*this)) |
1295 childNodeList->invalidateCache(); | 1310 childNodeList->invalidateCache(); |
1296 } | 1311 } |
1297 } | 1312 } |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1385 return true; | 1400 return true; |
1386 | 1401 |
1387 if (node->isElementNode() && toElement(node)->shadow()) | 1402 if (node->isElementNode() && toElement(node)->shadow()) |
1388 return true; | 1403 return true; |
1389 | 1404 |
1390 return false; | 1405 return false; |
1391 } | 1406 } |
1392 #endif | 1407 #endif |
1393 | 1408 |
1394 } // namespace blink | 1409 } // namespace blink |
OLD | NEW |