[Custom Elements] Implement bare-bone document.register()
authormorrita@google.com <morrita@google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 24 Feb 2013 13:21:42 +0000 (13:21 +0000)
committermorrita@google.com <morrita@google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 24 Feb 2013 13:21:42 +0000 (13:21 +0000)
commit29b0fa4011726c823773c6f687ca55f7f6edd317
tree630cde630a329ef7050b56c01c1a8c9f6b047523
parent4f742a70fe2a6f40ba983ece6a7bf54d908c7f33
[Custom Elements] Implement bare-bone document.register()
https://bugs.webkit.org/show_bug.cgi?id=100229

Reviewed by Adam Barth.

Source/WebCore:

This change implements a prefixed version of document.register(), with minimal feature support.
- The feature is guarded by ENABLE(CUSTOM_ELEMENTS) and RuntimeEnabledFeatures::customDOMElementsEnabled().
- This bare-bone version only recognizes "name" and "prototype" parameters. It doesn't support default value of "prototype" parameter.
- Currently only V8 is supported. JSC binding needs its own binding implementation.

= Major new classes under dom/:

The dom module gets two new classes:
- CustomElementConstructor: A return value of document.register()
  which holds the custom element definition.
- CustomElementRegistry: A collection of CustomElementConstructor objects.
  CustomElementRegistry instance is created per Document and is owned by the Document.

CustomElementConstructor knows the definition of each custom
element, which is registered by document.register(). The name and
other options are held by this object. CustomElementRegistry owns a set
of the registered constructors. The registry guarantees invariants
like validity and uniqueness of the element names.

= A change on make_names.pl

This change tweaks make_names.pl (or generated HTMLElementFactory)
to hook the creations of unknown elements. Some of element names
which come to the fallback path can be one of registered custom
element.

= [V8WrapAsFunction] extended attribute:

The document.register() API returns a constructor
function. However, the V8 binding currently doesn't support it. To
make it possible, this change introduces "V8WrapAsFunction"
extended attribute for annotating CustomElementConstructor IDL
interface.

V8WrapAsFunction wraps the annotated interface with a JavaScript
function, which calls the original object as a function, or as a
constructor depends on the context.

With this wrapper function, there are two levels of indirection
between native C++ object and author-visible JS function:

[JS Adaptor Function] <-(hidden property)-> [JS Wrapper Object] -(internal field)-> [C++ Native object]

The code generator generates the binding code which deals with
this indirection.  Also, there is a set of helper functions in
V8AdaptorFunction.h/cpp which takes care of this indirection.
V8DOMWrapper.cpp/h works as a facade for these APIs and is used from
the generated code.

This redundancy comes from limitations of both V8 bindings and V8
embedding API. See bug 108138 for details.

= V8HTMLCustomElement

Unlike built-in HTML elements, any custom element has no
corresponding C++ class. Instead, document.register() should allow
passing a prototype object for the elements being registered.

V8HTMLCustomElement handles this lack of native class.  It behaves
like a native side proxy of non-native HTMLElement subclasses.  It
connects each custom element to an appropriate native element,
which is HTMLElement at this time. This restriction will be
relaxed later. See Bug 110436 for details.

= Custom DOM elements and multiple worlds

In this patch, custom element registration and instantiation is not allowed
in non-main world and document.register() API just fails there.

Reviewed by Adam Barth.

Tests: fast/dom/custom/document-register-basic.html
       fast/dom/custom/document-register-reentrant-null-constructor.html
       fast/dom/custom/document-register-reentrant-returning-fake.html
       fast/dom/custom/document-register-reentrant-throwing-constructor.html

* DerivedSources.make:
* WebCore.gypi:
* bindings/generic/RuntimeEnabledFeatures.cpp:
* bindings/generic/RuntimeEnabledFeatures.h:
(RuntimeEnabledFeatures):
(WebCore::RuntimeEnabledFeatures::customDOMElementsEnabled):
(WebCore::RuntimeEnabledFeatures::setCustomDOMElements):
* bindings/scripts/CodeGeneratorV8.pm:
(GenerateHeader):
* bindings/scripts/IDLAttributes.txt:
* bindings/v8/CustomElementHelpers.cpp: Added.
(WebCore::CustomElementHelpers::initializeConstructorWrapper):
(WebCore::hasNoBuiltinsInPrototype):
(WebCore::CustomElementHelpers::isValidPrototypeParameter):
(WebCore::CustomElementHelpers::isFeatureAllowed):
* bindings/v8/CustomElementHelpers.h: Copied from Source/WebCore/bindings/v8/V8HiddenPropertyName.h.
(CustomElementHelpers):
* bindings/v8/V8AdaptorFunction.cpp: Added.
(WebCore::V8AdaptorFunction::getTemplate):
(WebCore::V8AdaptorFunction::configureTemplate):
(WebCore::V8AdaptorFunction::invocationCallback):
(WebCore::V8AdaptorFunction::wrap):
* bindings/v8/V8AdaptorFunction.h: Added.
(V8AdaptorFunction):
(WebCore::V8AdaptorFunction::unwrap):
(WebCore::V8AdaptorFunction::get):
* bindings/v8/V8DOMConfiguration.cpp:
(WebCore::V8DOMConfiguration::configureTemplate):
* bindings/v8/V8DOMWrapper.cpp:
(WebCore::V8DOMWrapper::toFunction):
(WebCore::V8DOMWrapper::fromFunction):
* bindings/v8/V8DOMWrapper.h:
(V8DOMWrapper):
* bindings/v8/V8HTMLCustomElement.cpp: Added.
(WebCore::V8HTMLCustomElement::createWrapper):
* bindings/v8/V8HTMLCustomElement.h: Copied from Source/WebCore/bindings/v8/V8HiddenPropertyName.h.
(V8HTMLCustomElement):
(WebCore::V8HTMLCustomElement::toV8):
(WebCore::HTMLCustomElement::toV8):
* bindings/v8/V8HiddenPropertyName.h:
* bindings/v8/custom/V8CustomElementConstructorCustom.cpp: Added.
(WebCore::V8CustomElementConstructor::callAsFunctionCallback):
* dom/CustomElementConstructor.cpp: Copied from Source/WebCore/bindings/v8/V8HiddenPropertyName.h.
(WebCore::CustomElementConstructor::create):
(WebCore::CustomElementConstructor::CustomElementConstructor):
(WebCore::CustomElementConstructor::~CustomElementConstructor):
(WebCore::CustomElementConstructor::createElement):
* dom/CustomElementConstructor.h: Copied from Source/WebCore/bindings/v8/V8HiddenPropertyName.h.
(CustomElementConstructor):
(WebCore::CustomElementConstructor::document):
(WebCore::CustomElementConstructor::tagName):
(WebCore::CustomElementConstructor::name):
* dom/CustomElementConstructor.idl: Added.
* dom/CustomElementRegistry.cpp: Added.
(WebCore::CustomElementRegistry::CustomElementRegistry):
(WebCore::CustomElementRegistry::~CustomElementRegistry):
(WebCore::CustomElementRegistry::constructorOf):
(WebCore::CustomElementRegistry::isValidName):
(WebCore::CustomElementRegistry::registerElement):
(WebCore::CustomElementRegistry::find):
(WebCore::CustomElementRegistry::createElement):
(WebCore::CustomElementRegistry::document):
* dom/CustomElementRegistry.h: Added.
(CustomElementRegistry):
* dom/Document.cpp:
(WebCore::Document::removedLastRef):
(WebCore::Document::registerElement):
(WebCore::Document::registry):
* dom/Document.h:
(Document):
* dom/make_names.pl:
(printWrapperFactoryCppFile):
* html/HTMLDocument.idl:

Source/WebKit/chromium:

Added enableCustomDOMElements flag.

* features.gypi:
* public/WebRuntimeFeatures.h:
(WebRuntimeFeatures):
* src/WebRuntimeFeatures.cpp:
(WebKit::WebRuntimeFeatures::enableCustomDOMElements):
(WebKit):
(WebKit::WebRuntimeFeatures::isCustomDOMElementsEnabled):

Tools:

Added enableCustomDOMElements flag.

* DumpRenderTree/chromium/TestShell.cpp:
(TestShell::TestShell):

LayoutTests:

* fast/dom/custom/document-register-basic-expected.txt: Added.
* fast/dom/custom/document-register-basic.html: Added.
* fast/dom/custom/document-register-reentrant-null-constructor-expected.txt: Added.
* fast/dom/custom/document-register-reentrant-null-constructor.html: Added.
* fast/dom/custom/document-register-reentrant-returning-fake-expected.txt: Added.
* fast/dom/custom/document-register-reentrant-returning-fake.html: Added.
* fast/dom/custom/document-register-reentrant-throwing-constructor-expected.txt: Added.
* fast/dom/custom/document-register-reentrant-throwing-constructor.html: Added.
* fast/dom/custom/resources/document-register-fuzz.js: Added.
* platform/mac/TestExpectations:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@143865 268f45cc-cd09-0410-ab3c-d52691b4dbfc
44 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/dom/custom/document-register-basic-expected.txt [new file with mode: 0644]
LayoutTests/fast/dom/custom/document-register-basic.html [new file with mode: 0644]
LayoutTests/fast/dom/custom/document-register-reentrant-null-constructor-expected.txt [new file with mode: 0644]
LayoutTests/fast/dom/custom/document-register-reentrant-null-constructor.html [new file with mode: 0644]
LayoutTests/fast/dom/custom/document-register-reentrant-returning-fake-expected.txt [new file with mode: 0644]
LayoutTests/fast/dom/custom/document-register-reentrant-returning-fake.html [new file with mode: 0644]
LayoutTests/fast/dom/custom/document-register-reentrant-throwing-constructor-expected.txt [new file with mode: 0644]
LayoutTests/fast/dom/custom/document-register-reentrant-throwing-constructor.html [new file with mode: 0644]
LayoutTests/fast/dom/custom/resources/document-register-fuzz.js [new file with mode: 0644]
LayoutTests/platform/mac/TestExpectations
Source/WebCore/ChangeLog
Source/WebCore/DerivedSources.make
Source/WebCore/WebCore.gypi
Source/WebCore/bindings/generic/RuntimeEnabledFeatures.cpp
Source/WebCore/bindings/generic/RuntimeEnabledFeatures.h
Source/WebCore/bindings/scripts/CodeGeneratorV8.pm
Source/WebCore/bindings/scripts/IDLAttributes.txt
Source/WebCore/bindings/v8/CustomElementHelpers.cpp [new file with mode: 0644]
Source/WebCore/bindings/v8/CustomElementHelpers.h [new file with mode: 0644]
Source/WebCore/bindings/v8/V8AdaptorFunction.cpp [new file with mode: 0644]
Source/WebCore/bindings/v8/V8AdaptorFunction.h [new file with mode: 0644]
Source/WebCore/bindings/v8/V8DOMConfiguration.cpp
Source/WebCore/bindings/v8/V8DOMWrapper.cpp
Source/WebCore/bindings/v8/V8DOMWrapper.h
Source/WebCore/bindings/v8/V8HTMLCustomElement.cpp [new file with mode: 0644]
Source/WebCore/bindings/v8/V8HTMLCustomElement.h [new file with mode: 0644]
Source/WebCore/bindings/v8/V8HiddenPropertyName.h
Source/WebCore/bindings/v8/custom/V8CustomElementConstructorCustom.cpp [new file with mode: 0644]
Source/WebCore/dom/CustomElementConstructor.cpp [new file with mode: 0644]
Source/WebCore/dom/CustomElementConstructor.h [new file with mode: 0644]
Source/WebCore/dom/CustomElementConstructor.idl [new file with mode: 0644]
Source/WebCore/dom/CustomElementRegistry.cpp [new file with mode: 0644]
Source/WebCore/dom/CustomElementRegistry.h [new file with mode: 0644]
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/Document.h
Source/WebCore/dom/make_names.pl
Source/WebCore/html/HTMLDocument.idl
Source/WebKit/chromium/ChangeLog
Source/WebKit/chromium/features.gypi
Source/WebKit/chromium/public/WebRuntimeFeatures.h
Source/WebKit/chromium/src/WebRuntimeFeatures.cpp
Tools/ChangeLog
Tools/DumpRenderTree/chromium/TestShell.cpp