OLD | NEW |
---|---|
1 {% filter format_blink_cpp_source_code %} | 1 {% filter format_blink_cpp_source_code %} |
2 | 2 |
3 {% include 'copyright_block.txt' %} | 3 {% include 'copyright_block.txt' %} |
4 #include "{{v8_class_or_partial}}.h" | 4 #include "{{v8_class_or_partial}}.h" |
5 | 5 |
6 {% for filename in cpp_includes if filename != '%s.h' % cpp_class_or_partial %} | 6 {% for filename in cpp_includes if filename != '%s.h' % cpp_class_or_partial %} |
7 #include "{{filename}}" | 7 #include "{{filename}}" |
8 {% endfor %} | 8 {% endfor %} |
9 | 9 |
10 namespace blink { | 10 namespace blink { |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
114 {% endif %} | 114 {% endif %} |
115 {% if attribute.has_setter %} | 115 {% if attribute.has_setter %} |
116 {% if not attribute.has_custom_setter %} | 116 {% if not attribute.has_custom_setter %} |
117 {{attribute_setter(attribute, world_suffix)}} | 117 {{attribute_setter(attribute, world_suffix)}} |
118 {% endif %} | 118 {% endif %} |
119 {{attribute_setter_callback(attribute, world_suffix)}} | 119 {{attribute_setter_callback(attribute, world_suffix)}} |
120 {% endif %} | 120 {% endif %} |
121 {% endfor %} | 121 {% endfor %} |
122 {% endfor %} | 122 {% endfor %} |
123 {##############################################################################} | 123 {##############################################################################} |
124 {% block security_check_functions %} | |
125 {% if has_access_check_callbacks and not is_partial %} | |
126 bool securityCheck(v8::Local<v8::Context> accessingContext, v8::Local<v8::Object > accessedObject, v8::Local<v8::Value> data) { | |
127 {% if interface_name == 'Window' %} | |
128 v8::Isolate* isolate = v8::Isolate::GetCurrent(); | |
129 v8::Local<v8::Object> window = V8Window::findInstanceInPrototypeChain(accessed Object, isolate); | |
130 if (window.IsEmpty()) | |
131 return false; // the frame is gone. | |
132 | |
133 const DOMWindow* targetWindow = V8Window::toImpl(window); | |
134 return BindingSecurity::shouldAllowAccessTo(toLocalDOMWindow(toDOMWindow(acces singContext)), targetWindow, BindingSecurity::ErrorReportOption::DoNotReport); | |
135 {% else %}{# if interface_name == 'Window' #} | |
136 {# Not 'Window' means it\'s Location. #} | |
137 {{cpp_class}}* impl = {{v8_class}}::toImpl(accessedObject); | |
138 return BindingSecurity::shouldAllowAccessTo(toLocalDOMWindow(toDOMWindow(acces singContext)), impl, BindingSecurity::ErrorReportOption::DoNotReport); | |
139 {% endif %}{# if interface_name == 'Window' #} | |
140 } | |
141 | |
142 {% endif %} | |
143 {% endblock %} | |
144 {##############################################################################} | |
145 {# Methods #} | 124 {# Methods #} |
146 {% from 'methods.cpp.tmpl' import generate_method, overload_resolution_method, | 125 {% from 'methods.cpp.tmpl' import generate_method, overload_resolution_method, |
147 method_callback, origin_safe_method_getter, generate_constructor, | 126 method_callback, origin_safe_method_getter, generate_constructor, |
148 method_implemented_in_private_script, generate_post_message_impl, | 127 method_implemented_in_private_script, generate_post_message_impl, |
149 runtime_determined_length_method, runtime_determined_maxarg_method | 128 runtime_determined_length_method, runtime_determined_maxarg_method |
150 with context %} | 129 with context %} |
151 {% for method in methods if method.should_be_exposed_to_script %} | 130 {% for method in methods if method.should_be_exposed_to_script %} |
152 {% for world_suffix in method.world_suffixes %} | 131 {% for world_suffix in method.world_suffixes %} |
153 {% if not method.is_custom and not method.is_post_message and method.visible %} | 132 {% if not method.is_custom and not method.is_post_message and method.visible %} |
154 {{generate_method(method, world_suffix)}} | 133 {{generate_method(method, world_suffix)}} |
(...skipping 14 matching lines...) Expand all Loading... | |
169 {# Document about the following condition: #} | 148 {# Document about the following condition: #} |
170 {# https://docs.google.com/document/d/1qBC7Therp437Jbt_QYAtNYMZs6zQ_7_tnMkNUG_AC qs/edit?usp=sharing #} | 149 {# https://docs.google.com/document/d/1qBC7Therp437Jbt_QYAtNYMZs6zQ_7_tnMkNUG_AC qs/edit?usp=sharing #} |
171 {% if (method.overloads and method.overloads.visible and | 150 {% if (method.overloads and method.overloads.visible and |
172 (not method.overloads.has_partial_overloads or not is_partial)) or | 151 (not method.overloads.has_partial_overloads or not is_partial)) or |
173 (not method.overloads and method.visible) %} | 152 (not method.overloads and method.visible) %} |
174 {# A single callback is generated for overloaded methods #} | 153 {# A single callback is generated for overloaded methods #} |
175 {# with considering partial overloads #} | 154 {# with considering partial overloads #} |
176 {{method_callback(method, world_suffix)}} | 155 {{method_callback(method, world_suffix)}} |
177 {% endif %} | 156 {% endif %} |
178 {% endif %} | 157 {% endif %} |
179 {% if method.is_do_not_check_security and method.visible %} | 158 {% if method.is_cross_origin and method.visible %} |
180 {{origin_safe_method_getter(method, world_suffix)}} | 159 {{origin_safe_method_getter(method, world_suffix)}} |
181 {% endif %} | 160 {% endif %} |
182 {% endfor %} | 161 {% endfor %} |
183 {% endfor %} | 162 {% endfor %} |
184 {% if iterator_method %} | 163 {% if iterator_method %} |
185 {{generate_method(iterator_method)}} | 164 {{generate_method(iterator_method)}} |
186 {{method_callback(iterator_method)}} | 165 {{method_callback(iterator_method)}} |
187 {% endif %} | 166 {% endif %} |
188 {% block origin_safe_method_setter %}{% endblock %} | 167 {% block origin_safe_method_setter %}{% endblock %} |
189 {# Constructors #} | 168 {# Constructors #} |
(...skipping 12 matching lines...) Expand all Loading... | |
202 {% block named_property_query %}{% endblock %} | 181 {% block named_property_query %}{% endblock %} |
203 {% block named_property_query_callback %}{% endblock %} | 182 {% block named_property_query_callback %}{% endblock %} |
204 {% block named_property_enumerator %}{% endblock %} | 183 {% block named_property_enumerator %}{% endblock %} |
205 {% block named_property_enumerator_callback %}{% endblock %} | 184 {% block named_property_enumerator_callback %}{% endblock %} |
206 {% block indexed_property_getter %}{% endblock %} | 185 {% block indexed_property_getter %}{% endblock %} |
207 {% block indexed_property_getter_callback %}{% endblock %} | 186 {% block indexed_property_getter_callback %}{% endblock %} |
208 {% block indexed_property_setter %}{% endblock %} | 187 {% block indexed_property_setter %}{% endblock %} |
209 {% block indexed_property_setter_callback %}{% endblock %} | 188 {% block indexed_property_setter_callback %}{% endblock %} |
210 {% block indexed_property_deleter %}{% endblock %} | 189 {% block indexed_property_deleter %}{% endblock %} |
211 {% block indexed_property_deleter_callback %}{% endblock %} | 190 {% block indexed_property_deleter_callback %}{% endblock %} |
191 {##############################################################################} | |
192 {% block security_check_functions %} | |
193 {% if has_access_check_callbacks and not is_partial %} | |
194 bool securityCheck(v8::Local<v8::Context> accessingContext, v8::Local<v8::Object > accessedObject, v8::Local<v8::Value> data) { | |
195 {% if interface_name == 'Window' %} | |
196 v8::Isolate* isolate = v8::Isolate::GetCurrent(); | |
197 v8::Local<v8::Object> window = V8Window::findInstanceInPrototypeChain(accessed Object, isolate); | |
198 if (window.IsEmpty()) | |
199 return false; // the frame is gone. | |
haraken
2016/12/08 08:21:02
Not really. window.IsEmpty happens when the protot
dcheng
2016/12/08 09:04:11
I'm just copying and pasting code here =)
What wo
haraken
2016/12/09 02:26:55
"It's not a window wrapper" :)
dcheng
2016/12/09 05:06:14
Strictly speaking, is that true though? We only se
| |
200 | |
201 const DOMWindow* targetWindow = V8Window::toImpl(window); | |
202 return BindingSecurity::shouldAllowAccessTo(toLocalDOMWindow(toDOMWindow(acces singContext)), targetWindow, BindingSecurity::ErrorReportOption::DoNotReport); | |
203 {% else %}{# if interface_name == 'Window' #} | |
204 {# Not 'Window' means it\'s Location. #} | |
205 {{cpp_class}}* impl = {{v8_class}}::toImpl(accessedObject); | |
206 return BindingSecurity::shouldAllowAccessTo(toLocalDOMWindow(toDOMWindow(acces singContext)), impl, BindingSecurity::ErrorReportOption::DoNotReport); | |
207 {% endif %}{# if interface_name == 'Window' #} | |
208 } | |
209 | |
210 {% if has_cross_origin_named_enumerator %} | |
211 // TODO(dcheng): Can we / should we use AtomicString here? That means using DEFI NE_STATIC_LOCAL here. | |
haraken
2016/12/08 08:21:02
I'm fine with const char*.
dcheng
2016/12/08 09:04:11
Done. I removed the TODO... I think it might still
| |
212 static const struct { | |
213 using GetterCallback = void(*)(const v8::PropertyCallbackInfo<v8::Value>&); | |
214 using SetterCallback = void(*)(v8::Local<v8::Value>, const V8CrossOriginSetter Info&); | |
215 | |
216 const char* const name; | |
217 const GetterCallback getter; | |
218 const SetterCallback setter; | |
219 } kCrossOriginAttributeTable[] = { | |
220 {##### Cross-origin attributes #####} | |
221 {% for attribute in attributes if attribute.has_cross_origin_getter or attribu te.has_cross_origin_setter %} | |
222 { | |
223 "{{attribute.name}}", | |
224 {%+ if attribute.has_cross_origin_getter %}&{{cpp_class}}V8Internal::{{attri bute.name}}AttributeGetter{% else %}nullptr{% endif %}, | |
225 {%+ if attribute.has_cross_origin_setter %}&{{cpp_class}}V8Internal::{{attri bute.name}}AttributeSetter{% else %}nullptr{% endif %}, | |
226 }, | |
227 {% endfor %} | |
228 {##### Cross-origin methods #####} | |
229 {% for method in methods if method.is_cross_origin %} | |
230 {"{{method.name}}", &{{cpp_class}}V8Internal::{{method.name}}OriginSafeMethodG etter, nullptr}, | |
haraken
2016/12/08 08:21:02
After this CL, OriginSafeMethodSetter is no longer
dcheng
2016/12/08 09:04:11
Unfortunately, it is still needed. Originally, I t
haraken
2016/12/09 02:26:56
Yes, I understand why we still need to keep Origin
dcheng
2016/12/09 05:06:13
I thought that this would be needed so that if JS
| |
231 {% endfor %} | |
232 }; | |
233 {% endif %} | |
234 | |
235 {% if has_cross_origin_named_getter %} | |
236 void crossOriginNamedGetter(v8::Local<v8::Name> name, const v8::PropertyCallback Info<v8::Value>& info) { | |
haraken
2016/12/08 08:21:02
Just to confirm: V8 calls back crossOriginNamedGet
dcheng
2016/12/08 09:04:11
That's correct: this interceptor is only invoked w
| |
237 if (!name->IsString()) | |
238 return; | |
239 const AtomicString& propertyName = toCoreAtomicString(name.As<v8::String>()); | |
240 | |
241 for (const auto& attribute: kCrossOriginAttributeTable) { | |
Yuki
2016/12/07 12:03:40
nit: attribute : kCrossOrigin...
(one space before
dcheng
2016/12/08 09:04:11
Done.
| |
242 if (propertyName == attribute.name && attribute.getter) { | |
243 attribute.getter(info); | |
244 return; | |
245 } | |
246 } | |
247 | |
248 {% if named_property_getter and named_property_getter.is_cross_origin %} | |
249 {% if named_property_getter.is_custom %} | |
250 {{v8_class}}::namedPropertyGetterCustom(propertyName, info); | |
251 {% else %} | |
252 {{cpp_class}}V8Internal::namedPropertyGetter(propertyName, info); | |
253 {% endif %} | |
254 {% else %} | |
255 BindingSecurity::failedAccessCheckFor( | |
256 info.GetIsolate(), | |
257 {{v8_class}}::toImpl(info.Holder())->frame()); | |
258 {% endif %} | |
259 } | |
260 {% endif %} | |
261 | |
262 {% if has_cross_origin_named_setter %} | |
263 void crossOriginNamedSetter(v8::Local<v8::Name> name, v8::Local<v8::Value> value , const v8::PropertyCallbackInfo<v8::Value>& info) { | |
264 if (!name->IsString()) | |
265 return; | |
266 const AtomicString& propertyName = toCoreAtomicString(name.As<v8::String>()); | |
267 | |
268 for (const auto& attribute: kCrossOriginAttributeTable) { | |
Yuki
2016/12/07 12:03:40
ditto
dcheng
2016/12/08 09:04:11
Done.
| |
269 if (propertyName == attribute.name && attribute.setter) { | |
270 attribute.setter(value, V8CrossOriginSetterInfo(info.GetIsolate(), info.Ho lder())); | |
271 return; | |
272 } | |
273 } | |
274 | |
haraken
2016/12/08 08:21:02
Why don't you need to call V8Internal::namedProper
dcheng
2016/12/08 09:04:11
I could add this for consistency... but there is n
haraken
2016/12/09 02:26:56
Okay, let's add a comment.
dcheng
2016/12/09 05:06:13
Done.
| |
275 BindingSecurity::failedAccessCheckFor( | |
276 info.GetIsolate(), | |
277 {{v8_class}}::toImpl(info.Holder())->frame()); | |
278 } | |
279 {% endif %} | |
280 | |
281 {% if has_cross_origin_named_enumerator %} | |
282 void crossOriginNamedEnumerator(const v8::PropertyCallbackInfo<v8::Array>& info) { | |
283 Vector<String> names; | |
284 for (const auto& attribute : kCrossOriginAttributeTable) | |
285 names.append(attribute.name); | |
286 | |
287 v8SetReturnValue( | |
288 info, | |
289 toV8(names, info.Holder(), info.GetIsolate()).As<v8::Array>()); | |
290 } | |
291 {% endif %} | |
292 | |
293 {% if has_cross_origin_indexed_getter %} | |
294 void crossOriginIndexedGetter(uint32_t index, const v8::PropertyCallbackInfo<v8: :Value>& info) { | |
295 {% if indexed_property_getter.is_custom %} | |
296 {{v8_class}}::indexedPropertyGetterCustom(index, info); | |
haraken
2016/12/08 08:21:02
Is there any real use case of indexedPropertyGette
dcheng
2016/12/08 09:04:10
See my previous comment about window[0], window[1]
| |
297 {% else %} | |
298 {{cpp_class}}V8Internal::indexedPropertyGetter(index, info); | |
299 {% endif %} | |
300 } | |
301 {% endif %} | |
302 | |
303 {% endif %} | |
304 {% endblock %} | |
305 {##############################################################################} | |
212 } // namespace {{cpp_class_or_partial}}V8Internal | 306 } // namespace {{cpp_class_or_partial}}V8Internal |
213 | 307 |
214 {% block visit_dom_wrapper %}{% endblock %} | 308 {% block visit_dom_wrapper %}{% endblock %} |
215 {##############################################################################} | 309 {##############################################################################} |
216 {% block install_attributes %} | 310 {% block install_attributes %} |
217 {% from 'attributes.cpp.tmpl' import attribute_configuration with context %} | 311 {% from 'attributes.cpp.tmpl' import attribute_configuration with context %} |
218 {% if attributes | has_attribute_configuration %} | 312 {% if attributes | has_attribute_configuration %} |
219 // Suppress warning: global constructors, because AttributeConfiguration is triv ial | 313 // Suppress warning: global constructors, because AttributeConfiguration is triv ial |
220 // and does not depend on another global objects. | 314 // and does not depend on another global objects. |
221 #if defined(COMPONENT_BUILD) && defined(WIN32) && COMPILER(CLANG) | 315 #if defined(COMPONENT_BUILD) && defined(WIN32) && COMPILER(CLANG) |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
343 {% endif %} | 437 {% endif %} |
344 {% if attributes | has_accessor_configuration %} | 438 {% if attributes | has_accessor_configuration %} |
345 V8DOMConfiguration::installAccessors(isolate, world, instanceTemplate, prototy peTemplate, interfaceTemplate, signature, {{'%sAccessors' % v8_class}}, {{'WTF_A RRAY_LENGTH(%sAccessors)' % v8_class}}); | 439 V8DOMConfiguration::installAccessors(isolate, world, instanceTemplate, prototy peTemplate, interfaceTemplate, signature, {{'%sAccessors' % v8_class}}, {{'WTF_A RRAY_LENGTH(%sAccessors)' % v8_class}}); |
346 {% endif %} | 440 {% endif %} |
347 {% if methods | has_method_configuration(is_partial) %} | 441 {% if methods | has_method_configuration(is_partial) %} |
348 V8DOMConfiguration::installMethods(isolate, world, instanceTemplate, prototype Template, interfaceTemplate, signature, {{'%sMethods' % v8_class}}, {{'WTF_ARRAY _LENGTH(%sMethods)' % v8_class}}); | 442 V8DOMConfiguration::installMethods(isolate, world, instanceTemplate, prototype Template, interfaceTemplate, signature, {{'%sMethods' % v8_class}}, {{'WTF_ARRAY _LENGTH(%sMethods)' % v8_class}}); |
349 {% endif %} | 443 {% endif %} |
350 {% endfilter %} | 444 {% endfilter %} |
351 {%- if has_access_check_callbacks and not is_partial %}{{newline}} | 445 {%- if has_access_check_callbacks and not is_partial %}{{newline}} |
352 // Cross-origin access check | 446 // Cross-origin access check |
353 instanceTemplate->SetAccessCheckCallback({{cpp_class}}V8Internal::securityChec k, v8::External::New(isolate, const_cast<WrapperTypeInfo*>(&{{v8_class}}::wrappe rTypeInfo))); | 447 {% set cross_origin_named_getter = '%sV8Internal::crossOriginNamedGetter' % cp p_class if has_cross_origin_named_getter else 'nullptr' %} |
448 {% set cross_origin_named_setter = '%sV8Internal::crossOriginNamedSetter' % cp p_class if has_cross_origin_named_setter else 'nullptr' %} | |
449 {% set cross_origin_named_enumerator = '%sV8Internal::crossOriginNamedEnumerat or' % cpp_class if has_cross_origin_named_enumerator else 'nullptr' %} | |
450 {% set cross_origin_indexed_getter = '%sV8Internal::crossOriginIndexedGetter' % cpp_class if has_cross_origin_indexed_getter else 'nullptr' %} | |
451 instanceTemplate->SetAccessCheckCallbackAndHandler({{cpp_class}}V8Internal::se curityCheck, v8::NamedPropertyHandlerConfiguration({{cross_origin_named_getter}} , {{cross_origin_named_setter}}, nullptr, nullptr, {{cross_origin_named_enumerat or}}), v8::IndexedPropertyHandlerConfiguration({{cross_origin_indexed_getter}}), v8::External::New(isolate, const_cast<WrapperTypeInfo*>(&{{v8_class}}::wrapperT ypeInfo))); | |
354 {% endif %} | 452 {% endif %} |
355 | 453 |
356 {%- for group in attributes | purely_runtime_enabled_attributes | groupby('run time_feature_name') %}{{newline}} | 454 {%- for group in attributes | purely_runtime_enabled_attributes | groupby('run time_feature_name') %}{{newline}} |
357 if ({{group.list[0].runtime_enabled_function}}()) { | 455 if ({{group.list[0].runtime_enabled_function}}()) { |
358 {% for attribute in group.list | unique_by('name') | sort %} | 456 {% for attribute in group.list | unique_by('name') | sort %} |
359 {% if attribute.is_data_type_property %} | 457 {% if attribute.is_data_type_property %} |
360 const V8DOMConfiguration::AttributeConfiguration attribute{{attribute.name}} Configuration = {{attribute_configuration(attribute)}}; | 458 const V8DOMConfiguration::AttributeConfiguration attribute{{attribute.name}} Configuration = {{attribute_configuration(attribute)}}; |
361 V8DOMConfiguration::installAttribute(isolate, world, instanceTemplate, proto typeTemplate, attribute{{attribute.name}}Configuration); | 459 V8DOMConfiguration::installAttribute(isolate, world, instanceTemplate, proto typeTemplate, attribute{{attribute.name}}Configuration); |
362 {% else %} | 460 {% else %} |
363 const V8DOMConfiguration::AccessorConfiguration accessor{{attribute.name}}Co nfiguration = {{attribute_configuration(attribute)}}; | 461 const V8DOMConfiguration::AccessorConfiguration accessor{{attribute.name}}Co nfiguration = {{attribute_configuration(attribute)}}; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
402 instanceTemplate->MarkAsUndetectable(); | 500 instanceTemplate->MarkAsUndetectable(); |
403 {% endif %} | 501 {% endif %} |
404 | 502 |
405 {%- if methods | custom_registration(is_partial) %}{{newline}} | 503 {%- if methods | custom_registration(is_partial) %}{{newline}} |
406 {% for method in methods | custom_registration(is_partial) %} | 504 {% for method in methods | custom_registration(is_partial) %} |
407 {# install_custom_signature #} | 505 {# install_custom_signature #} |
408 {% filter exposed(method.overloads.exposed_test_all | 506 {% filter exposed(method.overloads.exposed_test_all |
409 if method.overloads else method.exposed_test) %} | 507 if method.overloads else method.exposed_test) %} |
410 {% filter runtime_enabled(method.overloads.runtime_enabled_function_all | 508 {% filter runtime_enabled(method.overloads.runtime_enabled_function_all |
411 if method.overloads else method.runtime_enabled_func tion) %} | 509 if method.overloads else method.runtime_enabled_func tion) %} |
412 {% if method.is_do_not_check_security %} | 510 {% if method.is_cross_origin %} |
413 {{install_do_not_check_security_method(method, '', 'instanceTemplate', 'protot ypeTemplate') | indent(2)}} | 511 {# TODO(dcheng): This shouldn't be necessary with cross-origin interceptors, |
512 but v8 doesn't support querying the incumbent context. For now, always | |
513 incorrectly create per-realm representations. #} | |
514 {{install_origin_safe_method(method, '', 'instanceTemplate', 'prototypeTemplat e') | indent(2)}} | |
414 {% else %} | 515 {% else %} |
415 {{install_custom_signature(method, 'instanceTemplate', 'prototypeTemplate', 'i nterfaceTemplate', 'signature') | indent(2)}} | 516 {{install_custom_signature(method, 'instanceTemplate', 'prototypeTemplate', 'i nterfaceTemplate', 'signature') | indent(2)}} |
416 {% endif %} | 517 {% endif %} |
417 {% endfilter %} | 518 {% endfilter %} |
418 {% endfilter %} | 519 {% endfilter %} |
419 {% endfor %} | 520 {% endfor %} |
420 {% endif %} | 521 {% endif %} |
421 } | 522 } |
422 | 523 |
423 {% endif %}{# not is_array_buffer_or_view #} | 524 {% endif %}{# not is_array_buffer_or_view #} |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
489 {% for attribute in attributes if attribute.is_implemented_in_private_script %} | 590 {% for attribute in attributes if attribute.is_implemented_in_private_script %} |
490 {{attribute_getter_implemented_in_private_script(attribute)}} | 591 {{attribute_getter_implemented_in_private_script(attribute)}} |
491 {% if attribute.has_setter %} | 592 {% if attribute.has_setter %} |
492 {{attribute_setter_implemented_in_private_script(attribute)}} | 593 {{attribute_setter_implemented_in_private_script(attribute)}} |
493 {% endif %} | 594 {% endif %} |
494 {% endfor %} | 595 {% endfor %} |
495 {% block partial_interface %}{% endblock %} | 596 {% block partial_interface %}{% endblock %} |
496 } // namespace blink | 597 } // namespace blink |
497 | 598 |
498 {% endfilter %}{# format_blink_cpp_source_code #} | 599 {% endfilter %}{# format_blink_cpp_source_code #} |
OLD | NEW |