Changeset 145932 in webkit
- Timestamp:
- Mar 15, 2013 1:12:15 PM (11 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 34 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r145929 r145932 1 2013-03-15 Hajime Morrita <morrita@google.com> 2 3 [Custom Elements] Any HTMLElement subclass should become a superclass of custom element 4 https://bugs.webkit.org/show_bug.cgi?id=110436 5 6 Reviewed by Dimitri Glazkov. 7 8 * fast/dom/custom/document-register-basic-expected.txt: 9 * fast/dom/custom/document-register-basic.html: 10 * fast/dom/custom/document-register-type-extensions-expected.txt: Added. 11 * fast/dom/custom/document-register-type-extensions.html: Added. 12 1 13 2013-03-15 Joshua Bell <jsbell@chromium.org> 2 14 -
trunk/LayoutTests/fast/dom/custom/document-register-basic-expected.txt
r145175 r145932 15 15 PASS document.register('x-bad-b', { prototype: {} }) threw exception Error: InvalidStateError: DOM Exception 11. 16 16 PASS document.register('x-bad-c', { prototype: Object.create(Document.prototype) }) threw exception Error: InvalidStateError: DOM Exception 11. 17 PASS document.register('x-bad-d', { prototype: Object.create(HTMLSpanElement.prototype) }) threw exception Error: InvalidStateError: DOM Exception 11.18 17 PASS fooConstructor() threw exception TypeError: DOM object constructor cannot be called as a function.. 19 18 PASS createdFoo.__proto__ is fooConstructor.prototype -
trunk/LayoutTests/fast/dom/custom/document-register-basic.html
r145175 r145932 40 40 // Bad prototype: wrong __proto__ 41 41 shouldThrow("document.register('x-bad-c', { prototype: Object.create(Document.prototype) })", "'Error: InvalidStateError: DOM Exception 11'"); 42 // Bug 110436 - Elements other than HTMLEmement should be allowed as a superclass.43 shouldThrow("document.register('x-bad-d', { prototype: Object.create(HTMLSpanElement.prototype) })", "'Error: InvalidStateError: DOM Exception 11'");44 42 // Call as function 45 43 shouldThrow("fooConstructor()", "'TypeError: DOM object constructor cannot be called as a function.'") -
trunk/Source/WebCore/ChangeLog
r145930 r145932 1 2013-03-15 Hajime Morrita <morrita@google.com> 2 3 [Custom Elements] Any HTMLElement subclass should become a superclass of custom element 4 https://bugs.webkit.org/show_bug.cgi?id=110436 5 6 Reviewed by Dimitri Glazkov. 7 8 This change introduces "type extension" concept of custom elements. 9 With the type extension, each custom elements are able to inherit 10 from not only HTMLElement, but also any HTML element. To make it work, 11 this change extends the plumbing. 12 13 This change does following changes: 14 15 = Data structure: 16 17 - Let CustomElementConstructor objects being keyed by pair of (element 18 name, local name) as the standard requries, instead of just using 19 single name. See CustomElementRegistry::ConstructorMap and CustomElementRegistry::find(). 20 21 - Creates mapping from WrapperTypeInfo to element name. This map 22 can be looked-up by generated functions like 23 findHTMLTagNameOfV8Type(). With this table, WebKit can determine 24 the custom element local name of given prototype object. See make_names.pl. 25 Note that V8 prototype object knows associated WrapperTypeInfo. See r144865. 26 27 = Hooking up element lifecyle: 28 29 - Create appropriate C++ instance for each custom element. Before 30 this change, the C++ backend of custom elements were always 31 HTMLUnknownElements or HTMLElement. See 32 CustomElementConstructor::createElement() and ElementFactories in 33 make_names.pl. 34 35 - Hooks up element construction and element wrapper creation for 36 custom element "before" non-custom case instead of "after" 37 that. We do this because custom element needs to 38 override non-custom case when @is attribute is given for 39 otherwise-non-custom elements like <div is=x-bar>. 40 See make_names.pl. 41 42 - Gives @is attributes to elements if needed. See setTypeExtension() call sites 43 like Document::createElement(), Document::createElementtNS() and CustomElementConstructor::createElementt() 44 45 Test: fast/dom/custom/document-register-type-extensions.html 46 47 * bindings/scripts/CodeGeneratorV8.pm: 48 (GenerateHeader): 49 * bindings/scripts/test/V8/V8Float64Array.h: 50 * bindings/scripts/test/V8/V8TestActiveDOMObject.h: 51 * bindings/scripts/test/V8/V8TestCustomNamedGetter.h: 52 * bindings/scripts/test/V8/V8TestEventConstructor.h: 53 * bindings/scripts/test/V8/V8TestEventTarget.h: 54 * bindings/scripts/test/V8/V8TestException.h: 55 * bindings/scripts/test/V8/V8TestInterface.h: 56 * bindings/scripts/test/V8/V8TestMediaQueryListListener.h: 57 * bindings/scripts/test/V8/V8TestNamedConstructor.h: 58 * bindings/scripts/test/V8/V8TestNode.h: 59 * bindings/scripts/test/V8/V8TestObj.h: 60 * bindings/scripts/test/V8/V8TestOverloadedConstructors.h: 61 * bindings/scripts/test/V8/V8TestSerializedScriptValueInterface.h: 62 * bindings/scripts/test/V8/V8TestTypedefs.h: 63 * bindings/v8/CustomElementHelpers.cpp: 64 (WebCore::hasValidPrototypeChain): 65 (WebCore::CustomElementHelpers::isValidPrototypeParameter): 66 (WebCore::CustomElementHelpers::findLocalName): 67 (WebCore): 68 (WebCore::CustomElementHelpers::findWrapperType): 69 * bindings/v8/CustomElementHelpers.h: 70 (CustomElementHelpers): 71 * bindings/v8/V8CustomElement.cpp: 72 (WebCore::V8CustomElement::createWrapper): 73 * bindings/v8/V8CustomElement.h: 74 (V8CustomElement): 75 (WebCore::V8CustomElement::wrap): 76 (WebCore::V8CustomElement::constructorOf): 77 * bindings/v8/WrapperTypeInfo.h: 78 (WrapperTypeTraits): Added. 79 * bindings/v8/custom/V8CustomElementConstructorCustom.cpp: 80 (WebCore::V8CustomElementConstructor::callAsFunctionCallback): 81 * dom/CustomElementConstructor.cpp: 82 (WebCore::CustomElementConstructor::create): 83 (WebCore::CustomElementConstructor::CustomElementConstructor): 84 (WebCore::CustomElementConstructor::createElement): 85 (WebCore::setTypeExtension): 86 * dom/CustomElementConstructor.h: 87 (CustomElementConstructor): 88 (WebCore::CustomElementConstructor::document): 89 (WebCore::CustomElementConstructor::typeName): 90 (WebCore::CustomElementConstructor::localName): 91 * dom/CustomElementRegistry.cpp: 92 (WebCore::nameIncludesHyphen): 93 (WebCore::CustomElementRegistry::isValidName): 94 (WebCore::CustomElementRegistry::registerElement): 95 (WebCore::CustomElementRegistry::findFor): 96 (WebCore::CustomElementRegistry::find): 97 (WebCore::CustomElementRegistry::createElement): 98 * dom/CustomElementRegistry.h: 99 (CustomElementRegistry): 100 * dom/Document.cpp: 101 (WebCore::Document::createElement): 102 (WebCore::Document::createElementNS): 103 (WebCore::Document::registerElement): 104 * dom/Document.h: 105 (Document): 106 (WebCore::Document::registry): Moved from Document.cpp to be inlined. 107 * dom/Document.idl: 108 * dom/make_names.pl: 109 (printFactoryCppFile): 110 (printWrapperFactoryCppFile): 111 (printWrapperFactoryHeaderFile): 112 * html/HTMLAttributeNames.in: Added @is attribute 113 1 114 2013-03-15 Alexey Proskuryakov <ap@apple.com> 2 115 -
trunk/Source/WebCore/bindings/scripts/CodeGeneratorV8.pm
r145929 r145932 514 514 515 515 push(@headerContent, <<END); 516 }; 517 518 template<> 519 class WrapperTypeTraits<${nativeType} > { 520 public: 521 static WrapperTypeInfo* info() { return &${v8InterfaceName}::info; } 516 522 }; 517 523 -
trunk/Source/WebCore/bindings/scripts/test/V8/V8Float64Array.h
r145906 r145932 54 54 }; 55 55 56 template<> 57 class WrapperTypeTraits<Float64Array > { 58 public: 59 static WrapperTypeInfo* info() { return &V8Float64Array::info; } 60 }; 61 56 62 57 63 v8::Handle<v8::Object> wrap(Float64Array* impl, v8::Handle<v8::Object> creationContext, v8::Isolate*); -
trunk/Source/WebCore/bindings/scripts/test/V8/V8TestActiveDOMObject.h
r145906 r145932 52 52 }; 53 53 54 template<> 55 class WrapperTypeTraits<TestActiveDOMObject > { 56 public: 57 static WrapperTypeInfo* info() { return &V8TestActiveDOMObject::info; } 58 }; 59 54 60 55 61 inline v8::Handle<v8::Object> wrap(TestActiveDOMObject* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) -
trunk/Source/WebCore/bindings/scripts/test/V8/V8TestCustomNamedGetter.h
r145906 r145932 53 53 }; 54 54 55 template<> 56 class WrapperTypeTraits<TestCustomNamedGetter > { 57 public: 58 static WrapperTypeInfo* info() { return &V8TestCustomNamedGetter::info; } 59 }; 60 55 61 56 62 inline v8::Handle<v8::Object> wrap(TestCustomNamedGetter* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) -
trunk/Source/WebCore/bindings/scripts/test/V8/V8TestEventConstructor.h
r145906 r145932 54 54 }; 55 55 56 template<> 57 class WrapperTypeTraits<TestEventConstructor > { 58 public: 59 static WrapperTypeInfo* info() { return &V8TestEventConstructor::info; } 60 }; 61 56 62 57 63 inline v8::Handle<v8::Object> wrap(TestEventConstructor* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) -
trunk/Source/WebCore/bindings/scripts/test/V8/V8TestEventTarget.h
r145906 r145932 56 56 }; 57 57 58 template<> 59 class WrapperTypeTraits<TestEventTarget > { 60 public: 61 static WrapperTypeInfo* info() { return &V8TestEventTarget::info; } 62 }; 63 58 64 59 65 inline v8::Handle<v8::Object> wrap(TestEventTarget* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) -
trunk/Source/WebCore/bindings/scripts/test/V8/V8TestException.h
r145906 r145932 52 52 }; 53 53 54 template<> 55 class WrapperTypeTraits<TestException > { 56 public: 57 static WrapperTypeInfo* info() { return &V8TestException::info; } 58 }; 59 54 60 55 61 inline v8::Handle<v8::Object> wrap(TestException* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) -
trunk/Source/WebCore/bindings/scripts/test/V8/V8TestInterface.h
r145906 r145932 56 56 }; 57 57 58 template<> 59 class WrapperTypeTraits<TestInterface > { 60 public: 61 static WrapperTypeInfo* info() { return &V8TestInterface::info; } 62 }; 63 58 64 59 65 inline v8::Handle<v8::Object> wrap(TestInterface* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) -
trunk/Source/WebCore/bindings/scripts/test/V8/V8TestMediaQueryListListener.h
r145906 r145932 52 52 }; 53 53 54 template<> 55 class WrapperTypeTraits<TestMediaQueryListListener > { 56 public: 57 static WrapperTypeInfo* info() { return &V8TestMediaQueryListListener::info; } 58 }; 59 54 60 55 61 inline v8::Handle<v8::Object> wrap(TestMediaQueryListListener* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) -
trunk/Source/WebCore/bindings/scripts/test/V8/V8TestNamedConstructor.h
r145906 r145932 59 59 }; 60 60 61 template<> 62 class WrapperTypeTraits<TestNamedConstructor > { 63 public: 64 static WrapperTypeInfo* info() { return &V8TestNamedConstructor::info; } 65 }; 66 61 67 62 68 inline v8::Handle<v8::Object> wrap(TestNamedConstructor* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) -
trunk/Source/WebCore/bindings/scripts/test/V8/V8TestNode.h
r145906 r145932 54 54 }; 55 55 56 template<> 57 class WrapperTypeTraits<TestNode > { 58 public: 59 static WrapperTypeInfo* info() { return &V8TestNode::info; } 60 }; 61 56 62 57 63 inline v8::Handle<v8::Object> wrap(TestNode* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) -
trunk/Source/WebCore/bindings/scripts/test/V8/V8TestObj.h
r145906 r145932 58 58 }; 59 59 60 template<> 61 class WrapperTypeTraits<TestObj > { 62 public: 63 static WrapperTypeInfo* info() { return &V8TestObj::info; } 64 }; 65 60 66 61 67 inline v8::Handle<v8::Object> wrap(TestObj* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) -
trunk/Source/WebCore/bindings/scripts/test/V8/V8TestOverloadedConstructors.h
r145906 r145932 53 53 }; 54 54 55 template<> 56 class WrapperTypeTraits<TestOverloadedConstructors > { 57 public: 58 static WrapperTypeInfo* info() { return &V8TestOverloadedConstructors::info; } 59 }; 60 55 61 56 62 inline v8::Handle<v8::Object> wrap(TestOverloadedConstructors* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) -
trunk/Source/WebCore/bindings/scripts/test/V8/V8TestSerializedScriptValueInterface.h
r145906 r145932 54 54 }; 55 55 56 template<> 57 class WrapperTypeTraits<TestSerializedScriptValueInterface > { 58 public: 59 static WrapperTypeInfo* info() { return &V8TestSerializedScriptValueInterface::info; } 60 }; 61 56 62 57 63 inline v8::Handle<v8::Object> wrap(TestSerializedScriptValueInterface* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) -
trunk/Source/WebCore/bindings/scripts/test/V8/V8TestTypedefs.h
r145906 r145932 53 53 }; 54 54 55 template<> 56 class WrapperTypeTraits<TestTypedefs > { 57 public: 58 static WrapperTypeInfo* info() { return &V8TestTypedefs::info; } 59 }; 60 55 61 56 62 inline v8::Handle<v8::Object> wrap(TestTypedefs* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) -
trunk/Source/WebCore/bindings/v8/CustomElementHelpers.cpp
r144587 r145932 34 34 #include "DOMWrapperWorld.h" 35 35 #include "V8CustomElementConstructor.h" 36 #include "V8HTMLElementWrapperFactory.h" 36 37 #include "V8HTMLParagraphElement.h" 37 38 #include "V8HTMLSpanElement.h" … … 64 65 } 65 66 66 // See FIXME on the caller side comment. 67 static bool hasNoBuiltinsInPrototype(v8::Handle<v8::Object> htmlPrototype, v8::Handle<v8::Value> chain) 67 static bool hasValidPrototypeChain(v8::Handle<v8::Object> requiredAncestor, v8::Handle<v8::Value> chain) 68 68 { 69 while (!chain.IsEmpty() ) {70 if (chain == htmlPrototype)69 while (!chain.IsEmpty() && chain->IsObject()) { 70 if (chain == requiredAncestor) 71 71 return true; 72 if (!chain->IsObject())73 return false;74 // The internal field count indicates the object might be a native backed, built-in object.75 if (v8::Handle<v8::Object>::Cast(chain)->InternalFieldCount())76 return false;77 72 chain = v8::Handle<v8::Object>::Cast(chain)->GetPrototype(); 78 73 } … … 91 86 return false; 92 87 V8PerContextData* perContextData = V8PerContextData::from(state->context()); 93 // 94 // FIXME: https://bugs.webkit.org/show_bug.cgi?id=110436 95 // document.register() should allow arbitrary HTMLElement subclassses. 96 // Currently it supports custom elements which are 97 // - direct subclasses of HTMLElement or 98 // - subclasses of other custom elements 99 // 88 // FIXME: non-HTML subclasses should be also supported: https://bugs.webkit.org/show_bug.cgi?id=111693 100 89 v8::Handle<v8::Object> htmlConstructor = v8::Handle<v8::Object>::Cast(perContextData->constructorForType(&V8HTMLElement::info)); 101 90 if (htmlConstructor.IsEmpty()) … … 104 93 if (htmlPrototype.IsEmpty()) 105 94 return false; 106 if (!has NoBuiltinsInPrototype(htmlPrototype, prototypeObject))95 if (!hasValidPrototypeChain(htmlPrototype, prototypeObject)) 107 96 return false; 108 97 return true; … … 121 110 } 122 111 112 const QualifiedName* CustomElementHelpers::findLocalName(const ScriptValue& prototype) 113 { 114 if (prototype.v8Value().IsEmpty() || !prototype.v8Value()->IsObject()) 115 return 0; 116 return findLocalName(v8::Handle<v8::Object>::Cast(prototype.v8Value())); 117 } 118 119 WrapperTypeInfo* CustomElementHelpers::findWrapperType(v8::Handle<v8::Value> chain) 120 { 121 while (!chain.IsEmpty() && chain->IsObject()) { 122 v8::Handle<v8::Object> chainObject = v8::Handle<v8::Object>::Cast(chain); 123 // Only prototype objects of native-backed types have the extra internal field storing WrapperTypeInfo. 124 if (v8PrototypeInternalFieldcount == chainObject->InternalFieldCount()) 125 return reinterpret_cast<WrapperTypeInfo*>(chainObject->GetAlignedPointerFromInternalField(v8PrototypeTypeIndex)); 126 chain = chainObject->GetPrototype(); 127 } 128 129 return 0; 130 } 131 132 // This can return null. In that case, we should take the element name as its local name. 133 const QualifiedName* CustomElementHelpers::findLocalName(v8::Handle<v8::Object> chain) 134 { 135 WrapperTypeInfo* type = CustomElementHelpers::findWrapperType(chain); 136 if (!type) 137 return 0; 138 return findHTMLTagNameOfV8Type(type); 139 } 123 140 124 141 #endif // ENABLE(CUSTOM_ELEMENTS) -
trunk/Source/WebCore/bindings/v8/CustomElementHelpers.h
r143865 r145932 40 40 41 41 class CustomElementConstructor; 42 class QualifiedName; 42 43 class ScriptState; 43 44 … … 47 48 static bool isValidPrototypeParameter(const ScriptValue&, ScriptState*); 48 49 static bool isFeatureAllowed(ScriptState*); 50 static const QualifiedName* findLocalName(const ScriptValue& prototype); 49 51 50 52 static bool isFeatureAllowed(v8::Handle<v8::Context>); 53 static WrapperTypeInfo* findWrapperType(v8::Handle<v8::Value> chain); 54 static const QualifiedName* findLocalName(v8::Handle<v8::Object> chain); 51 55 }; 52 56 -
trunk/Source/WebCore/bindings/v8/V8CustomElement.cpp
r145040 r145932 43 43 namespace WebCore { 44 44 45 static WrapperTypeInfo* findWrapperTypeOf(v8::Handle<v8::Value> chain) 46 { 47 while (!chain.IsEmpty() && chain->IsObject()) { 48 v8::Handle<v8::Object> chainObject = v8::Handle<v8::Object>::Cast(chain); 49 if (v8PrototypeInternalFieldcount == chainObject->InternalFieldCount()) 50 return reinterpret_cast<WrapperTypeInfo*>(chainObject->GetAlignedPointerFromInternalField(v8PrototypeTypeIndex)); 51 chain = chainObject->GetPrototype(); 52 } 53 54 return 0; 55 } 56 57 v8::Handle<v8::Object> V8CustomElement::createWrapper(PassRefPtr<Element> impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) 45 v8::Handle<v8::Object> V8CustomElement::createWrapper(PassRefPtr<Element> impl, v8::Handle<v8::Object> creationContext, PassRefPtr<CustomElementConstructor> constructor, v8::Isolate* isolate) 58 46 { 59 47 ASSERT(impl); 60 61 RefPtr<CustomElementConstructor> constructor = CustomElementRegistry::constructorOf(impl.get());62 if (!constructor) {63 v8::Handle<v8::Value> wrapperValue = WebCore::toV8(toHTMLUnknownElement(toHTMLElement(impl.get())), creationContext, isolate);64 if (!wrapperValue.IsEmpty() && wrapperValue->IsObject())65 return v8::Handle<v8::Object>::Cast(wrapperValue);66 return v8::Handle<v8::Object>();67 }68 48 69 49 // The constructor and registered lifecycle callbacks should be visible only from main world. … … 82 62 v8::Handle<v8::Object> constructorWapper = v8::Handle<v8::Object>::Cast(constructorValue); 83 63 v8::Handle<v8::Object> prototype = v8::Handle<v8::Object>::Cast(constructorWapper->Get(v8::String::NewSymbol("prototype"))); 84 WrapperTypeInfo* typeInfo = findWrapperTypeOf(prototype);64 WrapperTypeInfo* typeInfo = CustomElementHelpers::findWrapperType(prototype); 85 65 if (!typeInfo) 86 66 return v8::Handle<v8::Object>(); -
trunk/Source/WebCore/bindings/v8/V8CustomElement.h
r145040 r145932 32 32 #define V8CustomElement_h 33 33 34 #include "CustomElementConstructor.h" 35 #include "CustomElementRegistry.h" 36 #include "Document.h" 34 37 #include "V8Binding.h" 35 38 #include "V8DOMWrapper.h" … … 41 44 42 45 class Element; 46 class CustomElementConstructor; 43 47 44 48 #if ENABLE(CUSTOM_ELEMENTS) … … 46 50 class V8CustomElement { 47 51 public: 48 static v8::Handle<v8::Value> toV8(Element*, v8::Handle<v8::Object> creationContext = v8::Handle<v8::Object>(), v8::Isolate* = 0); 49 static v8::Handle<v8::Object> wrap(Element*, v8::Handle<v8::Object> creationContext, v8::Isolate*); 52 // 53 // You can just use toV8(Node*) to get correct wrapper objects, even for custom elements. 54 // Then generated ElementWrapperFactories call V8CustomElement::wrap() with proper CustomElementConstructor instances 55 // accordingly. 56 // 57 static v8::Handle<v8::Object> wrap(Element*, v8::Handle<v8::Object> creationContext, PassRefPtr<CustomElementConstructor>, v8::Isolate*); 58 static PassRefPtr<CustomElementConstructor> constructorOf(Element*); 50 59 51 60 private: 52 static v8::Handle<v8::Object> createWrapper(PassRefPtr<Element>, v8::Handle<v8::Object>, v8::Isolate*);61 static v8::Handle<v8::Object> createWrapper(PassRefPtr<Element>, v8::Handle<v8::Object>, PassRefPtr<CustomElementConstructor>, v8::Isolate*); 53 62 }; 54 63 55 inline v8::Handle<v8::Value> V8CustomElement::toV8(Element* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) 56 { 57 if (UNLIKELY(!impl)) 58 return v8NullWithCheck(isolate); 59 v8::Handle<v8::Object> wrapper = DOMDataStore::getWrapper(impl, isolate); 60 if (!wrapper.IsEmpty()) 61 return wrapper; 62 return V8CustomElement::wrap(impl, creationContext, isolate); 63 } 64 65 inline v8::Handle<v8::Object> V8CustomElement::wrap(Element* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) 64 inline v8::Handle<v8::Object> V8CustomElement::wrap(Element* impl, v8::Handle<v8::Object> creationContext, PassRefPtr<CustomElementConstructor> constructor, v8::Isolate* isolate) 66 65 { 67 66 ASSERT(impl); 68 67 ASSERT(DOMDataStore::getWrapper(impl, isolate).IsEmpty()); 69 return V8CustomElement::createWrapper(impl, creationContext, isolate);68 return V8CustomElement::createWrapper(impl, creationContext, constructor, isolate); 70 69 } 71 70 72 #else // ENABLE(CUSTOM_ELEMENTS) 73 74 class V8CustomElement { 75 public: 76 static v8::Handle<v8::Object> wrap(Element*, v8::Handle<v8::Object> creationContext = v8::Handle<v8::Object>(), v8::Isolate* = 0); 77 }; 78 79 inline v8::Handle<v8::Object> HTMLCustomElement::wrap(Element* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) 71 inline PassRefPtr<CustomElementConstructor> V8CustomElement::constructorOf(Element* element) 80 72 { 81 return wrap(toHTMLUnknownElement(impl), creationContext, isolate); 73 if (CustomElementRegistry* registry = element->document()->registry()) 74 return registry->findFor(element); 75 return 0; 82 76 } 83 77 -
trunk/Source/WebCore/bindings/v8/WrapperTypeInfo.h
r145575 r145932 179 179 return configuration; 180 180 } 181 182 template<class ElementType> 183 class WrapperTypeTraits { 184 // specialized classes have thier own functions, which are generated by binding generator. 185 }; 181 186 } 182 187 -
trunk/Source/WebCore/bindings/v8/custom/V8CustomElementConstructorCustom.cpp
r145040 r145932 49 49 if (!element) 50 50 return v8Undefined(); 51 return V8CustomElement:: toV8(element.get(), args.Holder(), args.GetIsolate());51 return V8CustomElement::wrap(element.get(), args.Holder(), impl, args.GetIsolate()); 52 52 } 53 53 -
trunk/Source/WebCore/dom/CustomElementConstructor.cpp
r145040 r145932 38 38 #include "Document.h" 39 39 #include "HTMLElement.h" 40 #include "HTMLNames.h" 40 41 #include <wtf/Assertions.h> 41 42 42 43 namespace WebCore { 43 44 44 PassRefPtr<CustomElementConstructor> CustomElementConstructor::create(ScriptState* state, Document* document, const QualifiedName& name, const ScriptValue& prototype)45 PassRefPtr<CustomElementConstructor> CustomElementConstructor::create(ScriptState* state, Document* document, const QualifiedName& typeName, const QualifiedName& localName, const ScriptValue& prototype) 45 46 { 46 RefPtr<CustomElementConstructor> created = adoptRef(new CustomElementConstructor(document, name)); 47 ASSERT(CustomElementHelpers::isValidPrototypeParameter(prototype, state)); 48 ASSERT(localName == typeName || localName == *CustomElementHelpers::findLocalName(prototype)); 49 RefPtr<CustomElementConstructor> created = adoptRef(new CustomElementConstructor(document, typeName, localName)); 47 50 if (!CustomElementHelpers::initializeConstructorWrapper(created.get(), prototype, state)) 48 51 return 0; … … 50 53 } 51 54 52 CustomElementConstructor::CustomElementConstructor(Document* document, const QualifiedName& name)55 CustomElementConstructor::CustomElementConstructor(Document* document, const QualifiedName& typeName, const QualifiedName& localName) 53 56 : ContextDestructionObserver(document) 54 , m_name(name) 57 , m_typeName(typeName) 58 , m_localName(localName) 55 59 { 56 60 } … … 64 68 if (!document()) 65 69 return 0; 66 return HTMLElement::create(m_name, document()); 70 if (m_localName != m_typeName) 71 return setTypeExtension(document()->createElement(m_localName, document()), m_typeName.localName()); 72 return HTMLElement::create(m_typeName, document()); 73 } 74 75 PassRefPtr<Element> setTypeExtension(PassRefPtr<Element> element, const AtomicString& typeExtension) 76 { 77 if (!typeExtension.isEmpty()) 78 element->setAttribute(HTMLNames::isAttr, typeExtension); 79 return element; 67 80 } 68 81 -
trunk/Source/WebCore/dom/CustomElementConstructor.h
r145745 r145932 49 49 class ScriptValue; 50 50 51 PassRefPtr<Element> setTypeExtension(PassRefPtr<Element>, const AtomicString& typeExtension); 52 51 53 class CustomElementConstructor : public RefCounted<CustomElementConstructor> , public ContextDestructionObserver { 52 54 public: 53 static PassRefPtr<CustomElementConstructor> create(ScriptState*, Document*, const QualifiedName& , const ScriptValue&);55 static PassRefPtr<CustomElementConstructor> create(ScriptState*, Document*, const QualifiedName& typeName, const QualifiedName& localName, const ScriptValue&); 54 56 55 57 virtual ~CustomElementConstructor(); 56 58 57 Document* document() const { return toDocument(m_scriptExecutionContext); } 58 const QualifiedName& name() const { return m_name; } 59 Document* document() const { return static_cast<Document*>(m_scriptExecutionContext); } 60 const QualifiedName& typeName() const { return m_typeName; } 61 const QualifiedName& localName() const { return m_localName; } 59 62 60 63 PassRefPtr<Element> createElement() const; 61 64 62 65 private: 63 CustomElementConstructor(Document*, const QualifiedName& );66 CustomElementConstructor(Document*, const QualifiedName& typeName, const QualifiedName& localName); 64 67 65 QualifiedName m_name; 68 QualifiedName m_typeName; 69 QualifiedName m_localName; 66 70 }; 67 71 -
trunk/Source/WebCore/dom/CustomElementRegistry.cpp
r145745 r145932 41 41 #include "Element.h" 42 42 #include "HTMLNames.h" 43 #include "HTMLUnknownElement.h" 43 44 #include "RuntimeEnabledFeatures.h" 44 45 #include <wtf/ASCIICType.h> … … 63 64 } 64 65 65 PassRefPtr<CustomElementConstructor> CustomElementRegistry::constructorOf(Element* element) 66 { 67 RefPtr<CustomElementRegistry> self = element->document()->registry(); 68 if (!self) 69 return 0; 70 return self->find(element->tagQName()); 66 static inline bool nameIncludesHyphen(const AtomicString& name) 67 { 68 size_t hyphenPosition = name.find('-'); 69 return (hyphenPosition != notFound); 71 70 } 72 71 73 72 bool CustomElementRegistry::isValidName(const AtomicString& name) 74 73 { 75 size_t hyphenPosition = name.find('-'); 76 if (hyphenPosition == notFound) 74 if (!nameIncludesHyphen(name)) 77 75 return false; 78 76 … … 113 111 } 114 112 115 if (find(newName)) {116 ec = INVALID_STATE_ERR;117 return 0;118 }119 120 113 ScriptValue prototypeValue; 121 114 if (!options.get("prototype", prototypeValue)) { … … 133 126 return 0; 134 127 } 128 129 if (m_names.contains(newName)) { 130 ec = INVALID_STATE_ERR; 131 return 0; 132 } 133 134 const QualifiedName* localNameFound = CustomElementHelpers::findLocalName(prototypeValue); 135 QualifiedName localNameToUse = localNameFound ? *localNameFound : newName; 136 if (find(newName, localNameToUse)) { 137 ec = INVALID_STATE_ERR; 138 return 0; 139 } 135 140 136 // A nscript execution could happen in isValidPrototypeParameter(), which kills the document.141 // A script execution could happen in isValidPrototypeParameter(), which kills the document. 137 142 if (!document()) { 138 143 ec = INVALID_STATE_ERR; … … 140 145 } 141 146 142 RefPtr<CustomElementConstructor> constructor = CustomElementConstructor::create(state, document(), newName, prototypeValue);147 RefPtr<CustomElementConstructor> constructor = CustomElementConstructor::create(state, document(), newName, localNameToUse, prototypeValue); 143 148 if (!constructor) { 144 149 ec = INVALID_STATE_ERR; … … 146 151 } 147 152 148 m_constructors.add(constructor->name().impl(), constructor); 153 m_constructors.add(std::make_pair(constructor->typeName(), constructor->localName()), constructor); 154 m_names.add(constructor->typeName()); 155 149 156 return constructor; 150 157 } 151 158 152 PassRefPtr<CustomElementConstructor> CustomElementRegistry::find(const QualifiedName& name) const 153 { 154 ConstructorMap::const_iterator found = m_constructors.find(name.impl()); 155 return (found != m_constructors.end()) ? found->value : 0; 156 } 157 158 PassRefPtr<Element> CustomElementRegistry::createElement(const QualifiedName& name) const 159 { 160 if (RefPtr<CustomElementConstructor> found = find(name)) 161 return found->createElement(); 159 PassRefPtr<CustomElementConstructor> CustomElementRegistry::findFor(Element* element) const 160 { 161 ASSERT(element->document()->registry() == this); 162 163 // Most elements can be rejected this quick screening. 164 if (!nameIncludesHyphen(element->tagName()) && !element->hasAttribute(HTMLNames::isAttr)) 165 return 0; 166 167 QualifiedName idValue(nullAtom, element->getAttribute(HTMLNames::isAttr), HTMLNames::xhtmlNamespaceURI); 168 return find(idValue, element->tagQName()); 169 } 170 171 PassRefPtr<CustomElementConstructor> CustomElementRegistry::find(const QualifiedName& typeName, const QualifiedName& localName) const 172 { 173 ConstructorMap::const_iterator found = m_constructors.end(); 174 if (!typeName.localName().isEmpty()) 175 found = m_constructors.find(std::make_pair(typeName, localName)); 176 if (found == m_constructors.end()) 177 found = m_constructors.find(std::make_pair(localName, localName)); 178 if (found == m_constructors.end()) 179 return 0; 180 return found->value; 181 } 182 183 PassRefPtr<Element> CustomElementRegistry::createElement(const QualifiedName& localName, const AtomicString& typeExtension) const 184 { 185 const QualifiedName& typeName = QualifiedName(nullAtom, typeExtension, localName.namespaceURI()); 186 if (RefPtr<CustomElementConstructor> found = find(typeName, localName)) { 187 RefPtr<Element> created = found->createElement(); 188 if (!typeName.localName().isEmpty() && localName != typeName) 189 return setTypeExtension(created, typeExtension); 190 return created.release(); 191 } 192 162 193 return 0; 163 194 } -
trunk/Source/WebCore/dom/CustomElementRegistry.h
r145040 r145932 40 40 #include "Supplementable.h" 41 41 #include <wtf/Forward.h> 42 #include <wtf/HashSet.h> 42 43 #include <wtf/PassRefPtr.h> 43 44 #include <wtf/RefCounted.h> … … 60 61 61 62 PassRefPtr<CustomElementConstructor> registerElement(WebCore::ScriptState*, const AtomicString& name, const Dictionary& options, ExceptionCode&); 62 PassRefPtr<CustomElementConstructor> find(const QualifiedName&) const; 63 PassRefPtr<Element> createElement(const QualifiedName&) const; 63 PassRefPtr<CustomElementConstructor> findFor(Element*) const; 64 PassRefPtr<CustomElementConstructor> find(const QualifiedName& elementName, const QualifiedName& localName) const; 65 PassRefPtr<Element> createElement(const QualifiedName& localName, const AtomicString& typeExtension) const; 66 64 67 Document* document() const; 65 68 66 static PassRefPtr<CustomElementConstructor> constructorOf(Element*);67 68 69 private: 69 70 static bool isValidName(const AtomicString&); 70 71 71 typedef HashMap<QualifiedName::QualifiedNameImpl*, RefPtr<CustomElementConstructor> >ConstructorMap; 72 typedef HashMap<std::pair<QualifiedName, QualifiedName>, RefPtr<CustomElementConstructor> > ConstructorMap; 73 typedef HashSet<QualifiedName> NameSet; 72 74 73 75 ConstructorMap m_constructors; 76 NameSet m_names; 74 77 }; 75 78 -
trunk/Source/WebCore/dom/Document.cpp
r145914 r145932 843 843 844 844 #if ENABLE(CUSTOM_ELEMENTS) 845 PassRefPtr<Element> Document::createElement(const AtomicString& localName, const AtomicString& typeExtension, ExceptionCode& ec) 846 { 847 if (!isValidName(localName)) { 848 ec = INVALID_CHARACTER_ERR; 849 return 0; 850 } 851 852 if (m_registry) { 853 if (PassRefPtr<Element> created = m_registry->createElement(QualifiedName(nullAtom, localName, xhtmlNamespaceURI), typeExtension)) 854 return created; 855 } 856 857 return setTypeExtension(createElement(localName, ec), typeExtension); // FIXME: take care of @is 858 } 859 860 PassRefPtr<Element> Document::createElementNS(const AtomicString& namespaceURI, const String& qualifiedName, const AtomicString& typeExtension, ExceptionCode& ec) 861 { 862 String prefix, localName; 863 if (!parseQualifiedName(qualifiedName, prefix, localName, ec)) 864 return 0; 865 866 QualifiedName qName(prefix, localName, namespaceURI); 867 if (!hasValidNamespaceForElements(qName)) { 868 ec = NAMESPACE_ERR; 869 return 0; 870 } 871 872 if (m_registry) { 873 if (PassRefPtr<Element> created = m_registry->createElement(qName, typeExtension)) 874 return created; 875 } 876 877 return setTypeExtension(createElementNS(namespaceURI, qualifiedName, ec), typeExtension); 878 } 879 845 880 PassRefPtr<CustomElementConstructor> Document::registerElement(WebCore::ScriptState* state, const AtomicString& name, ExceptionCode& ec) 846 881 { … … 858 893 m_registry = adoptRef(new CustomElementRegistry(this)); 859 894 return m_registry->registerElement(state, name, options, ec); 860 }861 862 PassRefPtr<CustomElementRegistry> Document::registry() const863 {864 return m_registry;865 895 } 866 896 #endif // ENABLE(CUSTOM_ELEMENTS) -
trunk/Source/WebCore/dom/Document.h
r145826 r145932 1161 1161 1162 1162 #if ENABLE(CUSTOM_ELEMENTS) 1163 PassRefPtr<Element> createElement(const AtomicString& localName, const AtomicString& typeExtension, ExceptionCode&); 1164 PassRefPtr<Element> createElementNS(const AtomicString& namespaceURI, const String& qualifiedName, const AtomicString& typeExtension, ExceptionCode&); 1163 1165 PassRefPtr<CustomElementConstructor> registerElement(WebCore::ScriptState*, const AtomicString& name, ExceptionCode&); 1164 1166 PassRefPtr<CustomElementConstructor> registerElement(WebCore::ScriptState*, const AtomicString& name, const Dictionary& options, ExceptionCode&); 1165 PassRefPtr<CustomElementRegistry> registry() const;1167 CustomElementRegistry* registry() const { return m_registry.get(); } 1166 1168 #endif 1167 1169 -
trunk/Source/WebCore/dom/Document.idl
r145787 r145932 364 364 [V8EnabledAtRuntime=customDOMElements, Conditional=CUSTOM_ELEMENTS, ImplementedAs=registerElement, CallWith=ScriptState] 365 365 CustomElementConstructor webkitRegister(in DOMString name, in [Optional] Dictionary options) raises(DOMException); 366 [ReturnNewObject] Element createElement(in DOMString localName, in [TreatNullAs=NullString] DOMString typeExtension) raises (DOMException); 367 [ReturnNewObject] Element createElementNS(in [TreatNullAs=NullString] DOMString namespaceURI, in DOMString qualifiedName, 368 in [TreatNullAs=NullString] DOMString typeExtension) raises (DOMException); 366 369 #endif 367 370 -
trunk/Source/WebCore/dom/make_names.pl
r145040 r145932 824 824 #include "RuntimeEnabledFeatures.h" 825 825 826 #if ENABLE(CUSTOM_ELEMENTS) 827 #include "CustomElementConstructor.h" 828 #include "CustomElementRegistry.h" 829 #endif 830 826 831 #if ENABLE(DASHBOARD_SUPPORT) || ENABLE(VIDEO) 827 832 #include "Document.h" … … 897 902 898 903 print F <<END 904 #if ENABLE(CUSTOM_ELEMENTS) 905 if (document->registry()) { 906 if (RefPtr<CustomElementConstructor> constructor = document->registry()->find(nullQName(), qName)) { 907 RefPtr<Element> element = constructor->createElement(); 908 ASSERT(element->is$parameters{namespace}Element()); 909 return static_pointer_cast<$parameters{namespace}Element>(element.release()); 910 } 911 } 912 #endif 913 899 914 if (!gFunctionMap) 900 915 createFunctionMap(); … … 913 928 } 914 929 915 END 916 ; 917 print F " return $parameters{fallbackInterfaceName}::create(qName, document);\n"; 918 919 print F <<END 930 return $parameters{fallbackInterfaceName}::create(qName, document); 920 931 } 921 932 … … 1173 1184 } elsif ($wrapperFactoryType eq "V8") { 1174 1185 print F <<END 1186 #include "V8$parameters{namespace}Element.h" 1187 1188 #if ENABLE(CUSTOM_ELEMENTS) 1175 1189 #include "V8CustomElement.h" 1176 # include "V8$parameters{namespace}Element.h"1190 #endif 1177 1191 1178 1192 #include <v8.h> … … 1245 1259 print F <<END 1246 1260 } 1261 END 1262 ; 1263 if ($wrapperFactoryType eq "V8") { 1264 print F <<END 1265 #if ENABLE(CUSTOM_ELEMENTS) 1266 if (PassRefPtr<CustomElementConstructor> constructor = V8CustomElement::constructorOf(element)) 1267 return V8CustomElement::wrap(element, creationContext, constructor, isolate); 1268 #endif 1269 END 1270 ; 1271 } 1272 1273 print F <<END 1247 1274 Create$parameters{namespace}ElementWrapperFunction createWrapperFunction = map.get(element->localName().impl()); 1248 1275 if (createWrapperFunction) … … 1276 1303 END 1277 1304 ; 1278 } elsif ($parameters{namespace} eq "HTML") {1279 print F <<END1280 return V8CustomElement::wrap(element, creationContext, isolate);1281 END1282 ;1283 1305 } else { 1284 1306 print F <<END … … 1290 1312 print F <<END 1291 1313 } 1292 1293 } 1294 1295 END 1296 ; 1297 1314 END 1315 ; 1316 1317 if ($wrapperFactoryType eq "V8") { 1318 print F <<END 1319 1320 const QualifiedName* find$parameters{namespace}TagNameOfV8Type(const WrapperTypeInfo* type) 1321 { 1322 typedef HashMap<const WrapperTypeInfo*, const QualifiedName*> TypeNameMap; 1323 DEFINE_STATIC_LOCAL(TypeNameMap, map, ()); 1324 if (map.isEmpty()) { 1325 END 1326 ; 1327 1328 for my $tagName (sort keys %enabledTags) { 1329 if (!usesDefaultJSWrapper($tagName)) { 1330 my $conditional = $enabledTags{$tagName}{conditional}; 1331 if ($conditional) { 1332 my $conditionalString = "ENABLE(" . join(") && ENABLE(", split(/&/, $conditional)) . ")"; 1333 print F "#if ${conditionalString}\n"; 1334 } 1335 1336 my $JSInterfaceName = $enabledTags{$tagName}{JSInterfaceName}; 1337 print F " map.set(WrapperTypeTraits<${JSInterfaceName}>::info(), &${tagName}Tag);\n"; 1338 1339 if ($conditional) { 1340 print F "#endif\n"; 1341 } 1342 } 1343 } 1344 1345 print F <<END 1346 } 1347 1348 return map.get(type); 1349 } 1350 1351 END 1352 ; 1353 } 1354 1355 print F "}\n\n"; 1298 1356 print F "#endif\n" if $parameters{guardFactoryWith}; 1299 1357 … … 1346 1404 class $parameters{namespace}Element; 1347 1405 1406 const QualifiedName* find$parameters{namespace}TagNameOfV8Type(const WrapperTypeInfo*); 1348 1407 v8::Handle<v8::Object> createV8$parameters{namespace}Wrapper($parameters{namespace}Element*, v8::Handle<v8::Object> creationContext, v8::Isolate*); 1349 1408 inline v8::Handle<v8::Object> createV8$parameters{namespace}DirectWrapper($parameters{namespace}Element* element, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) -
trunk/Source/WebCore/html/HTMLAttributeNames.in
r144858 r145932 127 127 incremental 128 128 indeterminate 129 is 129 130 ismap 130 131 itemid
Note: See TracChangeset
for help on using the changeset viewer.