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