summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/core/html/custom/README.md
blob: 289833db2aaa38c4465dc1966373b0f2bd01dfd3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# Custom Elements

Custom elements let authors create their own elements, with their own
methods, behavior, and attribute handling. Custom elements shipped in
M33. We colloquially refer to that version as "v0."

Contact Dominic Cooney
([dominicc@chromium.org](mailto:dominicc@chromium.org)) with
questions.

### Code Location

The custom elements implementation is split between core/dom and
bindings/core/v8.

## Design

### Some Important Classes

###### CustomElementDefinition

The definition of one ‘class’ of element. This type is
abstract to permit different kinds of definitions, although at the
moment there is only one: ScriptCustomElementDefinition.

ScriptCustomElementDefinition is linked to its constructor by an ID
number. The ID number is stored in a map, keyed by constructor, in a
hidden value of the CustomElementRegistry wrapper. The ID is an index
into a list of definitions stored in V8PerContextData.

###### CustomElementDescriptor

A tuple of local name, and custom element name. For autonomous custom
elements, these strings are the same; for customized built-in elements
these strings will be different. In that case, the local name is the
element's tag name and the custom element name is related to the value
of the “is” attribute.

###### CustomElementRegistry

Implements the `window.customElements` property. This maintains the
set of registered names. The wrapper of this object is used by
ScriptCustomElementDefinition to cache state in V8.

###### V8HTMLElement Constructor

The `HTMLElement` interface constructor. When a custom element is
created from JavaScript all we have to go on is the constructor (in
`new.target`); this uses ScriptCustomElementDefinition's state to find
the definition to use.

### Memory Management

Once defined, custom element constructors and prototypes have to be
kept around indefinitely because they could be created in future by
the parser. On the other hand, we must not leak when a window can no
longer run script.

We use a V8HiddenValue on the CustomElementRegistry wrapper which
points to a map that keeps constructors and prototypes alive. See
ScriptCustomElementDefinition.

## Style Guide

In comments and prose, write custom elements, not Custom Elements, to
match the HTML standard.

Prefix type names with CustomElement (singular).

## Testing

Custom elements have small C++ unit tests and medium
“layout” tests.

###### C++ Unit Tests

These are in third_party/blink/renderer/core/dom/*_test.cc and are
built as part of the webkit_unit_tests target. The test names start
with CustomElement so you can run them with:

    $ out/Debug/webkit_unit_tests --gtest_filter=CustomElement*

###### Layout Tests

The custom element layout tests are generally in
third_party/WebKit/LayoutTests/custom-elements.

All custom elements layout tests use the [W3C web-platform-tests
harness](http://web-platform-tests.org/) and follow its style. The
W3C is not very prescriptive, so be consistent with other custom
elements tests.

When naming tests, use short names describing what the test is doing.
Avoid articles. For example, "HTMLElement constructor, invoke". When
writing assertion messages, start with a lowercase letter (unless the
word is a proper noun), use normal grammar and articles, and include
the word “should” to leave no doubt whate the expected
behavior is.

###### Spec Tests

These will be upstreamed to the W3C, replacing [the tests for
registerElement](https://github.com/w3c/web-platform-tests/commits/master/custom-elements)
we contributed earlier. To facilitate that, follow these guidelines:

* Keep the tests together in the `spec` directory.
* Only test things required in a spec. The test should permit other
  possible reasonable implementations.
* Avoid using Blink-specific test mechanisms. Don't use
  `window.internals` for example.

###### Implementation Tests

These are for testing Blink-specific details like object lifetimes,
crash regressions, interaction with registerElement and HTML Imports,
and so on.

These tests can use Blink-specific testing hooks like
`window.internals` and `testRunner`.

###### Web Exposed Tests

Finally there are /TODO(dominicc): should be/ tests in
webexposed/custom-elements which assert that we HAVE NOT shipped
`window.customElements.define` yet. These tests need to be updated
when we ship `window.customElements.define` or remove
`registerElement`.

## “V0” Deprecation

The plan is to:

1. Implement the ‘new’ kind of custom elements separately
   from the existing implementation. We have renamed all of old
   implementation so that the type names start with V0; it should be
   easy to tell whether you are looking at the old or new
   implementation.
1. When we ship `window.customElements.define`, add a deprecation
   warning to `document.registerElement` directing authors to use the
   new API.
1. Change the ‘web’ API to use the new kind of custom
   elements. That API is used by extensions to implement the webview
   tag and things like that.
1. When [the use counter for
   registerElement](https://www.chromestatus.com/metrics/feature/timeline/popularity/457)
   drops below 0.03% of page loads, remove the old implementation. We
   may remove it even sooner, if we have evidence that sites are using
   feature detection correctly.

## References

These have links to the parts of the DOM and HTML specs which define
custom elements:

* [WHATWG DOM Wiki: Custom Elements](https://github.com/whatwg/dom/wiki#custom-elements)
* [WHATWG HTML Wiki: Custom Elements](https://github.com/whatwg/html/wiki#custom-elements)