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 |