1# Custom Elements 2 3Custom elements let authors create their own elements, with their own 4methods, behavior, and attribute handling. Custom elements shipped in 5M33. We colloquially refer to that version as "v0." 6 7Contact Dominic Cooney 8([dominicc@chromium.org](mailto:dominicc@chromium.org)) with 9questions. 10 11### Code Location 12 13The custom elements implementation is split between core/dom and 14bindings/core/v8. 15 16## Design 17 18### Some Important Classes 19 20###### CustomElementDefinition 21 22The definition of one ‘class’ of element. This type is 23abstract to permit different kinds of definitions, although at the 24moment there is only one: ScriptCustomElementDefinition. 25 26ScriptCustomElementDefinition is linked to its constructor by an ID 27number. The ID number is stored in a map, keyed by constructor, in a 28hidden value of the CustomElementRegistry wrapper. The ID is an index 29into a list of definitions stored in V8PerContextData. 30 31###### CustomElementDescriptor 32 33A tuple of local name, and custom element name. For autonomous custom 34elements, these strings are the same; for customized built-in elements 35these strings will be different. In that case, the local name is the 36element's tag name and the custom element name is related to the value 37of the “is” attribute. 38 39###### CustomElementRegistry 40 41Implements the `window.customElements` property. This maintains the 42set of registered names. The wrapper of this object is used by 43ScriptCustomElementDefinition to cache state in V8. 44 45###### V8HTMLElement Constructor 46 47The `HTMLElement` interface constructor. When a custom element is 48created from JavaScript all we have to go on is the constructor (in 49`new.target`); this uses ScriptCustomElementDefinition's state to find 50the definition to use. 51 52### Memory Management 53 54Once defined, custom element constructors and prototypes have to be 55kept around indefinitely because they could be created in future by 56the parser. On the other hand, we must not leak when a window can no 57longer run script. 58 59We use a V8HiddenValue on the CustomElementRegistry wrapper which 60points to a map that keeps constructors and prototypes alive. See 61ScriptCustomElementDefinition. 62 63## Style Guide 64 65In comments and prose, write custom elements, not Custom Elements, to 66match the HTML standard. 67 68Prefix type names with CustomElement (singular). 69 70## Testing 71 72Custom elements have small C++ unit tests and medium 73“layout” tests. 74 75###### C++ Unit Tests 76 77These are in third_party/blink/renderer/core/dom/*_test.cc and are 78built as part of the blink_unittests target. The test names start 79with CustomElement so you can run them with: 80 81 $ out/Debug/blink_unittests --gtest_filter=CustomElement* 82 83###### Web Tests 84 85The custom element web tests are generally in 86third_party/blink/web_tests/custom-elements. 87 88All custom elements web tests use the [web-platform-tests 89harness](https://web-platform-tests.org/) and follow its style. The 90WPT style is not very prescriptive, so be consistent with other custom 91elements tests. 92 93When naming tests, use short names describing what the test is doing. 94Avoid articles. For example, "HTMLElement constructor, invoke". When 95writing assertion messages, start with a lowercase letter (unless the 96word is a proper noun), use normal grammar and articles, and include 97the word “should” to leave no doubt whate the expected 98behavior is. 99 100###### Spec Tests 101 102These will be upstreamed to WPT, replacing [the tests for 103registerElement](https://github.com/web-platform-tests/wpt/tree/master/custom-elements) 104we contributed earlier. To facilitate that, follow these guidelines: 105 106* Keep the tests together in the `spec` directory. 107* Only test things required in a spec. The test should permit other 108 possible reasonable implementations. 109* Avoid using Blink-specific test mechanisms. Don't use 110 `window.internals` for example. 111 112###### Implementation Tests 113 114These are for testing Blink-specific details like object lifetimes, 115crash regressions, interaction with registerElement and HTML Imports, 116and so on. 117 118These tests can use Blink-specific testing hooks like 119`window.internals` and `testRunner`. 120 121###### Web Exposed Tests 122 123Finally there are /TODO(dominicc): should be/ tests in 124webexposed/custom-elements which assert that we HAVE NOT shipped 125`window.customElements.define` yet. These tests need to be updated 126when we ship `window.customElements.define` or remove 127`registerElement`. 128 129## “V0” Deprecation 130 131The plan is to: 132 1331. Implement the ‘new’ kind of custom elements separately 134 from the existing implementation. We have renamed all of old 135 implementation so that the type names start with V0; it should be 136 easy to tell whether you are looking at the old or new 137 implementation. 1381. When we ship `window.customElements.define`, add a deprecation 139 warning to `document.registerElement` directing authors to use the 140 new API. 1411. Change the ‘web’ API to use the new kind of custom 142 elements. That API is used by extensions to implement the webview 143 tag and things like that. 1441. When [the use counter for 145 registerElement](https://www.chromestatus.com/metrics/feature/timeline/popularity/457) 146 drops below 0.03% of page loads, remove the old implementation. We 147 may remove it even sooner, if we have evidence that sites are using 148 feature detection correctly. 149 150## References 151 152These have links to the parts of the DOM and HTML specs which define 153custom elements: 154 155* [WHATWG DOM Wiki: Custom Elements](https://github.com/whatwg/dom/wiki#custom-elements) 156* [WHATWG HTML Wiki: Custom Elements](https://github.com/whatwg/html/wiki#custom-elements) 157