Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / bindings / templates / attributes.cpp
1 {##############################################################################}
2 {% macro attribute_getter(attribute, world_suffix) %}
3 {% filter conditional(attribute.conditional_string) %}
4 static void {{attribute.name}}AttributeGetter{{world_suffix}}(
5 {%- if attribute.is_expose_js_accessors %}
6 const v8::FunctionCallbackInfo<v8::Value>& info
7 {%- else %}
8 const v8::PropertyCallbackInfo<v8::Value>& info
9 {%- endif %})
10 {
11     {% if attribute.is_reflect and not attribute.is_url
12           and attribute.idl_type == 'DOMString' and is_node
13           and not attribute.is_implemented_in_private_script %}
14     {% set cpp_class, v8_class = 'Element', 'V8Element' %}
15     {% endif %}
16     {# holder #}
17     {% if not attribute.is_static %}
18     v8::Handle<v8::Object> holder = info.Holder();
19     {% endif %}
20     {# impl #}
21     {% if attribute.cached_attribute_validation_method %}
22     v8::Handle<v8::String> propertyName = v8AtomicString(info.GetIsolate(), "{{attribute.name}}");
23     {{cpp_class}}* impl = {{v8_class}}::toImpl(holder);
24     if (!impl->{{attribute.cached_attribute_validation_method}}()) {
25         v8::Handle<v8::Value> v8Value = V8HiddenValue::getHiddenValue(info.GetIsolate(), holder, propertyName);
26         if (!v8Value.IsEmpty()) {
27             v8SetReturnValue(info, v8Value);
28             return;
29         }
30     }
31     {% elif not attribute.is_static %}
32     {{cpp_class}}* impl = {{v8_class}}::toImpl(holder);
33     {% endif %}
34     {% if interface_name == 'Window' and attribute.idl_type == 'EventHandler' %}
35     if (!impl->document())
36         return;
37     {% endif %}
38     {# Local variables #}
39     {% if attribute.is_call_with_execution_context %}
40     ExecutionContext* executionContext = currentExecutionContext(info.GetIsolate());
41     {% endif %}
42     {% if attribute.is_call_with_script_state %}
43     ScriptState* scriptState = ScriptState::current(info.GetIsolate());
44     {% endif %}
45     {% if attribute.is_check_security_for_node or
46           attribute.is_getter_raises_exception %}
47     ExceptionState exceptionState(ExceptionState::GetterContext, "{{attribute.name}}", "{{interface_name}}", holder, info.GetIsolate());
48     {% endif %}
49     {% if attribute.is_explicit_nullable %}
50     bool isNull = false;
51     {% endif %}
52     {% if attribute.is_implemented_in_private_script %}
53     {{attribute.cpp_type}} result{{attribute.cpp_type_initializer}};
54     if (!{{attribute.cpp_value_original}})
55         return;
56     {% elif attribute.cpp_value_original %}
57     {{attribute.cpp_type}} {{attribute.cpp_value}}({{attribute.cpp_value_original}});
58     {% endif %}
59     {# Checks #}
60     {% if attribute.is_getter_raises_exception %}
61     if (UNLIKELY(exceptionState.throwIfNeeded()))
62         return;
63     {% endif %}
64     {% if attribute.is_check_security_for_node %}
65     if (!BindingSecurity::shouldAllowAccessToNode(info.GetIsolate(), {{attribute.cpp_value}}, exceptionState)) {
66         v8SetReturnValueNull(info);
67         exceptionState.throwIfNeeded();
68         return;
69     }
70     {% endif %}
71     {% if attribute.reflect_only %}
72     {{release_only_check(attribute.reflect_only, attribute.reflect_missing,
73                          attribute.reflect_invalid, attribute.reflect_empty,
74                          attribute.cpp_value)
75       | indent}}
76     {% endif %}
77     {% if attribute.is_explicit_nullable %}
78     if (isNull) {
79         v8SetReturnValueNull(info);
80         return;
81     }
82     {% endif %}
83     {% if attribute.cached_attribute_validation_method %}
84     V8HiddenValue::setHiddenValue(info.GetIsolate(), holder, propertyName, {{attribute.cpp_value_to_v8_value}});
85     {% endif %}
86     {# v8SetReturnValue #}
87     {% if attribute.is_keep_alive_for_gc %}
88     if ({{attribute.cpp_value}} && DOMDataStore::setReturnValue{{world_suffix}}(info.GetReturnValue(), {{attribute.cpp_value}}.get()))
89         return;
90     v8::Handle<v8::Value> wrapper = toV8({{attribute.cpp_value}}.get(), holder, info.GetIsolate());
91     if (!wrapper.IsEmpty()) {
92         V8HiddenValue::setHiddenValue(info.GetIsolate(), holder, v8AtomicString(info.GetIsolate(), "{{attribute.name}}"), wrapper);
93         {{attribute.v8_set_return_value}};
94     }
95     {% elif world_suffix %}
96     {{attribute.v8_set_return_value_for_main_world}};
97     {% else %}
98     {% if attribute.use_output_parameter_for_result %}
99     {{attribute.cpp_type}} result;
100     {{attribute.cpp_value}};
101     {% endif %}
102     {{attribute.v8_set_return_value}};
103     {% endif %}
104 }
105 {% endfilter %}
106 {% endmacro %}
107
108 {######################################}
109 {% macro release_only_check(reflect_only_values, reflect_missing,
110                             reflect_invalid, reflect_empty, cpp_value) %}
111 {# Attribute is limited to only known values: check that the attribute value is
112    one of those. If not, set it to the empty string.
113    http://www.whatwg.org/specs/web-apps/current-work/#limited-to-only-known-values #}
114 {% if reflect_empty %}
115 if ({{cpp_value}}.isNull()) {
116 {% if reflect_missing %}
117     {{cpp_value}} = "{{reflect_missing}}";
118 {% else %}
119     ;
120 {% endif %}
121 } else if ({{cpp_value}}.isEmpty()) {
122     {{cpp_value}} = "{{reflect_empty}}";
123 {% else %}
124 if ({{cpp_value}}.isEmpty()) {
125 {# FIXME: should use [ReflectEmpty] instead; need to change IDL files #}
126 {% if reflect_missing %}
127     {{cpp_value}} = "{{reflect_missing}}";
128 {% else %}
129     ;
130 {% endif %}
131 {% endif %}
132 {% for value in reflect_only_values %}
133 } else if (equalIgnoringCase({{cpp_value}}, "{{value}}")) {
134     {{cpp_value}} = "{{value}}";
135 {% endfor %}
136 } else {
137     {{cpp_value}} = "{{reflect_invalid}}";
138 }
139 {% endmacro %}
140
141
142 {##############################################################################}
143 {% macro attribute_getter_callback(attribute, world_suffix) %}
144 {% filter conditional(attribute.conditional_string) %}
145 static void {{attribute.name}}AttributeGetterCallback{{world_suffix}}(
146 {%- if attribute.is_expose_js_accessors %}
147 const v8::FunctionCallbackInfo<v8::Value>& info
148 {%- else %}
149 v8::Local<v8::String>, const v8::PropertyCallbackInfo<v8::Value>& info
150 {%- endif %})
151 {
152     TRACE_EVENT_SET_SAMPLING_STATE("blink", "DOMGetter");
153     {% if attribute.deprecate_as %}
154     UseCounter::countDeprecationIfNotPrivateScript(info.GetIsolate(), callingExecutionContext(info.GetIsolate()), UseCounter::{{attribute.deprecate_as}});
155     {% endif %}
156     {% if attribute.measure_as %}
157     UseCounter::countIfNotPrivateScript(info.GetIsolate(), callingExecutionContext(info.GetIsolate()), UseCounter::{{attribute.measure_as}});
158     {% endif %}
159     {% if world_suffix in attribute.activity_logging_world_list_for_getter %}
160     ScriptState* scriptState = ScriptState::from(info.GetIsolate()->GetCurrentContext());
161     V8PerContextData* contextData = scriptState->perContextData();
162     {% if attribute.activity_logging_world_check %}
163     if (scriptState->world().isIsolatedWorld() && contextData && contextData->activityLogger())
164     {% else %}
165     if (contextData && contextData->activityLogger())
166     {% endif %}
167         contextData->activityLogger()->logGetter("{{interface_name}}.{{attribute.name}}");
168     {% endif %}
169     {% if attribute.has_custom_getter %}
170     {{v8_class}}::{{attribute.name}}AttributeGetterCustom(info);
171     {% else %}
172     {{cpp_class_or_partial}}V8Internal::{{attribute.name}}AttributeGetter{{world_suffix}}(info);
173     {% endif %}
174     TRACE_EVENT_SET_SAMPLING_STATE("v8", "V8Execution");
175 }
176 {% endfilter %}
177 {% endmacro %}
178
179
180 {##############################################################################}
181 {% macro constructor_getter_callback(attribute, world_suffix) %}
182 {% filter conditional(attribute.conditional_string) %}
183 static void {{attribute.name}}ConstructorGetterCallback{{world_suffix}}(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value>& info)
184 {
185     TRACE_EVENT_SET_SAMPLING_STATE("blink", "DOMGetter");
186     {% if attribute.deprecate_as %}
187     UseCounter::countDeprecationIfNotPrivateScript(info.GetIsolate(), callingExecutionContext(info.GetIsolate()), UseCounter::{{attribute.deprecate_as}});
188     {% endif %}
189     {% if attribute.measure_as %}
190     UseCounter::countIfNotPrivateScript(info.GetIsolate(), callingExecutionContext(info.GetIsolate()), UseCounter::{{attribute.measure_as}});
191     {% endif %}
192     {{cpp_class_or_partial}}V8Internal::{{cpp_class}}ConstructorGetter{{world_suffix}}(property, info);
193     TRACE_EVENT_SET_SAMPLING_STATE("v8", "V8Execution");
194 }
195 {% endfilter %}
196 {% endmacro %}
197
198
199 {##############################################################################}
200 {% macro attribute_setter(attribute, world_suffix) %}
201 {% filter conditional(attribute.conditional_string) %}
202 static void {{attribute.name}}AttributeSetter{{world_suffix}}(
203 {%- if attribute.is_expose_js_accessors %}
204 v8::Local<v8::Value> v8Value, const v8::FunctionCallbackInfo<v8::Value>& info
205 {%- else %}
206 v8::Local<v8::Value> v8Value, const v8::PropertyCallbackInfo<void>& info
207 {%- endif %})
208 {
209     {% if attribute.is_reflect and attribute.idl_type == 'DOMString'
210           and is_node and not attribute.is_implemented_in_private_script %}
211     {% set cpp_class, v8_class = 'Element', 'V8Element' %}
212     {% endif %}
213     {# Local variables #}
214     {% if not attribute.is_static %}
215     v8::Handle<v8::Object> holder = info.Holder();
216     {% endif %}
217     {% if attribute.has_setter_exception_state %}
218     ExceptionState exceptionState(ExceptionState::SetterContext, "{{attribute.name}}", "{{interface_name}}", holder, info.GetIsolate());
219     {% endif %}
220     {# Type checking #}
221     {% if attribute.has_type_checking_interface %}
222     {# Type checking for interface types (if interface not implemented, throw
223        TypeError), per http://www.w3.org/TR/WebIDL/#es-interface #}
224     if ({% if attribute.is_nullable %}!isUndefinedOrNull(v8Value) && {% endif %}!V8{{attribute.idl_type}}::hasInstance(v8Value, info.GetIsolate())) {
225         exceptionState.throwTypeError("The provided value is not of type '{{attribute.idl_type}}'.");
226         exceptionState.throwIfNeeded();
227         return;
228     }
229     {% endif %}
230     {% if attribute.use_output_parameter_for_result %}
231     {{attribute.cpp_type}} cppValue;
232     {% endif %}
233     {# impl #}
234     {% if attribute.put_forwards %}
235     {{cpp_class}}* proxyImpl = {{v8_class}}::toImpl(holder);
236     {{attribute.cpp_type}} impl = WTF::getPtr(proxyImpl->{{attribute.name}}());
237     if (!impl)
238         return;
239     {% elif not attribute.is_static %}
240     {{cpp_class}}* impl = {{v8_class}}::toImpl(holder);
241     {% endif %}
242     {% if attribute.idl_type == 'EventHandler' and interface_name == 'Window' %}
243     if (!impl->document())
244         return;
245     {% endif %}
246     {# Convert JS value to C++ value #}
247     {% if attribute.idl_type != 'EventHandler' %}
248     {{attribute.v8_value_to_local_cpp_value}};
249     {% elif not is_node %}{# EventHandler hack #}
250     moveEventListenerToNewWrapper(info.GetIsolate(), holder, {{attribute.event_handler_getter_expression}}, v8Value, {{v8_class}}::eventListenerCacheIndex);
251     {% endif %}
252     {# Type checking, possibly throw a TypeError, per:
253        http://www.w3.org/TR/WebIDL/#es-type-mapping #}
254     {% if attribute.has_type_checking_unrestricted %}
255     {# Non-finite floating point values (NaN, +Infinity or âˆ’Infinity), per:
256        http://heycam.github.io/webidl/#es-float
257        http://heycam.github.io/webidl/#es-double #}
258     if (!std::isfinite(cppValue)) {
259         exceptionState.throwTypeError("The provided {{attribute.idl_type}} value is non-finite.");
260         exceptionState.throwIfNeeded();
261         return;
262     }
263     {% elif attribute.enum_validation_expression %}
264     {# Setter ignores invalid enum values:
265        http://www.w3.org/TR/WebIDL/#idl-enums #}
266     String string = cppValue;
267     if (!({{attribute.enum_validation_expression}}))
268         return;
269     {% endif %}
270     {# Pre-set context #}
271     {% if attribute.is_custom_element_callbacks or
272           (attribute.is_reflect and
273            not(attribute.idl_type == 'DOMString' and is_node)) %}
274     {# Skip on compact node DOMString getters #}
275     CustomElementProcessingStack::CallbackDeliveryScope deliveryScope;
276     {% endif %}
277     {% if attribute.is_call_with_execution_context or
278           attribute.is_setter_call_with_execution_context %}
279     ExecutionContext* executionContext = currentExecutionContext(info.GetIsolate());
280     {% endif %}
281     {# Set #}
282     {{attribute.cpp_setter}};
283     {# Post-set #}
284     {% if attribute.is_setter_raises_exception %}
285     exceptionState.throwIfNeeded();
286     {% endif %}
287     {% if attribute.cached_attribute_validation_method %}
288     V8HiddenValue::deleteHiddenValue(info.GetIsolate(), holder, v8AtomicString(info.GetIsolate(), "{{attribute.name}}")); // Invalidate the cached value.
289     {% endif %}
290 }
291 {% endfilter %}
292 {% endmacro %}
293
294
295 {##############################################################################}
296 {% macro attribute_setter_callback(attribute, world_suffix) %}
297 {% filter conditional(attribute.conditional_string) %}
298 static void {{attribute.name}}AttributeSetterCallback{{world_suffix}}(
299 {%- if attribute.is_expose_js_accessors %}
300 const v8::FunctionCallbackInfo<v8::Value>& info
301 {%- else %}
302 v8::Local<v8::String>, v8::Local<v8::Value> v8Value, const v8::PropertyCallbackInfo<void>& info
303 {%- endif %})
304 {
305     {% if attribute.is_expose_js_accessors %}
306     v8::Local<v8::Value> v8Value = info[0];
307     {% endif %}
308     TRACE_EVENT_SET_SAMPLING_STATE("blink", "DOMSetter");
309     {% if attribute.deprecate_as %}
310     UseCounter::countDeprecationIfNotPrivateScript(info.GetIsolate(), callingExecutionContext(info.GetIsolate()), UseCounter::{{attribute.deprecate_as}});
311     {% endif %}
312     {% if attribute.measure_as %}
313     UseCounter::countIfNotPrivateScript(info.GetIsolate(), callingExecutionContext(info.GetIsolate()), UseCounter::{{attribute.measure_as}});
314     {% endif %}
315     {% if world_suffix in attribute.activity_logging_world_list_for_setter %}
316     ScriptState* scriptState = ScriptState::from(info.GetIsolate()->GetCurrentContext());
317     V8PerContextData* contextData = scriptState->perContextData();
318     {% if attribute.activity_logging_world_check %}
319     if (scriptState->world().isIsolatedWorld() && contextData && contextData->activityLogger()) {
320     {% else %}
321     if (contextData && contextData->activityLogger()) {
322     {% endif %}
323         contextData->activityLogger()->logSetter("{{interface_name}}.{{attribute.name}}", v8Value);
324     }
325     {% endif %}
326     {% if attribute.is_custom_element_callbacks or attribute.is_reflect %}
327     CustomElementProcessingStack::CallbackDeliveryScope deliveryScope;
328     {% endif %}
329     {% if attribute.has_custom_setter %}
330     {{v8_class}}::{{attribute.name}}AttributeSetterCustom(v8Value, info);
331     {% else %}
332     {{cpp_class_or_partial}}V8Internal::{{attribute.name}}AttributeSetter{{world_suffix}}(v8Value, info);
333     {% endif %}
334     TRACE_EVENT_SET_SAMPLING_STATE("v8", "V8Execution");
335 }
336 {% endfilter %}
337 {% endmacro %}
338
339
340 {##############################################################################}
341 {% macro attribute_getter_implemented_in_private_script(attribute) %}
342 bool {{v8_class}}::PrivateScript::{{attribute.name}}AttributeGetter(LocalFrame* frame, {{cpp_class}}* holderImpl, {{attribute.cpp_type}}* result)
343 {
344     if (!frame)
345         return false;
346     v8::HandleScope handleScope(toIsolate(frame));
347     ScriptForbiddenScope::AllowUserAgentScript script;
348     v8::Handle<v8::Context> contextInPrivateScript = toV8Context(frame, DOMWrapperWorld::privateScriptIsolatedWorld());
349     if (contextInPrivateScript.IsEmpty())
350         return false;
351     ScriptState* scriptState = ScriptState::from(contextInPrivateScript);
352     ScriptState* scriptStateInUserScript = ScriptState::forMainWorld(frame);
353     if (!scriptState->executionContext())
354         return false;
355
356     ScriptState::Scope scope(scriptState);
357     v8::Handle<v8::Value> holder = toV8(holderImpl, scriptState->context()->Global(), scriptState->isolate());
358
359     ExceptionState exceptionState(ExceptionState::GetterContext, "{{attribute.name}}", "{{cpp_class}}", scriptState->context()->Global(), scriptState->isolate());
360     v8::Handle<v8::Value> v8Value = PrivateScriptRunner::runDOMAttributeGetter(scriptState, scriptStateInUserScript, "{{cpp_class}}", "{{attribute.name}}", holder);
361     if (v8Value.IsEmpty())
362         return false;
363     {{attribute.private_script_v8_value_to_local_cpp_value}};
364     RELEASE_ASSERT(!exceptionState.hadException());
365     *result = cppValue;
366     return true;
367 }
368 {% endmacro %}
369
370
371 {% macro attribute_setter_implemented_in_private_script(attribute) %}
372 bool {{v8_class}}::PrivateScript::{{attribute.name}}AttributeSetter(LocalFrame* frame, {{cpp_class}}* holderImpl, {{attribute.argument_cpp_type}} cppValue)
373 {
374     if (!frame)
375         return false;
376     v8::HandleScope handleScope(toIsolate(frame));
377     ScriptForbiddenScope::AllowUserAgentScript script;
378     v8::Handle<v8::Context> contextInPrivateScript = toV8Context(frame, DOMWrapperWorld::privateScriptIsolatedWorld());
379     if (contextInPrivateScript.IsEmpty())
380         return false;
381     ScriptState* scriptState = ScriptState::from(contextInPrivateScript);
382     ScriptState* scriptStateInUserScript = ScriptState::forMainWorld(frame);
383     if (!scriptState->executionContext())
384         return false;
385
386     ScriptState::Scope scope(scriptState);
387     v8::Handle<v8::Value> holder = toV8(holderImpl, scriptState->context()->Global(), scriptState->isolate());
388
389     ExceptionState exceptionState(ExceptionState::SetterContext, "{{attribute.name}}", "{{cpp_class}}", scriptState->context()->Global(), scriptState->isolate());
390     return PrivateScriptRunner::runDOMAttributeSetter(scriptState, scriptStateInUserScript, "{{cpp_class}}", "{{attribute.name}}", holder, {{attribute.private_script_cpp_value_to_v8_value}});
391 }
392 {% endmacro %}
393
394
395 {##############################################################################}
396 {% macro attribute_configuration(attribute) %}
397 {% set getter_callback =
398        '%sV8Internal::%sAttributeGetterCallback' %
399             (cpp_class_or_partial, attribute.name)
400        if not attribute.constructor_type else
401        ('%sV8Internal::%sConstructorGetterCallback' %
402             (cpp_class_or_partial, attribute.name)
403         if attribute.needs_constructor_getter_callback else
404        '%sV8Internal::%sConstructorGetter' % (cpp_class_or_partial, cpp_class)) %}
405 {% set getter_callback_for_main_world =
406        '%sV8Internal::%sAttributeGetterCallbackForMainWorld' %
407             (cpp_class_or_partial, attribute.name)
408        if attribute.is_per_world_bindings else '0' %}
409 {% set setter_callback = attribute.setter_callback %}
410 {% set setter_callback_for_main_world =
411        '%sV8Internal::%sAttributeSetterCallbackForMainWorld' %
412            (cpp_class_or_partial, attribute.name)
413        if attribute.is_per_world_bindings and
414           (not attribute.is_read_only or attribute.put_forwards) else '0' %}
415 {% set wrapper_type_info =
416        'const_cast<WrapperTypeInfo*>(&V8%s::wrapperTypeInfo)' %
417             attribute.constructor_type
418         if attribute.constructor_type else '0' %}
419 {% set access_control = 'static_cast<v8::AccessControl>(%s)' %
420                         ' | '.join(attribute.access_control_list) %}
421 {% set property_attribute = 'static_cast<v8::PropertyAttribute>(%s)' %
422                             ' | '.join(attribute.property_attributes) %}
423 {% set only_exposed_to_private_script = 'V8DOMConfiguration::OnlyExposedToPrivateScript' if attribute.only_exposed_to_private_script else 'V8DOMConfiguration::ExposedToAllScripts' %}
424 {% set on_prototype = 'V8DOMConfiguration::OnPrototype'
425        if interface_name == 'Window' and attribute.idl_type == 'EventHandler'
426        else 'V8DOMConfiguration::OnInstance' %}
427 {% set attribute_configuration_list = [
428        '"%s"' % attribute.name,
429        getter_callback,
430        setter_callback,
431        getter_callback_for_main_world,
432        setter_callback_for_main_world,
433        wrapper_type_info,
434        access_control,
435        property_attribute,
436        only_exposed_to_private_script,
437    ] %}
438 {% if not attribute.is_expose_js_accessors %}
439 {% set attribute_configuration_list = attribute_configuration_list
440                                     + [on_prototype] %}
441 {% endif %}
442 {{'{'}}{{attribute_configuration_list | join(', ')}}{{'}'}}
443 {%- endmacro %}