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