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