b819d5caf1dcd9b0b3cf911853eaef9ca17e126d
[WebKit-https.git] / Source / WebKit / efl / ewk / ewk_view.cpp
1 /*
2     Copyright (C) 2009-2010 ProFUSION embedded systems
3     Copyright (C) 2009-2011 Samsung Electronics
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 #define __STDC_FORMAT_MACROS
22 #include "config.h"
23 #include "ewk_view.h"
24
25 #include "BackForwardListImpl.h"
26 #include "Bridge.h"
27 #include "Chrome.h"
28 #include "ChromeClientEfl.h"
29 #include "ContextMenuController.h"
30 #include "DocumentLoader.h"
31 #include "DragClientEfl.h"
32 #include "EWebKit.h"
33 #include "EditorClientEfl.h"
34 #include "EventHandler.h"
35 #include "FocusController.h"
36 #include "FrameLoaderClientEfl.h"
37 #include "FrameView.h"
38 #include "GraphicsContext.h"
39 #include "HTMLElement.h"
40 #include "HTMLInputElement.h"
41 #include "HTMLNames.h"
42 #include "InspectorClientEfl.h"
43 #include "IntSize.h"
44 #include "JSDOMBinding.h"
45 #include "JSDOMWindow.h"
46 #include "JSLock.h"
47 #include "LayoutTypes.h"
48 #include "PlatformMouseEvent.h"
49 #include "PopupMenuClient.h"
50 #include "ProgressTracker.h"
51 #include "RenderTheme.h"
52 #include "c_instance.h"
53 #include "ewk_private.h"
54 #include "ewk_protocol_handler.h"
55
56 #include <Ecore.h>
57 #include <Eina.h>
58 #include <Evas.h>
59 #include <eina_safety_checks.h>
60 #include <inttypes.h>
61 #include <limits>
62 #include <math.h>
63 #include <sys/time.h>
64
65 #if ENABLE(DEVICE_ORIENTATION)
66 #include "DeviceMotionClientEfl.h"
67 #include "DeviceOrientationClientEfl.h"
68 #endif
69
70 #define ZOOM_MIN (0.05)
71 #define ZOOM_MAX (4.0)
72
73 #define DEVICE_PIXEL_RATIO (1.0)
74
75 static const char EWK_VIEW_TYPE_STR[] = "EWK_View";
76
77 static const size_t EWK_VIEW_REPAINTS_SIZE_INITIAL = 32;
78 static const size_t EWK_VIEW_REPAINTS_SIZE_STEP = 8;
79 static const size_t EWK_VIEW_REPAINTS_SIZE_MAX_FREE = 64;
80
81 static const size_t EWK_VIEW_SCROLLS_SIZE_INITIAL = 8;
82 static const size_t EWK_VIEW_SCROLLS_SIZE_STEP = 2;
83 static const size_t EWK_VIEW_SCROLLS_SIZE_MAX_FREE = 32;
84
85 /**
86  * @brief Private data that is used internally by EFL WebKit
87  * and should never be modified from outside.
88  *
89  * @internal
90  */
91 struct _Ewk_View_Private_Data {
92     WebCore::Page* page;
93     WebCore::Settings* pageSettings;
94     WebCore::Frame* mainFrame;
95     WebCore::ViewportArguments viewportArguments;
96     Ewk_History* history;
97     struct {
98         void* context;
99         Ewk_View_Resource_Handler_Cb function;
100     } customResourceHandler;
101     struct {
102         Ewk_Menu menu;
103         WebCore::PopupMenuClient* menuClient;
104     } popup;
105     struct {
106         Eina_Rectangle* array;
107         size_t count;
108         size_t allocated;
109     } repaints;
110     struct {
111         Ewk_Scroll_Request* array;
112         size_t count;
113         size_t allocated;
114     } scrolls;
115     unsigned int imh; /**< input method hints */
116     struct {
117         Eina_Bool viewCleared : 1;
118         Eina_Bool needTouchEvents : 1;
119     } flags;
120     struct {
121         const char* userAgent;
122         const char* userStylesheet;
123         const char* encodingDefault;
124         const char* encodingCustom;
125         const char* theme;
126         const char* localStorageDatabasePath;
127         int fontMinimumSize;
128         int fontMinimumLogicalSize;
129         int fontDefaultSize;
130         int fontMonospaceSize;
131         const char* fontStandard;
132         const char* fontCursive;
133         const char* fontMonospace;
134         const char* fontFantasy;
135         const char* fontSerif;
136         const char* fontSansSerif;
137         Eina_Bool autoLoadImages : 1;
138         Eina_Bool autoShrinkImages : 1;
139         Eina_Bool enableAutoResizeWindow : 1;
140         Eina_Bool enableDeveloperExtras : 1;
141         Eina_Bool enableScripts : 1;
142         Eina_Bool enablePlugins : 1;
143         Eina_Bool enableFrameFlattening : 1;
144         Eina_Bool encodingDetector : 1;
145         Eina_Bool scriptsWindowOpen : 1;
146         Eina_Bool scriptsCanCloseWindows : 1;
147         Eina_Bool resizableTextareas : 1;
148         Eina_Bool privateBrowsing : 1;
149         Eina_Bool caretBrowsing : 1;
150         Eina_Bool spatialNavigation : 1;
151         Eina_Bool localStorage : 1;
152         Eina_Bool offlineAppCache : 1;
153         Eina_Bool pageCache : 1;
154         struct {
155             float minScale;
156             float maxScale;
157             Eina_Bool userScalable : 1;
158         } zoomRange;
159         float devicePixelRatio;
160         double domTimerInterval;
161     } settings;
162     struct {
163         struct {
164             double start;
165             double end;
166             double duration;
167         } time;
168         struct {
169             float start;
170             float end;
171             float range;
172         } zoom;
173         struct {
174             Evas_Coord x, y;
175         } center;
176         Ecore_Animator* animator;
177     } animatedZoom;
178 };
179
180 #ifndef EWK_TYPE_CHECK
181 #define EWK_VIEW_TYPE_CHECK(ewkView, ...) do { } while (0)
182 #else
183 #define EWK_VIEW_TYPE_CHECK(ewkView, ...)                                     \
184     do {                                                                \
185         const char* _tmp_otype = evas_object_type_get(ewkView);               \
186         const Evas_Smart* _tmp_s = evas_object_smart_smart_get(ewkView);      \
187         if (EINA_UNLIKELY(!_tmp_s)) {                                   \
188             EINA_LOG_CRIT                                               \
189                 ("%p (%s) is not a smart object!", ewkView,                   \
190                 _tmp_otype ? _tmp_otype : "(null)");                   \
191             return __VA_ARGS__;                                         \
192         }                                                               \
193         const Evas_Smart_Class* _tmp_sc = evas_smart_class_get(_tmp_s); \
194         if (EINA_UNLIKELY(!_tmp_sc)) {                                  \
195             EINA_LOG_CRIT                                               \
196                 ("%p (%s) is not a smart object!", ewkView,                   \
197                 _tmp_otype ? _tmp_otype : "(null)");                   \
198             return __VA_ARGS__;                                         \
199         }                                                               \
200         if (EINA_UNLIKELY(_tmp_sc->data != EWK_VIEW_TYPE_STR)) {        \
201             EINA_LOG_CRIT                                               \
202                 ("%p (%s) is not of an ewk_view (need %p, got %p)!",    \
203                 ewkView, _tmp_otype ? _tmp_otype : "(null)",                 \
204                 EWK_VIEW_TYPE_STR, _tmp_sc->data);                     \
205             return __VA_ARGS__;                                         \
206         }                                                               \
207     } while (0)
208 #endif
209
210 #define EWK_VIEW_SD_GET(ewkView, ptr)                                 \
211     Ewk_View_Smart_Data* ptr = static_cast<Ewk_View_Smart_Data*>(evas_object_smart_data_get(ewkView))
212
213 #define EWK_VIEW_SD_GET_OR_RETURN(ewkView, ptr, ...)          \
214     EWK_VIEW_TYPE_CHECK(ewkView, __VA_ARGS__);                \
215     EWK_VIEW_SD_GET(ewkView, ptr);                            \
216     if (!ptr) {                                         \
217         CRITICAL("no smart data for object %p (%s)",    \
218                  ewkView, evas_object_type_get(ewkView));           \
219         return __VA_ARGS__;                             \
220     }
221
222 #define EWK_VIEW_PRIV_GET(smartData, ptr)              \
223     Ewk_View_Private_Data *ptr = smartData->_priv
224
225 #define EWK_VIEW_PRIV_GET_OR_RETURN(smartData, ptr, ...)               \
226     EWK_VIEW_PRIV_GET(smartData, ptr);                                 \
227     if (!ptr) {                                                 \
228         CRITICAL("no private data for object %p (%s)",          \
229                  smartData->self, evas_object_type_get(smartData->self));     \
230         return __VA_ARGS__;                                     \
231     }
232
233 static void _ewk_view_smart_changed(Ewk_View_Smart_Data* smartData)
234 {
235     if (smartData->changed.any)
236         return;
237     smartData->changed.any = EINA_TRUE;
238     evas_object_smart_changed(smartData->self);
239 }
240
241 static Eina_Bool _ewk_view_repaints_resize(Ewk_View_Private_Data* priv, size_t size)
242 {
243     void* tmp = realloc(priv->repaints.array, size * sizeof(Eina_Rectangle));
244     if (!tmp) {
245         CRITICAL("could not realloc repaints array to %zu elements.", size);
246         return EINA_FALSE;
247     }
248     priv->repaints.allocated = size;
249     priv->repaints.array = static_cast<Eina_Rectangle*>(tmp);
250     return EINA_TRUE;
251 }
252
253 static void _ewk_view_repaint_add(Ewk_View_Private_Data* priv, Evas_Coord x, Evas_Coord y, Evas_Coord width, Evas_Coord height)
254 {
255     Eina_Rectangle* rect;
256
257     // fprintf(stderr, ">>> repaint requested: %d,%d+%dx%d\n", x, y, w, h);
258     if (priv->repaints.allocated == priv->repaints.count) {
259         size_t size;
260         if (!priv->repaints.allocated)
261             size = EWK_VIEW_REPAINTS_SIZE_INITIAL;
262         else
263             size = priv->repaints.allocated + EWK_VIEW_REPAINTS_SIZE_STEP;
264         if (!_ewk_view_repaints_resize(priv, size))
265             return;
266     }
267
268     rect = priv->repaints.array + priv->repaints.count;
269     priv->repaints.count++;
270
271     rect->x = x;
272     rect->y = y;
273     rect->w = width;
274     rect->h = height;
275
276     DBG("add repaint %d, %d+%dx%d", x, y, width, height);
277 }
278
279 static void _ewk_view_repaints_flush(Ewk_View_Private_Data* priv)
280 {
281     priv->repaints.count = 0;
282     if (priv->repaints.allocated <= EWK_VIEW_REPAINTS_SIZE_MAX_FREE)
283         return;
284     _ewk_view_repaints_resize(priv, EWK_VIEW_REPAINTS_SIZE_MAX_FREE);
285 }
286
287 static Eina_Bool _ewk_view_scrolls_resize(Ewk_View_Private_Data* priv, size_t size)
288 {
289     void* tmp = realloc(priv->scrolls.array, size * sizeof(Ewk_Scroll_Request));
290     if (!tmp) {
291         CRITICAL("could not realloc scrolls array to %zu elements.", size);
292         return EINA_FALSE;
293     }
294     priv->scrolls.allocated = size;
295     priv->scrolls.array = static_cast<Ewk_Scroll_Request*>(tmp);
296     return EINA_TRUE;
297 }
298
299 static void _ewk_view_scroll_add(Ewk_View_Private_Data* priv, Evas_Coord deltaX, Evas_Coord deltaY, Evas_Coord x, Evas_Coord y, Evas_Coord width, Evas_Coord height, Eina_Bool mainScroll)
300 {
301     Ewk_Scroll_Request* rect;
302     Ewk_Scroll_Request* rect_end;
303     Evas_Coord x2 = x + width, y2 = y + height;
304
305     rect = priv->scrolls.array;
306     rect_end = rect + priv->scrolls.count;
307     for (; rect < rect_end; rect++) {
308         if (rect->x == x && rect->y == y && rect->w == width && rect->h == height) {
309             DBG("region already scrolled %d,%d+%dx%d %+03d,%+03d add "
310                 "%+03d,%+03d",
311                 rect->x, rect->y, rect->w, rect->h, rect->dx, rect->dy, deltaX, deltaY);
312             rect->dx += deltaX;
313             rect->dy += deltaY;
314             return;
315         }
316         if ((x <= rect->x && x2 >= rect->x2) && (y <= rect->y && y2 >= rect->y2)) {
317             DBG("old viewport (%d,%d+%dx%d %+03d,%+03d) was scrolled itself, "
318                 "add %+03d,%+03d",
319                 rect->x, rect->y, rect->w, rect->h, rect->dx, rect->dy, deltaX, deltaY);
320             rect->x += deltaX;
321             rect->y += deltaY;
322         }
323     }
324
325     if (priv->scrolls.allocated == priv->scrolls.count) {
326         size_t size;
327         if (!priv->scrolls.allocated)
328             size = EWK_VIEW_SCROLLS_SIZE_INITIAL;
329         else
330             size = priv->scrolls.allocated + EWK_VIEW_SCROLLS_SIZE_STEP;
331         if (!_ewk_view_scrolls_resize(priv, size))
332             return;
333     }
334
335     rect = priv->scrolls.array + priv->scrolls.count;
336     priv->scrolls.count++;
337
338     rect->x = x;
339     rect->y = y;
340     rect->w = width;
341     rect->h = height;
342     rect->x2 = x2;
343     rect->y2 = y2;
344     rect->dx = deltaX;
345     rect->dy = deltaY;
346     rect->main_scroll = mainScroll;
347     DBG("add scroll in region: %d, %d+%dx%d %+03d, %+03d", x, y, width, height, deltaX, deltaY);
348
349     Eina_Rectangle* pr;
350     Eina_Rectangle* pr_end;
351     size_t count;
352     pr = priv->repaints.array;
353     count = priv->repaints.count;
354     pr_end = pr + count;
355     for (; pr < pr_end; pr++) {
356         pr->x += deltaX;
357         pr->y += deltaY;
358     }
359 }
360
361 static void _ewk_view_scrolls_flush(Ewk_View_Private_Data* priv)
362 {
363     priv->scrolls.count = 0;
364     if (priv->scrolls.allocated <= EWK_VIEW_SCROLLS_SIZE_MAX_FREE)
365         return;
366     _ewk_view_scrolls_resize(priv, EWK_VIEW_SCROLLS_SIZE_MAX_FREE);
367 }
368
369 // Default Event Handling //////////////////////////////////////////////
370 static Eina_Bool _ewk_view_smart_focus_in(Ewk_View_Smart_Data* smartData)
371 {
372     EWK_VIEW_PRIV_GET(smartData, priv);
373     WebCore::FocusController* fc = priv->page->focusController();
374     DBG("ewkView=%p, fc=%p", smartData->self, fc);
375     EINA_SAFETY_ON_NULL_RETURN_VAL(fc, EINA_FALSE);
376
377     fc->setActive(true);
378     fc->setFocused(true);
379     return EINA_TRUE;
380 }
381
382 static Eina_Bool _ewk_view_smart_focus_out(Ewk_View_Smart_Data* smartData)
383 {
384     EWK_VIEW_PRIV_GET(smartData, priv);
385     WebCore::FocusController* focusController = priv->page->focusController();
386     DBG("ewkView=%p, fc=%p", smartData->self, focusController);
387     EINA_SAFETY_ON_NULL_RETURN_VAL(focusController, EINA_FALSE);
388
389     focusController->setActive(false);
390     focusController->setFocused(false);
391     return EINA_TRUE;
392 }
393
394 static Eina_Bool _ewk_view_smart_mouse_wheel(Ewk_View_Smart_Data* smartData, const Evas_Event_Mouse_Wheel* wheelEvent)
395 {
396     return ewk_frame_feed_mouse_wheel(smartData->main_frame, wheelEvent);
397 }
398
399 static Eina_Bool _ewk_view_smart_mouse_down(Ewk_View_Smart_Data* smartData, const Evas_Event_Mouse_Down* downEvent)
400 {
401     return ewk_frame_feed_mouse_down(smartData->main_frame, downEvent);
402 }
403
404 static Eina_Bool _ewk_view_smart_mouse_up(Ewk_View_Smart_Data* smartData, const Evas_Event_Mouse_Up* upEvent)
405 {
406     return ewk_frame_feed_mouse_up(smartData->main_frame, upEvent);
407 }
408
409 static Eina_Bool _ewk_view_smart_mouse_move(Ewk_View_Smart_Data* smartData, const Evas_Event_Mouse_Move* moveEvent)
410 {
411     return ewk_frame_feed_mouse_move(smartData->main_frame, moveEvent);
412 }
413
414 static Eina_Bool _ewk_view_smart_key_down(Ewk_View_Smart_Data* smartData, const Evas_Event_Key_Down* downEvent)
415 {
416     Evas_Object* frame = ewk_view_frame_focused_get(smartData->self);
417
418     if (!frame)
419         frame = smartData->main_frame;
420
421     return ewk_frame_feed_key_down(frame, downEvent);
422 }
423
424 static Eina_Bool _ewk_view_smart_key_up(Ewk_View_Smart_Data* smartData, const Evas_Event_Key_Up* upEvent)
425 {
426     Evas_Object* frame = ewk_view_frame_focused_get(smartData->self);
427
428     if (!frame)
429         frame = smartData->main_frame;
430
431     return ewk_frame_feed_key_up(frame, upEvent);
432 }
433
434 static void _ewk_view_smart_add_console_message(Ewk_View_Smart_Data* smartData, const char* message, unsigned int lineNumber, const char* sourceID)
435 {
436     INF("console message: %s @%d: %s\n", sourceID, lineNumber, message);
437 }
438
439 static void _ewk_view_smart_run_javascript_alert(Ewk_View_Smart_Data* smartData, Evas_Object* frame, const char* message)
440 {
441     INF("javascript alert: %s\n", message);
442 }
443
444 static Eina_Bool _ewk_view_smart_run_javascript_confirm(Ewk_View_Smart_Data* smartData, Evas_Object* frame, const char* message)
445 {
446     INF("javascript confirm: %s", message);
447     INF("javascript confirm (HARD CODED)? YES");
448     return EINA_TRUE;
449 }
450
451 static Eina_Bool _ewk_view_smart_should_interrupt_javascript(Ewk_View_Smart_Data* smartData)
452 {
453     INF("should interrupt javascript?\n"
454         "\t(HARD CODED) NO");
455     return EINA_FALSE;
456 }
457
458 static Eina_Bool _ewk_view_smart_run_javascript_prompt(Ewk_View_Smart_Data* smartData, Evas_Object* frame, const char* message, const char* defaultValue, char** value)
459 {
460     *value = strdup("test");
461     Eina_Bool result = EINA_TRUE;
462     INF("javascript prompt:\n"
463         "\t      message: %s\n"
464         "\tdefault value: %s\n"
465         "\tgiving answer: %s\n"
466         "\t       button: %s", message, defaultValue, *value, result ? "ok" : "cancel");
467
468     return result;
469 }
470
471 // Event Handling //////////////////////////////////////////////////////
472 static void _ewk_view_on_focus_in(void* data, Evas* eventType, Evas_Object* callback, void* eventInfo)
473 {
474     Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
475     EINA_SAFETY_ON_NULL_RETURN(smartData->api);
476     EINA_SAFETY_ON_NULL_RETURN(smartData->api->focus_in);
477     smartData->api->focus_in(smartData);
478 }
479
480 static void _ewk_view_on_focus_out(void* data, Evas* eventType, Evas_Object* callback, void* eventInfo)
481 {
482     Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
483     EINA_SAFETY_ON_NULL_RETURN(smartData->api);
484     EINA_SAFETY_ON_NULL_RETURN(smartData->api->focus_out);
485     smartData->api->focus_out(smartData);
486 }
487
488 static void _ewk_view_on_mouse_wheel(void* data, Evas* eventType, Evas_Object* callback, void* eventInfo)
489 {
490     Evas_Event_Mouse_Wheel* wheelEvent = static_cast<Evas_Event_Mouse_Wheel*>(eventInfo);
491     Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
492     EINA_SAFETY_ON_NULL_RETURN(smartData->api);
493     EINA_SAFETY_ON_NULL_RETURN(smartData->api->mouse_wheel);
494     smartData->api->mouse_wheel(smartData, wheelEvent);
495 }
496
497 static void _ewk_view_on_mouse_down(void* data, Evas* eventType, Evas_Object* callback, void* eventInfo)
498 {
499     Evas_Event_Mouse_Down* downEvent = static_cast<Evas_Event_Mouse_Down*>(eventInfo);
500     Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
501     EINA_SAFETY_ON_NULL_RETURN(smartData->api);
502     EINA_SAFETY_ON_NULL_RETURN(smartData->api->mouse_down);
503     smartData->api->mouse_down(smartData, downEvent);
504 }
505
506 static void _ewk_view_on_mouse_up(void* data, Evas* eventType, Evas_Object* callback, void* eventInfo)
507 {
508     Evas_Event_Mouse_Up* upEvent = static_cast<Evas_Event_Mouse_Up*>(eventInfo);
509     Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
510     EINA_SAFETY_ON_NULL_RETURN(smartData->api);
511     EINA_SAFETY_ON_NULL_RETURN(smartData->api->mouse_up);
512     smartData->api->mouse_up(smartData, upEvent);
513 }
514
515 static void _ewk_view_on_mouse_move(void* data, Evas* eventType, Evas_Object* callback, void* eventInfo)
516 {
517     Evas_Event_Mouse_Move* moveEvent = static_cast<Evas_Event_Mouse_Move*>(eventInfo);
518     Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
519     EINA_SAFETY_ON_NULL_RETURN(smartData->api);
520     EINA_SAFETY_ON_NULL_RETURN(smartData->api->mouse_move);
521     smartData->api->mouse_move(smartData, moveEvent);
522 }
523
524 static void _ewk_view_on_key_down(void* data, Evas* eventType, Evas_Object* callback, void* eventInfo)
525 {
526     Evas_Event_Key_Down* downEvent = static_cast<Evas_Event_Key_Down*>(eventInfo);
527     Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
528     EINA_SAFETY_ON_NULL_RETURN(smartData->api);
529     EINA_SAFETY_ON_NULL_RETURN(smartData->api->key_down);
530     smartData->api->key_down(smartData, downEvent);
531 }
532
533 static void _ewk_view_on_key_up(void* data, Evas* eventType, Evas_Object* callback, void* eventInfo)
534 {
535     Evas_Event_Key_Up* upEvent = static_cast<Evas_Event_Key_Up*>(eventInfo);
536     Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
537     EINA_SAFETY_ON_NULL_RETURN(smartData->api);
538     EINA_SAFETY_ON_NULL_RETURN(smartData->api->key_up);
539     smartData->api->key_up(smartData, upEvent);
540 }
541
542 static WTF::PassRefPtr<WebCore::Frame> _ewk_view_core_frame_new(Ewk_View_Smart_Data* smartData, Ewk_View_Private_Data* priv, WebCore::HTMLFrameOwnerElement* owner)
543 {
544     WebCore::FrameLoaderClientEfl* frameLoaderClient = new WebCore::FrameLoaderClientEfl(smartData->self);
545     if (!frameLoaderClient) {
546         CRITICAL("Could not create frame loader client.");
547         return 0;
548     }
549     frameLoaderClient->setCustomUserAgent(String::fromUTF8(priv->settings.userAgent));
550
551     return WebCore::Frame::create(priv->page, owner, frameLoaderClient);
552 }
553
554 static Evas_Smart_Class _parent_sc = EVAS_SMART_CLASS_INIT_NULL;
555
556 static Ewk_View_Private_Data* _ewk_view_priv_new(Ewk_View_Smart_Data* smartData)
557 {
558     Ewk_View_Private_Data* priv =
559         static_cast<Ewk_View_Private_Data*>(calloc(1, sizeof(Ewk_View_Private_Data)));
560     AtomicString string;
561     WebCore::KURL url;
562
563     if (!priv) {
564         CRITICAL("could not allocate Ewk_View_Private_Data");
565         return 0;
566     }
567
568     WebCore::Page::PageClients pageClients;
569     pageClients.chromeClient = static_cast<WebCore::ChromeClient*>(new WebCore::ChromeClientEfl(smartData->self));
570     pageClients.editorClient = static_cast<WebCore::EditorClient*>(new WebCore::EditorClientEfl(smartData->self));
571     pageClients.dragClient = static_cast<WebCore::DragClient*>(new WebCore::DragClientEfl);
572     pageClients.inspectorClient = static_cast<WebCore::InspectorClient*>(new WebCore::InspectorClientEfl);
573 #if ENABLE(DEVICE_ORIENTATION)
574     pageClients.deviceMotionClient = static_cast<WebCore::DeviceMotionClient*>(new WebCore::DeviceMotionClientEfl);
575     pageClients.deviceOrientationClient = static_cast<WebCore::DeviceOrientationClient*>(new WebCore::DeviceOrientationClientEfl);
576 #endif
577     priv->page = new WebCore::Page(pageClients);
578     if (!priv->page) {
579         CRITICAL("Could not create WebKit Page");
580         goto error_page;
581     }
582
583     priv->pageSettings = priv->page->settings();
584     if (!priv->pageSettings) {
585         CRITICAL("Could not get page settings.");
586         goto error_settings;
587     }
588
589     priv->viewportArguments.width = WebCore::ViewportArguments::ValueAuto;
590     priv->viewportArguments.height = WebCore::ViewportArguments::ValueAuto;
591     priv->viewportArguments.initialScale = WebCore::ViewportArguments::ValueAuto;
592     priv->viewportArguments.minimumScale = WebCore::ViewportArguments::ValueAuto;
593     priv->viewportArguments.maximumScale = WebCore::ViewportArguments::ValueAuto;
594     priv->viewportArguments.targetDensityDpi = WebCore::ViewportArguments::ValueAuto;
595     priv->viewportArguments.userScalable = EINA_TRUE;
596
597     priv->pageSettings->setLoadsImagesAutomatically(true);
598     priv->pageSettings->setDefaultTextEncodingName("iso-8859-1");
599     priv->pageSettings->setDefaultFixedFontSize(12);
600     priv->pageSettings->setDefaultFontSize(16);
601     priv->pageSettings->setSerifFontFamily("serif");
602     priv->pageSettings->setFixedFontFamily("monotype");
603     priv->pageSettings->setSansSerifFontFamily("sans");
604     priv->pageSettings->setStandardFontFamily("sans");
605     priv->pageSettings->setJavaScriptEnabled(true);
606     priv->pageSettings->setPluginsEnabled(true);
607     priv->pageSettings->setLocalStorageEnabled(true);
608     priv->pageSettings->setOfflineWebApplicationCacheEnabled(true);
609     priv->pageSettings->setUsesPageCache(true);
610     priv->pageSettings->setUsesEncodingDetector(false);
611
612     url = priv->pageSettings->userStyleSheetLocation();
613     priv->settings.userStylesheet = eina_stringshare_add(url.string().utf8().data());
614
615     priv->settings.encodingDefault = eina_stringshare_add
616                                           (priv->pageSettings->defaultTextEncodingName().utf8().data());
617     priv->settings.encodingCustom = 0;
618
619     string = priv->pageSettings->localStorageDatabasePath();
620     priv->settings.localStorageDatabasePath = eina_stringshare_add(string.string().utf8().data());
621
622     priv->settings.fontMinimumSize = priv->pageSettings->minimumFontSize();
623     priv->settings.fontMinimumLogicalSize = priv->pageSettings->minimumLogicalFontSize();
624     priv->settings.fontDefaultSize = priv->pageSettings->defaultFontSize();
625     priv->settings.fontMonospaceSize = priv->pageSettings->defaultFixedFontSize();
626
627     string = priv->pageSettings->standardFontFamily();
628     priv->settings.fontStandard = eina_stringshare_add(string.string().utf8().data());
629     string = priv->pageSettings->cursiveFontFamily();
630     priv->settings.fontCursive = eina_stringshare_add(string.string().utf8().data());
631     string = priv->pageSettings->fixedFontFamily();
632     priv->settings.fontMonospace = eina_stringshare_add(string.string().utf8().data());
633     string = priv->pageSettings->fantasyFontFamily();
634     priv->settings.fontFantasy = eina_stringshare_add(string.string().utf8().data());
635     string = priv->pageSettings->serifFontFamily();
636     priv->settings.fontSerif = eina_stringshare_add(string.string().utf8().data());
637     string = priv->pageSettings->sansSerifFontFamily();
638     priv->settings.fontSansSerif = eina_stringshare_add(string.string().utf8().data());
639
640     priv->settings.autoLoadImages = priv->pageSettings->loadsImagesAutomatically();
641     priv->settings.autoShrinkImages = priv->pageSettings->shrinksStandaloneImagesToFit();
642     priv->settings.enableAutoResizeWindow = EINA_TRUE;
643     priv->settings.enableDeveloperExtras = priv->pageSettings->developerExtrasEnabled();
644     priv->settings.enableScripts = priv->pageSettings->isJavaScriptEnabled();
645     priv->settings.enablePlugins = priv->pageSettings->arePluginsEnabled();
646     priv->settings.enableFrameFlattening = priv->pageSettings->frameFlatteningEnabled();
647     priv->settings.scriptsWindowOpen = priv->pageSettings->javaScriptCanOpenWindowsAutomatically();
648     priv->settings.scriptsCanCloseWindows = priv->pageSettings->allowScriptsToCloseWindows();
649     priv->settings.resizableTextareas = priv->pageSettings->textAreasAreResizable();
650     priv->settings.privateBrowsing = priv->pageSettings->privateBrowsingEnabled();
651     priv->settings.caretBrowsing = priv->pageSettings->caretBrowsingEnabled();
652     priv->settings.spatialNavigation = priv->pageSettings->isSpatialNavigationEnabled();
653     priv->settings.localStorage = priv->pageSettings->localStorageEnabled();
654     priv->settings.offlineAppCache = true; // XXX no function to read setting; this keeps the original setting
655     priv->settings.pageCache = priv->pageSettings->usesPageCache();
656     priv->settings.encodingDetector = priv->pageSettings->usesEncodingDetector();
657
658     priv->settings.userAgent = ewk_settings_default_user_agent_get();
659
660     // Since there's no scale separated from zooming in webkit-efl, this functionality of
661     // viewport meta tag is implemented using zoom. When scale zoom is supported by webkit-efl,
662     // this functionality will be modified by the scale zoom patch.
663     priv->settings.zoomRange.minScale = ZOOM_MIN;
664     priv->settings.zoomRange.maxScale = ZOOM_MAX;
665     priv->settings.zoomRange.userScalable = EINA_TRUE;
666     priv->settings.devicePixelRatio = DEVICE_PIXEL_RATIO;
667
668     priv->settings.domTimerInterval = priv->pageSettings->defaultMinDOMTimerInterval();
669
670     priv->mainFrame = _ewk_view_core_frame_new(smartData, priv, 0).get();
671     if (!priv->mainFrame) {
672         CRITICAL("Could not create main frame.");
673         goto error_main_frame;
674     }
675
676     priv->history = ewk_history_new(static_cast<WebCore::BackForwardListImpl*>(priv->page->backForwardList()));
677     if (!priv->history) {
678         CRITICAL("Could not create history instance for view.");
679         goto error_history;
680     }
681
682     return priv;
683
684 error_history:
685     // delete priv->main_frame; /* do not delete priv->main_frame */
686 error_main_frame:
687 error_settings:
688     delete priv->page;
689 error_page:
690     free(priv);
691     return 0;
692 }
693
694 static void _ewk_view_priv_del(Ewk_View_Private_Data* priv)
695 {
696     if (!priv)
697         return;
698
699     /* do not delete priv->main_frame */
700
701     free(priv->repaints.array);
702     free(priv->scrolls.array);
703
704     eina_stringshare_del(priv->settings.userAgent);
705     eina_stringshare_del(priv->settings.userStylesheet);
706     eina_stringshare_del(priv->settings.encodingDefault);
707     eina_stringshare_del(priv->settings.encodingCustom);
708     eina_stringshare_del(priv->settings.fontStandard);
709     eina_stringshare_del(priv->settings.fontCursive);
710     eina_stringshare_del(priv->settings.fontMonospace);
711     eina_stringshare_del(priv->settings.fontFantasy);
712     eina_stringshare_del(priv->settings.fontSerif);
713     eina_stringshare_del(priv->settings.fontSansSerif);
714     eina_stringshare_del(priv->settings.localStorageDatabasePath);
715
716     if (priv->animatedZoom.animator)
717         ecore_animator_del(priv->animatedZoom.animator);
718
719     ewk_history_free(priv->history);
720
721     delete priv->page;
722     free(priv);
723 }
724
725 static void _ewk_view_smart_add(Evas_Object* ewkView)
726 {
727     const Evas_Smart* smart = evas_object_smart_smart_get(ewkView);
728     const Evas_Smart_Class* smartClass = evas_smart_class_get(smart);
729     const Ewk_View_Smart_Class* api = reinterpret_cast<const Ewk_View_Smart_Class*>(smartClass);
730     EINA_SAFETY_ON_NULL_RETURN(api->backing_store_add);
731     EWK_VIEW_SD_GET(ewkView, smartData);
732
733     if (!smartData) {
734         smartData = static_cast<Ewk_View_Smart_Data*>(calloc(1, sizeof(Ewk_View_Smart_Data)));
735         if (!smartData) {
736             CRITICAL("could not allocate Ewk_View_Smart_Data");
737             return;
738         }
739         evas_object_smart_data_set(ewkView, smartData);
740     }
741
742     smartData->bg_color.r = 255;
743     smartData->bg_color.g = 255;
744     smartData->bg_color.b = 255;
745     smartData->bg_color.a = 255;
746
747     smartData->self = ewkView;
748     smartData->_priv = _ewk_view_priv_new(smartData);
749     smartData->api = api;
750
751     _parent_sc.add(ewkView);
752
753     if (!smartData->_priv)
754         return;
755
756     EWK_VIEW_PRIV_GET(smartData, priv);
757
758     smartData->backing_store = api->backing_store_add(smartData);
759     if (!smartData->backing_store) {
760         ERR("Could not create backing store object.");
761         return;
762     }
763
764     evas_object_smart_member_add(smartData->backing_store, ewkView);
765     evas_object_show(smartData->backing_store);
766     evas_object_pass_events_set(smartData->backing_store, EINA_TRUE);
767
768     smartData->events_rect = evas_object_rectangle_add(smartData->base.evas);
769     evas_object_color_set(smartData->events_rect, 0, 0, 0, 0);
770     evas_object_smart_member_add(smartData->events_rect, ewkView);
771     evas_object_show(smartData->events_rect);
772
773     smartData->main_frame = ewk_frame_add(smartData->base.evas);
774     if (!smartData->main_frame) {
775         ERR("Could not create main frame object.");
776         return;
777     }
778
779     if (!ewk_frame_init(smartData->main_frame, ewkView, priv->mainFrame)) {
780         ERR("Could not initialize main frme object.");
781         evas_object_del(smartData->main_frame);
782         smartData->main_frame = 0;
783
784         delete priv->mainFrame;
785         priv->mainFrame = 0;
786         return;
787     }
788
789     evas_object_name_set(smartData->main_frame, "EWK_Frame:main");
790     evas_object_smart_member_add(smartData->main_frame, ewkView);
791     evas_object_show(smartData->main_frame);
792
793 #define CONNECT(s, c) evas_object_event_callback_add(ewkView, s, c, smartData)
794     CONNECT(EVAS_CALLBACK_FOCUS_IN, _ewk_view_on_focus_in);
795     CONNECT(EVAS_CALLBACK_FOCUS_OUT, _ewk_view_on_focus_out);
796     CONNECT(EVAS_CALLBACK_MOUSE_WHEEL, _ewk_view_on_mouse_wheel);
797     CONNECT(EVAS_CALLBACK_MOUSE_DOWN, _ewk_view_on_mouse_down);
798     CONNECT(EVAS_CALLBACK_MOUSE_UP, _ewk_view_on_mouse_up);
799     CONNECT(EVAS_CALLBACK_MOUSE_MOVE, _ewk_view_on_mouse_move);
800     CONNECT(EVAS_CALLBACK_KEY_DOWN, _ewk_view_on_key_down);
801     CONNECT(EVAS_CALLBACK_KEY_UP, _ewk_view_on_key_up);
802 #undef CONNECT
803 }
804
805 static void _ewk_view_smart_del(Evas_Object* ewkView)
806 {
807     EWK_VIEW_SD_GET(ewkView, smartData);
808     Ewk_View_Private_Data* priv = smartData ? smartData->_priv : 0;
809
810     ewk_view_stop(ewkView);
811     _parent_sc.del(ewkView);
812     _ewk_view_priv_del(priv);
813 }
814
815 static void _ewk_view_smart_resize(Evas_Object* ewkView, Evas_Coord w, Evas_Coord h)
816 {
817     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
818
819     // these should be queued and processed in calculate as well!
820     evas_object_resize(smartData->backing_store, w, h);
821
822     smartData->changed.size = EINA_TRUE;
823     _ewk_view_smart_changed(smartData);
824 }
825
826 static void _ewk_view_smart_move(Evas_Object* ewkView, Evas_Coord x, Evas_Coord y)
827 {
828     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
829     smartData->changed.position = EINA_TRUE;
830     _ewk_view_smart_changed(smartData);
831 }
832
833 static void _ewk_view_smart_calculate(Evas_Object* ewkView)
834 {
835     EWK_VIEW_SD_GET(ewkView, smartData);
836     EWK_VIEW_PRIV_GET(smartData, priv);
837     EINA_SAFETY_ON_NULL_RETURN(smartData->api->contents_resize);
838     EINA_SAFETY_ON_NULL_RETURN(smartData->api->scrolls_process);
839     EINA_SAFETY_ON_NULL_RETURN(smartData->api->repaints_process);
840     Evas_Coord x, y, width, height;
841
842     smartData->changed.any = EINA_FALSE;
843
844     if (!smartData->main_frame || !priv->mainFrame)
845         return;
846
847     evas_object_geometry_get(ewkView, &x, &y, &width, &height);
848
849     DBG("ewkView=%p geo=[%d, %d + %dx%d], changed: size=%hhu, "
850         "scrolls=%zu, repaints=%zu",
851         ewkView, x, y, width, height, smartData->changed.size,
852         priv->scrolls.count, priv->repaints.count);
853
854     if (smartData->changed.size && ((width != smartData->view.w) || (height != smartData->view.h))) {
855         WebCore::FrameView* view = priv->mainFrame->view();
856         if (view) {
857             view->resize(width, height);
858             view->forceLayout();
859             view->adjustViewSize();
860         }
861         evas_object_resize(smartData->main_frame, width, height);
862         evas_object_resize(smartData->events_rect, width, height);
863         smartData->changed.frame_rect = EINA_TRUE;
864         smartData->view.w = width;
865         smartData->view.h = height;
866
867         _ewk_view_repaint_add(priv, 0, 0, width, height);
868
869         // This callback is a good place e.g. to change fixed layout size (ewk_view_fixed_layout_size_set).
870         evas_object_smart_callback_call(ewkView, "view,resized", 0);
871     }
872     smartData->changed.size = EINA_FALSE;
873
874     if (smartData->changed.position && ((x != smartData->view.x) || (y != smartData->view.y))) {
875         evas_object_move(smartData->main_frame, x, y);
876         evas_object_move(smartData->backing_store, x, y);
877         evas_object_move(smartData->events_rect, x, y);
878         smartData->changed.frame_rect = EINA_TRUE;
879         smartData->view.x = x;
880         smartData->view.y = y;
881     }
882     smartData->changed.position = EINA_FALSE;
883
884     if (!smartData->api->scrolls_process(smartData))
885         ERR("failed to process scrolls.");
886     _ewk_view_scrolls_flush(priv);
887
888     if (!smartData->api->repaints_process(smartData))
889         ERR("failed to process repaints.");
890     _ewk_view_repaints_flush(priv);
891
892     if (smartData->changed.frame_rect) {
893         WebCore::FrameView* view = priv->mainFrame->view();
894         view->frameRectsChanged(); /* force tree to get position from root */
895         smartData->changed.frame_rect = EINA_FALSE;
896     }
897 }
898
899 static void _ewk_view_smart_show(Evas_Object* ewkView)
900 {
901     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
902
903     if (evas_object_clipees_get(smartData->base.clipper))
904         evas_object_show(smartData->base.clipper);
905     evas_object_show(smartData->backing_store);
906 }
907
908 static void _ewk_view_smart_hide(Evas_Object* ewkView)
909 {
910     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
911
912     evas_object_hide(smartData->base.clipper);
913     evas_object_hide(smartData->backing_store);
914 }
915
916 static Eina_Bool _ewk_view_smart_contents_resize(Ewk_View_Smart_Data* smartData, int width, int height)
917 {
918     return EINA_TRUE;
919 }
920
921 static Eina_Bool _ewk_view_smart_zoom_set(Ewk_View_Smart_Data* smartData, float zoom, Evas_Coord centerX, Evas_Coord centerY)
922 {
923     double px, py;
924     Evas_Coord x, y, width, height;
925     Eina_Bool result;
926
927     ewk_frame_scroll_size_get(smartData->main_frame, &width, &height);
928     ewk_frame_scroll_pos_get(smartData->main_frame, &x, &y);
929
930     if (width + smartData->view.w > 0)
931         px = static_cast<double>(x + centerX) / (width + smartData->view.w);
932     else
933         px = 0.0;
934
935     if (height + smartData->view.h > 0)
936         py = static_cast<double>(y + centerY) / (height + smartData->view.h);
937     else
938         py = 0.0;
939
940     result = ewk_frame_page_zoom_set(smartData->main_frame, zoom);
941
942     ewk_frame_scroll_size_get(smartData->main_frame, &width, &height);
943     x = (width + smartData->view.w) * px - centerX;
944     y = (height + smartData->view.h) * py - centerY;
945     ewk_frame_scroll_set(smartData->main_frame, x, y);
946     return result;
947 }
948
949 static void _ewk_view_smart_flush(Ewk_View_Smart_Data* smartData)
950 {
951     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv);
952     _ewk_view_repaints_flush(priv);
953     _ewk_view_scrolls_flush(priv);
954 }
955
956 static Eina_Bool _ewk_view_smart_pre_render_region(Ewk_View_Smart_Data* smartData, Evas_Coord x, Evas_Coord y, Evas_Coord width, Evas_Coord height, float zoom)
957 {
958     WRN("not supported by engine. sd=%p area=%d,%d+%dx%d, zoom=%f",
959         smartData, x, y, width, height, zoom);
960     return EINA_FALSE;
961 }
962
963 static Eina_Bool _ewk_view_smart_pre_render_relative_radius(Ewk_View_Smart_Data* smartData, unsigned int number, float zoom)
964 {
965     WRN("not supported by engine. sd=%p, n=%u zoom=%f",
966         smartData, number, zoom);
967     return EINA_FALSE;
968 }
969
970 static void _ewk_view_smart_pre_render_cancel(Ewk_View_Smart_Data* smartData)
971 {
972     WRN("not supported by engine. sd=%p", smartData);
973 }
974
975 static void _ewk_view_zoom_animated_mark_stop(Ewk_View_Smart_Data* smartData)
976 {
977     smartData->animated_zoom.zoom.start = 0.0;
978     smartData->animated_zoom.zoom.end = 0.0;
979     smartData->animated_zoom.zoom.current = 0.0;
980 }
981
982 static void _ewk_view_zoom_animated_finish(Ewk_View_Smart_Data* smartData)
983 {
984     EWK_VIEW_PRIV_GET(smartData, priv);
985     ecore_animator_del(priv->animatedZoom.animator);
986     priv->animatedZoom.animator = 0;
987     _ewk_view_zoom_animated_mark_stop(smartData);
988     evas_object_smart_callback_call(smartData->self, "zoom,animated,end", 0);
989 }
990
991 static float _ewk_view_zoom_animated_current(Ewk_View_Private_Data* priv)
992 {
993     double now = ecore_loop_time_get();
994     double delta = now - priv->animatedZoom.time.start;
995
996     if (delta > priv->animatedZoom.time.duration)
997         delta = priv->animatedZoom.time.duration;
998     if (delta < 0.0) // time went back, clock adjusted?
999         delta = 0.0;
1000
1001     delta /= priv->animatedZoom.time.duration;
1002
1003     return ((priv->animatedZoom.zoom.range * delta)
1004             + priv->animatedZoom.zoom.start);
1005 }
1006
1007 static Eina_Bool _ewk_view_zoom_animator_cb(void* data)
1008 {
1009     Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
1010     Evas_Coord centerX, centerY;
1011     EWK_VIEW_PRIV_GET(smartData, priv);
1012     double now = ecore_loop_time_get();
1013
1014     centerX = priv->animatedZoom.center.x;
1015     centerY = priv->animatedZoom.center.y;
1016
1017     // TODO: progressively center (cx, cy) -> (view.x + view.h/2, view.y + view.h/2)
1018     if (centerX >= smartData->view.w)
1019         centerX = smartData->view.w - 1;
1020     if (centerY >= smartData->view.h)
1021         centerY = smartData->view.h - 1;
1022
1023     if ((now >= priv->animatedZoom.time.end)
1024         || (now < priv->animatedZoom.time.start)) {
1025         _ewk_view_zoom_animated_finish(smartData);
1026         ewk_view_zoom_set(smartData->self, priv->animatedZoom.zoom.end, centerX, centerY);
1027         smartData->api->sc.calculate(smartData->self);
1028         return EINA_FALSE;
1029     }
1030
1031     smartData->animated_zoom.zoom.current = _ewk_view_zoom_animated_current(priv);
1032     smartData->api->zoom_weak_set(smartData, smartData->animated_zoom.zoom.current, centerX, centerY);
1033     return EINA_TRUE;
1034 }
1035
1036 static void _ewk_view_zoom_animation_start(Ewk_View_Smart_Data* smartData)
1037 {
1038     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv);
1039     if (priv->animatedZoom.animator)
1040         return;
1041     priv->animatedZoom.animator = ecore_animator_add
1042                                        (_ewk_view_zoom_animator_cb, smartData);
1043 }
1044
1045 static WebCore::ViewportAttributes _ewk_view_viewport_attributes_compute(const Evas_Object* ewkView)
1046 {
1047     EWK_VIEW_SD_GET(ewkView, smartData);
1048     EWK_VIEW_PRIV_GET(smartData, priv);
1049
1050     int desktopWidth = 980;
1051     int deviceDPI = ewk_util_dpi_get();
1052
1053     WebCore::IntRect availableRect = enclosingIntRect(priv->page->chrome()->client()->pageRect());
1054     WebCore::IntRect deviceRect = enclosingIntRect(priv->page->chrome()->client()->windowRect());
1055
1056     WebCore::ViewportAttributes attributes = WebCore::computeViewportAttributes(priv->viewportArguments, desktopWidth, deviceRect.width(), deviceRect.height(), deviceDPI, availableRect.size());
1057
1058     return attributes;
1059 }
1060
1061 static Eina_Bool _ewk_view_smart_disable_render(Ewk_View_Smart_Data* smartData)
1062 {
1063     WRN("not supported by engine. sd=%p", smartData);
1064     return EINA_FALSE;
1065 }
1066
1067 static Eina_Bool _ewk_view_smart_enable_render(Ewk_View_Smart_Data* smartData)
1068 {
1069     WRN("not supported by engine. sd=%p", smartData);
1070     return EINA_FALSE;
1071 }
1072
1073 Eina_Bool ewk_view_base_smart_set(Ewk_View_Smart_Class* api)
1074 {
1075     EINA_SAFETY_ON_NULL_RETURN_VAL(api, EINA_FALSE);
1076
1077     if (api->version != EWK_VIEW_SMART_CLASS_VERSION) {
1078         EINA_LOG_CRIT
1079             ("Ewk_View_Smart_Class %p is version %lu while %lu was expected.",
1080             api, api->version, EWK_VIEW_SMART_CLASS_VERSION);
1081         return EINA_FALSE;
1082     }
1083
1084     if (EINA_UNLIKELY(!_parent_sc.add))
1085         evas_object_smart_clipped_smart_set(&_parent_sc);
1086
1087     evas_object_smart_clipped_smart_set(&api->sc);
1088     api->sc.add = _ewk_view_smart_add;
1089     api->sc.del = _ewk_view_smart_del;
1090     api->sc.resize = _ewk_view_smart_resize;
1091     api->sc.move = _ewk_view_smart_move;
1092     api->sc.calculate = _ewk_view_smart_calculate;
1093     api->sc.show = _ewk_view_smart_show;
1094     api->sc.hide = _ewk_view_smart_hide;
1095     api->sc.data = EWK_VIEW_TYPE_STR; /* used by type checking */
1096
1097     api->contents_resize = _ewk_view_smart_contents_resize;
1098     api->zoom_set = _ewk_view_smart_zoom_set;
1099     api->flush = _ewk_view_smart_flush;
1100     api->pre_render_region = _ewk_view_smart_pre_render_region;
1101     api->pre_render_relative_radius = _ewk_view_smart_pre_render_relative_radius;
1102     api->pre_render_cancel = _ewk_view_smart_pre_render_cancel;
1103     api->disable_render = _ewk_view_smart_disable_render;
1104     api->enable_render = _ewk_view_smart_enable_render;
1105
1106     api->focus_in = _ewk_view_smart_focus_in;
1107     api->focus_out = _ewk_view_smart_focus_out;
1108     api->mouse_wheel = _ewk_view_smart_mouse_wheel;
1109     api->mouse_down = _ewk_view_smart_mouse_down;
1110     api->mouse_up = _ewk_view_smart_mouse_up;
1111     api->mouse_move = _ewk_view_smart_mouse_move;
1112     api->key_down = _ewk_view_smart_key_down;
1113     api->key_up = _ewk_view_smart_key_up;
1114
1115     api->add_console_message = _ewk_view_smart_add_console_message;
1116     api->run_javascript_alert = _ewk_view_smart_run_javascript_alert;
1117     api->run_javascript_confirm = _ewk_view_smart_run_javascript_confirm;
1118     api->run_javascript_prompt = _ewk_view_smart_run_javascript_prompt;
1119     api->should_interrupt_javascript = _ewk_view_smart_should_interrupt_javascript;
1120
1121     return EINA_TRUE;
1122 }
1123
1124 void ewk_view_fixed_layout_size_set(Evas_Object* ewkView, Evas_Coord width, Evas_Coord height)
1125 {
1126     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
1127     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv);
1128
1129     WebCore::FrameView* view = priv->mainFrame->view();
1130     if (width <= 0 && height <= 0) {
1131         if (!view->useFixedLayout())
1132             return;
1133         view->setUseFixedLayout(EINA_FALSE);
1134     } else {
1135         WebCore::IntSize size = view->fixedLayoutSize();
1136         if (size.width() == width && size.height() == height)
1137             return;
1138         if (view)
1139             view->setFixedLayoutSize(WebCore::IntSize(width, height));
1140     }
1141
1142     if (!view)
1143         return;
1144     view->setUseFixedLayout(EINA_TRUE);
1145     view->forceLayout();
1146 }
1147
1148 void ewk_view_fixed_layout_size_get(const Evas_Object* ewkView, Evas_Coord* width, Evas_Coord* height)
1149 {
1150     if (width)
1151         *width = 0;
1152     if (height)
1153         *height = 0;
1154     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
1155     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv);
1156     WebCore::FrameView* view = priv->mainFrame->view();
1157     if (view->useFixedLayout()) {
1158         WebCore::IntSize size = view->fixedLayoutSize();
1159         if (width)
1160             *width = size.width();
1161         if (height)
1162             *height = size.height();
1163     }
1164 }
1165
1166 void ewk_view_theme_set(Evas_Object* ewkView, const char* path)
1167 {
1168     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
1169     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv);
1170     if (!eina_stringshare_replace(&priv->settings.theme, path))
1171         return;
1172
1173     WebCore::FrameView* view = priv->mainFrame->view();
1174     if (view) {
1175         view->setEdjeTheme(WTF::String(path));
1176         priv->page->theme()->themeChanged();
1177     }
1178
1179 }
1180
1181 const char* ewk_view_theme_get(const Evas_Object* ewkView)
1182 {
1183     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
1184     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0);
1185     return priv->settings.theme;
1186 }
1187
1188 Evas_Object* ewk_view_frame_main_get(const Evas_Object* ewkView)
1189 {
1190     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
1191     return smartData->main_frame;
1192 }
1193
1194 Evas_Object* ewk_view_frame_focused_get(const Evas_Object* ewkView)
1195 {
1196     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
1197     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0);
1198
1199     WebCore::Frame* core = priv->page->focusController()->focusedFrame();
1200     if (!core)
1201         return 0;
1202
1203     WebCore::FrameLoaderClientEfl* client = static_cast<WebCore::FrameLoaderClientEfl*>(core->loader()->client());
1204     if (!client)
1205         return 0;
1206     return client->webFrame();
1207 }
1208
1209 Eina_Bool ewk_view_uri_set(Evas_Object* ewkView, const char* uri)
1210 {
1211     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1212     return ewk_frame_uri_set(smartData->main_frame, uri);
1213 }
1214
1215 const char* ewk_view_uri_get(const Evas_Object* ewkView)
1216 {
1217     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
1218     return ewk_frame_uri_get(smartData->main_frame);
1219 }
1220
1221 const char* ewk_view_title_get(const Evas_Object* ewkView)
1222 {
1223     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
1224     return ewk_frame_title_get(smartData->main_frame);
1225 }
1226
1227 Eina_Bool ewk_view_editable_get(const Evas_Object* ewkView)
1228 {
1229     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1230     return ewk_frame_editable_get(smartData->main_frame);
1231 }
1232
1233 void ewk_view_bg_color_set(Evas_Object* ewkView, int red, int green, int blue, int alpha)
1234 {
1235     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
1236     EINA_SAFETY_ON_NULL_RETURN(smartData->api);
1237     EINA_SAFETY_ON_NULL_RETURN(smartData->api->bg_color_set);
1238
1239     if (alpha < 0) {
1240         WRN("Alpha less than zero (%d).", alpha);
1241         alpha = 0;
1242     } else if (alpha > 255) {
1243         WRN("Alpha is larger than 255 (%d).", alpha);
1244         alpha = 255;
1245     }
1246
1247 #define CHECK_PREMUL_COLOR(color, alpha)                                        \
1248     if (color < 0) {                                                        \
1249         WRN("Color component " #color " is less than zero (%d).", color);         \
1250         color = 0;                                                          \
1251     } else if (color > alpha) {                                                 \
1252         WRN("Color component " #color " is greater than alpha (%d, alpha=%d).", \
1253             color, alpha);                                                      \
1254         color = alpha;                                                          \
1255     }
1256     CHECK_PREMUL_COLOR(red, alpha);
1257     CHECK_PREMUL_COLOR(green, alpha);
1258     CHECK_PREMUL_COLOR(blue, alpha);
1259 #undef CHECK_PREMUL_COLOR
1260
1261     smartData->bg_color.r = red;
1262     smartData->bg_color.g = green;
1263     smartData->bg_color.b = blue;
1264     smartData->bg_color.a = alpha;
1265
1266     smartData->api->bg_color_set(smartData, red, green, blue, alpha);
1267
1268     WebCore::FrameView* view = smartData->_priv->mainFrame->view();
1269     if (view) {
1270         WebCore::Color color;
1271
1272         if (!alpha)
1273             color = WebCore::Color(0, 0, 0, 0);
1274         else if (alpha == 255)
1275             color = WebCore::Color(red, green, blue, alpha);
1276         else
1277             color = WebCore::Color(red * 255 / alpha, green * 255 / alpha, blue * 255 / alpha, alpha);
1278
1279         view->updateBackgroundRecursively(color, !alpha);
1280     }
1281 }
1282
1283 void ewk_view_bg_color_get(const Evas_Object* ewkView, int* red, int* green, int* blue, int* alpha)
1284 {
1285     if (red)
1286         *red = 0;
1287     if (green)
1288         *green = 0;
1289     if (blue)
1290         *blue = 0;
1291     if (alpha)
1292         *alpha = 0;
1293     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
1294     if (red)
1295         *red = smartData->bg_color.r;
1296     if (green)
1297         *green = smartData->bg_color.g;
1298     if (blue)
1299         *blue = smartData->bg_color.b;
1300     if (alpha)
1301         *alpha = smartData->bg_color.a;
1302 }
1303
1304 Eina_Bool ewk_view_text_search(const Evas_Object* ewkView, const char* string, Eina_Bool caseSensitive, Eina_Bool forward, Eina_Bool wrap)
1305 {
1306     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1307     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
1308     EINA_SAFETY_ON_NULL_RETURN_VAL(string, EINA_FALSE);
1309     WTF::TextCaseSensitivity sensitive;
1310     WebCore::FindDirection direction;
1311
1312     if (caseSensitive)
1313         sensitive = WTF::TextCaseSensitive;
1314     else
1315         sensitive = WTF::TextCaseInsensitive;
1316
1317     if (forward)
1318         direction = WebCore::FindDirectionForward;
1319     else
1320         direction = WebCore::FindDirectionBackward;
1321
1322     return priv->page->findString(String::fromUTF8(string), sensitive, direction, wrap);
1323 }
1324
1325 /**
1326  * Mark matches the given text string in document.
1327  *
1328  * @param ewkView view object where to search text.
1329  * @param string reference string to match.
1330  * @param caseSensitive if match should be case sensitive or not.
1331  * @param heightighlight if matches should be highlighted.
1332  * @param limit maximum amount of matches, or zero to unlimited.
1333  *
1334  * @return number of matches.
1335  */
1336 unsigned int ewk_view_text_matches_mark(Evas_Object* ewkView, const char* string, Eina_Bool caseSensitive, Eina_Bool highlight, unsigned int limit)
1337 {
1338     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
1339     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0);
1340     EINA_SAFETY_ON_NULL_RETURN_VAL(string, 0);
1341     WTF::TextCaseSensitivity sensitive;
1342
1343     if (caseSensitive)
1344         sensitive = WTF::TextCaseSensitive;
1345     else
1346         sensitive = WTF::TextCaseInsensitive;
1347
1348     return priv->page->markAllMatchesForText(String::fromUTF8(string), sensitive, highlight, limit);
1349 }
1350
1351 Eina_Bool ewk_view_text_matches_unmark_all(Evas_Object* ewkView)
1352 {
1353     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1354     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
1355     priv->page->unmarkAllTextMatches();
1356     return EINA_TRUE;
1357 }
1358
1359 Eina_Bool ewk_view_text_matches_highlight_set(Evas_Object* ewkView, Eina_Bool highlight)
1360 {
1361     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1362     return ewk_frame_text_matches_highlight_set(smartData->main_frame, highlight);
1363 }
1364
1365 Eina_Bool ewk_view_text_matches_highlight_get(const Evas_Object* ewkView)
1366 {
1367     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1368     return ewk_frame_text_matches_highlight_get(smartData->main_frame);
1369 }
1370
1371 Eina_Bool ewk_view_editable_set(Evas_Object* ewkView, Eina_Bool editable)
1372 {
1373     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1374     return ewk_frame_editable_set(smartData->main_frame, editable);
1375 }
1376
1377 char* ewk_view_selection_get(const Evas_Object* ewkView)
1378 {
1379     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
1380     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0);
1381     CString selectedString = priv->page->focusController()->focusedOrMainFrame()->editor()->selectedText().utf8();
1382     if (selectedString.isNull())
1383         return 0;
1384     return strdup(selectedString.data());
1385 }
1386
1387 static Eina_Bool _ewk_view_editor_command(Ewk_View_Private_Data* priv, const char* command, const char* value = 0)
1388 {
1389     return priv->page->focusController()->focusedOrMainFrame()->editor()->command(WTF::String::fromUTF8(command)).execute(value);
1390 }
1391
1392 Eina_Bool ewk_view_execute_editor_command(Evas_Object* ewkView, const Ewk_Editor_Command command, const char* value)
1393 {
1394     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1395     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
1396
1397     switch (command) {
1398     case EWK_EDITOR_COMMAND_INSERT_IMAGE:
1399         return _ewk_view_editor_command(priv, "InsertImage", value);
1400     case EWK_EDITOR_COMMAND_INSERT_TEXT:
1401         return _ewk_view_editor_command(priv, "InsertText", value);
1402     case EWK_EDITOR_COMMAND_SELECT_NONE:
1403         return _ewk_view_editor_command(priv, "Unselect");
1404     case EWK_EDITOR_COMMAND_SELECT_ALL:
1405         return _ewk_view_editor_command(priv, "SelectAll");
1406     case EWK_EDITOR_COMMAND_SELECT_PARAGRAPH:
1407         return _ewk_view_editor_command(priv, "SelectParagraph");
1408     case EWK_EDITOR_COMMAND_SELECT_SENTENCE:
1409         return _ewk_view_editor_command(priv, "SelectSentence");
1410     case EWK_EDITOR_COMMAND_SELECT_LINE:
1411         return _ewk_view_editor_command(priv, "SelectLine");
1412     case EWK_EDITOR_COMMAND_SELECT_WORD:
1413         return _ewk_view_editor_command(priv, "SelectWord");
1414     default:
1415         return EINA_FALSE;
1416     }
1417 }
1418
1419 Eina_Bool ewk_view_context_menu_forward_event(Evas_Object* ewkView, const Evas_Event_Mouse_Down* downEvent)
1420 {
1421 #if ENABLE(CONTEXT_MENUS)
1422     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1423     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
1424     Eina_Bool mouse_press_handled = EINA_FALSE;
1425
1426     priv->page->contextMenuController()->clearContextMenu();
1427     WebCore::Frame* mainFrame = priv->page->mainFrame();
1428     Evas_Coord x, y;
1429     evas_object_geometry_get(smartData->self, &x, &y, 0, 0);
1430
1431     WebCore::PlatformMouseEvent event(downEvent, WebCore::IntPoint(x, y));
1432
1433     if (mainFrame->view()) {
1434         mouse_press_handled =
1435             mainFrame->eventHandler()->handleMousePressEvent(event);
1436     }
1437
1438     if (mainFrame->eventHandler()->sendContextMenuEvent(event))
1439         return EINA_FALSE;
1440
1441     WebCore::ContextMenu* coreMenu =
1442         priv->page->contextMenuController()->contextMenu();
1443     if (!coreMenu) {
1444         // WebCore decided not to create a context menu, return true if event
1445         // was handled by handleMouseReleaseEvent
1446         return mouse_press_handled;
1447     }
1448
1449     return EINA_TRUE;
1450 #else
1451     return EINA_FALSE;
1452 #endif
1453 }
1454
1455 double ewk_view_load_progress_get(const Evas_Object* ewkView)
1456 {
1457     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, -1.0);
1458     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, -1.0);
1459     return priv->page->progress()->estimatedProgress();
1460 }
1461
1462 Eina_Bool ewk_view_stop(Evas_Object* ewkView)
1463 {
1464     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1465     return ewk_frame_stop(smartData->main_frame);
1466 }
1467
1468 Eina_Bool ewk_view_reload(Evas_Object* ewkView)
1469 {
1470     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1471     return ewk_frame_reload(smartData->main_frame);
1472 }
1473
1474 Eina_Bool ewk_view_reload_full(Evas_Object* ewkView)
1475 {
1476     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1477     return ewk_frame_reload_full(smartData->main_frame);
1478 }
1479
1480 Eina_Bool ewk_view_back(Evas_Object* ewkView)
1481 {
1482     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1483     return ewk_frame_back(smartData->main_frame);
1484 }
1485
1486 Eina_Bool ewk_view_forward(Evas_Object* ewkView)
1487 {
1488     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1489     return ewk_frame_forward(smartData->main_frame);
1490 }
1491
1492 Eina_Bool ewk_view_navigate(Evas_Object* ewkView, int steps)
1493 {
1494     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1495     return ewk_frame_navigate(smartData->main_frame, steps);
1496 }
1497
1498 Eina_Bool ewk_view_back_possible(Evas_Object* ewkView)
1499 {
1500     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1501     return ewk_frame_back_possible(smartData->main_frame);
1502 }
1503
1504 Eina_Bool ewk_view_forward_possible(Evas_Object* ewkView)
1505 {
1506     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1507     return ewk_frame_forward_possible(smartData->main_frame);
1508 }
1509
1510 Eina_Bool ewk_view_navigate_possible(Evas_Object* ewkView, int steps)
1511 {
1512     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1513     return ewk_frame_navigate_possible(smartData->main_frame, steps);
1514 }
1515
1516 Eina_Bool ewk_view_history_enable_get(const Evas_Object* ewkView)
1517 {
1518     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1519     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
1520     return static_cast<WebCore::BackForwardListImpl*>(priv->page->backForwardList())->enabled();
1521 }
1522
1523 Eina_Bool ewk_view_history_enable_set(Evas_Object* ewkView, Eina_Bool enable)
1524 {
1525     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1526     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
1527     static_cast<WebCore::BackForwardListImpl*>(priv->page->backForwardList())->setEnabled(enable);
1528     return EINA_TRUE;
1529 }
1530
1531 Ewk_History* ewk_view_history_get(const Evas_Object* ewkView)
1532 {
1533     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
1534     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0);
1535     if (!static_cast<WebCore::BackForwardListImpl*>(priv->page->backForwardList())->enabled()) {
1536         ERR("asked history, but it's disabled! Returning 0!");
1537         return 0;
1538     }
1539     return priv->history;
1540 }
1541
1542 float ewk_view_zoom_get(const Evas_Object* ewkView)
1543 {
1544     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, -1.0);
1545     return ewk_frame_page_zoom_get(smartData->main_frame);
1546 }
1547
1548 Eina_Bool ewk_view_zoom_set(Evas_Object* ewkView, float zoom, Evas_Coord centerX, Evas_Coord centerY)
1549 {
1550     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1551     EWK_VIEW_PRIV_GET(smartData, priv);
1552
1553     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->api, EINA_FALSE);
1554     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->api->zoom_set, EINA_FALSE);
1555
1556     if (!priv->settings.zoomRange.userScalable) {
1557         WRN("userScalable is false");
1558         return EINA_FALSE;
1559     }
1560
1561     if (zoom < priv->settings.zoomRange.minScale) {
1562         WRN("zoom level is < %f : %f", priv->settings.zoomRange.minScale, zoom);
1563         return EINA_FALSE;
1564     }
1565     if (zoom > priv->settings.zoomRange.maxScale) {
1566         WRN("zoom level is > %f : %f", priv->settings.zoomRange.maxScale, zoom);
1567         return EINA_FALSE;
1568     }
1569
1570     _ewk_view_zoom_animated_mark_stop(smartData);
1571     return smartData->api->zoom_set(smartData, zoom, centerX, centerY);
1572 }
1573
1574 float ewk_view_page_zoom_get(const Evas_Object* ewkView)
1575 {
1576     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, -1.0);
1577     return ewk_frame_page_zoom_get(smartData->main_frame);
1578 }
1579
1580 Eina_Bool ewk_view_page_zoom_set(Evas_Object* ewkView, float pageZoomFactor)
1581 {
1582     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1583     return ewk_frame_page_zoom_set(smartData->main_frame, pageZoomFactor);
1584 }
1585
1586 float ewk_view_scale_get(const Evas_Object* ewkView)
1587 {
1588     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, -1.0);
1589     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, -1.0);
1590     return priv->page->pageScaleFactor();
1591 }
1592
1593 Eina_Bool ewk_view_scale_set(Evas_Object* ewkView, float scaleFactor, Evas_Coord centerX, Evas_Coord centerY)
1594 {
1595     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1596     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
1597
1598     float currentScaleFactor = ewk_view_scale_get(ewkView);
1599     if (currentScaleFactor == -1)
1600         return EINA_FALSE;
1601
1602     int x, y;
1603     ewk_frame_scroll_pos_get(smartData->main_frame, &x, &y);
1604
1605     x = static_cast<int>(((x + centerX) / currentScaleFactor) * scaleFactor) - centerX;
1606     y = static_cast<int>(((y + centerY) / currentScaleFactor) * scaleFactor) - centerY;
1607     priv->page->setPageScaleFactor(scaleFactor, WebCore::LayoutPoint(x, y));
1608     return EINA_TRUE;
1609 }
1610
1611 float ewk_view_text_zoom_get(const Evas_Object* ewkView)
1612 {
1613     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, -1.0);
1614     return ewk_frame_text_zoom_get(smartData->main_frame);
1615 }
1616
1617 Eina_Bool ewk_view_text_zoom_set(Evas_Object* ewkView, float textZoomFactor)
1618 {
1619     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1620     return ewk_frame_text_zoom_set(smartData->main_frame, textZoomFactor);
1621 }
1622
1623 Eina_Bool ewk_view_zoom_weak_smooth_scale_get(const Evas_Object* ewkView)
1624 {
1625     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1626     return smartData->zoom_weak_smooth_scale;
1627 }
1628
1629 void ewk_view_zoom_weak_smooth_scale_set(Evas_Object* ewkView, Eina_Bool smoothScale)
1630 {
1631     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
1632     smoothScale = !!smoothScale;
1633     if (smartData->zoom_weak_smooth_scale == smoothScale)
1634         return;
1635     smartData->zoom_weak_smooth_scale = smoothScale;
1636     EINA_SAFETY_ON_NULL_RETURN(smartData->api);
1637     EINA_SAFETY_ON_NULL_RETURN(smartData->api->zoom_weak_smooth_scale_set);
1638     smartData->api->zoom_weak_smooth_scale_set(smartData, smoothScale);
1639 }
1640
1641 Eina_Bool ewk_view_zoom_weak_set(Evas_Object* ewkView, float zoom, Evas_Coord centerX, Evas_Coord centerY)
1642 {
1643     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1644     EWK_VIEW_PRIV_GET(smartData, priv);
1645
1646     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->api, EINA_FALSE);
1647     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->api->zoom_weak_set, EINA_FALSE);
1648
1649     if (!priv->settings.zoomRange.userScalable) {
1650         WRN("userScalable is false");
1651         return EINA_FALSE;
1652     }
1653
1654     if (zoom < priv->settings.zoomRange.minScale) {
1655         WRN("zoom level is < %f : %f", priv->settings.zoomRange.minScale, zoom);
1656         return EINA_FALSE;
1657     }
1658     if (zoom > priv->settings.zoomRange.maxScale) {
1659         WRN("zoom level is > %f : %f", priv->settings.zoomRange.maxScale, zoom);
1660         return EINA_FALSE;
1661     }
1662
1663     smartData->animated_zoom.zoom.start = ewk_frame_page_zoom_get(smartData->main_frame);
1664     smartData->animated_zoom.zoom.end = zoom;
1665     smartData->animated_zoom.zoom.current = zoom;
1666     return smartData->api->zoom_weak_set(smartData, zoom, centerX, centerY);
1667 }
1668
1669 Eina_Bool ewk_view_zoom_animated_mark_start(Evas_Object* ewkView, float zoom)
1670 {
1671     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1672     smartData->animated_zoom.zoom.start = zoom;
1673     return EINA_TRUE;
1674 }
1675
1676 Eina_Bool ewk_view_zoom_animated_mark_end(Evas_Object* ewkView, float zoom)
1677 {
1678     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1679     smartData->animated_zoom.zoom.end = zoom;
1680     return EINA_TRUE;
1681 }
1682
1683 Eina_Bool ewk_view_zoom_animated_mark_current(Evas_Object* ewkView, float zoom)
1684 {
1685     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1686     smartData->animated_zoom.zoom.current = zoom;
1687     return EINA_TRUE;
1688 }
1689
1690 Eina_Bool ewk_view_zoom_animated_mark_stop(Evas_Object* ewkView)
1691 {
1692     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1693     _ewk_view_zoom_animated_mark_stop(smartData);
1694     return EINA_TRUE;
1695 }
1696
1697 Eina_Bool ewk_view_zoom_animated_set(Evas_Object* ewkView, float zoom, float duration, Evas_Coord centerX, Evas_Coord centerY)
1698 {
1699     double now;
1700     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1701     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
1702     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->api, EINA_FALSE);
1703     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->api->zoom_weak_set, EINA_FALSE);
1704
1705     if (!priv->settings.zoomRange.userScalable) {
1706         WRN("userScalable is false");
1707         return EINA_FALSE;
1708     }
1709
1710     if (zoom < priv->settings.zoomRange.minScale) {
1711         WRN("zoom level is < %f : %f", priv->settings.zoomRange.minScale, zoom);
1712         return EINA_FALSE;
1713     }
1714     if (zoom > priv->settings.zoomRange.maxScale) {
1715         WRN("zoom level is > %f : %f", priv->settings.zoomRange.maxScale, zoom);
1716         return EINA_FALSE;
1717     }
1718
1719     if (priv->animatedZoom.animator)
1720         priv->animatedZoom.zoom.start = _ewk_view_zoom_animated_current(priv);
1721     else {
1722         priv->animatedZoom.zoom.start = ewk_frame_page_zoom_get(smartData->main_frame);
1723         _ewk_view_zoom_animation_start(smartData);
1724     }
1725
1726     if (centerX < 0)
1727         centerX = 0;
1728     if (centerY < 0)
1729         centerY = 0;
1730
1731     now = ecore_loop_time_get();
1732     priv->animatedZoom.time.start = now;
1733     priv->animatedZoom.time.end = now + duration;
1734     priv->animatedZoom.time.duration = duration;
1735     priv->animatedZoom.zoom.end = zoom;
1736     priv->animatedZoom.zoom.range = (priv->animatedZoom.zoom.end - priv->animatedZoom.zoom.start);
1737     priv->animatedZoom.center.x = centerX;
1738     priv->animatedZoom.center.y = centerY;
1739     smartData->animated_zoom.zoom.current = priv->animatedZoom.zoom.start;
1740     smartData->animated_zoom.zoom.start = priv->animatedZoom.zoom.start;
1741     smartData->animated_zoom.zoom.end = priv->animatedZoom.zoom.end;
1742
1743     return EINA_TRUE;
1744 }
1745
1746 Eina_Bool ewk_view_pre_render_region(Evas_Object* ewkView, Evas_Coord x, Evas_Coord y, Evas_Coord width, Evas_Coord height, float zoom)
1747 {
1748     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1749     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
1750     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->api->pre_render_region, EINA_FALSE);
1751     float cur_zoom;
1752     Evas_Coord contentsWidth, contentsHeight;
1753
1754     /* When doing animated zoom it's not possible to call pre-render since it
1755      * would screw up parameters that animation is currently using
1756      */
1757     if (priv->animatedZoom.animator)
1758         return EINA_FALSE;
1759
1760     cur_zoom = ewk_frame_page_zoom_get(smartData->main_frame);
1761
1762     if (cur_zoom < 0.00001)
1763         return EINA_FALSE;
1764     if (!ewk_frame_contents_size_get(smartData->main_frame, &contentsWidth, &contentsHeight))
1765         return EINA_FALSE;
1766
1767     contentsWidth *= zoom / cur_zoom;
1768     contentsHeight *= zoom / cur_zoom;
1769     DBG("region %d,%d+%dx%d @ %f contents=%dx%d", x, y, width, height, zoom, contentsWidth, contentsHeight);
1770
1771     if (x + width > contentsWidth)
1772         width = contentsWidth - x;
1773
1774     if (y + height > contentsHeight)
1775         height = contentsHeight - y;
1776
1777     if (x < 0) {
1778         width += x;
1779         x = 0;
1780     }
1781     if (y < 0) {
1782         height += y;
1783         y = 0;
1784     }
1785
1786     return smartData->api->pre_render_region(smartData, x, y, width, height, zoom);
1787 }
1788
1789 Eina_Bool ewk_view_pre_render_relative_radius(Evas_Object* ewkView, unsigned int number)
1790 {
1791     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1792     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
1793     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->api->pre_render_relative_radius, EINA_FALSE);
1794     float currentZoom;
1795
1796     if (priv->animatedZoom.animator)
1797         return EINA_FALSE;
1798
1799     currentZoom = ewk_frame_page_zoom_get(smartData->main_frame);
1800     return smartData->api->pre_render_relative_radius(smartData, number, currentZoom);
1801 }
1802
1803 unsigned int ewk_view_imh_get(const Evas_Object* ewkView)
1804 {
1805     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
1806     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0);
1807     return priv->imh;
1808 }
1809
1810 void ewk_view_pre_render_cancel(Evas_Object* ewkView)
1811 {
1812     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
1813     EINA_SAFETY_ON_NULL_RETURN(smartData->api->pre_render_cancel);
1814     smartData->api->pre_render_cancel(smartData);
1815 }
1816
1817 Eina_Bool ewk_view_enable_render(const Evas_Object* ewkView)
1818 {
1819     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1820     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->api->enable_render, EINA_FALSE);
1821     return smartData->api->enable_render(smartData);
1822 }
1823
1824 Eina_Bool ewk_view_disable_render(const Evas_Object* ewkView)
1825 {
1826     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1827     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->api->disable_render, EINA_FALSE);
1828     return smartData->api->disable_render(smartData);
1829 }
1830
1831 const char* ewk_view_setting_user_agent_get(const Evas_Object* ewkView)
1832 {
1833     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
1834     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0);
1835     return priv->settings.userAgent;
1836 }
1837
1838 Eina_Bool ewk_view_setting_user_agent_set(Evas_Object* ewkView, const char* userAgent)
1839 {
1840     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1841     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
1842     if (eina_stringshare_replace(&priv->settings.userAgent, userAgent)) {
1843         WebCore::FrameLoaderClientEfl* client = static_cast<WebCore::FrameLoaderClientEfl*>(priv->mainFrame->loader()->client());
1844         client->setCustomUserAgent(String::fromUTF8(userAgent));
1845     }
1846     return EINA_TRUE;
1847 }
1848
1849 const char* ewk_view_setting_user_stylesheet_get(const Evas_Object* ewkView)
1850 {
1851     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
1852     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0);
1853     return priv->settings.userStylesheet;
1854 }
1855
1856 Eina_Bool ewk_view_setting_user_stylesheet_set(Evas_Object* ewkView, const char* uri)
1857 {
1858     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1859     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
1860     if (eina_stringshare_replace(&priv->settings.userStylesheet, uri)) {
1861         WebCore::KURL kurl(WebCore::KURL(), String::fromUTF8(uri));
1862         priv->pageSettings->setUserStyleSheetLocation(kurl);
1863     }
1864     return EINA_TRUE;
1865 }
1866
1867 Eina_Bool ewk_view_setting_auto_load_images_get(const Evas_Object* ewkView)
1868 {
1869     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1870     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
1871     return priv->settings.autoLoadImages;
1872 }
1873
1874 Eina_Bool ewk_view_setting_auto_load_images_set(Evas_Object* ewkView, Eina_Bool automatic)
1875 {
1876     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1877     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
1878     automatic = !!automatic;
1879     if (priv->settings.autoLoadImages != automatic) {
1880         priv->pageSettings->setLoadsImagesAutomatically(automatic);
1881         priv->settings.autoLoadImages = automatic;
1882     }
1883     return EINA_TRUE;
1884 }
1885
1886 Eina_Bool ewk_view_setting_auto_shrink_images_get(const Evas_Object* ewkView)
1887 {
1888     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1889     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
1890     return priv->settings.autoShrinkImages;
1891 }
1892
1893 Eina_Bool ewk_view_setting_auto_shrink_images_set(Evas_Object* ewkView, Eina_Bool automatic)
1894 {
1895     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1896     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
1897     automatic = !!automatic;
1898     if (priv->settings.autoShrinkImages != automatic) {
1899         priv->pageSettings->setShrinksStandaloneImagesToFit(automatic);
1900         priv->settings.autoShrinkImages = automatic;
1901     }
1902     return EINA_TRUE;
1903 }
1904
1905 Eina_Bool ewk_view_setting_enable_auto_resize_window_get(const Evas_Object* ewkView)
1906 {
1907     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1908     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
1909     return priv->settings.enableAutoResizeWindow;
1910 }
1911
1912 Eina_Bool ewk_view_setting_enable_auto_resize_window_set(Evas_Object* ewkView, Eina_Bool resizable)
1913 {
1914     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1915     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
1916     priv->settings.enableAutoResizeWindow = resizable;
1917     return EINA_TRUE;
1918 }
1919
1920 Eina_Bool ewk_view_setting_enable_scripts_get(const Evas_Object* ewkView)
1921 {
1922     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1923     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
1924     return priv->settings.enableScripts;
1925 }
1926
1927 Eina_Bool ewk_view_setting_enable_scripts_set(Evas_Object* ewkView, Eina_Bool enable)
1928 {
1929     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1930     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
1931     enable = !!enable;
1932     if (priv->settings.enableScripts != enable) {
1933         priv->pageSettings->setJavaScriptEnabled(enable);
1934         priv->settings.enableScripts = enable;
1935     }
1936     return EINA_TRUE;
1937 }
1938
1939 Eina_Bool ewk_view_setting_enable_plugins_get(const Evas_Object* ewkView)
1940 {
1941     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1942     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
1943     return priv->settings.enablePlugins;
1944 }
1945
1946 Eina_Bool ewk_view_setting_enable_plugins_set(Evas_Object* ewkView, Eina_Bool enable)
1947 {
1948     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1949     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
1950     enable = !!enable;
1951     if (priv->settings.enablePlugins != enable) {
1952         priv->pageSettings->setPluginsEnabled(enable);
1953         priv->settings.enablePlugins = enable;
1954     }
1955     return EINA_TRUE;
1956 }
1957
1958 Eina_Bool ewk_view_setting_enable_frame_flattening_get(const Evas_Object* ewkView)
1959 {
1960     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1961     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
1962     return priv->settings.enableFrameFlattening;
1963 }
1964
1965 Eina_Bool ewk_view_setting_enable_frame_flattening_set(Evas_Object* ewkView, Eina_Bool enable)
1966 {
1967     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1968     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
1969     enable = !!enable;
1970     if (priv->settings.enableFrameFlattening != enable) {
1971         priv->pageSettings->setFrameFlatteningEnabled(enable);
1972         priv->settings.enableFrameFlattening = enable;
1973     }
1974     return EINA_TRUE;
1975 }
1976
1977 Eina_Bool ewk_view_setting_scripts_window_open_get(const Evas_Object* ewkView)
1978 {
1979     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1980     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
1981     return priv->settings.scriptsWindowOpen;
1982 }
1983
1984 Eina_Bool ewk_view_setting_scripts_window_open_set(Evas_Object* ewkView, Eina_Bool allow)
1985 {
1986     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1987     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
1988     allow = !!allow;
1989     if (priv->settings.scriptsWindowOpen != allow) {
1990         priv->pageSettings->setJavaScriptCanOpenWindowsAutomatically(allow);
1991         priv->settings.scriptsWindowOpen = allow;
1992     }
1993     return EINA_TRUE;
1994 }
1995
1996 Eina_Bool ewk_view_setting_scripts_can_close_windows_get(const Evas_Object* ewkView)
1997 {
1998     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
1999     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
2000     return priv->settings.scriptsCanCloseWindows;
2001 }
2002
2003 Eina_Bool ewk_view_setting_scripts_can_close_windows_set(Evas_Object* ewkView, Eina_Bool allow)
2004 {
2005     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
2006     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
2007     allow = !!allow;
2008     if (priv->settings.scriptsCanCloseWindows != allow) {
2009         priv->pageSettings->setAllowScriptsToCloseWindows(allow);
2010         priv->settings.scriptsCanCloseWindows = allow;
2011     }
2012     return EINA_TRUE;
2013 }
2014
2015 Eina_Bool ewk_view_setting_resizable_textareas_get(const Evas_Object* ewkView)
2016 {
2017     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
2018     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
2019     return priv->settings.resizableTextareas;
2020 }
2021
2022 Eina_Bool ewk_view_setting_resizable_textareas_set(Evas_Object* ewkView, Eina_Bool enable)
2023 {
2024     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
2025     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
2026     enable = !!enable;
2027     if (priv->settings.resizableTextareas != enable) {
2028         priv->pageSettings->setTextAreasAreResizable(enable);
2029         priv->settings.resizableTextareas = enable;
2030     }
2031     return EINA_TRUE;
2032 }
2033
2034 Eina_Bool ewk_view_setting_private_browsing_get(const Evas_Object* ewkView)
2035 {
2036     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
2037     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
2038     return priv->settings.privateBrowsing;
2039 }
2040
2041 Eina_Bool ewk_view_setting_private_browsing_set(Evas_Object* ewkView, Eina_Bool enable)
2042 {
2043     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
2044     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
2045     enable = !!enable;
2046     if (priv->settings.privateBrowsing != enable) {
2047         priv->pageSettings->setPrivateBrowsingEnabled(enable);
2048         priv->settings.privateBrowsing = enable;
2049     }
2050     return EINA_TRUE;
2051 }
2052
2053 Eina_Bool ewk_view_setting_offline_app_cache_get(const Evas_Object* ewkView)
2054 {
2055     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
2056     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
2057     return priv->settings.offlineAppCache;
2058 }
2059
2060 Eina_Bool ewk_view_setting_offline_app_cache_set(Evas_Object* ewkView, Eina_Bool enable)
2061 {
2062     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
2063     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
2064     enable = !!enable;
2065     if (priv->settings.offlineAppCache != enable) {
2066         priv->pageSettings->setOfflineWebApplicationCacheEnabled(enable);
2067         priv->settings.offlineAppCache = enable;
2068     }
2069     return EINA_TRUE;
2070 }
2071
2072
2073 Eina_Bool ewk_view_setting_caret_browsing_get(const Evas_Object* ewkView)
2074 {
2075     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
2076     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
2077     return priv->settings.caretBrowsing;
2078 }
2079
2080 Eina_Bool ewk_view_setting_caret_browsing_set(Evas_Object* ewkView, Eina_Bool enable)
2081 {
2082     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
2083     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
2084     enable = !!enable;
2085     if (priv->settings.caretBrowsing != enable) {
2086         priv->pageSettings->setCaretBrowsingEnabled(enable);
2087         priv->settings.caretBrowsing = enable;
2088     }
2089     return EINA_TRUE;
2090 }
2091
2092 const char* ewk_view_setting_encoding_custom_get(const Evas_Object* ewkView)
2093 {
2094     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
2095     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0);
2096     Evas_Object* main_frame = ewk_view_frame_main_get(ewkView);
2097     WebCore::Frame* core_frame = EWKPrivate::coreFrame(main_frame);
2098
2099     String overrideEncoding = core_frame->loader()->documentLoader()->overrideEncoding();
2100
2101     if (overrideEncoding.isEmpty())
2102         return 0;
2103
2104     eina_stringshare_replace(&priv->settings.encodingCustom, overrideEncoding.utf8().data());
2105     return priv->settings.encodingCustom;
2106 }
2107
2108 Eina_Bool ewk_view_setting_encoding_custom_set(Evas_Object* ewkView, const char* encoding)
2109 {
2110     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
2111     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
2112     Evas_Object* main_frame = ewk_view_frame_main_get(ewkView);
2113     WebCore::Frame* coreFrame = EWKPrivate::coreFrame(main_frame);
2114     DBG("%s", encoding);
2115     if (eina_stringshare_replace(&priv->settings.encodingCustom, encoding))
2116         coreFrame->loader()->reloadWithOverrideEncoding(String::fromUTF8(encoding));
2117     return EINA_TRUE;
2118 }
2119
2120 const char* ewk_view_setting_encoding_default_get(const Evas_Object* ewkView)
2121 {
2122     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
2123     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0);
2124     return priv->settings.encodingDefault;
2125 }
2126
2127 Eina_Bool ewk_view_setting_encoding_default_set(Evas_Object* ewkView, const char* encoding)
2128 {
2129     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
2130     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
2131     if (eina_stringshare_replace(&priv->settings.encodingDefault, encoding))
2132         priv->pageSettings->setDefaultTextEncodingName(String::fromUTF8(encoding));
2133     return EINA_TRUE;
2134 }
2135
2136 Eina_Bool ewk_view_setting_encoding_detector_set(Evas_Object* ewkView, Eina_Bool enable)
2137 {
2138     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
2139     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
2140     enable = !!enable;
2141     if (priv->settings.encodingDetector != enable) {
2142         priv->pageSettings->setUsesEncodingDetector(enable);
2143         priv->settings.encodingDetector = enable;
2144     }
2145     return EINA_TRUE;
2146 }
2147
2148 Eina_Bool ewk_view_setting_encoding_detector_get(const Evas_Object* ewkView)
2149 {
2150     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
2151     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
2152     return priv->settings.encodingDetector;
2153 }
2154
2155 Eina_Bool ewk_view_setting_enable_developer_extras_get(const Evas_Object* ewkView)
2156 {
2157     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
2158     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
2159     return priv->settings.enableDeveloperExtras;
2160 }
2161
2162 Eina_Bool ewk_view_setting_enable_developer_extras_set(Evas_Object* ewkView, Eina_Bool enable)
2163 {
2164     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
2165     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
2166     enable = !!enable;
2167     if (priv->settings.enableDeveloperExtras != enable) {
2168         priv->pageSettings->setDeveloperExtrasEnabled(enable);
2169         priv->settings.enableDeveloperExtras = enable;
2170     }
2171     return EINA_TRUE;
2172 }
2173
2174 int ewk_view_setting_font_minimum_size_get(const Evas_Object* ewkView)
2175 {
2176     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
2177     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0);
2178     return priv->settings.fontMinimumSize;
2179 }
2180
2181 Eina_Bool ewk_view_setting_font_minimum_size_set(Evas_Object* ewkView, int size)
2182 {
2183     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
2184     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
2185     if (priv->settings.fontMinimumSize != size) {
2186         priv->pageSettings->setMinimumFontSize(size);
2187         priv->settings.fontMinimumSize = size;
2188     }
2189     return EINA_TRUE;
2190 }
2191
2192 int ewk_view_setting_font_minimum_logical_size_get(const Evas_Object* ewkView)
2193 {
2194     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
2195     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0);
2196     return priv->settings.fontMinimumLogicalSize;
2197 }
2198
2199 Eina_Bool ewk_view_setting_font_minimum_logical_size_set(Evas_Object* ewkView, int size)
2200 {
2201     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
2202     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
2203     if (priv->settings.fontMinimumLogicalSize != size) {
2204         priv->pageSettings->setMinimumLogicalFontSize(size);
2205         priv->settings.fontMinimumLogicalSize = size;
2206     }
2207     return EINA_TRUE;
2208 }
2209
2210 int ewk_view_setting_font_default_size_get(const Evas_Object* ewkView)
2211 {
2212     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
2213     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0);
2214     return priv->settings.fontDefaultSize;
2215 }
2216
2217 Eina_Bool ewk_view_setting_font_default_size_set(Evas_Object* ewkView, int size)
2218 {
2219     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
2220     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
2221     if (priv->settings.fontDefaultSize != size) {
2222         priv->pageSettings->setDefaultFontSize(size);
2223         priv->settings.fontDefaultSize = size;
2224     }
2225     return EINA_TRUE;
2226 }
2227
2228 int ewk_view_setting_font_monospace_size_get(const Evas_Object* ewkView)
2229 {
2230     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
2231     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0);
2232     return priv->settings.fontMonospaceSize;
2233 }
2234
2235 Eina_Bool ewk_view_setting_font_monospace_size_set(Evas_Object* ewkView, int size)
2236 {
2237     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
2238     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
2239     if (priv->settings.fontMonospaceSize != size) {
2240         priv->pageSettings->setDefaultFixedFontSize(size);
2241         priv->settings.fontMonospaceSize = size;
2242     }
2243     return EINA_TRUE;
2244 }
2245
2246 const char* ewk_view_font_family_name_get(const Evas_Object* ewkView, Ewk_Font_Family fontFamily)
2247 {
2248     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
2249     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0);
2250
2251     switch (fontFamily) {
2252     case EWK_FONT_FAMILY_STANDARD:
2253         return priv->settings.fontStandard;
2254     case EWK_FONT_FAMILY_CURSIVE:
2255         return priv->settings.fontCursive;
2256     case EWK_FONT_FAMILY_FANTASY:
2257         return priv->settings.fontFantasy;
2258     case EWK_FONT_FAMILY_MONOSPACE:
2259         return priv->settings.fontMonospace;
2260     case EWK_FONT_FAMILY_SERIF:
2261         return priv->settings.fontSerif;
2262     case EWK_FONT_FAMILY_SANS_SERIF:
2263         return priv->settings.fontSansSerif;
2264     }
2265     return 0;
2266 }
2267
2268 Eina_Bool ewk_view_font_family_name_set(Evas_Object* ewkView, Ewk_Font_Family fontFamily, const char* name)
2269 {
2270     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
2271     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
2272
2273     switch (fontFamily) {
2274     case EWK_FONT_FAMILY_STANDARD:
2275         if (eina_stringshare_replace(&priv->settings.fontStandard, name))
2276             priv->pageSettings->setStandardFontFamily(AtomicString::fromUTF8(name));
2277         break;
2278     case EWK_FONT_FAMILY_CURSIVE:
2279         if (eina_stringshare_replace(&priv->settings.fontCursive, name))
2280             priv->pageSettings->setCursiveFontFamily(AtomicString::fromUTF8(name));
2281         break;
2282     case EWK_FONT_FAMILY_FANTASY:
2283         if (eina_stringshare_replace(&priv->settings.fontFantasy, name))
2284             priv->pageSettings->setFantasyFontFamily(AtomicString::fromUTF8(name));
2285         break;
2286     case EWK_FONT_FAMILY_MONOSPACE:
2287         if (eina_stringshare_replace(&priv->settings.fontMonospace, name))
2288             priv->pageSettings->setFixedFontFamily(AtomicString::fromUTF8(name));
2289         break;
2290     case EWK_FONT_FAMILY_SERIF:
2291         if (eina_stringshare_replace(&priv->settings.fontSerif, name))
2292             priv->pageSettings->setSerifFontFamily(AtomicString::fromUTF8(name));
2293         break;
2294     case EWK_FONT_FAMILY_SANS_SERIF:
2295         if (eina_stringshare_replace(&priv->settings.fontSansSerif, name))
2296             priv->pageSettings->setSansSerifFontFamily(AtomicString::fromUTF8(name));
2297         break;
2298     default:
2299         return EINA_FALSE;
2300     }
2301
2302     return EINA_TRUE;
2303 }
2304
2305 Eina_Bool ewk_view_setting_spatial_navigation_get(const Evas_Object* ewkView)
2306 {
2307     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
2308     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
2309     return priv->settings.spatialNavigation;
2310 }
2311
2312 Eina_Bool ewk_view_setting_spatial_navigation_set(Evas_Object* ewkView, Eina_Bool enable)
2313 {
2314     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
2315     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
2316     enable = !!enable;
2317     if (priv->settings.spatialNavigation != enable) {
2318         priv->pageSettings->setSpatialNavigationEnabled(enable);
2319         priv->settings.spatialNavigation = enable;
2320     }
2321     return EINA_TRUE;
2322 }
2323
2324 Eina_Bool ewk_view_setting_local_storage_get(const Evas_Object* ewkView)
2325 {
2326     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
2327     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
2328     return priv->settings.localStorage;
2329 }
2330
2331 Eina_Bool ewk_view_setting_local_storage_set(Evas_Object* ewkView, Eina_Bool enable)
2332 {
2333     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
2334     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
2335     enable = !!enable;
2336     if (priv->settings.localStorage != enable) {
2337         priv->pageSettings->setLocalStorageEnabled(enable);
2338         priv->settings.localStorage = enable;
2339     }
2340     return EINA_TRUE;
2341 }
2342
2343 Eina_Bool ewk_view_setting_page_cache_get(const Evas_Object* ewkView)
2344 {
2345     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
2346     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
2347     return priv->settings.pageCache;
2348 }
2349
2350 Eina_Bool ewk_view_setting_page_cache_set(Evas_Object* ewkView, Eina_Bool enable)
2351 {
2352     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
2353     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
2354     enable = !!enable;
2355     if (priv->settings.pageCache != enable) {
2356         priv->pageSettings->setUsesPageCache(enable);
2357         priv->settings.pageCache = enable;
2358     }
2359     return EINA_TRUE;
2360 }
2361
2362 const char* ewk_view_setting_local_storage_database_path_get(const Evas_Object* ewkView)
2363 {
2364     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
2365     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0);
2366     return priv->settings.localStorageDatabasePath;
2367 }
2368
2369 Eina_Bool ewk_view_setting_local_storage_database_path_set(Evas_Object* ewkView, const char* path)
2370 {
2371     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
2372     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
2373     if (eina_stringshare_replace(&priv->settings.localStorageDatabasePath, path))
2374         priv->pageSettings->setLocalStorageDatabasePath(String::fromUTF8(path));
2375     return EINA_TRUE;
2376 }
2377
2378 Eina_Bool ewk_view_setting_minimum_timer_interval_set(Evas_Object* ewkView, double interval)
2379 {
2380     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
2381     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
2382     if (fabs(priv->settings.domTimerInterval - interval) >= std::numeric_limits<double>::epsilon()) {
2383         priv->pageSettings->setMinDOMTimerInterval(interval);
2384         priv->settings.domTimerInterval = interval;
2385     }
2386     return EINA_TRUE;
2387 }
2388
2389 double ewk_view_setting_minimum_timer_interval_get(const Evas_Object* ewkView)
2390 {
2391     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
2392     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
2393     return priv->settings.domTimerInterval;
2394 }
2395
2396 Ewk_View_Smart_Data* ewk_view_smart_data_get(const Evas_Object* ewkView)
2397 {
2398     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
2399     return smartData;
2400 }
2401
2402 /**
2403  * Gets the internal array of repaint requests.
2404  *
2405  * This array should not be modified anyhow. It should be processed
2406  * immediately as any further ewk_view call might change it, like
2407  * those that add repaints or flush them, so be sure that your code
2408  * does not call any of those while you process the repaints,
2409  * otherwise copy the array.
2410  *
2411  * @param priv private handle pointer of the view to get repaints.
2412  * @param count where to return the number of elements of returned array, may be @c 0.
2413  *
2414  * @return reference to array of requested repaints.
2415  *
2416  * @note this is not for general use but just for subclasses that want
2417  *       to define their own backing store.
2418  */
2419 const Eina_Rectangle* ewk_view_repaints_get(const Ewk_View_Private_Data* priv, size_t* count)
2420 {
2421     if (count)
2422         *count = 0;
2423     EINA_SAFETY_ON_NULL_RETURN_VAL(priv, 0);
2424     if (count)
2425         *count = priv->repaints.count;
2426     return priv->repaints.array;
2427 }
2428
2429 /**
2430  * Gets the internal array of scroll requests.
2431  *
2432  * This array should not be modified anyhow. It should be processed
2433  * immediately as any further ewk_view call might change it, like
2434  * those that add scrolls or flush them, so be sure that your code
2435  * does not call any of those while you process the scrolls,
2436  * otherwise copy the array.
2437  *
2438  * @param priv private handle pointer of the view to get scrolls.
2439  * @param count where to return the number of elements of returned array, may be @c 0.
2440  *
2441  * @return reference to array of requested scrolls.
2442  *
2443  * @note this is not for general use but just for subclasses that want
2444  *       to define their own backing store.
2445  */
2446 const Ewk_Scroll_Request* ewk_view_scroll_requests_get(const Ewk_View_Private_Data* priv, size_t* count)
2447 {
2448     if (count)
2449         *count = 0;
2450     EINA_SAFETY_ON_NULL_RETURN_VAL(priv, 0);
2451     if (count)
2452         *count = priv->scrolls.count;
2453     return priv->scrolls.array;
2454 }
2455
2456 /**
2457  * Add a new repaint request to queue.
2458  *
2459  * The repaints are assumed to be relative to current viewport.
2460  *
2461  * @param priv private handle pointer of the view to add repaint request.
2462  * @param x horizontal position relative to current view port (scrolled).
2463  * @param y vertical position relative to current view port (scrolled).
2464  * @param width width of area to be repainted
2465  * @param height height of area to be repainted
2466  *
2467  * @note this is not for general use but just for subclasses that want
2468  *       to define their own backing store.
2469  */
2470 void ewk_view_repaint_add(Ewk_View_Private_Data* priv, Evas_Coord x, Evas_Coord y, Evas_Coord width, Evas_Coord height)
2471 {
2472     EINA_SAFETY_ON_NULL_RETURN(priv);
2473     _ewk_view_repaint_add(priv, x, y, width, height);
2474 }
2475
2476 /**
2477  * Do layout if required, applied recursively.
2478  *
2479  * @param priv private handle pointer of the view to layout.
2480  *
2481  * @note this is not for general use but just for subclasses that want
2482  *       to define their own backing store.
2483  */
2484 void ewk_view_layout_if_needed_recursive(Ewk_View_Private_Data* priv)
2485 {
2486     EINA_SAFETY_ON_NULL_RETURN(priv);
2487
2488     WebCore::FrameView* view = priv->mainFrame->view();
2489     if (!view) {
2490         ERR("no main frame view");
2491         return;
2492     }
2493     view->updateLayoutAndStyleIfNeededRecursive();
2494 }
2495
2496 void ewk_view_scrolls_process(Ewk_View_Smart_Data* smartData)
2497 {
2498     EINA_SAFETY_ON_NULL_RETURN(smartData);
2499     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv);
2500     if (!smartData->api->scrolls_process(smartData))
2501         ERR("failed to process scrolls.");
2502     _ewk_view_scrolls_flush(priv);
2503 }
2504
2505 /**
2506  * @brief Structure that keeps the paint context.
2507  *
2508  * @internal
2509  *
2510  * @note This is not for general use but just for subclasses that want
2511  *       to define their own backing store.
2512  */
2513 struct _Ewk_View_Paint_Context {
2514     WebCore::GraphicsContext* graphicContext;
2515     WebCore::FrameView* view;
2516     cairo_t* cr;
2517 };
2518
2519 Ewk_View_Paint_Context* ewk_view_paint_context_new(Ewk_View_Private_Data* priv, cairo_t* cr)
2520 {
2521     EINA_SAFETY_ON_NULL_RETURN_VAL(priv, 0);
2522     EINA_SAFETY_ON_NULL_RETURN_VAL(cr, 0);
2523     EINA_SAFETY_ON_NULL_RETURN_VAL(priv->mainFrame, 0);
2524     WebCore::FrameView* view = priv->mainFrame->view();
2525     EINA_SAFETY_ON_NULL_RETURN_VAL(view, 0);
2526     Ewk_View_Paint_Context* context = static_cast<Ewk_View_Paint_Context*>(malloc(sizeof(*context)));
2527     EINA_SAFETY_ON_NULL_RETURN_VAL(context, 0);
2528
2529     context->graphicContext = new WebCore::GraphicsContext(cr);
2530     if (!context->graphicContext) {
2531         free(context);
2532         return 0;
2533     }
2534     context->view = view;
2535     context->cr = cairo_reference(cr);
2536     return context;
2537 }
2538
2539 void ewk_view_paint_context_free(Ewk_View_Paint_Context* context)
2540 {
2541     EINA_SAFETY_ON_NULL_RETURN(context);
2542     delete context->graphicContext;
2543     cairo_destroy(context->cr);
2544     free(context);
2545 }
2546
2547 void ewk_view_paint_context_save(Ewk_View_Paint_Context* context)
2548 {
2549     EINA_SAFETY_ON_NULL_RETURN(context);
2550     cairo_save(context->cr);
2551     context->graphicContext->save();
2552 }
2553
2554 void ewk_view_paint_context_restore(Ewk_View_Paint_Context* context)
2555 {
2556     EINA_SAFETY_ON_NULL_RETURN(context);
2557     context->graphicContext->restore();
2558     cairo_restore(context->cr);
2559 }
2560
2561 void ewk_view_paint_context_clip(Ewk_View_Paint_Context* context, const Eina_Rectangle* area)
2562 {
2563     EINA_SAFETY_ON_NULL_RETURN(context);
2564     EINA_SAFETY_ON_NULL_RETURN(area);
2565     context->graphicContext->clip(WebCore::IntRect(area->x, area->y, area->w, area->h));
2566 }
2567
2568 void ewk_view_paint_context_paint(Ewk_View_Paint_Context* context, const Eina_Rectangle* area)
2569 {
2570     EINA_SAFETY_ON_NULL_RETURN(context);
2571     EINA_SAFETY_ON_NULL_RETURN(area);
2572
2573     WebCore::IntRect rect(area->x, area->y, area->w, area->h);
2574
2575     if (context->view->isTransparent())
2576         context->graphicContext->clearRect(rect);
2577     context->view->paint(context->graphicContext, rect);
2578 }
2579
2580 void ewk_view_paint_context_paint_contents(Ewk_View_Paint_Context* context, const Eina_Rectangle* area)
2581 {
2582     EINA_SAFETY_ON_NULL_RETURN(context);
2583     EINA_SAFETY_ON_NULL_RETURN(area);
2584
2585     WebCore::IntRect rect(area->x, area->y, area->w, area->h);
2586
2587     if (context->view->isTransparent())
2588         context->graphicContext->clearRect(rect);
2589
2590     context->view->paintContents(context->graphicContext, rect);
2591 }
2592
2593 void ewk_view_paint_context_scale(Ewk_View_Paint_Context* context, float scaleX, float scaleY)
2594 {
2595     EINA_SAFETY_ON_NULL_RETURN(context);
2596
2597     context->graphicContext->scale(WebCore::FloatSize(scaleX, scaleY));
2598 }
2599
2600 void ewk_view_paint_context_translate(Ewk_View_Paint_Context* context, float x, float y)
2601 {
2602     EINA_SAFETY_ON_NULL_RETURN(context);
2603
2604     context->graphicContext->translate(x, y);
2605 }
2606
2607 Eina_Bool ewk_view_paint(Ewk_View_Private_Data* priv, cairo_t* cr, const Eina_Rectangle* area)
2608 {
2609     EINA_SAFETY_ON_NULL_RETURN_VAL(priv, EINA_FALSE);
2610     EINA_SAFETY_ON_NULL_RETURN_VAL(cr, EINA_FALSE);
2611     EINA_SAFETY_ON_NULL_RETURN_VAL(area, EINA_FALSE);
2612     WebCore::FrameView* view = priv->mainFrame->view();
2613     EINA_SAFETY_ON_NULL_RETURN_VAL(view, EINA_FALSE);
2614
2615     if (view->needsLayout())
2616         view->forceLayout();
2617     WebCore::GraphicsContext graphicsContext(cr);
2618     WebCore::IntRect rect(area->x, area->y, area->w, area->h);
2619
2620     cairo_save(cr);
2621     graphicsContext.save();
2622     graphicsContext.clip(rect);
2623     if (view->isTransparent())
2624         graphicsContext.clearRect(rect);
2625     view->paint(&graphicsContext, rect);
2626     graphicsContext.restore();
2627     cairo_restore(cr);
2628
2629     return EINA_TRUE;
2630 }
2631
2632 Eina_Bool ewk_view_paint_contents(Ewk_View_Private_Data* priv, cairo_t* cr, const Eina_Rectangle* area)
2633 {
2634     EINA_SAFETY_ON_NULL_RETURN_VAL(priv, EINA_FALSE);
2635     EINA_SAFETY_ON_NULL_RETURN_VAL(cr, EINA_FALSE);
2636     EINA_SAFETY_ON_NULL_RETURN_VAL(area, EINA_FALSE);
2637     WebCore::FrameView* view = priv->mainFrame->view();
2638     EINA_SAFETY_ON_NULL_RETURN_VAL(view, EINA_FALSE);
2639
2640     WebCore::GraphicsContext graphicsContext(cr);
2641     WebCore::IntRect rect(area->x, area->y, area->w, area->h);
2642
2643     cairo_save(cr);
2644     graphicsContext.save();
2645     graphicsContext.clip(rect);
2646     if (view->isTransparent())
2647         graphicsContext.clearRect(rect);
2648     view->paintContents(&graphicsContext,  rect);
2649     graphicsContext.restore();
2650     cairo_restore(cr);
2651
2652     return EINA_TRUE;
2653 }
2654
2655
2656 /* internal methods ****************************************************/
2657 /**
2658  * @internal
2659  * Reports the view is ready to be displayed as all elements are aready.
2660  *
2661  * Emits signal: "ready" with no parameters.
2662  */
2663 void ewk_view_ready(Evas_Object* ewkView)
2664 {
2665     DBG("ewkView=%p", ewkView);
2666     evas_object_smart_callback_call(ewkView, "ready", 0);
2667 }
2668
2669 /**
2670  * @internal
2671  * Reports the state of input method changed. This is triggered, for example
2672  * when a input field received/lost focus
2673  *
2674  * Emits signal: "inputmethod,changed" with a boolean indicating whether it's
2675  * enabled or not.
2676  */
2677 void ewk_view_input_method_state_set(Evas_Object* ewkView, Eina_Bool active)
2678 {
2679     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
2680     EWK_VIEW_PRIV_GET(smartData, priv);
2681     WebCore::Frame* focusedFrame = priv->page->focusController()->focusedOrMainFrame();
2682
2683     priv->imh = 0;
2684     if (focusedFrame
2685         && focusedFrame->document()
2686         && focusedFrame->document()->focusedNode()
2687         && focusedFrame->document()->focusedNode()->hasTagName(WebCore::HTMLNames::inputTag)) {
2688         WebCore::HTMLInputElement* inputElement;
2689
2690         inputElement = static_cast<WebCore::HTMLInputElement*>(focusedFrame->document()->focusedNode());
2691         if (inputElement) {
2692             // for password fields, active == false
2693             if (!active) {
2694                 active = inputElement->isPasswordField();
2695                 priv->imh = inputElement->isPasswordField() * EWK_IMH_PASSWORD;
2696             } else {
2697                 // Set input method hints for "number", "tel", "email", and "url" input elements.
2698                 priv->imh |= inputElement->isTelephoneField() * EWK_IMH_TELEPHONE;
2699                 priv->imh |= inputElement->isNumberField() * EWK_IMH_NUMBER;
2700                 priv->imh |= inputElement->isEmailField() * EWK_IMH_EMAIL;
2701                 priv->imh |= inputElement->isURLField() * EWK_IMH_URL;
2702             }
2703         }
2704     }
2705
2706     evas_object_smart_callback_call(ewkView, "inputmethod,changed", (void*)active);
2707 }
2708
2709 /**
2710  * @internal
2711  * The view title was changed by the frame loader.
2712  *
2713  * Emits signal: "title,changed" with pointer to new title string.
2714  */
2715 void ewk_view_title_set(Evas_Object* ewkView, const char* title)
2716 {
2717     DBG("ewkView=%p, title=%s", ewkView, title ? title : "(null)");
2718     evas_object_smart_callback_call(ewkView, "title,changed", (void*)title);
2719 }
2720
2721 /**
2722  * @internal
2723  * Reports that main frame's uri changed.
2724  *
2725  * Emits signal: "uri,changed" with pointer to the new uri string.
2726  */
2727 void ewk_view_uri_changed(Evas_Object* ewkView)
2728 {
2729     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
2730     const char* uri = ewk_frame_uri_get(smartData->main_frame);
2731     DBG("ewkView=%p, uri=%s", ewkView, uri ? uri : "(null)");
2732     evas_object_smart_callback_call(ewkView, "uri,changed", (void*)uri);
2733 }
2734
2735 /**
2736  * @internal
2737  * Reports that a DOM document object has finished loading for @p frame.
2738  *
2739  * @param ewkView View which contains the frame.
2740  * @param frame The frame whose load has triggered the event.
2741  *
2742  * Emits signal: "load,document,finished" with @p frame as the parameter.
2743  */
2744 void ewk_view_load_document_finished(Evas_Object* ewkView, Evas_Object* frame)
2745 {
2746     evas_object_smart_callback_call(ewkView, "load,document,finished", frame);
2747 }
2748
2749 /**
2750  * @internal
2751  * Reports the view started loading something.
2752  *
2753  * @param ewkView View.
2754  *
2755  * Emits signal: "load,started" with no parameters.
2756  */
2757 void ewk_view_load_started(Evas_Object* ewkView)
2758 {
2759     DBG("ewkView=%p", ewkView);
2760     evas_object_smart_callback_call(ewkView, "load,started", 0);
2761 }
2762
2763 /**
2764  * Reports the frame started loading something.
2765  *
2766  * @param ewkView View.
2767  *
2768  * Emits signal: "load,started" on main frame with no parameters.
2769  */
2770 void ewk_view_frame_main_load_started(Evas_Object* ewkView)
2771 {
2772     DBG("ewkView=%p", ewkView);
2773     Evas_Object* frame = ewk_view_frame_main_get(ewkView);
2774     evas_object_smart_callback_call(frame, "load,started", 0);
2775 }
2776
2777 /**
2778  * @internal
2779  * Reports the main frame started provisional load.
2780  *
2781  * @param ewkView View.
2782  *
2783  * Emits signal: "load,provisional" on View with no parameters.
2784  */
2785 void ewk_view_load_provisional(Evas_Object* ewkView)
2786 {
2787     DBG("ewkView=%p", ewkView);
2788     evas_object_smart_callback_call(ewkView, "load,provisional", 0);
2789 }
2790
2791 /**
2792  * @internal
2793  * Reports view can be shown after a new window is created.
2794  *
2795  * @param ewkView Frame.
2796  *
2797  * Emits signal: "load,newwindow,show" on view with no parameters.
2798  */
2799 void ewk_view_load_show(Evas_Object* ewkView)
2800 {
2801     DBG("ewkView=%p", ewkView);
2802     evas_object_smart_callback_call(ewkView, "load,newwindow,show", 0);
2803 }
2804
2805
2806 /**
2807  * @internal
2808  * Reports the main frame was cleared.
2809  *
2810  * @param ewkView View.
2811  */
2812 void ewk_view_frame_main_cleared(Evas_Object* ewkView)
2813 {
2814     DBG("ewkView=%p", ewkView);
2815     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
2816     EINA_SAFETY_ON_NULL_RETURN(smartData->api->flush);
2817     smartData->api->flush(smartData);
2818 }
2819
2820 /**
2821  * @internal
2822  * Reports the main frame received an icon.
2823  *
2824  * @param ewkView View.
2825  *
2826  * Emits signal: "icon,received" with no parameters.
2827  */
2828 void ewk_view_frame_main_icon_received(Evas_Object* ewkView)
2829 {
2830     DBG("ewkView=%p", ewkView);
2831     Evas_Object* frame = ewk_view_frame_main_get(ewkView);
2832     evas_object_smart_callback_call(frame, "icon,received", 0);
2833 }
2834
2835 /**
2836  * @internal
2837  * Reports load finished, optionally with error information.
2838  *
2839  * Emits signal: "load,finished" with pointer to #Ewk_Frame_Load_Error
2840  * if any error, or @c 0 if successful load.
2841  *
2842  * @note there should not be any error stuff here, but trying to be
2843  *       compatible with previous WebKit.
2844  */
2845 void ewk_view_load_finished(Evas_Object* ewkView, const Ewk_Frame_Load_Error* error)
2846 {
2847     DBG("ewkView=%p, error=%p", ewkView, error);
2848     evas_object_smart_callback_call(ewkView, "load,finished", (void*)error);
2849 }
2850
2851 /**
2852  * @internal
2853  * Reports load failed with error information.
2854  *
2855  * Emits signal: "load,error" with pointer to Ewk_Frame_Load_Error.
2856  */
2857 void ewk_view_load_error(Evas_Object* ewkView, const Ewk_Frame_Load_Error* error)
2858 {
2859     DBG("ewkView=%p, error=%p", ewkView, error);
2860     evas_object_smart_callback_call(ewkView, "load,error", (void*)error);
2861 }
2862
2863 /**
2864  * @internal
2865  * Reports load progress changed.
2866  *
2867  * Emits signal: "load,progress" with pointer to a double from 0.0 to 1.0.
2868  */
2869 void ewk_view_load_progress_changed(Evas_Object* ewkView)
2870 {
2871     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
2872     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv);
2873
2874     // Evas_Coord width, height;
2875     double progress = priv->page->progress()->estimatedProgress();
2876
2877     DBG("ewkView=%p (p=%0.3f)", ewkView, progress);
2878
2879     evas_object_smart_callback_call(ewkView, "load,progress", &progress);
2880 }
2881
2882 /**
2883  * @internal
2884  * Reports view @param ewkView should be restored to default conditions
2885  *
2886  * @param ewkView View.
2887  * @param frame Frame that originated restore.
2888  *
2889  * Emits signal: "restore" with frame.
2890  */
2891 void ewk_view_restore_state(Evas_Object* ewkView, Evas_Object* frame)
2892 {
2893     evas_object_smart_callback_call(ewkView, "restore", frame);
2894 }
2895
2896 /**
2897  * @internal
2898  * Delegates to browser the creation of a new window. If it is not implemented,
2899  * current view is returned, so navigation might continue in same window. If
2900  * browser supports the creation of new windows, a new Ewk_Window_Features is
2901  * created and passed to browser. If it intends to keep the request for opening
2902  * the window later it must increments the Ewk_Winwdow_Features ref count by
2903  * calling ewk_window_features_ref(window_features). Otherwise this struct will
2904  * be freed after returning to this function.
2905  *
2906  * @param ewkView Current view.
2907  * @param javascript @c EINA_TRUE if the new window is originated from javascript,
2908  * @c EINA_FALSE otherwise
2909  * @param widthindow_features Features of the new window being created. If it's @c
2910  * NULL, it will be created a window with default features.
2911  *
2912  * @return New view, in case smart class implements the creation of new windows;
2913  * else, current view @param ewkView or @c 0 on failure.
2914  *
2915  * @see ewk_window_features_ref().
2916  */
2917 Evas_Object* ewk_view_window_create(Evas_Object* ewkView, Eina_Bool javascript, const WebCore::WindowFeatures* coreFeatures)
2918 {
2919     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
2920
2921     if (!smartData->api->window_create)
2922         return ewkView;
2923
2924     Ewk_Window_Features* windowFeatures = ewk_window_features_new_from_core(coreFeatures);
2925     if (!windowFeatures)
2926         return 0;
2927
2928     Evas_Object* view = smartData->api->window_create(smartData, javascript, windowFeatures);
2929     ewk_window_features_unref(windowFeatures);
2930
2931     return view;
2932 }
2933
2934 /**
2935  * @internal
2936  * Reports a window should be closed. It's client responsibility to decide if
2937  * the window should in fact be closed. So, if only windows created by javascript
2938  * are allowed to be closed by this call, browser needs to save the javascript
2939  * flag when the window is created. Since a window can close itself (for example
2940  * with a 'self.close()' in Javascript) browser must postpone the deletion to an
2941  * idler.
2942  *
2943  * @param ewkView View to be closed.
2944  */
2945 void ewk_view_window_close(Evas_Object* ewkView)
2946 {
2947     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
2948
2949     ewk_view_stop(ewkView);
2950     if (!smartData->api->window_close)
2951         return;
2952     smartData->api->window_close(smartData);
2953 }
2954
2955 /**
2956  * @internal
2957  * Reports mouse has moved over a link.
2958  *
2959  * Emits signal: "link,hover,in"
2960  */
2961 void ewk_view_mouse_link_hover_in(Evas_Object* ewkView, void* data)
2962 {
2963     evas_object_smart_callback_call(ewkView, "link,hover,in", data);
2964 }
2965
2966 /**
2967  * @internal
2968  * Reports mouse is not over a link anymore.
2969  *
2970  * Emits signal: "link,hover,out"
2971  */
2972 void ewk_view_mouse_link_hover_out(Evas_Object* ewkView)
2973 {
2974     evas_object_smart_callback_call(ewkView, "link,hover,out", 0);
2975 }
2976
2977 /**
2978  * @internal
2979  * Set toolbar visible.
2980  *
2981  * Emits signal: "toolbars,visible,set" with a pointer to a boolean.
2982  */
2983 void ewk_view_toolbars_visible_set(Evas_Object* ewkView, Eina_Bool visible)
2984 {
2985     DBG("ewkView=%p (visible=%d)", ewkView, !!visible);
2986     evas_object_smart_callback_call(ewkView, "toolbars,visible,set", &visible);
2987 }
2988
2989 /**
2990  * @internal
2991  * Get toolbar visibility.
2992  *
2993  * @param ewkView View.
2994  * @param visible boolean pointer in which to save the result. It defaults
2995  * to @c FALSE, i.e. if browser does no listen to emitted signal, it means
2996  * there are no toolbars and therefore they are not visible.
2997  *
2998  * Emits signal: "toolbars,visible,get" with a pointer to a boolean.
2999  */
3000 void ewk_view_toolbars_visible_get(Evas_Object* ewkView, Eina_Bool* visible)
3001 {
3002     DBG("%s, o=%p", __func__, ewkView);
3003     *visible = EINA_FALSE;
3004     evas_object_smart_callback_call(ewkView, "toolbars,visible,get", visible);
3005 }
3006
3007 /**
3008  * @internal
3009  * Set statusbar visible.
3010  *
3011  * @param ewkView View.
3012  * @param visible @c TRUE if statusbar are visible, @c FALSE otherwise.
3013  *
3014  * Emits signal: "statusbar,visible,set" with a pointer to a boolean.
3015  */
3016 void ewk_view_statusbar_visible_set(Evas_Object* ewkView, Eina_Bool visible)
3017 {
3018     DBG("ewkView=%p (visible=%d)", ewkView, !!visible);
3019     evas_object_smart_callback_call(ewkView, "statusbar,visible,set", &visible);
3020 }
3021
3022 /**
3023  * @internal
3024  * Get statusbar visibility.
3025  *
3026  * @param ewkView View.
3027  * @param visible boolean pointer in which to save the result. It defaults
3028  * to @c FALSE, i.e. if browser does no listen to emitted signal, it means
3029  * there is no statusbar and therefore it is not visible.
3030  *
3031  * Emits signal: "statusbar,visible,get" with a pointer to a boolean.
3032  */
3033 void ewk_view_statusbar_visible_get(Evas_Object* ewkView, Eina_Bool* visible)
3034 {
3035     DBG("%s, o=%p", __func__, ewkView);
3036     *visible = EINA_FALSE;
3037     evas_object_smart_callback_call(ewkView, "statusbar,visible,get", visible);
3038 }
3039
3040 /**
3041  * @internal
3042  * Set text of statusbar
3043  *
3044  * @param ewkView View.
3045  * @param text New text to put on statusbar.
3046  *
3047  * Emits signal: "statusbar,text,set" with a string.
3048  */
3049 void ewk_view_statusbar_text_set(Evas_Object* ewkView, const char* text)
3050 {
3051     DBG("ewkView=%p (text=%s)", ewkView, text);
3052     INF("status bar text set: %s", text);
3053     evas_object_smart_callback_call(ewkView, "statusbar,text,set", (void*)text);
3054 }
3055
3056 /**
3057  * @internal
3058  * Set scrollbars visible.
3059  *
3060  * @param ewkView View.
3061  * @param visible @c TRUE if scrollbars are visible, @c FALSE otherwise.
3062  *
3063  * Emits signal: "scrollbars,visible,set" with a pointer to a boolean.
3064  */
3065 void ewk_view_scrollbars_visible_set(Evas_Object* ewkView, Eina_Bool visible)
3066 {
3067     DBG("ewkView=%p (visible=%d)", ewkView, !!visible);
3068     evas_object_smart_callback_call(ewkView, "scrollbars,visible,set", &visible);
3069 }
3070
3071 /**
3072  * @internal
3073  * Get scrollbars visibility.
3074  *
3075  * @param ewkView View.
3076  * @param visible boolean pointer in which to save the result. It defaults
3077  * to @c FALSE, i.e. if browser does no listen to emitted signal, it means
3078  * there are no scrollbars and therefore they are not visible.
3079  *
3080  * Emits signal: "scrollbars,visible,get" with a pointer to a boolean.
3081  */
3082 void ewk_view_scrollbars_visible_get(Evas_Object* ewkView, Eina_Bool* visible)
3083 {
3084     DBG("%s, o=%p", __func__, ewkView);
3085     *visible = EINA_FALSE;
3086     evas_object_smart_callback_call(ewkView, "scrollbars,visible,get", visible);
3087 }
3088
3089 /**
3090  * @internal
3091  * Set menubar visible.
3092  *
3093  * @param ewkView View.
3094  * @param visible @c TRUE if menubar is visible, @c FALSE otherwise.
3095  *
3096  * Emits signal: "menubar,visible,set" with a pointer to a boolean.
3097  */
3098 void ewk_view_menubar_visible_set(Evas_Object* ewkView, Eina_Bool visible)
3099 {
3100     DBG("ewkView=%p (visible=%d)", ewkView, !!visible);
3101     evas_object_smart_callback_call(ewkView, "menubar,visible,set", &visible);
3102 }
3103
3104 /**
3105  * @internal
3106  * Get menubar visibility.
3107  *
3108  * @param ewkView View.
3109  * @param visible boolean pointer in which to save the result. It defaults
3110  * to @c FALSE, i.e. if browser does no listen to emitted signal, it means
3111  * there is no menubar and therefore it is not visible.
3112  *
3113  * Emits signal: "menubar,visible,get" with a pointer to a boolean.
3114  */
3115 void ewk_view_menubar_visible_get(Evas_Object* ewkView, Eina_Bool* visible)
3116 {
3117     DBG("%s, o=%p", __func__, ewkView);
3118     *visible = EINA_FALSE;
3119     evas_object_smart_callback_call(ewkView, "menubar,visible,get", visible);
3120 }
3121
3122 /**
3123  * @internal
3124  * Set tooltip text and display if it is currently hidden.
3125  *
3126  * @param ewkView View.
3127  * @param text Text to set tooltip to.
3128  *
3129  * Emits signal: "tooltip,text,set" with a string. If tooltip must be actually
3130  * removed, text will be 0 or '\0'
3131  */
3132 void ewk_view_tooltip_text_set(Evas_Object* ewkView, const char* text)
3133 {
3134     DBG("ewkView=%p text=%s", ewkView, text);
3135     evas_object_smart_callback_call(ewkView, "tooltip,text,set", (void*)text);
3136 }
3137
3138 /**
3139  * @internal
3140  *
3141  * @param ewkView View.
3142  * @param message String to show on console.
3143  * @param lineNumber Line number.
3144  * @sourceID Source id.
3145  *
3146  */
3147 void ewk_view_add_console_message(Evas_Object* ewkView, const char* message, unsigned int lineNumber, const char* sourceID)
3148 {
3149     DBG("ewkView=%p message=%s lineNumber=%u sourceID=%s", ewkView, message, lineNumber, sourceID);
3150     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
3151     EINA_SAFETY_ON_NULL_RETURN(smartData->api);
3152     EINA_SAFETY_ON_NULL_RETURN(smartData->api->add_console_message);
3153     smartData->api->add_console_message(smartData, message, lineNumber, sourceID);
3154 }
3155
3156 bool ewk_view_focus_can_cycle(Evas_Object* ewkView, Ewk_Focus_Direction direction)
3157 {
3158     DBG("ewkView=%p direction=%d", ewkView, direction);
3159     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
3160     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->api, false);
3161
3162     if (!smartData->api->focus_can_cycle)
3163         return false;
3164
3165     return smartData->api->focus_can_cycle(smartData, direction);
3166 }
3167
3168 void ewk_view_run_javascript_alert(Evas_Object* ewkView, Evas_Object* frame, const char* message)
3169 {
3170     DBG("ewkView=%p frame=%p message=%s", ewkView, frame, message);
3171     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
3172     EINA_SAFETY_ON_NULL_RETURN(smartData->api);
3173
3174     if (!smartData->api->run_javascript_alert)
3175         return;
3176
3177     smartData->api->run_javascript_alert(smartData, frame, message);
3178 }
3179
3180 Eina_Bool ewk_view_run_javascript_confirm(Evas_Object* ewkView, Evas_Object* frame, const char* message)
3181 {
3182     DBG("ewkView=%p frame=%p message=%s", ewkView, frame, message);
3183     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
3184     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->api, EINA_FALSE);
3185
3186     if (!smartData->api->run_javascript_confirm)
3187         return EINA_FALSE;
3188
3189     return smartData->api->run_javascript_confirm(smartData, frame, message);
3190 }
3191
3192 Eina_Bool ewk_view_run_javascript_prompt(Evas_Object* ewkView, Evas_Object* frame, const char* message, const char* defaultValue, char** value)
3193 {
3194     DBG("ewkView=%p frame=%p message=%s", ewkView, frame, message);
3195     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
3196     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->api, EINA_FALSE);
3197
3198     if (!smartData->api->run_javascript_prompt)
3199         return EINA_FALSE;
3200
3201     return smartData->api->run_javascript_prompt(smartData, frame, message, defaultValue, value);
3202 }
3203
3204 /**
3205  * @internal
3206  * Delegates to client to decide whether a script must be stopped because it's
3207  * running for too long. If client does not implement it, it goes to default
3208  * implementation, which logs and returns EINA_FALSE. Client may remove log by
3209  * setting this function 0, which will just return EINA_FALSE.
3210  *
3211  * @param ewkView View.
3212  *
3213  * @return @c EINA_TRUE if script should be stopped; @c EINA_FALSE otherwise
3214  */
3215 Eina_Bool ewk_view_should_interrupt_javascript(Evas_Object* ewkView)
3216 {
3217     DBG("ewkView=%p", ewkView);
3218     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
3219     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->api, EINA_FALSE);
3220
3221     if (!smartData->api->should_interrupt_javascript)
3222         return EINA_FALSE;
3223
3224     return smartData->api->should_interrupt_javascript(smartData);
3225 }
3226
3227 /**
3228  * @internal
3229  * This is called whenever the web site shown in @param frame is asking to store data
3230  * to the database @param databaseName and the quota allocated to that web site
3231  * is exceeded. Browser may use this to increase the size of quota before the
3232  * originating operationa fails.
3233  *
3234  * @param ewkView View.
3235  * @param frame The frame whose web page exceeded its database quota.
3236  * @param databaseName Database name.
3237  * @param currentSize Current size of this database
3238  * @param expectedSize The expected size of this database in order to fulfill
3239  * site's requirement.
3240  */
3241 uint64_t ewk_view_exceeded_database_quota(Evas_Object* ewkView, Evas_Object* frame, const char* databaseName, uint64_t currentSize, uint64_t expectedSize)
3242 {
3243     DBG("ewkView=%p", ewkView);
3244     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
3245     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->api, 0);
3246     if (!smartData->api->exceeded_database_quota)
3247         return 0;
3248
3249     INF("currentSize=%" PRIu64 " expectedSize=%" PRIu64, currentSize, expectedSize);
3250     return smartData->api->exceeded_database_quota(smartData, frame, databaseName, currentSize, expectedSize);
3251 }
3252
3253 /**
3254  * @internal
3255  * Open panel to choose a file.
3256  *
3257  * @param ewkView View.
3258  * @param frame Frame in which operation is required.
3259  * @param allowsMultipleFiles @c true when more than one file may be selected, @c false otherwise.
3260  * @param acceptMIMETypes List of accepted mime types. It is passed to child objects as an Eina_List of char pointers that is freed automatically.
3261  * @param selectedFilenames List of files selected.
3262  *
3263  * @return @EINA_FALSE if user canceled file selection; @EINA_TRUE if confirmed.
3264  */
3265 Eina_Bool ewk_view_run_open_panel(Evas_Object* ewkView, Evas_Object* frame, bool allowsMultipleFiles, const WTF::Vector<WTF::String>& acceptMIMETypes, Eina_List** selectedFilenames)
3266 {
3267     DBG("ewkView=%p frame=%p allows_multiple_files=%d", ewkView, frame, allowsMultipleFiles);
3268     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
3269     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->api, EINA_FALSE);
3270
3271     if (!smartData->api->run_open_panel)
3272         return EINA_FALSE;
3273
3274     *selectedFilenames = 0;
3275
3276     Eina_List* cAcceptMIMETypes = 0;
3277     for (WTF::Vector<WTF::String>::const_iterator iterator = acceptMIMETypes.begin(); iterator != acceptMIMETypes.end(); ++iterator)
3278         cAcceptMIMETypes = eina_list_append(cAcceptMIMETypes, strdup((*iterator).utf8().data()));
3279
3280     bool confirm = smartData->api->run_open_panel(smartData, frame, allowsMultipleFiles, cAcceptMIMETypes, selectedFilenames);
3281     if (!confirm && *selectedFilenames)
3282         ERR("Canceled file selection, but selected filenames != 0. Free names before return.");
3283
3284     void* item = 0;
3285     EINA_LIST_FREE(cAcceptMIMETypes, item)
3286         free(item);
3287
3288     return confirm;
3289 }
3290
3291 void ewk_view_repaint(Evas_Object* ewkView, Evas_Coord x, Evas_Coord y, Evas_Coord width, Evas_Coord height)
3292 {
3293     DBG("ewkView=%p, region=%d,%d + %dx%d", ewkView, x, y, width, height);
3294     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
3295     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv);
3296
3297     _ewk_view_repaint_add(priv, x, y, width, height);
3298     _ewk_view_smart_changed(smartData);
3299 }
3300
3301 void ewk_view_scroll(Evas_Object* ewkView, Evas_Coord dx, Evas_Coord dy, Evas_Coord scrollX, Evas_Coord scrollY, Evas_Coord scrollWidth, Evas_Coord scrollHeight, Evas_Coord centerX, Evas_Coord centerY, Evas_Coord centerWidth, Evas_Coord centerHeight, Eina_Bool mainFrame)
3302 {
3303     DBG("ewkView=%p, delta: %d,%d, scroll: %d,%d+%dx%d, clip: %d,%d+%dx%d",
3304         ewkView, dx, dy, scrollX, scrollY, scrollWidth, scrollHeight, centerX, centerY, centerWidth, centerHeight);
3305
3306     if ((scrollX != centerX) || (scrollY != centerY) || (scrollWidth != centerWidth) || (scrollHeight != centerHeight))
3307         WRN("scroll region and clip are different! %d,%d+%dx%d and %d,%d+%dx%d",
3308             scrollX, scrollY, scrollWidth, scrollHeight, centerX, centerY, centerWidth, centerHeight);
3309
3310     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
3311     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv);
3312     EINA_SAFETY_ON_TRUE_RETURN(!dx && !dy);
3313
3314     _ewk_view_scroll_add(priv, dx, dy, scrollX, scrollY, scrollWidth, scrollHeight, mainFrame);
3315
3316     _ewk_view_smart_changed(smartData);
3317 }
3318
3319 WebCore::Page* ewk_view_core_page_get(const Evas_Object* ewkView)
3320 {
3321     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
3322     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0);
3323     return priv->page;
3324 }
3325
3326 /**
3327  * Creates a new frame for given url and owner element.
3328  *
3329  * Emits "frame,created" with the new frame object on success.
3330  */
3331 WTF::PassRefPtr<WebCore::Frame> ewk_view_frame_create(Evas_Object* ewkView, Evas_Object* frame, const WTF::String& name, WebCore::HTMLFrameOwnerElement* ownerElement, const WebCore::KURL& url, const WTF::String& referrer)
3332 {
3333     DBG("ewkView=%p, frame=%p, name=%s, ownerElement=%p, url=%s, referrer=%s",
3334         ewkView, frame, name.utf8().data(), ownerElement,
3335         url.string().utf8().data(), referrer.utf8().data());
3336
3337     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
3338     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0);
3339
3340     WTF::RefPtr<WebCore::Frame> coreFrame = _ewk_view_core_frame_new
3341                                          (smartData, priv, ownerElement);
3342     if (!coreFrame) {
3343         ERR("Could not create child core frame '%s'", name.utf8().data());
3344         return 0;
3345     }
3346
3347     if (!ewk_frame_child_add(frame, coreFrame, name, url, referrer)) {
3348         ERR("Could not create child frame object '%s'", name.utf8().data());
3349         return 0;
3350     }
3351
3352     // The creation of the frame may have removed itself already.
3353     if (!coreFrame->page() || !coreFrame->tree() || !coreFrame->tree()->parent())
3354         return 0;
3355
3356     smartData->changed.frame_rect = EINA_TRUE;
3357     _ewk_view_smart_changed(smartData);
3358
3359     evas_object_smart_callback_call(ewkView, "frame,created", frame);
3360     return coreFrame.release();
3361 }
3362
3363 WTF::PassRefPtr<WebCore::Widget> ewk_view_plugin_create(Evas_Object* ewkView, Evas_Object* frame, const WebCore::IntSize& pluginSize, WebCore::HTMLPlugInElement* element, const WebCore::KURL& url, const WTF::Vector<WTF::String>& paramNames, const WTF::Vector<WTF::String>& paramValues, const WTF::String& mimeType, bool loadManually)
3364 {
3365     DBG("ewkView=%p, frame=%p, size=%dx%d, element=%p, url=%s, mimeType=%s",
3366         ewkView, frame, pluginSize.width(), pluginSize.height(), element,
3367         url.string().utf8().data(), mimeType.utf8().data());
3368
3369     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
3370     smartData->changed.frame_rect = EINA_TRUE;
3371     _ewk_view_smart_changed(smartData);
3372
3373     return ewk_frame_plugin_create
3374                (frame, pluginSize, element, url, paramNames, paramValues,
3375                mimeType, loadManually);
3376 }
3377
3378 /**
3379  * @internal
3380  *
3381  * Creates a new popup with options when a select widget was clicked.
3382  *
3383  * @param client PopupMenuClient instance that allows communication with webkit.
3384  * @param selected Selected item.
3385  * @param rect Menu's position.
3386  *
3387  * Emits: "popup,create" with a list of Ewk_Menu containing each item's data
3388  */
3389 void ewk_view_popup_new(Evas_Object* ewkView, WebCore::PopupMenuClient* client, int selected, const WebCore::IntRect& rect)
3390 {
3391     INF("ewkView=%p", ewkView);
3392     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
3393     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv);
3394
3395     if (priv->popup.menuClient)
3396         ewk_view_popup_destroy(ewkView);
3397
3398     priv->popup.menuClient = client;
3399
3400     // populate items
3401     const int size = client->listSize();
3402     for (int i = 0; i < size; ++i) {
3403         Ewk_Menu_Item* item = static_cast<Ewk_Menu_Item*>(malloc(sizeof(*item)));
3404         if (client->itemIsSeparator(i))
3405             item->type = EWK_MENU_SEPARATOR;
3406         else if (client->itemIsLabel(i))
3407             item->type = EWK_MENU_GROUP;
3408         else
3409             item->type = EWK_MENU_OPTION;
3410         item->text = eina_stringshare_add(client->itemText(i).utf8().data());
3411
3412         priv->popup.menu.items = eina_list_append(priv->popup.menu.items, item);
3413     }
3414
3415     priv->popup.menu.x = rect.x();
3416     priv->popup.menu.y = rect.y();
3417     priv->popup.menu.width = rect.width();
3418     priv->popup.menu.height = rect.height();
3419     evas_object_smart_callback_call(ewkView, "popup,create", &priv->popup.menu);
3420 }
3421
3422 Eina_Bool ewk_view_popup_destroy(Evas_Object* ewkView)
3423 {
3424     INF("ewkView=%p", ewkView);
3425     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
3426     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
3427
3428     if (!priv->popup.menuClient)
3429         return EINA_FALSE;
3430
3431     evas_object_smart_callback_call(ewkView, "popup,willdelete", &priv->popup.menu);
3432
3433     void* itemv;
3434     EINA_LIST_FREE(priv->popup.menu.items, itemv) {
3435         Ewk_Menu_Item* item = static_cast<Ewk_Menu_Item*>(itemv);
3436         eina_stringshare_del(item->text);
3437         free(item);
3438     }
3439     priv->popup.menuClient->popupDidHide();
3440     priv->popup.menuClient = 0;
3441
3442     return EINA_TRUE;
3443 }
3444
3445 void ewk_view_popup_selected_set(Evas_Object* ewkView, int index)
3446 {
3447     INF("ewkView=%p", ewkView);
3448     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
3449     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv);
3450     EINA_SAFETY_ON_NULL_RETURN(priv->popup.menuClient);
3451
3452     priv->popup.menuClient->valueChanged(index);
3453 }
3454
3455 /**
3456  * @internal
3457  * Request a download to user.
3458  *
3459  * @param ewkView View.
3460  * @oaram download Ewk_Download struct to be sent.
3461  *
3462  * Emits: "download,request" with an Ewk_Download containing the details of the
3463  * requested download. The download per se must be handled outside of webkit.
3464  */
3465 void ewk_view_download_request(Evas_Object* ewkView, Ewk_Download* download)
3466 {
3467     DBG("ewkView=%p", ewkView);
3468     evas_object_smart_callback_call(ewkView, "download,request", download);
3469 }
3470
3471 /**
3472  * @internal
3473  * Reports the JS window object was cleared.
3474  *
3475  * @param ewkView view.
3476  * @param frame the frame.
3477  */
3478 void ewk_view_js_window_object_clear(Evas_Object* ewkView, Evas_Object* frame)
3479 {
3480     evas_object_smart_callback_call(ewkView, "js,windowobject,clear", frame);
3481 }
3482
3483 /**
3484  * @internal
3485  * Reports the viewport has changed.
3486  *
3487  * @param arguments viewport argument.
3488  *
3489  * Emits signal: "viewport,changed" with no parameters.
3490  */
3491 void ewk_view_viewport_attributes_set(Evas_Object* ewkView, const WebCore::ViewportArguments& arguments)
3492 {
3493     EWK_VIEW_SD_GET(ewkView, smartData);
3494     EWK_VIEW_PRIV_GET(smartData, priv);
3495
3496     priv->viewportArguments = arguments;
3497     evas_object_smart_callback_call(ewkView, "viewport,changed", 0);
3498 }
3499
3500 void ewk_view_viewport_attributes_get(const Evas_Object* ewkView, int* width, int* height, float* initScale, float* maxScale, float* minScale, float* devicePixelRatio, Eina_Bool* userScalable)
3501 {
3502     WebCore::ViewportAttributes attributes = _ewk_view_viewport_attributes_compute(ewkView);
3503
3504     if (width)
3505         *width = attributes.layoutSize.width();
3506     if (height)
3507         *height = attributes.layoutSize.height();
3508     if (initScale)
3509         *initScale = attributes.initialScale;
3510     if (maxScale)
3511         *maxScale = attributes.maximumScale;
3512     if (minScale)
3513         *minScale = attributes.minimumScale;
3514     if (devicePixelRatio)
3515         *devicePixelRatio = attributes.devicePixelRatio;
3516     if (userScalable)
3517         *userScalable = static_cast<bool>(attributes.userScalable);
3518 }
3519
3520 Eina_Bool ewk_view_zoom_range_set(Evas_Object* ewkView, float minScale, float maxScale)
3521 {
3522     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
3523     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
3524
3525     if (maxScale < minScale) {
3526         WRN("min_scale is larger than max_scale");
3527         return EINA_FALSE;
3528     }
3529
3530     priv->settings.zoomRange.minScale = minScale;
3531     priv->settings.zoomRange.maxScale = maxScale;
3532
3533     return EINA_TRUE;
3534 }
3535
3536 float ewk_view_zoom_range_min_get(const Evas_Object* ewkView)
3537 {
3538     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, -1.0);
3539     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, -1.0);
3540
3541     return priv->settings.zoomRange.minScale;
3542 }
3543
3544 float ewk_view_zoom_range_max_get(const Evas_Object* ewkView)
3545 {
3546     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, -1.0);
3547     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, -1.0);
3548
3549     return priv->settings.zoomRange.maxScale;
3550 }
3551
3552 Eina_Bool ewk_view_user_scalable_set(Evas_Object* ewkView, Eina_Bool userScalable)
3553 {
3554     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
3555     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
3556
3557     priv->settings.zoomRange.userScalable = userScalable;
3558
3559     return EINA_TRUE;
3560 }
3561
3562 Eina_Bool ewk_view_user_scalable_get(const Evas_Object* ewkView)
3563 {
3564     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
3565     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
3566
3567     return priv->settings.zoomRange.userScalable;
3568 }
3569
3570 float ewk_view_device_pixel_ratio_get(const Evas_Object* ewkView)
3571 {
3572     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, -1.0);
3573     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, -1.0);
3574
3575     return priv->settings.devicePixelRatio;
3576 }
3577
3578 void ewk_view_did_first_visually_nonempty_layout(Evas_Object* ewkView)
3579 {
3580     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
3581     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv);
3582     if (!priv->flags.viewCleared) {
3583         ewk_view_frame_main_cleared(ewkView);
3584         ewk_view_enable_render(ewkView);
3585         priv->flags.viewCleared = EINA_TRUE;
3586     }
3587 }
3588
3589 /**
3590  * @internal
3591  * Dispatch finished loading.
3592  *
3593  * @param ewkView view.
3594  */
3595 void ewk_view_dispatch_did_finish_loading(Evas_Object* ewkView)
3596 {
3597     /* If we reach this point and rendering is still disabled, WebCore will not
3598      * trigger the didFirstVisuallyNonEmptyLayout signal anymore. So, we
3599      * forcefully re-enable the rendering.
3600      */
3601     ewk_view_did_first_visually_nonempty_layout(ewkView);
3602 }
3603
3604 void ewk_view_transition_to_commited_for_newpage(Evas_Object* ewkView)
3605 {
3606     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
3607     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv);
3608
3609     ewk_view_disable_render(ewkView);
3610     priv->flags.viewCleared = EINA_FALSE;
3611 }
3612
3613
3614 /**
3615  * @internal
3616  * Reports a requeset will be loaded. It's client responsibility to decide if
3617  * request would be used. If @return is true, loader will try to load. Else,
3618  * Loader ignore action of request.
3619  *
3620  * @param ewkView View to load
3621  * @param request Request which contain url to navigate
3622  */
3623 Eina_Bool ewk_view_navigation_policy_decision(Evas_Object* ewkView, Ewk_Frame_Resource_Request* request)
3624 {
3625     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_TRUE);
3626     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->api, EINA_TRUE);
3627
3628     if (!smartData->api->navigation_policy_decision)
3629         return EINA_TRUE;
3630
3631     return smartData->api->navigation_policy_decision(smartData, request);
3632 }
3633
3634 Eina_Bool ewk_view_js_object_add(Evas_Object* ewkView, Ewk_JS_Object* object, const char* objectName)
3635 {
3636 #if ENABLE(NETSCAPE_PLUGIN_API)
3637     if (object->view) // object has already been added to another ewk_view
3638         return EINA_FALSE;
3639     object->name = eina_stringshare_add(objectName);
3640     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
3641     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
3642
3643     JSC::JSLock lock(JSC::SilenceAssertionsOnly);
3644     WebCore::JSDOMWindow* window = toJSDOMWindow(priv->mainFrame, WebCore::mainThreadNormalWorld());
3645     JSC::Bindings::RootObject* root;
3646     root = priv->mainFrame->script()->bindingRootObject();
3647
3648     if (!window) {
3649         ERR("Warning: couldn't get window object");
3650         return EINA_FALSE;
3651     }
3652
3653     JSC::ExecState* executeState = window->globalExec();
3654
3655     object->view = ewkView;
3656     JSC::JSObject* runtimeObject = (JSC::JSObject*)JSC::Bindings::CInstance::create((NPObject*)object, root)->createRuntimeObject(executeState);
3657     JSC::Identifier id = JSC::Identifier(exec, objectName);
3658
3659     JSC::PutPropertySlot slot;
3660     window->putVirtual(exec, id, runtimeObject, slot);
3661     return EINA_TRUE;
3662 #else
3663     return EINA_FALSE;
3664 #endif // ENABLE(NETSCAPE_PLUGIN_API)
3665 }
3666
3667 Eina_Bool ewk_view_protocol_handler_set(Evas_Object* ewkView, const char** protocols, Ewk_View_Resource_Handler_Cb handler, void* context)
3668 {
3669     EWK_VIEW_SD_GET(ewkView, smartData);
3670     EWK_VIEW_PRIV_GET(smartData, priv);
3671
3672     if (!handler)
3673         return EINA_FALSE;
3674
3675     priv->customResourceHandler.function = handler;
3676     priv->customResourceHandler.context = context;
3677
3678     return ewk_custom_protocol_handler_set(protocols);
3679 }
3680
3681 Eina_Bool ewk_view_protocol_handler_unset(Evas_Object* ewkView)
3682 {
3683     EWK_VIEW_SD_GET(ewkView, smartData);
3684     EWK_VIEW_PRIV_GET(smartData, priv);
3685     Eina_Bool ret = ewk_custom_protocol_handler_all_unset();
3686
3687     if (ret) {
3688         priv->customResourceHandler.function = 0;
3689         priv->customResourceHandler.context = 0;
3690     }
3691
3692     return ret;
3693 }
3694
3695 void* ewk_view_protocol_handler_resource_get(Evas_Object* ewkView, size_t* bytesRead, char** mime, const char* file)
3696 {
3697     EWK_VIEW_SD_GET(ewkView, smartData);
3698     EWK_VIEW_PRIV_GET(smartData, priv);
3699
3700     Ewk_View_Resource_Handler_Cb function = priv->customResourceHandler.function;
3701     if (function)
3702         return function(file, bytesRead, mime, priv->customResourceHandler.context);
3703
3704     return 0;
3705 }
3706
3707 /**
3708  * @internal
3709  * Reports that the contents have resized. The ewk_view calls contents_resize,
3710  * which can be reimplemented as needed.
3711  *
3712  * @param ewkView view.
3713  * @param width new content width.
3714  * @param height new content height.
3715  */
3716 void ewk_view_contents_size_changed(Evas_Object* ewkView, int width, int height)
3717 {
3718     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
3719     EINA_SAFETY_ON_NULL_RETURN(smartData->api);
3720     EINA_SAFETY_ON_NULL_RETURN(smartData->api->contents_resize);
3721
3722     if (!smartData->api->contents_resize(smartData, width, height))
3723         ERR("failed to resize contents to %dx%d", width, height);
3724 }
3725
3726 /**
3727  * @internal
3728  * Gets page size from frameview.
3729  *
3730  * @param ewkView view.
3731  *
3732  * @return page size.
3733  */
3734 WebCore::FloatRect ewk_view_page_rect_get(const Evas_Object* ewkView)
3735 {
3736     EWK_VIEW_SD_GET(ewkView, smartData);
3737     EWK_VIEW_PRIV_GET(smartData, priv);
3738
3739     WebCore::Frame* main_frame = priv->page->mainFrame();
3740     return main_frame->view()->frameRect();
3741 }
3742
3743 #if ENABLE(TOUCH_EVENTS)
3744 void ewk_view_need_touch_events_set(Evas_Object* ewkView, bool needed)
3745 {
3746     EWK_VIEW_SD_GET(ewkView, smartData);
3747     EWK_VIEW_PRIV_GET(smartData, priv);
3748
3749     priv->flags.needTouchEvents = needed;
3750 }
3751
3752 Eina_Bool ewk_view_need_touch_events_get(const Evas_Object* ewkView)
3753 {
3754     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
3755     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
3756     return priv->flags.needTouchEvents;
3757 }
3758 #endif
3759
3760 Eina_Bool ewk_view_mode_set(Evas_Object* ewkView, Ewk_View_Mode viewMode)
3761 {
3762     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, EINA_FALSE);
3763     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, EINA_FALSE);
3764
3765     switch (viewMode) {
3766     case EWK_VIEW_MODE_WINDOWED:
3767         priv->page->setViewMode(WebCore::Page::ViewModeWindowed);
3768         break;
3769     case EWK_VIEW_MODE_FLOATING:
3770         priv->page->setViewMode(WebCore::Page::ViewModeFloating);
3771         break;
3772     case EWK_VIEW_MODE_FULLSCREEN:
3773         priv->page->setViewMode(WebCore::Page::ViewModeFullscreen);
3774         break;
3775     case EWK_VIEW_MODE_MAXIMIZED:
3776         priv->page->setViewMode(WebCore::Page::ViewModeMaximized);
3777         break;
3778     case EWK_VIEW_MODE_MINIMIZED:
3779         priv->page->setViewMode(WebCore::Page::ViewModeMinimized);
3780         break;
3781     default:
3782         return EINA_FALSE;
3783     }
3784
3785     return EINA_TRUE;
3786 }
3787
3788 Ewk_View_Mode ewk_view_mode_get(const Evas_Object* ewkView)
3789 {
3790     Ewk_View_Mode mode = EWK_VIEW_MODE_WINDOWED;
3791     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, mode);
3792     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, mode);
3793
3794     switch (priv->page->viewMode()) {
3795     case WebCore::Page::ViewModeFloating:
3796         mode = EWK_VIEW_MODE_FLOATING;
3797         break;
3798     case WebCore::Page::ViewModeFullscreen:
3799         mode = EWK_VIEW_MODE_FULLSCREEN;
3800         break;
3801     case WebCore::Page::ViewModeMaximized:
3802         mode = EWK_VIEW_MODE_MAXIMIZED;
3803         break;
3804     case WebCore::Page::ViewModeMinimized:
3805         mode = EWK_VIEW_MODE_MINIMIZED;
3806         break;
3807     default:
3808         break;
3809     }
3810
3811     return mode;
3812 }
3813
3814 /**
3815  * @internal
3816  * Reports the view that editor client selection has changed.
3817  *
3818  * @param ewkView View.
3819  *
3820  * Emits signal: "editorclientselection,changed" with no parameters.
3821  */
3822 void ewk_view_editor_client_selection_changed(Evas_Object* ewkView)
3823 {
3824     evas_object_smart_callback_call(ewkView, "editorclient,selection,changed", 0);
3825 }
3826
3827 /**
3828  * @internal
3829  * Reports to the view that editor client's contents were changed.
3830  *
3831  * @param ewkView View.
3832  *
3833  * Emits signal: "editorclient,contents,changed" with no parameters.
3834  */
3835 void ewk_view_editor_client_contents_changed(Evas_Object* ewkView)
3836 {
3837     evas_object_smart_callback_call(ewkView, "editorclient,contents,changed", 0);
3838 }
3839
3840 namespace EWKPrivate {
3841
3842 WebCore::Page *corePage(const Evas_Object *ewkView)
3843 {
3844     EWK_VIEW_SD_GET_OR_RETURN(ewkView, sd, 0);
3845     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0);
3846     return priv->page;
3847 }
3848
3849 } // namespace EWKPrivate