OLD | NEW |
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 "core/dom/custom/CustomElementsRegistry.h" | 5 #include "core/dom/custom/CustomElementsRegistry.h" |
6 | 6 |
7 // TODO(dominicc): Stop including Document.h when | 7 // TODO(dominicc): Stop including Document.h when |
8 // v0CustomElementIsDefined has been removed. | 8 // v0CustomElementIsDefined has been removed. |
9 #include "bindings/core/v8/DOMWrapperWorld.h" | 9 #include "bindings/core/v8/DOMWrapperWorld.h" |
10 #include "bindings/core/v8/ExceptionState.h" | 10 #include "bindings/core/v8/ExceptionState.h" |
11 #include "bindings/core/v8/ScriptState.h" | 11 #include "bindings/core/v8/ScriptState.h" |
12 #include "bindings/core/v8/ScriptValue.h" | 12 #include "bindings/core/v8/ScriptValue.h" |
13 #include "bindings/core/v8/V8Binding.h" | 13 #include "bindings/core/v8/V8Binding.h" |
14 #include "bindings/core/v8/V8BindingMacros.h" | 14 #include "bindings/core/v8/V8BindingMacros.h" |
15 #include "bindings/core/v8/V8HiddenValue.h" | 15 #include "bindings/core/v8/V8HiddenValue.h" |
16 #include "core/dom/Document.h" | 16 #include "core/dom/Document.h" |
17 #include "core/dom/ElementRegistrationOptions.h" | 17 #include "core/dom/ElementRegistrationOptions.h" |
18 #include "core/dom/ExceptionCode.h" | 18 #include "core/dom/ExceptionCode.h" |
19 #include "core/dom/custom/CustomElement.h" | 19 #include "core/dom/custom/CustomElement.h" |
20 #include "core/dom/custom/CustomElementDefinition.h" | 20 #include "core/dom/custom/CustomElementDefinition.h" |
21 #include "core/dom/custom/V0CustomElementRegistrationContext.h" | 21 #include "core/dom/custom/V0CustomElementRegistrationContext.h" |
22 #include "core/dom/custom/V0CustomElementRegistry.h" | 22 #include "core/dom/custom/V0CustomElementRegistry.h" |
23 | 23 |
24 namespace blink { | 24 namespace blink { |
25 | 25 |
| 26 namespace { |
| 27 |
| 28 const int kConstructorIndex = 0; |
| 29 const int kPrototypeIndex = 1; |
| 30 const int kSizeOfIdMapEntry = 2; |
| 31 |
| 32 } // namespace |
| 33 |
| 34 |
26 CustomElementsRegistry* CustomElementsRegistry::create( | 35 CustomElementsRegistry* CustomElementsRegistry::create( |
27 ScriptState* scriptState, | 36 ScriptState* scriptState, |
28 V0CustomElementRegistrationContext* v0) | 37 V0CustomElementRegistrationContext* v0) |
29 { | 38 { |
30 DCHECK(scriptState->world().isMainWorld()); | 39 DCHECK(scriptState->world().isMainWorld()); |
31 CustomElementsRegistry* registry = new CustomElementsRegistry(v0); | 40 CustomElementsRegistry* registry = new CustomElementsRegistry(v0); |
32 if (v0) | 41 if (v0) |
33 v0->setV1(registry); | 42 v0->setV1(registry); |
34 | 43 |
35 v8::Isolate* isolate = scriptState->isolate(); | 44 v8::Isolate* isolate = scriptState->isolate(); |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 | 139 |
131 Id id = m_definitions.size(); | 140 Id id = m_definitions.size(); |
132 v8::Local<v8::Value> idValue = v8::Integer::NewFromUnsigned(isolate, id); | 141 v8::Local<v8::Value> idValue = v8::Integer::NewFromUnsigned(isolate, id); |
133 m_definitions.append(new CustomElementDefinition( | 142 m_definitions.append(new CustomElementDefinition( |
134 this, | 143 this, |
135 id, | 144 id, |
136 CustomElementDescriptor(name, name))); | 145 CustomElementDescriptor(name, name))); |
137 // This map is stored in a hidden reference from the | 146 // This map is stored in a hidden reference from the |
138 // CustomElementsRegistry wrapper. | 147 // CustomElementsRegistry wrapper. |
139 v8::Local<v8::Map> map = idMap(scriptState); | 148 v8::Local<v8::Map> map = idMap(scriptState); |
| 149 v8::Local<v8::Array> mapEntry = v8::Array::New(isolate, kSizeOfIdMapEntry); |
| 150 v8CallOrCrash(mapEntry->Set(context, kConstructorIndex, constructor)); |
| 151 v8CallOrCrash(mapEntry->Set(context, kPrototypeIndex, prototype)); |
140 // The map keeps the constructor and prototypes alive. | 152 // The map keeps the constructor and prototypes alive. |
141 v8CallOrCrash(map->Set(context, constructor, idValue)); | 153 v8CallOrCrash(map->Set(context, constructor, idValue)); |
142 v8CallOrCrash(map->Set(context, idValue, prototype)); | 154 v8CallOrCrash(map->Set(context, idValue, mapEntry)); |
143 m_names.add(name); | 155 m_names.add(name, id); |
144 | 156 |
145 // TODO(dominicc): Implement steps: | 157 // TODO(dominicc): Implement steps: |
146 // 20: when-defined promise processing | 158 // 20: when-defined promise processing |
147 DCHECK(!tryCatch.HasCaught() || tryCatch.HasTerminated()); | 159 DCHECK(!tryCatch.HasCaught() || tryCatch.HasTerminated()); |
148 } | 160 } |
149 | 161 |
150 CustomElementDefinition* CustomElementsRegistry::definitionForConstructor( | 162 CustomElementDefinition* CustomElementsRegistry::definitionForConstructor( |
151 ScriptState* scriptState, | 163 ScriptState* scriptState, |
152 v8::Local<v8::Value> constructor) | 164 v8::Local<v8::Value> constructor) |
153 { | 165 { |
154 Id id; | 166 Id id; |
155 if (!idForConstructor(scriptState, constructor, id)) | 167 if (!idForConstructor(scriptState, constructor, id)) |
156 return nullptr; | 168 return nullptr; |
157 return m_definitions[id]; | 169 return m_definitions[id]; |
158 } | 170 } |
159 | 171 |
| 172 // https://html.spec.whatwg.org/multipage/scripting.html#dom-customelementsregis
try-get |
| 173 ScriptValue CustomElementsRegistry::get( |
| 174 ScriptState* scriptState, |
| 175 const AtomicString& name) |
| 176 { |
| 177 DCHECK(scriptState->world().isMainWorld()); |
| 178 const auto& it = m_names.find(name); |
| 179 if (it == m_names.end()) |
| 180 return ScriptValue(scriptState, v8Undefined()); |
| 181 v8::Local<v8::Context> context = scriptState->context(); |
| 182 v8::Local<v8::Map> map = idMap(scriptState); |
| 183 v8::Local<v8::Value> mapEntry = v8CallOrCrash( |
| 184 map->Get(context, toV8(it->value, scriptState))); |
| 185 DCHECK(mapEntry->IsArray()) << *v8::String::Utf8Value(mapEntry); |
| 186 v8::Local<v8::Value> result = v8CallOrCrash( |
| 187 mapEntry.As<v8::Array>()->Get(context, kConstructorIndex)); |
| 188 return ScriptValue(scriptState, result); |
| 189 } |
| 190 |
160 v8::Local<v8::Object> CustomElementsRegistry::prototype( | 191 v8::Local<v8::Object> CustomElementsRegistry::prototype( |
161 ScriptState* scriptState, | 192 ScriptState* scriptState, |
162 const CustomElementDefinition& def) | 193 const CustomElementDefinition& def) |
163 { | 194 { |
164 v8::Local<v8::Value> idValue = | 195 v8::Local<v8::Value> idValue = toV8(def.id(), scriptState); |
165 v8::Integer::NewFromUnsigned(scriptState->isolate(), def.id()); | 196 v8::Local<v8::Value> mapEntry = v8CallOrCrash( |
166 return v8CallOrCrash( | 197 idMap(scriptState)->Get(scriptState->context(), idValue)); |
167 idMap(scriptState)->Get(scriptState->context(), idValue)) | 198 return mapEntry.As<v8::Array>()->Get(kPrototypeIndex).As<v8::Object>(); |
168 .As<v8::Object>(); | |
169 } | 199 } |
170 | 200 |
171 bool CustomElementsRegistry::nameIsDefined(const AtomicString& name) const | 201 bool CustomElementsRegistry::nameIsDefined(const AtomicString& name) const |
172 { | 202 { |
173 return m_names.contains(name); | 203 return m_names.contains(name); |
174 } | 204 } |
175 | 205 |
| 206 // Note: Since |toV8(this, scriptState)| requires non-const pointer, we can't |
| 207 // make |idMap()| as const function. |
176 v8::Local<v8::Map> CustomElementsRegistry::idMap(ScriptState* scriptState) | 208 v8::Local<v8::Map> CustomElementsRegistry::idMap(ScriptState* scriptState) |
177 { | 209 { |
178 DCHECK(scriptState->world().isMainWorld()); | 210 DCHECK(scriptState->world().isMainWorld()); |
179 v8::Local<v8::Object> wrapper = | 211 v8::Local<v8::Object> wrapper = |
180 toV8(this, scriptState).As<v8::Object>(); | 212 toV8(this, scriptState).As<v8::Object>(); |
181 v8::Local<v8::String> name = V8HiddenValue::customElementsRegistryMap( | 213 v8::Local<v8::String> name = V8HiddenValue::customElementsRegistryMap( |
182 scriptState->isolate()); | 214 scriptState->isolate()); |
183 return V8HiddenValue::getHiddenValue(scriptState, wrapper, name) | 215 return V8HiddenValue::getHiddenValue(scriptState, wrapper, name) |
184 .As<v8::Map>(); | 216 .As<v8::Map>(); |
185 } | 217 } |
(...skipping 16 matching lines...) Expand all Loading... |
202 return m_v0.get() && m_v0->nameIsDefined(name); | 234 return m_v0.get() && m_v0->nameIsDefined(name); |
203 } | 235 } |
204 | 236 |
205 DEFINE_TRACE(CustomElementsRegistry) | 237 DEFINE_TRACE(CustomElementsRegistry) |
206 { | 238 { |
207 visitor->trace(m_definitions); | 239 visitor->trace(m_definitions); |
208 visitor->trace(m_v0); | 240 visitor->trace(m_v0); |
209 } | 241 } |
210 | 242 |
211 } // namespace blink | 243 } // namespace blink |
OLD | NEW |