Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(60)

Side by Side Diff: third_party/WebKit/Source/core/dom/ContainerNode.cpp

Issue 1509853002: Remove checkForChildrenAdjacentRuleChanges. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Might need to schedule sibling invalidation sets for SubtreeStyleChange Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 1062 matching lines...) Expand 10 before | Expand all | Expand 10 after
1073 1073
1074 // This is used by FrameSelection to denote when the active-state of the page ha s changed 1074 // This is used by FrameSelection to denote when the active-state of the page ha s changed
1075 // independent of the focused element changing. 1075 // independent of the focused element changing.
1076 void ContainerNode::focusStateChanged() 1076 void ContainerNode::focusStateChanged()
1077 { 1077 {
1078 // If we're just changing the window's active state and the focused node has no 1078 // If we're just changing the window's active state and the focused node has no
1079 // layoutObject we can just ignore the state change. 1079 // layoutObject we can just ignore the state change.
1080 if (!layoutObject()) 1080 if (!layoutObject())
1081 return; 1081 return;
1082 1082
1083 if (computedStyle()->affectedByFocus() && computedStyle()->hasPseudoStyle(FI RST_LETTER)) 1083 if (computedStyle()->affectedByFocus()) {
1084 setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::cre ateWithExtraData(StyleChangeReason::PseudoClass, StyleChangeExtraData::Focus)); 1084 StyleChangeType changeType = computedStyle()->hasPseudoStyle(FIRST_LETTE R) ? SubtreeStyleChange : LocalStyleChange;
1085 else if (isElementNode() && toElement(this)->childrenOrSiblingsAffectedByFoc us()) 1085 setNeedsStyleRecalc(changeType, StyleChangeReasonForTracing::createWithE xtraData(StyleChangeReason::PseudoClass, StyleChangeExtraData::Focus));
1086 }
1087 if (isElementNode() && toElement(this)->childrenOrSiblingsAffectedByFocus())
1086 toElement(this)->pseudoStateChanged(CSSSelector::PseudoFocus); 1088 toElement(this)->pseudoStateChanged(CSSSelector::PseudoFocus);
1087 else if (computedStyle()->affectedByFocus())
1088 setNeedsStyleRecalc(LocalStyleChange, StyleChangeReasonForTracing::creat eWithExtraData(StyleChangeReason::PseudoClass, StyleChangeExtraData::Focus));
1089 1089
1090 LayoutTheme::theme().controlStateChanged(*layoutObject(), FocusControlState) ; 1090 LayoutTheme::theme().controlStateChanged(*layoutObject(), FocusControlState) ;
1091 } 1091 }
1092 1092
1093 void ContainerNode::setFocus(bool received) 1093 void ContainerNode::setFocus(bool received)
1094 { 1094 {
1095 // Recurse up author shadow trees to mark shadow hosts if it matches :focus. 1095 // Recurse up author shadow trees to mark shadow hosts if it matches :focus.
1096 // TODO(kochi): Handle UA shadows which marks multiple nodes as focused such as 1096 // TODO(kochi): Handle UA shadows which marks multiple nodes as focused such as
1097 // <input type="date"> the same way as author shadow. 1097 // <input type="date"> the same way as author shadow.
1098 if (ShadowRoot* root = containingShadowRoot()) { 1098 if (ShadowRoot* root = containingShadowRoot()) {
(...skipping 27 matching lines...) Expand all
1126 1126
1127 void ContainerNode::setActive(bool down) 1127 void ContainerNode::setActive(bool down)
1128 { 1128 {
1129 if (down == active()) 1129 if (down == active())
1130 return; 1130 return;
1131 1131
1132 Node::setActive(down); 1132 Node::setActive(down);
1133 1133
1134 // FIXME: Why does this not need to handle the display: none transition like :hover does? 1134 // FIXME: Why does this not need to handle the display: none transition like :hover does?
1135 if (layoutObject()) { 1135 if (layoutObject()) {
1136 if (computedStyle()->affectedByActive() && computedStyle()->hasPseudoSty le(FIRST_LETTER)) 1136 if (computedStyle()->affectedByActive()) {
1137 setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing: :createWithExtraData(StyleChangeReason::PseudoClass, StyleChangeExtraData::Activ e)); 1137 StyleChangeType changeType = computedStyle()->hasPseudoStyle(FIRST_L ETTER) ? SubtreeStyleChange : LocalStyleChange;
1138 else if (isElementNode() && toElement(this)->childrenOrSiblingsAffectedB yActive()) 1138 setNeedsStyleRecalc(changeType, StyleChangeReasonForTracing::createW ithExtraData(StyleChangeReason::PseudoClass, StyleChangeExtraData::Active));
1139 }
1140 if (isElementNode() && toElement(this)->childrenOrSiblingsAffectedByActi ve())
1139 toElement(this)->pseudoStateChanged(CSSSelector::PseudoActive); 1141 toElement(this)->pseudoStateChanged(CSSSelector::PseudoActive);
1140 else if (computedStyle()->affectedByActive())
1141 setNeedsStyleRecalc(LocalStyleChange, StyleChangeReasonForTracing::c reateWithExtraData(StyleChangeReason::PseudoClass, StyleChangeExtraData::Active) );
1142 1142
1143 LayoutTheme::theme().controlStateChanged(*layoutObject(), PressedControl State); 1143 LayoutTheme::theme().controlStateChanged(*layoutObject(), PressedControl State);
1144 } 1144 }
1145 } 1145 }
1146 1146
1147 void ContainerNode::setHovered(bool over) 1147 void ContainerNode::setHovered(bool over)
1148 { 1148 {
1149 if (over == hovered()) 1149 if (over == hovered())
1150 return; 1150 return;
1151 1151
1152 Node::setHovered(over); 1152 Node::setHovered(over);
1153 1153
1154 // If :hover sets display: none we lose our hover but still need to recalc o ur style. 1154 // If :hover sets display: none we lose our hover but still need to recalc o ur style.
1155 if (!layoutObject()) { 1155 if (!layoutObject()) {
1156 if (over) 1156 if (over)
1157 return; 1157 return;
1158 if (isElementNode() && toElement(this)->childrenOrSiblingsAffectedByHove r()) 1158 if (isElementNode() && toElement(this)->childrenOrSiblingsAffectedByHove r())
1159 toElement(this)->pseudoStateChanged(CSSSelector::PseudoHover); 1159 toElement(this)->pseudoStateChanged(CSSSelector::PseudoHover);
1160 else 1160 else
1161 setNeedsStyleRecalc(LocalStyleChange, StyleChangeReasonForTracing::c reateWithExtraData(StyleChangeReason::PseudoClass, StyleChangeExtraData::Hover)) ; 1161 setNeedsStyleRecalc(LocalStyleChange, StyleChangeReasonForTracing::c reateWithExtraData(StyleChangeReason::PseudoClass, StyleChangeExtraData::Hover)) ;
1162 return; 1162 return;
1163 } 1163 }
1164 1164
1165 if (computedStyle()->affectedByHover() && computedStyle()->hasPseudoStyle(FI RST_LETTER)) 1165 if (computedStyle()->affectedByHover()) {
1166 setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::cre ateWithExtraData(StyleChangeReason::PseudoClass, StyleChangeExtraData::Hover)); 1166 StyleChangeType changeType = computedStyle()->hasPseudoStyle(FIRST_LETTE R) ? SubtreeStyleChange : LocalStyleChange;
1167 else if (isElementNode() && toElement(this)->childrenOrSiblingsAffectedByHov er()) 1167 setNeedsStyleRecalc(changeType, StyleChangeReasonForTracing::createWithE xtraData(StyleChangeReason::PseudoClass, StyleChangeExtraData::Hover));
1168 }
1169 if (isElementNode() && toElement(this)->childrenOrSiblingsAffectedByHover())
1168 toElement(this)->pseudoStateChanged(CSSSelector::PseudoHover); 1170 toElement(this)->pseudoStateChanged(CSSSelector::PseudoHover);
1169 else if (computedStyle()->affectedByHover())
1170 setNeedsStyleRecalc(LocalStyleChange, StyleChangeReasonForTracing::creat eWithExtraData(StyleChangeReason::PseudoClass, StyleChangeExtraData::Hover));
1171 1171
1172 LayoutTheme::theme().controlStateChanged(*layoutObject(), HoverControlState) ; 1172 LayoutTheme::theme().controlStateChanged(*layoutObject(), HoverControlState) ;
1173 } 1173 }
1174 1174
1175 PassRefPtrWillBeRawPtr<HTMLCollection> ContainerNode::children() 1175 PassRefPtrWillBeRawPtr<HTMLCollection> ContainerNode::children()
1176 { 1176 {
1177 return ensureCachedCollection<HTMLCollection>(NodeChildren); 1177 return ensureCachedCollection<HTMLCollection>(NodeChildren);
1178 } 1178 }
1179 1179
1180 unsigned ContainerNode::countChildren() const 1180 unsigned ContainerNode::countChildren() const
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1293 ASSERT(isElementNode() || isShadowRoot()); 1293 ASSERT(isElementNode() || isShadowRoot());
1294 ensureRareData().setRestyleFlag(mask); 1294 ensureRareData().setRestyleFlag(mask);
1295 } 1295 }
1296 1296
1297 void ContainerNode::recalcChildStyle(StyleRecalcChange change) 1297 void ContainerNode::recalcChildStyle(StyleRecalcChange change)
1298 { 1298 {
1299 ASSERT(document().inStyleRecalc()); 1299 ASSERT(document().inStyleRecalc());
1300 ASSERT(change >= UpdatePseudoElements || childNeedsStyleRecalc()); 1300 ASSERT(change >= UpdatePseudoElements || childNeedsStyleRecalc());
1301 ASSERT(!needsStyleRecalc()); 1301 ASSERT(!needsStyleRecalc());
1302 1302
1303 if (change < Force && hasRareData() && childNeedsStyleRecalc())
1304 checkForChildrenAdjacentRuleChanges();
1305
1306 // This loop is deliberately backwards because we use insertBefore in the la yout tree, and want to avoid 1303 // This loop is deliberately backwards because we use insertBefore in the la yout tree, and want to avoid
1307 // a potentially n^2 loop to find the insertion point while resolving style. Having us start from the last 1304 // a potentially n^2 loop to find the insertion point while resolving style. Having us start from the last
1308 // child and work our way back means in the common case, we'll find the inse rtion point in O(1) time. 1305 // child and work our way back means in the common case, we'll find the inse rtion point in O(1) time.
1309 // See crbug.com/288225 1306 // See crbug.com/288225
1310 StyleResolver& styleResolver = document().ensureStyleResolver(); 1307 StyleResolver& styleResolver = document().ensureStyleResolver();
1311 Text* lastTextNode = nullptr; 1308 Text* lastTextNode = nullptr;
1312 for (Node* child = lastChild(); child; child = child->previousSibling()) { 1309 for (Node* child = lastChild(); child; child = child->previousSibling()) {
1313 if (child->isTextNode()) { 1310 if (child->isTextNode()) {
1314 toText(child)->recalcTextStyle(change, lastTextNode); 1311 toText(child)->recalcTextStyle(change, lastTextNode);
1315 lastTextNode = toText(child); 1312 lastTextNode = toText(child);
1316 } else if (child->isElementNode()) { 1313 } else if (child->isElementNode()) {
1317 Element* element = toElement(child); 1314 Element* element = toElement(child);
1318 if (element->shouldCallRecalcStyle(change)) 1315 if (element->shouldCallRecalcStyle(change))
1319 element->recalcStyle(change, lastTextNode); 1316 element->recalcStyle(change, lastTextNode);
1320 else if (element->supportsStyleSharing()) 1317 else if (element->supportsStyleSharing())
1321 styleResolver.addToStyleSharingList(*element); 1318 styleResolver.addToStyleSharingList(*element);
1322 if (element->layoutObject()) 1319 if (element->layoutObject())
1323 lastTextNode = nullptr; 1320 lastTextNode = nullptr;
1324 } 1321 }
1325 } 1322 }
1326 } 1323 }
1327 1324
1328 void ContainerNode::checkForChildrenAdjacentRuleChanges()
1329 {
1330 bool hasDirectAdjacentRules = childrenAffectedByDirectAdjacentRules();
1331 bool hasIndirectAdjacentRules = childrenAffectedByIndirectAdjacentRules();
1332
1333 if (!hasDirectAdjacentRules && !hasIndirectAdjacentRules)
1334 return;
1335
1336 unsigned forceCheckOfNextElementCount = 0;
1337 bool forceCheckOfAnyElementSibling = false;
1338 Document& document = this->document();
1339
1340 for (Element* child = ElementTraversal::firstChild(*this); child; child = El ementTraversal::nextSibling(*child)) {
1341 bool childRulesChanged = child->needsStyleRecalc() && child->styleChange Type() >= SubtreeStyleChange;
1342
1343 if (forceCheckOfNextElementCount || forceCheckOfAnyElementSibling)
1344 child->setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForT racing::create(StyleChangeReason::SiblingSelector));
1345
1346 if (childRulesChanged && hasDirectAdjacentRules)
1347 forceCheckOfNextElementCount = document.styleEngine().maxDirectAdjac entSelectors();
1348 else if (forceCheckOfNextElementCount)
1349 --forceCheckOfNextElementCount;
1350
1351 forceCheckOfAnyElementSibling = forceCheckOfAnyElementSibling || (childR ulesChanged && hasIndirectAdjacentRules);
1352 }
1353 }
1354
1355 void ContainerNode::checkForSiblingStyleChanges(SiblingCheckType changeType, Nod e* nodeBeforeChange, Node* nodeAfterChange) 1325 void ContainerNode::checkForSiblingStyleChanges(SiblingCheckType changeType, Nod e* nodeBeforeChange, Node* nodeAfterChange)
1356 { 1326 {
1357 if (!inActiveDocument() || document().hasPendingForcedStyleRecalc() || style ChangeType() >= SubtreeStyleChange) 1327 if (!inActiveDocument() || document().hasPendingForcedStyleRecalc() || style ChangeType() >= SubtreeStyleChange)
1358 return; 1328 return;
1359 1329
1360 // Forward positional selectors include nth-child, nth-of-type, first-of-typ e and only-of-type. 1330 // Forward positional selectors include nth-child, nth-of-type, first-of-typ e and only-of-type.
1361 // The indirect adjacent selector is the ~ selector. 1331 // The indirect adjacent selector is the ~ selector.
1362 // Backward positional selectors include nth-last-child, nth-last-of-type, l ast-of-type and only-of-type. 1332 // Backward positional selectors include nth-last-child, nth-last-of-type, l ast-of-type and only-of-type.
1363 // We have to invalidate everything following the insertion point in the for ward and indirect adjacent case, 1333 // We have to invalidate everything following the insertion point in the for ward and indirect adjacent case,
1364 // and everything before the insertion point in the backward case. 1334 // and everything before the insertion point in the backward case.
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1410 1380
1411 // 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 1381 // 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
1412 // to match now. 1382 // to match now.
1413 if ((changeType == SiblingElementRemoved || changeType == FinishedParsin gChildren) && lastChildElement == elementBeforeChange && lastChildElement && las tChildElement->affectedByLastChildRules()) 1383 if ((changeType == SiblingElementRemoved || changeType == FinishedParsin gChildren) && lastChildElement == elementBeforeChange && lastChildElement && las tChildElement->affectedByLastChildRules())
1414 lastChildElement->setNeedsStyleRecalc(SubtreeStyleChange, StyleChang eReasonForTracing::create(StyleChangeReason::SiblingSelector)); 1384 lastChildElement->setNeedsStyleRecalc(SubtreeStyleChange, StyleChang eReasonForTracing::create(StyleChangeReason::SiblingSelector));
1415 } 1385 }
1416 1386
1417 // The + selector. We need to invalidate the first element following the cha nge. It is the only possible element 1387 // The + selector. We need to invalidate the first element following the cha nge. It is the only possible element
1418 // that could be affected by this DOM change. 1388 // that could be affected by this DOM change.
1419 if (childrenAffectedByDirectAdjacentRules() && nodeAfterChange) { 1389 if (childrenAffectedByDirectAdjacentRules() && nodeAfterChange) {
1420 if (Element* elementAfterChange = nodeAfterChange->isElementNode() ? toE lement(nodeAfterChange) : ElementTraversal::nextSibling(*nodeAfterChange)) 1390 Element* elementAfterChange = nodeAfterChange->isElementNode() ? toEleme nt(nodeAfterChange) : ElementTraversal::nextSibling(*nodeAfterChange);
1391 for (unsigned i = document().styleEngine().maxDirectAdjacentSelectors(); i && elementAfterChange; --i, elementAfterChange = ElementTraversal::nextSiblin g(*elementAfterChange))
1421 elementAfterChange->setNeedsStyleRecalc(SubtreeStyleChange, StyleCha ngeReasonForTracing::create(StyleChangeReason::SiblingSelector)); 1392 elementAfterChange->setNeedsStyleRecalc(SubtreeStyleChange, StyleCha ngeReasonForTracing::create(StyleChangeReason::SiblingSelector));
1422 } 1393 }
1423 } 1394 }
1424 1395
1425 void ContainerNode::invalidateNodeListCachesInAncestors(const QualifiedName* att rName, Element* attributeOwnerElement) 1396 void ContainerNode::invalidateNodeListCachesInAncestors(const QualifiedName* att rName, Element* attributeOwnerElement)
1426 { 1397 {
1427 if (hasRareData() && (!attrName || isAttributeNode())) { 1398 if (hasRareData() && (!attrName || isAttributeNode())) {
1428 if (NodeListsNodeData* lists = rareData()->nodeLists()) { 1399 if (NodeListsNodeData* lists = rareData()->nodeLists()) {
1429 if (ChildNodeList* childNodeList = lists->childNodeList(*this)) 1400 if (ChildNodeList* childNodeList = lists->childNodeList(*this))
1430 childNodeList->invalidateCache(); 1401 childNodeList->invalidateCache();
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1523 return true; 1494 return true;
1524 1495
1525 if (node->isElementNode() && toElement(node)->shadow()) 1496 if (node->isElementNode() && toElement(node)->shadow())
1526 return true; 1497 return true;
1527 1498
1528 return false; 1499 return false;
1529 } 1500 }
1530 #endif 1501 #endif
1531 1502
1532 } // namespace blink 1503 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698