| // Copyright 2016 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_CUSTOM_ELEMENT_H_ |
| #define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_CUSTOM_ELEMENT_H_ |
| |
| #include "third_party/blink/renderer/core/core_export.h" |
| #include "third_party/blink/renderer/core/dom/create_element_flags.h" |
| #include "third_party/blink/renderer/core/dom/element.h" |
| #include "third_party/blink/renderer/platform/text/character.h" |
| #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" |
| #include "third_party/blink/renderer/platform/wtf/text/ascii_ctype.h" |
| #include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" |
| |
| namespace blink { |
| |
| class Document; |
| class Element; |
| class FileOrUSVStringOrFormData; |
| class HTMLElement; |
| class HTMLFormElement; |
| class QualifiedName; |
| class CustomElementDefinition; |
| class CustomElementReaction; |
| class CustomElementRegistry; |
| |
| class CORE_EXPORT CustomElement { |
| STATIC_ONLY(CustomElement); |
| |
| public: |
| // Retrieves the CustomElementRegistry for Element, if any. This |
| // may be a different object for a given element over its lifetime |
| // as it moves between documents. |
| static CustomElementRegistry* Registry(const Element&); |
| static CustomElementRegistry* Registry(const Document&); |
| |
| static CustomElementDefinition* DefinitionForElement(const Element*); |
| |
| static void AddEmbedderCustomElementName(const AtomicString& name); |
| |
| static bool IsValidName(const AtomicString& name) { |
| return IsValidName(name, true); |
| } |
| |
| static bool IsValidName(const AtomicString& name, |
| bool including_embedder_names) { |
| if (including_embedder_names && EmbedderCustomElementNames().Contains(name)) |
| return true; |
| |
| // This quickly rejects all common built-in element names. |
| if (name.find('-', 1) == kNotFound) |
| return false; |
| |
| if (!IsASCIILower(name[0])) |
| return false; |
| |
| if (name.Is8Bit()) { |
| const LChar* characters = name.Characters8(); |
| for (wtf_size_t i = 1; i < name.length(); ++i) { |
| if (!Character::IsPotentialCustomElementName8BitChar(characters[i])) |
| return false; |
| } |
| } else { |
| const UChar* characters = name.Characters16(); |
| for (wtf_size_t i = 1; i < name.length();) { |
| UChar32 ch; |
| U16_NEXT(characters, i, name.length(), ch); |
| if (!Character::IsPotentialCustomElementNameChar(ch)) |
| return false; |
| } |
| } |
| |
| return !IsHyphenatedSpecElementName(name); |
| } |
| |
| static bool ShouldCreateCustomElement(const AtomicString& local_name); |
| static bool ShouldCreateCustomElement(const QualifiedName&); |
| static bool ShouldCreateCustomizedBuiltinElement( |
| const AtomicString& local_name, |
| const Document&); |
| static bool ShouldCreateCustomizedBuiltinElement(const QualifiedName&, |
| const Document&); |
| |
| // Look up a definition, and create an autonomous custom element if |
| // it's found. |
| static HTMLElement* CreateCustomElement(Document&, |
| const QualifiedName&, |
| const CreateElementFlags); |
| |
| // Creates "uncustomized" or "undefined" state element. This should be |
| // used when CustomElementDefinition is not found. |
| static Element* CreateUncustomizedOrUndefinedElement( |
| Document&, |
| const QualifiedName&, |
| const CreateElementFlags, |
| const AtomicString& is_value); |
| static HTMLElement* CreateFailedElement(Document&, const QualifiedName&); |
| |
| static void Enqueue(Element&, CustomElementReaction&); |
| static void EnqueueConnectedCallback(Element&); |
| static void EnqueueDisconnectedCallback(Element&); |
| static void EnqueueAdoptedCallback(Element&, |
| Document& old_owner, |
| Document& new_owner); |
| static void EnqueueAttributeChangedCallback(Element&, |
| const QualifiedName&, |
| const AtomicString& old_value, |
| const AtomicString& new_value); |
| static void EnqueueFormAssociatedCallback(Element& element, |
| HTMLFormElement* nullable_form); |
| static void EnqueueFormResetCallback(Element& element); |
| static void EnqueueFormDisabledCallback(Element& element, bool is_disabled); |
| static void EnqueueFormStateRestoreCallback( |
| Element& element, |
| const FileOrUSVStringOrFormData& value, |
| const String& mode); |
| |
| static void TryToUpgrade(Element&); |
| |
| static void AddEmbedderCustomElementNameForTesting(const AtomicString& name, |
| ExceptionState&); |
| |
| private: |
| // Some existing specs have element names with hyphens in them, |
| // like font-face in SVG. The custom elements spec explicitly |
| // disallows these as custom element names. |
| // https://html.spec.whatwg.org/C/#valid-custom-element-name |
| static bool IsHyphenatedSpecElementName(const AtomicString&); |
| |
| static Vector<AtomicString>& EmbedderCustomElementNames(); |
| |
| enum CreateUUCheckLevel { |
| kCheckAll, |
| // QualifiedName is a valid custom element name, and is_value is null. |
| kQNameIsValid, |
| }; |
| template <CreateUUCheckLevel> |
| static Element* CreateUncustomizedOrUndefinedElementTemplate( |
| Document&, |
| const QualifiedName&, |
| const CreateElementFlags, |
| const AtomicString& is_value); |
| }; |
| |
| } // namespace blink |
| |
| #endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_CUSTOM_ELEMENT_H_ |