| 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 1287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1298 ASSERT(isElementNode() || isShadowRoot()); | 1298 ASSERT(isElementNode() || isShadowRoot()); |
| 1299 ensureRareData().setRestyleFlag(mask); | 1299 ensureRareData().setRestyleFlag(mask); |
| 1300 } | 1300 } |
| 1301 | 1301 |
| 1302 void ContainerNode::recalcChildStyle(StyleRecalcChange change) | 1302 void ContainerNode::recalcChildStyle(StyleRecalcChange change) |
| 1303 { | 1303 { |
| 1304 ASSERT(document().inStyleRecalc()); | 1304 ASSERT(document().inStyleRecalc()); |
| 1305 ASSERT(change >= UpdatePseudoElements || childNeedsStyleRecalc()); | 1305 ASSERT(change >= UpdatePseudoElements || childNeedsStyleRecalc()); |
| 1306 ASSERT(!needsStyleRecalc()); | 1306 ASSERT(!needsStyleRecalc()); |
| 1307 | 1307 |
| 1308 if (change < Force && hasRareData() && childNeedsStyleRecalc()) | |
| 1309 checkForChildrenAdjacentRuleChanges(); | |
| 1310 | |
| 1311 // This loop is deliberately backwards because we use insertBefore in the la
yout tree, and want to avoid | 1308 // This loop is deliberately backwards because we use insertBefore in the la
yout tree, and want to avoid |
| 1312 // a potentially n^2 loop to find the insertion point while resolving style.
Having us start from the last | 1309 // a potentially n^2 loop to find the insertion point while resolving style.
Having us start from the last |
| 1313 // child and work our way back means in the common case, we'll find the inse
rtion point in O(1) time. | 1310 // child and work our way back means in the common case, we'll find the inse
rtion point in O(1) time. |
| 1314 // See crbug.com/288225 | 1311 // See crbug.com/288225 |
| 1315 StyleResolver& styleResolver = document().ensureStyleResolver(); | 1312 StyleResolver& styleResolver = document().ensureStyleResolver(); |
| 1316 Text* lastTextNode = nullptr; | 1313 Text* lastTextNode = nullptr; |
| 1317 for (Node* child = lastChild(); child; child = child->previousSibling()) { | 1314 for (Node* child = lastChild(); child; child = child->previousSibling()) { |
| 1318 if (child->isTextNode()) { | 1315 if (child->isTextNode()) { |
| 1319 toText(child)->recalcTextStyle(change, lastTextNode); | 1316 toText(child)->recalcTextStyle(change, lastTextNode); |
| 1320 lastTextNode = toText(child); | 1317 lastTextNode = toText(child); |
| 1321 } else if (child->isElementNode()) { | 1318 } else if (child->isElementNode()) { |
| 1322 Element* element = toElement(child); | 1319 Element* element = toElement(child); |
| 1323 if (element->shouldCallRecalcStyle(change)) | 1320 if (element->shouldCallRecalcStyle(change)) |
| 1324 element->recalcStyle(change, lastTextNode); | 1321 element->recalcStyle(change, lastTextNode); |
| 1325 else if (element->supportsStyleSharing()) | 1322 else if (element->supportsStyleSharing()) |
| 1326 styleResolver.addToStyleSharingList(*element); | 1323 styleResolver.addToStyleSharingList(*element); |
| 1327 if (element->layoutObject()) | 1324 if (element->layoutObject()) |
| 1328 lastTextNode = nullptr; | 1325 lastTextNode = nullptr; |
| 1329 } | 1326 } |
| 1330 } | 1327 } |
| 1331 } | 1328 } |
| 1332 | 1329 |
| 1333 void ContainerNode::checkForChildrenAdjacentRuleChanges() | |
| 1334 { | |
| 1335 bool hasDirectAdjacentRules = childrenAffectedByDirectAdjacentRules(); | |
| 1336 bool hasIndirectAdjacentRules = childrenAffectedByIndirectAdjacentRules(); | |
| 1337 | |
| 1338 if (!hasDirectAdjacentRules && !hasIndirectAdjacentRules) | |
| 1339 return; | |
| 1340 | |
| 1341 unsigned forceCheckOfNextElementCount = 0; | |
| 1342 bool forceCheckOfAnyElementSibling = false; | |
| 1343 Document& document = this->document(); | |
| 1344 | |
| 1345 for (Element* child = ElementTraversal::firstChild(*this); child; child = El
ementTraversal::nextSibling(*child)) { | |
| 1346 bool childRulesChanged = child->needsStyleRecalc() && child->styleChange
Type() >= SubtreeStyleChange; | |
| 1347 | |
| 1348 if (forceCheckOfNextElementCount || forceCheckOfAnyElementSibling) | |
| 1349 child->setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForT
racing::create(StyleChangeReason::SiblingSelector)); | |
| 1350 | |
| 1351 if (childRulesChanged && hasDirectAdjacentRules) | |
| 1352 forceCheckOfNextElementCount = document.styleEngine().maxDirectAdjac
entSelectors(); | |
| 1353 else if (forceCheckOfNextElementCount) | |
| 1354 --forceCheckOfNextElementCount; | |
| 1355 | |
| 1356 forceCheckOfAnyElementSibling = forceCheckOfAnyElementSibling || (childR
ulesChanged && hasIndirectAdjacentRules); | |
| 1357 } | |
| 1358 } | |
| 1359 | |
| 1360 void ContainerNode::checkForSiblingStyleChanges(SiblingCheckType changeType, Nod
e* nodeBeforeChange, Node* nodeAfterChange) | 1330 void ContainerNode::checkForSiblingStyleChanges(SiblingCheckType changeType, Nod
e* nodeBeforeChange, Node* nodeAfterChange) |
| 1361 { | 1331 { |
| 1362 if (!inActiveDocument() || document().hasPendingForcedStyleRecalc() || style
ChangeType() >= SubtreeStyleChange) | 1332 if (!inActiveDocument() || document().hasPendingForcedStyleRecalc() || style
ChangeType() >= SubtreeStyleChange) |
| 1363 return; | 1333 return; |
| 1364 | 1334 |
| 1365 // Forward positional selectors include nth-child, nth-of-type, first-of-typ
e and only-of-type. | 1335 // Forward positional selectors include nth-child, nth-of-type, first-of-typ
e and only-of-type. |
| 1366 // The indirect adjacent selector is the ~ selector. | 1336 // The indirect adjacent selector is the ~ selector. |
| 1367 // Backward positional selectors include nth-last-child, nth-last-of-type, l
ast-of-type and only-of-type. | 1337 // Backward positional selectors include nth-last-child, nth-last-of-type, l
ast-of-type and only-of-type. |
| 1368 // We have to invalidate everything following the insertion point in the for
ward and indirect adjacent case, | 1338 // We have to invalidate everything following the insertion point in the for
ward and indirect adjacent case, |
| 1369 // and everything before the insertion point in the backward case. | 1339 // and everything before the insertion point in the backward case. |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1415 | 1385 |
| 1416 // 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 | 1386 // 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 |
| 1417 // to match now. | 1387 // to match now. |
| 1418 if ((changeType == SiblingElementRemoved || changeType == FinishedParsin
gChildren) && lastChildElement == elementBeforeChange && lastChildElement && las
tChildElement->affectedByLastChildRules()) | 1388 if ((changeType == SiblingElementRemoved || changeType == FinishedParsin
gChildren) && lastChildElement == elementBeforeChange && lastChildElement && las
tChildElement->affectedByLastChildRules()) |
| 1419 lastChildElement->setNeedsStyleRecalc(SubtreeStyleChange, StyleChang
eReasonForTracing::create(StyleChangeReason::SiblingSelector)); | 1389 lastChildElement->setNeedsStyleRecalc(SubtreeStyleChange, StyleChang
eReasonForTracing::create(StyleChangeReason::SiblingSelector)); |
| 1420 } | 1390 } |
| 1421 | 1391 |
| 1422 // The + selector. We need to invalidate the first element following the cha
nge. It is the only possible element | 1392 // The + selector. We need to invalidate the first element following the cha
nge. It is the only possible element |
| 1423 // that could be affected by this DOM change. | 1393 // that could be affected by this DOM change. |
| 1424 if (childrenAffectedByDirectAdjacentRules() && nodeAfterChange) { | 1394 if (childrenAffectedByDirectAdjacentRules() && nodeAfterChange) { |
| 1425 if (Element* elementAfterChange = nodeAfterChange->isElementNode() ? toE
lement(nodeAfterChange) : ElementTraversal::nextSibling(*nodeAfterChange)) | 1395 Element* elementAfterChange = nodeAfterChange->isElementNode() ? toEleme
nt(nodeAfterChange) : ElementTraversal::nextSibling(*nodeAfterChange); |
| 1396 for (unsigned i = document().styleEngine().maxDirectAdjacentSelectors();
i && elementAfterChange; --i, elementAfterChange = ElementTraversal::nextSiblin
g(*elementAfterChange)) |
| 1426 elementAfterChange->setNeedsStyleRecalc(SubtreeStyleChange, StyleCha
ngeReasonForTracing::create(StyleChangeReason::SiblingSelector)); | 1397 elementAfterChange->setNeedsStyleRecalc(SubtreeStyleChange, StyleCha
ngeReasonForTracing::create(StyleChangeReason::SiblingSelector)); |
| 1427 } | 1398 } |
| 1428 } | 1399 } |
| 1429 | 1400 |
| 1430 void ContainerNode::invalidateNodeListCachesInAncestors(const QualifiedName* att
rName, Element* attributeOwnerElement) | 1401 void ContainerNode::invalidateNodeListCachesInAncestors(const QualifiedName* att
rName, Element* attributeOwnerElement) |
| 1431 { | 1402 { |
| 1432 if (hasRareData() && (!attrName || isAttributeNode())) { | 1403 if (hasRareData() && (!attrName || isAttributeNode())) { |
| 1433 if (NodeListsNodeData* lists = rareData()->nodeLists()) { | 1404 if (NodeListsNodeData* lists = rareData()->nodeLists()) { |
| 1434 if (ChildNodeList* childNodeList = lists->childNodeList(*this)) | 1405 if (ChildNodeList* childNodeList = lists->childNodeList(*this)) |
| 1435 childNodeList->invalidateCache(); | 1406 childNodeList->invalidateCache(); |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1528 return true; | 1499 return true; |
| 1529 | 1500 |
| 1530 if (node->isElementNode() && toElement(node)->shadow()) | 1501 if (node->isElementNode() && toElement(node)->shadow()) |
| 1531 return true; | 1502 return true; |
| 1532 | 1503 |
| 1533 return false; | 1504 return false; |
| 1534 } | 1505 } |
| 1535 #endif | 1506 #endif |
| 1536 | 1507 |
| 1537 } // namespace blink | 1508 } // namespace blink |
| OLD | NEW |