8bb8b9351acbe465ccc4748a9da2ed4926a64cb4
[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 and
12           attribute.idl_type == 'DOMString' and is_node %}
13     {% set cpp_class, v8_class = 'Element', 'V8Element' %}
14     {# FIXME: Perl skips most of function, but this seems unnecessary #}
15     {% endif %}
16     {% if attribute.is_unforgeable %}
17     v8::Handle<v8::Object> holder = info.This()->FindInstanceInPrototypeChain({{v8_class}}::domTemplate(info.GetIsolate(), worldType(info.GetIsolate())));
18     if (holder.IsEmpty())
19         return;
20     {{cpp_class}}* imp = {{v8_class}}::toNative(holder);
21     {% endif %}
22     {% if attribute.cached_attribute_validation_method %}
23     v8::Handle<v8::String> propertyName = v8AtomicString(info.GetIsolate(), "{{attribute.name}}");
24     {{cpp_class}}* imp = {{v8_class}}::toNative(info.Holder());
25     if (!imp->{{attribute.cached_attribute_validation_method}}()) {
26         v8::Handle<v8::Value> jsValue = getHiddenValue(info.GetIsolate(), info.Holder(), propertyName);
27         if (!jsValue.IsEmpty()) {
28             v8SetReturnValue(info, jsValue);
29             return;
30         }
31     }
32     {% elif not (attribute.is_static or attribute.is_unforgeable) %}
33     {{cpp_class}}* imp = {{v8_class}}::toNative(info.Holder());
34     {% endif %}
35     {% if attribute.is_call_with_execution_context %}
36     ExecutionContext* scriptContext = getExecutionContext();
37     {% endif %}
38     {# Special cases #}
39     {% if attribute.is_check_security_for_node or
40           attribute.is_getter_raises_exception %}
41     ExceptionState exceptionState(ExceptionState::GetterContext, "{{attribute.name}}", "{{interface_name}}", info.Holder(), info.GetIsolate());
42     {% endif %}
43     {% if attribute.is_check_security_for_node %}
44     {# FIXME: consider using a local variable to not call getter twice #}
45     if (!BindingSecurity::shouldAllowAccessToNode({{attribute.cpp_value}}, exceptionState)) {
46         v8SetReturnValueNull(info);
47         exceptionState.throwIfNeeded();
48         return;
49     }
50     {% endif %}
51     {% if attribute.is_getter_raises_exception %}
52     {{attribute.cpp_type}} {{attribute.cpp_value}} = {{attribute.cpp_value_original}};
53     if (UNLIKELY(exceptionState.throwIfNeeded()))
54         return;
55     {% endif %}
56     {% if attribute.is_nullable %}
57     bool isNull = false;
58     {{attribute.cpp_type}} {{attribute.cpp_value}} = {{attribute.cpp_value_original}};
59     if (isNull) {
60         v8SetReturnValueNull(info);
61         return;
62     }
63     {% elif attribute.idl_type == 'EventHandler' or
64             attribute.cached_attribute_validation_method %}
65     {# FIXME: consider merging all these assign to local variable statements #}
66     {{attribute.cpp_type}} {{attribute.cpp_value}} = {{attribute.cpp_value_original}};
67     {% endif %}
68     {% if attribute.cached_attribute_validation_method %}
69     setHiddenValue(info.GetIsolate(), info.Holder(), propertyName, {{attribute.cpp_value}}.v8Value());
70     {% endif %}
71     {# End special cases #}
72     {% if attribute.is_keep_alive_for_gc %}
73     {{attribute.cpp_type}} result = {{attribute.cpp_value}};
74     if (result && DOMDataStore::setReturnValueFromWrapper<{{attribute.v8_type}}>(info.GetReturnValue(), result.get()))
75         return;
76     v8::Handle<v8::Value> wrapper = toV8(result.get(), info.Holder(), info.GetIsolate());
77     if (!wrapper.IsEmpty()) {
78         setHiddenValue(info.GetIsolate(), info.Holder(), "{{attribute.name}}", wrapper);
79         {{attribute.v8_set_return_value}};
80     }
81     {% else %}
82     {{attribute.v8_set_return_value}};
83     {% endif %}
84 }
85 {% endfilter %}
86 {% endmacro %}
87
88
89 {##############################################################################}
90 {% macro attribute_getter_callback(attribute, world_suffix) %}
91 {% filter conditional(attribute.conditional_string) %}
92 static void {{attribute.name}}AttributeGetterCallback{{world_suffix}}(
93 {%- if attribute.is_expose_js_accessors %}
94 const v8::FunctionCallbackInfo<v8::Value>& info
95 {%- else %}
96 v8::Local<v8::String>, const v8::PropertyCallbackInfo<v8::Value>& info
97 {%- endif %})
98 {
99     TRACE_EVENT_SET_SAMPLING_STATE("Blink", "DOMGetter");
100     {% if attribute.deprecate_as %}
101     UseCounter::countDeprecation(activeExecutionContext(), UseCounter::{{attribute.deprecate_as}});
102     {% endif %}
103     {% if attribute.measure_as %}
104     UseCounter::count(activeExecutionContext(), UseCounter::{{attribute.measure_as}});
105     {% endif %}
106     {% if world_suffix in attribute.activity_logging_world_list_for_getter %}
107     V8PerContextData* contextData = V8PerContextData::from(info.GetIsolate()->GetCurrentContext());
108     if (contextData && contextData->activityLogger())
109         contextData->activityLogger()->log("{{interface_name}}.{{attribute.name}}", 0, 0, "Getter");
110     {% endif %}
111     {% if attribute.has_custom_getter %}
112     {{v8_class}}::{{attribute.name}}AttributeGetterCustom(info);
113     {% else %}
114     {{cpp_class}}V8Internal::{{attribute.name}}AttributeGetter{{world_suffix}}(info);
115     {% endif %}
116     TRACE_EVENT_SET_SAMPLING_STATE("V8", "V8Execution");
117 }
118 {% endfilter %}
119 {% endmacro %}
120
121
122 {##############################################################################}
123 {% macro attribute_setter(attribute, world_suffix) %}
124 {% filter conditional(attribute.conditional_string) %}
125 static void {{attribute.name}}AttributeSetter{{world_suffix}}(
126 {%- if attribute.is_expose_js_accessors %}
127 v8::Local<v8::Value> jsValue, const v8::FunctionCallbackInfo<v8::Value>& info
128 {%- else %}
129 v8::Local<v8::Value> jsValue, const v8::PropertyCallbackInfo<void>& info
130 {%- endif %})
131 {
132     {% if attribute.is_reflect and attribute.idl_type == 'DOMString' and
133           is_node %}
134     {% set cpp_class, v8_class = 'Element', 'V8Element' %}
135     {# FIXME: Perl skips most of function, but this seems unnecessary #}
136     {% endif %}
137     {% if attribute.has_setter_exception_state %}
138     ExceptionState exceptionState(ExceptionState::SetterContext, "{{attribute.name}}", "{{interface_name}}", info.Holder(), info.GetIsolate());
139     {% endif %}
140     {% if attribute.has_strict_type_checking %}
141     {# Type checking for interface types (if interface not implemented, throw
142        TypeError), per http://www.w3.org/TR/WebIDL/#es-interface #}
143     if (!isUndefinedOrNull(jsValue) && !V8{{attribute.idl_type}}::hasInstance(jsValue, info.GetIsolate())) {
144         exceptionState.throwTypeError("The provided value is not of type '{{attribute.idl_type}}'.");
145         exceptionState.throwIfNeeded();
146         return;
147     }
148     {% endif %}
149     {% if attribute.put_forwards %}
150     {{cpp_class}}* proxyImp = {{v8_class}}::toNative(info.Holder());
151     {{attribute.idl_type}}* imp = proxyImp->{{attribute.name}}();
152     if (!imp)
153         return;
154     {% elif not attribute.is_static %}
155     {{cpp_class}}* imp = {{v8_class}}::toNative(info.Holder());
156     {% endif %}
157     {% if attribute.idl_type == 'EventHandler' and interface_name == 'Window' %}
158     if (!imp->document())
159         return;
160     {% endif %}
161     {% if attribute.idl_type != 'EventHandler' %}
162     {{attribute.v8_value_to_local_cpp_value}};
163     {% elif not is_node %}{# EventHandler hack #}
164     transferHiddenDependency(info.Holder(), {{attribute.event_handler_getter_expression}}, jsValue, {{v8_class}}::eventListenerCacheIndex, info.GetIsolate());
165     {% endif %}
166     {% if attribute.enum_validation_expression %}
167     {# Setter ignores invalid enum values: http://www.w3.org/TR/WebIDL/#idl-enums #}
168     String string = cppValue;
169     if (!({{attribute.enum_validation_expression}}))
170         return;
171     {% endif %}
172     {% if attribute.is_reflect and
173           not(attribute.idl_type == 'DOMString' and is_node) %}
174     CustomElementCallbackDispatcher::CallbackDeliveryScope deliveryScope;
175     {% endif %}
176     {% if attribute.is_call_with_execution_context %}
177     ExecutionContext* scriptContext = getExecutionContext();
178     {% endif %}
179     {{attribute.cpp_setter}};
180     {% if attribute.is_setter_raises_exception %}
181     exceptionState.throwIfNeeded();
182     {% endif %}
183     {% if attribute.cached_attribute_validation_method %}
184     deleteHiddenValue(info.GetIsolate(), info.Holder(), "{{attribute.name}}"); // Invalidate the cached value.
185     {% endif %}
186 }
187 {% endfilter %}
188 {% endmacro %}
189
190
191 {##############################################################################}
192 {% macro attribute_setter_callback(attribute, world_suffix) %}
193 {% filter conditional(attribute.conditional_string) %}
194 static void {{attribute.name}}AttributeSetterCallback{{world_suffix}}(
195 {%- if attribute.is_expose_js_accessors %}
196 const v8::FunctionCallbackInfo<v8::Value>& info
197 {%- else %}
198 v8::Local<v8::String>, v8::Local<v8::Value> jsValue, const v8::PropertyCallbackInfo<void>& info
199 {%- endif %})
200 {
201     {% if attribute.is_expose_js_accessors %}
202     v8::Local<v8::Value> jsValue = info[0];
203     {% endif %}
204     TRACE_EVENT_SET_SAMPLING_STATE("Blink", "DOMSetter");
205     {% if attribute.deprecate_as %}
206     UseCounter::countDeprecation(activeExecutionContext(), UseCounter::{{attribute.deprecate_as}});
207     {% endif %}
208     {% if attribute.measure_as %}
209     UseCounter::count(activeExecutionContext(), UseCounter::{{attribute.measure_as}});
210     {% endif %}
211     {% if world_suffix in attribute.activity_logging_world_list_for_setter %}
212     V8PerContextData* contextData = V8PerContextData::from(info.GetIsolate()->GetCurrentContext());
213     if (contextData && contextData->activityLogger()) {
214         v8::Handle<v8::Value> loggerArg[] = { jsValue };
215         contextData->activityLogger()->log("{{interface_name}}.{{attribute.name}}", 1, &loggerArg[0], "Setter");
216     }
217     {% endif %}
218     {% if attribute.is_reflect %}
219     CustomElementCallbackDispatcher::CallbackDeliveryScope deliveryScope;
220     {% endif %}
221     {% if attribute.has_custom_setter %}
222     {{v8_class}}::{{attribute.name}}AttributeSetterCustom(jsValue, info);
223     {% else %}
224     {{cpp_class}}V8Internal::{{attribute.name}}AttributeSetter{{world_suffix}}(jsValue, info);
225     {% endif %}
226     TRACE_EVENT_SET_SAMPLING_STATE("V8", "V8Execution");
227 }
228 {% endfilter %}
229 {% endmacro %}