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