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