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 479 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
490 // It they start the same, check for exact match or following '-': | 490 // It they start the same, check for exact match or following '-': |
491 if (value.length() != selectorValue.length() && value[selectorValue.leng
th()] != '-') | 491 if (value.length() != selectorValue.length() && value[selectorValue.leng
th()] != '-') |
492 return false; | 492 return false; |
493 return true; | 493 return true; |
494 default: | 494 default: |
495 ASSERT_NOT_REACHED(); | 495 ASSERT_NOT_REACHED(); |
496 return false; | 496 return false; |
497 } | 497 } |
498 } | 498 } |
499 | 499 |
| 500 static HashSet<StringImpl*>* createHtmlCaseInsensitiveAttributesSet() |
| 501 { |
| 502 // This list of attributes is from |
| 503 // https://html.spec.whatwg.org/#case-sensitivity-of-selectors |
| 504 HashSet<StringImpl*>* attrSet = new HashSet<StringImpl*>; |
| 505 |
| 506 const QualifiedName* caseInsensitiveAttributes[] = { |
| 507 &accept_charsetAttr, &acceptAttr, &alignAttr, &alinkAttr, &axisAttr, |
| 508 &bgcolorAttr, |
| 509 &charsetAttr, &checkedAttr, &clearAttr, &codetypeAttr, &colorAttr, &comp
actAttr, |
| 510 &declareAttr, &deferAttr, &dirAttr, &directionAttr, &disabledAttr, |
| 511 &enctypeAttr, |
| 512 &faceAttr, &frameAttr, |
| 513 &hreflangAttr, &http_equivAttr, |
| 514 &langAttr, &languageAttr, &linkAttr, |
| 515 &mediaAttr, &methodAttr, &multipleAttr, |
| 516 &nohrefAttr, &noresizeAttr, &noshadeAttr, &nowrapAttr, |
| 517 &readonlyAttr, &relAttr, &revAttr, &rulesAttr, |
| 518 &scopeAttr, &scrollingAttr, &selectedAttr, &shapeAttr, |
| 519 &targetAttr, &textAttr, &typeAttr, |
| 520 &valignAttr, &valuetypeAttr, &vlinkAttr }; |
| 521 |
| 522 attrSet->reserveCapacityForSize(WTF_ARRAY_LENGTH(caseInsensitiveAttributes))
; |
| 523 for (const QualifiedName* attr : caseInsensitiveAttributes) |
| 524 attrSet->add(attr->localName().impl()); |
| 525 |
| 526 return attrSet; |
| 527 } |
| 528 |
| 529 static bool isHtmlCaseSensitiveAttribute(const QualifiedName& attributeName) |
| 530 { |
| 531 static HashSet<StringImpl*>* htmlCaseInsensitiveAttributesSet = createHtmlCa
seInsensitiveAttributesSet(); |
| 532 bool isPossibleHTMLAttr = !attributeName.hasPrefix() && (attributeName.names
paceURI() == nullAtom); |
| 533 return !isPossibleHTMLAttr || !htmlCaseInsensitiveAttributesSet->contains(at
tributeName.localName().impl()); |
| 534 } |
| 535 |
500 static bool anyAttributeMatches(Element& element, CSSSelector::MatchType match,
const CSSSelector& selector) | 536 static bool anyAttributeMatches(Element& element, CSSSelector::MatchType match,
const CSSSelector& selector) |
501 { | 537 { |
502 const QualifiedName& selectorAttr = selector.attribute(); | 538 const QualifiedName& selectorAttr = selector.attribute(); |
503 ASSERT(selectorAttr.localName() != starAtom); // Should not be possible from
the CSS grammar. | 539 ASSERT(selectorAttr.localName() != starAtom); // Should not be possible from
the CSS grammar. |
504 | 540 |
505 // Synchronize the attribute in case it is lazy-computed. | 541 // Synchronize the attribute in case it is lazy-computed. |
506 // Currently all lazy properties have a null namespace, so only pass localNa
me(). | 542 // Currently all lazy properties have a null namespace, so only pass localNa
me(). |
507 element.synchronizeAttribute(selectorAttr.localName()); | 543 element.synchronizeAttribute(selectorAttr.localName()); |
508 | 544 |
509 const AtomicString& selectorValue = selector.value(); | 545 const AtomicString& selectorValue = selector.value(); |
510 TextCaseSensitivity caseSensitivity = (selector.attributeMatch() == CSSSelec
tor::CaseInsensitive) ? TextCaseASCIIInsensitive : TextCaseSensitive; | 546 TextCaseSensitivity caseSensitivity = (selector.attributeMatch() == CSSSelec
tor::CaseInsensitive) ? TextCaseASCIIInsensitive : TextCaseSensitive; |
511 | 547 |
512 AttributeCollection attributes = element.attributesWithoutUpdate(); | 548 AttributeCollection attributes = element.attributesWithoutUpdate(); |
513 for (const auto& attributeItem: attributes) { | 549 for (const auto& attributeItem: attributes) { |
514 if (!attributeItem.matches(selectorAttr)) | 550 if (!attributeItem.matches(selectorAttr)) |
515 continue; | 551 continue; |
516 | 552 |
517 if (attributeValueMatches(attributeItem, match, selectorValue, caseSensi
tivity)) | 553 if (attributeValueMatches(attributeItem, match, selectorValue, caseSensi
tivity)) |
518 return true; | 554 return true; |
519 | 555 |
520 if (caseSensitivity == TextCaseASCIIInsensitive) { | 556 if (caseSensitivity == TextCaseASCIIInsensitive) { |
521 if (selectorAttr.namespaceURI() != starAtom) | 557 if (selectorAttr.namespaceURI() != starAtom) |
522 return false; | 558 return false; |
523 continue; | 559 continue; |
524 } | 560 } |
525 | 561 |
526 // Legacy dictates that values of some attributes should be compared in | 562 // https://html.spec.whatwg.org/#case-sensitivity-of-selectors |
527 // a case-insensitive manner regardless of whether the case insensitive | 563 // TODO(foolip): The spec says "HTML element in an HTML document", but |
528 // flag is set or not. | 564 // this applies to any element in an HTML document. |
529 bool legacyCaseInsensitive = element.document().isHTMLDocument() && !HTM
LDocument::isCaseSensitiveAttribute(selectorAttr); | 565 bool legacyCaseInsensitive = element.document().isHTMLDocument() && !isH
tmlCaseSensitiveAttribute(selectorAttr); |
530 | 566 |
531 // If case-insensitive, re-check, and count if result differs. | 567 // If case-insensitive, re-check, and count if result differs. |
532 // See http://code.google.com/p/chromium/issues/detail?id=327060 | 568 // See http://code.google.com/p/chromium/issues/detail?id=327060 |
533 if (legacyCaseInsensitive && attributeValueMatches(attributeItem, match,
selectorValue, TextCaseASCIIInsensitive)) { | 569 if (legacyCaseInsensitive && attributeValueMatches(attributeItem, match,
selectorValue, TextCaseASCIIInsensitive)) { |
534 UseCounter::count(element.document(), UseCounter::CaseInsensitiveAtt
rSelectorMatch); | 570 UseCounter::count(element.document(), UseCounter::CaseInsensitiveAtt
rSelectorMatch); |
535 return true; | 571 return true; |
536 } | 572 } |
537 if (selectorAttr.namespaceURI() != starAtom) | 573 if (selectorAttr.namespaceURI() != starAtom) |
538 return false; | 574 return false; |
539 } | 575 } |
(...skipping 622 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1162 } | 1198 } |
1163 | 1199 |
1164 bool SelectorChecker::matchesFocusPseudoClass(const Element& element) | 1200 bool SelectorChecker::matchesFocusPseudoClass(const Element& element) |
1165 { | 1201 { |
1166 if (InspectorInstrumentation::forcePseudoState(const_cast<Element*>(&element
), CSSSelector::PseudoFocus)) | 1202 if (InspectorInstrumentation::forcePseudoState(const_cast<Element*>(&element
), CSSSelector::PseudoFocus)) |
1167 return true; | 1203 return true; |
1168 return element.focused() && isFrameFocused(element); | 1204 return element.focused() && isFrameFocused(element); |
1169 } | 1205 } |
1170 | 1206 |
1171 } // namespace blink | 1207 } // namespace blink |
OLD | NEW |