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