| 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, 2012, 2013 Apple Inc.
All rights reserved. | 5 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 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 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 500 { | 500 { |
| 501 // TODO(esprehn): How do we get here with a null value? | 501 // TODO(esprehn): How do we get here with a null value? |
| 502 const AtomicString& value = attributeItem.value(); | 502 const AtomicString& value = attributeItem.value(); |
| 503 if (value.isNull()) | 503 if (value.isNull()) |
| 504 return false; | 504 return false; |
| 505 | 505 |
| 506 switch (match) { | 506 switch (match) { |
| 507 case CSSSelector::AttributeExact: | 507 case CSSSelector::AttributeExact: |
| 508 if (caseSensitivity == TextCaseSensitive) | 508 if (caseSensitivity == TextCaseSensitive) |
| 509 return selectorValue == value; | 509 return selectorValue == value; |
| 510 return equalIgnoringCase(selectorValue, value); | 510 return equalIgnoringASCIICase(selectorValue, value); |
| 511 case CSSSelector::AttributeSet: | 511 case CSSSelector::AttributeSet: |
| 512 return true; | 512 return true; |
| 513 case CSSSelector::AttributeList: | 513 case CSSSelector::AttributeList: |
| 514 { | 514 { |
| 515 // Ignore empty selectors or selectors containing HTML spaces | 515 // Ignore empty selectors or selectors containing HTML spaces |
| 516 if (selectorValue.isEmpty() || containsHTMLSpace(selectorValue)) | 516 if (selectorValue.isEmpty() || containsHTMLSpace(selectorValue)) |
| 517 return false; | 517 return false; |
| 518 | 518 |
| 519 unsigned startSearchAt = 0; | 519 unsigned startSearchAt = 0; |
| 520 while (true) { | 520 while (true) { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 564 static bool anyAttributeMatches(Element& element, CSSSelector::Match match, cons
t CSSSelector& selector) | 564 static bool anyAttributeMatches(Element& element, CSSSelector::Match match, cons
t CSSSelector& selector) |
| 565 { | 565 { |
| 566 const QualifiedName& selectorAttr = selector.attribute(); | 566 const QualifiedName& selectorAttr = selector.attribute(); |
| 567 ASSERT(selectorAttr.localName() != starAtom); // Should not be possible from
the CSS grammar. | 567 ASSERT(selectorAttr.localName() != starAtom); // Should not be possible from
the CSS grammar. |
| 568 | 568 |
| 569 // Synchronize the attribute in case it is lazy-computed. | 569 // Synchronize the attribute in case it is lazy-computed. |
| 570 // Currently all lazy properties have a null namespace, so only pass localNa
me(). | 570 // Currently all lazy properties have a null namespace, so only pass localNa
me(). |
| 571 element.synchronizeAttribute(selectorAttr.localName()); | 571 element.synchronizeAttribute(selectorAttr.localName()); |
| 572 | 572 |
| 573 const AtomicString& selectorValue = selector.value(); | 573 const AtomicString& selectorValue = selector.value(); |
| 574 TextCaseSensitivity caseSensitivity = (selector.attributeMatchType() == CSSS
elector::CaseInsensitive) ? TextCaseInsensitive : TextCaseSensitive; | 574 TextCaseSensitivity caseSensitivity = (selector.attributeMatchType() == CSSS
elector::CaseInsensitive) ? TextCaseASCIIInsensitive : TextCaseSensitive; |
| 575 | 575 |
| 576 AttributeCollection attributes = element.attributesWithoutUpdate(); | 576 AttributeCollection attributes = element.attributesWithoutUpdate(); |
| 577 for (const auto& attributeItem: attributes) { | 577 for (const auto& attributeItem: attributes) { |
| 578 if (!attributeItem.matches(selectorAttr)) | 578 if (!attributeItem.matches(selectorAttr)) |
| 579 continue; | 579 continue; |
| 580 | 580 |
| 581 if (attributeValueMatches(attributeItem, match, selectorValue, caseSensi
tivity)) | 581 if (attributeValueMatches(attributeItem, match, selectorValue, caseSensi
tivity)) |
| 582 return true; | 582 return true; |
| 583 | 583 |
| 584 if (caseSensitivity == TextCaseInsensitive) { | 584 if (caseSensitivity == TextCaseASCIIInsensitive) { |
| 585 if (selectorAttr.namespaceURI() != starAtom) | 585 if (selectorAttr.namespaceURI() != starAtom) |
| 586 return false; | 586 return false; |
| 587 continue; | 587 continue; |
| 588 } | 588 } |
| 589 | 589 |
| 590 // Legacy dictates that values of some attributes should be compared in | 590 // Legacy dictates that values of some attributes should be compared in |
| 591 // a case-insensitive manner regardless of whether the case insensitive | 591 // a case-insensitive manner regardless of whether the case insensitive |
| 592 // flag is set or not. | 592 // flag is set or not. |
| 593 bool legacyCaseInsensitive = element.document().isHTMLDocument() && !HTM
LDocument::isCaseSensitiveAttribute(selectorAttr); | 593 bool legacyCaseInsensitive = element.document().isHTMLDocument() && !HTM
LDocument::isCaseSensitiveAttribute(selectorAttr); |
| 594 | 594 |
| 595 // If case-insensitive, re-check, and count if result differs. | 595 // If case-insensitive, re-check, and count if result differs. |
| 596 // See http://code.google.com/p/chromium/issues/detail?id=327060 | 596 // See http://code.google.com/p/chromium/issues/detail?id=327060 |
| 597 if (legacyCaseInsensitive && attributeValueMatches(attributeItem, match,
selectorValue, TextCaseInsensitive)) { | 597 if (legacyCaseInsensitive && attributeValueMatches(attributeItem, match,
selectorValue, TextCaseASCIIInsensitive)) { |
| 598 UseCounter::count(element.document(), UseCounter::CaseInsensitiveAtt
rSelectorMatch); | 598 UseCounter::count(element.document(), UseCounter::CaseInsensitiveAtt
rSelectorMatch); |
| 599 return true; | 599 return true; |
| 600 } | 600 } |
| 601 if (selectorAttr.namespaceURI() != starAtom) | 601 if (selectorAttr.namespaceURI() != starAtom) |
| 602 return false; | 602 return false; |
| 603 } | 603 } |
| 604 | 604 |
| 605 return false; | 605 return false; |
| 606 } | 606 } |
| 607 | 607 |
| (...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 926 case CSSSelector::PseudoRoot: | 926 case CSSSelector::PseudoRoot: |
| 927 return element == element.document().documentElement(); | 927 return element == element.document().documentElement(); |
| 928 case CSSSelector::PseudoLang: | 928 case CSSSelector::PseudoLang: |
| 929 { | 929 { |
| 930 AtomicString value; | 930 AtomicString value; |
| 931 if (element.isVTTElement()) | 931 if (element.isVTTElement()) |
| 932 value = toVTTElement(element).language(); | 932 value = toVTTElement(element).language(); |
| 933 else | 933 else |
| 934 value = element.computeInheritedLanguage(); | 934 value = element.computeInheritedLanguage(); |
| 935 const AtomicString& argument = selector.argument(); | 935 const AtomicString& argument = selector.argument(); |
| 936 if (value.isEmpty() || !startsWithIgnoringASCIICase(value, argument)
) | 936 if (value.isEmpty() || !value.startsWith(argument, TextCaseASCIIInse
nsitive)) |
| 937 break; | 937 break; |
| 938 if (value.length() != argument.length() && value[argument.length()]
!= '-') | 938 if (value.length() != argument.length() && value[argument.length()]
!= '-') |
| 939 break; | 939 break; |
| 940 return true; | 940 return true; |
| 941 } | 941 } |
| 942 case CSSSelector::PseudoFullScreen: | 942 case CSSSelector::PseudoFullScreen: |
| 943 // While a Document is in the fullscreen state, and the document's curre
nt fullscreen | 943 // While a Document is in the fullscreen state, and the document's curre
nt fullscreen |
| 944 // element is an element in the document, the 'full-screen' pseudoclass
applies to | 944 // element is an element in the document, the 'full-screen' pseudoclass
applies to |
| 945 // that element. Also, an <iframe>, <object> or <embed> element whose ch
ild browsing | 945 // that element. Also, an <iframe>, <object> or <embed> element whose ch
ild browsing |
| 946 // context's Document is in the fullscreen state has the 'full-screen' p
seudoclass applied. | 946 // context's Document is in the fullscreen state has the 'full-screen' p
seudoclass applied. |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1191 } | 1191 } |
| 1192 | 1192 |
| 1193 bool SelectorChecker::matchesFocusPseudoClass(const Element& element) | 1193 bool SelectorChecker::matchesFocusPseudoClass(const Element& element) |
| 1194 { | 1194 { |
| 1195 if (InspectorInstrumentation::forcePseudoState(const_cast<Element*>(&element
), CSSSelector::PseudoFocus)) | 1195 if (InspectorInstrumentation::forcePseudoState(const_cast<Element*>(&element
), CSSSelector::PseudoFocus)) |
| 1196 return true; | 1196 return true; |
| 1197 return element.focused() && isFrameFocused(element); | 1197 return element.focused() && isFrameFocused(element); |
| 1198 } | 1198 } |
| 1199 | 1199 |
| 1200 } | 1200 } |
| OLD | NEW |