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

Side by Side Diff: third_party/WebKit/Source/bindings/core/v8/ScriptCustomElementDefinition.cpp

Issue 2054433002: Implement "create an element" when sync for Custom Element V1 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@async-ce
Patch Set: dominicc review Created 4 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
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "bindings/core/v8/ScriptCustomElementDefinition.h" 5 #include "bindings/core/v8/ScriptCustomElementDefinition.h"
6 6
7 #include "bindings/core/v8/ScriptState.h" 7 #include "bindings/core/v8/ScriptState.h"
8 #include "bindings/core/v8/V8Binding.h" 8 #include "bindings/core/v8/V8Binding.h"
9 #include "bindings/core/v8/V8BindingMacros.h" 9 #include "bindings/core/v8/V8BindingMacros.h"
10 #include "bindings/core/v8/V8CustomElementsRegistry.h" 10 #include "bindings/core/v8/V8CustomElementsRegistry.h"
11 #include "bindings/core/v8/V8Element.h" 11 #include "bindings/core/v8/V8Element.h"
12 #include "bindings/core/v8/V8HiddenValue.h" 12 #include "bindings/core/v8/V8HiddenValue.h"
13 #include "bindings/core/v8/V8ScriptRunner.h" 13 #include "bindings/core/v8/V8ScriptRunner.h"
14 #include "bindings/core/v8/V8ThrowException.h" 14 #include "bindings/core/v8/V8ThrowException.h"
15 #include "core/dom/ExceptionCode.h" 15 #include "core/dom/ExceptionCode.h"
16 #include "core/html/HTMLElement.h"
17 #include "core/html/HTMLUnknownElement.h"
16 #include "v8.h" 18 #include "v8.h"
17 #include "wtf/Allocator.h" 19 #include "wtf/Allocator.h"
18 20
19 namespace blink { 21 namespace blink {
20 22
21 // Retrieves the custom elements constructor -> name map, creating it 23 // Retrieves the custom elements constructor -> name map, creating it
22 // if necessary. The same map is used to keep prototypes alive. 24 // if necessary. The same map is used to keep prototypes alive.
23 static v8::Local<v8::Map> ensureCustomElementsRegistryMap( 25 static v8::Local<v8::Map> ensureCustomElementsRegistryMap(
24 ScriptState* scriptState, 26 ScriptState* scriptState,
25 CustomElementsRegistry* registry) 27 CustomElementsRegistry* registry)
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 const v8::Local<v8::Object>& disconnectedCallback, 147 const v8::Local<v8::Object>& disconnectedCallback,
146 const v8::Local<v8::Object>& attributeChangedCallback, 148 const v8::Local<v8::Object>& attributeChangedCallback,
147 const HashSet<AtomicString>& observedAttributes) 149 const HashSet<AtomicString>& observedAttributes)
148 : CustomElementDefinition(descriptor) 150 : CustomElementDefinition(descriptor)
149 , m_scriptState(scriptState) 151 , m_scriptState(scriptState)
150 , m_constructor(scriptState->isolate(), constructor) 152 , m_constructor(scriptState->isolate(), constructor)
151 , m_observedAttributes(observedAttributes) 153 , m_observedAttributes(observedAttributes)
152 { 154 {
153 } 155 }
154 156
157 HTMLElement* ScriptCustomElementDefinition::createElementSync(
158 Document& document, const QualifiedName& tagName,
159 ExceptionState& exceptionState)
160 {
161 // Create an element
haraken 2016/06/13 09:05:35 Is it guaranteed that you're already in m_scriptSt
kojii 2016/06/13 10:28:25 Yes, that's the assumption atm; we assume DOM crea
162 // https://dom.spec.whatwg.org/#concept-create-element
163 // 6. If definition is non-null
164 // 6.1. If the synchronous custom elements flag is set:
165 // 6.1.2. Set result to Construct(C). Rethrow any exceptions.
166 Element* element;
haraken 2016/06/13 09:05:35 element = nullptr
kojii 2016/06/13 10:28:25 Will fix in the next CL.
167 {
168 v8::TryCatch tryCatch(m_scriptState->isolate());
169 element = runConstructor();
170 if (tryCatch.HasCaught()) {
171 exceptionState.rethrowV8Exception(tryCatch.Exception());
172 return nullptr;
173 }
174 }
175
176 // 6.1.3. through 6.1.9.
177 checkConstructorResult(element, document, tagName, exceptionState);
178 if (exceptionState.hadException())
179 return nullptr;
180
181 DCHECK_EQ(element->getCustomElementState(), CustomElementState::Custom);
182 return toHTMLElement(element);
183 }
184
185 HTMLElement* ScriptCustomElementDefinition::createElementSync(
186 Document& document, const QualifiedName& tagName)
187 {
188 // When invoked from "create an element for a token":
189 // https://html.spec.whatwg.org/multipage/syntax.html#create-an-element-for- the-token
190 // 7. If this step throws an exception, then report the exception, and
191 // let element be instead a new element that implements HTMLUnknownElement,
192 // with no attributes, namespace set to given namespace, namespace prefix
193 // set to null, custom element state "undefined", and node document set to
194 // document.
195 ScriptState::Scope scope(m_scriptState.get());
196 v8::Isolate* isolate = m_scriptState->isolate();
197 v8::TryCatch tryCatch(isolate);
haraken 2016/06/13 09:05:35 Why do you need this TryCatch?
198 tryCatch.SetVerbose(true);
haraken 2016/06/13 09:05:35 Remove this line unless you really want to make it
kojii 2016/06/13 10:28:25 The spec (copied in the comment above) says catch
199 ExceptionState exceptionState(ExceptionState::ConstructionContext, "CustomEl ement", constructor(), isolate);
200
201 HTMLElement* element = createElementSync(document, tagName, exceptionState);
202 DCHECK(!tryCatch.HasCaught());
haraken 2016/06/13 09:05:35 Instead, you can check DCHECK(!exceptionState.hadE
kojii 2016/06/13 10:28:25 There are errors here when JS throws. The purpose
203
204 exceptionState.throwIfNeeded();
205 if (tryCatch.HasCaught() || !element) {
206 element = HTMLUnknownElement::create(tagName, document);
207 element->setCustomElementState(CustomElementState::Undefined);
208 }
209 return element;
210 }
211
155 // https://html.spec.whatwg.org/multipage/scripting.html#upgrades 212 // https://html.spec.whatwg.org/multipage/scripting.html#upgrades
156 bool ScriptCustomElementDefinition::runConstructor(Element* element) 213 bool ScriptCustomElementDefinition::runConstructor(Element* element)
157 { 214 {
158 if (!m_scriptState->contextIsValid()) 215 if (!m_scriptState->contextIsValid())
159 return false; 216 return false;
160 ScriptState::Scope scope(m_scriptState.get()); 217 ScriptState::Scope scope(m_scriptState.get());
161 v8::Isolate* isolate = m_scriptState->isolate(); 218 v8::Isolate* isolate = m_scriptState->isolate();
162 219
163 // Step 5 says to rethrow the exception; but there is no one to 220 // Step 5 says to rethrow the exception; but there is no one to
164 // catch it. The side effect is to report the error. 221 // catch it. The side effect is to report the error.
165 v8::TryCatch tryCatch(isolate); 222 v8::TryCatch tryCatch(isolate);
166 tryCatch.SetVerbose(true); 223 tryCatch.SetVerbose(true);
haraken 2016/06/13 09:05:35 Remove this line.
kojii 2016/06/13 10:28:25 The spec requires to "report the error" here, as i
167 224
168 ExecutionContext* executionContext = m_scriptState->getExecutionContext(); 225 Element* result = runConstructor();
169 v8::Local<v8::Value> result; 226 if (!result)
170 if (!v8Call(V8ScriptRunner::callAsConstructor(
171 isolate,
172 constructor(),
173 executionContext,
174 0,
175 nullptr),
176 result))
177 return false; 227 return false;
178 228
179 if (V8Element::toImplWithTypeCheck(isolate, result) != element) { 229 if (result != element) {
180 V8ThrowException::throwException( 230 V8ThrowException::throwException(
181 V8ThrowException::createDOMException( 231 V8ThrowException::createDOMException(
182 m_scriptState->isolate(), 232 m_scriptState->isolate(),
183 InvalidStateError, 233 InvalidStateError,
184 "custom element constructors must call super() first and must " 234 "custom element constructors must call super() first and must "
185 "not return a different object", 235 "not return a different object",
186 constructor()), 236 constructor()),
187 m_scriptState->isolate()); 237 m_scriptState->isolate());
188 return false; 238 return false;
189 } 239 }
190 240
191 return true; 241 return true;
192 } 242 }
193 243
244 Element* ScriptCustomElementDefinition::runConstructor()
245 {
246 v8::Isolate* isolate = m_scriptState->isolate();
haraken 2016/06/13 09:05:35 Is it guaranteed that you're already in m_scriptSt
kojii 2016/06/13 10:28:25 Yes, this is called from either: 1. createElement
247 ExecutionContext* executionContext = m_scriptState->getExecutionContext();
248 v8::Local<v8::Value> result;
249 if (!v8Call(V8ScriptRunner::callAsConstructor(
250 isolate,
251 constructor(),
252 executionContext,
253 0,
254 nullptr),
255 result)) {
256 return nullptr;
257 }
258 return V8Element::toImplWithTypeCheck(isolate, result);
259 }
260
194 v8::Local<v8::Object> ScriptCustomElementDefinition::constructor() const 261 v8::Local<v8::Object> ScriptCustomElementDefinition::constructor() const
195 { 262 {
196 DCHECK(!m_constructor.isEmpty()); 263 DCHECK(!m_constructor.isEmpty());
197 return m_constructor.newLocal(m_scriptState->isolate()); 264 return m_constructor.newLocal(m_scriptState->isolate());
198 } 265 }
199 266
200 v8::Local<v8::Object> ScriptCustomElementDefinition::prototype() const 267 v8::Local<v8::Object> ScriptCustomElementDefinition::prototype() const
201 { 268 {
202 DCHECK(!m_prototype.isEmpty()); 269 DCHECK(!m_prototype.isEmpty());
203 return m_prototype.newLocal(m_scriptState->isolate()); 270 return m_prototype.newLocal(m_scriptState->isolate());
204 } 271 }
205 272
206 // CustomElementDefinition 273 // CustomElementDefinition
207 ScriptValue ScriptCustomElementDefinition::getConstructorForScript() 274 ScriptValue ScriptCustomElementDefinition::getConstructorForScript()
208 { 275 {
209 return ScriptValue(m_scriptState.get(), constructor()); 276 return ScriptValue(m_scriptState.get(), constructor());
210 } 277 }
211 278
212 } // namespace blink 279 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698