| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2011, 2013 Apple Inc. All rights reserved. | 2 * Copyright (C) 2011, 2013 Apple Inc. All rights reserved. |
| 3 * Copyright (C) 2014 Samsung Electronics. All rights reserved. | 3 * Copyright (C) 2014 Samsung Electronics. All rights reserved. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
| 7 * are met: | 7 * are met: |
| 8 * | 8 * |
| 9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
| 10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 237 // We need to return the matches in document order. To use id lookup while | 237 // We need to return the matches in document order. To use id lookup while |
| 238 // there is possiblity of multiple matches we would need to sort the | 238 // there is possiblity of multiple matches we would need to sort the |
| 239 // results. For now, just traverse the document in that case. | 239 // results. For now, just traverse the document in that case. |
| 240 DCHECK_EQ(m_selectors.size(), 1u); | 240 DCHECK_EQ(m_selectors.size(), 1u); |
| 241 | 241 |
| 242 bool isRightmostSelector = true; | 242 bool isRightmostSelector = true; |
| 243 bool startFromParent = false; | 243 bool startFromParent = false; |
| 244 | 244 |
| 245 for (const CSSSelector* selector = m_selectors[0]; selector; | 245 for (const CSSSelector* selector = m_selectors[0]; selector; |
| 246 selector = selector->tagHistory()) { | 246 selector = selector->tagHistory()) { |
| 247 if (selector->match() == CSSSelector::Id && rootNode.isInTreeScope() && | 247 if (selector->match() == CSSSelector::Id && |
| 248 !rootNode.containingTreeScope().containsMultipleElementsWithId( | 248 !rootNode.containingTreeScope().containsMultipleElementsWithId( |
| 249 selector->value())) { | 249 selector->value())) { |
| 250 // Id selectors in the right most selector are handled by the caller, |
| 251 // we should never hit them here. |
| 252 DCHECK(!isRightmostSelector); |
| 250 Element* element = | 253 Element* element = |
| 251 rootNode.containingTreeScope().getElementById(selector->value()); | 254 rootNode.containingTreeScope().getElementById(selector->value()); |
| 252 ContainerNode* adjustedNode = &rootNode; | 255 if (!element) |
| 253 if (element && element->isDescendantOf(&rootNode)) | |
| 254 adjustedNode = element; | |
| 255 else if (!element || isRightmostSelector) | |
| 256 adjustedNode = nullptr; | |
| 257 if (isRightmostSelector) { | |
| 258 if (!adjustedNode) | |
| 259 return; | |
| 260 element = toElement(adjustedNode); | |
| 261 if (selectorMatches(*m_selectors[0], *element, rootNode)) | |
| 262 SelectorQueryTrait::appendElement(output, *element); | |
| 263 return; | 256 return; |
| 264 } | 257 ContainerNode* start = &rootNode; |
| 265 | 258 if (element->isDescendantOf(&rootNode)) |
| 266 if (startFromParent && adjustedNode) | 259 start = element; |
| 267 adjustedNode = adjustedNode->parentNode(); | 260 if (startFromParent) |
| 268 | 261 start = start->parentNode(); |
| 269 executeForTraverseRoot<SelectorQueryTrait>(adjustedNode, rootNode, | 262 executeForTraverseRoot<SelectorQueryTrait>(start, rootNode, output); |
| 270 output); | |
| 271 return; | 263 return; |
| 272 } | 264 } |
| 273 | 265 |
| 274 // If we have both CSSSelector::Id and CSSSelector::Class at the same time, | 266 // If we have both CSSSelector::Id and CSSSelector::Class at the same time, |
| 275 // we should use Id to find traverse root. | 267 // we should use Id to find traverse root. |
| 276 if (!SelectorQueryTrait::shouldOnlyMatchFirstElement && !startFromParent && | 268 if (!SelectorQueryTrait::shouldOnlyMatchFirstElement && !startFromParent && |
| 277 selector->match() == CSSSelector::Class) { | 269 selector->match() == CSSSelector::Class) { |
| 278 if (isRightmostSelector) { | 270 if (isRightmostSelector) { |
| 279 ClassElementList<AllElements> traverseRoots(rootNode, | 271 ClassElementList<AllElements> traverseRoots(rootNode, |
| 280 selector->value()); | 272 selector->value()); |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 577 return m_entries | 569 return m_entries |
| 578 .insert(selectors, SelectorQuery::adopt(std::move(selectorList))) | 570 .insert(selectors, SelectorQuery::adopt(std::move(selectorList))) |
| 579 .storedValue->value.get(); | 571 .storedValue->value.get(); |
| 580 } | 572 } |
| 581 | 573 |
| 582 void SelectorQueryCache::invalidate() { | 574 void SelectorQueryCache::invalidate() { |
| 583 m_entries.clear(); | 575 m_entries.clear(); |
| 584 } | 576 } |
| 585 | 577 |
| 586 } // namespace blink | 578 } // namespace blink |
| OLD | NEW |