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

Side by Side Diff: Source/bindings/v8/CustomElementHelpers.cpp

Issue 16708002: Simplify Custom Element constructors to be functions, not wrappers (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Rebased Created 7 years, 6 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
« no previous file with comments | « Source/bindings/v8/CustomElementHelpers.h ('k') | Source/bindings/v8/V8AdaptorFunction.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2012 Google Inc. All rights reserved. 2 * Copyright (C) 2012 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 16 matching lines...) Expand all
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */ 29 */
30 30
31 #include "config.h" 31 #include "config.h"
32 32
33 #include "bindings/v8/CustomElementHelpers.h" 33 #include "bindings/v8/CustomElementHelpers.h"
34 34
35 #include "HTMLNames.h" 35 #include "HTMLNames.h"
36 #include "SVGNames.h" 36 #include "SVGNames.h"
37 #include "V8CustomElementConstructor.h" 37 #include "V8Document.h"
38 #include "V8HTMLElementWrapperFactory.h" 38 #include "V8HTMLElementWrapperFactory.h"
39 #include "V8SVGElementWrapperFactory.h" 39 #include "V8SVGElementWrapperFactory.h"
40 #include "bindings/v8/DOMDataStore.h" 40 #include "bindings/v8/DOMDataStore.h"
41 #include "bindings/v8/DOMWrapperWorld.h" 41 #include "bindings/v8/DOMWrapperWorld.h"
42 #include "bindings/v8/ScriptController.h" 42 #include "bindings/v8/ScriptController.h"
43 #include "bindings/v8/ScriptState.h"
43 #include "bindings/v8/UnsafePersistent.h" 44 #include "bindings/v8/UnsafePersistent.h"
45 #include "bindings/v8/V8HiddenPropertyName.h"
44 #include "bindings/v8/V8PerContextData.h" 46 #include "bindings/v8/V8PerContextData.h"
45 #include "core/dom/CustomElementRegistry.h" 47 #include "core/dom/CustomElementRegistry.h"
48 #include "core/dom/Element.h"
49 #include "core/dom/ExceptionCode.h"
46 #include "core/dom/Node.h" 50 #include "core/dom/Node.h"
47 #include "core/html/HTMLElement.h" 51 #include "core/html/HTMLElement.h"
48 #include "core/html/HTMLUnknownElement.h" 52 #include "core/html/HTMLUnknownElement.h"
49 #include "core/svg/SVGElement.h" 53 #include "core/svg/SVGElement.h"
50 54
51 namespace WebCore { 55 namespace WebCore {
52 56
53 void CustomElementHelpers::didRegisterDefinition(CustomElementDefinition* defini tion, ScriptExecutionContext* executionContext, const HashSet<Element*>& upgrade Candidates, const ScriptValue& prototypeValue) 57 void CustomElementHelpers::didRegisterDefinition(CustomElementDefinition* defini tion, ScriptExecutionContext* executionContext, const HashSet<Element*>& upgrade Candidates, const ScriptValue& prototypeValue)
54 { 58 {
55 ASSERT(v8::Isolate::GetCurrent()); 59 ASSERT(v8::Isolate::GetCurrent());
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 else { 135 else {
132 ASSERT(0); 136 ASSERT(0);
133 return v8::Handle<v8::Object>(); 137 return v8::Handle<v8::Object>();
134 } 138 }
135 } else { 139 } else {
136 // It's a type extension 140 // It's a type extension
137 return createTypeExtensionUpgradeCandidateWrapper.invoke(element.get(), creationContext, isolate); 141 return createTypeExtensionUpgradeCandidateWrapper.invoke(element.get(), creationContext, isolate);
138 } 142 }
139 } 143 }
140 144
141 bool CustomElementHelpers::initializeConstructorWrapper(CustomElementConstructor * constructor, const ScriptValue& prototype, ScriptState* state) 145 static void constructCustomElement(const v8::FunctionCallbackInfo<v8::Value>& ar gs)
142 { 146 {
143 ASSERT(isFeatureAllowed(state)); 147 v8::Isolate* isolate = args.GetIsolate();
144 ASSERT(!prototype.v8Value().IsEmpty() && prototype.v8Value()->IsObject());
145 v8::Handle<v8::Value> wrapperValue = toV8(constructor, state->context()->Glo bal(), state->context()->GetIsolate());
146 if (wrapperValue.IsEmpty() || !wrapperValue->IsObject())
147 return false;
148 v8::Handle<v8::Function> wrapper = v8::Handle<v8::Function>::Cast(wrapperVal ue);
149 // - Object::ForceSet() nor Object::SetAccessor Doesn't work against the "pr ototype" property of function objects.
150 // - Set()-ing here is safe because
151 // - Hooking Object.prototype's defineProperty() with "prototype" or "cons tructor" also doesn't affect on these properties of function objects and
152 // - Using Set() is okay becaues each function has "prototype" property fr om start and Objects.prototype cannot intercept the property access.
153 v8::Handle<v8::String> prototypeKey = v8String("prototype", state->context() ->GetIsolate());
154 ASSERT(wrapper->HasOwnProperty(prototypeKey));
155 wrapper->Set(prototypeKey, prototype.v8Value(), v8::ReadOnly);
156 148
157 v8::Handle<v8::String> constructorKey = v8String("constructor", state->conte xt()->GetIsolate()); 149 if (!args.IsConstructCall()) {
158 v8::Handle<v8::Object> prototypeObject = v8::Handle<v8::Object>::Cast(protot ype.v8Value()); 150 throwTypeError("DOM object constructor cannot be called as a function.", isolate);
159 ASSERT(!prototypeObject->HasOwnProperty(constructorKey)); 151 return;
160 prototypeObject->ForceSet(constructorKey, wrapper, v8::ReadOnly); 152 }
161 return true; 153
154 if (args.Length() > 0) {
155 throwTypeError(0, isolate);
156 return;
157 }
158
159 Document* document = V8Document::toNative(v8::Handle<v8::Object>::Cast(args. Callee()->GetHiddenValue(V8HiddenPropertyName::document())));
160 V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, namespaceURI, args. Callee()->GetHiddenValue(V8HiddenPropertyName::namespaceURI()));
161 V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, name, args.Callee() ->GetHiddenValue(V8HiddenPropertyName::name()));
162 v8::Handle<v8::Value> maybeType = args.Callee()->GetHiddenValue(V8HiddenProp ertyName::type());
163 V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, type, maybeType);
164
165 ExceptionCode ec = 0;
166 CustomElementRegistry::CallbackDeliveryScope deliveryScope;
167 RefPtr<Element> element = document->createElementNS(namespaceURI, name, mayb eType->IsNull() ? nullAtom : type, ec);
168 if (ec) {
169 setDOMException(ec, isolate);
170 return;
171 }
172 v8SetReturnValue(args, toV8Fast(element.release(), args, document));
173 }
174
175 ScriptValue CustomElementHelpers::createConstructor(ScriptState* state, const Sc riptValue& prototypeValue, Document* document, const AtomicString& namespaceURI, const AtomicString& name, const AtomicString& type)
176 {
177 v8::Isolate* isolate = state->isolate();
178
179 v8::HandleScope handleScope;
180 v8::TryCatch tryCatch;
181 v8::Local<v8::FunctionTemplate> constructorTemplate = v8::FunctionTemplate:: New();
182 constructorTemplate->SetCallHandler(constructCustomElement);
183 v8::Handle<v8::Function> constructor = constructorTemplate->GetFunction();
184 if (tryCatch.HasCaught()) {
185 state->setException(tryCatch.Exception());
186 return ScriptValue();
187 }
188 if (constructor.IsEmpty()) {
189 state->setException(v8::Local<v8::Value>::New(setDOMException(INVALID_ST ATE_ERR, isolate)));
190 return ScriptValue();
191 }
192
193 v8::Handle<v8::String> v8Name = v8String(name, isolate);
194 v8::Handle<v8::Value> v8Type = v8StringOrNull(type, isolate);
195
196 constructor->SetName(v8Type->IsNull() ? v8Name : v8::Handle<v8::String>::Cas t(v8Type));
197
198 V8HiddenPropertyName::setNamedHiddenReference(constructor, "document", toV8( document, state->context()->Global(), isolate));
199 V8HiddenPropertyName::setNamedHiddenReference(constructor, "namespaceURI", v 8String(namespaceURI, isolate));
200 V8HiddenPropertyName::setNamedHiddenReference(constructor, "name", v8Name);
201 V8HiddenPropertyName::setNamedHiddenReference(constructor, "type", v8Type);
202
203 // Neither Object::ForceSet nor Object::SetAccessor can set the
204 // "prototype" property of function objects, so we use Set()
205 // instead. This is safe because each function has "prototype"
206 // property from birth so the Function, etc. prototypes will not
207 // intercept the property access.
208 v8::Handle<v8::Object> prototype = v8::Handle<v8::Object>::Cast(prototypeVal ue.v8Value());
209 v8::Handle<v8::String> prototypeKey = v8String("prototype", isolate);
210 ASSERT(constructor->HasOwnProperty(prototypeKey));
211 constructor->Set(prototypeKey, prototype, v8::ReadOnly);
212
213 prototype->ForceSet(v8String("constructor", isolate), constructor, v8::ReadO nly);
214
215 ASSERT(!tryCatch.HasCaught());
216
217 return ScriptValue(constructor);
162 } 218 }
163 219
164 static bool hasValidPrototypeChainFor(v8::Handle<v8::Object> prototypeObject, Wr apperTypeInfo* typeInfo, v8::Handle<v8::Context> context) 220 static bool hasValidPrototypeChainFor(v8::Handle<v8::Object> prototypeObject, Wr apperTypeInfo* typeInfo, v8::Handle<v8::Context> context)
165 { 221 {
166 // document.register() sets the constructor property, so the prototype shoul dn't have one. 222 // document.register() sets the constructor property, so the prototype shoul dn't have one.
167 if (prototypeObject->HasOwnProperty(v8String("constructor", context->GetIsol ate()))) 223 if (prototypeObject->HasOwnProperty(v8String("constructor", context->GetIsol ate())))
168 return false; 224 return false;
169 225
170 v8::Handle<v8::Object> elementConstructor = v8::Handle<v8::Object>::Cast(V8P erContextData::from(context)->constructorForType(typeInfo)); 226 v8::Handle<v8::Object> elementConstructor = v8::Handle<v8::Object>::Cast(V8P erContextData::from(context)->constructorForType(typeInfo));
171 if (elementConstructor.IsEmpty()) 227 if (elementConstructor.IsEmpty())
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 return; 357 return;
302 v8::Context::Scope scope(context); 358 v8::Context::Scope scope(context);
303 359
304 for (size_t i = 0; i < invocations.size(); ++i) { 360 for (size_t i = 0; i < invocations.size(); ++i) {
305 ASSERT(executionContext == invocations[i].element()->document()); 361 ASSERT(executionContext == invocations[i].element()->document());
306 invokeReadyCallbackIfNeeded(invocations[i].element(), context); 362 invokeReadyCallbackIfNeeded(invocations[i].element(), context);
307 } 363 }
308 } 364 }
309 365
310 } // namespace WebCore 366 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/bindings/v8/CustomElementHelpers.h ('k') | Source/bindings/v8/V8AdaptorFunction.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698