Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(232)

Unified Diff: Source/bindings/v8/CustomElementConstructorBuilder.cpp

Issue 23717043: Implement Custom Elements 'extends' option. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/bindings/v8/CustomElementConstructorBuilder.h ('k') | Source/bindings/v8/V8PerContextData.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/bindings/v8/CustomElementConstructorBuilder.cpp
diff --git a/Source/bindings/v8/CustomElementConstructorBuilder.cpp b/Source/bindings/v8/CustomElementConstructorBuilder.cpp
index 6793ba5ca924291def1771b6a9c4766afe84ab22..042c35cb34b14a4703a8c7ffa34696f4832d7480 100644
--- a/Source/bindings/v8/CustomElementConstructorBuilder.cpp
+++ b/Source/bindings/v8/CustomElementConstructorBuilder.cpp
@@ -69,12 +69,12 @@ bool CustomElementConstructorBuilder::isFeatureAllowed() const
return !DOMWrapperWorld::isolatedWorld(m_context);
}
-bool CustomElementConstructorBuilder::validateOptions(const AtomicString& type, ExceptionState& es)
+bool CustomElementConstructorBuilder::validateOptions(const AtomicString& type, QualifiedName& tagName, ExceptionState& es)
{
ASSERT(m_prototype.IsEmpty());
ScriptValue prototypeScriptValue;
- if (m_options->get("prototype", prototypeScriptValue)) {
+ if (m_options->get("prototype", prototypeScriptValue) && !prototypeScriptValue.isNull()) {
m_prototype = prototypeScriptValue.v8Value().As<v8::Object>();
if (m_prototype.IsEmpty()) {
CustomElementException::throwException(CustomElementException::PrototypeNotAnObject, type, es);
@@ -82,61 +82,51 @@ bool CustomElementConstructorBuilder::validateOptions(const AtomicString& type,
}
} else {
m_prototype = v8::Object::New();
- m_prototype->SetPrototype(V8PerContextData::from(m_context)->prototypeForType(&V8HTMLElement::info));
+ v8::Local<v8::Object> basePrototype = V8PerContextData::from(m_context)->prototypeForType(&V8HTMLElement::info);
+ if (!basePrototype.IsEmpty())
+ m_prototype->SetPrototype(basePrototype);
}
+ String extends;
+ bool extendsProvidedAndNonNull = m_options->get("extends", extends);
+
if (!V8PerContextData::from(m_context)) {
// FIXME: This should generate an InvalidContext exception at a later point.
CustomElementException::throwException(CustomElementException::ContextDestroyedCheckingPrototype, type, es);
return false;
}
- if (hasValidPrototypeChainFor(&V8HTMLElement::info)) {
- m_namespaceURI = HTMLNames::xhtmlNamespaceURI;
- return true;
- }
- if (hasValidPrototypeChainFor(&V8SVGElement::info)) {
- m_namespaceURI = SVGNames::svgNamespaceURI;
- return true;
- }
- if (hasValidPrototypeChainFor(&V8Element::info)) {
- m_namespaceURI = nullAtom;
- // This generates a different DOM exception, so we feign success for now.
- return true;
- }
-
- CustomElementException::throwException(CustomElementException::PrototypeDoesNotExtendHTMLElementSVGElementPrototype, type, es);
- return false;
-}
-bool CustomElementConstructorBuilder::findTagName(const AtomicString& customElementType, QualifiedName& tagName)
-{
- ASSERT(!m_prototype.IsEmpty());
+ AtomicString namespaceURI = HTMLNames::xhtmlNamespaceURI;
+ if (hasValidPrototypeChainFor(&V8SVGElement::info))
+ namespaceURI = SVGNames::svgNamespaceURI;
- m_wrapperType = findWrapperType(m_prototype);
- if (!m_wrapperType) {
- // Invalid prototype.
- return false;
- }
+ AtomicString localName;
- if (const QualifiedName* htmlName = findHTMLTagNameOfV8Type(m_wrapperType)) {
- ASSERT(htmlName->namespaceURI() == m_namespaceURI);
- tagName = *htmlName;
- return true;
- }
+ if (extendsProvidedAndNonNull) {
+ localName = extends.lower();
- if (const QualifiedName* svgName = findSVGTagNameOfV8Type(m_wrapperType)) {
- ASSERT(svgName->namespaceURI() == m_namespaceURI);
- tagName = *svgName;
- return true;
+ if (!Document::isValidName(localName)) {
+ CustomElementException::throwException(CustomElementException::ExtendsIsInvalidName, type, es);
+ return false;
+ }
+ if (CustomElement::isValidName(localName)) {
+ CustomElementException::throwException(CustomElementException::ExtendsIsCustomElementName, type, es);
+ return false;
+ }
+ } else {
+ localName = type;
}
- if (m_namespaceURI != nullAtom) {
- // Use the custom element type as the tag's local name.
- tagName = QualifiedName(nullAtom, customElementType, m_namespaceURI);
- return true;
- }
+ if (!extendsProvidedAndNonNull)
+ m_wrapperType = &V8HTMLElement::info;
+ else if (namespaceURI == HTMLNames::xhtmlNamespaceURI)
+ m_wrapperType = findWrapperTypeForHTMLTagName(localName);
+ else
+ m_wrapperType = findWrapperTypeForSVGTagName(localName);
- return false;
+ ASSERT(m_wrapperType);
+ tagName = QualifiedName(nullAtom, localName, namespaceURI);
+ return m_wrapperType;
}
PassRefPtr<CustomElementLifecycleCallbacks> CustomElementConstructorBuilder::createCallbacks()
@@ -245,22 +235,6 @@ ScriptValue CustomElementConstructorBuilder::bindingsReturnValue() const
return ScriptValue(m_constructor);
}
-WrapperTypeInfo* CustomElementConstructorBuilder::findWrapperType(v8::Handle<v8::Value> chain)
-{
- while (!chain.IsEmpty() && chain->IsObject()) {
- v8::Handle<v8::Object> chainObject = chain.As<v8::Object>();
- // Only prototype objects of native-backed types have the extra internal field storing WrapperTypeInfo.
- if (v8PrototypeInternalFieldcount == chainObject->InternalFieldCount()) {
- WrapperTypeInfo* wrapperType = reinterpret_cast<WrapperTypeInfo*>(chainObject->GetAlignedPointerFromInternalField(v8PrototypeTypeIndex));
- ASSERT(wrapperType);
- return wrapperType;
- }
- chain = chainObject->GetPrototype();
- }
-
- return 0;
-}
-
bool CustomElementConstructorBuilder::hasValidPrototypeChainFor(WrapperTypeInfo* type) const
{
v8::Handle<v8::Object> elementPrototype = V8PerContextData::from(m_context)->prototypeForType(type);
« no previous file with comments | « Source/bindings/v8/CustomElementConstructorBuilder.h ('k') | Source/bindings/v8/V8PerContextData.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698