12ab00e7ea041f06a5e198292df5b314091a15b4
[WebKit-https.git] / WebKit / efl / ewk / ewk_view.cpp
1 /*
2     Copyright (C) 2009-2010 ProFUSION embedded systems
3     Copyright (C) 2009-2010 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 "Chrome.h"
27 #include "ChromeClientEfl.h"
28 #include "ContextMenuController.h"
29 #include "DocumentLoader.h"
30 #include "DragClientEfl.h"
31 #include "EWebKit.h"
32 #include "EditorClientEfl.h"
33 #include "EventHandler.h"
34 #include "FocusController.h"
35 #include "FrameLoaderClientEfl.h"
36 #include "FrameView.h"
37 #include "GraphicsContext.h"
38 #include "HTMLElement.h"
39 #include "HTMLInputElement.h"
40 #include "HTMLNames.h"
41 #include "InspectorClientEfl.h"
42 #include "PlatformMouseEvent.h"
43 #include "PopupMenuClient.h"
44 #include "ProgressTracker.h"
45 #include "appcache/ApplicationCacheStorage.h"
46 #include "ewk_private.h"
47
48 #include <Ecore.h>
49 #include <Eina.h>
50 #include <Evas.h>
51 #include <eina_safety_checks.h>
52 #include <inttypes.h>
53 #include <sys/time.h>
54
55 #ifdef HAVE_ECORE_X
56 #include <Ecore_X.h>
57 #endif
58
59 #define ZOOM_MIN (0.05)
60 #define ZOOM_MAX (4.0)
61
62 #define DEVICE_PIXEL_RATIO (1.0)
63
64 static const char EWK_VIEW_TYPE_STR[] = "EWK_View";
65
66 static const size_t EWK_VIEW_REPAINTS_SIZE_INITIAL = 32;
67 static const size_t EWK_VIEW_REPAINTS_SIZE_STEP = 8;
68 static const size_t EWK_VIEW_REPAINTS_SIZE_MAX_FREE = 64;
69
70 static const size_t EWK_VIEW_SCROLLS_SIZE_INITIAL = 8;
71 static const size_t EWK_VIEW_SCROLLS_SIZE_STEP = 2;
72 static const size_t EWK_VIEW_SCROLLS_SIZE_MAX_FREE = 32;
73
74 struct _Ewk_View_Private_Data {
75     WebCore::Page* page;
76     WebCore::Settings* page_settings;
77     WebCore::Frame* main_frame;
78     WebCore::ViewportArguments viewport_arguments;
79     Ewk_History* history;
80     struct {
81         Ewk_Menu menu;
82         WebCore::PopupMenuClient* menu_client;
83     } popup;
84     struct {
85         Eina_Rectangle* array;
86         size_t count;
87         size_t allocated;
88     } repaints;
89     struct {
90         Ewk_Scroll_Request* array;
91         size_t count;
92         size_t allocated;
93     } scrolls;
94     unsigned int imh; /**< input method hints */
95     struct {
96         Eina_Bool view_cleared:1;
97     } flags;
98     struct {
99         const char* user_agent;
100         const char* user_stylesheet;
101         const char* encoding_default;
102         const char* encoding_custom;
103         const char* cache_directory;
104         const char* theme;
105         const char* local_storage_database_path;
106         int font_minimum_size;
107         int font_minimum_logical_size;
108         int font_default_size;
109         int font_monospace_size;
110         const char* font_standard;
111         const char* font_cursive;
112         const char* font_monospace;
113         const char* font_fantasy;
114         const char* font_serif;
115         const char* font_sans_serif;
116         Eina_Bool auto_load_images:1;
117         Eina_Bool auto_shrink_images:1;
118         Eina_Bool enable_auto_resize_window:1;
119         Eina_Bool enable_scripts:1;
120         Eina_Bool enable_plugins:1;
121         Eina_Bool enable_frame_flattening:1;
122         Eina_Bool encoding_detector:1;
123         Eina_Bool scripts_window_open:1;
124         Eina_Bool resizable_textareas:1;
125         Eina_Bool private_browsing:1;
126         Eina_Bool caret_browsing:1;
127         Eina_Bool spatial_navigation:1;
128         Eina_Bool local_storage:1;
129         Eina_Bool offline_app_cache: 1;
130         Eina_Bool page_cache: 1;
131         struct {
132             float min_scale;
133             float max_scale;
134             Eina_Bool user_scalable:1;
135         } zoom_range;
136         float device_pixel_ratio;
137     } settings;
138     struct {
139         struct {
140             double start;
141             double end;
142             double duration;
143         } time;
144         struct {
145             float start;
146             float end;
147             float range;
148         } zoom;
149         struct {
150             Evas_Coord x, y;
151         } center;
152         Ecore_Animator* animator;
153     } animated_zoom;
154     struct {
155         Evas_Coord w, h;
156         Eina_Bool use:1;
157     } fixed_layout;
158 };
159
160 #ifndef EWK_TYPE_CHECK
161 #define EWK_VIEW_TYPE_CHECK(o, ...) do { } while (0)
162 #else
163 #define EWK_VIEW_TYPE_CHECK(o, ...)                                     \
164     do {                                                                \
165         const char* _tmp_otype = evas_object_type_get(o);               \
166         const Evas_Smart* _tmp_s = evas_object_smart_smart_get(o);      \
167         if (EINA_UNLIKELY(!_tmp_s)) {                                   \
168             EINA_LOG_CRIT                                               \
169                 ("%p (%s) is not a smart object!", o,                   \
170                  _tmp_otype ? _tmp_otype : "(null)");                   \
171             return __VA_ARGS__;                                         \
172         }                                                               \
173         const Evas_Smart_Class* _tmp_sc = evas_smart_class_get(_tmp_s); \
174         if (EINA_UNLIKELY(!_tmp_sc)) {                                  \
175             EINA_LOG_CRIT                                               \
176                 ("%p (%s) is not a smart object!", o,                   \
177                  _tmp_otype ? _tmp_otype : "(null)");                   \
178             return __VA_ARGS__;                                         \
179         }                                                               \
180         if (EINA_UNLIKELY(_tmp_sc->data != EWK_VIEW_TYPE_STR)) {        \
181             EINA_LOG_CRIT                                               \
182                 ("%p (%s) is not of an ewk_view (need %p, got %p)!",    \
183                  o, _tmp_otype ? _tmp_otype : "(null)",                 \
184                  EWK_VIEW_TYPE_STR, _tmp_sc->data);                     \
185             return __VA_ARGS__;                                         \
186         }                                                               \
187     } while (0)
188 #endif
189
190 #define EWK_VIEW_SD_GET(o, ptr)                                 \
191     Ewk_View_Smart_Data* ptr = (Ewk_View_Smart_Data*)evas_object_smart_data_get(o)
192
193 #define EWK_VIEW_SD_GET_OR_RETURN(o, ptr, ...)          \
194     EWK_VIEW_TYPE_CHECK(o, __VA_ARGS__);                \
195     EWK_VIEW_SD_GET(o, ptr);                            \
196     if (!ptr) {                                         \
197         CRITICAL("no smart data for object %p (%s)",    \
198                  o, evas_object_type_get(o));           \
199         return __VA_ARGS__;                             \
200     }
201
202 #define EWK_VIEW_PRIV_GET(sd, ptr)              \
203     Ewk_View_Private_Data* ptr = sd->_priv
204
205 #define EWK_VIEW_PRIV_GET_OR_RETURN(sd, ptr, ...)               \
206     EWK_VIEW_PRIV_GET(sd, ptr);                                 \
207     if (!ptr) {                                                 \
208         CRITICAL("no private data for object %p (%s)",          \
209                  sd->self, evas_object_type_get(sd->self));     \
210         return __VA_ARGS__;                                     \
211     }
212
213 static void _ewk_view_smart_changed(Ewk_View_Smart_Data* sd)
214 {
215     if (sd->changed.any)
216         return;
217     sd->changed.any = EINA_TRUE;
218     evas_object_smart_changed(sd->self);
219 }
220
221 static Eina_Bool _ewk_view_repaints_resize(Ewk_View_Private_Data* priv, size_t size)
222 {
223     void* tmp = realloc(priv->repaints.array, size * sizeof(Eina_Rectangle));
224     if (!tmp) {
225         CRITICAL("could not realloc repaints array to %zu elements.", size);
226         return EINA_FALSE;
227     }
228     priv->repaints.allocated = size;
229     priv->repaints.array = (Eina_Rectangle*)tmp;
230     return EINA_TRUE;
231 }
232
233 static void _ewk_view_repaint_add(Ewk_View_Private_Data* priv, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h)
234 {
235     Eina_Rectangle* r;
236
237     // fprintf(stderr, ">>> repaint requested: %d,%d+%dx%d\n", x, y, w, h);
238     if (priv->repaints.allocated == priv->repaints.count) {
239         size_t size;
240         if (!priv->repaints.allocated)
241             size = EWK_VIEW_REPAINTS_SIZE_INITIAL;
242         else
243             size = priv->repaints.allocated + EWK_VIEW_REPAINTS_SIZE_STEP;
244         if (!_ewk_view_repaints_resize(priv, size))
245             return;
246     }
247
248     r = priv->repaints.array + priv->repaints.count;
249     priv->repaints.count++;
250
251     r->x = x;
252     r->y = y;
253     r->w = w;
254     r->h = h;
255
256     DBG("add repaint %d,%d+%dx%d", x, y, w, h);
257 }
258
259 static void _ewk_view_repaints_flush(Ewk_View_Private_Data* priv)
260 {
261     priv->repaints.count = 0;
262     if (priv->repaints.allocated <= EWK_VIEW_REPAINTS_SIZE_MAX_FREE)
263         return;
264     _ewk_view_repaints_resize(priv, EWK_VIEW_REPAINTS_SIZE_MAX_FREE);
265 }
266
267 static Eina_Bool _ewk_view_scrolls_resize(Ewk_View_Private_Data* priv, size_t size)
268 {
269     void* tmp = realloc(priv->scrolls.array, size * sizeof(Ewk_Scroll_Request));
270     if (!tmp) {
271         CRITICAL("could not realloc scrolls array to %zu elements.", size);
272         return EINA_FALSE;
273     }
274     priv->scrolls.allocated = size;
275     priv->scrolls.array = (Ewk_Scroll_Request*)tmp;
276     return EINA_TRUE;
277 }
278
279 static void _ewk_view_scroll_add(Ewk_View_Private_Data* priv, Evas_Coord dx, Evas_Coord dy, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h, Eina_Bool main_scroll)
280 {
281     Ewk_Scroll_Request* r;
282     Ewk_Scroll_Request* r_end;
283     Evas_Coord x2 = x + w, y2 = y + h;
284
285     r = priv->scrolls.array;
286     r_end = r + priv->scrolls.count;
287     for (; r < r_end; r++) {
288         if (r->x == x && r->y == y && r->w == w && r->h == h) {
289             DBG("region already scrolled %d,%d+%dx%d %+03d,%+03d add "
290                 "%+03d,%+03d",
291                 r->x, r->y, r->w, r->h, r->dx, r->dy, dx, dy);
292             r->dx += dx;
293             r->dy += dy;
294             return;
295         }
296         if ((x <= r->x && x2 >= r->x2) && (y <= r->y && y2 >= r->y2)) {
297             DBG("old viewport (%d,%d+%dx%d %+03d,%+03d) was scrolled itself, "
298                 "add %+03d,%+03d",
299                 r->x, r->y, r->w, r->h, r->dx, r->dy, dx, dy);
300             r->x += dx;
301             r->y += dy;
302         }
303     }
304
305     if (priv->scrolls.allocated == priv->scrolls.count) {
306         size_t size;
307         if (!priv->scrolls.allocated)
308             size = EWK_VIEW_SCROLLS_SIZE_INITIAL;
309         else
310             size = priv->scrolls.allocated + EWK_VIEW_SCROLLS_SIZE_STEP;
311         if (!_ewk_view_scrolls_resize(priv, size))
312             return;
313     }
314
315     r = priv->scrolls.array + priv->scrolls.count;
316     priv->scrolls.count++;
317
318     r->x = x;
319     r->y = y;
320     r->w = w;
321     r->h = h;
322     r->x2 = x2;
323     r->y2 = y2;
324     r->dx = dx;
325     r->dy = dy;
326     r->main_scroll = main_scroll;
327     DBG("add scroll in region: %d,%d+%dx%d %+03d,%+03d", x, y, w, h, dx, dy);
328
329     Eina_Rectangle* pr;
330     Eina_Rectangle* pr_end;
331     size_t count;
332     pr = priv->repaints.array;
333     count = priv->repaints.count;
334     pr_end = pr + count;
335     for (; pr < pr_end; pr++) {
336         pr->x += dx;
337         pr->y += dy;
338     }
339 }
340
341 static void _ewk_view_scrolls_flush(Ewk_View_Private_Data* priv)
342 {
343     priv->scrolls.count = 0;
344     if (priv->scrolls.allocated <= EWK_VIEW_SCROLLS_SIZE_MAX_FREE)
345         return;
346     _ewk_view_scrolls_resize(priv, EWK_VIEW_SCROLLS_SIZE_MAX_FREE);
347 }
348
349 // Default Event Handling //////////////////////////////////////////////
350 static Eina_Bool _ewk_view_smart_focus_in(Ewk_View_Smart_Data* sd)
351 {
352     EWK_VIEW_PRIV_GET(sd, priv);
353     WebCore::FocusController* fc = priv->page->focusController();
354     DBG("o=%p, fc=%p", sd->self, fc);
355     EINA_SAFETY_ON_NULL_RETURN_VAL(fc, EINA_FALSE);
356
357     fc->setActive(true);
358     fc->setFocused(true);
359     return EINA_TRUE;
360 }
361
362 static Eina_Bool _ewk_view_smart_focus_out(Ewk_View_Smart_Data* sd)
363 {
364     EWK_VIEW_PRIV_GET(sd, priv);
365     WebCore::FocusController* fc = priv->page->focusController();
366     DBG("o=%p, fc=%p", sd->self, fc);
367     EINA_SAFETY_ON_NULL_RETURN_VAL(fc, EINA_FALSE);
368
369     fc->setActive(false);
370     fc->setFocused(false);
371     return EINA_TRUE;
372 }
373
374 static Eina_Bool _ewk_view_smart_mouse_wheel(Ewk_View_Smart_Data* sd, const Evas_Event_Mouse_Wheel* ev)
375 {
376     return ewk_frame_feed_mouse_wheel(sd->main_frame, ev);
377 }
378
379 static Eina_Bool _ewk_view_smart_mouse_down(Ewk_View_Smart_Data* sd, const Evas_Event_Mouse_Down* ev)
380 {
381     return ewk_frame_feed_mouse_down(sd->main_frame, ev);
382 }
383
384 static Eina_Bool _ewk_view_smart_mouse_up(Ewk_View_Smart_Data* sd, const Evas_Event_Mouse_Up* ev)
385 {
386     return ewk_frame_feed_mouse_up(sd->main_frame, ev);
387 }
388
389 static Eina_Bool _ewk_view_smart_mouse_move(Ewk_View_Smart_Data* sd, const Evas_Event_Mouse_Move* ev)
390 {
391     return ewk_frame_feed_mouse_move(sd->main_frame, ev);
392 }
393
394 static Eina_Bool _ewk_view_smart_key_down(Ewk_View_Smart_Data* sd, const Evas_Event_Key_Down* ev)
395 {
396     Evas_Object* frame = ewk_view_frame_focused_get(sd->self);
397
398     if (!frame)
399         frame = sd->main_frame;
400
401     return ewk_frame_feed_key_down(frame, ev);
402 }
403
404 static Eina_Bool _ewk_view_smart_key_up(Ewk_View_Smart_Data* sd, const Evas_Event_Key_Up* ev)
405 {
406     Evas_Object* frame = ewk_view_frame_focused_get(sd->self);
407
408     if (!frame)
409         frame = sd->main_frame;
410
411     return ewk_frame_feed_key_up(frame, ev);
412 }
413
414 static void _ewk_view_smart_add_console_message(Ewk_View_Smart_Data* sd, const char* message, unsigned int lineNumber, const char* sourceID)
415 {
416     INF("console message: %s @%d: %s\n", sourceID, lineNumber, message);
417 }
418
419 static void _ewk_view_smart_run_javascript_alert(Ewk_View_Smart_Data* sd, Evas_Object* frame, const char* message)
420 {
421     INF("javascript alert: %s\n", message);
422 }
423
424 static Eina_Bool _ewk_view_smart_run_javascript_confirm(Ewk_View_Smart_Data* sd, Evas_Object* frame, const char* message)
425 {
426     INF("javascript confirm: %s", message);
427     INF("javascript confirm (HARD CODED)? YES");
428     return EINA_TRUE;
429 }
430
431 static Eina_Bool _ewk_view_smart_should_interrupt_javascript(Ewk_View_Smart_Data* sd)
432 {
433     INF("should interrupt javascript?\n"
434             "\t(HARD CODED) NO");
435     return EINA_FALSE;
436 }
437
438 static Eina_Bool _ewk_view_smart_run_javascript_prompt(Ewk_View_Smart_Data* sd, Evas_Object* frame, const char* message, const char* defaultValue, char** value)
439 {
440     *value = strdup("test");
441     Eina_Bool ret = EINA_TRUE;
442     INF("javascript prompt:\n"
443             "\t      message: %s\n"
444             "\tdefault value: %s\n"
445             "\tgiving answer: %s\n"
446             "\t       button: %s", message, defaultValue, *value, ret?"ok":"cancel");
447
448     return ret;
449 }
450
451 // Event Handling //////////////////////////////////////////////////////
452 static void _ewk_view_on_focus_in(void* data, Evas* e, Evas_Object* o, void* event_info)
453 {
454     Ewk_View_Smart_Data* sd = (Ewk_View_Smart_Data*)data;
455     EINA_SAFETY_ON_NULL_RETURN(sd->api);
456     EINA_SAFETY_ON_NULL_RETURN(sd->api->focus_in);
457     sd->api->focus_in(sd);
458 }
459
460 static void _ewk_view_on_focus_out(void* data, Evas* e, Evas_Object* o, void* event_info)
461 {
462     Ewk_View_Smart_Data* sd = (Ewk_View_Smart_Data*)data;
463     EINA_SAFETY_ON_NULL_RETURN(sd->api);
464     EINA_SAFETY_ON_NULL_RETURN(sd->api->focus_out);
465     sd->api->focus_out(sd);
466 }
467
468 static void _ewk_view_on_mouse_wheel(void* data, Evas* e, Evas_Object* o, void* event_info)
469 {
470     Evas_Event_Mouse_Wheel* ev = (Evas_Event_Mouse_Wheel*)event_info;
471     Ewk_View_Smart_Data* sd = (Ewk_View_Smart_Data*)data;
472     EINA_SAFETY_ON_NULL_RETURN(sd->api);
473     EINA_SAFETY_ON_NULL_RETURN(sd->api->mouse_wheel);
474     sd->api->mouse_wheel(sd, ev);
475 }
476
477 static void _ewk_view_on_mouse_down(void* data, Evas* e, Evas_Object* o, void* event_info)
478 {
479     Evas_Event_Mouse_Down* ev = (Evas_Event_Mouse_Down*)event_info;
480     Ewk_View_Smart_Data* sd = (Ewk_View_Smart_Data*)data;
481     EINA_SAFETY_ON_NULL_RETURN(sd->api);
482     EINA_SAFETY_ON_NULL_RETURN(sd->api->mouse_down);
483     sd->api->mouse_down(sd, ev);
484 }
485
486 static void _ewk_view_on_mouse_up(void* data, Evas* e, Evas_Object* o, void* event_info)
487 {
488     Evas_Event_Mouse_Up* ev = (Evas_Event_Mouse_Up*)event_info;
489     Ewk_View_Smart_Data* sd = (Ewk_View_Smart_Data*)data;
490     EINA_SAFETY_ON_NULL_RETURN(sd->api);
491     EINA_SAFETY_ON_NULL_RETURN(sd->api->mouse_up);
492     sd->api->mouse_up(sd, ev);
493 }
494
495 static void _ewk_view_on_mouse_move(void* data, Evas* e, Evas_Object* o, void* event_info)
496 {
497     Evas_Event_Mouse_Move* ev = (Evas_Event_Mouse_Move*)event_info;
498     Ewk_View_Smart_Data* sd = (Ewk_View_Smart_Data*)data;
499     EINA_SAFETY_ON_NULL_RETURN(sd->api);
500     EINA_SAFETY_ON_NULL_RETURN(sd->api->mouse_move);
501     sd->api->mouse_move(sd, ev);
502 }
503
504 static void _ewk_view_on_key_down(void* data, Evas* e, Evas_Object* o, void* event_info)
505 {
506     Evas_Event_Key_Down* ev = (Evas_Event_Key_Down*)event_info;
507     Ewk_View_Smart_Data* sd = (Ewk_View_Smart_Data*)data;
508     EINA_SAFETY_ON_NULL_RETURN(sd->api);
509     EINA_SAFETY_ON_NULL_RETURN(sd->api->key_down);
510     sd->api->key_down(sd, ev);
511 }
512
513 static void _ewk_view_on_key_up(void* data, Evas* e, Evas_Object* o, void* event_info)
514 {
515     Evas_Event_Key_Up* ev = (Evas_Event_Key_Up*)event_info;
516     Ewk_View_Smart_Data* sd = (Ewk_View_Smart_Data*)data;
517     EINA_SAFETY_ON_NULL_RETURN(sd->api);
518     EINA_SAFETY_ON_NULL_RETURN(sd->api->key_up);
519     sd->api->key_up(sd, ev);
520 }
521
522 static WTF::PassRefPtr<WebCore::Frame> _ewk_view_core_frame_new(Ewk_View_Smart_Data* sd, Ewk_View_Private_Data* priv, WebCore::HTMLFrameOwnerElement* owner)
523 {
524     WebCore::FrameLoaderClientEfl* flc = new WebCore::FrameLoaderClientEfl(sd->self);
525     if (!flc) {
526         CRITICAL("Could not create frame loader client.");
527         return 0;
528     }
529     flc->setCustomUserAgent(WTF::String::fromUTF8(priv->settings.user_agent));
530
531     return WebCore::Frame::create(priv->page, owner, flc);
532 }
533
534 static Evas_Smart_Class _parent_sc = EVAS_SMART_CLASS_INIT_NULL;
535
536 static Ewk_View_Private_Data* _ewk_view_priv_new(Ewk_View_Smart_Data* sd)
537 {
538     Ewk_View_Private_Data* priv =
539         (Ewk_View_Private_Data*)calloc(1, sizeof(Ewk_View_Private_Data));
540     WTF::AtomicString s;
541     WebCore::KURL url;
542
543     if (!priv) {
544         CRITICAL("could not allocate Ewk_View_Private_Data");
545         return 0;
546     }
547
548     WebCore::Page::PageClients pageClients;
549     pageClients.chromeClient = static_cast<WebCore::ChromeClient*>(new WebCore::ChromeClientEfl(sd->self));
550     pageClients.editorClient = static_cast<WebCore::EditorClient*>(new WebCore::EditorClientEfl(sd->self));
551     pageClients.dragClient = static_cast<WebCore::DragClient*>(new WebCore::DragClientEfl);
552     pageClients.inspectorClient = static_cast<WebCore::InspectorClient*>(new WebCore::InspectorClientEfl);
553     priv->page = new WebCore::Page(pageClients);
554     if (!priv->page) {
555         CRITICAL("Could not create WebKit Page");
556         goto error_page;
557     }
558
559     priv->page_settings = priv->page->settings();
560     if (!priv->page_settings) {
561         CRITICAL("Could not get page settings.");
562         goto error_settings;
563     }
564
565     priv->page_settings->setLoadsImagesAutomatically(true);
566     priv->page_settings->setDefaultFixedFontSize(12);
567     priv->page_settings->setDefaultFontSize(16);
568     priv->page_settings->setSerifFontFamily("serif");
569     priv->page_settings->setFixedFontFamily("monotype");
570     priv->page_settings->setSansSerifFontFamily("sans");
571     priv->page_settings->setStandardFontFamily("sans");
572     priv->page_settings->setJavaScriptEnabled(true);
573     priv->page_settings->setPluginsEnabled(true);
574     priv->page_settings->setLocalStorageEnabled(true);
575     priv->page_settings->setOfflineWebApplicationCacheEnabled(true);
576     priv->page_settings->setUsesPageCache(true);
577     priv->page_settings->setUsesEncodingDetector(true);
578
579     url = priv->page_settings->userStyleSheetLocation();
580     priv->settings.user_stylesheet = eina_stringshare_add(url.prettyURL().utf8().data());
581
582     priv->settings.encoding_default = eina_stringshare_add
583         (priv->page_settings->defaultTextEncodingName().utf8().data());
584     priv->settings.encoding_custom = 0;
585
586     priv->settings.cache_directory = eina_stringshare_add
587         (WebCore::cacheStorage().cacheDirectory().utf8().data());
588
589     s = priv->page_settings->localStorageDatabasePath();
590     priv->settings.local_storage_database_path = eina_stringshare_add(s.string().utf8().data());
591
592     priv->settings.font_minimum_size = priv->page_settings->minimumFontSize();
593     priv->settings.font_minimum_logical_size = priv->page_settings->minimumLogicalFontSize();
594     priv->settings.font_default_size = priv->page_settings->defaultFontSize();
595     priv->settings.font_monospace_size = priv->page_settings->defaultFixedFontSize();
596
597     s = priv->page_settings->standardFontFamily();
598     priv->settings.font_standard = eina_stringshare_add(s.string().utf8().data());
599     s = priv->page_settings->cursiveFontFamily();
600     priv->settings.font_cursive = eina_stringshare_add(s.string().utf8().data());
601     s = priv->page_settings->fixedFontFamily();
602     priv->settings.font_monospace = eina_stringshare_add(s.string().utf8().data());
603     s = priv->page_settings->fantasyFontFamily();
604     priv->settings.font_fantasy = eina_stringshare_add(s.string().utf8().data());
605     s = priv->page_settings->serifFontFamily();
606     priv->settings.font_serif = eina_stringshare_add(s.string().utf8().data());
607     s = priv->page_settings->sansSerifFontFamily();
608     priv->settings.font_sans_serif = eina_stringshare_add(s.string().utf8().data());
609
610     priv->settings.auto_load_images = priv->page_settings->loadsImagesAutomatically();
611     priv->settings.auto_shrink_images = priv->page_settings->shrinksStandaloneImagesToFit();
612     priv->settings.enable_auto_resize_window = EINA_TRUE;
613     priv->settings.enable_scripts = priv->page_settings->isJavaScriptEnabled();
614     priv->settings.enable_plugins = priv->page_settings->arePluginsEnabled();
615     priv->settings.enable_frame_flattening = priv->page_settings->frameFlatteningEnabled();
616     priv->settings.scripts_window_open = priv->page_settings->allowScriptsToCloseWindows();
617     priv->settings.resizable_textareas = priv->page_settings->textAreasAreResizable();
618     priv->settings.private_browsing = priv->page_settings->privateBrowsingEnabled();
619     priv->settings.caret_browsing = priv->page_settings->caretBrowsingEnabled();
620     priv->settings.local_storage = priv->page_settings->localStorageEnabled();
621     priv->settings.offline_app_cache = true; // XXX no function to read setting; this keeps the original setting
622     priv->settings.page_cache = priv->page_settings->usesPageCache();
623     priv->settings.encoding_detector = priv->page_settings->usesEncodingDetector();
624
625     // Since there's no scale separated from zooming in webkit-efl, this functionality of
626     // viewport meta tag is implemented using zoom. When scale zoom is supported by webkit-efl,
627     // this functionality will be modified by the scale zoom patch.
628     priv->settings.zoom_range.min_scale = ZOOM_MIN;
629     priv->settings.zoom_range.max_scale = ZOOM_MAX;
630     priv->settings.zoom_range.user_scalable = EINA_TRUE;
631     priv->settings.device_pixel_ratio = DEVICE_PIXEL_RATIO;
632
633     priv->main_frame = _ewk_view_core_frame_new(sd, priv, 0).get();
634     if (!priv->main_frame) {
635         CRITICAL("Could not create main frame.");
636         goto error_main_frame;
637     }
638
639     priv->history = ewk_history_new(static_cast<WebCore::BackForwardListImpl*>(priv->page->backForwardList()));
640     if (!priv->history) {
641         CRITICAL("Could not create history instance for view.");
642         goto error_history;
643     }
644
645     return priv;
646
647 error_history:
648     // delete priv->main_frame; /* do not delete priv->main_frame */
649 error_main_frame:
650 error_settings:
651     delete priv->page;
652 error_page:
653     free(priv);
654     return 0;
655 }
656
657 static void _ewk_view_priv_del(Ewk_View_Private_Data* priv)
658 {
659     if (!priv)
660         return;
661
662     /* do not delete priv->main_frame */
663
664     free(priv->repaints.array);
665     free(priv->scrolls.array);
666
667     eina_stringshare_del(priv->settings.user_agent);
668     eina_stringshare_del(priv->settings.user_stylesheet);
669     eina_stringshare_del(priv->settings.encoding_default);
670     eina_stringshare_del(priv->settings.encoding_custom);
671     eina_stringshare_del(priv->settings.cache_directory);
672     eina_stringshare_del(priv->settings.font_standard);
673     eina_stringshare_del(priv->settings.font_cursive);
674     eina_stringshare_del(priv->settings.font_monospace);
675     eina_stringshare_del(priv->settings.font_fantasy);
676     eina_stringshare_del(priv->settings.font_serif);
677     eina_stringshare_del(priv->settings.font_sans_serif);
678     eina_stringshare_del(priv->settings.local_storage_database_path);
679
680     if (priv->animated_zoom.animator)
681         ecore_animator_del(priv->animated_zoom.animator);
682
683     ewk_history_free(priv->history);
684
685     delete priv->page;
686     free(priv);
687 }
688
689 static void _ewk_view_smart_add(Evas_Object* o)
690 {
691     const Evas_Smart* smart = evas_object_smart_smart_get(o);
692     const Evas_Smart_Class* sc = evas_smart_class_get(smart);
693     const Ewk_View_Smart_Class* api = (const Ewk_View_Smart_Class*)sc;
694     EINA_SAFETY_ON_NULL_RETURN(api->backing_store_add);
695     EWK_VIEW_SD_GET(o, sd);
696
697     if (!sd) {
698         sd = (Ewk_View_Smart_Data*)calloc(1, sizeof(Ewk_View_Smart_Data));
699         if (!sd)
700             CRITICAL("could not allocate Ewk_View_Smart_Data");
701         else
702             evas_object_smart_data_set(o, sd);
703     }
704
705     sd->bg_color.r = 255;
706     sd->bg_color.g = 255;
707     sd->bg_color.b = 255;
708     sd->bg_color.a = 255;
709
710     sd->self = o;
711     sd->_priv = _ewk_view_priv_new(sd);
712     sd->api = api;
713
714     _parent_sc.add(o);
715
716     if (!sd->_priv)
717         return;
718
719     EWK_VIEW_PRIV_GET(sd, priv);
720
721     sd->backing_store = api->backing_store_add(sd);
722     if (!sd->backing_store) {
723         ERR("Could not create backing store object.");
724         return;
725     }
726
727     evas_object_smart_member_add(sd->backing_store, o);
728     evas_object_show(sd->backing_store);
729     evas_object_pass_events_set(sd->backing_store, EINA_TRUE);
730
731     sd->events_rect = evas_object_rectangle_add(sd->base.evas);
732     evas_object_color_set(sd->events_rect, 0, 0, 0, 0);
733     evas_object_smart_member_add(sd->events_rect, o);
734     evas_object_show(sd->events_rect);
735
736     sd->main_frame = ewk_frame_add(sd->base.evas);
737     if (!sd->main_frame) {
738         ERR("Could not create main frame object.");
739         return;
740     }
741
742     if (!ewk_frame_init(sd->main_frame, o, priv->main_frame)) {
743         ERR("Could not initialize main frme object.");
744         evas_object_del(sd->main_frame);
745         sd->main_frame = 0;
746
747         delete priv->main_frame;
748         priv->main_frame = 0;
749         return;
750     }
751
752     evas_object_name_set(sd->main_frame, "EWK_Frame:main");
753     evas_object_smart_member_add(sd->main_frame, o);
754     evas_object_show(sd->main_frame);
755
756 #define CONNECT(s, c) evas_object_event_callback_add(o, s, c, sd)
757     CONNECT(EVAS_CALLBACK_FOCUS_IN, _ewk_view_on_focus_in);
758     CONNECT(EVAS_CALLBACK_FOCUS_OUT, _ewk_view_on_focus_out);
759     CONNECT(EVAS_CALLBACK_MOUSE_WHEEL, _ewk_view_on_mouse_wheel);
760     CONNECT(EVAS_CALLBACK_MOUSE_DOWN, _ewk_view_on_mouse_down);
761     CONNECT(EVAS_CALLBACK_MOUSE_UP, _ewk_view_on_mouse_up);
762     CONNECT(EVAS_CALLBACK_MOUSE_MOVE, _ewk_view_on_mouse_move);
763     CONNECT(EVAS_CALLBACK_KEY_DOWN, _ewk_view_on_key_down);
764     CONNECT(EVAS_CALLBACK_KEY_UP, _ewk_view_on_key_up);
765 #undef CONNECT
766 }
767
768 static void _ewk_view_smart_del(Evas_Object* o)
769 {
770     EWK_VIEW_SD_GET(o, sd);
771     Ewk_View_Private_Data* priv = sd ? sd->_priv : 0;
772
773     ewk_view_stop(o);
774     _parent_sc.del(o);
775     _ewk_view_priv_del(priv);
776 }
777
778 static void _ewk_view_smart_resize(Evas_Object* o, Evas_Coord w, Evas_Coord h)
779 {
780     EWK_VIEW_SD_GET(o, sd);
781
782     // these should be queued and processed in calculate as well!
783     evas_object_resize(sd->backing_store, w, h);
784
785     sd->changed.size = EINA_TRUE;
786     _ewk_view_smart_changed(sd);
787 }
788
789 static void _ewk_view_smart_move(Evas_Object* o, Evas_Coord x, Evas_Coord y)
790 {
791     EWK_VIEW_SD_GET(o, sd);
792     sd->changed.position = EINA_TRUE;
793     _ewk_view_smart_changed(sd);
794 }
795
796 static void _ewk_view_smart_calculate(Evas_Object* o)
797 {
798     EWK_VIEW_SD_GET(o, sd);
799     EWK_VIEW_PRIV_GET(sd, priv);
800     EINA_SAFETY_ON_NULL_RETURN(sd->api->contents_resize);
801     EINA_SAFETY_ON_NULL_RETURN(sd->api->scrolls_process);
802     EINA_SAFETY_ON_NULL_RETURN(sd->api->repaints_process);
803     Evas_Coord x, y, w, h;
804
805     sd->changed.any = EINA_FALSE;
806
807     if (!sd->main_frame || !priv->main_frame)
808         return;
809
810     evas_object_geometry_get(o, &x, &y, &w, &h);
811
812     DBG("o=%p geo=[%d, %d + %dx%d], changed: size=%hhu, "
813         "scrolls=%zu, repaints=%zu",
814         o, x, y, w, h, sd->changed.size,
815         priv->scrolls.count, priv->repaints.count);
816
817     if (sd->changed.size && ((w != sd->view.w) || (h != sd->view.h))) {
818         WebCore::FrameView* view = priv->main_frame->view();
819         if (view) {
820             view->resize(w, h);
821             view->forceLayout();
822             view->adjustViewSize();
823         }
824         evas_object_resize(sd->main_frame, w, h);
825         evas_object_resize(sd->events_rect, w, h);
826         sd->changed.frame_rect = EINA_TRUE;
827         sd->view.w = w;
828         sd->view.h = h;
829
830         // This callback is a good place e.g. to change fixed layout size (ewk_view_fixed_layout_size_set).
831         evas_object_smart_callback_call(o, "view,resized", 0);
832     }
833     sd->changed.size = EINA_FALSE;
834
835     if (sd->changed.position && ((x != sd->view.x) || (y != sd->view.y))) {
836         evas_object_move(sd->main_frame, x, y);
837         evas_object_move(sd->backing_store, x, y);
838         evas_object_move(sd->events_rect, x, y);
839         sd->changed.frame_rect = EINA_TRUE;
840         sd->view.x = x;
841         sd->view.y = y;
842     }
843     sd->changed.position = EINA_FALSE;
844
845     ewk_view_layout_if_needed_recursive(sd->_priv);
846
847     if (!sd->api->scrolls_process(sd))
848         ERR("failed to process scrolls.");
849     _ewk_view_scrolls_flush(priv);
850
851     if (!sd->api->repaints_process(sd))
852         ERR("failed to process repaints.");
853     _ewk_view_repaints_flush(priv);
854
855     if (sd->changed.frame_rect) {
856         WebCore::FrameView* view = priv->main_frame->view();
857         view->frameRectsChanged(); /* force tree to get position from root */
858         sd->changed.frame_rect = EINA_FALSE;
859     }
860 }
861
862 static void _ewk_view_smart_show(Evas_Object *o)
863 {
864     EWK_VIEW_SD_GET(o, sd);
865     EWK_VIEW_PRIV_GET(sd, priv);
866
867     if (evas_object_clipees_get(sd->base.clipper))
868         evas_object_show(sd->base.clipper);
869     evas_object_show(sd->backing_store);
870 }
871
872 static void _ewk_view_smart_hide(Evas_Object *o)
873 {
874     EWK_VIEW_SD_GET(o, sd);
875     EWK_VIEW_PRIV_GET(sd, priv);
876
877     evas_object_hide(sd->base.clipper);
878     evas_object_hide(sd->backing_store);
879 }
880
881 static Eina_Bool _ewk_view_smart_contents_resize(Ewk_View_Smart_Data* sd, int w, int h)
882 {
883     return EINA_TRUE;
884 }
885
886 static Eina_Bool _ewk_view_smart_zoom_set(Ewk_View_Smart_Data* sd, float zoom, Evas_Coord cx, Evas_Coord cy)
887 {
888     double px, py;
889     Evas_Coord x, y, w, h;
890     Eina_Bool ret;
891
892     ewk_frame_scroll_size_get(sd->main_frame, &w, &h);
893     ewk_frame_scroll_pos_get(sd->main_frame, &x, &y);
894
895     if (w + sd->view.w > 0)
896         px = (double)(x + cx) / (w + sd->view.w);
897     else
898         px = 0.0;
899
900     if (h + sd->view.h > 0)
901         py = (double)(y + cy) / (h + sd->view.h);
902     else
903         py = 0.0;
904
905     ret = ewk_frame_zoom_set(sd->main_frame, zoom);
906
907     ewk_frame_scroll_size_get(sd->main_frame, &w, &h);
908     x = (w + sd->view.w) * px - cx;
909     y = (h + sd->view.h) * py - cy;
910     ewk_frame_scroll_set(sd->main_frame, x, y);
911     return ret;
912 }
913
914 static void _ewk_view_smart_flush(Ewk_View_Smart_Data* sd)
915 {
916     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv);
917     _ewk_view_repaints_flush(priv);
918     _ewk_view_scrolls_flush(priv);
919 }
920
921 static Eina_Bool _ewk_view_smart_pre_render_region(Ewk_View_Smart_Data* sd, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h, float zoom)
922 {
923     WRN("not supported by engine. sd=%p area=%d,%d+%dx%d, zoom=%f",
924         sd, x, y, w, h, zoom);
925     return EINA_FALSE;
926 }
927
928 static Eina_Bool _ewk_view_smart_pre_render_relative_radius(Ewk_View_Smart_Data* sd, unsigned int n, float zoom)
929 {
930     WRN("not supported by engine. sd=%p, n=%u zoom=%f",
931         sd, n, zoom);
932     return EINA_FALSE;
933 }
934
935 static void _ewk_view_smart_pre_render_cancel(Ewk_View_Smart_Data* sd)
936 {
937     WRN("not supported by engine. sd=%p", sd);
938 }
939
940 static void _ewk_view_zoom_animated_mark_stop(Ewk_View_Smart_Data* sd)
941 {
942     sd->animated_zoom.zoom.start = 0.0;
943     sd->animated_zoom.zoom.end = 0.0;
944     sd->animated_zoom.zoom.current = 0.0;
945 }
946
947 static void _ewk_view_zoom_animated_finish(Ewk_View_Smart_Data* sd)
948 {
949     EWK_VIEW_PRIV_GET(sd, priv);
950     ecore_animator_del(priv->animated_zoom.animator);
951     priv->animated_zoom.animator = 0;
952     _ewk_view_zoom_animated_mark_stop(sd);
953     evas_object_smart_callback_call(sd->self, "zoom,animated,end", 0);
954 }
955
956 static float _ewk_view_zoom_animated_current(Ewk_View_Private_Data* priv)
957 {
958     double now = ecore_loop_time_get();
959     double delta = now - priv->animated_zoom.time.start;
960
961     if (delta > priv->animated_zoom.time.duration)
962         delta = priv->animated_zoom.time.duration;
963     if (delta < 0.0) // time went back, clock adjusted?
964         delta = 0.0;
965
966     delta /= priv->animated_zoom.time.duration;
967
968     return ((priv->animated_zoom.zoom.range * delta)
969             + priv->animated_zoom.zoom.start);
970 }
971
972 static Eina_Bool _ewk_view_zoom_animator_cb(void* data)
973 {
974     Ewk_View_Smart_Data* sd = (Ewk_View_Smart_Data*)data;
975     Evas_Coord cx, cy;
976     EWK_VIEW_PRIV_GET(sd, priv);
977     double now = ecore_loop_time_get();
978
979     cx = priv->animated_zoom.center.x;
980     cy = priv->animated_zoom.center.y;
981
982     // TODO: progressively center (cx, cy) -> (view.x + view.h/2, view.y + view.h/2)
983     if (cx >= sd->view.w)
984         cx = sd->view.w - 1;
985     if (cy >= sd->view.h)
986         cy = sd->view.h - 1;
987
988     if ((now >= priv->animated_zoom.time.end)
989         || (now < priv->animated_zoom.time.start)) {
990         _ewk_view_zoom_animated_finish(sd);
991         ewk_view_zoom_set(sd->self, priv->animated_zoom.zoom.end, cx, cy);
992         sd->api->sc.calculate(sd->self);
993         return EINA_FALSE;
994     }
995
996     sd->animated_zoom.zoom.current = _ewk_view_zoom_animated_current(priv);
997     sd->api->zoom_weak_set(sd, sd->animated_zoom.zoom.current, cx, cy);
998     return EINA_TRUE;
999 }
1000
1001 static void _ewk_view_zoom_animation_start(Ewk_View_Smart_Data* sd)
1002 {
1003     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv);
1004     if (priv->animated_zoom.animator)
1005         return;
1006     priv->animated_zoom.animator = ecore_animator_add
1007         (_ewk_view_zoom_animator_cb, sd);
1008 }
1009
1010 static WebCore::ViewportAttributes _ewk_view_viewport_attributes_compute(Evas_Object* o)
1011 {
1012     EWK_VIEW_SD_GET(o, sd);
1013     EWK_VIEW_PRIV_GET(sd, priv);
1014
1015     int desktop_width = 980;
1016     int device_dpi = 160;
1017
1018     int available_width = (int) priv->page->chrome()->client()->pageRect().width();
1019     int available_height = (int) priv->page->chrome()->client()->pageRect().height();
1020
1021     int device_width = (int) priv->page->chrome()->client()->windowRect().width();
1022     int device_height = (int) priv->page->chrome()->client()->windowRect().height();
1023
1024     IntSize available_size = IntSize(available_width, available_height);
1025     WebCore::ViewportAttributes attributes = WebCore::computeViewportAttributes(priv->viewport_arguments, desktop_width, device_width, device_height, device_dpi, available_size);
1026
1027     return attributes;
1028 }
1029
1030 static Eina_Bool _ewk_view_smart_disable_render(Ewk_View_Smart_Data *sd)
1031 {
1032     WRN("not supported by engine. sd=%p", sd);
1033     return EINA_FALSE;
1034 }
1035
1036 static Eina_Bool _ewk_view_smart_enable_render(Ewk_View_Smart_Data *sd)
1037 {
1038     WRN("not supported by engine. sd=%p", sd);
1039     return EINA_FALSE;
1040 }
1041
1042 /**
1043  * Sets the smart class api without any backing store, enabling view
1044  * to be inherited.
1045  *
1046  * @param api class definition to be set, all members with the
1047  *        exception of Evas_Smart_Class->data may be overridden. Must
1048  *        @b not be @c 0.
1049  *
1050  * @note Evas_Smart_Class->data is used to implement type checking and
1051  *       is not supposed to be changed/overridden. If you need extra
1052  *       data for your smart class to work, just extend
1053  *       Ewk_View_Smart_Class instead.
1054  *
1055  * @return @c EINA_TRUE on success, @c EINA_FALSE on failure (probably
1056  *         version mismatch).
1057  *
1058  * @see ewk_view_single_smart_set()
1059  * @see ewk_view_tiled_smart_set()
1060  */
1061 Eina_Bool ewk_view_base_smart_set(Ewk_View_Smart_Class* api)
1062 {
1063     EINA_SAFETY_ON_NULL_RETURN_VAL(api, EINA_FALSE);
1064
1065     if (api->version != EWK_VIEW_SMART_CLASS_VERSION) {
1066         EINA_LOG_CRIT
1067             ("Ewk_View_Smart_Class %p is version %lu while %lu was expected.",
1068              api, api->version, EWK_VIEW_SMART_CLASS_VERSION);
1069         return EINA_FALSE;
1070     }
1071
1072     if (EINA_UNLIKELY(!_parent_sc.add))
1073         evas_object_smart_clipped_smart_set(&_parent_sc);
1074
1075     evas_object_smart_clipped_smart_set(&api->sc);
1076     api->sc.add = _ewk_view_smart_add;
1077     api->sc.del = _ewk_view_smart_del;
1078     api->sc.resize = _ewk_view_smart_resize;
1079     api->sc.move = _ewk_view_smart_move;
1080     api->sc.calculate = _ewk_view_smart_calculate;
1081     api->sc.show = _ewk_view_smart_show;
1082     api->sc.hide = _ewk_view_smart_hide;
1083     api->sc.data = EWK_VIEW_TYPE_STR; /* used by type checking */
1084
1085     api->contents_resize = _ewk_view_smart_contents_resize;
1086     api->zoom_set = _ewk_view_smart_zoom_set;
1087     api->flush = _ewk_view_smart_flush;
1088     api->pre_render_region = _ewk_view_smart_pre_render_region;
1089     api->pre_render_relative_radius = _ewk_view_smart_pre_render_relative_radius;
1090     api->pre_render_cancel = _ewk_view_smart_pre_render_cancel;
1091     api->disable_render = _ewk_view_smart_disable_render;
1092     api->enable_render = _ewk_view_smart_enable_render;
1093
1094     api->focus_in = _ewk_view_smart_focus_in;
1095     api->focus_out = _ewk_view_smart_focus_out;
1096     api->mouse_wheel = _ewk_view_smart_mouse_wheel;
1097     api->mouse_down = _ewk_view_smart_mouse_down;
1098     api->mouse_up = _ewk_view_smart_mouse_up;
1099     api->mouse_move = _ewk_view_smart_mouse_move;
1100     api->key_down = _ewk_view_smart_key_down;
1101     api->key_up = _ewk_view_smart_key_up;
1102
1103     api->add_console_message = _ewk_view_smart_add_console_message;
1104     api->run_javascript_alert = _ewk_view_smart_run_javascript_alert;
1105     api->run_javascript_confirm = _ewk_view_smart_run_javascript_confirm;
1106     api->run_javascript_prompt = _ewk_view_smart_run_javascript_prompt;
1107     api->should_interrupt_javascript = _ewk_view_smart_should_interrupt_javascript;
1108
1109     return EINA_TRUE;
1110 }
1111
1112 /**
1113  * Set a fixed layout size to be used, dissociating it from viewport size.
1114  *
1115  * Setting a width different than zero enables fixed layout on that
1116  * size. It's automatically scaled based on zoom, but will not change
1117  * if viewport changes.
1118  *
1119  * Setting both @a w and @a h to zero will disable fixed layout.
1120  *
1121  * @param o view object to change fixed layout.
1122  * @param w fixed width to use. This size will be automatically scaled
1123  *        based on zoom level.
1124  * @param h fixed height to use. This size will be automatically scaled
1125  *        based on zoom level.
1126  */
1127 void ewk_view_fixed_layout_size_set(Evas_Object* o, Evas_Coord w, Evas_Coord h)
1128 {
1129     EWK_VIEW_SD_GET_OR_RETURN(o, sd);
1130     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv);
1131
1132     WebCore::FrameView* view = sd->_priv->main_frame->view();
1133     if (w <= 0 && h <= 0) {
1134         if (!priv->fixed_layout.use)
1135             return;
1136         priv->fixed_layout.w = 0;
1137         priv->fixed_layout.h = 0;
1138         priv->fixed_layout.use = EINA_FALSE;
1139     } else {
1140         if (priv->fixed_layout.use
1141             && priv->fixed_layout.w == w && priv->fixed_layout.h == h)
1142             return;
1143         priv->fixed_layout.w = w;
1144         priv->fixed_layout.h = h;
1145         priv->fixed_layout.use = EINA_TRUE;
1146
1147         if (view)
1148             view->setFixedLayoutSize(WebCore::IntSize(w, h));
1149     }
1150
1151     if (!view)
1152         return;
1153     view->setUseFixedLayout(priv->fixed_layout.use);
1154     view->forceLayout();
1155 }
1156
1157 /**
1158  * Get fixed layout size in use.
1159  *
1160  * @param o view object to query fixed layout size.
1161  * @param w where to return width. Returns 0 on error or if no fixed
1162  *        layout in use.
1163  * @param h where to return height. Returns 0 on error or if no fixed
1164  *        layout in use.
1165  */
1166 void ewk_view_fixed_layout_size_get(Evas_Object* o, Evas_Coord* w, Evas_Coord* h)
1167 {
1168     if (w)
1169         *w = 0;
1170     if (h)
1171         *h = 0;
1172     EWK_VIEW_SD_GET_OR_RETURN(o, sd);
1173     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv);
1174     if (priv->fixed_layout.use) {
1175         if (w)
1176             *w = priv->fixed_layout.w;
1177         if (h)
1178             *h = priv->fixed_layout.h;
1179     }
1180 }
1181
1182 /**
1183  * Set the theme path to be used by this view.
1184  *
1185  * This also sets the theme on the main frame. As frames inherit theme
1186  * from their parent, this will have all frames with unset theme to
1187  * use this one.
1188  *
1189  * @param o view object to change theme.
1190  * @param path theme path, may be @c 0 to reset to default.
1191  */
1192 void ewk_view_theme_set(Evas_Object* o, const char* path)
1193 {
1194     EWK_VIEW_SD_GET_OR_RETURN(o, sd);
1195     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv);
1196     if (!eina_stringshare_replace(&priv->settings.theme, path))
1197         return;
1198     ewk_frame_theme_set(sd->main_frame, path);
1199 }
1200
1201 /**
1202  * Gets the theme set on this frame.
1203  *
1204  * This returns the value set by ewk_view_theme_set().
1205  *
1206  * @param o view object to get theme path.
1207  *
1208  * @return theme path, may be @c 0 if not set.
1209  */
1210 const char* ewk_view_theme_get(Evas_Object* o)
1211 {
1212     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
1213     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0);
1214     return priv->settings.theme;
1215 }
1216
1217 /**
1218  * Get the object that represents the main frame.
1219  *
1220  * @param o view object to get main frame.
1221  *
1222  * @return ewk_frame object or @c 0 if none yet.
1223  */
1224 Evas_Object* ewk_view_frame_main_get(const Evas_Object* o)
1225 {
1226     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
1227     return sd->main_frame;
1228 }
1229
1230 /**
1231  * Get the currently focused frame object.
1232  *
1233  * @param o view object to get focused frame.
1234  *
1235  * @return ewk_frame object or @c 0 if none yet.
1236  */
1237 Evas_Object* ewk_view_frame_focused_get(const Evas_Object* o)
1238 {
1239     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
1240     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0);
1241
1242     WebCore::Frame* core = priv->page->focusController()->focusedFrame();
1243     if (!core)
1244         return 0;
1245
1246     WebCore::FrameLoaderClientEfl* client = static_cast<WebCore::FrameLoaderClientEfl*>(core->loader()->client());
1247     if (!client)
1248         return 0;
1249     return client->webFrame();
1250 }
1251
1252 /**
1253  * Ask main frame to load the given URI.
1254  *
1255  * @param o view object to load uri.
1256  * @param uri uniform resource identifier to load.
1257  *
1258  * @return @c EINA_TRUE on successful request, @c EINA_FALSE on failure.
1259  *         Note that it means the request was done, not that it was
1260  *         satisfied.
1261  */
1262 Eina_Bool ewk_view_uri_set(Evas_Object* o, const char* uri)
1263 {
1264     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1265     return ewk_frame_uri_set(sd->main_frame, uri);
1266 }
1267
1268 /**
1269  * Get the current uri loaded by main frame.
1270  *
1271  * @param o view object to get current uri.
1272  *
1273  * @return current uri reference or @c 0. It's internal, don't change.
1274  */
1275 const char* ewk_view_uri_get(const Evas_Object* o)
1276 {
1277     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
1278     return ewk_frame_uri_get(sd->main_frame);
1279 }
1280
1281 /**
1282  * Get the current title of main frame.
1283  *
1284  * @param o view object to get current title.
1285  *
1286  * @return current title reference or @c 0. It's internal, don't change.
1287  */
1288 const char* ewk_view_title_get(const Evas_Object* o)
1289 {
1290     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
1291     return ewk_frame_title_get(sd->main_frame);
1292 }
1293
1294 /**
1295  * Gets if main frame is editable.
1296  *
1297  * @param o view object to get editable state.
1298  *
1299  * @return @c EINA_TRUE if editable, @c EINA_FALSE otherwise.
1300  */
1301 Eina_Bool ewk_view_editable_get(const Evas_Object* o)
1302 {
1303     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1304     return ewk_frame_editable_get(sd->main_frame);
1305 }
1306
1307 /**
1308  * Set background color and transparency
1309  *
1310  * Just as in Evas, colors are pre-multiplied, so 50% red is
1311  * (128, 0, 0, 128) and not (255, 0, 0, 128)!
1312  *
1313  * @warning Watch out performance issues with transparency! Object
1314  *          will be handled as transparent image by evas even if the
1315  *          webpage specifies a background color. That mean you'll pay
1316  *          a price even if it's not really transparent, thus
1317  *          scrolling/panning and zooming will be likely slower than
1318  *          if transparency is off.
1319  *
1320  * @param o view object to change.
1321  * @param r red component.
1322  * @param g green component.
1323  * @param b blue component.
1324  * @param a transparency.
1325  */
1326 void ewk_view_bg_color_set(Evas_Object* o, int r, int g, int b, int a)
1327 {
1328     EWK_VIEW_SD_GET_OR_RETURN(o, sd);
1329     EINA_SAFETY_ON_NULL_RETURN(sd->api);
1330     EINA_SAFETY_ON_NULL_RETURN(sd->api->bg_color_set);
1331
1332     if (a < 0) {
1333         WRN("Alpha less than zero (%d).", a);
1334         a = 0;
1335     } else if (a > 255) {
1336         WRN("Alpha is larger than 255 (%d).", a);
1337         a = 255;
1338     }
1339
1340 #define CHECK_PREMUL_COLOR(c, a)                                        \
1341     if (c < 0) {                                                        \
1342         WRN("Color component "#c" is less than zero (%d).", c);         \
1343         c = 0;                                                          \
1344     } else if (c > a) {                                                 \
1345         WRN("Color component "#c" is greater than alpha (%d, alpha=%d).", \
1346             c, a);                                                      \
1347         c = a;                                                          \
1348     }
1349     CHECK_PREMUL_COLOR(r, a);
1350     CHECK_PREMUL_COLOR(g, a);
1351     CHECK_PREMUL_COLOR(b, a);
1352 #undef CHECK_PREMUL_COLOR
1353
1354     sd->bg_color.r = r;
1355     sd->bg_color.g = g;
1356     sd->bg_color.b = b;
1357     sd->bg_color.a = a;
1358
1359     sd->api->bg_color_set(sd, r, g, b, a);
1360
1361     WebCore::FrameView* view = sd->_priv->main_frame->view();
1362     if (view) {
1363         WebCore::Color color;
1364
1365         if (!a)
1366             color = WebCore::Color(0, 0, 0, 0);
1367         else if (a == 255)
1368             color = WebCore::Color(r, g, b, a);
1369         else
1370             color = WebCore::Color(r * 255 / a, g * 255 / a, b * 255 / a, a);
1371
1372         view->updateBackgroundRecursively(color, !a);
1373     }
1374 }
1375
1376 /**
1377  * Query if view object background color.
1378  *
1379  * Just as in Evas, colors are pre-multiplied, so 50% red is
1380  * (128, 0, 0, 128) and not (255, 0, 0, 128)!
1381  *
1382  * @param o view object to query.
1383  * @param r where to return red color component.
1384  * @param g where to return green color component.
1385  * @param b where to return blue color component.
1386  * @param a where to return alpha value.
1387  */
1388 void ewk_view_bg_color_get(const Evas_Object* o, int* r, int* g, int* b, int* a)
1389 {
1390     if (r)
1391         *r = 0;
1392     if (g)
1393         *g = 0;
1394     if (b)
1395         *b = 0;
1396     if (a)
1397         *a = 0;
1398     EWK_VIEW_SD_GET_OR_RETURN(o, sd);
1399     if (r)
1400         *r = sd->bg_color.r;
1401     if (g)
1402         *g = sd->bg_color.g;
1403     if (b)
1404         *b = sd->bg_color.b;
1405     if (a)
1406         *a = sd->bg_color.a;
1407 }
1408
1409 /**
1410  * Search the given text string in document.
1411  *
1412  * @param o view object where to search text.
1413  * @param string reference string to search.
1414  * @param case_sensitive if search should be case sensitive or not.
1415  * @param forward if search is from cursor and on or backwards.
1416  * @param wrap if search should wrap at end.
1417  *
1418  * @return @c EINA_TRUE if found, @c EINA_FALSE if not or failure.
1419  */
1420 Eina_Bool ewk_view_text_search(const Evas_Object* o, const char* string, Eina_Bool case_sensitive, Eina_Bool forward, Eina_Bool wrap)
1421 {
1422     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1423     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
1424     EINA_SAFETY_ON_NULL_RETURN_VAL(string, EINA_FALSE);
1425     WTF::TextCaseSensitivity sensitive;
1426     WebCore::FindDirection direction;
1427
1428     if (case_sensitive)
1429         sensitive = WTF::TextCaseSensitive;
1430     else
1431         sensitive = WTF::TextCaseInsensitive;
1432
1433     if (forward)
1434         direction = WebCore::FindDirectionForward;
1435     else
1436         direction = WebCore::FindDirectionBackward;
1437
1438     return priv->page->findString(WTF::String::fromUTF8(string), sensitive, direction, wrap);
1439 }
1440
1441 /**
1442  * Mark matches the given text string in document.
1443  *
1444  * @param o view object where to search text.
1445  * @param string reference string to match.
1446  * @param case_sensitive if match should be case sensitive or not.
1447  * @param highlight if matches should be highlighted.
1448  * @param limit maximum amount of matches, or zero to unlimited.
1449  *
1450  * @return number of matches.
1451  */
1452 unsigned int ewk_view_text_matches_mark(Evas_Object* o, const char* string, Eina_Bool case_sensitive, Eina_Bool highlight, unsigned int limit)
1453 {
1454     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
1455     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0);
1456     EINA_SAFETY_ON_NULL_RETURN_VAL(string, 0);
1457     WTF::TextCaseSensitivity sensitive;
1458
1459     if (case_sensitive)
1460         sensitive = WTF::TextCaseSensitive;
1461     else
1462         sensitive = WTF::TextCaseInsensitive;
1463
1464     return priv->page->markAllMatchesForText(WTF::String::fromUTF8(string), sensitive, highlight, limit);
1465 }
1466
1467 /**
1468  * Reverses the effect of ewk_view_text_matches_mark()
1469  *
1470  * @param o view object where to search text.
1471  *
1472  * @return @c EINA_TRUE on success, @c EINA_FALSE for failure.
1473  */
1474 Eina_Bool ewk_view_text_matches_unmark_all(Evas_Object* o)
1475 {
1476     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1477     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
1478     priv->page->unmarkAllTextMatches();
1479     return EINA_TRUE;
1480 }
1481
1482 /**
1483  * Set if should highlight matches marked with ewk_view_text_matches_mark().
1484  *
1485  * @param o view object where to set if matches are highlighted or not.
1486  * @param highlight if @c EINA_TRUE, matches will be highlighted.
1487  *
1488  * @return @c EINA_TRUE on success, @c EINA_FALSE for failure.
1489  */
1490 Eina_Bool ewk_view_text_matches_highlight_set(Evas_Object* o, Eina_Bool highlight)
1491 {
1492     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1493     return ewk_frame_text_matches_highlight_set(sd->main_frame, highlight);
1494 }
1495
1496 /**
1497  * Get if should highlight matches marked with ewk_view_text_matches_mark().
1498  *
1499  * @param o view object to query if matches are highlighted or not.
1500  *
1501  * @return @c EINA_TRUE if they are highlighted, @c EINA_FALSE otherwise.
1502  */
1503 Eina_Bool ewk_view_text_matches_highlight_get(const Evas_Object* o)
1504 {
1505     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1506     return ewk_frame_text_matches_highlight_get(sd->main_frame);
1507 }
1508
1509 /**
1510  * Sets if main frame is editable.
1511  *
1512  * @param o view object to set editable state.
1513  * @param editable new state.
1514  *
1515  * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
1516  */
1517 Eina_Bool ewk_view_editable_set(Evas_Object* o, Eina_Bool editable)
1518 {
1519     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1520     return ewk_frame_editable_set(sd->main_frame, editable);
1521 }
1522
1523 /**
1524  * Get the copy of the selection text.
1525  *
1526  * @param o view object to get selection text.
1527  *
1528  * @return newly allocated string or @c 0 if nothing is selected or failure.
1529  */
1530 char* ewk_view_selection_get(const Evas_Object* o)
1531 {
1532     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
1533     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0);
1534     WTF::CString s = priv->page->focusController()->focusedOrMainFrame()->editor()->selectedText().utf8();
1535     if (s.isNull())
1536         return 0;
1537     return strdup(s.data());
1538 }
1539
1540 static Eina_Bool _ewk_view_editor_command(Ewk_View_Private_Data* priv, const char* command)
1541 {
1542     return priv->page->focusController()->focusedOrMainFrame()->editor()->command(WTF::String::fromUTF8(command)).execute();
1543 }
1544
1545 /**
1546  * Unselects whatever was selected.
1547  *
1548  * @return @c EINA_TRUE if operation was executed, @c EINA_FALSE otherwise.
1549  */
1550 Eina_Bool ewk_view_select_none(Evas_Object* o)
1551 {
1552     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1553     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
1554     return _ewk_view_editor_command(priv, "Unselect");
1555 }
1556
1557 /**
1558  * Selects everything.
1559  *
1560  * @return @c EINA_TRUE if operation was executed, @c EINA_FALSE otherwise.
1561  */
1562 Eina_Bool ewk_view_select_all(Evas_Object* o)
1563 {
1564     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1565     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
1566     return _ewk_view_editor_command(priv, "SelectAll");
1567 }
1568
1569 /**
1570  * Selects the current paragrah.
1571  *
1572  * @return @c EINA_TRUE if operation was executed, @c EINA_FALSE otherwise.
1573  */
1574 Eina_Bool ewk_view_select_paragraph(Evas_Object* o)
1575 {
1576     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1577     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
1578     return _ewk_view_editor_command(priv, "SelectParagraph");
1579 }
1580
1581 /**
1582  * Selects the current sentence.
1583  *
1584  * @return @c EINA_TRUE if operation was executed, @c EINA_FALSE otherwise.
1585  */
1586 Eina_Bool ewk_view_select_sentence(Evas_Object* o)
1587 {
1588     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1589     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
1590     return _ewk_view_editor_command(priv, "SelectSentence");
1591 }
1592
1593 /**
1594  * Selects the current line.
1595  *
1596  * @return @c EINA_TRUE if operation was executed, @c EINA_FALSE otherwise.
1597  */
1598 Eina_Bool ewk_view_select_line(Evas_Object* o)
1599 {
1600     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1601     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
1602     return _ewk_view_editor_command(priv, "SelectLine");
1603 }
1604
1605 /**
1606  * Selects the current word.
1607  *
1608  * @return @c EINA_TRUE if operation was executed, @c EINA_FALSE otherwise.
1609  */
1610 Eina_Bool ewk_view_select_word(Evas_Object* o)
1611 {
1612     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1613     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
1614     return _ewk_view_editor_command(priv, "SelectWord");
1615 }
1616
1617 /**
1618  * Forwards a request of new Context Menu to WebCore.
1619  *
1620  * @param o View.
1621  * @param ev Event data.
1622  *
1623  * @return @c EINA_TRUE if operation was executed, @c EINA_FALSE otherwise.
1624  */
1625 Eina_Bool ewk_view_context_menu_forward_event(Evas_Object* o, const Evas_Event_Mouse_Down* ev)
1626 {
1627     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1628     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
1629     Eina_Bool mouse_press_handled = EINA_FALSE;
1630
1631     priv->page->contextMenuController()->clearContextMenu();
1632     WebCore::Frame* main_frame = priv->page->mainFrame();
1633     Evas_Coord x, y;
1634     evas_object_geometry_get(sd->self, &x, &y, 0, 0);
1635
1636     WebCore::PlatformMouseEvent event(ev, WebCore::IntPoint(x, y));
1637
1638     if (main_frame->view()) {
1639         mouse_press_handled =
1640             main_frame->eventHandler()->handleMousePressEvent(event);
1641     }
1642
1643     if (main_frame->eventHandler()->sendContextMenuEvent(event))
1644         return EINA_FALSE;
1645
1646     WebCore::ContextMenu* coreMenu =
1647         priv->page->contextMenuController()->contextMenu();
1648     if (!coreMenu) {
1649         // WebCore decided not to create a context menu, return true if event
1650         // was handled by handleMouseReleaseEvent
1651         return mouse_press_handled;
1652     }
1653
1654     return EINA_TRUE;
1655 }
1656
1657 /**
1658  * Get current load progress estimate from 0.0 to 1.0.
1659  *
1660  * @param o view object to get current progress.
1661  *
1662  * @return progres value from 0.0 to 1.0 or -1.0 on error.
1663  */
1664 double ewk_view_load_progress_get(const Evas_Object* o)
1665 {
1666     EWK_VIEW_SD_GET_OR_RETURN(o, sd, -1.0);
1667     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, -1.0);
1668     return priv->page->progress()->estimatedProgress();
1669 }
1670
1671 /**
1672  * Ask main frame to stop loading.
1673  *
1674  * @param o view object to stop loading.
1675  *
1676  * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
1677  *
1678  * @see ewk_frame_stop()
1679  */
1680 Eina_Bool ewk_view_stop(Evas_Object* o)
1681 {
1682     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1683     return ewk_frame_stop(sd->main_frame);
1684 }
1685
1686 /**
1687  * Ask main frame to reload current document.
1688  *
1689  * @param o view object to reload.
1690  *
1691  * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
1692  *
1693  * @see ewk_frame_reload()
1694  */
1695 Eina_Bool ewk_view_reload(Evas_Object* o)
1696 {
1697     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1698     return ewk_frame_reload(sd->main_frame);
1699 }
1700
1701 /**
1702  * Ask main frame to fully reload current document, using no caches.
1703  *
1704  * @param o view object to reload.
1705  *
1706  * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
1707  *
1708  * @see ewk_frame_reload_full()
1709  */
1710 Eina_Bool ewk_view_reload_full(Evas_Object* o)
1711 {
1712     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1713     return ewk_frame_reload_full(sd->main_frame);
1714 }
1715
1716 /**
1717  * Ask main frame to navigate back in history.
1718  *
1719  * @param o view object to navigate back.
1720  *
1721  * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
1722  *
1723  * @see ewk_frame_back()
1724  */
1725 Eina_Bool ewk_view_back(Evas_Object* o)
1726 {
1727     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1728     return ewk_frame_back(sd->main_frame);
1729 }
1730
1731 /**
1732  * Ask main frame to navigate forward in history.
1733  *
1734  * @param o view object to navigate forward.
1735  *
1736  * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
1737  *
1738  * @see ewk_frame_forward()
1739  */
1740 Eina_Bool ewk_view_forward(Evas_Object* o)
1741 {
1742     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1743     return ewk_frame_forward(sd->main_frame);
1744 }
1745
1746 /**
1747  * Navigate back or forward in history.
1748  *
1749  * @param o view object to navigate.
1750  * @param steps if positive navigates that amount forwards, if negative
1751  *        does backwards.
1752  *
1753  * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
1754  *
1755  * @see ewk_frame_navigate()
1756  */
1757 Eina_Bool ewk_view_navigate(Evas_Object* o, int steps)
1758 {
1759     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1760     return ewk_frame_navigate(sd->main_frame, steps);
1761 }
1762
1763 /**
1764  * Check if it is possible to navigate backwards one item in history.
1765  *
1766  * @param o view object to check if backward navigation is possible.
1767  *
1768  * @return @c EINA_TRUE if possible, @c EINA_FALSE otherwise.
1769  *
1770  * @see ewk_view_navigate_possible()
1771  */
1772 Eina_Bool ewk_view_back_possible(Evas_Object* o)
1773 {
1774     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1775     return ewk_frame_back_possible(sd->main_frame);
1776 }
1777
1778 /**
1779  * Check if it is possible to navigate forwards one item in history.
1780  *
1781  * @param o view object to check if forward navigation is possible.
1782  *
1783  * @return @c EINA_TRUE if possible, @c EINA_FALSE otherwise.
1784  *
1785  * @see ewk_view_navigate_possible()
1786  */
1787 Eina_Bool ewk_view_forward_possible(Evas_Object* o)
1788 {
1789     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1790     return ewk_frame_forward_possible(sd->main_frame);
1791 }
1792
1793 /**
1794  * Check if it is possible to navigate given @a steps in history.
1795  *
1796  * @param o view object to navigate.
1797  * @param steps if positive navigates that amount forwards, if negative
1798  *        does backwards.
1799  *
1800  * @return @c EINA_TRUE if possible, @c EINA_FALSE otherwise.
1801  */
1802 Eina_Bool ewk_view_navigate_possible(Evas_Object* o, int steps)
1803 {
1804     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1805     return ewk_frame_navigate_possible(sd->main_frame, steps);
1806 }
1807
1808 /**
1809  * Check if navigation history (back-forward lists) is enabled.
1810  *
1811  * @param o view object to check if navigation history is enabled.
1812  *
1813  * @return @c EINA_TRUE if view keeps history, @c EINA_FALSE otherwise.
1814  */
1815 Eina_Bool ewk_view_history_enable_get(const Evas_Object* o)
1816 {
1817     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1818     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
1819     return static_cast<WebCore::BackForwardListImpl*>(priv->page->backForwardList())->enabled();
1820 }
1821
1822 /**
1823  * Sets if navigation history (back-forward lists) is enabled.
1824  *
1825  * @param o view object to set if navigation history is enabled.
1826  * @param enable @c EINA_TRUE if we want to enable navigation history;
1827  * @c EINA_FALSE otherwise.
1828  *
1829  * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
1830  */
1831 Eina_Bool ewk_view_history_enable_set(Evas_Object* o, Eina_Bool enable)
1832 {
1833     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1834     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
1835     static_cast<WebCore::BackForwardListImpl*>(priv->page->backForwardList())->setEnabled(enable);
1836     return EINA_TRUE;
1837 }
1838
1839 /**
1840  * Gets the history (back-forward list) associated with this view.
1841  *
1842  * @param o view object to get navigation history from.
1843  *
1844  * @return returns the history instance handle associated with this
1845  *         view or @c 0 on errors (including when history is not
1846  *         enabled with ewk_view_history_enable_set()). This instance
1847  *         is unique for this view and thus multiple calls to this
1848  *         function with the same view as parameter returns the same
1849  *         handle. This handle is alive while view is alive, thus one
1850  *         might want to listen for EVAS_CALLBACK_DEL on given view
1851  *         (@a o) to know when to stop using returned handle.
1852  *
1853  * @see ewk_view_history_enable_set()
1854  */
1855 Ewk_History* ewk_view_history_get(const Evas_Object* o)
1856 {
1857     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
1858     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0);
1859     if (!static_cast<WebCore::BackForwardListImpl*>(priv->page->backForwardList())->enabled()) {
1860         ERR("asked history, but it's disabled! Returning 0!");
1861         return 0;
1862     }
1863     return priv->history;
1864 }
1865
1866 /**
1867  * Get the current zoom level of main frame.
1868  *
1869  * @param o view object to query zoom level.
1870  *
1871  * @return current zoom level in use or -1.0 on error.
1872  */
1873 float ewk_view_zoom_get(const Evas_Object* o)
1874 {
1875     EWK_VIEW_SD_GET_OR_RETURN(o, sd, -1.0);
1876     return ewk_frame_zoom_get(sd->main_frame);
1877 }
1878
1879 /**
1880  * Set the current zoom level of main frame.
1881  *
1882  * @param o view object to set zoom level.
1883  * @param zoom new level to use.
1884  * @param cx x of center coordinate
1885  * @param cy y of center coordinate
1886  *
1887  * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
1888  */
1889 Eina_Bool ewk_view_zoom_set(Evas_Object* o, float zoom, Evas_Coord cx, Evas_Coord cy)
1890 {
1891     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1892     EWK_VIEW_PRIV_GET(sd, priv);
1893
1894     EINA_SAFETY_ON_NULL_RETURN_VAL(sd->api, EINA_FALSE);
1895     EINA_SAFETY_ON_NULL_RETURN_VAL(sd->api->zoom_set, EINA_FALSE);
1896
1897     if (!priv->settings.zoom_range.user_scalable) {
1898         WRN("userScalable is false");
1899         return EINA_FALSE;
1900     }
1901
1902     if (zoom < priv->settings.zoom_range.min_scale) {
1903         WRN("zoom level is < %f : %f", (double)priv->settings.zoom_range.min_scale, (double)zoom);
1904         return EINA_FALSE;
1905     }
1906     if (zoom > priv->settings.zoom_range.max_scale) {
1907         WRN("zoom level is > %f : %f", (double)priv->settings.zoom_range.max_scale, (double)zoom);
1908         return EINA_FALSE;
1909     }
1910
1911     if (cx >= sd->view.w)
1912         cx = sd->view.w - 1;
1913     if (cy >= sd->view.h)
1914         cy = sd->view.h - 1;
1915     if (cx < 0)
1916         cx = 0;
1917     if (cy < 0)
1918         cy = 0;
1919     _ewk_view_zoom_animated_mark_stop(sd);
1920     return sd->api->zoom_set(sd, zoom, cx, cy);
1921 }
1922
1923 Eina_Bool ewk_view_zoom_weak_smooth_scale_get(const Evas_Object* o)
1924 {
1925     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1926     return sd->zoom_weak_smooth_scale;
1927 }
1928
1929 void ewk_view_zoom_weak_smooth_scale_set(Evas_Object* o, Eina_Bool smooth_scale)
1930 {
1931     EWK_VIEW_SD_GET_OR_RETURN(o, sd);
1932     smooth_scale = !!smooth_scale;
1933     if (sd->zoom_weak_smooth_scale == smooth_scale)
1934         return;
1935     sd->zoom_weak_smooth_scale = smooth_scale;
1936     EINA_SAFETY_ON_NULL_RETURN(sd->api);
1937     EINA_SAFETY_ON_NULL_RETURN(sd->api->zoom_weak_smooth_scale_set);
1938     sd->api->zoom_weak_smooth_scale_set(sd, smooth_scale);
1939 }
1940
1941 /**
1942  * Set the current zoom level of backing store, centered at given point.
1943  *
1944  * Unlike ewk_view_zoom_set(), this call do not ask WebKit to render
1945  * at new size, but scale what is already rendered, being much faster
1946  * but worse quality.
1947  *
1948  * Often one should use ewk_view_zoom_animated_set(), it will call the
1949  * same machinery internally.
1950  *
1951  * @note this will set variables used by ewk_view_zoom_animated_set()
1952  *       so sub-classes will not reset internal state on their
1953  *       "calculate" phase. To unset those and enable sub-classes to
1954  *       reset their internal state, call
1955  *       ewk_view_zoom_animated_mark_stop(). Namely, this call will
1956  *       set ewk_view_zoom_animated_mark_start() to actual webkit zoom
1957  *       level, ewk_view_zoom_animated_mark_end() and
1958  *       ewk_view_zoom_animated_mark_current() to given zoom level.
1959  *
1960  * @param o view object to set weak zoom level.
1961  * @param zoom level to scale backing store.
1962  * @param cx horizontal center offset, relative to object (w/2 is middle).
1963  * @param cy vertical center offset, relative to object (h/2 is middle).
1964  *
1965  * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
1966  */
1967 Eina_Bool ewk_view_zoom_weak_set(Evas_Object* o, float zoom, Evas_Coord cx, Evas_Coord cy)
1968 {
1969     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1970     EWK_VIEW_PRIV_GET(sd, priv);
1971
1972     EINA_SAFETY_ON_NULL_RETURN_VAL(sd->api, EINA_FALSE);
1973     EINA_SAFETY_ON_NULL_RETURN_VAL(sd->api->zoom_weak_set, EINA_FALSE);
1974
1975     if (!priv->settings.zoom_range.user_scalable) {
1976         WRN("userScalable is false");
1977         return EINA_FALSE;
1978     }
1979
1980     if (zoom < priv->settings.zoom_range.min_scale) {
1981         WRN("zoom level is < %f : %f", (double)priv->settings.zoom_range.min_scale, (double)zoom);
1982         return EINA_FALSE;
1983     }
1984     if (zoom > priv->settings.zoom_range.max_scale) {
1985         WRN("zoom level is > %f : %f", (double)priv->settings.zoom_range.max_scale, (double)zoom);
1986         return EINA_FALSE;
1987     }
1988
1989     if (cx >= sd->view.w)
1990         cx = sd->view.w - 1;
1991     if (cy >= sd->view.h)
1992         cy = sd->view.h - 1;
1993     if (cx < 0)
1994         cx = 0;
1995     if (cy < 0)
1996         cy = 0;
1997
1998     sd->animated_zoom.zoom.start = ewk_frame_zoom_get(sd->main_frame);
1999     sd->animated_zoom.zoom.end = zoom;
2000     sd->animated_zoom.zoom.current = zoom;
2001     return sd->api->zoom_weak_set(sd, zoom, cx, cy);
2002 }
2003
2004 /**
2005  * Mark internal zoom animation state to given zoom.
2006  *
2007  * This does not modify any actual zoom in WebKit or backing store,
2008  * just set the Ewk_View_Smart_Data->animated_zoom.zoom.start so
2009  * sub-classes will know they should not reset their internal state.
2010  *
2011  * @param o view object to change value.
2012  * @param zoom new start value.
2013  *
2014  * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
2015  *
2016  * @see ewk_view_zoom_animated_set()
2017  * @see ewk_view_zoom_weak_set()
2018  * @see ewk_view_zoom_animated_mark_stop()
2019  * @see ewk_view_zoom_animated_mark_end()
2020  * @see ewk_view_zoom_animated_mark_current()
2021  */
2022 Eina_Bool ewk_view_zoom_animated_mark_start(Evas_Object* o, float zoom)
2023 {
2024     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2025     sd->animated_zoom.zoom.start = zoom;
2026     return EINA_TRUE;
2027 }
2028
2029 /**
2030  * Mark internal zoom animation state to given zoom.
2031  *
2032  * This does not modify any actual zoom in WebKit or backing store,
2033  * just set the Ewk_View_Smart_Data->animated_zoom.zoom.end so
2034  * sub-classes will know they should not reset their internal state.
2035  *
2036  * @param o view object to change value.
2037  * @param zoom new end value.
2038  *
2039  * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
2040  *
2041  * @see ewk_view_zoom_animated_set()
2042  * @see ewk_view_zoom_weak_set()
2043  * @see ewk_view_zoom_animated_mark_stop()
2044  * @see ewk_view_zoom_animated_mark_start()
2045  * @see ewk_view_zoom_animated_mark_current()
2046  */
2047 Eina_Bool ewk_view_zoom_animated_mark_end(Evas_Object* o, float zoom)
2048 {
2049     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2050     sd->animated_zoom.zoom.end = zoom;
2051     return EINA_TRUE;
2052 }
2053
2054 /**
2055  * Mark internal zoom animation state to given zoom.
2056  *
2057  * This does not modify any actual zoom in WebKit or backing store,
2058  * just set the Ewk_View_Smart_Data->animated_zoom.zoom.current so
2059  * sub-classes will know they should not reset their internal state.
2060  *
2061  * @param o view object to change value.
2062  * @param zoom new current value.
2063  *
2064  * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
2065  *
2066  * @see ewk_view_zoom_animated_set()
2067  * @see ewk_view_zoom_weak_set()
2068  * @see ewk_view_zoom_animated_mark_stop()
2069  * @see ewk_view_zoom_animated_mark_start()
2070  * @see ewk_view_zoom_animated_mark_end()
2071  */
2072 Eina_Bool ewk_view_zoom_animated_mark_current(Evas_Object* o, float zoom)
2073 {
2074     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2075     sd->animated_zoom.zoom.current = zoom;
2076     return EINA_TRUE;
2077 }
2078
2079 /**
2080  * Unmark internal zoom animation state.
2081  *
2082  * This zero all start, end and current values.
2083  *
2084  * @param o view object to mark as animated is stopped.
2085  *
2086  * @see ewk_view_zoom_animated_mark_start()
2087  * @see ewk_view_zoom_animated_mark_end()
2088  * @see ewk_view_zoom_animated_mark_current()
2089  * @see ewk_view_zoom_weak_set()
2090  */
2091 Eina_Bool ewk_view_zoom_animated_mark_stop(Evas_Object* o)
2092 {
2093     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2094     _ewk_view_zoom_animated_mark_stop(sd);
2095     return EINA_TRUE;
2096 }
2097
2098 /**
2099  * Set the current zoom level while animating.
2100  *
2101  * If the view was already animating to another zoom, it will start
2102  * from current point to the next provided zoom (@a zoom parameter)
2103  * and duration (@a duration parameter).
2104  *
2105  * This is the recommended way to do transitions from one level to
2106  * another. However, one may wish to do those from outside, in that
2107  * case use ewk_view_zoom_weak_set() and later control intermediate
2108  * states with ewk_view_zoom_animated_mark_current(),
2109  * ewk_view_zoom_animated_mark_end() and
2110  * ewk_view_zoom_animated_mark_stop().
2111  *
2112  * @param o view object to animate.
2113  * @param zoom final zoom level to use.
2114  * @param duration time in seconds the animation should take.
2115  * @param cx offset inside object that defines zoom center. 0 is left side.
2116  * @param cy offset inside object that defines zoom center. 0 is top side.
2117  * @return @c EINA_TRUE if animation will be started, @c EINA_FALSE if not
2118  *            because zoom is too small/big.
2119  */
2120 Eina_Bool ewk_view_zoom_animated_set(Evas_Object* o, float zoom, float duration, Evas_Coord cx, Evas_Coord cy)
2121 {
2122     double now;
2123     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2124     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2125     EINA_SAFETY_ON_NULL_RETURN_VAL(sd->api, EINA_FALSE);
2126     EINA_SAFETY_ON_NULL_RETURN_VAL(sd->api->zoom_weak_set, EINA_FALSE);
2127
2128     if (!priv->settings.zoom_range.user_scalable) {
2129         WRN("userScalable is false");
2130         return EINA_FALSE;
2131     }
2132
2133     if (zoom < priv->settings.zoom_range.min_scale) {
2134         WRN("zoom level is < %f : %f", (double)priv->settings.zoom_range.min_scale, (double)zoom);
2135         return EINA_FALSE;
2136     }
2137     if (zoom > priv->settings.zoom_range.max_scale) {
2138         WRN("zoom level is > %f : %f", (double)priv->settings.zoom_range.max_scale, (double)zoom);
2139         return EINA_FALSE;
2140     }
2141
2142     if (priv->animated_zoom.animator)
2143         priv->animated_zoom.zoom.start = _ewk_view_zoom_animated_current(priv);
2144     else {
2145         priv->animated_zoom.zoom.start = ewk_frame_zoom_get(sd->main_frame);
2146         _ewk_view_zoom_animation_start(sd);
2147     }
2148
2149     if (cx < 0)
2150         cx = 0;
2151     if (cy < 0)
2152         cy = 0;
2153
2154     now = ecore_loop_time_get();
2155     priv->animated_zoom.time.start = now;
2156     priv->animated_zoom.time.end = now + duration;
2157     priv->animated_zoom.time.duration = duration;
2158     priv->animated_zoom.zoom.end = zoom;
2159     priv->animated_zoom.zoom.range = (priv->animated_zoom.zoom.end - priv->animated_zoom.zoom.start);
2160     priv->animated_zoom.center.x = cx;
2161     priv->animated_zoom.center.y = cy;
2162     sd->animated_zoom.zoom.current = priv->animated_zoom.zoom.start;
2163     sd->animated_zoom.zoom.start = priv->animated_zoom.zoom.start;
2164     sd->animated_zoom.zoom.end = priv->animated_zoom.zoom.end;
2165
2166     return EINA_TRUE;
2167 }
2168
2169 /**
2170  * Query if zoom level just applies to text and not other elements.
2171  *
2172  * @param o view to query setting.
2173  *
2174  * @return @c EINA_TRUE if just text are scaled, @c EINA_FALSE otherwise.
2175  */
2176 Eina_Bool ewk_view_zoom_text_only_get(const Evas_Object* o)
2177 {
2178     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2179     return ewk_frame_zoom_text_only_get(sd->main_frame);
2180 }
2181
2182 /**
2183  * Set if zoom level just applies to text and not other elements.
2184  *
2185  * @param o view to change setting.
2186  * @param setting @c EINA_TRUE if zoom should just be applied to text.
2187  *
2188  * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
2189  */
2190 Eina_Bool ewk_view_zoom_text_only_set(Evas_Object* o, Eina_Bool setting)
2191 {
2192     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2193     return ewk_frame_zoom_text_only_set(sd->main_frame, setting);
2194 }
2195
2196 /**
2197  * Hint engine to pre-render region.
2198  *
2199  * Engines and backing store might be able to pre-render regions in
2200  * order to speed up zooming or scrolling to that region. Not all
2201  * engines might implement that and they will return @c EINA_FALSE
2202  * in that case.
2203  *
2204  * The given region is a hint. Engines might do bigger or smaller area
2205  * that covers that region. Pre-render might not be immediate, it may
2206  * be postponed to a thread, operated cooperatively in the main loop
2207  * and may be even ignored or cancelled afterwards.
2208  *
2209  * Multiple requests might be queued by engines. One can clear/forget
2210  * about them with ewk_view_pre_render_cancel().
2211  *
2212  * @param o view to ask pre-render of given region.
2213  * @param x absolute coordinate (0=left) to pre-render at zoom.
2214  * @param y absolute coordinate (0=top) to pre-render at zoom.
2215  * @param w width to pre-render starting from @a x at zoom.
2216  * @param h height to pre-render starting from @a y at zoom.
2217  * @param zoom desired zoom.
2218  *
2219  * @return @c EINA_TRUE if request was accepted, @c EINA_FALSE
2220  *         otherwise (errors, pre-render not supported, etc).
2221  *
2222  * @see ewk_view_pre_render_cancel()
2223  */
2224 Eina_Bool ewk_view_pre_render_region(Evas_Object* o, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h, float zoom)
2225 {
2226     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2227     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2228     EINA_SAFETY_ON_NULL_RETURN_VAL(sd->api->pre_render_region, EINA_FALSE);
2229     float cur_zoom;
2230     Evas_Coord cw, ch;
2231
2232     /* When doing animated zoom it's not possible to call pre-render since it
2233      * would screw up parameters that animation is currently using
2234      */
2235     if (priv->animated_zoom.animator)
2236         return EINA_FALSE;
2237
2238     cur_zoom = ewk_frame_zoom_get(sd->main_frame);
2239
2240     if (cur_zoom < 0.00001)
2241         return EINA_FALSE;
2242     if (!ewk_frame_contents_size_get(sd->main_frame, &cw, &ch))
2243         return EINA_FALSE;
2244
2245     cw *= zoom / cur_zoom;
2246     ch *= zoom / cur_zoom;
2247     DBG("region %d,%d+%dx%d @ %f contents=%dx%d", x, y, w, h, zoom, cw, ch);
2248
2249     if (x + w > cw)
2250         w = cw - x;
2251
2252     if (y + h > ch)
2253         h = ch - y;
2254
2255     if (x < 0) {
2256         w += x;
2257         x = 0;
2258     }
2259     if (y < 0) {
2260         h += y;
2261         y = 0;
2262     }
2263
2264     return sd->api->pre_render_region(sd, x, y, w, h, zoom);
2265 }
2266
2267 /**
2268  * Hint engine to pre-render region, given n extra cols/rows
2269  *
2270  * This is an alternative method to ewk_view_pre_render_region(). It does not
2271  * make sense in all engines and therefore it might not be implemented at all.
2272  *
2273  * It's only useful if engine divide the area being rendered in smaller tiles,
2274  * forming a grid. Then, browser could call this function to pre-render @param n
2275  * rows/cols involving the current viewport.
2276  *
2277  * @param o view to ask pre-render on.
2278  * @param n number of cols/rows that must be part of the region pre-rendered
2279  *
2280  * @see ewk_view_pre_render_region()
2281  */
2282 Eina_Bool ewk_view_pre_render_relative_radius(Evas_Object* o, unsigned int n)
2283 {
2284     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2285     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2286     EINA_SAFETY_ON_NULL_RETURN_VAL(sd->api->pre_render_relative_radius, EINA_FALSE);
2287     float cur_zoom;
2288
2289     if (priv->animated_zoom.animator)
2290         return EINA_FALSE;
2291
2292     cur_zoom = ewk_frame_zoom_get(sd->main_frame);
2293     return sd->api->pre_render_relative_radius(sd, n, cur_zoom);
2294 }
2295
2296 /**
2297  * Get input method hints
2298  *
2299  * @param o View.
2300  *
2301  * @return input method hints
2302  */
2303 unsigned int ewk_view_imh_get(Evas_Object *o)
2304 {
2305     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
2306     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0);
2307     return priv->imh;
2308 }
2309
2310 /**
2311  * Cancel (clear) previous pre-render requests.
2312  *
2313  * @param o view to clear pre-render requests.
2314  */
2315 void ewk_view_pre_render_cancel(Evas_Object* o)
2316 {
2317     EWK_VIEW_SD_GET_OR_RETURN(o, sd);
2318     EINA_SAFETY_ON_NULL_RETURN(sd->api->pre_render_cancel);
2319     sd->api->pre_render_cancel(sd);
2320 }
2321
2322 /**
2323   * Enable processing of update requests.
2324   *
2325   * @param o view to enable rendering.
2326   *
2327   * @return @c EINA_TRUE if render was enabled, @c EINA_FALSE
2328             otherwise (errors, rendering suspension not supported).
2329   */
2330 Eina_Bool ewk_view_enable_render(const Evas_Object *o)
2331 {
2332     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2333     EINA_SAFETY_ON_NULL_RETURN_VAL(sd->api->enable_render, EINA_FALSE);
2334     return sd->api->enable_render(sd);
2335 }
2336
2337 /**
2338   * Disable processing of update requests.
2339   *
2340   * @param o view to disable rendering.
2341   *
2342   * @return @c EINA_TRUE if render was disabled, @c EINA_FALSE
2343             otherwise (errors, rendering suspension not supported).
2344   */
2345 Eina_Bool ewk_view_disable_render(const Evas_Object *o)
2346 {
2347     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2348     EINA_SAFETY_ON_NULL_RETURN_VAL(sd->api->disable_render, EINA_FALSE);
2349     return sd->api->disable_render(sd);
2350 }
2351
2352 const char* ewk_view_setting_user_agent_get(const Evas_Object* o)
2353 {
2354     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
2355     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0);
2356     return priv->settings.user_agent;
2357 }
2358
2359 Eina_Bool ewk_view_setting_user_agent_set(Evas_Object* o, const char* user_agent)
2360 {
2361     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2362     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2363     if (eina_stringshare_replace(&priv->settings.user_agent, user_agent)) {
2364         WebCore::FrameLoaderClientEfl* client = static_cast<WebCore::FrameLoaderClientEfl*>(priv->main_frame->loader()->client());
2365         client->setCustomUserAgent(WTF::String::fromUTF8(user_agent));
2366     }
2367     return EINA_TRUE;
2368 }
2369
2370 const char* ewk_view_setting_user_stylesheet_get(const Evas_Object* o)
2371 {
2372     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
2373     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0);
2374     return priv->settings.user_stylesheet;
2375 }
2376
2377 Eina_Bool ewk_view_setting_user_stylesheet_set(Evas_Object* o, const char* uri)
2378 {
2379     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2380     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2381     if (eina_stringshare_replace(&priv->settings.user_stylesheet, uri)) {
2382         WebCore::KURL kurl(WebCore::KURL(), WTF::String::fromUTF8(uri));
2383         priv->page_settings->setUserStyleSheetLocation(kurl);
2384     }
2385     return EINA_TRUE;
2386 }
2387
2388 Eina_Bool ewk_view_setting_auto_load_images_get(const Evas_Object* o)
2389 {
2390     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2391     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2392     return priv->settings.auto_load_images;
2393 }
2394
2395 Eina_Bool ewk_view_setting_auto_load_images_set(Evas_Object* o, Eina_Bool automatic)
2396 {
2397     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2398     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2399     automatic = !!automatic;
2400     if (priv->settings.auto_load_images != automatic) {
2401         priv->page_settings->setLoadsImagesAutomatically(automatic);
2402         priv->settings.auto_load_images = automatic;
2403     }
2404     return EINA_TRUE;
2405 }
2406
2407 Eina_Bool ewk_view_setting_auto_shrink_images_get(const Evas_Object* o)
2408 {
2409     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2410     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2411     return priv->settings.auto_shrink_images;
2412 }
2413
2414 Eina_Bool ewk_view_setting_auto_shrink_images_set(Evas_Object* o, Eina_Bool automatic)
2415 {
2416     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2417     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2418     automatic = !!automatic;
2419     if (priv->settings.auto_shrink_images != automatic) {
2420         priv->page_settings->setShrinksStandaloneImagesToFit(automatic);
2421         priv->settings.auto_shrink_images = automatic;
2422     }
2423     return EINA_TRUE;
2424 }
2425
2426 /**
2427  * Gets if view can be resized automatically.
2428  *
2429  * @param o view to check status
2430  *
2431  * @return EINA_TRUE if view can be resized, EINA_FALSE
2432  *         otherwise (errors, cannot be resized).
2433  */
2434 Eina_Bool ewk_view_setting_enable_auto_resize_window_get(const Evas_Object* o)
2435 {
2436     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2437     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2438     return priv->settings.enable_auto_resize_window;
2439 }
2440
2441 /**
2442  * Sets if view can be resized automatically.
2443  *
2444  * @param o View.
2445  * @param resizable @c EINA_TRUE if we want to resize automatically;
2446  * @c EINA_FALSE otherwise. It defaults to @c EINA_TRUE
2447  *
2448  * @return EINA_TRUE if auto_resize_window status set, EINA_FALSE
2449  *         otherwise (errors).
2450  */
2451 Eina_Bool ewk_view_setting_enable_auto_resize_window_set(Evas_Object* o, Eina_Bool resizable)
2452 {
2453     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2454     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2455     priv->settings.enable_auto_resize_window = resizable;
2456     return EINA_TRUE;
2457 }
2458
2459 Eina_Bool ewk_view_setting_enable_scripts_get(const Evas_Object* o)
2460 {
2461     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2462     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2463     return priv->settings.enable_scripts;
2464 }
2465
2466 Eina_Bool ewk_view_setting_enable_scripts_set(Evas_Object* o, Eina_Bool enable)
2467 {
2468     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2469     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2470     enable = !!enable;
2471     if (priv->settings.enable_scripts != enable) {
2472         priv->page_settings->setJavaScriptEnabled(enable);
2473         priv->settings.enable_scripts = enable;
2474     }
2475     return EINA_TRUE;
2476 }
2477
2478 Eina_Bool ewk_view_setting_enable_plugins_get(const Evas_Object* o)
2479 {
2480     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2481     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2482     return priv->settings.enable_plugins;
2483 }
2484
2485 Eina_Bool ewk_view_setting_enable_plugins_set(Evas_Object* o, Eina_Bool enable)
2486 {
2487     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2488     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2489     enable = !!enable;
2490     if (priv->settings.enable_plugins != enable) {
2491         priv->page_settings->setPluginsEnabled(enable);
2492         priv->settings.enable_plugins = enable;
2493     }
2494     return EINA_TRUE;
2495 }
2496
2497 /**
2498  * Get status of frame flattening.
2499  *
2500  * @param o view to check status
2501  *
2502  * @return EINA_TRUE if flattening is enabled, EINA_FALSE
2503  *         otherwise (errors, flattening disabled).
2504  */
2505 Eina_Bool ewk_view_setting_enable_frame_flattening_get(const Evas_Object* o)
2506 {
2507     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2508     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2509     return priv->settings.enable_frame_flattening;
2510 }
2511
2512 /**
2513  * Set frame flattening.
2514  *
2515  * @param o view to set flattening
2516  *
2517  * @return EINA_TRUE if flattening status set, EINA_FALSE
2518  *         otherwise (errors).
2519  */
2520 Eina_Bool ewk_view_setting_enable_frame_flattening_set(Evas_Object* o, Eina_Bool enable)
2521 {
2522     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2523     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2524     enable = !!enable;
2525     if (priv->settings.enable_frame_flattening != enable) {
2526         priv->page_settings->setFrameFlatteningEnabled(enable);
2527         priv->settings.enable_frame_flattening = enable;
2528     }
2529     return EINA_TRUE;
2530 }
2531
2532 Eina_Bool ewk_view_setting_scripts_window_open_get(const Evas_Object* o)
2533 {
2534     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2535     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2536     return priv->settings.scripts_window_open;
2537 }
2538
2539 Eina_Bool ewk_view_setting_scripts_window_open_set(Evas_Object* o, Eina_Bool allow)
2540 {
2541     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2542     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2543     allow = !!allow;
2544     if (priv->settings.scripts_window_open != allow) {
2545         priv->page_settings->setJavaScriptCanOpenWindowsAutomatically(allow);
2546         priv->settings.scripts_window_open = allow;
2547     }
2548     return EINA_TRUE;
2549 }
2550
2551 Eina_Bool ewk_view_setting_resizable_textareas_get(const Evas_Object* o)
2552 {
2553     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2554     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2555     return priv->settings.resizable_textareas;
2556 }
2557
2558 Eina_Bool ewk_view_setting_resizable_textareas_set(Evas_Object* o, Eina_Bool enable)
2559 {
2560     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2561     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2562     enable = !!enable;
2563     if (priv->settings.resizable_textareas != enable) {
2564         priv->page_settings->setTextAreasAreResizable(enable);
2565         priv->settings.resizable_textareas = enable;
2566     }
2567     return EINA_TRUE;
2568 }
2569
2570 Eina_Bool ewk_view_setting_private_browsing_get(const Evas_Object* o)
2571 {
2572     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2573     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2574     return priv->settings.private_browsing;
2575 }
2576
2577 Eina_Bool ewk_view_setting_private_browsing_set(Evas_Object* o, Eina_Bool enable)
2578 {
2579     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2580     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2581     enable = !!enable;
2582     if (priv->settings.private_browsing != enable) {
2583         priv->page_settings->setPrivateBrowsingEnabled(enable);
2584         priv->settings.private_browsing = enable;
2585     }
2586     return EINA_TRUE;
2587 }
2588
2589 Eina_Bool ewk_view_setting_offline_app_cache_get(const Evas_Object* o)
2590 {
2591     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2592     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2593     return priv->settings.offline_app_cache;
2594 }
2595
2596 Eina_Bool ewk_view_setting_offline_app_cache_set(Evas_Object* o, Eina_Bool enable)
2597 {
2598     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2599     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2600     enable = !!enable;
2601     if (priv->settings.offline_app_cache != enable) {
2602         priv->page_settings->setOfflineWebApplicationCacheEnabled(enable);
2603         priv->settings.offline_app_cache = enable;
2604     }
2605     return EINA_TRUE;
2606 }
2607
2608
2609 Eina_Bool ewk_view_setting_caret_browsing_get(const Evas_Object* o)
2610 {
2611     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2612     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2613     return priv->settings.caret_browsing;
2614 }
2615
2616 Eina_Bool ewk_view_setting_caret_browsing_set(Evas_Object* o, Eina_Bool enable)
2617 {
2618     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2619     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2620     enable = !!enable;
2621     if (priv->settings.caret_browsing != enable) {
2622         priv->page_settings->setCaretBrowsingEnabled(enable);
2623         priv->settings.caret_browsing = enable;
2624     }
2625     return EINA_TRUE;
2626 }
2627
2628 /**
2629  * Get current encoding of this View.
2630  *
2631  * @param o View.
2632  *
2633  * @return A pointer to an eina_strinshare containing the current custom
2634  * encoding for View object @param o, or @c 0 if it's not set.
2635  */
2636 const char* ewk_view_setting_encoding_custom_get(const Evas_Object* o)
2637 {
2638     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
2639     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0);
2640     Evas_Object* main_frame = ewk_view_frame_main_get(o);
2641     WebCore::Frame* core_frame = ewk_frame_core_get(main_frame);
2642
2643     WTF::String overrideEncoding = core_frame->loader()->documentLoader()->overrideEncoding();
2644
2645     if (overrideEncoding.isEmpty())
2646         return 0;
2647
2648     eina_stringshare_replace(&priv->settings.encoding_custom, overrideEncoding.utf8().data());
2649     return priv->settings.encoding_custom;
2650 }
2651
2652 /**
2653  * Set encoding of this View and reload page.
2654  *
2655  * @param o View.
2656  * @param encoding The new encoding or @c 0 to restore the default encoding.
2657  *
2658  * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
2659  */
2660 Eina_Bool ewk_view_setting_encoding_custom_set(Evas_Object* o, const char *encoding)
2661 {
2662     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2663     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2664     Evas_Object* main_frame = ewk_view_frame_main_get(o);
2665     WebCore::Frame* core_frame = ewk_frame_core_get(main_frame);
2666 DBG("%s", encoding);
2667     eina_stringshare_replace(&priv->settings.encoding_custom, encoding);
2668     core_frame->loader()->reloadWithOverrideEncoding(WTF::String::fromUTF8(encoding));
2669
2670     return EINA_TRUE;
2671 }
2672
2673 const char* ewk_view_setting_encoding_default_get(const Evas_Object* o)
2674 {
2675     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
2676     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0);
2677     return priv->settings.encoding_default;
2678 }
2679
2680 Eina_Bool ewk_view_setting_encoding_default_set(Evas_Object* o, const char* encoding)
2681 {
2682     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2683     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2684     if (eina_stringshare_replace(&priv->settings.encoding_default, encoding))
2685         priv->page_settings->setDefaultTextEncodingName(WTF::String::fromUTF8(encoding));
2686     return EINA_TRUE;
2687 }
2688
2689 /**
2690  * Sets the encoding detector.
2691  *
2692  * @param o view object to set if encoding detector is enabled.
2693  * @return @c EINA_TRUE on success and @c EINA_FALSE on failure
2694  */
2695 Eina_Bool ewk_view_setting_encoding_detector_set(Evas_Object* o, Eina_Bool enable)
2696 {
2697     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2698     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2699     enable = !!enable;
2700     if (priv->settings.encoding_detector != enable) {
2701         priv->page_settings->setUsesEncodingDetector(enable);
2702         priv->settings.encoding_detector = enable;
2703     }
2704     return EINA_TRUE;
2705 }
2706
2707 /**
2708  * Gets if the encoding detector is enabled.
2709  *
2710  * @param o view object to get if encoding detector is enabled.
2711  * @return @c EINA_TRUE if encoding detector is enabled, @c EINA_FALSE if not or on errors.
2712  */
2713 Eina_Bool ewk_view_setting_encoding_detector_get(Evas_Object* o)
2714 {
2715     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2716     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2717     return priv->settings.encoding_detector;
2718 }
2719
2720 const char* ewk_view_setting_cache_directory_get(const Evas_Object* o)
2721 {
2722     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
2723     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0);
2724     return priv->settings.cache_directory;
2725 }
2726
2727 Eina_Bool ewk_view_setting_cache_directory_set(Evas_Object* o, const char* path)
2728 {
2729     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2730     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2731     if (eina_stringshare_replace(&priv->settings.cache_directory, path))
2732         WebCore::cacheStorage().setCacheDirectory(WTF::String::fromUTF8(path));
2733     return EINA_TRUE;
2734 }
2735
2736 int ewk_view_setting_font_minimum_size_get(const Evas_Object* o)
2737 {
2738     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
2739     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0);
2740     return priv->settings.font_minimum_size;
2741 }
2742
2743 Eina_Bool ewk_view_setting_font_minimum_size_set(Evas_Object* o, int size)
2744 {
2745     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2746     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2747     if (priv->settings.font_minimum_size != size) {
2748         priv->page_settings->setMinimumFontSize(size);
2749         priv->settings.font_minimum_size = size;
2750     }
2751     return EINA_TRUE;
2752 }
2753
2754 int ewk_view_setting_font_minimum_logical_size_get(const Evas_Object* o)
2755 {
2756     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
2757     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0);
2758     return priv->settings.font_minimum_logical_size;
2759 }
2760
2761 Eina_Bool ewk_view_setting_font_minimum_logical_size_set(Evas_Object* o, int size)
2762 {
2763     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2764     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2765     if (priv->settings.font_minimum_logical_size != size) {
2766         priv->page_settings->setMinimumLogicalFontSize(size);
2767         priv->settings.font_minimum_logical_size = size;
2768     }
2769     return EINA_TRUE;
2770 }
2771
2772 int ewk_view_setting_font_default_size_get(const Evas_Object* o)
2773 {
2774     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
2775     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0);
2776     return priv->settings.font_default_size;
2777 }
2778
2779 Eina_Bool ewk_view_setting_font_default_size_set(Evas_Object* o, int size)
2780 {
2781     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2782     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2783     if (priv->settings.font_default_size != size) {
2784         priv->page_settings->setDefaultFontSize(size);
2785         priv->settings.font_default_size = size;
2786     }
2787     return EINA_TRUE;
2788 }
2789
2790 int ewk_view_setting_font_monospace_size_get(const Evas_Object* o)
2791 {
2792     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
2793     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0);
2794     return priv->settings.font_monospace_size;
2795 }
2796
2797 Eina_Bool ewk_view_setting_font_monospace_size_set(Evas_Object* o, int size)
2798 {
2799     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2800     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2801     if (priv->settings.font_monospace_size != size) {
2802         priv->page_settings->setDefaultFixedFontSize(size);
2803         priv->settings.font_monospace_size = size;
2804     }
2805     return EINA_TRUE;
2806 }
2807
2808 const char* ewk_view_setting_font_standard_get(const Evas_Object* o)
2809 {
2810     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
2811     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0);
2812     return priv->settings.font_standard;
2813 }
2814
2815 Eina_Bool ewk_view_setting_font_standard_set(Evas_Object* o, const char* family)
2816 {
2817     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2818     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2819     if (eina_stringshare_replace(&priv->settings.font_standard, family)) {
2820         WTF::AtomicString s = WTF::String::fromUTF8(family);
2821         priv->page_settings->setStandardFontFamily(s);
2822     }
2823     return EINA_TRUE;
2824 }
2825
2826 const char* ewk_view_setting_font_cursive_get(const Evas_Object* o)
2827 {
2828     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
2829     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0);
2830     return priv->settings.font_cursive;
2831 }
2832
2833 Eina_Bool ewk_view_setting_font_cursive_set(Evas_Object* o, const char* family)
2834 {
2835     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2836     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2837     if (eina_stringshare_replace(&priv->settings.font_cursive, family)) {
2838         WTF::AtomicString s = WTF::String::fromUTF8(family);
2839         priv->page_settings->setCursiveFontFamily(s);
2840     }
2841     return EINA_TRUE;
2842 }
2843
2844 const char* ewk_view_setting_font_fantasy_get(const Evas_Object* o)
2845 {
2846     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
2847     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0);
2848     return priv->settings.font_fantasy;
2849 }
2850
2851 Eina_Bool ewk_view_setting_font_fantasy_set(Evas_Object* o, const char* family)
2852 {
2853     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2854     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2855     if (eina_stringshare_replace(&priv->settings.font_fantasy, family)) {
2856         WTF::AtomicString s = WTF::String::fromUTF8(family);
2857         priv->page_settings->setFantasyFontFamily(s);
2858     }
2859     return EINA_TRUE;
2860 }
2861
2862 const char* ewk_view_setting_font_monospace_get(const Evas_Object* o)
2863 {
2864     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
2865     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0);
2866     return priv->settings.font_monospace;
2867 }
2868
2869 Eina_Bool ewk_view_setting_font_monospace_set(Evas_Object* o, const char* family)
2870 {
2871     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2872     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2873     if (eina_stringshare_replace(&priv->settings.font_monospace, family)) {
2874         WTF::AtomicString s = WTF::String::fromUTF8(family);
2875         priv->page_settings->setFixedFontFamily(s);
2876     }
2877     return EINA_TRUE;
2878 }
2879
2880 const char* ewk_view_setting_font_serif_get(const Evas_Object* o)
2881 {
2882     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
2883     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0);
2884     return priv->settings.font_serif;
2885 }
2886
2887 Eina_Bool ewk_view_setting_font_serif_set(Evas_Object* o, const char* family)
2888 {
2889     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2890     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2891     if (eina_stringshare_replace(&priv->settings.font_serif, family)) {
2892         WTF::AtomicString s = WTF::String::fromUTF8(family);
2893         priv->page_settings->setSerifFontFamily(s);
2894     }
2895     return EINA_TRUE;
2896 }
2897
2898 const char* ewk_view_setting_font_sans_serif_get(const Evas_Object* o)
2899 {
2900     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
2901     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0);
2902     return priv->settings.font_sans_serif;
2903 }
2904   
2905 Eina_Bool ewk_view_setting_font_sans_serif_set(Evas_Object* o, const char* family)
2906 {
2907     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2908     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2909     if (eina_stringshare_replace(&priv->settings.font_sans_serif, family)) {
2910         WTF::AtomicString s = WTF::String::fromUTF8(family);
2911         priv->page_settings->setSansSerifFontFamily(s);
2912     }
2913     return EINA_TRUE;
2914 }
2915
2916 Eina_Bool ewk_view_setting_spatial_navigation_get(Evas_Object* o)
2917 {
2918     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2919     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2920     return priv->settings.spatial_navigation;
2921 }
2922
2923 Eina_Bool ewk_view_setting_spatial_navigation_set(Evas_Object* o, Eina_Bool enable)
2924 {
2925     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2926     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2927     enable = !!enable;
2928     if (priv->settings.spatial_navigation != enable) {
2929         priv->page_settings->setSpatialNavigationEnabled(enable);
2930         priv->settings.spatial_navigation = enable;
2931     }
2932     return EINA_TRUE;
2933 }
2934
2935 /**
2936  * Gets if the local storage is enabled.
2937  *
2938  * @param o view object to get if local storage is enabled.
2939  * @return @c EINA_TRUE if local storage is enabled, @c EINA_FALSE if not or on errors.
2940  */
2941 Eina_Bool ewk_view_setting_local_storage_get(Evas_Object* o)
2942 {
2943     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2944     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2945     return priv->settings.local_storage;
2946 }
2947
2948 /**
2949  * Sets the local storage of HTML5.
2950  *
2951  * @param o view object to set if local storage is enabled.
2952  * @return @c EINA_TRUE on success and @c EINA_FALSE on failure
2953  */
2954 Eina_Bool ewk_view_setting_local_storage_set(Evas_Object* o, Eina_Bool enable)
2955 {
2956     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2957     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2958     enable = !!enable;
2959     if (priv->settings.local_storage != enable) {
2960         priv->page_settings->setLocalStorageEnabled(enable);
2961         priv->settings.local_storage = enable;
2962     }
2963     return EINA_TRUE;
2964 }
2965
2966 /**
2967  * Gets if the page cache is enabled.
2968  *
2969  * @param o view object to set if page cache is enabled.
2970  * @return @c EINA_TRUE if page cache is enabled, @c EINA_FALSE if not.
2971  */
2972 Eina_Bool ewk_view_setting_page_cache_get(Evas_Object* o)
2973 {
2974     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2975     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2976     return priv->settings.page_cache;
2977 }
2978
2979 /**
2980  * Sets the page cache.
2981  *
2982  * @param o view object to set if page cache is enabled.
2983  * @return @c EINA_TRUE on success and @c EINA_FALSE on failure
2984  */
2985 Eina_Bool ewk_view_setting_page_cache_set(Evas_Object* o, Eina_Bool enable)
2986 {
2987     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2988     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2989     enable = !!enable;
2990     if (priv->settings.page_cache != enable) {
2991         priv->page_settings->setUsesPageCache(enable);
2992         priv->settings.page_cache = enable;
2993     }
2994     return EINA_TRUE;
2995 }
2996
2997 /*
2998  * Gets the local storage database path.
2999  *
3000  * @param o view object to get the local storage database path.
3001  * @return the local storage database path.
3002  */
3003 const char* ewk_view_setting_local_storage_database_path_get(const Evas_Object* o)
3004 {
3005     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
3006     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0);
3007     return priv->settings.local_storage_database_path;
3008 }
3009
3010 /**
3011  * Sets the local storage database path.
3012  *
3013  * @param o view object to set the local storage database path.
3014  * @return @c EINA_TRUE on success and @c EINA_FALSE on failure
3015  */
3016 Eina_Bool ewk_view_setting_local_storage_database_path_set(Evas_Object* o, const char* path)
3017 {
3018     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
3019     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
3020     if (eina_stringshare_replace(&priv->settings.local_storage_database_path, path)) {
3021         WTF::AtomicString s = WTF::String::fromUTF8(path);
3022         priv->page_settings->setLocalStorageDatabasePath(s);
3023     }
3024     return EINA_TRUE;
3025 }
3026
3027 /**
3028  * Similar to evas_object_smart_data_get(), but does type checking.
3029  *
3030  * @param o view object to query internal data.
3031  * @return internal data or @c 0 on errors (ie: incorrect type of @a o).
3032  */
3033 Ewk_View_Smart_Data* ewk_view_smart_data_get(const Evas_Object* o)
3034 {
3035     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
3036     return sd;
3037 }
3038
3039 /**
3040  * Gets the internal array of repaint requests.
3041  *
3042  * This array should not be modified anyhow. It should be processed
3043  * immediately as any further ewk_view call might change it, like
3044  * those that add repaints or flush them, so be sure that your code
3045  * does not call any of those while you process the repaints,
3046  * otherwise copy the array.
3047  *
3048  * @param priv private handle pointer of the view to get repaints.
3049  * @param count where to return the number of elements of returned array.
3050  *
3051  * @return reference to array of requested repaints.
3052  *
3053  * @note this is not for general use but just for subclasses that want
3054  *       to define their own backing store.
3055  */
3056 const Eina_Rectangle* ewk_view_repaints_get(const Ewk_View_Private_Data* priv, size_t* count)
3057 {
3058     EINA_SAFETY_ON_NULL_RETURN_VAL(count, 0);
3059     if (count)
3060         *count = 0;
3061     EINA_SAFETY_ON_NULL_RETURN_VAL(priv, 0);
3062     if (count)
3063         *count = priv->repaints.count;
3064     return priv->repaints.array;
3065 }
3066
3067 /**
3068  * Gets the internal array of scroll requests.
3069  *
3070  * This array should not be modified anyhow. It should be processed
3071  * immediately as any further ewk_view call might change it, like
3072  * those that add scrolls or flush them, so be sure that your code
3073  * does not call any of those while you process the scrolls,
3074  * otherwise copy the array.
3075  *
3076  * @param priv private handle pointer of the view to get scrolls.
3077  * @param count where to return the number of elements of returned array.
3078  *
3079  * @return reference to array of requested scrolls.
3080  *
3081  * @note this is not for general use but just for subclasses that want
3082  *       to define their own backing store.
3083  */
3084 const Ewk_Scroll_Request* ewk_view_scroll_requests_get(const Ewk_View_Private_Data* priv, size_t* count)
3085 {
3086     EINA_SAFETY_ON_NULL_RETURN_VAL(count, 0);
3087     if (count)
3088         *count = 0;
3089     EINA_SAFETY_ON_NULL_RETURN_VAL(priv, 0);
3090     if (count)
3091         *count = priv->scrolls.count;
3092     return priv->scrolls.array;
3093 }
3094
3095 /**
3096  * Add a new repaint request to queue.
3097  *
3098  * The repaints are assumed to be relative to current viewport.
3099  *
3100  * @param priv private handle pointer of the view to add repaint request.
3101  * @param x horizontal position relative to current view port (scrolled).
3102  * @param y vertical position relative to current view port (scrolled).
3103  * @param w width of area to be repainted
3104  * @param h height of area to be repainted
3105  *
3106  * @note this is not for general use but just for subclasses that want
3107  *       to define their own backing store.
3108  */
3109 void ewk_view_repaint_add(Ewk_View_Private_Data* priv, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h)
3110 {
3111     EINA_SAFETY_ON_NULL_RETURN(priv);
3112     _ewk_view_repaint_add(priv, x, y, w, h);
3113 }
3114
3115 /**
3116  * Do layout if required, applied recursively.
3117  *
3118  * @param priv private handle pointer of the view to layout.
3119  *
3120  * @note this is not for general use but just for subclasses that want
3121  *       to define their own backing store.
3122  */
3123 void ewk_view_layout_if_needed_recursive(Ewk_View_Private_Data* priv)
3124 {
3125     EINA_SAFETY_ON_NULL_RETURN(priv);
3126
3127     WebCore::FrameView* v = priv->main_frame->view();
3128     if (!v) {
3129         ERR("no main frame view");
3130         return;
3131     }
3132     v->updateLayoutAndStyleIfNeededRecursive();
3133 }
3134
3135 void ewk_view_scrolls_process(Ewk_View_Smart_Data* sd)
3136 {
3137     EINA_SAFETY_ON_NULL_RETURN(sd);
3138     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv);
3139     if (!sd->api->scrolls_process(sd))
3140         ERR("failed to process scrolls.");
3141     _ewk_view_scrolls_flush(priv);
3142 }
3143
3144 struct _Ewk_View_Paint_Context {
3145     WebCore::GraphicsContext* gc;
3146     WebCore::FrameView* view;
3147     cairo_t* cr;
3148 };
3149
3150 /**
3151  * Create a new paint context using the view as source and cairo as output.
3152  *
3153  * @param priv private handle pointer of the view to use as paint source.
3154  * @param cr cairo context to use as paint destination. A new
3155  *        reference is taken, so it's safe to call cairo_destroy()
3156  *        after this function returns.
3157  *
3158  * @return newly allocated instance or @c 0 on errors.
3159  *
3160  * @note this is not for general use but just for subclasses that want
3161  *       to define their own backing store.
3162  */
3163 Ewk_View_Paint_Context* ewk_view_paint_context_new(Ewk_View_Private_Data* priv, cairo_t* cr)
3164 {
3165     EINA_SAFETY_ON_NULL_RETURN_VAL(priv, 0);
3166     EINA_SAFETY_ON_NULL_RETURN_VAL(cr, 0);
3167     EINA_SAFETY_ON_NULL_RETURN_VAL(priv->main_frame, 0);
3168     WebCore::FrameView* view = priv->main_frame->view();
3169     EINA_SAFETY_ON_NULL_RETURN_VAL(view, 0);
3170     Ewk_View_Paint_Context* ctxt = (Ewk_View_Paint_Context*)malloc(sizeof(*ctxt));
3171     EINA_SAFETY_ON_NULL_RETURN_VAL(ctxt, 0);
3172
3173     ctxt->gc = new WebCore::GraphicsContext(cr);
3174     if (!ctxt->gc) {
3175         free(ctxt);
3176         return 0;
3177     }
3178     ctxt->view = view;
3179     ctxt->cr = cairo_reference(cr);
3180     return ctxt;
3181 }
3182
3183 /**
3184  * Destroy previously created paint context.
3185  *
3186  * @param ctxt paint context to destroy. Must @b not be @c 0.
3187  *
3188  * @note this is not for general use but just for subclasses that want
3189  *       to define their own backing store.
3190  */
3191 void ewk_view_paint_context_free(Ewk_View_Paint_Context* ctxt)
3192 {
3193     EINA_SAFETY_ON_NULL_RETURN(ctxt);
3194     delete ctxt->gc;
3195     cairo_destroy(ctxt->cr);
3196     free(ctxt);
3197 }
3198
3199 /**
3200  * Save (push to stack) paint context status.
3201  *
3202  * @param ctxt paint context to save. Must @b not be @c 0.
3203  *
3204  * @see ewk_view_paint_context_restore()
3205  *
3206  * @note this is not for general use but just for subclasses that want
3207  *       to define their own backing store.
3208  */
3209 void ewk_view_paint_context_save(Ewk_View_Paint_Context* ctxt)
3210 {
3211     EINA_SAFETY_ON_NULL_RETURN(ctxt);
3212     cairo_save(ctxt->cr);
3213     ctxt->gc->save();
3214 }
3215
3216 /**
3217  * Restore (pop from stack) paint context status.
3218  *
3219  * @param ctxt paint context to restore. Must @b not be @c 0.
3220  *
3221  * @see ewk_view_paint_context_save()
3222  *
3223  * @note this is not for general use but just for subclasses that want
3224  *       to define their own backing store.
3225  */
3226 void ewk_view_paint_context_restore(Ewk_View_Paint_Context* ctxt)
3227 {
3228     EINA_SAFETY_ON_NULL_RETURN(ctxt);
3229     ctxt->gc->restore();
3230     cairo_restore(ctxt->cr);
3231 }
3232
3233 /**
3234  * Clip paint context drawings to given area.
3235  *
3236  * @param ctxt paint context to clip. Must @b not be @c 0.
3237  * @param area clip area to use.
3238  *
3239  * @see ewk_view_paint_context_save()
3240  * @see ewk_view_paint_context_restore()
3241  *
3242  * @note this is not for general use but just for subclasses that want
3243  *       to define their own backing store.
3244  */
3245 void ewk_view_paint_context_clip(Ewk_View_Paint_Context* ctxt, const Eina_Rectangle* area)
3246 {
3247     EINA_SAFETY_ON_NULL_RETURN(ctxt);
3248     EINA_SAFETY_ON_NULL_RETURN(area);
3249     ctxt->gc->clip(WebCore::IntRect(area->x, area->y, area->w, area->h));
3250 }
3251
3252 /**
3253  * Paint using context using given area.
3254  *
3255  * @param ctxt paint context to paint. Must @b not be @c 0.
3256  * @param area paint area to use. Coordinates are relative to current viewport,
3257  *        thus "scrolled".
3258  *
3259  * @note one may use cairo functions on the cairo context to
3260  *       translate, scale or any modification that may fit his desires.
3261  *
3262  * @see ewk_view_paint_context_clip()
3263  * @see ewk_view_paint_context_paint_contents()
3264  *
3265  * @note this is not for general use but just for subclasses that want
3266  *       to define their own backing store.
3267  */
3268 void ewk_view_paint_context_paint(Ewk_View_Paint_Context* ctxt, const Eina_Rectangle* area)
3269 {
3270     EINA_SAFETY_ON_NULL_RETURN(ctxt);
3271     EINA_SAFETY_ON_NULL_RETURN(area);
3272
3273     WebCore::IntRect rect(area->x, area->y, area->w, area->h);
3274
3275     if (ctxt->view->isTransparent())
3276         ctxt->gc->clearRect(rect);
3277     ctxt->view->paint(ctxt->gc, rect);
3278 }
3279
3280 /**
3281  * Paint just contents using context using given area.
3282  *
3283  * Unlike ewk_view_paint_context_paint(), this function paint just
3284  * bare contents and ignores any scrolling, scrollbars and extras. It
3285  * will walk the rendering tree and paint contents inside the given
3286  * area to the cairo context specified in @a ctxt.
3287  *
3288  * @param ctxt paint context to paint. Must @b not be @c 0.
3289  * @param area paint area to use. Coordinates are absolute to page.
3290  *
3291  * @note one may use cairo functions on the cairo context to
3292  *       translate, scale or any modification that may fit his desires.
3293  *
3294  * @see ewk_view_paint_context_clip()
3295  * @see ewk_view_paint_context_paint()
3296  *
3297  * @note this is not for general use but just for subclasses that want
3298  *       to define their own backing store.
3299  */
3300 void ewk_view_paint_context_paint_contents(Ewk_View_Paint_Context* ctxt, const Eina_Rectangle* area)
3301 {
3302     EINA_SAFETY_ON_NULL_RETURN(ctxt);
3303     EINA_SAFETY_ON_NULL_RETURN(area);
3304
3305     WebCore::IntRect rect(area->x, area->y, area->w, area->h);
3306
3307     if (ctxt->view->isTransparent())
3308         ctxt->gc->clearRect(rect);
3309
3310     ctxt->view->paintContents(ctxt->gc, rect);
3311 }
3312
3313 /**
3314  * Scale the contents by the given factors.
3315  *
3316  * This function applies a scaling transformation using Cairo.
3317  *
3318  * @param ctxt    paint context to paint. Must @b not be @c 0.
3319  * @param scale_x scale factor for the X dimension.
3320  * @param scale_y scale factor for the Y dimension.
3321  */
3322 void ewk_view_paint_context_scale(Ewk_View_Paint_Context* ctxt, float scale_x, float scale_y)
3323 {
3324     EINA_SAFETY_ON_NULL_RETURN(ctxt);
3325
3326     ctxt->gc->scale(WebCore::FloatSize(scale_x, scale_y));
3327 }
3328
3329 /**
3330  * Performs a translation of the origin coordinates.
3331  *
3332  * This function moves the origin coordinates by @p x and @p y pixels.
3333  *
3334  * @param ctxt paint context to paint. Must @b not be @c 0.
3335  * @param x    amount of pixels to translate in the X dimension.
3336  * @param y    amount of pixels to translate in the Y dimension.
3337  */
3338 void ewk_view_paint_context_translate(Ewk_View_Paint_Context* ctxt, float x, float y)
3339 {
3340     EINA_SAFETY_ON_NULL_RETURN(ctxt);
3341
3342     ctxt->gc->translate(x, y);
3343 }
3344
3345 /**
3346  * Paint using given graphics context the given area.
3347  *
3348  * This uses viewport relative area and will also handle scrollbars
3349  * and other extra elements. See ewk_view_paint_contents() for the
3350  * alternative function.
3351  *
3352  * @param priv private handle pointer of view to use as paint source.
3353  * @param cr cairo context to use as paint destination. Its state will
3354  *        be saved before operation and restored afterwards.
3355  * @param area viewport relative geometry to paint.
3356  *
3357  * @return @c EINA_TRUE on success and @c EINA_FALSE on failure, like
3358  *         incorrect parameters.
3359  *
3360  * @note this is an easy to use version, but internal structures are
3361  *       always created, then graphics context is clipped, then
3362  *       painted, restored and destroyed. This might not be optimum,
3363  *       so using #Ewk_View_Paint_Context may be a better solutions
3364  *       for large number of operations.
3365  *
3366  * @see ewk_view_paint_contents()
3367  * @see ewk_view_paint_context_paint()
3368  *
3369  * @note this is not for general use but just for subclasses that want
3370  *       to define their own backing store.
3371  */
3372 Eina_Bool ewk_view_paint(Ewk_View_Private_Data* priv, cairo_t* cr, const Eina_Rectangle* area)
3373 {
3374     EINA_SAFETY_ON_NULL_RETURN_VAL(priv, EINA_FALSE);
3375     EINA_SAFETY_ON_NULL_RETURN_VAL(cr, EINA_FALSE);
3376     EINA_SAFETY_ON_NULL_RETURN_VAL(area, EINA_FALSE);
3377     WebCore::FrameView* view = priv->main_frame->view();
3378     EINA_SAFETY_ON_NULL_RETURN_VAL(view, EINA_FALSE);
3379
3380     if (view->needsLayout())
3381         view->forceLayout();
3382     WebCore::GraphicsContext gc(cr);
3383     WebCore::IntRect rect(area->x, area->y, area->w, area->h);
3384
3385     cairo_save(cr);
3386     gc.save();
3387     gc.clip(rect);
3388     if (view->isTransparent())
3389         gc.clearRect(rect);
3390     view->paint(&gc,  rect);
3391     gc.restore();
3392     cairo_restore(cr);
3393
3394     return EINA_TRUE;
3395 }
3396
3397 /**
3398  * Paint just contents using given graphics context the given area.
3399  *
3400  * This uses absolute coordinates for area and will just handle
3401  * contents, no scrollbars or extras. See ewk_view_paint() for the
3402  * alternative solution.
3403  *
3404  * @param priv private handle pointer of view to use as paint source.
3405  * @param cr cairo context to use as paint destination. Its state will
3406  *        be saved before operation and restored afterwards.
3407  * @param area absolute geometry to paint.
3408  *
3409  * @return @c EINA_TRUE on success and @c EINA_FALSE on failure, like
3410  *         incorrect parameters.
3411  *
3412  * @note this is an easy to use version, but internal structures are
3413  *       always created, then graphics context is clipped, then
3414  *       painted, restored and destroyed. This might not be optimum,
3415  *       so using #Ewk_View_Paint_Context may be a better solutions
3416  *       for large number of operations.
3417  *
3418  * @see ewk_view_paint()
3419  * @see ewk_view_paint_context_paint_contents()
3420  *
3421  * @note this is not for general use but just for subclasses that want
3422  *       to define their own backing store.
3423  */
3424 Eina_Bool ewk_view_paint_contents(Ewk_View_Private_Data* priv, cairo_t* cr, const Eina_Rectangle* area)
3425 {
3426     EINA_SAFETY_ON_NULL_RETURN_VAL(priv, EINA_FALSE);
3427     EINA_SAFETY_ON_NULL_RETURN_VAL(cr, EINA_FALSE);
3428     EINA_SAFETY_ON_NULL_RETURN_VAL(area, EINA_FALSE);
3429     WebCore::FrameView* view = priv->main_frame->view();
3430     EINA_SAFETY_ON_NULL_RETURN_VAL(view, EINA_FALSE);
3431
3432     WebCore::GraphicsContext gc(cr);
3433     WebCore::IntRect rect(area->x, area->y, area->w, area->h);
3434
3435     cairo_save(cr);
3436     gc.save();
3437     gc.clip(rect);
3438     if (view->isTransparent())
3439         gc.clearRect(rect);
3440     view->paintContents(&gc,  rect);
3441     gc.restore();
3442     cairo_restore(cr);
3443
3444     return EINA_TRUE;
3445 }
3446
3447
3448 /* internal methods ****************************************************/
3449 /**
3450  * @internal
3451  * Reports the view is ready to be displayed as all elements are aready.
3452  *
3453  * Emits signal: "ready" with no parameters.
3454  */
3455 void ewk_view_ready(Evas_Object* o)
3456 {
3457     DBG("o=%p", o);
3458     evas_object_smart_callback_call(o, "ready", 0);
3459 }
3460
3461 /**
3462  * @internal
3463  * Reports the state of input method changed. This is triggered, for example
3464  * when a input field received/lost focus
3465  *
3466  * Emits signal: "inputmethod,changed" with a boolean indicating whether it's
3467  * enabled or not.
3468  */
3469 void ewk_view_input_method_state_set(Evas_Object* o, Eina_Bool active)
3470 {
3471     EWK_VIEW_SD_GET_OR_RETURN(o, sd);
3472     EWK_VIEW_PRIV_GET(sd, priv);
3473     WebCore::Frame* focusedFrame = priv->page->focusController()->focusedOrMainFrame();
3474
3475     if (focusedFrame
3476         && focusedFrame->document()
3477         && focusedFrame->document()->focusedNode()
3478         && focusedFrame->document()->focusedNode()->hasTagName(WebCore::HTMLNames::inputTag)) {
3479         WebCore::HTMLInputElement* inputElement;
3480
3481         inputElement = static_cast<WebCore::HTMLInputElement*>(focusedFrame->document()->focusedNode());
3482         if (inputElement) {
3483             priv->imh = 0;
3484             // for password fields, active == false
3485             if (!active) {
3486                 active = inputElement->isPasswordField();
3487                 priv->imh = inputElement->isPasswordField() * EWK_IMH_PASSWORD;
3488             } else {
3489                 // Set input method hints for "number", "tel", "email", and "url" input elements.
3490                 priv->imh |= inputElement->isTelephoneField() * EWK_IMH_TELEPHONE;
3491                 priv->imh |= inputElement->isNumberField() * EWK_IMH_NUMBER;
3492                 priv->imh |= inputElement->isEmailField() * EWK_IMH_EMAIL;
3493                 priv->imh |= inputElement->isURLField() * EWK_IMH_URL;
3494             }
3495         }
3496     }
3497
3498     evas_object_smart_callback_call(o, "inputmethod,changed", (void*)active);
3499 }
3500
3501 /**
3502  * @internal
3503  * The view title was changed by the frame loader.
3504  *
3505  * Emits signal: "title,changed" with pointer to new title string.
3506  */
3507 void ewk_view_title_set(Evas_Object* o, const char* title)
3508 {
3509     DBG("o=%p, title=%s", o, title ? title : "(null)");
3510     evas_object_smart_callback_call(o, "title,changed", (void*)title);
3511 }
3512
3513 /**
3514  * @internal
3515  * Reports that main frame's uri changed.
3516  *
3517  * Emits signal: "uri,changed" with pointer to the new uri string.
3518  */
3519 void ewk_view_uri_changed(Evas_Object* o)
3520 {
3521     EWK_VIEW_SD_GET_OR_RETURN(o, sd);
3522     const char* uri = ewk_frame_uri_get(sd->main_frame);
3523     DBG("o=%p, uri=%s", o, uri ? uri : "(null)");
3524     evas_object_smart_callback_call(o, "uri,changed", (void*)uri);
3525 }
3526
3527 /**
3528  * @internal
3529  * Reports the view started loading something.
3530  *
3531  * @param o View.
3532  *
3533  * Emits signal: "load,started" with no parameters.
3534  */
3535 void ewk_view_load_started(Evas_Object* o)
3536 {
3537     DBG("o=%p", o);
3538     evas_object_smart_callback_call(o, "load,started", 0);
3539 }
3540
3541 /**
3542  * Reports the frame started loading something.
3543  *
3544  * @param o View.
3545  *
3546  * Emits signal: "load,started" on main frame with no parameters.
3547  */
3548 void ewk_view_frame_main_load_started(Evas_Object* o)
3549 {
3550     DBG("o=%p", o);
3551     Evas_Object* frame = ewk_view_frame_main_get(o);
3552     evas_object_smart_callback_call(frame, "load,started", 0);
3553 }
3554
3555 /**
3556  * @internal
3557  * Reports the main frame started provisional load.
3558  *
3559  * @param o View.
3560  *
3561  * Emits signal: "load,provisional" on View with no parameters.
3562  */
3563 void ewk_view_load_provisional(Evas_Object* o)
3564 {
3565     DBG("o=%p", o);
3566     evas_object_smart_callback_call(o, "load,provisional", 0);
3567 }
3568
3569 /**
3570  * @internal
3571  * Reports view can be shown after a new window is created.
3572  *
3573  * @param o Frame.
3574  *
3575  * Emits signal: "load,newwindow,show" on view with no parameters.
3576  */
3577 void ewk_view_load_show(Evas_Object* o)
3578 {
3579     DBG("o=%p", o);
3580     evas_object_smart_callback_call(o, "load,newwindow,show", 0);
3581 }
3582
3583
3584 /**
3585  * @internal
3586  * Reports the main frame was cleared.
3587  *
3588  * @param o View.
3589  */
3590 void ewk_view_frame_main_cleared(Evas_Object* o)
3591 {
3592     DBG("o=%p", o);
3593     EWK_VIEW_SD_GET_OR_RETURN(o, sd);
3594     EINA_SAFETY_ON_NULL_RETURN(sd->api->flush);
3595     sd->api->flush(sd);
3596 }
3597
3598 /**
3599  * @internal
3600  * Reports the main frame received an icon.
3601  *
3602  * @param o View.
3603  *
3604  * Emits signal: "icon,received" with no parameters.
3605  */
3606 void ewk_view_frame_main_icon_received(Evas_Object* o)
3607 {
3608     DBG("o=%p", o);
3609     Evas_Object* frame = ewk_view_frame_main_get(o);
3610     evas_object_smart_callback_call(frame, "icon,received", 0);
3611 }
3612
3613 /**
3614  * @internal
3615  * Reports load finished, optionally with error information.
3616  *
3617  * Emits signal: "load,finished" with pointer to #Ewk_Frame_Load_Error
3618  * if any error, or @c 0 if successful load.
3619  *
3620  * @note there should not be any error stuff here, but trying to be
3621  *       compatible with previous WebKit.
3622  */
3623 void ewk_view_load_finished(Evas_Object* o, const Ewk_Frame_Load_Error* error)
3624 {
3625     DBG("o=%p, error=%p", o, error);
3626     evas_object_smart_callback_call(o, "load,finished", (void*)error);
3627 }
3628
3629 /**
3630  * @internal
3631  * Reports load failed with error information.
3632  *
3633  * Emits signal: "load,error" with pointer to Ewk_Frame_Load_Error.
3634  */
3635 void ewk_view_load_error(Evas_Object* o, const Ewk_Frame_Load_Error* error)
3636 {
3637     DBG("o=%p, error=%p", o, error);
3638     evas_object_smart_callback_call(o, "load,error", (void*)error);
3639 }
3640
3641 /**
3642  * @internal
3643  * Reports load progress changed.
3644  *
3645  * Emits signal: "load,progress" with pointer to a double from 0.0 to 1.0.
3646  */
3647 void ewk_view_load_progress_changed(Evas_Object* o)
3648 {
3649     EWK_VIEW_SD_GET_OR_RETURN(o, sd);
3650     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv);
3651
3652     // Evas_Coord w, h;
3653     double progress = priv->page->progress()->estimatedProgress();
3654
3655     DBG("o=%p (p=%0.3f)", o, progress);
3656
3657     evas_object_smart_callback_call(o, "load,progress", &progress);
3658 }
3659
3660 /**
3661  * @internal
3662  * Reports view @param o should be restored to default conditions
3663  *
3664  * @param o View.
3665  * @param frame Frame that originated restore.
3666  *
3667  * Emits signal: "restore" with frame.
3668  */
3669 void ewk_view_restore_state(Evas_Object* o, Evas_Object* frame)
3670 {
3671     evas_object_smart_callback_call(o, "restore", frame);
3672 }
3673
3674 /**
3675  * @internal
3676  * Delegates to browser the creation of a new window. If it is not implemented,
3677  * current view is returned, so navigation might continue in same window. If
3678  * browser supports the creation of new windows, a new Ewk_Window_Features is
3679  * created and passed to browser. If it intends to keep the request for opening
3680  * the window later it must increments the Ewk_Winwdow_Features ref count by
3681  * calling ewk_window_features_ref(window_features). Otherwise this struct will
3682  * be freed after returning to this function.
3683  *
3684  * @param o Current view.
3685  * @param javascript @c EINA_TRUE if the new window is originated from javascript,
3686  * @c EINA_FALSE otherwise
3687  * @param window_features Features of the new window being created. If it's @c
3688  * NULL, it will be created a window with default features.
3689  *
3690  * @return New view, in case smart class implements the creation of new windows;
3691  * else, current view @param o.
3692  *
3693  * @see ewk_window_features_ref().
3694  */
3695 Evas_Object* ewk_view_window_create(Evas_Object* o, Eina_Bool javascript, const WebCore::WindowFeatures* coreFeatures)
3696 {
3697     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
3698
3699     if (!sd->api->window_create)
3700         return o;
3701
3702     Ewk_Window_Features* window_features = ewk_window_features_new_from_core(coreFeatures);
3703     Evas_Object* view = sd->api->window_create(sd, javascript, window_features);
3704     ewk_window_features_unref(window_features);
3705
3706     return view;
3707 }
3708
3709 /**
3710  * @internal
3711  * Reports a window should be closed. It's client responsibility to decide if
3712  * the window should in fact be closed. So, if only windows created by javascript
3713  * are allowed to be closed by this call, browser needs to save the javascript
3714  * flag when the window is created. Since a window can close itself (for example
3715  * with a 'self.close()' in Javascript) browser must postpone the deletion to an
3716  * idler.
3717  *
3718  * @param o View to be closed.
3719  */
3720 void ewk_view_window_close(Evas_Object* o)
3721 {
3722     EWK_VIEW_SD_GET_OR_RETURN(o, sd);
3723
3724     ewk_view_stop(o);
3725     if (!sd->api->window_close)
3726         return;
3727     sd->api->window_close(sd);
3728 }
3729
3730 /**
3731  * @internal
3732  * Reports mouse has moved over a link.
3733  *
3734  * Emits signal: "link,hover,in"
3735  */
3736 void ewk_view_mouse_link_hover_in(Evas_Object* o, void* data)
3737 {
3738     evas_object_smart_callback_call(o, "link,hover,in", data);
3739 }
3740
3741 /**
3742  * @internal
3743  * Reports mouse is not over a link anymore.
3744  *
3745  * Emits signal: "link,hover,out"
3746  */
3747 void ewk_view_mouse_link_hover_out(Evas_Object* o)
3748 {
3749     evas_object_smart_callback_call(o, "link,hover,out", 0);
3750 }
3751
3752 /**
3753  * @internal
3754  * Set toolbar visible.
3755  *
3756  * Emits signal: "toolbars,visible,set" with a pointer to a boolean.
3757  */
3758 void ewk_view_toolbars_visible_set(Evas_Object* o, Eina_Bool visible)
3759 {
3760     DBG("o=%p (visible=%d)", o, !!visible);
3761     evas_object_smart_callback_call(o, "toolbars,visible,set", &visible);
3762 }
3763
3764 /**
3765  * @internal
3766  * Get toolbar visibility.
3767  *
3768  * @param o View.
3769  * @param visible boolean pointer in which to save the result. It defaults
3770  * to @c FALSE, i.e. if browser does no listen to emitted signal, it means
3771  * there are no toolbars and therefore they are not visible.
3772  *
3773  * Emits signal: "toolbars,visible,get" with a pointer to a boolean.
3774  */
3775 void ewk_view_toolbars_visible_get(Evas_Object* o, Eina_Bool* visible)
3776 {
3777     DBG("%s, o=%p", __func__, o);
3778     *visible = EINA_FALSE;
3779     evas_object_smart_callback_call(o, "toolbars,visible,get", visible);
3780 }
3781
3782 /**
3783  * @internal
3784  * Set statusbar visible.
3785  *
3786  * @param o View.
3787  * @param visible @c TRUE if statusbar are visible, @c FALSE otherwise.
3788  *
3789  * Emits signal: "statusbar,visible,set" with a pointer to a boolean.
3790  */
3791 void ewk_view_statusbar_visible_set(Evas_Object* o, Eina_Bool visible)
3792 {
3793     DBG("o=%p (visible=%d)", o, !!visible);
3794     evas_object_smart_callback_call(o, "statusbar,visible,set", &visible);
3795 }
3796
3797 /**
3798  * @internal
3799  * Get statusbar visibility.
3800  *
3801  * @param o View.
3802  * @param visible boolean pointer in which to save the result. It defaults
3803  * to @c FALSE, i.e. if browser does no listen to emitted signal, it means
3804  * there is no statusbar and therefore it is not visible.
3805  *
3806  * Emits signal: "statusbar,visible,get" with a pointer to a boolean.
3807  */
3808 void ewk_view_statusbar_visible_get(Evas_Object* o, Eina_Bool* visible)
3809 {
3810     DBG("%s, o=%p", __func__, o);
3811     *visible = EINA_FALSE;
3812     evas_object_smart_callback_call(o, "statusbar,visible,get", visible);
3813 }
3814
3815 /**
3816  * @internal
3817  * Set text of statusbar
3818  *
3819  * @param o View.
3820  * @param text New text to put on statusbar.
3821  *
3822  * Emits signal: "statusbar,text,set" with a string.
3823  */
3824 void ewk_view_statusbar_text_set(Evas_Object* o, const char* text)
3825 {
3826     DBG("o=%p (text=%s)", o, text);
3827     INF("status bar text set: %s", text);
3828     evas_object_smart_callback_call(o, "statusbar,text,set", (void *)text);
3829 }
3830
3831 /**
3832  * @internal
3833  * Set scrollbars visible.
3834  *
3835  * @param o View.
3836  * @param visible @c TRUE if scrollbars are visible, @c FALSE otherwise.
3837  *
3838  * Emits signal: "scrollbars,visible,set" with a pointer to a boolean.
3839  */
3840 void ewk_view_scrollbars_visible_set(Evas_Object* o, Eina_Bool visible)
3841 {
3842     DBG("o=%p (visible=%d)", o, !!visible);
3843     evas_object_smart_callback_call(o, "scrollbars,visible,set", &visible);
3844 }
3845
3846 /**
3847  * @internal
3848  * Get scrollbars visibility.
3849  *
3850  * @param o View.
3851  * @param visible boolean pointer in which to save the result. It defaults
3852  * to @c FALSE, i.e. if browser does no listen to emitted signal, it means
3853  * there are no scrollbars and therefore they are not visible.
3854  *
3855  * Emits signal: "scrollbars,visible,get" with a pointer to a boolean.
3856  */
3857 void ewk_view_scrollbars_visible_get(Evas_Object* o, Eina_Bool* visible)
3858 {
3859     DBG("%s, o=%p", __func__, o);
3860     *visible = EINA_FALSE;
3861     evas_object_smart_callback_call(o, "scrollbars,visible,get", visible);
3862 }
3863
3864 /**
3865  * @internal
3866  * Set menubar visible.
3867  *
3868  * @param o View.
3869  * @param visible @c TRUE if menubar is visible, @c FALSE otherwise.
3870  *
3871  * Emits signal: "menubar,visible,set" with a pointer to a boolean.
3872  */
3873 void ewk_view_menubar_visible_set(Evas_Object* o, Eina_Bool visible)
3874 {
3875     DBG("o=%p (visible=%d)", o, !!visible);
3876     evas_object_smart_callback_call(o, "menubar,visible,set", &visible);
3877 }
3878
3879 /**
3880  * @internal
3881  * Get menubar visibility.
3882  *
3883  * @param o View.
3884  * @param visible boolean pointer in which to save the result. It defaults
3885  * to @c FALSE, i.e. if browser does no listen to emitted signal, it means
3886  * there is no menubar and therefore it is not visible.
3887  *
3888  * Emits signal: "menubar,visible,get" with a pointer to a boolean.
3889  */
3890 void ewk_view_menubar_visible_get(Evas_Object* o, Eina_Bool* visible)
3891 {
3892     DBG("%s, o=%p", __func__, o);
3893     *visible = EINA_FALSE;
3894     evas_object_smart_callback_call(o, "menubar,visible,get", visible);
3895 }
3896
3897 /**
3898  * @internal
3899  * Set tooltip text and display if it is currently hidden.
3900  *
3901  * @param o View.
3902  * @param text Text to set tooltip to.
3903  *
3904  * Emits signal: "tooltip,text,set" with a string. If tooltip must be actually
3905  * removed, text will be 0 or '\0'
3906  */
3907 void ewk_view_tooltip_text_set(Evas_Object* o, const char* text)
3908 {
3909     DBG("o=%p text=%s", o, text);
3910     evas_object_smart_callback_call(o, "tooltip,text,set", (void *)text);
3911 }
3912
3913 /**
3914  * @internal
3915  *
3916  * @param o View.
3917  * @param message String to show on console.
3918  * @param lineNumber Line number.
3919  * @sourceID Source id.
3920  *
3921  */
3922 void ewk_view_add_console_message(Evas_Object* o, const char* message, unsigned int lineNumber, const char* sourceID)
3923 {
3924     DBG("o=%p message=%s lineNumber=%u sourceID=%s", o, message, lineNumber, sourceID);
3925     EWK_VIEW_SD_GET_OR_RETURN(o, sd);
3926     EINA_SAFETY_ON_NULL_RETURN(sd->api);
3927     EINA_SAFETY_ON_NULL_RETURN(sd->api->add_console_message);
3928     sd->api->add_console_message(sd, message, lineNumber, sourceID);
3929 }
3930
3931 void ewk_view_run_javascript_alert(Evas_Object* o, Evas_Object* frame, const char* message)
3932 {
3933     DBG("o=%p frame=%p message=%s", o, frame, message);
3934     EWK_VIEW_SD_GET_OR_RETURN(o, sd);
3935     EINA_SAFETY_ON_NULL_RETURN(sd->api);
3936
3937     if (!sd->api->run_javascript_alert)
3938         return;
3939
3940     sd->api->run_javascript_alert(sd, frame, message);
3941 }
3942
3943 Eina_Bool ewk_view_run_javascript_confirm(Evas_Object* o, Evas_Object* frame, const char* message)
3944 {
3945     DBG("o=%p frame=%p message=%s", o, frame, message);
3946     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
3947     EINA_SAFETY_ON_NULL_RETURN_VAL(sd->api, EINA_FALSE);
3948
3949     if (!sd->api->run_javascript_confirm)
3950         return EINA_FALSE;
3951
3952     return sd->api->run_javascript_confirm(sd, frame, message);
3953 }
3954
3955 Eina_Bool ewk_view_run_javascript_prompt(Evas_Object* o, Evas_Object* frame, const char* message, const char* defaultValue, char** value)
3956 {
3957     DBG("o=%p frame=%p message=%s", o, frame, message);
3958     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
3959     EINA_SAFETY_ON_NULL_RETURN_VAL(sd->api, EINA_FALSE);
3960
3961     if (!sd->api->run_javascript_prompt)
3962         return EINA_FALSE;
3963
3964     return sd->api->run_javascript_prompt(sd, frame, message, defaultValue, value);
3965 }
3966
3967 /**
3968  * @internal
3969  * Delegates to client to decide whether a script must be stopped because it's
3970  * running for too long. If client does not implement it, it goes to default
3971  * implementation, which logs and returns EINA_FALSE. Client may remove log by
3972  * setting this function 0, which will just return EINA_FALSE.
3973  *
3974  * @param o View.
3975  *
3976  * @return @c EINA_TRUE if script should be stopped; @c EINA_FALSE otherwise
3977  */
3978 Eina_Bool ewk_view_should_interrupt_javascript(Evas_Object* o)
3979 {
3980     DBG("o=%p", o);
3981     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
3982     EINA_SAFETY_ON_NULL_RETURN_VAL(sd->api, EINA_FALSE);
3983
3984     if (!sd->api->should_interrupt_javascript)
3985         return EINA_FALSE;
3986
3987     return sd->api->should_interrupt_javascript(sd);
3988 }
3989
3990 /**
3991  * @internal
3992  * This is called whenever the web site shown in @param frame is asking to store data
3993  * to the database @param databaseName and the quota allocated to that web site
3994  * is exceeded. Browser may use this to increase the size of quota before the
3995  * originating operationa fails.
3996  *
3997  * @param o View.
3998  * @param frame The frame whose web page exceeded its database quota.
3999  * @param databaseName Database name.
4000  * @param current_size Current size of this database
4001  * @param expected_size The expected size of this database in order to fulfill
4002  * site's requirement.
4003  */
4004 uint64_t ewk_view_exceeded_database_quota(Evas_Object* o, Evas_Object* frame, const char* databaseName, uint64_t current_size, uint64_t expected_size)
4005 {
4006     DBG("o=%p", o);
4007     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
4008     EINA_SAFETY_ON_NULL_RETURN_VAL(sd->api, 0);
4009     if (!sd->api->exceeded_database_quota)
4010         return 0;
4011
4012     INF("current_size=%"PRIu64" expected_size=%"PRIu64, current_size, expected_size);
4013     return sd->api->exceeded_database_quota(sd, frame, databaseName, current_size, expected_size);
4014 }
4015
4016 /**
4017  * @internal
4018  * Open panel to choose a file.
4019  *
4020  * @param o View.
4021  * @param frame Frame in which operation is required.
4022  * @param allows_multiple_files @c EINA_TRUE when more than one file may be
4023  * selected, @c EINA_FALSE otherwise
4024  * @suggested_filenames List of suggested files to select. It's advisable to
4025  * just ignore this value, since it's a source of security flaw.
4026  * @selected_filenames List of files selected.
4027  *
4028  * @return @EINA_FALSE if user canceled file selection; @EINA_TRUE if confirmed.
4029  */
4030 Eina_Bool ewk_view_run_open_panel(Evas_Object* o, Evas_Object* frame, Eina_Bool allows_multiple_files, const Eina_List* suggested_filenames, Eina_List** selected_filenames)
4031 {
4032     DBG("o=%p frame=%p allows_multiple_files=%d", o, frame, allows_multiple_files);
4033     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
4034     EINA_SAFETY_ON_NULL_RETURN_VAL(sd->api, EINA_FALSE);
4035     Eina_Bool confirm;
4036
4037     if (!sd->api->run_open_panel)
4038         return EINA_FALSE;
4039
4040     *selected_filenames = 0;
4041
4042     confirm = sd->api->run_open_panel(sd, frame, allows_multiple_files, suggested_filenames, selected_filenames);
4043     if (!confirm && *selected_filenames)
4044         ERR("Canceled file selection, but selected filenames != 0. Free names before return.");
4045     return confirm;
4046 }
4047
4048 void ewk_view_repaint(Evas_Object* o, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h)
4049 {
4050     DBG("o=%p, region=%d,%d + %dx%d", o, x, y, w, h);
4051     EWK_VIEW_SD_GET_OR_RETURN(o, sd);
4052     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv);
4053
4054     if (!priv->main_frame->contentRenderer()) {
4055         ERR("no main frame content renderer.");
4056         return;
4057     }
4058
4059     _ewk_view_repaint_add(priv, x, y, w, h);
4060     _ewk_view_smart_changed(sd);
4061 }
4062
4063 void ewk_view_scroll(Evas_Object* o, Evas_Coord dx, Evas_Coord dy, Evas_Coord sx, Evas_Coord sy, Evas_Coord sw, Evas_Coord sh, Evas_Coord cx, Evas_Coord cy, Evas_Coord cw, Evas_Coord ch, Eina_Bool main_frame)
4064 {
4065     DBG("o=%p, delta: %d,%d, scroll: %d,%d+%dx%d, clip: %d,%d+%dx%d",
4066         o, dx, dy, sx, sy, sw, sh, cx, cy, cw, ch);
4067
4068     if ((sx != cx) || (sy != cy) || (sw != cw) || (sh != ch))
4069         WRN("scroll region and clip are different! %d,%d+%dx%d and %d,%d+%dx%d",
4070             sx, sy, sw, sh, cx, cy, cw, ch);
4071
4072     EWK_VIEW_SD_GET_OR_RETURN(o, sd);
4073     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv);
4074     EINA_SAFETY_ON_TRUE_RETURN(!dx && !dy);
4075
4076     _ewk_view_scroll_add(priv, dx, dy, sx, sy, sw, sh, main_frame);
4077
4078     _ewk_view_smart_changed(sd);
4079 }
4080
4081 WebCore::Page* ewk_view_core_page_get(const Evas_Object* o)
4082 {
4083     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
4084     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0);
4085     return priv->page;
4086 }
4087
4088 /**
4089  * Creates a new frame for given url and owner element.
4090  *
4091  * Emits "frame,created" with the new frame object on success.
4092  */
4093 WTF::PassRefPtr<WebCore::Frame> ewk_view_frame_create(Evas_Object* o, Evas_Object* frame, const WTF::String& name, WebCore::HTMLFrameOwnerElement* ownerElement, const WebCore::KURL& url, const WTF::String& referrer)
4094 {
4095     DBG("o=%p, frame=%p, name=%s, ownerElement=%p, url=%s, referrer=%s",
4096         o, frame, name.utf8().data(), ownerElement,
4097         url.prettyURL().utf8().data(), referrer.utf8().data());
4098
4099     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
4100     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0);
4101
4102     WTF::RefPtr<WebCore::Frame> cf = _ewk_view_core_frame_new
4103         (sd, priv, ownerElement);
4104     if (!cf) {
4105         ERR("Could not create child core frame '%s'", name.utf8().data());
4106         return 0;
4107     }
4108
4109     if (!ewk_frame_child_add(frame, cf, name, url, referrer)) {
4110         ERR("Could not create child frame object '%s'", name.utf8().data());
4111         return 0;
4112     }
4113
4114     // The creation of the frame may have removed itself already.
4115     if (!cf->page() || !cf->tree() || !cf->tree()->parent())
4116         return 0;
4117
4118     sd->changed.frame_rect = EINA_TRUE;
4119     _ewk_view_smart_changed(sd);
4120
4121     evas_object_smart_callback_call(o, "frame,created", frame);
4122     return cf.release();
4123 }
4124
4125 WTF::PassRefPtr<WebCore::Widget> ewk_view_plugin_create(Evas_Object* o, 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)
4126 {
4127     DBG("o=%p, frame=%p, size=%dx%d, element=%p, url=%s, mimeType=%s",
4128         o, frame, pluginSize.width(), pluginSize.height(), element,
4129         url.prettyURL().utf8().data(), mimeType.utf8().data());
4130
4131     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
4132     sd->changed.frame_rect = EINA_TRUE;
4133     _ewk_view_smart_changed(sd);
4134
4135     return ewk_frame_plugin_create
4136         (frame, pluginSize, element, url, paramNames, paramValues,
4137          mimeType, loadManually);
4138 }
4139
4140
4141 /**
4142  * @internal
4143  *
4144  * Creates a new popup with options when a select widget was clicked.
4145  *
4146  * @param client PopupMenuClient instance that allows communication with webkit.
4147  * @param selected Selected item.
4148  * @param rect Menu's position.
4149  *
4150  * Emits: "popup,create" with a list of Ewk_Menu containing each item's data
4151  */
4152 void ewk_view_popup_new(Evas_Object* o, WebCore::PopupMenuClient* client, int selected, const WebCore::IntRect& rect)
4153 {
4154     INF("o=%p", o);
4155     EWK_VIEW_SD_GET_OR_RETURN(o, sd);
4156     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv);
4157
4158     if (priv->popup.menu_client)
4159         ewk_view_popup_destroy(o);
4160
4161     priv->popup.menu_client = client;
4162
4163     // populate items
4164     const int size = client->listSize();
4165     for (int i = 0; i < size; ++i) {
4166         Ewk_Menu_Item* item = (Ewk_Menu_Item*) malloc(sizeof(*item));
4167         if (client->itemIsSeparator(i))
4168             item->type = EWK_MENU_SEPARATOR;
4169         else if (client->itemIsLabel(i))
4170             item->type = EWK_MENU_GROUP;
4171         else
4172             item->type = EWK_MENU_OPTION;
4173         item->text = eina_stringshare_add(client->itemText(i).utf8().data());
4174
4175         priv->popup.menu.items = eina_list_append(priv->popup.menu.items, item);
4176     }
4177
4178     priv->popup.menu.x = rect.x();
4179     priv->popup.menu.y = rect.y();
4180     priv->popup.menu.width = rect.width();
4181     priv->popup.menu.height = rect.height();
4182     evas_object_smart_callback_call(o, "popup,create", &priv->popup.menu);
4183 }
4184
4185 /**
4186  * Destroy a previously created menu.
4187  *
4188  * Before destroying, it informs client that menu's data is ready to be
4189  * destroyed by sending a "popup,willdelete" with a list of menu items. Then it
4190  * removes any reference to menu inside webkit. It's safe to call this
4191  * function either from inside webkit or from browser.
4192  *
4193  * @param o View.
4194  *
4195  * @returns EINA_TRUE in case menu was successfully destroyed or EINA_TRUE in
4196  * case there wasn't any menu to be destroyed.
4197  */
4198 Eina_Bool ewk_view_popup_destroy(Evas_Object* o)
4199 {
4200     INF("o=%p", o);
4201     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
4202     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
4203
4204     if (!priv->popup.menu_client)
4205         return EINA_FALSE;
4206
4207     evas_object_smart_callback_call(o, "popup,willdelete", &priv->popup.menu);
4208
4209     void* itemv;
4210     EINA_LIST_FREE(priv->popup.menu.items, itemv) {
4211         Ewk_Menu_Item* item = (Ewk_Menu_Item*)itemv;
4212         eina_stringshare_del(item->text);
4213         free(item);
4214     }
4215     priv->popup.menu_client->popupDidHide();
4216     priv->popup.menu_client = 0;
4217
4218     return EINA_TRUE;
4219 }
4220
4221 /**
4222  * Changes currently selected item.
4223  *
4224  * Changes the option selected in select widget. This is called by browser
4225  * whenever user has chosen a different item. Most likely after calling this, a
4226  * call to ewk_view_popup_destroy might be made in order to close the popup.
4227  *
4228  * @param o View.
4229  * @index Index of selected item.
4230  *
4231  */
4232 void ewk_view_popup_selected_set(Evas_Object* o, int index)
4233 {
4234     INF("o=%p", o);
4235     EWK_VIEW_SD_GET_OR_RETURN(o, sd);
4236     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv);
4237     EINA_SAFETY_ON_NULL_RETURN(priv->popup.menu_client);
4238
4239     priv->popup.menu_client->valueChanged(index);
4240 }
4241
4242 /**
4243  * @internal
4244  * Request a download to user.
4245  *
4246  * @param o View.
4247  * @oaram download Ewk_Download struct to be sent.
4248  *
4249  * Emits: "download,request" with an Ewk_Download containing the details of the
4250  * requested download. The download per se must be handled outside of webkit.
4251  */
4252 void ewk_view_download_request(Evas_Object* o, Ewk_Download* download)
4253 {
4254     DBG("view=%p", o);
4255     evas_object_smart_callback_call(o, "download,request", download);
4256 }
4257
4258 /**
4259  * @internal
4260  * Reports the viewport has changed.
4261  *
4262  * @param arguments viewport argument.
4263  *
4264  * Emits signal: "viewport,changed" with no parameters.
4265  */
4266 void ewk_view_viewport_attributes_set(Evas_Object *o, const WebCore::ViewportArguments& arguments)
4267 {
4268     EWK_VIEW_SD_GET(o, sd);
4269     EWK_VIEW_PRIV_GET(sd, priv);
4270     
4271     priv->viewport_arguments = arguments;
4272     evas_object_smart_callback_call(o, "viewport,changed", 0);
4273 }
4274
4275 /**
4276  * Gets attributes of viewport meta tag.
4277  *
4278  * @param o view.
4279  * @param w width.
4280  * @param h height.
4281  * @param init_scale initial Scale value.
4282  * @param max_scale maximum Scale value.
4283  * @param min_scale minimum Scale value.
4284  * @param device_pixel_ratio value.
4285  * @param user_scalable user Scalable value.
4286  */
4287 void ewk_view_viewport_attributes_get(Evas_Object *o, float* w, float* h, float* init_scale, float* max_scale, float* min_scale, float* device_pixel_ratio, Eina_Bool* user_scalable)
4288 {
4289     WebCore::ViewportAttributes attributes = _ewk_view_viewport_attributes_compute(o);
4290
4291     if (w)
4292         *w = attributes.layoutSize.width();
4293     if (h)
4294         *h = attributes.layoutSize.height();
4295     if (init_scale)
4296         *init_scale = attributes.initialScale;
4297     if (max_scale)
4298         *max_scale = attributes.maximumScale;
4299     if (min_scale)
4300         *min_scale = attributes.minimumScale;
4301     if (device_pixel_ratio)
4302         *device_pixel_ratio = attributes.devicePixelRatio;
4303     if (user_scalable)
4304         *user_scalable = attributes.userScalable;
4305 }
4306
4307 /**
4308  * Sets the zoom range.
4309  *
4310  * @param o view.
4311  * @param min_scale minimum value of zoom range.
4312  * @param max_scale maximum value of zoom range.
4313  * 
4314  * @return @c EINA_TRUE if zoom range is changed, @c EINA_FALSE if not or failure.
4315  */
4316 Eina_Bool ewk_view_zoom_range_set(Evas_Object* o, float min_scale, float max_scale)
4317 {
4318     EWK_VIEW_SD_GET(o, sd);
4319     EWK_VIEW_PRIV_GET(sd, priv);
4320
4321     if (max_scale < min_scale) {
4322         WRN("min_scale is larger than max_scale");
4323         return EINA_FALSE;
4324     }
4325
4326     priv->settings.zoom_range.min_scale = min_scale;
4327     priv->settings.zoom_range.max_scale = max_scale;
4328
4329     return EINA_TRUE;
4330 }
4331
4332 /**
4333  * Gets the minimum value of zoom range.
4334  *
4335  * @param o view.
4336  *
4337  * @return minimum value of zoom range.
4338  */
4339 float ewk_view_zoom_range_min_get(Evas_Object* o)
4340 {
4341     EWK_VIEW_SD_GET(o, sd);
4342     EWK_VIEW_PRIV_GET(sd, priv);
4343
4344     return priv->settings.zoom_range.min_scale;
4345 }
4346
4347 /**
4348  * Gets the maximum value of zoom range.
4349  *
4350  * @param o view.
4351  *
4352  * @return maximum value of zoom range.
4353  */
4354 float ewk_view_zoom_range_max_get(Evas_Object* o)
4355 {
4356     EWK_VIEW_SD_GET(o, sd);
4357     EWK_VIEW_PRIV_GET(sd, priv);
4358
4359     return priv->settings.zoom_range.max_scale;
4360 }
4361
4362 /**
4363  * Sets if zoom is enabled.
4364  *
4365  * @param o view.
4366  * @param user_scalable boolean pointer in which to enable zoom. It defaults
4367  * to @c EINA_TRUE.
4368  */
4369 void ewk_view_user_scalable_set(Evas_Object* o, Eina_Bool user_scalable)
4370 {
4371     EWK_VIEW_SD_GET(o, sd);
4372     EWK_VIEW_PRIV_GET(sd, priv);
4373
4374     priv->settings.zoom_range.user_scalable = user_scalable;
4375 }
4376
4377 /**
4378  * Gets if zoom is enabled.
4379  *
4380  * @param o view.
4381  * @param user_scalable where to return the current user scalable value.
4382  *
4383  * @return @c EINA_TRUE if zoom is enabled, @c EINA_FALSE if not.
4384  */
4385 Eina_Bool ewk_view_user_scalable_get(Evas_Object* o)
4386 {
4387     EWK_VIEW_SD_GET(o, sd);
4388     EWK_VIEW_PRIV_GET(sd, priv);
4389
4390     return priv->settings.zoom_range.user_scalable;
4391 }
4392
4393 /**
4394  * Gets device pixel ratio value.
4395  *
4396  * @param o view.
4397  * @param user_scalable where to return the current user scalable value.
4398  *
4399  * @return @c EINA_TRUE if zoom is enabled, @c EINA_FALSE if not.
4400  */
4401 float ewk_view_device_pixel_ratio_get(Evas_Object* o)
4402 {
4403     EWK_VIEW_SD_GET(o, sd);
4404     EWK_VIEW_PRIV_GET(sd, priv);
4405
4406     return priv->settings.device_pixel_ratio;
4407 }
4408
4409 void ewk_view_did_first_visually_nonempty_layout(Evas_Object *o)
4410 {
4411     EWK_VIEW_SD_GET_OR_RETURN(o, sd);
4412     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv);
4413     if (!priv->flags.view_cleared) {
4414         ewk_view_frame_main_cleared(o);
4415         ewk_view_enable_render(o);
4416         priv->flags.view_cleared = EINA_TRUE;
4417     }
4418 }
4419
4420 /**
4421  * @internal
4422  * Dispatch finished loading.
4423  *
4424  * @param o view.
4425  */
4426 void ewk_view_dispatch_did_finish_loading(Evas_Object *o)
4427 {
4428     /* If we reach this point and rendering is still disabled, WebCore will not
4429      * trigger the didFirstVisuallyNonEmptyLayout signal anymore. So, we
4430      * forcefully re-enable the rendering.
4431      */
4432     ewk_view_did_first_visually_nonempty_layout(o);
4433 }
4434
4435 void ewk_view_transition_to_commited_for_newpage(Evas_Object *o)
4436 {
4437     EWK_VIEW_SD_GET_OR_RETURN(o, sd);
4438     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv);
4439
4440     ewk_view_disable_render(o);
4441     priv->flags.view_cleared = EINA_FALSE;
4442 }
4443
4444
4445 /**
4446  * @internal
4447  * Reports a requeset will be loaded. It's client responsibility to decide if
4448  * request would be used. If @return is true, loader will try to load. Else,
4449  * Loader ignore action of request.
4450  *
4451  * @param o View to load
4452  * @param request Request which contain url to navigate
4453  */
4454 Eina_Bool ewk_view_navigation_policy_decision(Evas_Object* o, Ewk_Frame_Resource_Request* request)
4455 {
4456     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_TRUE);
4457     EINA_SAFETY_ON_NULL_RETURN_VAL(sd->api, EINA_TRUE);
4458
4459     if (!sd->api->navigation_policy_decision)
4460         return EINA_TRUE;
4461
4462     return sd->api->navigation_policy_decision(sd, request);
4463 }
4464