Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(257)

Side by Side Diff: third_party/WebKit/Source/core/dom/Document.cpp

Issue 2838123002: Count element name validity per DOM versus HTML parsing. (Closed)
Patch Set: Do not need the attribute counting. Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2001 Dirk Mueller (mueller@kde.org) 4 * (C) 2001 Dirk Mueller (mueller@kde.org)
5 * (C) 2006 Alexey Proskuryakov (ap@webkit.org) 5 * (C) 2006 Alexey Proskuryakov (ap@webkit.org)
6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012 Apple Inc. All 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012 Apple Inc. All
7 * rights reserved. 7 * rights reserved.
8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. 8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved.
9 * (http://www.torchmobile.com/) 9 * (http://www.torchmobile.com/)
10 * Copyright (C) 2008, 2009, 2011, 2012 Google Inc. All rights reserved. 10 * Copyright (C) 2008, 2009, 2011, 2012 Google Inc. All rights reserved.
(...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after
368 // rule (d) above 368 // rule (d) above
369 WTF::Unicode::CharDecompositionType decomp_type = 369 WTF::Unicode::CharDecompositionType decomp_type =
370 WTF::Unicode::DecompositionType(c); 370 WTF::Unicode::DecompositionType(c);
371 if (decomp_type == WTF::Unicode::kDecompositionFont || 371 if (decomp_type == WTF::Unicode::kDecompositionFont ||
372 decomp_type == WTF::Unicode::kDecompositionCompat) 372 decomp_type == WTF::Unicode::kDecompositionCompat)
373 return false; 373 return false;
374 374
375 return true; 375 return true;
376 } 376 }
377 377
378 // Tests whether |name| is something the HTML parser would accept as a
379 // tag name.
380 template <typename CharType>
381 static inline bool IsValidElementNamePerHTMLParser(const CharType* characters,
382 unsigned length) {
383 CharType c = characters[0] | 0x20;
384 if (!('a' <= c && c < 'z'))
385 return false;
386
387 for (unsigned i = 1; i < length; ++i) {
388 c = characters[i];
389 if (c == '\t' || c == '\n' || c == '\f' || c == '\r' || c == ' ' ||
390 c == '/' || c == '>')
391 return false;
392 }
393
394 return true;
395 }
396
397 static bool IsValidElementNamePerHTMLParser(const String& name) {
398 unsigned length = name.length();
399 if (!length)
400 return false;
401
402 if (name.Is8Bit()) {
403 const LChar* characters = name.Characters8();
404 return IsValidElementNamePerHTMLParser(characters, length);
405 }
406 const UChar* characters = name.Characters16();
407 return IsValidElementNamePerHTMLParser(characters, length);
408 }
409
410 // Tests whether |name| is a valid name per DOM spec. Also checks
411 // whether the HTML parser would accept this element name and counts
412 // cases of mismatches.
413 static bool IsValidElementName(const LocalDOMWindow* window,
414 const String& name) {
415 bool is_valid_dom_name = Document::IsValidName(name);
416 bool is_valid_html_name = IsValidElementNamePerHTMLParser(name);
417 if (UNLIKELY(is_valid_html_name != is_valid_dom_name && window)) {
418 UseCounter::Count(window->GetFrame(),
419 is_valid_dom_name
420 ? UseCounter::kElementNameDOMValidHTMLParserInvalid
421 : UseCounter::kElementNameDOMInvalidHTMLParserValid);
422 }
423 return is_valid_dom_name;
424 }
425
378 static bool AcceptsEditingFocus(const Element& element) { 426 static bool AcceptsEditingFocus(const Element& element) {
379 DCHECK(HasEditableStyle(element)); 427 DCHECK(HasEditableStyle(element));
380 428
381 return element.GetDocument().GetFrame() && RootEditableElement(element); 429 return element.GetDocument().GetFrame() && RootEditableElement(element);
382 } 430 }
383 431
384 uint64_t Document::global_tree_version_ = 0; 432 uint64_t Document::global_tree_version_ = 0;
385 433
386 static bool g_threaded_parsing_enabled_for_testing = true; 434 static bool g_threaded_parsing_enabled_for_testing = true;
387 435
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
687 735
688 bool Document::IsInMainFrame() const { 736 bool Document::IsInMainFrame() const {
689 return GetFrame() && GetFrame()->IsMainFrame(); 737 return GetFrame() && GetFrame()->IsMainFrame();
690 } 738 }
691 739
692 AtomicString Document::ConvertLocalName(const AtomicString& name) { 740 AtomicString Document::ConvertLocalName(const AtomicString& name) {
693 return IsHTMLDocument() ? name.LowerASCII() : name; 741 return IsHTMLDocument() ? name.LowerASCII() : name;
694 } 742 }
695 743
696 // https://dom.spec.whatwg.org/#dom-document-createelement 744 // https://dom.spec.whatwg.org/#dom-document-createelement
697 Element* Document::createElement(const AtomicString& name, 745 Element* Document::createElement(const LocalDOMWindow* window,
746 const AtomicString& name,
698 ExceptionState& exception_state) { 747 ExceptionState& exception_state) {
699 if (!IsValidName(name)) { 748 if (!IsValidElementName(window, name)) {
700 exception_state.ThrowDOMException( 749 exception_state.ThrowDOMException(
701 kInvalidCharacterError, 750 kInvalidCharacterError,
702 "The tag name provided ('" + name + "') is not a valid name."); 751 "The tag name provided ('" + name + "') is not a valid name.");
703 return nullptr; 752 return nullptr;
704 } 753 }
705 754
706 if (IsXHTMLDocument() || IsHTMLDocument()) { 755 if (IsXHTMLDocument() || IsHTMLDocument()) {
707 // 2. If the context object is an HTML document, let localName be 756 // 2. If the context object is an HTML document, let localName be
708 // converted to ASCII lowercase. 757 // converted to ASCII lowercase.
709 AtomicString local_name = ConvertLocalName(name); 758 AtomicString local_name = ConvertLocalName(name);
(...skipping 29 matching lines...) Expand all
739 return g_empty_string; 788 return g_empty_string;
740 789
741 if (impl.hasIs()) 790 if (impl.hasIs())
742 return impl.is(); 791 return impl.is();
743 } 792 }
744 793
745 return g_empty_string; 794 return g_empty_string;
746 } 795 }
747 796
748 // https://dom.spec.whatwg.org/#dom-document-createelement 797 // https://dom.spec.whatwg.org/#dom-document-createelement
749 Element* Document::createElement(const AtomicString& local_name, 798 Element* Document::createElement(const LocalDOMWindow* window,
799 const AtomicString& local_name,
750 const StringOrDictionary& string_or_options, 800 const StringOrDictionary& string_or_options,
751 ExceptionState& exception_state) { 801 ExceptionState& exception_state) {
752 // 1. If localName does not match Name production, throw InvalidCharacterError 802 // 1. If localName does not match Name production, throw InvalidCharacterError
753 if (!IsValidName(local_name)) { 803 if (!IsValidElementName(window, local_name)) {
754 exception_state.ThrowDOMException( 804 exception_state.ThrowDOMException(
755 kInvalidCharacterError, 805 kInvalidCharacterError,
756 "The tag name provided ('" + local_name + "') is not a valid name."); 806 "The tag name provided ('" + local_name + "') is not a valid name.");
757 return nullptr; 807 return nullptr;
758 } 808 }
759 809
760 // 2. localName converted to ASCII lowercase 810 // 2. localName converted to ASCII lowercase
761 const AtomicString& converted_local_name = ConvertLocalName(local_name); 811 const AtomicString& converted_local_name = ConvertLocalName(local_name);
762 812
763 bool is_v1 = string_or_options.isDictionary() || !RegistrationContext(); 813 bool is_v1 = string_or_options.isDictionary() || !RegistrationContext();
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
799 849
800 if (definition) { 850 if (definition) {
801 element = CustomElement::CreateCustomElementSync( 851 element = CustomElement::CreateCustomElementSync(
802 *this, converted_local_name, definition); 852 *this, converted_local_name, definition);
803 } else if (V0CustomElement::IsValidName(local_name) && 853 } else if (V0CustomElement::IsValidName(local_name) &&
804 RegistrationContext()) { 854 RegistrationContext()) {
805 element = RegistrationContext()->CreateCustomTagElement( 855 element = RegistrationContext()->CreateCustomTagElement(
806 *this, 856 *this,
807 QualifiedName(g_null_atom, converted_local_name, xhtmlNamespaceURI)); 857 QualifiedName(g_null_atom, converted_local_name, xhtmlNamespaceURI));
808 } else { 858 } else {
809 element = createElement(local_name, exception_state); 859 element = createElement(window, local_name, exception_state);
810 if (exception_state.HadException()) 860 if (exception_state.HadException())
811 return nullptr; 861 return nullptr;
812 } 862 }
813 863
814 // 8. If 'is' is non-null, set 'is' attribute 864 // 8. If 'is' is non-null, set 'is' attribute
815 if (!is.IsEmpty()) { 865 if (!is.IsEmpty()) {
816 if (string_or_options.isString()) { 866 if (string_or_options.isString()) {
817 V0CustomElementRegistrationContext::SetIsAttributeAndTypeExtension( 867 V0CustomElementRegistrationContext::SetIsAttributeAndTypeExtension(
818 element, is); 868 element, is);
819 } else if (string_or_options.isDictionary()) { 869 } else if (string_or_options.isDictionary()) {
(...skipping 19 matching lines...) Expand all
839 kNamespaceError, 889 kNamespaceError,
840 "The namespace URI provided ('" + namespace_uri + 890 "The namespace URI provided ('" + namespace_uri +
841 "') is not valid for the qualified name provided ('" + 891 "') is not valid for the qualified name provided ('" +
842 qualified_name + "')."); 892 qualified_name + "').");
843 return QualifiedName::Null(); 893 return QualifiedName::Null();
844 } 894 }
845 895
846 return q_name; 896 return q_name;
847 } 897 }
848 898
849 Element* Document::createElementNS(const AtomicString& namespace_uri, 899 Element* Document::createElementNS(const LocalDOMWindow* window,
900 const AtomicString& namespace_uri,
850 const AtomicString& qualified_name, 901 const AtomicString& qualified_name,
851 ExceptionState& exception_state) { 902 ExceptionState& exception_state) {
852 QualifiedName q_name( 903 QualifiedName q_name(
853 CreateQualifiedName(namespace_uri, qualified_name, exception_state)); 904 CreateQualifiedName(namespace_uri, qualified_name, exception_state));
854 if (q_name == QualifiedName::Null()) 905 if (q_name == QualifiedName::Null())
855 return nullptr; 906 return nullptr;
856 907
857 if (CustomElement::ShouldCreateCustomElement(q_name)) 908 if (CustomElement::ShouldCreateCustomElement(q_name))
858 return CustomElement::CreateCustomElementSync(*this, q_name); 909 return CustomElement::CreateCustomElementSync(*this, q_name);
859 return createElement(q_name, kCreatedByCreateElement); 910 return createElement(q_name, kCreatedByCreateElement);
860 } 911 }
861 912
862 // https://dom.spec.whatwg.org/#internal-createelementns-steps 913 // https://dom.spec.whatwg.org/#internal-createelementns-steps
863 Element* Document::createElementNS(const AtomicString& namespace_uri, 914 Element* Document::createElementNS(const LocalDOMWindow* window,
915 const AtomicString& namespace_uri,
864 const AtomicString& qualified_name, 916 const AtomicString& qualified_name,
865 const StringOrDictionary& string_or_options, 917 const StringOrDictionary& string_or_options,
866 ExceptionState& exception_state) { 918 ExceptionState& exception_state) {
867 // 1. Validate and extract 919 // 1. Validate and extract
868 QualifiedName q_name( 920 QualifiedName q_name(
869 CreateQualifiedName(namespace_uri, qualified_name, exception_state)); 921 CreateQualifiedName(namespace_uri, qualified_name, exception_state));
870 if (q_name == QualifiedName::Null()) 922 if (q_name == QualifiedName::Null())
871 return nullptr; 923 return nullptr;
872 924
873 bool is_v1 = string_or_options.isDictionary() || !RegistrationContext(); 925 bool is_v1 = string_or_options.isDictionary() || !RegistrationContext();
874 bool create_v1_builtin = 926 bool create_v1_builtin =
875 string_or_options.isDictionary() && 927 string_or_options.isDictionary() &&
876 RuntimeEnabledFeatures::customElementsBuiltinEnabled(); 928 RuntimeEnabledFeatures::customElementsBuiltinEnabled();
877 bool should_create_builtin = 929 bool should_create_builtin =
878 create_v1_builtin || string_or_options.isString(); 930 create_v1_builtin || string_or_options.isString();
879 931
880 // 2. 932 // 2.
881 const AtomicString& is = 933 const AtomicString& is =
882 AtomicString(GetTypeExtension(this, string_or_options, exception_state)); 934 AtomicString(GetTypeExtension(this, string_or_options, exception_state));
883 const AtomicString& name = should_create_builtin ? is : qualified_name; 935 const AtomicString& name = should_create_builtin ? is : qualified_name;
884 936
885 if (!IsValidName(qualified_name)) { 937 if (!IsValidElementName(window, qualified_name)) {
886 exception_state.ThrowDOMException( 938 exception_state.ThrowDOMException(
887 kInvalidCharacterError, "The tag name provided ('" + qualified_name + 939 kInvalidCharacterError, "The tag name provided ('" + qualified_name +
888 "') is not a valid name."); 940 "') is not a valid name.");
889 return nullptr; 941 return nullptr;
890 } 942 }
891 943
892 // 3. Let definition be result of lookup up custom element definition 944 // 3. Let definition be result of lookup up custom element definition
893 CustomElementDefinition* definition = nullptr; 945 CustomElementDefinition* definition = nullptr;
894 if (is_v1) { 946 if (is_v1) {
895 const CustomElementDescriptor desc = 947 const CustomElementDescriptor desc =
(...skipping 5795 matching lines...) Expand 10 before | Expand all | Expand 10 after
6691 } 6743 }
6692 6744
6693 void showLiveDocumentInstances() { 6745 void showLiveDocumentInstances() {
6694 WeakDocumentSet& set = liveDocumentSet(); 6746 WeakDocumentSet& set = liveDocumentSet();
6695 fprintf(stderr, "There are %u documents currently alive:\n", set.size()); 6747 fprintf(stderr, "There are %u documents currently alive:\n", set.size());
6696 for (blink::Document* document : set) 6748 for (blink::Document* document : set)
6697 fprintf(stderr, "- Document %p URL: %s\n", document, 6749 fprintf(stderr, "- Document %p URL: %s\n", document,
6698 document->Url().GetString().Utf8().data()); 6750 document->Url().GetString().Utf8().data());
6699 } 6751 }
6700 #endif 6752 #endif
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/dom/Document.h ('k') | third_party/WebKit/Source/core/dom/Document.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698