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