Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 "core/dom/CustomElementRegistry.h" | 43 #include "core/dom/CustomElementRegistry.h" |
| 44 #include "core/dom/Element.h" | |
| 44 #include "core/dom/Node.h" | 45 #include "core/dom/Node.h" |
| 45 #include "core/html/HTMLElement.h" | 46 #include "core/html/HTMLElement.h" |
| 46 #include "core/html/HTMLUnknownElement.h" | 47 #include "core/html/HTMLUnknownElement.h" |
| 47 #include "core/svg/SVGElement.h" | 48 #include "core/svg/SVGElement.h" |
| 48 | 49 |
| 49 namespace WebCore { | 50 namespace WebCore { |
| 50 | 51 |
| 51 v8::Handle<v8::Object> CustomElementHelpers::createWrapper(PassRefPtr<Element> i mpl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate, const CreateW rapperFunction& createTypeExtensionUpgradeCandidateWrapper) | 52 v8::Handle<v8::Object> CustomElementHelpers::createWrapper(PassRefPtr<Element> i mpl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate, const CreateW rapperFunction& createTypeExtensionUpgradeCandidateWrapper) |
| 52 { | 53 { |
| 53 ASSERT(impl); | 54 ASSERT(impl); |
| 54 | 55 |
| 55 // The constructor and registered lifecycle callbacks should be visible only from main world. | 56 // The constructor and registered lifecycle callbacks should be visible only from main world. |
| 56 // FIXME: This shouldn't be needed once each custom element has its own Func tionTemplate | |
| 57 // https://bugs.webkit.org/show_bug.cgi?id=108138 | |
| 58 | 57 |
| 59 // FIXME: creationContext.IsEmpty() should never happen. Remove | 58 // FIXME: creationContext.IsEmpty() should never happen. Remove |
| 60 // this when callers (like InspectorController::inspect) are fixed | 59 // this when callers (like InspectorController::inspect) are fixed |
| 61 // to never pass an empty creation context. | 60 // to never pass an empty creation context. |
| 62 if (!CustomElementHelpers::isFeatureAllowed(creationContext.IsEmpty() ? v8:: Context::GetCurrent() : creationContext->CreationContext())) { | 61 if (!CustomElementHelpers::isFeatureAllowed(creationContext.IsEmpty() ? v8:: Context::GetCurrent() : creationContext->CreationContext())) { |
| 63 v8::Handle<v8::Object> wrapper = V8DOMWrapper::createWrapper(creationCon text, &V8HTMLElement::info, impl.get(), isolate); | 62 v8::Handle<v8::Object> wrapper = V8DOMWrapper::createWrapper(creationCon text, &V8HTMLElement::info, impl.get(), isolate); |
| 64 if (!wrapper.IsEmpty()) | 63 if (!wrapper.IsEmpty()) |
| 65 V8DOMWrapper::associateObjectWithWrapper(impl, &V8HTMLElement::info, wrapper, isolate, WrapperConfiguration::Dependent); | 64 V8DOMWrapper::associateObjectWithWrapper(impl, &V8HTMLElement::info, wrapper, isolate, WrapperConfiguration::Dependent); |
| 66 return wrapper; | 65 return wrapper; |
| 67 } | 66 } |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 114 else { | 113 else { |
| 115 ASSERT(0); | 114 ASSERT(0); |
| 116 return v8::Handle<v8::Object>(); | 115 return v8::Handle<v8::Object>(); |
| 117 } | 116 } |
| 118 } else { | 117 } else { |
| 119 // It's a type extension | 118 // It's a type extension |
| 120 return createTypeExtensionUpgradeCandidateWrapper.invoke(element.get(), creationContext, isolate); | 119 return createTypeExtensionUpgradeCandidateWrapper.invoke(element.get(), creationContext, isolate); |
| 121 } | 120 } |
| 122 } | 121 } |
| 123 | 122 |
| 124 bool CustomElementHelpers::initializeConstructorWrapper(CustomElementConstructor * constructor, const ScriptValue& prototype, ScriptState* state) | 123 static void constructCustomElement(const v8::FunctionCallbackInfo<v8::Value>& ar gs) |
| 125 { | 124 { |
| 126 ASSERT(isFeatureAllowed(state)); | 125 v8::Isolate* isolate = args.GetIsolate(); |
| 127 ASSERT(!prototype.v8Value().IsEmpty() && prototype.v8Value()->IsObject()); | |
| 128 v8::Handle<v8::Value> wrapperValue = toV8(constructor, state->context()->Glo bal(), state->context()->GetIsolate()); | |
| 129 if (wrapperValue.IsEmpty() || !wrapperValue->IsObject()) | |
| 130 return false; | |
| 131 v8::Handle<v8::Function> wrapper = v8::Handle<v8::Function>::Cast(wrapperVal ue); | |
| 132 // - Object::ForceSet() nor Object::SetAccessor Doesn't work against the "pr ototype" property of function objects. | |
| 133 // - Set()-ing here is safe because | |
| 134 // - Hooking Object.prototype's defineProperty() with "prototype" or "cons tructor" also doesn't affect on these properties of function objects and | |
| 135 // - Using Set() is okay becaues each function has "prototype" property fr om start and Objects.prototype cannot intercept the property access. | |
| 136 v8::Handle<v8::String> prototypeKey = v8String("prototype", state->context() ->GetIsolate()); | |
| 137 ASSERT(wrapper->HasOwnProperty(prototypeKey)); | |
| 138 wrapper->Set(prototypeKey, prototype.v8Value(), v8::ReadOnly); | |
| 139 | 126 |
| 140 v8::Handle<v8::String> constructorKey = v8String("constructor", state->conte xt()->GetIsolate()); | 127 if (!args.IsConstructCall()) { |
| 141 v8::Handle<v8::Object> prototypeObject = v8::Handle<v8::Object>::Cast(protot ype.v8Value()); | 128 throwTypeError("DOM object constructor cannot be called as a function.", isolate); |
| 142 ASSERT(!prototypeObject->HasOwnProperty(constructorKey)); | 129 return; |
| 143 prototypeObject->ForceSet(constructorKey, wrapper, v8::ReadOnly); | 130 } |
| 144 return true; | 131 |
|
haraken
2013/06/10 09:11:03
I think you need to add the following check here:
dominicc (has gone to gerrit)
2013/06/11 01:29:02
This is different to a wrapper constructor; this f
| |
| 132 if (args.Length() > 0) { | |
|
haraken
2013/06/10 09:11:03
Nit: Do you need this check?
dominicc (has gone to gerrit)
2013/06/11 01:29:02
This is per <http://www.w3.org/TR/WebIDL/#es-inter
| |
| 133 throwTypeError(0, isolate); | |
| 134 return; | |
| 135 } | |
| 136 | |
| 137 Document* document = V8Document::toNative(v8::Handle<v8::Object>::Cast(args. Callee()->GetHiddenValue(v8String("document", isolate)))); | |
| 138 V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, namespaceURI, args. Callee()->GetHiddenValue(v8String("namespaceURI", isolate))); | |
|
abarth-chromium
2013/06/10 17:42:19
Please use V8HiddenPropertyNames rather than alloc
| |
| 139 V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, name, args.Callee() ->GetHiddenValue(v8String("name", isolate))); | |
| 140 v8::Handle<v8::Value> maybeType = args.Callee()->GetHiddenValue(v8String("ty pe", isolate)); | |
| 141 V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, type, maybeType); | |
| 142 | |
| 143 ExceptionCode ec = 0; | |
| 144 CustomElementRegistry::CallbackDeliveryScope deliveryScope; | |
| 145 RefPtr<Element> element = document->createElementNS(namespaceURI, name, mayb eType->IsNull() ? nullAtom : type, ec); | |
| 146 if (ec) { | |
| 147 setDOMException(ec, isolate); | |
| 148 return; | |
| 149 } | |
| 150 v8SetReturnValue(args, toV8Fast(element.release(), args, document)); | |
| 151 } | |
| 152 | |
| 153 ScriptValue CustomElementHelpers::createConstructor(ScriptState* state, const Sc riptValue& prototypeValue, Document* document, const AtomicString& namespaceURI, const AtomicString& name, const AtomicString& type) | |
|
haraken
2013/06/10 09:11:03
Not related to this CL: won't prototypeValue cause
dominicc (has gone to gerrit)
2013/06/11 01:29:02
We discussed this offline:
- We think that the F
| |
| 154 { | |
| 155 v8::Isolate* isolate = state->context()->GetIsolate(); | |
| 156 | |
| 157 v8::TryCatch tryCatch; | |
| 158 v8::Local<v8::FunctionTemplate> constructorTemplate = v8::FunctionTemplate:: New(); | |
| 159 constructorTemplate->SetCallHandler(constructCustomElement); | |
| 160 v8::Handle<v8::Function> constructor = constructorTemplate->GetFunction(); | |
| 161 if (tryCatch.HasCaught()) { | |
| 162 state->setException(tryCatch.Exception()); | |
| 163 return ScriptValue(); | |
| 164 } | |
| 165 | |
| 166 v8::Handle<v8::String> v8Name = v8String(name, isolate); | |
| 167 v8::Handle<v8::Value> v8Type; | |
| 168 | |
| 169 if (type.isNull()) { | |
| 170 v8Type = v8::Null(isolate); | |
| 171 constructor->SetName(v8Name); | |
|
haraken
2013/06/10 09:11:03
You need to somehow handle a case where constructo
dominicc (has gone to gerrit)
2013/06/11 01:29:02
When would that happen? I think we early return on
haraken
2013/06/11 01:39:21
I just wanted to make sure here that the construct
dominicc (has gone to gerrit)
2013/06/11 02:41:33
Done.
| |
| 172 } else { | |
| 173 v8::Handle<v8::String> v8TypeString = v8String(type, isolate); | |
|
haraken
2013/06/10 09:11:03
By using v8StringOrNull() here, I think you can ki
| |
| 174 v8Type = v8TypeString; | |
| 175 constructor->SetName(v8TypeString); | |
| 176 } | |
| 177 | |
| 178 constructor->SetHiddenValue(v8String("document", isolate), toV8(document, st ate->context()->Global(), isolate)); | |
|
haraken
2013/06/10 09:11:03
Can't you use toV8Fast(), given that we already kn
dominicc (has gone to gerrit)
2013/06/11 01:29:02
Not sure... ScriptState is not a "HolderContainer"
haraken
2013/06/11 01:39:21
You're right. Please ignore my comment. You can us
| |
| 179 constructor->SetHiddenValue(v8String("namespaceURI", isolate), v8String(name spaceURI, isolate)); | |
| 180 constructor->SetHiddenValue(v8String("name", isolate), v8Name); | |
| 181 constructor->SetHiddenValue(v8String("type", isolate), v8Type); | |
| 182 | |
| 183 // Neither Object::ForceSet nor Object::SetAccessor can set the | |
| 184 // "prototype" property of function objects, so we use Set() | |
| 185 // instead. This is safe because each function has "prototype" | |
| 186 // property from birth so the Function, etc. prototypes will not | |
| 187 // intercept the property access. | |
| 188 v8::Handle<v8::Object> prototype = v8::Handle<v8::Object>::Cast(prototypeVal ue.v8Value()); | |
| 189 v8::Handle<v8::String> prototypeKey = v8String("prototype", isolate); | |
| 190 ASSERT(constructor->HasOwnProperty(prototypeKey)); | |
| 191 constructor->Set(prototypeKey, prototype, v8::ReadOnly); | |
| 192 | |
| 193 prototype->ForceSet(v8String("constructor", isolate), constructor, v8::ReadO nly); | |
| 194 | |
| 195 ASSERT(!tryCatch.HasCaught()); | |
| 196 | |
| 197 return ScriptValue(constructor); | |
| 145 } | 198 } |
| 146 | 199 |
| 147 static bool hasValidPrototypeChainFor(v8::Handle<v8::Object> prototypeObject, Wr apperTypeInfo* typeInfo, v8::Handle<v8::Context> context) | 200 static bool hasValidPrototypeChainFor(v8::Handle<v8::Object> prototypeObject, Wr apperTypeInfo* typeInfo, v8::Handle<v8::Context> context) |
| 148 { | 201 { |
| 149 // document.register() sets the constructor property, so the prototype shoul dn't have one. | 202 // document.register() sets the constructor property, so the prototype shoul dn't have one. |
| 150 if (prototypeObject->HasOwnProperty(v8String("constructor", context->GetIsol ate()))) | 203 if (prototypeObject->HasOwnProperty(v8String("constructor", context->GetIsol ate()))) |
| 151 return false; | 204 return false; |
| 152 | 205 |
| 153 v8::Handle<v8::Object> elementConstructor = v8::Handle<v8::Object>::Cast(V8P erContextData::from(context)->constructorForType(typeInfo)); | 206 v8::Handle<v8::Object> elementConstructor = v8::Handle<v8::Object>::Cast(V8P erContextData::from(context)->constructorForType(typeInfo)); |
| 154 if (elementConstructor.IsEmpty()) | 207 if (elementConstructor.IsEmpty()) |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 290 return; | 343 return; |
| 291 v8::Context::Scope scope(context); | 344 v8::Context::Scope scope(context); |
| 292 | 345 |
| 293 for (size_t i = 0; i < invocations.size(); ++i) { | 346 for (size_t i = 0; i < invocations.size(); ++i) { |
| 294 ASSERT(executionContext == invocations[i].element()->document()); | 347 ASSERT(executionContext == invocations[i].element()->document()); |
| 295 invokeReadyCallbackIfNeeded(invocations[i].element(), context); | 348 invokeReadyCallbackIfNeeded(invocations[i].element(), context); |
| 296 } | 349 } |
| 297 } | 350 } |
| 298 | 351 |
| 299 } // namespace WebCore | 352 } // namespace WebCore |
| OLD | NEW |