Unreviewed, rolling out r135973.
[WebKit-https.git] / Source / WebKit2 / UIProcess / API / efl / ewk_view.cpp
1 /*
2    Copyright (C) 2011 Samsung Electronics
3    Copyright (C) 2012 Intel Corporation. All rights reserved.
4
5     This library is free software; you can redistribute it and/or
6     modify it under the terms of the GNU Library General Public
7     License as published by the Free Software Foundation; either
8     version 2 of the License, or (at your option) any later version.
9
10     This library is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13     Library General Public License for more details.
14
15     You should have received a copy of the GNU Library General Public License
16     along with this library; see the file COPYING.LIB.  If not, write to
17     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18     Boston, MA 02110-1301, USA.
19 */
20
21 #include "config.h"
22 #include "ewk_view.h"
23
24 #include "EwkViewImpl.h"
25 #include "FindClientEfl.h"
26 #include "FormClientEfl.h"
27 #include "InputMethodContextEfl.h"
28 #include "NativeWebKeyboardEvent.h"
29 #include "NativeWebMouseEvent.h"
30 #include "NativeWebWheelEvent.h"
31 #include "PageClientBase.h"
32 #include "PageLoadClientEfl.h"
33 #include "PagePolicyClientEfl.h"
34 #include "PageUIClientEfl.h"
35 #include "ResourceLoadClientEfl.h"
36 #include "WKAPICast.h"
37 #include "WKEinaSharedString.h"
38 #include "WKFindOptions.h"
39 #include "WKRetainPtr.h"
40 #include "WKString.h"
41 #include "WebContext.h"
42 #include "WebFullScreenManagerProxy.h"
43 #include "WebPageGroup.h"
44 #include "WebPreferences.h"
45 #include "ewk_back_forward_list_private.h"
46 #include "ewk_context.h"
47 #include "ewk_context_private.h"
48 #include "ewk_favicon_database_private.h"
49 #include "ewk_intent_private.h"
50 #include "ewk_private.h"
51 #include "ewk_settings_private.h"
52 #include "ewk_view_private.h"
53 #include <Ecore_Evas.h>
54 #include <WebKit2/WKPageGroup.h>
55 #include <wtf/text/CString.h>
56
57 #if ENABLE(INSPECTOR)
58 #include "WebInspectorProxy.h"
59 #endif
60
61 #if USE(TILED_BACKING_STORE)
62 #include "PageViewportController.h"
63 #include "PageViewportControllerClientEfl.h"
64 #endif
65
66 using namespace WebKit;
67 using namespace WebCore;
68
69 static const char EWK_VIEW_TYPE_STR[] = "EWK2_View";
70
71 #define EWK_VIEW_TYPE_CHECK(ewkView, result)                                   \
72     bool result = true;                                                        \
73     do {                                                                       \
74         if (!ewkView) {                                                        \
75             EINA_LOG_CRIT("null is not a ewk_view");                           \
76             result = false;                                                    \
77             break;                                                             \
78         }                                                                      \
79         const char* _tmp_otype = evas_object_type_get(ewkView);                \
80         const Evas_Smart* _tmp_s = evas_object_smart_smart_get(ewkView);       \
81         if (EINA_UNLIKELY(!_tmp_s)) {                                          \
82             EINA_LOG_CRIT                                                      \
83                 ("%p (%s) is not a smart object!",                             \
84                  ewkView, _tmp_otype ? _tmp_otype : "(null)");                 \
85             result = false;                                                    \
86             break;                                                             \
87         }                                                                      \
88         const Evas_Smart_Class* _tmp_sc = evas_smart_class_get(_tmp_s);        \
89         if (EINA_UNLIKELY(!_tmp_sc)) {                                         \
90             EINA_LOG_CRIT                                                      \
91                 ("%p (%s) is not a smart object!",                             \
92                  ewkView, _tmp_otype ? _tmp_otype : "(null)");                 \
93             result = false;                                                    \
94             break;                                                             \
95         }                                                                      \
96         if (EINA_UNLIKELY(_tmp_sc->data != EWK_VIEW_TYPE_STR)) {               \
97             EINA_LOG_CRIT                                                      \
98                 ("%p (%s) is not of an ewk_view (need %p, got %p)!",           \
99                  ewkView, _tmp_otype ? _tmp_otype : "(null)",                  \
100                  EWK_VIEW_TYPE_STR, _tmp_sc->data);                            \
101             result = false;                                                    \
102         }                                                                      \
103     } while (0)
104
105 #define EWK_VIEW_SD_GET(ewkView, smartData)                                    \
106     EWK_VIEW_TYPE_CHECK(ewkView, _tmp_result);                                 \
107     Ewk_View_Smart_Data* smartData = 0;                                        \
108     if (_tmp_result)                                                           \
109         smartData = (Ewk_View_Smart_Data*)evas_object_smart_data_get(ewkView)
110
111 #define EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, ...)                     \
112     EWK_VIEW_SD_GET(ewkView, smartData);                                       \
113     do {                                                                       \
114         if (!smartData) {                                                      \
115             EINA_LOG_CRIT("no smart data for object %p (%s)",                  \
116                      ewkView, evas_object_type_get(ewkView));                  \
117             return __VA_ARGS__;                                                \
118         }                                                                      \
119     } while (0)
120
121 #define EWK_VIEW_IMPL_GET_BY_SD_OR_RETURN(smartData, impl, ...)                \
122     if (!smartData) {                                                          \
123         EINA_LOG_CRIT("smart data is null");                                   \
124         return __VA_ARGS__;                                                    \
125     }                                                                          \
126     EwkViewImpl* impl = smartData->priv;                                       \
127     do {                                                                       \
128         if (!impl) {                                                           \
129             EINA_LOG_CRIT("no private data for object %p (%s)",                \
130                 smartData->self, evas_object_type_get(smartData->self));       \
131             return __VA_ARGS__;                                                \
132         }                                                                      \
133     } while (0)
134
135 #define EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, ...)                        \
136     EwkViewImpl* impl = 0;                                                     \
137     do {                                                                       \
138         EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, __VA_ARGS__);            \
139         impl = smartData->priv;                                                \
140         if (!impl) {                                                           \
141             EINA_LOG_CRIT("no private data for object %p (%s)",                \
142                 smartData->self, evas_object_type_get(smartData->self));       \
143             return __VA_ARGS__;                                                \
144         }                                                                      \
145     } while (0)
146
147 static void _ewk_view_smart_changed(Ewk_View_Smart_Data* smartData)
148 {
149     if (smartData->changed.any)
150         return;
151     smartData->changed.any = true;
152     evas_object_smart_changed(smartData->self);
153 }
154
155 // Default Event Handling.
156 static Eina_Bool _ewk_view_smart_focus_in(Ewk_View_Smart_Data* smartData)
157 {
158     EWK_VIEW_IMPL_GET_BY_SD_OR_RETURN(smartData, impl, false);
159
160     impl->page()->viewStateDidChange(WebPageProxy::ViewIsFocused | WebPageProxy::ViewWindowIsActive);
161     return true;
162 }
163
164 static Eina_Bool _ewk_view_smart_focus_out(Ewk_View_Smart_Data* smartData)
165 {
166     EWK_VIEW_IMPL_GET_BY_SD_OR_RETURN(smartData, impl, false);
167
168     impl->page()->viewStateDidChange(WebPageProxy::ViewIsFocused | WebPageProxy::ViewWindowIsActive);
169     return true;
170 }
171
172 static Eina_Bool _ewk_view_smart_mouse_wheel(Ewk_View_Smart_Data* smartData, const Evas_Event_Mouse_Wheel* wheelEvent)
173 {
174     EWK_VIEW_IMPL_GET_BY_SD_OR_RETURN(smartData, impl, false);
175
176     impl->page()->handleWheelEvent(NativeWebWheelEvent(wheelEvent, impl->transformFromScene(), impl->transformToScreen()));
177     return true;
178 }
179
180 static Eina_Bool _ewk_view_smart_mouse_down(Ewk_View_Smart_Data* smartData, const Evas_Event_Mouse_Down* downEvent)
181 {
182     EWK_VIEW_IMPL_GET_BY_SD_OR_RETURN(smartData, impl, false);
183
184     impl->page()->handleMouseEvent(NativeWebMouseEvent(downEvent, impl->transformFromScene(), impl->transformToScreen()));
185     return true;
186 }
187
188 static Eina_Bool _ewk_view_smart_mouse_up(Ewk_View_Smart_Data* smartData, const Evas_Event_Mouse_Up* upEvent)
189 {
190     EWK_VIEW_IMPL_GET_BY_SD_OR_RETURN(smartData, impl, false);
191
192     impl->page()->handleMouseEvent(NativeWebMouseEvent(upEvent, impl->transformFromScene(), impl->transformToScreen()));
193
194     InputMethodContextEfl* inputMethodContext = impl->inputMethodContext();
195     if (inputMethodContext)
196         inputMethodContext->handleMouseUpEvent(upEvent);
197
198     return true;
199 }
200
201 static Eina_Bool _ewk_view_smart_mouse_move(Ewk_View_Smart_Data* smartData, const Evas_Event_Mouse_Move* moveEvent)
202 {
203     EWK_VIEW_IMPL_GET_BY_SD_OR_RETURN(smartData, impl, false);
204
205     impl->page()->handleMouseEvent(NativeWebMouseEvent(moveEvent, impl->transformFromScene(), impl->transformToScreen()));
206     return true;
207 }
208
209 static Eina_Bool _ewk_view_smart_key_down(Ewk_View_Smart_Data* smartData, const Evas_Event_Key_Down* downEvent)
210 {
211     EWK_VIEW_IMPL_GET_BY_SD_OR_RETURN(smartData, impl, false);
212
213     bool isFiltered = false;
214     InputMethodContextEfl* inputMethodContext = impl->inputMethodContext();
215     if (inputMethodContext)
216         inputMethodContext->handleKeyDownEvent(downEvent, &isFiltered);
217
218     impl->page()->handleKeyboardEvent(NativeWebKeyboardEvent(downEvent, isFiltered));
219     return true;
220 }
221
222 static Eina_Bool _ewk_view_smart_key_up(Ewk_View_Smart_Data* smartData, const Evas_Event_Key_Up* upEvent)
223 {
224     EWK_VIEW_IMPL_GET_BY_SD_OR_RETURN(smartData, impl, false);
225
226     impl->page()->handleKeyboardEvent(NativeWebKeyboardEvent(upEvent));
227     return true;
228 }
229
230 // Event Handling.
231 static void _ewk_view_on_focus_in(void* data, Evas*, Evas_Object*, void* /*eventInfo*/)
232 {
233     Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
234     EINA_SAFETY_ON_NULL_RETURN(smartData->api);
235     EINA_SAFETY_ON_NULL_RETURN(smartData->api->focus_in);
236     smartData->api->focus_in(smartData);
237 }
238
239 static void _ewk_view_on_focus_out(void* data, Evas*, Evas_Object*, void* /*eventInfo*/)
240 {
241     Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
242     EINA_SAFETY_ON_NULL_RETURN(smartData->api);
243     EINA_SAFETY_ON_NULL_RETURN(smartData->api->focus_out);
244     smartData->api->focus_out(smartData);
245 }
246
247 static void _ewk_view_on_mouse_wheel(void* data, Evas*, Evas_Object*, void* eventInfo)
248 {
249     Evas_Event_Mouse_Wheel* wheelEvent = static_cast<Evas_Event_Mouse_Wheel*>(eventInfo);
250     Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
251     EINA_SAFETY_ON_NULL_RETURN(smartData->api);
252     EINA_SAFETY_ON_NULL_RETURN(smartData->api->mouse_wheel);
253     smartData->api->mouse_wheel(smartData, wheelEvent);
254 }
255
256 static void _ewk_view_on_key_down(void* data, Evas*, Evas_Object*, void* eventInfo)
257 {
258     Evas_Event_Key_Down* downEvent = static_cast<Evas_Event_Key_Down*>(eventInfo);
259     Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
260     EINA_SAFETY_ON_NULL_RETURN(smartData->api);
261     EINA_SAFETY_ON_NULL_RETURN(smartData->api->key_down);
262     smartData->api->key_down(smartData, downEvent);
263 }
264
265 static void _ewk_view_on_key_up(void* data, Evas*, Evas_Object*, void* eventInfo)
266 {
267     Evas_Event_Key_Up* upEvent = static_cast<Evas_Event_Key_Up*>(eventInfo);
268     Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
269     EINA_SAFETY_ON_NULL_RETURN(smartData->api);
270     EINA_SAFETY_ON_NULL_RETURN(smartData->api->key_up);
271     smartData->api->key_up(smartData, upEvent);
272 }
273
274 static void _ewk_view_on_show(void* data, Evas*, Evas_Object*, void* /*eventInfo*/)
275 {
276     Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
277     EWK_VIEW_IMPL_GET_BY_SD_OR_RETURN(smartData, impl);
278     impl->page()->viewStateDidChange(WebPageProxy::ViewIsVisible);
279 }
280
281 static void _ewk_view_on_hide(void* data, Evas*, Evas_Object*, void* /*eventInfo*/)
282 {
283     Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
284     EWK_VIEW_IMPL_GET_BY_SD_OR_RETURN(smartData, impl);
285
286     // This call may look wrong, but we really need to pass ViewIsVisible here.
287     // viewStateDidChange() itself is responsible for actually setting the visibility to Visible or Hidden
288     // depending on what WebPageProxy::isViewVisible() returns, this simply triggers the process.
289     impl->page()->viewStateDidChange(WebPageProxy::ViewIsVisible);
290 }
291
292 static Evas_Smart_Class g_parentSmartClass = EVAS_SMART_CLASS_INIT_NULL;
293
294 static void _ewk_view_smart_add(Evas_Object* ewkView)
295 {
296     const Evas_Smart* smart = evas_object_smart_smart_get(ewkView);
297     const Evas_Smart_Class* smartClass = evas_smart_class_get(smart);
298     const Ewk_View_Smart_Class* api = reinterpret_cast<const Ewk_View_Smart_Class*>(smartClass);
299     EWK_VIEW_SD_GET(ewkView, smartData);
300
301     if (!smartData) {
302         smartData = static_cast<Ewk_View_Smart_Data*>(calloc(1, sizeof(Ewk_View_Smart_Data)));
303         if (!smartData) {
304             EINA_LOG_CRIT("could not allocate Ewk_View_Smart_Data");
305             return;
306         }
307         evas_object_smart_data_set(ewkView, smartData);
308     }
309
310     smartData->self = ewkView;
311     smartData->api = api;
312
313     g_parentSmartClass.add(ewkView);
314
315     smartData->priv = 0;
316
317     // Create evas_object_image to draw web contents.
318     smartData->image = evas_object_image_add(smartData->base.evas);
319     evas_object_image_alpha_set(smartData->image, false);
320     evas_object_image_filled_set(smartData->image, true);
321     evas_object_smart_member_add(smartData->image, ewkView);
322     evas_object_show(smartData->image);
323
324 #define CONNECT(s, c) evas_object_event_callback_add(ewkView, s, c, smartData)
325     CONNECT(EVAS_CALLBACK_FOCUS_IN, _ewk_view_on_focus_in);
326     CONNECT(EVAS_CALLBACK_FOCUS_OUT, _ewk_view_on_focus_out);
327     CONNECT(EVAS_CALLBACK_MOUSE_WHEEL, _ewk_view_on_mouse_wheel);
328     CONNECT(EVAS_CALLBACK_KEY_DOWN, _ewk_view_on_key_down);
329     CONNECT(EVAS_CALLBACK_KEY_UP, _ewk_view_on_key_up);
330     CONNECT(EVAS_CALLBACK_SHOW, _ewk_view_on_show);
331     CONNECT(EVAS_CALLBACK_HIDE, _ewk_view_on_hide);
332 #undef CONNECT
333 }
334
335 static void _ewk_view_smart_del(Evas_Object* ewkView)
336 {
337     EWK_VIEW_SD_GET(ewkView, smartData);
338     if (smartData)
339         delete smartData->priv;
340
341     g_parentSmartClass.del(ewkView);
342 }
343
344 static void _ewk_view_smart_resize(Evas_Object* ewkView, Evas_Coord width, Evas_Coord height)
345 {
346     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
347
348     evas_object_resize(smartData->image, width, height);
349     evas_object_image_size_set(smartData->image, width, height);
350     evas_object_image_fill_set(smartData->image, 0, 0, width, height);
351
352     smartData->changed.size = true;
353     _ewk_view_smart_changed(smartData);
354 }
355
356 static void _ewk_view_smart_move(Evas_Object* ewkView, Evas_Coord /*x*/, Evas_Coord /*y*/)
357 {
358     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
359
360     smartData->changed.position = true;
361     _ewk_view_smart_changed(smartData);
362 }
363
364 static void _ewk_view_smart_calculate(Evas_Object* ewkView)
365 {
366     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
367     EWK_VIEW_IMPL_GET_BY_SD_OR_RETURN(smartData, impl);
368
369     smartData->changed.any = false;
370
371     Evas_Coord x, y, width, height;
372     evas_object_geometry_get(ewkView, &x, &y, &width, &height);
373
374     if (smartData->changed.position) {
375         smartData->changed.position = false;
376         smartData->view.x = x;
377         smartData->view.y = y;
378         evas_object_move(smartData->image, x, y);
379     }
380
381     if (smartData->changed.size) {
382         smartData->changed.size = false;
383         smartData->view.w = width;
384         smartData->view.h = height;
385
386         if (impl->page()->drawingArea())
387             impl->page()->drawingArea()->setSize(IntSize(width, height), IntSize());
388
389 #if USE(ACCELERATED_COMPOSITING)
390         if (width && height)
391             impl->createGLSurface(IntSize(width, height));
392 #endif
393 #if USE(TILED_BACKING_STORE)
394         impl->pageClient()->updateViewportSize(IntSize(width, height));
395 #endif
396     }
397 }
398
399 static void _ewk_view_smart_show(Evas_Object* ewkView)
400 {
401     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
402
403     if (evas_object_clipees_get(smartData->base.clipper))
404         evas_object_show(smartData->base.clipper);
405     evas_object_show(smartData->image);
406 }
407
408 static void _ewk_view_smart_hide(Evas_Object* ewkView)
409 {
410     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
411
412     evas_object_hide(smartData->base.clipper);
413     evas_object_hide(smartData->image);
414 }
415
416 static void _ewk_view_smart_color_set(Evas_Object* ewkView, int red, int green, int blue, int alpha)
417 {
418     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
419     EWK_VIEW_IMPL_GET_BY_SD_OR_RETURN(smartData, impl);
420
421     if (alpha < 0)
422         alpha = 0;
423     else if (alpha > 255)
424         alpha = 255;
425
426 #define CHECK_COLOR(color, alpha) \
427     if (color < 0)                \
428         color = 0;                \
429     else if (color > alpha)       \
430         color = alpha;
431     CHECK_COLOR(red, alpha);
432     CHECK_COLOR(green, alpha);
433     CHECK_COLOR(blue, alpha);
434 #undef CHECK_COLOR
435
436     evas_object_image_alpha_set(smartData->image, alpha < 255);
437     impl->page()->setDrawsBackground(red || green || blue);
438     impl->page()->setDrawsTransparentBackground(alpha < 255);
439
440     g_parentSmartClass.color_set(ewkView, red, green, blue, alpha);
441 }
442
443 Eina_Bool ewk_view_smart_class_set(Ewk_View_Smart_Class* api)
444 {
445     EINA_SAFETY_ON_NULL_RETURN_VAL(api, false);
446
447     if (api->version != EWK_VIEW_SMART_CLASS_VERSION) {
448         EINA_LOG_CRIT("Ewk_View_Smart_Class %p is version %lu while %lu was expected.",
449              api, api->version, EWK_VIEW_SMART_CLASS_VERSION);
450         return false;
451     }
452
453     if (EINA_UNLIKELY(!g_parentSmartClass.add))
454         evas_object_smart_clipped_smart_set(&g_parentSmartClass);
455
456     evas_object_smart_clipped_smart_set(&api->sc);
457
458     // Set Evas_Smart_Class functions.
459     api->sc.add = _ewk_view_smart_add;
460     api->sc.del = _ewk_view_smart_del;
461     api->sc.move = _ewk_view_smart_move;
462     api->sc.resize = _ewk_view_smart_resize;
463     api->sc.show = _ewk_view_smart_show;
464     api->sc.hide = _ewk_view_smart_hide;
465     api->sc.color_set = _ewk_view_smart_color_set;
466     api->sc.calculate = _ewk_view_smart_calculate;
467     api->sc.data = EWK_VIEW_TYPE_STR; // It is used by type checking.
468
469     // Set Ewk_View_Smart_Class functions.
470     api->focus_in = _ewk_view_smart_focus_in;
471     api->focus_out = _ewk_view_smart_focus_out;
472     api->mouse_wheel = _ewk_view_smart_mouse_wheel;
473     api->mouse_down = _ewk_view_smart_mouse_down;
474     api->mouse_up = _ewk_view_smart_mouse_up;
475     api->mouse_move = _ewk_view_smart_mouse_move;
476     api->key_down = _ewk_view_smart_key_down;
477     api->key_up = _ewk_view_smart_key_up;
478
479     return true;
480 }
481
482 static inline Evas_Smart* createEwkViewSmartClass(void)
483 {
484     static Ewk_View_Smart_Class api = EWK_VIEW_SMART_CLASS_INIT_NAME_VERSION("Ewk_View");
485     static Evas_Smart* smart = 0;
486
487     if (EINA_UNLIKELY(!smart)) {
488         ewk_view_smart_class_set(&api);
489         smart = evas_smart_class_new(&api.sc);
490     }
491
492     return smart;
493 }
494
495 static inline Evas_Object* createEwkView(Evas* canvas, Evas_Smart* smart, PassRefPtr<EwkContext> context, WKPageGroupRef pageGroupRef = 0, EwkViewImpl::ViewBehavior behavior = EwkViewImpl::DefaultBehavior)
496 {
497     EINA_SAFETY_ON_NULL_RETURN_VAL(canvas, 0);
498     EINA_SAFETY_ON_NULL_RETURN_VAL(smart, 0);
499     EINA_SAFETY_ON_NULL_RETURN_VAL(context, 0);
500
501     Evas_Object* ewkView = evas_object_smart_add(canvas, smart);
502     EINA_SAFETY_ON_NULL_RETURN_VAL(ewkView, 0);
503
504     EWK_VIEW_SD_GET(ewkView, smartData);
505     if (!smartData) {
506         evas_object_del(ewkView);
507         return 0;
508     }
509
510     ASSERT(!smartData->priv);
511     RefPtr<WebPageGroup> pageGroup = pageGroupRef ? toImpl(pageGroupRef) : WebPageGroup::create();
512     smartData->priv = new EwkViewImpl(ewkView, context, pageGroup, behavior);
513     return ewkView;
514 }
515
516 /**
517  * @internal
518  * Constructs a ewk_view Evas_Object with WKType parameters.
519  */
520 Evas_Object* ewk_view_base_add(Evas* canvas, WKContextRef contextRef, WKPageGroupRef pageGroupRef, EwkViewImpl::ViewBehavior behavior)
521 {
522     return createEwkView(canvas, createEwkViewSmartClass(), EwkContext::create(toImpl(contextRef)), pageGroupRef, behavior);
523 }
524
525 Evas_Object* ewk_view_smart_add(Evas* canvas, Evas_Smart* smart, Ewk_Context* context)
526 {
527     return createEwkView(canvas, smart, ewk_object_cast<EwkContext*>(context));
528 }
529
530 Evas_Object* ewk_view_add_with_context(Evas* canvas, Ewk_Context* context)
531 {
532     return ewk_view_smart_add(canvas, createEwkViewSmartClass(), ewk_object_cast<EwkContext*>(context));
533 }
534
535 Evas_Object* ewk_view_add(Evas* canvas)
536 {
537     return ewk_view_add_with_context(canvas, ewk_context_default_get());
538 }
539
540 Ewk_Context* ewk_view_context_get(const Evas_Object* ewkView)
541 {
542     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, 0);
543
544     return impl->ewkContext();
545 }
546
547 Eina_Bool ewk_view_url_set(Evas_Object* ewkView, const char* url)
548 {
549     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
550     EINA_SAFETY_ON_NULL_RETURN_VAL(url, false);
551
552     impl->page()->loadURL(url);
553     impl->informURLChange();
554
555     return true;
556 }
557
558 const char* ewk_view_url_get(const Evas_Object* ewkView)
559 {
560     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, 0);
561
562     return impl->url();
563 }
564
565 const char *ewk_view_icon_url_get(const Evas_Object *ewkView)
566 {
567     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, 0);
568
569     return impl->faviconURL();
570 }
571
572 Eina_Bool ewk_view_reload(Evas_Object* ewkView)
573 {
574     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
575
576     impl->page()->reload(/*reloadFromOrigin*/ false);
577     impl->informURLChange();
578
579     return true;
580 }
581
582 Eina_Bool ewk_view_reload_bypass_cache(Evas_Object* ewkView)
583 {
584     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
585
586     impl->page()->reload(/*reloadFromOrigin*/ true);
587     impl->informURLChange();
588
589     return true;
590 }
591
592 Eina_Bool ewk_view_stop(Evas_Object* ewkView)
593 {
594     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
595
596     impl->page()->stopLoading();
597
598     return true;
599 }
600
601 Ewk_Settings* ewk_view_settings_get(const Evas_Object* ewkView)
602 {
603     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, 0);
604
605     return impl->settings();
606 }
607
608 const char* ewk_view_title_get(const Evas_Object* ewkView)
609 {
610     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, 0);
611
612     return impl->title();
613 }
614
615 double ewk_view_load_progress_get(const Evas_Object* ewkView)
616 {
617     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, -1.0);
618
619     return impl->page()->estimatedProgress();
620 }
621
622 Eina_Bool ewk_view_scale_set(Evas_Object* ewkView, double scaleFactor, int x, int y)
623 {
624     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
625
626     impl->page()->scalePage(scaleFactor, IntPoint(x, y));
627     return true;
628 }
629
630 double ewk_view_scale_get(const Evas_Object* ewkView)
631 {
632     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, -1);
633
634     return impl->page()->pageScaleFactor();
635 }
636
637 Eina_Bool ewk_view_device_pixel_ratio_set(Evas_Object* ewkView, float ratio)
638 {
639     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
640
641     impl->page()->setCustomDeviceScaleFactor(ratio);
642
643     return true;
644 }
645
646 float ewk_view_device_pixel_ratio_get(const Evas_Object* ewkView)
647 {
648     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, -1.0);
649
650     return impl->page()->deviceScaleFactor();
651 }
652
653 void ewk_view_theme_set(Evas_Object* ewkView, const char* path)
654 {
655     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl);
656
657     impl->setThemePath(path);
658 }
659
660 const char* ewk_view_theme_get(const Evas_Object* ewkView)
661 {
662     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, 0);
663
664     return impl->themePath();
665 }
666
667 Eina_Bool ewk_view_back(Evas_Object* ewkView)
668 {
669     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
670
671     WebPageProxy* page = impl->page();
672     if (page->canGoBack()) {
673         page->goBack();
674         return true;
675     }
676
677     return false;
678 }
679
680 Eina_Bool ewk_view_forward(Evas_Object* ewkView)
681 {
682     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
683
684     WebPageProxy* page = impl->page();
685     if (page->canGoForward()) {
686         page->goForward();
687         return true;
688     }
689
690     return false;
691 }
692
693 Eina_Bool ewk_view_intent_deliver(Evas_Object* ewkView, Ewk_Intent* intent)
694 {
695 #if ENABLE(WEB_INTENTS)
696     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
697     EwkIntent* intentImpl = ewk_object_cast<EwkIntent*>(intent);
698     EINA_SAFETY_ON_NULL_RETURN_VAL(intentImpl, false);
699
700     WebPageProxy* page = impl->page();
701     page->deliverIntentToFrame(page->mainFrame(), intentImpl->webIntentData());
702
703     return true;
704 #else
705     return false;
706 #endif
707 }
708
709 Eina_Bool ewk_view_back_possible(Evas_Object* ewkView)
710 {
711     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
712
713     return impl->page()->canGoBack();
714 }
715
716 Eina_Bool ewk_view_forward_possible(Evas_Object* ewkView)
717 {
718     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
719
720     return impl->page()->canGoForward();
721 }
722
723 Ewk_Back_Forward_List* ewk_view_back_forward_list_get(const Evas_Object* ewkView)
724 {
725     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, 0);
726
727     return impl->backForwardList();
728 }
729
730 Eina_Bool ewk_view_html_string_load(Evas_Object* ewkView, const char* html, const char* baseUrl, const char* unreachableUrl)
731 {
732     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
733     EINA_SAFETY_ON_NULL_RETURN_VAL(html, false);
734
735     if (unreachableUrl && *unreachableUrl)
736         impl->page()->loadAlternateHTMLString(String::fromUTF8(html), baseUrl ? String::fromUTF8(baseUrl) : "", String::fromUTF8(unreachableUrl));
737     else
738         impl->page()->loadHTMLString(String::fromUTF8(html), baseUrl ? String::fromUTF8(baseUrl) : "");
739
740     impl->informURLChange();
741
742     return true;
743 }
744
745 const char* ewk_view_custom_encoding_get(const Evas_Object* ewkView)
746 {
747     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, 0);
748
749     return impl->customTextEncodingName();
750 }
751
752 Eina_Bool ewk_view_custom_encoding_set(Evas_Object* ewkView, const char* encoding)
753 {
754     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
755
756     impl->setCustomTextEncodingName(encoding ? encoding : String());
757
758     return true;
759 }
760
761 // EwkFindOptions should be matched up orders with WkFindOptions.
762 COMPILE_ASSERT_MATCHING_ENUM(EWK_FIND_OPTIONS_CASE_INSENSITIVE, kWKFindOptionsCaseInsensitive);
763 COMPILE_ASSERT_MATCHING_ENUM(EWK_FIND_OPTIONS_AT_WORD_STARTS, kWKFindOptionsAtWordStarts);
764 COMPILE_ASSERT_MATCHING_ENUM(EWK_FIND_OPTIONS_TREAT_MEDIAL_CAPITAL_AS_WORD_START, kWKFindOptionsTreatMedialCapitalAsWordStart);
765 COMPILE_ASSERT_MATCHING_ENUM(EWK_FIND_OPTIONS_BACKWARDS, kWKFindOptionsBackwards);
766 COMPILE_ASSERT_MATCHING_ENUM(EWK_FIND_OPTIONS_WRAP_AROUND, kWKFindOptionsWrapAround);
767 COMPILE_ASSERT_MATCHING_ENUM(EWK_FIND_OPTIONS_SHOW_OVERLAY, kWKFindOptionsShowOverlay);
768 COMPILE_ASSERT_MATCHING_ENUM(EWK_FIND_OPTIONS_SHOW_FIND_INDICATOR, kWKFindOptionsShowFindIndicator);
769 COMPILE_ASSERT_MATCHING_ENUM(EWK_FIND_OPTIONS_SHOW_HIGHLIGHT, kWKFindOptionsShowHighlight);
770
771 Eina_Bool ewk_view_text_find(Evas_Object* ewkView, const char* text, Ewk_Find_Options options, unsigned maxMatchCount)
772 {
773     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
774     EINA_SAFETY_ON_NULL_RETURN_VAL(text, false);
775
776     impl->page()->findString(String::fromUTF8(text), static_cast<WebKit::FindOptions>(options), maxMatchCount);
777
778     return true;
779 }
780
781 Eina_Bool ewk_view_text_find_highlight_clear(Evas_Object* ewkView)
782 {
783     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
784
785     impl->page()->hideFindUI();
786
787     return true;
788 }
789
790 Eina_Bool ewk_view_text_matches_count(Evas_Object* ewkView, const char* text, Ewk_Find_Options options, unsigned maxMatchCount)
791 {
792     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
793     EINA_SAFETY_ON_NULL_RETURN_VAL(text, false);
794
795     impl->page()->countStringMatches(String::fromUTF8(text), static_cast<WebKit::FindOptions>(options), maxMatchCount);
796
797     return true;
798 }
799
800 Eina_Bool ewk_view_mouse_events_enabled_set(Evas_Object* ewkView, Eina_Bool enabled)
801 {
802     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
803
804     impl->setMouseEventsEnabled(!!enabled);
805
806     return true;
807 }
808
809 Eina_Bool ewk_view_mouse_events_enabled_get(const Evas_Object* ewkView)
810 {
811     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
812
813     return impl->mouseEventsEnabled();
814 }
815
816 Eina_Bool ewk_view_feed_touch_event(Evas_Object* ewkView, Ewk_Touch_Event_Type type, const Eina_List* points, const Evas_Modifier* modifiers)
817 {
818 #if ENABLE(TOUCH_EVENTS)
819     EINA_SAFETY_ON_NULL_RETURN_VAL(points, false);
820     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
821     EWK_VIEW_IMPL_GET_BY_SD_OR_RETURN(smartData, impl, false);
822
823     impl->page()->handleTouchEvent(NativeWebTouchEvent(type, points, modifiers, impl->transformFromScene(), impl->transformToScreen(), ecore_time_get()));
824
825     return true;
826 #else
827     return false;
828 #endif
829 }
830
831 Eina_Bool ewk_view_touch_events_enabled_set(Evas_Object* ewkView, Eina_Bool enabled)
832 {
833 #if ENABLE(TOUCH_EVENTS)
834     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
835
836     impl->setTouchEventsEnabled(!!enabled);
837
838     return true;
839 #else
840     return false;
841 #endif
842 }
843
844 Eina_Bool ewk_view_touch_events_enabled_get(const Evas_Object* ewkView)
845 {
846 #if ENABLE(TOUCH_EVENTS)
847     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
848
849     return impl->touchEventsEnabled();
850 #else
851     return false;
852 #endif
853 }
854
855 Eina_Bool ewk_view_inspector_show(Evas_Object* ewkView)
856 {
857 #if ENABLE(INSPECTOR)
858     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
859
860     WebInspectorProxy* inspector = impl->page()->inspector();
861     if (inspector)
862         inspector->show();
863
864     return true;
865 #else
866     return false;
867 #endif
868 }
869
870 Eina_Bool ewk_view_inspector_close(Evas_Object* ewkView)
871 {
872 #if ENABLE(INSPECTOR)
873     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
874
875     WebInspectorProxy* inspector = impl->page()->inspector();
876     if (inspector)
877         inspector->close();
878
879     return true;
880 #else
881     return false;
882 #endif
883 }
884
885 // Ewk_Pagination_Mode should be matched up orders with WebCore::Pagination::Mode.
886 COMPILE_ASSERT_MATCHING_ENUM(EWK_PAGINATION_MODE_UNPAGINATED, WebCore::Pagination::Unpaginated);
887 COMPILE_ASSERT_MATCHING_ENUM(EWK_PAGINATION_MODE_LEFT_TO_RIGHT, WebCore::Pagination::LeftToRightPaginated);
888 COMPILE_ASSERT_MATCHING_ENUM(EWK_PAGINATION_MODE_RIGHT_TO_LEFT, WebCore::Pagination::RightToLeftPaginated);
889 COMPILE_ASSERT_MATCHING_ENUM(EWK_PAGINATION_MODE_TOP_TO_BOTTOM, WebCore::Pagination::TopToBottomPaginated);
890 COMPILE_ASSERT_MATCHING_ENUM(EWK_PAGINATION_MODE_BOTTOM_TO_TOP, WebCore::Pagination::BottomToTopPaginated);
891
892 Eina_Bool ewk_view_pagination_mode_set(Evas_Object* ewkView, Ewk_Pagination_Mode mode)
893 {
894     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
895     
896     impl->page()->setPaginationMode(static_cast<WebCore::Pagination::Mode>(mode));
897
898     return true;
899 }
900
901 Ewk_Pagination_Mode ewk_view_pagination_mode_get(const Evas_Object* ewkView)
902 {
903     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, EWK_PAGINATION_MODE_INVALID);
904
905     return static_cast<Ewk_Pagination_Mode>(impl->page()->paginationMode());
906 }
907
908 Eina_Bool ewk_view_fullscreen_exit(Evas_Object* ewkView)
909 {
910 #if ENABLE(FULLSCREEN_API)
911     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
912
913     impl->page()->fullScreenManager()->requestExitFullScreen();
914
915     return true;
916 #else
917     return false;
918 #endif
919 }
920
921 void ewk_view_draws_page_background_set(Evas_Object *ewkView, Eina_Bool enabled)
922 {
923     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl);
924
925     impl->setDrawsBackground(enabled);
926 }