[EFL][WK2] Extract the control of page background out of color_set
[WebKit-https.git] / Source / WebKit2 / UIProcess / API / efl / ewk_view.cpp
1 /*
2    Copyright (C) 2011 Samsung Electronics
3    Copyright (C) 2012 Intel Corporation. All rights reserved.
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 #include "config.h"
22 #include "ewk_view.h"
23 #include "ewk_view_private.h"
24
25 #include "EwkView.h"
26 #include "FindClientEfl.h"
27 #include "FormClientEfl.h"
28 #include "InputMethodContextEfl.h"
29 #include "PageLoadClientEfl.h"
30 #include "PagePolicyClientEfl.h"
31 #include "PageUIClientEfl.h"
32 #include "PageViewportController.h"
33 #include "PageViewportControllerClientEfl.h"
34 #include "ewk_back_forward_list_private.h"
35 #include "ewk_context.h"
36 #include "ewk_context_private.h"
37 #include "ewk_favicon_database_private.h"
38 #include "ewk_page_group.h"
39 #include "ewk_page_group_private.h"
40 #include "ewk_private.h"
41 #include "ewk_settings_private.h"
42 #include <Ecore_Evas.h>
43 #include <JavaScriptCore/JSRetainPtr.h>
44 #include <WebKit2/WKAPICast.h>
45 #include <WebKit2/WKData.h>
46 #include <WebKit2/WKEinaSharedString.h>
47 #include <WebKit2/WKFindOptions.h>
48 #include <WebKit2/WKInspector.h>
49 #include <WebKit2/WKPageGroup.h>
50 #include <WebKit2/WKRetainPtr.h>
51 #include <WebKit2/WKSerializedScriptValue.h>
52 #include <WebKit2/WKString.h>
53 #include <WebKit2/WKURL.h>
54 #include <WebKit2/WKView.h>
55 #include <WebKit2/WKViewEfl.h>
56 #include <wtf/text/CString.h>
57
58 #if ENABLE(INSPECTOR)
59 #include "WebInspectorProxy.h"
60 #endif
61
62 using namespace WebKit;
63
64 static inline EwkView* toEwkViewChecked(const Evas_Object* evasObject)
65 {
66     EINA_SAFETY_ON_NULL_RETURN_VAL(evasObject, nullptr);
67     if (EINA_UNLIKELY(!isEwkViewEvasObject(evasObject)))
68         return 0;
69
70     Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(evas_object_smart_data_get(evasObject));
71     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData, nullptr);
72
73     return smartData->priv;
74 }
75
76 #define EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, ...)                        \
77     EwkView* impl = toEwkViewChecked(ewkView);                                 \
78     do {                                                                       \
79         if (EINA_UNLIKELY(!impl)) {                                            \
80             EINA_LOG_CRIT("no private data for object %p", ewkView);           \
81             return __VA_ARGS__;                                                \
82         }                                                                      \
83     } while (0)
84
85
86 Eina_Bool ewk_view_smart_class_set(Ewk_View_Smart_Class* api)
87 {
88     EINA_SAFETY_ON_NULL_RETURN_VAL(api, false);
89
90     return EwkView::initSmartClassInterface(*api);
91 }
92
93 Evas_Object* EWKViewCreate(WKContextRef context, WKPageGroupRef pageGroup, Evas* canvas, Evas_Smart* smart)
94 {
95     WKRetainPtr<WKViewRef> wkView = adoptWK(WKViewCreate(context, pageGroup));
96     if (EwkView* ewkView = EwkView::create(wkView.get(), canvas, smart))
97         return ewkView->evasObject();
98
99     return 0;
100 }
101
102 WKViewRef EWKViewGetWKView(Evas_Object* ewkView)
103 {
104     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, nullptr);
105
106     return impl->wkView();
107 }
108
109 Evas_Object* ewk_view_smart_add(Evas* canvas, Evas_Smart* smart, Ewk_Context* context, Ewk_Page_Group* pageGroup)
110 {
111     EwkContext* ewkContext = ewk_object_cast<EwkContext*>(context);
112     EwkPageGroup* ewkPageGroup = ewk_object_cast<EwkPageGroup*>(pageGroup);
113
114     EINA_SAFETY_ON_NULL_RETURN_VAL(ewkContext, nullptr);
115     EINA_SAFETY_ON_NULL_RETURN_VAL(ewkContext->wkContext(), nullptr);
116     EINA_SAFETY_ON_NULL_RETURN_VAL(ewkPageGroup, nullptr);
117     EINA_SAFETY_ON_NULL_RETURN_VAL(ewkPageGroup->wkPageGroup(), nullptr);
118
119     return EWKViewCreate(ewkContext->wkContext(), ewkPageGroup->wkPageGroup(), canvas, smart);
120 }
121
122 Evas_Object* ewk_view_add(Evas* canvas)
123 {
124     return EWKViewCreate(adoptWK(WKContextCreate()).get(), 0, canvas, 0);
125 }
126
127 Evas_Object* ewk_view_add_with_context(Evas* canvas, Ewk_Context* context)
128 {
129     EwkContext* ewkContext = ewk_object_cast<EwkContext*>(context);
130     EINA_SAFETY_ON_NULL_RETURN_VAL(ewkContext, nullptr);
131     EINA_SAFETY_ON_NULL_RETURN_VAL(ewkContext->wkContext(), nullptr);
132
133     return EWKViewCreate(ewkContext->wkContext(), 0, canvas, 0);
134 }
135
136 Ewk_Context* ewk_view_context_get(const Evas_Object* ewkView)
137 {
138     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, nullptr);
139
140     return impl->ewkContext();
141 }
142
143 Ewk_Page_Group* ewk_view_page_group_get(const Evas_Object* ewkView)
144 {
145     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, nullptr);
146
147     return impl->ewkPageGroup();
148 }
149
150 Eina_Bool ewk_view_url_set(Evas_Object* ewkView, const char* url)
151 {
152     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
153     EINA_SAFETY_ON_NULL_RETURN_VAL(url, false);
154
155     WKRetainPtr<WKURLRef> wkUrl = adoptWK(WKURLCreateWithUTF8CString(url));
156     WKPageLoadURL(impl->wkPage(), wkUrl.get());
157     impl->informURLChange();
158
159     return true;
160 }
161
162 const char* ewk_view_url_get(const Evas_Object* ewkView)
163 {
164     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, nullptr);
165
166     return impl->url();
167 }
168
169 Evas_Object* ewk_view_favicon_get(const Evas_Object* ewkView)
170 {
171     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, nullptr);
172
173     return impl->createFavicon();
174 }
175
176 Eina_Bool ewk_view_reload(Evas_Object* ewkView)
177 {
178     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
179
180     WKPageReload(impl->wkPage());
181     impl->informURLChange();
182
183     return true;
184 }
185
186 Eina_Bool ewk_view_reload_bypass_cache(Evas_Object* ewkView)
187 {
188     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
189
190     WKPageReloadFromOrigin(impl->wkPage());
191     impl->informURLChange();
192
193     return true;
194 }
195
196 Eina_Bool ewk_view_stop(Evas_Object* ewkView)
197 {
198     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
199
200     WKPageStopLoading(impl->wkPage());
201
202     return true;
203 }
204
205 Ewk_Settings* ewk_view_settings_get(const Evas_Object* ewkView)
206 {
207     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, nullptr);
208
209     return impl->settings();
210 }
211
212 const char* ewk_view_title_get(const Evas_Object* ewkView)
213 {
214     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, nullptr);
215
216     return impl->title();
217 }
218
219 double ewk_view_load_progress_get(const Evas_Object* ewkView)
220 {
221     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, -1.0);
222
223     return WKPageGetEstimatedProgress(impl->wkPage());
224 }
225
226 Eina_Bool ewk_view_scale_set(Evas_Object* ewkView, double scaleFactor, int x, int y)
227 {
228     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
229
230     WKPageSetScaleFactor(impl->wkPage(), scaleFactor, WKPointMake(x, y));
231     return true;
232 }
233
234 double ewk_view_scale_get(const Evas_Object* ewkView)
235 {
236     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, -1);
237
238     return WKPageGetScaleFactor(impl->wkPage());
239 }
240
241 Eina_Bool ewk_view_device_pixel_ratio_set(Evas_Object* ewkView, float ratio)
242 {
243     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
244
245     impl->setDeviceScaleFactor(ratio);
246
247     return true;
248 }
249
250 float ewk_view_device_pixel_ratio_get(const Evas_Object* ewkView)
251 {
252     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, -1.0);
253
254     return WKPageGetBackingScaleFactor(impl->wkPage());
255 }
256
257 void ewk_view_theme_set(Evas_Object* ewkView, const char* path)
258 {
259     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl);
260
261     impl->setThemePath(path);
262 }
263
264 const char* ewk_view_theme_get(const Evas_Object* ewkView)
265 {
266     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, nullptr);
267
268     return impl->themePath();
269 }
270
271 Eina_Bool ewk_view_back(Evas_Object* ewkView)
272 {
273     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
274
275     WKPageRef page = impl->wkPage();
276     if (WKPageCanGoBack(page)) {
277         WKPageGoBack(page);
278         return true;
279     }
280
281     return false;
282 }
283
284 Eina_Bool ewk_view_forward(Evas_Object* ewkView)
285 {
286     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
287
288     WKPageRef page = impl->wkPage();
289     if (WKPageCanGoForward(page)) {
290         WKPageGoForward(page);
291         return true;
292     }
293
294     return false;
295 }
296
297 Eina_Bool ewk_view_back_possible(Evas_Object* ewkView)
298 {
299     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
300     return WKPageCanGoBack(impl->wkPage());
301 }
302
303 Eina_Bool ewk_view_forward_possible(Evas_Object* ewkView)
304 {
305     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
306     return WKPageCanGoForward(impl->wkPage());
307 }
308
309 Ewk_Back_Forward_List* ewk_view_back_forward_list_get(const Evas_Object* ewkView)
310 {
311     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, nullptr);
312
313     return impl->backForwardList();
314 }
315
316 Eina_Bool ewk_view_navigate_to(Evas_Object* ewkView, const Ewk_Back_Forward_List_Item* item)
317 {
318     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
319     EWK_OBJ_GET_IMPL_OR_RETURN(const EwkBackForwardListItem, item, itemImpl, false);
320
321     WKPageGoToBackForwardListItem(impl->wkPage(), itemImpl->wkItem());
322
323     return true;
324 }
325
326 Eina_Bool ewk_view_html_string_load(Evas_Object* ewkView, const char* html, const char* baseUrl, const char* unreachableUrl)
327 {
328     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
329     EINA_SAFETY_ON_NULL_RETURN_VAL(html, false);
330
331     WKRetainPtr<WKStringRef> wkHTMLString = adoptWK(WKStringCreateWithUTF8CString(html));
332     WKRetainPtr<WKURLRef> wkBaseURL = adoptWK(WKURLCreateWithUTF8CString(baseUrl));
333
334     if (unreachableUrl && *unreachableUrl) {
335         WKRetainPtr<WKURLRef> wkUnreachableURL = adoptWK(WKURLCreateWithUTF8CString(unreachableUrl));
336         WKPageLoadAlternateHTMLString(impl->wkPage(), wkHTMLString.get(), wkBaseURL.get(), wkUnreachableURL.get());
337     } else
338         WKPageLoadHTMLString(impl->wkPage(), wkHTMLString.get(), wkBaseURL.get());
339
340     impl->informURLChange();
341
342     return true;
343 }
344
345 const char* ewk_view_custom_encoding_get(const Evas_Object* ewkView)
346 {
347     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, nullptr);
348
349     return impl->customTextEncodingName();
350 }
351
352 Eina_Bool ewk_view_custom_encoding_set(Evas_Object* ewkView, const char* encoding)
353 {
354     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
355
356     impl->setCustomTextEncodingName(encoding);
357
358     return true;
359 }
360
361 const char* ewk_view_user_agent_get(const Evas_Object* ewkView)
362 {
363     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, nullptr);
364
365     return impl->userAgent();
366 }
367
368 Eina_Bool ewk_view_user_agent_set(Evas_Object* ewkView, const char* userAgent)
369 {
370     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
371
372     impl->setUserAgent(userAgent);
373
374     return true;
375 }
376
377 inline WKFindOptions toWKFindOptions(Ewk_Find_Options options)
378 {
379     unsigned wkFindOptions = 0;
380
381     if (options & EWK_FIND_OPTIONS_CASE_INSENSITIVE)
382         wkFindOptions |= kWKFindOptionsCaseInsensitive;
383     if (options & EWK_FIND_OPTIONS_AT_WORD_STARTS)
384         wkFindOptions |= kWKFindOptionsAtWordStarts;
385     if (options & EWK_FIND_OPTIONS_TREAT_MEDIAL_CAPITAL_AS_WORD_START)
386         wkFindOptions |= kWKFindOptionsTreatMedialCapitalAsWordStart;
387     if (options & EWK_FIND_OPTIONS_BACKWARDS)
388         wkFindOptions |= kWKFindOptionsBackwards;
389     if (options & EWK_FIND_OPTIONS_WRAP_AROUND)
390         wkFindOptions |= kWKFindOptionsWrapAround;
391     if (options & EWK_FIND_OPTIONS_SHOW_OVERLAY)
392         wkFindOptions |= kWKFindOptionsShowOverlay;
393     if (options & EWK_FIND_OPTIONS_SHOW_FIND_INDICATOR)
394         wkFindOptions |= kWKFindOptionsShowFindIndicator;
395     if (options & EWK_FIND_OPTIONS_SHOW_HIGHLIGHT)
396         wkFindOptions |= kWKFindOptionsShowHighlight;
397
398     return static_cast<WKFindOptions>(wkFindOptions);
399 }
400
401 Eina_Bool ewk_view_text_find(Evas_Object* ewkView, const char* text, Ewk_Find_Options options, unsigned maxMatchCount)
402 {
403     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
404     EINA_SAFETY_ON_NULL_RETURN_VAL(text, false);
405
406     WKRetainPtr<WKStringRef> wkText = adoptWK(WKStringCreateWithUTF8CString(text));
407     WKPageFindString(impl->wkPage(), wkText.get(), toWKFindOptions(options), maxMatchCount);
408
409     return true;
410 }
411
412 Eina_Bool ewk_view_text_find_highlight_clear(Evas_Object* ewkView)
413 {
414     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
415
416     WKPageHideFindUI(impl->wkPage());
417
418     return true;
419 }
420
421 Eina_Bool ewk_view_text_matches_count(Evas_Object* ewkView, const char* text, Ewk_Find_Options options, unsigned maxMatchCount)
422 {
423     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
424     EINA_SAFETY_ON_NULL_RETURN_VAL(text, false);
425
426     WKRetainPtr<WKStringRef> wkText = adoptWK(WKStringCreateWithUTF8CString(text));
427     WKPageCountStringMatches(impl->wkPage(), wkText.get(), static_cast<WebKit::FindOptions>(options), maxMatchCount);
428
429     return true;
430 }
431
432 Eina_Bool ewk_view_mouse_events_enabled_set(Evas_Object* ewkView, Eina_Bool enabled)
433 {
434     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
435
436     impl->setMouseEventsEnabled(!!enabled);
437
438     return true;
439 }
440
441 Eina_Bool ewk_view_mouse_events_enabled_get(const Evas_Object* ewkView)
442 {
443     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
444
445     return impl->mouseEventsEnabled();
446 }
447
448 Eina_Bool ewk_view_feed_touch_event(Evas_Object* ewkView, Ewk_Touch_Event_Type type, const Eina_List* points, const Evas_Modifier* modifiers)
449 {
450 #if ENABLE(TOUCH_EVENTS)
451     EINA_SAFETY_ON_NULL_RETURN_VAL(points, false);
452     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
453
454     impl->feedTouchEvent(type, points, modifiers);
455
456     return true;
457 #else
458     UNUSED_PARAM(ewkView);
459     UNUSED_PARAM(type);
460     UNUSED_PARAM(points);
461     UNUSED_PARAM(modifiers);
462     return false;
463 #endif
464 }
465
466 Eina_Bool ewk_view_touch_events_enabled_set(Evas_Object* ewkView, Eina_Bool enabled)
467 {
468 #if ENABLE(TOUCH_EVENTS)
469     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
470
471     impl->setTouchEventsEnabled(!!enabled);
472
473     return true;
474 #else
475     UNUSED_PARAM(ewkView);
476     UNUSED_PARAM(enabled);
477     return false;
478 #endif
479 }
480
481 Eina_Bool ewk_view_touch_events_enabled_get(const Evas_Object* ewkView)
482 {
483 #if ENABLE(TOUCH_EVENTS)
484     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
485
486     return impl->touchEventsEnabled();
487 #else
488     UNUSED_PARAM(ewkView);
489     return false;
490 #endif
491 }
492
493 Eina_Bool ewk_view_inspector_show(Evas_Object* ewkView)
494 {
495 #if ENABLE(INSPECTOR)
496     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
497
498     WKInspectorRef wkInspector = WKPageGetInspector(impl->wkPage());
499     if (wkInspector)
500         WKInspectorShow(wkInspector);
501
502     return true;
503 #else
504     UNUSED_PARAM(ewkView);
505     return false;
506 #endif
507 }
508
509 Eina_Bool ewk_view_inspector_close(Evas_Object* ewkView)
510 {
511 #if ENABLE(INSPECTOR)
512     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
513
514     WKInspectorRef wkInspector = WKPageGetInspector(impl->wkPage());
515     if (wkInspector)
516         WKInspectorClose(wkInspector);
517
518     return true;
519 #else
520     UNUSED_PARAM(ewkView);
521     return false;
522 #endif
523 }
524
525 inline WKPaginationMode toWKPaginationMode(Ewk_Pagination_Mode mode)
526 {
527     switch (mode) {
528     case EWK_PAGINATION_MODE_INVALID:
529         break;
530     case EWK_PAGINATION_MODE_UNPAGINATED:
531         return kWKPaginationModeUnpaginated;
532     case EWK_PAGINATION_MODE_LEFT_TO_RIGHT:
533         return kWKPaginationModeLeftToRight;
534     case EWK_PAGINATION_MODE_RIGHT_TO_LEFT:
535         return kWKPaginationModeRightToLeft;
536     case EWK_PAGINATION_MODE_TOP_TO_BOTTOM:
537         return kWKPaginationModeTopToBottom;
538     case EWK_PAGINATION_MODE_BOTTOM_TO_TOP:
539         return kWKPaginationModeBottomToTop;
540     }
541     ASSERT_NOT_REACHED();
542
543     return kWKPaginationModeUnpaginated;
544 }
545
546 inline Ewk_Pagination_Mode toEwkPaginationMode(WKPaginationMode mode)
547 {
548     switch (mode) {
549     case kWKPaginationModeUnpaginated:
550         return EWK_PAGINATION_MODE_UNPAGINATED;
551     case kWKPaginationModeLeftToRight:
552         return EWK_PAGINATION_MODE_LEFT_TO_RIGHT;
553     case kWKPaginationModeRightToLeft:
554         return EWK_PAGINATION_MODE_RIGHT_TO_LEFT;
555     case kWKPaginationModeTopToBottom:
556         return EWK_PAGINATION_MODE_TOP_TO_BOTTOM;
557     case kWKPaginationModeBottomToTop:
558         return EWK_PAGINATION_MODE_BOTTOM_TO_TOP;
559     }
560     ASSERT_NOT_REACHED();
561
562     return EWK_PAGINATION_MODE_UNPAGINATED;
563 }
564
565 Eina_Bool ewk_view_pagination_mode_set(Evas_Object* ewkView, Ewk_Pagination_Mode mode)
566 {
567     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
568
569     WKPageSetPaginationMode(impl->wkPage(), toWKPaginationMode(mode));
570
571     return true;
572 }
573
574 Ewk_Pagination_Mode ewk_view_pagination_mode_get(const Evas_Object* ewkView)
575 {
576     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, EWK_PAGINATION_MODE_INVALID);
577     
578     return toEwkPaginationMode(WKPageGetPaginationMode(impl->wkPage()));
579 }
580
581 Eina_Bool ewk_view_fullscreen_exit(Evas_Object* ewkView)
582 {
583 #if ENABLE(FULLSCREEN_API)
584     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
585
586     return WKViewExitFullScreen(impl->wkView());
587 #else
588     UNUSED_PARAM(ewkView);
589     return false;
590 #endif
591 }
592
593 /// Creates a type name for Ewk_Page_Contents_Context.
594 typedef struct Ewk_Page_Contents_Context Ewk_Page_Contents_Context;
595
596 /*
597  * @brief Structure containing page contents context used for ewk_view_page_contents_get() API.
598  */
599 struct Ewk_Page_Contents_Context {
600     Ewk_Page_Contents_Type type;
601     Ewk_Page_Contents_Cb callback;
602     void* userData;
603 };
604
605 /**
606  * @internal
607  * Callback function used for ewk_view_page_contents_get().
608  */
609 static void ewkViewPageContentsAsMHTMLCallback(WKDataRef wkData, WKErrorRef, void* context)
610 {
611     EINA_SAFETY_ON_NULL_RETURN(context);
612
613     auto contentsContext = std::unique_ptr<Ewk_Page_Contents_Context>(static_cast<Ewk_Page_Contents_Context*>(context));
614     contentsContext->callback(contentsContext->type, reinterpret_cast<const char*>(WKDataGetBytes(wkData)), contentsContext->userData);
615 }
616
617 /**
618  * @internal
619  * Callback function used for ewk_view_page_contents_get().
620  */
621 static void ewkViewPageContentsAsStringCallback(WKStringRef wkString, WKErrorRef, void* context)
622 {
623     EINA_SAFETY_ON_NULL_RETURN(context);
624
625     auto contentsContext = std::unique_ptr<Ewk_Page_Contents_Context>(static_cast<Ewk_Page_Contents_Context*>(context));
626     contentsContext->callback(contentsContext->type, WKEinaSharedString(wkString), contentsContext->userData);
627 }
628
629 Eina_Bool ewk_view_page_contents_get(const Evas_Object* ewkView, Ewk_Page_Contents_Type type, Ewk_Page_Contents_Cb callback, void* user_data)
630 {
631     EINA_SAFETY_ON_NULL_RETURN_VAL(callback, false);
632     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
633
634     Ewk_Page_Contents_Context* context = new Ewk_Page_Contents_Context;
635     context->type = type;
636     context->callback = callback;
637     context->userData = user_data;
638
639     switch (context->type) {
640     case EWK_PAGE_CONTENTS_TYPE_MHTML:
641         WKPageGetContentsAsMHTMLData(impl->wkPage(), false, context, ewkViewPageContentsAsMHTMLCallback);
642         break;
643     case EWK_PAGE_CONTENTS_TYPE_STRING:
644         WKPageGetContentsAsString(impl->wkPage(), context, ewkViewPageContentsAsStringCallback);
645         break;
646     default:
647         delete context;
648         ASSERT_NOT_REACHED();
649         return false;
650     }
651
652     return true;
653 }
654
655 struct Ewk_View_Script_Execute_Callback_Context {
656     Ewk_View_Script_Execute_Callback_Context(Ewk_View_Script_Execute_Cb callback, Evas_Object* ewkView, void* userData)
657         : m_callback(callback)
658         , m_view(ewkView)
659         , m_userData(userData)
660     {
661     }
662
663     Ewk_View_Script_Execute_Cb m_callback;
664     Evas_Object* m_view;
665     void* m_userData;
666 };
667
668 static void runJavaScriptCallback(WKSerializedScriptValueRef scriptValue, WKErrorRef, void* context)
669 {
670     ASSERT(context);
671
672     auto callbackContext = std::unique_ptr<Ewk_View_Script_Execute_Callback_Context>(static_cast<Ewk_View_Script_Execute_Callback_Context*>(context));
673     ASSERT(callbackContext->m_view);
674
675     if (!callbackContext->m_callback)
676         return;
677
678     if (scriptValue) {
679         EWK_VIEW_IMPL_GET_OR_RETURN(callbackContext->m_view, impl);
680         JSGlobalContextRef jsGlobalContext = impl->ewkContext()->jsGlobalContext();
681
682         JSValueRef value = WKSerializedScriptValueDeserialize(scriptValue, jsGlobalContext, 0);
683         JSRetainPtr<JSStringRef> jsStringValue(Adopt, JSValueToStringCopy(jsGlobalContext, value, 0));
684         size_t length = JSStringGetMaximumUTF8CStringSize(jsStringValue.get());
685         auto buffer = std::make_unique<char[]>(length);
686         JSStringGetUTF8CString(jsStringValue.get(), buffer.get(), length);
687         callbackContext->m_callback(callbackContext->m_view, buffer.get(), callbackContext->m_userData);
688     } else
689         callbackContext->m_callback(callbackContext->m_view, 0, callbackContext->m_userData);
690 }
691
692 Eina_Bool ewk_view_script_execute(Evas_Object* ewkView, const char* script, Ewk_View_Script_Execute_Cb callback, void* userData)
693 {
694     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
695     EINA_SAFETY_ON_NULL_RETURN_VAL(script, false);
696
697     Ewk_View_Script_Execute_Callback_Context* context = new Ewk_View_Script_Execute_Callback_Context(callback, ewkView, userData);
698     WKRetainPtr<WKStringRef> scriptString(AdoptWK, WKStringCreateWithUTF8CString(script));
699     WKPageRunJavaScriptInMainFrame(impl->wkPage(), scriptString.get(), context, runJavaScriptCallback);
700     return true;
701 }
702
703 Eina_Bool ewk_view_layout_fixed_set(Evas_Object* ewkView, Eina_Bool enabled)
704 {
705     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
706
707     WKPageSetUseFixedLayout(WKViewGetPage(impl->wkView()), enabled);
708
709     return true;
710 }
711
712 Eina_Bool ewk_view_layout_fixed_get(const Evas_Object* ewkView)
713 {
714     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl, false);
715
716     return WKPageUseFixedLayout(WKViewGetPage(impl->wkView()));
717 }
718
719 void ewk_view_bg_color_set(Evas_Object* ewkView, int red, int green, int blue, int alpha)
720 {
721     if (EINA_UNLIKELY(alpha < 0 || alpha > 255)) {
722         EINA_LOG_CRIT("Alpha should be between 0 and 255");
723         return;
724     }
725
726     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl);
727
728     if (red == 255 && green == 255 && blue == 255 && alpha == 255)
729         WKViewSetDrawsBackground(impl->wkView(), true);
730     else
731         WKViewSetDrawsBackground(impl->wkView(), false);
732
733     WKViewSetBackgroundColor(impl->wkView(), red, green, blue, alpha);
734 }
735
736 void ewk_view_bg_color_get(const Evas_Object* ewkView, int* red, int* green, int* blue, int* alpha)
737 {
738     EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl);
739
740     WKViewGetBackgroundColor(impl->wkView(), red, green, blue, alpha);
741 }