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