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

Side by Side Diff: sky/engine/bindings/core/v8/CustomElementConstructorBuilder.cpp

Issue 922053002: Remove unused V8 integration code in Sky (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 10 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
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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.
29 */
30
31 #include "sky/engine/config.h"
32 #include "sky/engine/bindings/core/v8/CustomElementConstructorBuilder.h"
33
34 #include "bindings/core/v8/V8Document.h"
35 #include "core/V8HTMLElementWrapperFactory.h" // FIXME: should be bindings/core/ v8
36 #include "sky/engine/bindings/core/v8/CustomElementBinding.h"
37 #include "sky/engine/bindings/core/v8/DOMWrapperWorld.h"
38 #include "sky/engine/bindings/core/v8/Dictionary.h"
39 #include "sky/engine/bindings/core/v8/ExceptionState.h"
40 #include "sky/engine/bindings/core/v8/V8Binding.h"
41 #include "sky/engine/bindings/core/v8/V8HiddenValue.h"
42 #include "sky/engine/bindings/core/v8/V8PerContextData.h"
43 #include "sky/engine/core/dom/Document.h"
44 #include "sky/engine/core/dom/custom/CustomElementDefinition.h"
45 #include "sky/engine/core/dom/custom/CustomElementException.h"
46 #include "sky/engine/core/dom/custom/CustomElementProcessingStack.h"
47 #include "sky/engine/wtf/Assertions.h"
48
49 namespace blink {
50
51 static void constructCustomElement(const v8::FunctionCallbackInfo<v8::Value>&);
52
53 CustomElementConstructorBuilder::CustomElementConstructorBuilder(ScriptState* sc riptState, const Dictionary* options)
54 : m_scriptState(scriptState)
55 , m_options(options)
56 , m_wrapperType(0)
57 {
58 ASSERT(m_scriptState->context() == m_scriptState->isolate()->GetCurrentConte xt());
59 }
60
61 bool CustomElementConstructorBuilder::validateOptions(const AtomicString& type, QualifiedName& tagName, ExceptionState& exceptionState)
62 {
63 ASSERT(m_prototype.IsEmpty());
64
65 v8::TryCatch tryCatch;
66
67 ScriptValue prototypeScriptValue;
68 if (DictionaryHelper::get(*m_options, "prototype", prototypeScriptValue) && !prototypeScriptValue.isNull()) {
69 ASSERT(!tryCatch.HasCaught());
70 if (!prototypeScriptValue.isObject()) {
71 CustomElementException::throwException(CustomElementException::Proto typeNotAnObject, type, exceptionState);
72 tryCatch.ReThrow();
73 return false;
74 }
75 m_prototype = prototypeScriptValue.v8Value().As<v8::Object>();
76 } else if (!tryCatch.HasCaught()) {
77 m_prototype = v8::Object::New(m_scriptState->isolate());
78 v8::Local<v8::Object> basePrototype = m_scriptState->perContextData()->p rototypeForType(&V8HTMLElement::wrapperTypeInfo);
79 if (!basePrototype.IsEmpty())
80 m_prototype->SetPrototype(basePrototype);
81 }
82
83 if (tryCatch.HasCaught()) {
84 tryCatch.ReThrow();
85 return false;
86 }
87
88 AtomicString extends;
89 bool extendsProvidedAndNonNull = DictionaryHelper::get(*m_options, "extends" , extends) && extends != "null";
90
91 if (tryCatch.HasCaught()) {
92 tryCatch.ReThrow();
93 return false;
94 }
95
96 if (!m_scriptState->perContextData()) {
97 // FIXME: This should generate an InvalidContext exception at a later po int.
98 CustomElementException::throwException(CustomElementException::ContextDe stroyedCheckingPrototype, type, exceptionState);
99 tryCatch.ReThrow();
100 return false;
101 }
102
103 ASSERT(!tryCatch.HasCaught());
104
105 AtomicString localName;
106
107 if (extendsProvidedAndNonNull) {
108 localName = extends.lower();
109
110 if (!Document::isValidName(localName)) {
111 CustomElementException::throwException(CustomElementException::Exten dsIsInvalidName, type, exceptionState);
112 tryCatch.ReThrow();
113 return false;
114 }
115 if (CustomElement::isValidName(localName)) {
116 CustomElementException::throwException(CustomElementException::Exten dsIsCustomElementName, type, exceptionState);
117 tryCatch.ReThrow();
118 return false;
119 }
120 } else {
121 localName = type;
122 }
123
124 if (!extendsProvidedAndNonNull)
125 m_wrapperType = &V8HTMLElement::wrapperTypeInfo;
126 else
127 m_wrapperType = findWrapperTypeForHTMLTagName(localName);
128
129 ASSERT(!tryCatch.HasCaught());
130 ASSERT(m_wrapperType);
131 tagName = QualifiedName(localName);
132 return m_wrapperType;
133 }
134
135 PassRefPtr<CustomElementLifecycleCallbacks> CustomElementConstructorBuilder::cre ateCallbacks()
136 {
137 ASSERT(!m_prototype.IsEmpty());
138
139 v8::TryCatch exceptionCatcher;
140 exceptionCatcher.SetVerbose(true);
141
142 v8::Isolate* isolate = m_scriptState->isolate();
143 v8::Handle<v8::Function> created = retrieveCallback(isolate, "createdCallbac k");
144 v8::Handle<v8::Function> attached = retrieveCallback(isolate, "attachedCallb ack");
145 v8::Handle<v8::Function> detached = retrieveCallback(isolate, "detachedCallb ack");
146 v8::Handle<v8::Function> attributeChanged = retrieveCallback(isolate, "attri buteChangedCallback");
147
148 m_callbacks = V8CustomElementLifecycleCallbacks::create(m_scriptState.get(), m_prototype, created, attached, detached, attributeChanged);
149 return m_callbacks.get();
150 }
151
152 v8::Handle<v8::Function> CustomElementConstructorBuilder::retrieveCallback(v8::I solate* isolate, const char* name)
153 {
154 v8::Handle<v8::Value> value = m_prototype->Get(v8String(isolate, name));
155 if (value.IsEmpty() || !value->IsFunction())
156 return v8::Handle<v8::Function>();
157 return value.As<v8::Function>();
158 }
159
160 bool CustomElementConstructorBuilder::createConstructor(Document* document, Cust omElementDefinition* definition, ExceptionState& exceptionState)
161 {
162 ASSERT(!m_prototype.IsEmpty());
163 ASSERT(m_constructor.IsEmpty());
164 ASSERT(document);
165
166 v8::Isolate* isolate = m_scriptState->isolate();
167
168 if (!prototypeIsValid(definition->localName(), exceptionState))
169 return false;
170
171 v8::Local<v8::FunctionTemplate> constructorTemplate = v8::FunctionTemplate:: New(isolate);
172 constructorTemplate->SetCallHandler(constructCustomElement);
173 m_constructor = constructorTemplate->GetFunction();
174 if (m_constructor.IsEmpty()) {
175 CustomElementException::throwException(CustomElementException::ContextDe stroyedRegisteringDefinition, definition->localName(), exceptionState);
176 return false;
177 }
178
179 v8::Handle<v8::String> v8TagName = v8String(isolate, definition->localName() );
180
181 m_constructor->SetName(v8TagName);
182
183 V8HiddenValue::setHiddenValue(isolate, m_constructor, V8HiddenValue::customE lementDocument(isolate), toV8(document, m_scriptState->context()->Global(), isol ate));
184 V8HiddenValue::setHiddenValue(isolate, m_constructor, V8HiddenValue::customE lementTagName(isolate), v8TagName);
185
186 v8::Handle<v8::String> prototypeKey = v8String(isolate, "prototype");
187 v8::Handle<v8::String> constructorKey = v8String(isolate, "constructor");
188
189 ASSERT(m_constructor->HasOwnProperty(prototypeKey));
190 // This sets the property *value*; calling Set is safe because
191 // "prototype" is a non-configurable data property so there can be
192 // no side effects.
193 m_constructor->Set(prototypeKey, m_prototype);
194 // This *configures* the property. ForceSet of a function's
195 // "prototype" does not affect the value, but can reconfigure the
196 // property.
197 m_constructor->ForceSet(prototypeKey, m_prototype, v8::PropertyAttribute(v8: :ReadOnly | v8::DontEnum | v8::DontDelete));
198 // The generated constructor should inherit from your constructor.
199 m_constructor->SetPrototype(m_prototype->Get(constructorKey));
200
201 V8HiddenValue::setHiddenValue(isolate, m_prototype, V8HiddenValue::customEle mentIsInterfacePrototypeObject(isolate), v8::True(isolate));
202 m_prototype->ForceSet(constructorKey, m_constructor, v8::DontEnum);
203
204 return true;
205 }
206
207 bool CustomElementConstructorBuilder::prototypeIsValid(const AtomicString& type, ExceptionState& exceptionState) const
208 {
209 if (m_prototype->InternalFieldCount() || !V8HiddenValue::getHiddenValue(m_sc riptState->isolate(), m_prototype, V8HiddenValue::customElementIsInterfaceProtot ypeObject(m_scriptState->isolate())).IsEmpty()) {
210 CustomElementException::throwException(CustomElementException::Prototype InUse, type, exceptionState);
211 return false;
212 }
213
214 if (m_prototype->GetPropertyAttributes(v8String(m_scriptState->isolate(), "c onstructor")) & v8::DontDelete) {
215 CustomElementException::throwException(CustomElementException::Construct orPropertyNotConfigurable, type, exceptionState);
216 return false;
217 }
218
219 return true;
220 }
221
222 bool CustomElementConstructorBuilder::didRegisterDefinition(CustomElementDefinit ion* definition) const
223 {
224 ASSERT(!m_constructor.IsEmpty());
225
226 return m_callbacks->setBinding(definition, CustomElementBinding::create(m_sc riptState->isolate(), m_prototype, m_wrapperType));
227 }
228
229 ScriptValue CustomElementConstructorBuilder::bindingsReturnValue() const
230 {
231 return ScriptValue(m_scriptState.get(), m_constructor);
232 }
233
234 bool CustomElementConstructorBuilder::hasValidPrototypeChainFor(const WrapperTyp eInfo* type) const
235 {
236 v8::Handle<v8::Object> elementPrototype = m_scriptState->perContextData()->p rototypeForType(type);
237 if (elementPrototype.IsEmpty())
238 return false;
239
240 v8::Handle<v8::Value> chain = m_prototype;
241 while (!chain.IsEmpty() && chain->IsObject()) {
242 if (chain == elementPrototype)
243 return true;
244 chain = chain.As<v8::Object>()->GetPrototype();
245 }
246
247 return false;
248 }
249
250 static void constructCustomElement(const v8::FunctionCallbackInfo<v8::Value>& in fo)
251 {
252 v8::Isolate* isolate = info.GetIsolate();
253
254 if (!info.IsConstructCall()) {
255 V8ThrowException::throwTypeError("DOM object constructor cannot be calle d as a function.", isolate);
256 return;
257 }
258
259 if (info.Length() > 0) {
260 V8ThrowException::throwTypeError("This constructor should be called with out arguments.", isolate);
261 return;
262 }
263
264 Document* document = V8Document::toNative(V8HiddenValue::getHiddenValue(info .GetIsolate(), info.Callee(), V8HiddenValue::customElementDocument(isolate)).As< v8::Object>());
265 TOSTRING_VOID(V8StringResource<>, tagName, V8HiddenValue::getHiddenValue(iso late, info.Callee(), V8HiddenValue::customElementTagName(isolate)));
266
267 ExceptionState exceptionState(ExceptionState::ConstructionContext, "CustomEl ement", info.Holder(), info.GetIsolate());
268 CustomElementProcessingStack::CallbackDeliveryScope deliveryScope;
269 RefPtr<Element> element = document->createElement(tagName, exceptionState);
270 if (exceptionState.throwIfNeeded())
271 return;
272 v8SetReturnValueFast(info, element.release(), document);
273 }
274
275 } // namespace blink
OLDNEW
« no previous file with comments | « sky/engine/bindings/core/v8/CustomElementConstructorBuilder.h ('k') | sky/engine/bindings/core/v8/CustomElementWrapper.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698