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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved. 2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 { 62 {
63 ASSERT(m_context == v8::Isolate::GetCurrent()->GetCurrentContext()); 63 ASSERT(m_context == v8::Isolate::GetCurrent()->GetCurrentContext());
64 } 64 }
65 65
66 bool CustomElementConstructorBuilder::isFeatureAllowed() const 66 bool CustomElementConstructorBuilder::isFeatureAllowed() const
67 { 67 {
68 // Check that we are in the main world 68 // Check that we are in the main world
69 return !DOMWrapperWorld::isolatedWorld(m_context); 69 return !DOMWrapperWorld::isolatedWorld(m_context);
70 } 70 }
71 71
72 bool CustomElementConstructorBuilder::validateOptions(const AtomicString& type, ExceptionState& es) 72 bool CustomElementConstructorBuilder::validateOptions(const AtomicString& type, QualifiedName& tagName, ExceptionState& es)
73 { 73 {
74 ASSERT(m_prototype.IsEmpty()); 74 ASSERT(m_prototype.IsEmpty());
75 75
76 ScriptValue prototypeScriptValue; 76 ScriptValue prototypeScriptValue;
77 if (m_options->get("prototype", prototypeScriptValue)) { 77 if (m_options->get("prototype", prototypeScriptValue) && !prototypeScriptVal ue.isNull()) {
78 m_prototype = prototypeScriptValue.v8Value().As<v8::Object>(); 78 m_prototype = prototypeScriptValue.v8Value().As<v8::Object>();
79 if (m_prototype.IsEmpty()) { 79 if (m_prototype.IsEmpty()) {
80 CustomElementException::throwException(CustomElementException::Proto typeNotAnObject, type, es); 80 CustomElementException::throwException(CustomElementException::Proto typeNotAnObject, type, es);
81 return false; 81 return false;
82 } 82 }
83 } else { 83 } else {
84 m_prototype = v8::Object::New(); 84 m_prototype = v8::Object::New();
85 m_prototype->SetPrototype(V8PerContextData::from(m_context)->prototypeFo rType(&V8HTMLElement::info)); 85 v8::Local<v8::Object> basePrototype = V8PerContextData::from(m_context)- >prototypeForType(&V8HTMLElement::info);
86 if (!basePrototype.IsEmpty())
87 m_prototype->SetPrototype(basePrototype);
86 } 88 }
87 89
90 String extends;
91 bool extendsProvidedAndNonNull = m_options->get("extends", extends);
92
88 if (!V8PerContextData::from(m_context)) { 93 if (!V8PerContextData::from(m_context)) {
89 // FIXME: This should generate an InvalidContext exception at a later po int. 94 // FIXME: This should generate an InvalidContext exception at a later po int.
90 CustomElementException::throwException(CustomElementException::ContextDe stroyedCheckingPrototype, type, es); 95 CustomElementException::throwException(CustomElementException::ContextDe stroyedCheckingPrototype, type, es);
91 return false; 96 return false;
92 } 97 }
93 if (hasValidPrototypeChainFor(&V8HTMLElement::info)) { 98
94 m_namespaceURI = HTMLNames::xhtmlNamespaceURI; 99 AtomicString namespaceURI = HTMLNames::xhtmlNamespaceURI;
95 return true; 100 if (hasValidPrototypeChainFor(&V8SVGElement::info))
96 } 101 namespaceURI = SVGNames::svgNamespaceURI;
97 if (hasValidPrototypeChainFor(&V8SVGElement::info)) { 102
98 m_namespaceURI = SVGNames::svgNamespaceURI; 103 AtomicString localName;
99 return true; 104
100 } 105 if (extendsProvidedAndNonNull) {
101 if (hasValidPrototypeChainFor(&V8Element::info)) { 106 localName = extends.lower();
102 m_namespaceURI = nullAtom; 107
103 // This generates a different DOM exception, so we feign success for now . 108 if (!Document::isValidName(localName)) {
104 return true; 109 CustomElementException::throwException(CustomElementException::Exten dsIsInvalidName, type, es);
110 return false;
111 }
112 if (CustomElement::isValidName(localName)) {
113 CustomElementException::throwException(CustomElementException::Exten dsIsCustomElementName, type, es);
114 return false;
115 }
116 } else {
117 localName = type;
105 } 118 }
106 119
107 CustomElementException::throwException(CustomElementException::PrototypeDoes NotExtendHTMLElementSVGElementPrototype, type, es); 120 if (!extendsProvidedAndNonNull)
108 return false; 121 m_wrapperType = &V8HTMLElement::info;
109 } 122 else if (namespaceURI == HTMLNames::xhtmlNamespaceURI)
123 m_wrapperType = findWrapperTypeForHTMLTagName(localName);
124 else
125 m_wrapperType = findWrapperTypeForSVGTagName(localName);
110 126
111 bool CustomElementConstructorBuilder::findTagName(const AtomicString& customElem entType, QualifiedName& tagName) 127 ASSERT(m_wrapperType);
112 { 128 tagName = QualifiedName(nullAtom, localName, namespaceURI);
113 ASSERT(!m_prototype.IsEmpty()); 129 return m_wrapperType;
114
115 m_wrapperType = findWrapperType(m_prototype);
116 if (!m_wrapperType) {
117 // Invalid prototype.
118 return false;
119 }
120
121 if (const QualifiedName* htmlName = findHTMLTagNameOfV8Type(m_wrapperType)) {
122 ASSERT(htmlName->namespaceURI() == m_namespaceURI);
123 tagName = *htmlName;
124 return true;
125 }
126
127 if (const QualifiedName* svgName = findSVGTagNameOfV8Type(m_wrapperType)) {
128 ASSERT(svgName->namespaceURI() == m_namespaceURI);
129 tagName = *svgName;
130 return true;
131 }
132
133 if (m_namespaceURI != nullAtom) {
134 // Use the custom element type as the tag's local name.
135 tagName = QualifiedName(nullAtom, customElementType, m_namespaceURI);
136 return true;
137 }
138
139 return false;
140 } 130 }
141 131
142 PassRefPtr<CustomElementLifecycleCallbacks> CustomElementConstructorBuilder::cre ateCallbacks() 132 PassRefPtr<CustomElementLifecycleCallbacks> CustomElementConstructorBuilder::cre ateCallbacks()
143 { 133 {
144 ASSERT(!m_prototype.IsEmpty()); 134 ASSERT(!m_prototype.IsEmpty());
145 135
146 RefPtr<ScriptExecutionContext> scriptExecutionContext(toScriptExecutionConte xt(m_context)); 136 RefPtr<ScriptExecutionContext> scriptExecutionContext(toScriptExecutionConte xt(m_context));
147 137
148 v8::TryCatch exceptionCatcher; 138 v8::TryCatch exceptionCatcher;
149 exceptionCatcher.SetVerbose(true); 139 exceptionCatcher.SetVerbose(true);
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 ASSERT(!m_constructor.IsEmpty()); 228 ASSERT(!m_constructor.IsEmpty());
239 229
240 return m_callbacks->setBinding(definition, CustomElementBinding::create(m_co ntext->GetIsolate(), m_prototype, m_wrapperType)); 230 return m_callbacks->setBinding(definition, CustomElementBinding::create(m_co ntext->GetIsolate(), m_prototype, m_wrapperType));
241 } 231 }
242 232
243 ScriptValue CustomElementConstructorBuilder::bindingsReturnValue() const 233 ScriptValue CustomElementConstructorBuilder::bindingsReturnValue() const
244 { 234 {
245 return ScriptValue(m_constructor); 235 return ScriptValue(m_constructor);
246 } 236 }
247 237
248 WrapperTypeInfo* CustomElementConstructorBuilder::findWrapperType(v8::Handle<v8: :Value> chain)
249 {
250 while (!chain.IsEmpty() && chain->IsObject()) {
251 v8::Handle<v8::Object> chainObject = chain.As<v8::Object>();
252 // Only prototype objects of native-backed types have the extra internal field storing WrapperTypeInfo.
253 if (v8PrototypeInternalFieldcount == chainObject->InternalFieldCount()) {
254 WrapperTypeInfo* wrapperType = reinterpret_cast<WrapperTypeInfo*>(ch ainObject->GetAlignedPointerFromInternalField(v8PrototypeTypeIndex));
255 ASSERT(wrapperType);
256 return wrapperType;
257 }
258 chain = chainObject->GetPrototype();
259 }
260
261 return 0;
262 }
263
264 bool CustomElementConstructorBuilder::hasValidPrototypeChainFor(WrapperTypeInfo* type) const 238 bool CustomElementConstructorBuilder::hasValidPrototypeChainFor(WrapperTypeInfo* type) const
265 { 239 {
266 v8::Handle<v8::Object> elementPrototype = V8PerContextData::from(m_context)- >prototypeForType(type); 240 v8::Handle<v8::Object> elementPrototype = V8PerContextData::from(m_context)- >prototypeForType(type);
267 if (elementPrototype.IsEmpty()) 241 if (elementPrototype.IsEmpty())
268 return false; 242 return false;
269 243
270 v8::Handle<v8::Value> chain = m_prototype; 244 v8::Handle<v8::Value> chain = m_prototype;
271 while (!chain.IsEmpty() && chain->IsObject()) { 245 while (!chain.IsEmpty() && chain->IsObject()) {
272 if (chain == elementPrototype) 246 if (chain == elementPrototype)
273 return true; 247 return true;
(...skipping 25 matching lines...) Expand all
299 273
300 ExceptionState es(args.GetIsolate()); 274 ExceptionState es(args.GetIsolate());
301 CustomElementCallbackDispatcher::CallbackDeliveryScope deliveryScope; 275 CustomElementCallbackDispatcher::CallbackDeliveryScope deliveryScope;
302 RefPtr<Element> element = document->createElementNS(namespaceURI, tagName, m aybeType->IsNull() ? nullAtom : type, es); 276 RefPtr<Element> element = document->createElementNS(namespaceURI, tagName, m aybeType->IsNull() ? nullAtom : type, es);
303 if (es.throwIfNeeded()) 277 if (es.throwIfNeeded())
304 return; 278 return;
305 v8SetReturnValueFast(args, element.release(), document); 279 v8SetReturnValueFast(args, element.release(), document);
306 } 280 }
307 281
308 } // namespace WebCore 282 } // namespace WebCore
OLDNEW
« 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