12013-01-29 Hajime Morrita <morrita@google.com>
2
3 [Custom Elements] Implement bare-bone document.register()
4 https://bugs.webkit.org/show_bug.cgi?id=100229
5
6 Reviewed by NOBODY (OOPS!).
7
8 This change implements prefixed version of document.register(), with minimal feature support.
9 - The feature is guarded by ENABLE(CUSTOM_ELEMENTS) and RuntimeEnabledFeatures::customDOMElementsEnabled().
10 - This bare-bone version only recognizes "name" parameter and ignores any other optional parameters.
11 - Currently only V8 is supported. JSC binding needs its own binding implementation.
12
13 = Major new classes under dom/:
14
15 The dom module has two new classes:
16 - CustomElementConstructor: A return value of document.register()
17 which holds the custom element definition.
18 - CustomElementRegistry: A collection of CustomElementConstructor objects.
19 CustomElementRegistry instance is created per Document and is owned by the Document.
20
21 CustomElementConstructor knows the definition of each custom
22 element, which is registered by document.register(). The name and
23 other options are held by this object. CustomElementRegistry owns a set
24 of the registered constructors. The registry guarantees invariants
25 like validity and uniqueness of the element names.
26
27 = A change on make_names.pl
28
29 This change tweaks make_names.pl (or generated HTMLElementFactory)
30 to hook the creations of unknown elements. Some of element names
31 which come to the fallback path can be one of registered custom
32 element.
33
34 = [V8WrapAsFunction] extended attribute:
35
36 The document.register() API returns a constructor
37 function. However, the V8 binding currently doesn't support it. To
38 make it possible, this change introduces "V8WrapAsFunction"
39 extended attribute for annotating CustomElementConstructor IDL
40 interface.
41
42 V8WrapAsFunction wraps the annotated interface with a JavaScript
43 function, which calls the original object as a function, or as a
44 constructor
45
46 With this wrapper function, there are two levels of indirection
47 between native C++ object and author-visible JS function:
48
49 [JS Adaptor Fiction] <-(hidden property)-> [JS Wrapper Object] -(internal field)-> [C++ Native object]
50
51 The code generator generates the binding code which deals with
52 this indirection. Also, there is a set of helper functions in
53 V8AdaptorFunction.h/cpp which take care of this indirection.
54 V8DOMWrapper.cpp/h works as a facade for these APIs and is used from
55 the generated code.
56
57 This redundancy comes from limitations of both V8 bindings and V8
58 embedding API. See bug 108138 for details.
59
60 = V8HTMLCustomElement
61
62 Unlike built-in HTML elements, any custom element has no
63 corresponding C++ class. Instead, document.register() should allow
64 passing a prototype object for the elements being registered.
65
66 Although this first version doesn't support the optional prototype
67 parameter yet, V8HTMLCustomElement class is made for a plumbing
68 for supporting such features in coming changes. This class
69 encapsulates JS wrapper object creation for custom element
70 instances. For example, it takes care of prototype chain setup. As
71 we support the "prototype" optional parameter for document.register(),
72 this plumbing will be extended.
73
74 = Custom DOM elements and multiple worlds
75
76 In this patch, custom element registration and instantiation is not allowed
77 in non-main world and document.register() API just fails there.
78
79 Test: fast/dom/custom/document-register-basic.html
80
81 * DerivedSources.make:
82 * WebCore.gypi:
83 * bindings/generic/RuntimeEnabledFeatures.cpp:
84 * bindings/generic/RuntimeEnabledFeatures.h:
85 (RuntimeEnabledFeatures):
86 (WebCore::RuntimeEnabledFeatures::customDOMElementsEnabled):
87 (WebCore::RuntimeEnabledFeatures::setCustomDOMElements):
88 * bindings/scripts/CodeGeneratorV8.pm:
89 (GenerateHeader):
90 * bindings/scripts/IDLAttributes.txt:
91 * bindings/v8/CustomElementHelpers.cpp: Added.
92 (WebCore::CustomElementHelpers::initializeConstructorWrapper):
93 (WebCore::CustomElementHelpers::defaultPrototypeOf):
94 (WebCore::CustomElementHelpers::isCustomElementsAllowed):
95 * bindings/v8/CustomElementHelpers.h: Copied from Source/WebCore/bindings/v8/V8HiddenPropertyName.h.
96 (CustomElementHelpers):
97 * bindings/v8/V8AdaptorFunction.cpp: Added.
98 (WebCore::V8AdaptorFunction::getTemplate):
99 (WebCore::V8AdaptorFunction::configureTemplate):
100 (WebCore::V8AdaptorFunction::invocationCallback):
101 (WebCore::V8AdaptorFunction::wrap):
102 * bindings/v8/V8AdaptorFunction.h: Added.
103 (V8AdaptorFunction):
104 (WebCore::V8AdaptorFunction::unwrap):
105 (WebCore::V8AdaptorFunction::get):
106 * bindings/v8/V8DOMWrapper.cpp:
107 (WebCore::V8DOMWrapper::toFunction):
108 (WebCore::V8DOMWrapper::fromFunction):
109 * bindings/v8/V8DOMWrapper.h:
110 (V8DOMWrapper):
111 * bindings/v8/V8HTMLCustomElement.cpp: Added.
112 (WebCore::V8HTMLCustomElement::createWrapper):
113 * bindings/v8/V8HTMLCustomElement.h: Copied from Source/WebCore/bindings/v8/V8HiddenPropertyName.h.
114 (V8HTMLCustomElement):
115 (WebCore::V8HTMLCustomElement::toV8):
116 (WebCore::HTMLCustomElement::toV8):
117 * bindings/v8/V8HiddenPropertyName.h:
118 * bindings/v8/custom/V8CustomElementConstructorCustom.cpp: Added.
119 (WebCore::V8CustomElementConstructor::callAsFunctionCallback):
120 * dom/CustomElementConstructor.cpp: Copied from Source/WebCore/bindings/v8/V8HiddenPropertyName.h.
121 (WebCore::CustomElementConstructor::create):
122 (WebCore::CustomElementConstructor::CustomElementConstructor):
123 (WebCore::CustomElementConstructor::~CustomElementConstructor):
124 (WebCore::CustomElementConstructor::willDestroyDocument):
125 (WebCore::CustomElementConstructor::createElement):
126 * dom/CustomElementConstructor.h: Copied from Source/WebCore/bindings/v8/V8HiddenPropertyName.h.
127 (CustomElementConstructor):
128 (WebCore::CustomElementConstructor::document):
129 (WebCore::CustomElementConstructor::tagName):
130 (WebCore::CustomElementConstructor::name):
131 * dom/CustomElementConstructor.idl: Added.
132 * dom/CustomElementRegistry.cpp: Added.
133 (WebCore::CustomElementRegistry::CustomElementRegistry):
134 (WebCore::CustomElementRegistry::~CustomElementRegistry):
135 (WebCore::CustomElementRegistry::constructorOf):
136 (WebCore::CustomElementRegistry::isValidName):
137 (WebCore::CustomElementRegistry::registerElement):
138 (WebCore::CustomElementRegistry::find):
139 (WebCore::CustomElementRegistry::createElement):
140 * dom/CustomElementRegistry.h: Added.
141 (CustomElementRegistry):
142 * dom/Document.cpp:
143 (WebCore::Document::removedLastRef):
144 (WebCore::Document::registerElement):
145 * dom/Document.h:
146 (WebCore::Document::registry):
147 * dom/make_names.pl:
148 (printWrapperFactoryCppFile):
149 * html/HTMLDocument.idl:
150