OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
3 * (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com) | 3 * (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com) |
4 * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com) | 4 * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com) |
5 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights
reserved. | 5 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights
reserved. |
6 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> | 6 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> |
7 * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org> | 7 * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org> |
8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t
orchmobile.com/) | 8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t
orchmobile.com/) |
9 * Copyright (c) 2011, Code Aurora Forum. All rights reserved. | 9 * Copyright (c) 2011, Code Aurora Forum. All rights reserved. |
10 * Copyright (C) Research In Motion Limited 2011. All rights reserved. | 10 * Copyright (C) Research In Motion Limited 2011. All rights reserved. |
(...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
443 if (!checkOneSelector(sel, e, dynamicPseudo, isSubSelector, visitedMatchType
, elementStyle, elementParentStyle)) | 443 if (!checkOneSelector(sel, e, dynamicPseudo, isSubSelector, visitedMatchType
, elementStyle, elementParentStyle)) |
444 return SelectorFailsLocally; | 444 return SelectorFailsLocally; |
445 | 445 |
446 // The rest of the selectors has to match | 446 // The rest of the selectors has to match |
447 CSSSelector::Relation relation = sel->relation(); | 447 CSSSelector::Relation relation = sel->relation(); |
448 | 448 |
449 // Prepare next sel | 449 // Prepare next sel |
450 sel = sel->tagHistory(); | 450 sel = sel->tagHistory(); |
451 if (!sel) | 451 if (!sel) |
452 return SelectorMatches; | 452 return SelectorMatches; |
453 | 453 |
454 if (relation != CSSSelector::SubSelector) { | 454 if (relation != CSSSelector::SubSelector) { |
455 // Bail-out if this selector is irrelevant for the pseudoStyle | 455 // Bail-out if this selector is irrelevant for the pseudoStyle |
456 if (m_pseudoStyle != NOPSEUDO && m_pseudoStyle != dynamicPseudo) | 456 if (m_pseudoStyle != NOPSEUDO && m_pseudoStyle != dynamicPseudo) |
457 return SelectorFailsCompletely; | 457 return SelectorFailsCompletely; |
458 | 458 |
459 // Disable :visited matching after we move to selector components that w
ould match anything else than the current element. | 459 // Disable :visited matching when we see the first link or try to match
anything else than an ancestors. |
460 if (!isSubSelector) | 460 if (!isSubSelector && (e->isLink() || (relation != CSSSelector::Descenda
nt && relation != CSSSelector::Child))) |
461 visitedMatchType = VisitedMatchDisabled; | 461 visitedMatchType = VisitedMatchDisabled; |
462 } | 462 } |
463 | 463 |
464 switch (relation) { | 464 switch (relation) { |
465 case CSSSelector::Descendant: | 465 case CSSSelector::Descendant: |
466 while (true) { | 466 while (true) { |
467 ContainerNode* n = e->parentNode(); | 467 ContainerNode* n = e->parentNode(); |
468 if (!n || !n->isElementNode()) | 468 if (!n || !n->isElementNode()) |
469 return SelectorFailsCompletely; | 469 return SelectorFailsCompletely; |
470 e = static_cast<Element*>(n); | 470 e = static_cast<Element*>(n); |
471 SelectorMatch match = checkSelector(sel, e, dynamicPseudo, false, vi
sitedMatchType); | 471 SelectorMatch match = checkSelector(sel, e, dynamicPseudo, false, vi
sitedMatchType); |
472 if (match != SelectorFailsLocally) | 472 if (match != SelectorFailsLocally) |
473 return match; | 473 return match; |
(...skipping 857 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1331 ASSERT_NOT_REACHED(); | 1331 ASSERT_NOT_REACHED(); |
1332 } | 1332 } |
1333 return true; | 1333 return true; |
1334 } | 1334 } |
1335 | 1335 |
1336 unsigned SelectorChecker::determineLinkMatchType(const CSSSelector* selector) | 1336 unsigned SelectorChecker::determineLinkMatchType(const CSSSelector* selector) |
1337 { | 1337 { |
1338 unsigned linkMatchType = MatchAll; | 1338 unsigned linkMatchType = MatchAll; |
1339 | 1339 |
1340 // Statically determine if this selector will match a link in visited, unvis
ited or any state, or never. | 1340 // Statically determine if this selector will match a link in visited, unvis
ited or any state, or never. |
1341 // :visited never matches other elements than the current. | 1341 // :visited never matches other elements than the innermost link element. |
1342 for (; selector; selector = selector->tagHistory()) { | 1342 for (; selector; selector = selector->tagHistory()) { |
1343 switch (selector->pseudoType()) { | 1343 switch (selector->pseudoType()) { |
1344 case CSSSelector::PseudoNot: | 1344 case CSSSelector::PseudoNot: |
1345 // :not(:visited) is equivalent to :link. Parser enforces that :not
can't nest. | 1345 // :not(:visited) is equivalent to :link. Parser enforces that :not
can't nest. |
1346 for (CSSSelector* subSelector = selector->selectorList()->first(); s
ubSelector; subSelector = subSelector->tagHistory()) { | 1346 for (CSSSelector* subSelector = selector->selectorList()->first(); s
ubSelector; subSelector = subSelector->tagHistory()) { |
1347 CSSSelector::PseudoType subType = subSelector->pseudoType(); | 1347 CSSSelector::PseudoType subType = subSelector->pseudoType(); |
1348 if (subType == CSSSelector::PseudoVisited) | 1348 if (subType == CSSSelector::PseudoVisited) |
1349 linkMatchType &= ~SelectorChecker::MatchVisited; | 1349 linkMatchType &= ~SelectorChecker::MatchVisited; |
1350 else if (subType == CSSSelector::PseudoLink) | 1350 else if (subType == CSSSelector::PseudoLink) |
1351 linkMatchType &= ~SelectorChecker::MatchLink; | 1351 linkMatchType &= ~SelectorChecker::MatchLink; |
1352 } | 1352 } |
1353 break; | 1353 break; |
1354 case CSSSelector::PseudoLink: | 1354 case CSSSelector::PseudoLink: |
1355 linkMatchType &= ~SelectorChecker::MatchVisited; | 1355 linkMatchType &= ~SelectorChecker::MatchVisited; |
1356 break; | 1356 break; |
1357 case CSSSelector::PseudoVisited: | 1357 case CSSSelector::PseudoVisited: |
1358 linkMatchType &= ~SelectorChecker::MatchLink; | 1358 linkMatchType &= ~SelectorChecker::MatchLink; |
1359 break; | 1359 break; |
1360 default: | 1360 default: |
1361 // We don't support :link and :visited inside :-webkit-any. | 1361 // We don't support :link and :visited inside :-webkit-any. |
1362 break; | 1362 break; |
1363 } | 1363 } |
1364 if (selector->relation() != CSSSelector::SubSelector) | 1364 CSSSelector::Relation relation = selector->relation(); |
| 1365 if (relation == CSSSelector::SubSelector) |
| 1366 continue; |
| 1367 if (relation != CSSSelector::Descendant && relation != CSSSelector::Chil
d) |
| 1368 return linkMatchType; |
| 1369 if (linkMatchType != MatchAll) |
1365 return linkMatchType; | 1370 return linkMatchType; |
1366 } | 1371 } |
1367 ASSERT_NOT_REACHED(); | |
1368 return linkMatchType; | 1372 return linkMatchType; |
1369 } | 1373 } |
1370 | 1374 |
1371 bool SelectorChecker::isFrameFocused(const Element* element) | 1375 bool SelectorChecker::isFrameFocused(const Element* element) |
1372 { | 1376 { |
1373 return element->document()->frame() && element->document()->frame()->selecti
on()->isFocusedAndActive(); | 1377 return element->document()->frame() && element->document()->frame()->selecti
on()->isFocusedAndActive(); |
1374 } | 1378 } |
1375 | 1379 |
1376 } | 1380 } |
OLD | NEW |