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