Popup removal
[platform/framework/web/wrt.git] / src / view / webkit / view_logic.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16 /**
17  * @file    view_logic.cpp
18  * @author  Pawel Sikorski (p.sikorsk@samsung.com)
19  * @author  Lukasz Wrzosek (l.wrzosek@samsung.com)
20  * @author  Yunchan Cho (yunchan.cho@samsung.com)
21  * @brief   View logic for Webkit2
22  */
23 #include "view_logic.h"
24
25 #include <cstring>
26 #include <string>
27 #include <dpl/assert.h>
28 #include <dpl/log/log.h>
29 #include <dpl/optional.h>
30 #include <dpl/string.h>
31
32 #include <appcore-common.h>
33 #include <pcrecpp.h>
34 #include <vconf.h>
35 #include <widget_model.h>
36 #include <dpl/wrt-dao-ro/widget_dao_read_only.h>
37 #include <wrt-commons/custom-handler-dao-ro/CustomHandlerDatabase.h>
38 #include <wrt-commons/custom-handler-dao-rw/custom_handler_dao.h>
39
40 #include <common/application_data.h>
41 #include <common/application_launcher.h>
42 #include <common/scheme.h>
43
44 #include <common/view_logic_apps_support.h>
45 #include <common/view_logic_custom_header_support.h>
46 #include <common/view_logic_password_support.h>
47 #include <common/view_logic_security_support.h>
48 #include <common/view_logic_security_origin_support.h>
49 #include <common/view_logic_storage_support.h>
50 #include <common/view_logic_uri_support.h>
51 #include <common/view_logic_user_agent_support.h>
52 #include <common/view_logic_vibration_support.h>
53 #include <common/view_logic_web_notification_support.h>
54 #include <view_logic_scheme_support.h>
55 #include <view_logic_filesystem_support.h>
56 #include <view_logic_geolocation_support_webkit2.h>
57 #include <view_logic_web_storage_support.h>
58 #include "bundles/plugin_module_support.h"
59 #include <popup-runner/PopupInvoker.h>
60
61 #include <EWebKit2.h>
62 #include <js_overlay_types.h>
63 #include <i_runnable_widget_object.h>
64 #include <profiling_util.h>
65
66 namespace {
67 const char * const bundlePath = "/usr/lib/wrt-wk2-bundles/libwrt-wk2-bundle.so";
68 const char * const uriBlockedMessageName = "uri_block_msg";
69 const char * const uriChangedMessageName = "uri_changed_msg";
70 const char * const URICHANGE_PLUGIN_STOP_ONLY = "plugin_stop_only";
71 const char * const URICHANGE_PLUGIN_RESTART = "plugin_restart";
72 const char * const URICHANGE_PLUGIN_NO_CHANGE = "plugin_no_change";
73 const char * const URICHANGE_BLOCKED_URL = "null";
74 const char* PATTERN_URI_CHANGE = "^(([^:/\\?#]+)://[^\\?#]*)";
75 const int MAX_NUM_CONTEXT_MENU_ITEMS = 10;
76 // IME State value
77 const char * const IME_STATE_ON = "on";
78 const char * const IME_STATE_OFF = "off";
79
80 // WKPageLoaderClient
81 const char * const EWK_LOAD_STARTED = "load,started";
82 const char * const EWK_LOAD_FINISHED = "load,finished";
83 const char * const EWK_TITLE_CHANGED = "title,changed";
84 const char * const EWK_LOAD_PROGRESS = "load,progress";
85 const char * const EWK_LOAD_PROGRESS_FINISHED = "load,progress,finished";
86 const char * const EWK_PROCESS_CRASHED = "process,crashed";
87 // WKPageUIClient
88 const char * const EWK_CREATE_WINDOW = "create,window";
89 const char * const EWK_CLOSE_WINDOW = "close,window";
90 // WKPagePolicyClient
91 const char * const EWK_POLICY_NAVIGATION_DECIDE = "policy,navigation,decide";
92 const char * const EWK_POLICY_NEWWINDOW_DECIDE = "policy,newwindow,decide";
93 const char * const EWK_POLICY_RESPONSE_DECIDE = "policy,response,decide";
94 // WKPageContextMenuClient
95 const char * const EWK_CONTEXTMENU_CUSTOMIZE = "contextmenu,customize";
96 // WKPageFormClient
97 const char * const EWK_FORM_SUBMIT = "form,submit";
98 // EWK Geolocation Callback
99 const char * const EWK_REQUEST_GEOLOCATION_PERMISSION =
100     "request,geolocation,permission";
101 // EWK Notification Callback
102 const char * const EWK_NOTIFICATION_SHOW = "notification,show";
103 const char * const EWK_NOTIFICATION_CANCEL = "notification,cancel";
104 const char * const EWK_NOTIFICATION_PERMISSION_REQUEST =
105     "notification,permission,request";
106 // EWK Vibration Callback
107 const char * const EWK_VIBRATION_VIBRATE = "vibration,vibrate";
108 const char * const EWK_VIBRATION_CANCEL = "vibration,cancel";
109
110 const char * const EWK_CONTEXT_EXCEEDED_QUOATA  = "database,quota,exceeded";
111 const char * const EWK_FILESYSTEM_PERMISSION_REQUEST = "filesystem,permission,request";
112 const char * const EWK_FULLSCREEN_ENTER = "fullscreen,enterfullscreen";
113 const char * const EWK_FULLSCREEN_EXIT = "fullscreen,exitfullscreen";
114
115 // IME Callback
116 const char * const EWK_INPUTMETHOD_CHANGED = "inputmethod,changed";
117 const char * const EWK_EDITORCLIENT_IME_CLOSED = "editorclient,ime,closed";
118
119 // Custom handlers
120 const char * const EWK_PROTOCOLHANDLER_REGISTRATION = "protocolhandler,registration,requested";
121 const char * const EWK_PROTOCOLHANDLER_ISREGISTERED = "protocolhandler,isregistered";
122 const char * const EWK_PROTOCOLHANDLER_UNREGISTRATION = "protocolhandler,unregistration,requested";
123 const char * const EWK_CONTENTHANDLER_REGISTRATION = "contenthandler,registration,requested";
124 const char * const EWK_CONTENTHANDLER_ISREGISTERED = "contenthandler,isregistered";
125 const char * const EWK_CONTENTHANDLER_UNREGISTRATION = "contenthandler,unregistration,requested";
126
127 const char PROTOCOL_HANDLER_ASK_MSG[] = "Add protocol?";
128 const char PROTOCOL_HANDLER_ASK_TITLE[] = "Add protocol";
129 const char CONTENT_HANDLER_ASK_MSG[] = "Add content?";
130 const char CONTENT_HANDLER_ASK_TITLE[] = "Add content";
131 }
132
133 ViewLogic::ViewLogic():
134     m_ewkContext(0),
135     m_currentEwkView(0),
136     m_window(NULL),
137     m_model(0),
138     m_cbs(new WRT::UserDelegates),
139     m_appsSupport(new ViewModule::AppsSupport()),
140     m_vibrationSupport(NULL),
141     m_attachedToCustomHandlerDao(false)
142 {
143 }
144
145 ViewLogic::~ViewLogic ()
146 {
147     detachFromCustomHandlersDao();
148 }
149
150 void ViewLogic::createWebView(Ewk_Context* context,
151                               Evas_Object* window)
152 {
153     LogDebug("");
154     initializeEwkContext(context);
155     Assert(NULL != m_ewkContext);
156     Assert(window);
157     m_window = window;
158     createEwkView(evas_object_evas_get(m_window));
159 }
160
161 void ViewLogic::destroyWebView()
162 {
163     if (m_ewkContext) {
164         finalizeEwkContext();
165     }
166 }
167
168 void ViewLogic::initialize()
169 {
170     LogDebug("Initializing");
171     ApplicationLauncherSingleton::Instance().Touch();
172     appcore_set_event_callback(
173         APPCORE_EVENT_LOW_MEMORY,
174         &appcoreLowMemoryCallback,
175         this);
176 }
177
178 void ViewLogic::terminate()
179 {
180     LogDebug("terminating view logic");
181     if (m_model) {
182         hideWidget();
183     } else {
184         LogError("Widget model not created");
185     }
186     LogDebug("done");
187 }
188
189 void ViewLogic::prepareView(WidgetModel* m, const std::string &startUrl)
190 {
191     LogDebug("View prepare");
192
193     Assert(m);
194     m_model = m;
195     m_startUrl = ViewModule::UriSupport::getUri(m_model, startUrl);
196     Assert(NULL != m_ewkContext);
197     Assert(m_window);
198
199     ADD_PROFILING_POINT("initializeSupport", "start");
200     initializeSupport();
201     ADD_PROFILING_POINT("initializeSupport", "stop");
202     setStartPage();
203     ewkClientInit(m_currentEwkView);
204     ADD_PROFILING_POINT("prepareEwkView", "start");
205     prepareEwkView(m_currentEwkView);
206     ADD_PROFILING_POINT("prepareEwkView", "stop");
207     initializePluginLoading();
208 }
209
210 void ViewLogic::showWidget()
211 {
212     LogDebug("showing widget");
213     Assert(NULL != m_currentEwkView && "ewk_view not created at this point");
214     if (m_currentUri.empty()) {
215         LogError("Localized current URI doesn't exist");
216         return;
217     }
218
219     LogInfo("m_currentUri: " << m_currentUri);
220
221     // load page
222     ewk_view_url_set(m_currentEwkView, m_currentUri.c_str());
223
224     if (!m_cbs->bufferSet.empty()) {
225         m_cbs->bufferSet(m_currentEwkView);
226     }
227 }
228
229 void ViewLogic::hideWidget()
230 {
231     LogDebug("hiding widget");
232     ViewModule::StorageSupport::deinitializeStorage(m_model);
233     m_appsSupport->deinitialize();
234
235     // temp
236     // m_vibrationSupport->deinitialize();
237
238     while (m_ewkViewList.size()) {
239         LogInfo("pop webview: " << m_ewkViewList.back());
240         removeEwkView(m_ewkViewList.back());
241     }
242     m_ewkViewList.clear();
243 }
244
245 void ViewLogic::suspendWidget()
246 {
247     LogInfo("Pausing widget");
248     Assert(m_model);
249
250     LogDebug("Request bundle to suspend");
251     PluginModuleSupport::suspend(m_ewkContext);
252
253     if (!m_currentEwkView) {
254         LogWarning("Cannot suspend widget without view");
255     } else {
256         suspendWebkit(m_currentEwkView);
257     }
258
259     evas_object_focus_set(m_currentEwkView, EINA_FALSE);
260
261     // call user callback
262     if (!m_cbs->suspend.empty()) {
263         m_cbs->suspend(true);
264     }
265 };
266
267 void ViewLogic::resumeWidget()
268 {
269     LogInfo("Resume widget");
270     Assert(m_model);
271
272     LogDebug("Request bundle to resume");
273     PluginModuleSupport::resume(m_ewkContext);
274
275     if (m_currentEwkView) {
276         resumeWebkit(m_currentEwkView);
277     }
278
279     if (m_window) {
280         elm_win_raise(m_window);
281     }
282     evas_object_focus_set(m_currentEwkView, EINA_TRUE);
283
284     // call user callback
285     if (!m_cbs->resume.empty()) {
286         m_cbs->resume(true);
287     }
288 };
289
290 void ViewLogic::resetWidget()
291 {
292     LogInfo("Resetting Widget");
293
294     // check if already created webview exists
295     if (!m_ewkViewList.size()) {
296         // create new webview
297         createEwkView(evas_object_evas_get(m_window));
298         setStartPage();
299         ewkClientInit(m_currentEwkView);
300         prepareEwkView(m_currentEwkView);
301     } else {
302         // check if current url is service url for this tizen service
303         std::string requestedUri =
304                 ViewModule::UriSupport::getUri(m_model, m_startUrl);
305         DPL::OptionalString servicedUri = ViewModule::UriSupport::localizeURI(
306                 DPL::FromUTF8String(requestedUri.c_str()),
307                 m_model);
308
309         const char* currentUri = ewk_view_uri_get(m_currentEwkView);
310         if (!currentUri && 0 == strlen(currentUri)) {
311             LogError("Fail to get uri from ewk_view_uri_get");
312             return;
313         }
314
315         // webview activated
316         PluginModuleSupport::resume(m_ewkContext);
317         resumeWebkit(m_currentEwkView);
318         if (DPL::ToUTF8String(*servicedUri) == currentUri) {
319             LogInfo("current page is raised");
320             // set only encoded bundle
321             double scale = elm_config_scale_get();
322             PluginModuleSupport::setCustomProperties(
323                 m_ewkContext,
324                 &scale,
325                 ApplicationDataSingleton::Instance().getEncodedBundle());
326             PluginModuleSupport::dispatchJavaScriptEvent(
327                 m_ewkContext,
328                 WrtPlugins::W3C::ServiceCustomEvent,
329                 NULL);
330         } else {
331             LogInfo("service page is loaded");
332             m_currentUri = DPL::ToUTF8String(*servicedUri);
333             ewk_view_url_set(m_currentEwkView, m_currentUri.c_str());
334         }
335         elm_win_raise(m_window);
336         evas_object_focus_set(m_currentEwkView, EINA_TRUE);
337     }
338
339     // call user callback
340     if (!m_cbs->reset.empty()) {
341         m_cbs->reset(true);
342     }
343     if (!m_cbs->bufferSet.empty()) {
344         m_cbs->bufferSet(m_currentEwkView);
345     }
346 }
347
348 void ViewLogic::backward()
349 {
350     if (ewk_view_back_possible(m_currentEwkView)) {
351         ewk_view_back(m_currentEwkView);
352     } else {
353         if (1 >= m_ewkViewList.size()) {
354             // If there is no previous page, widget move to backgroud.
355             LogInfo("Widget move to backgroud");
356             elm_win_lower(m_window);
357         } else {
358             // Back to previous webview
359             LogInfo("Widget move to previous webview");
360             ecore_idler_add(windowCloseIdlerCallback, this);
361         }
362     }
363 }
364
365 void ViewLogic::reload()
366 {
367     ewk_view_reload(m_currentEwkView);
368 }
369
370 void ViewLogic::forward()
371 {
372     if (ewk_view_forward_possible(m_currentEwkView)) {
373         ewk_view_forward(m_currentEwkView);
374     }
375 }
376
377 void ViewLogic::reloadStartPage()
378 {
379     LogInfo("Reload Start Page");
380
381     if (m_ewkViewList.size() == 0) {
382         // create new webview
383         createEwkView(evas_object_evas_get(m_window));
384         ewkClientInit(m_currentEwkView);
385     } else {
386         // close opened windows
387         while (m_ewkViewList.size() > 1) {
388             if (!m_cbs->bufferUnset.empty()) {
389                 m_cbs->bufferUnset(m_currentEwkView);
390             }
391             removeEwkView(m_currentEwkView);
392             m_currentEwkView = m_ewkViewList.back();
393         }
394         LogInfo("Close ewkViews done : m_ewkViewList.size() = "
395                 << m_ewkViewList.size());
396     }
397
398     setStartPage();
399     prepareEwkView(m_currentEwkView);
400     initializePluginLoading();
401
402     // load page
403     ewk_view_url_set(m_currentEwkView, m_currentUri.c_str());
404
405     // show ewkView
406     if (!m_cbs->bufferSet.empty()) {
407         m_cbs->bufferSet(m_currentEwkView);
408     }
409     LogInfo("Reloading Start Page is done!");
410 }
411
412 Evas_Object* ViewLogic::getCurrentWebview()
413 {
414     LogInfo("get current webview");
415     return m_currentEwkView;
416 }
417
418 void ViewLogic::fireJavascriptEvent(int event, void* data)
419 {
420     PluginModuleSupport::dispatchJavaScriptEvent(
421         m_ewkContext,
422         static_cast<WrtPlugins::W3C::CustomEventType>(event),
423         data);
424 }
425
426 void ViewLogic::setUserCallbacks(const WRT::UserDelegatesPtr& cbs)
427 {
428     m_cbs = cbs;
429 }
430
431 void ViewLogic::initializeEwkContext(Ewk_Context* newEwkContext)
432 {
433     LogInfo("initializeEwkContext called");
434     Assert(newEwkContext && "Ewk_Context provided can not be null");
435     // bundle callback setting
436     ewk_context_message_from_injected_bundle_callback_set(
437         newEwkContext,
438         contextMessageFromInjectedBundleCallback,
439         static_cast<void*>(this));
440
441     // proxy server setting
442     char *proxyAddress = vconf_get_str(VCONFKEY_NETWORK_PROXY);
443     if ((!proxyAddress) || (strlen(proxyAddress) == 0)
444         || (strstr(proxyAddress, "0.0.0.0")))
445     {
446         LogInfo("proxy address is empty");
447         ewk_context_proxy_uri_set(newEwkContext, NULL);
448     } else {
449         LogInfo("proxy address [" << proxyAddress << "]");
450         ewk_context_proxy_uri_set(newEwkContext,  proxyAddress);
451     }
452
453     if (proxyAddress) {
454         free(proxyAddress);
455         proxyAddress = NULL;
456     }
457
458     // theme setting
459     const char *theme = elm_theme_get(NULL);
460     if (theme) {
461         m_theme = theme;
462         LogInfo("theme is " << m_theme);
463     }
464
465     // Ewk download callback (WKContextDownloadClient)
466     ewk_context_did_start_download_callback_set(
467         newEwkContext,
468         didStartDownloadCallback,
469         this);
470
471     // set to member value
472     m_ewkContext = newEwkContext;
473 }
474
475 void ViewLogic::finalizeEwkContext()
476 {
477     LogInfo("finalizeEwkContext called");
478     ewk_context_message_from_injected_bundle_callback_set(
479             m_ewkContext,
480             NULL,
481             NULL);
482 //    ewk_context_delete(m_ewkContext);
483 //    m_ewkContext = 0;
484 }
485
486 void ViewLogic::initializeSupport()
487 {
488     // set local stroage database path
489     WrtDB::WidgetDAOReadOnly dao(m_model->TizenId);
490     ewk_context_web_storage_path_set(m_ewkContext,
491                                      dao.getPrivateLocalStoragePath().c_str());
492     m_schemeSupport.reset(new SchemeSupport(m_model->Type.Get().appType));
493     ViewModule::StorageSupport::initializeStorage(m_model);
494     m_appsSupport->initialize(m_model);
495     m_securityOriginSupport.reset(new ViewModule::SecurityOriginSupport(m_model));
496
497     // temp
498     // m_vibrationSupport->initialize();
499 }
500
501 void ViewLogic::initializePluginLoading()
502 {
503     // inform wrt information for plugin loading to web process
504     PluginModuleSupport::start(
505         m_ewkContext,
506         m_model->TizenId,
507         elm_config_scale_get(),
508         ApplicationDataSingleton::Instance().getEncodedBundle(),
509         m_theme.c_str(),
510         m_model->SettingList.Get().isEncrypted());
511 }
512
513 void ViewLogic::ewkClientInit(Evas_Object *wkView) {
514     Assert(NULL != wkView && "ewk_view not created at this point");
515     // WKPageLoaderClient
516     evas_object_smart_callback_add(
517         wkView,
518         EWK_LOAD_STARTED,
519         loadStartedCallback,
520         this);
521     evas_object_smart_callback_add(
522         wkView,
523         EWK_LOAD_FINISHED,
524         loadFinishedCallback,
525         this);
526     evas_object_smart_callback_add(
527         wkView,
528         EWK_TITLE_CHANGED,
529         titleChangedCallback,
530         this);
531     evas_object_smart_callback_add(
532         wkView,
533         EWK_LOAD_PROGRESS,
534         loadProgressCallback,
535         this);
536     evas_object_smart_callback_add(
537         wkView,
538         EWK_LOAD_PROGRESS_FINISHED,
539         loadProgressFinishedCallback,
540         this);
541     evas_object_smart_callback_add(
542         wkView,
543         EWK_PROCESS_CRASHED,
544         processCrashedCallback,
545         this);
546
547     // WKPageUIClient
548     evas_object_smart_callback_add(
549         wkView,
550         EWK_CREATE_WINDOW,
551         createWindowCallback,
552         this);
553     evas_object_smart_callback_add(
554         wkView,
555         EWK_CLOSE_WINDOW,
556         closeWindowCallback,
557         this);
558
559     // WKPagePolicyClient
560     evas_object_smart_callback_add(
561         wkView,
562         EWK_POLICY_NAVIGATION_DECIDE,
563         policyNavigationDecideCallback,
564         this);
565     evas_object_smart_callback_add(
566         wkView,
567         EWK_POLICY_NEWWINDOW_DECIDE,
568         policyNewWindowDecideCallback,
569         this);
570     evas_object_smart_callback_add(
571         wkView,
572         EWK_POLICY_RESPONSE_DECIDE,
573         pageResponseDecideCallback,
574         this);
575
576     // WKPageContextMenuClient
577     evas_object_smart_callback_add(
578         wkView,
579         EWK_CONTEXTMENU_CUSTOMIZE,
580         contextmenuCustomizeCallback,
581         this);
582
583     // WKPageFormClient
584     evas_object_smart_callback_add(
585         wkView,
586         EWK_FORM_SUBMIT,
587         formSubmitCallback,
588         this);
589
590     // EWK Geolocation Callback
591     evas_object_smart_callback_add(
592         wkView,
593         EWK_REQUEST_GEOLOCATION_PERMISSION,
594         geolocationPermissionRequestCallback,
595         this);
596
597     // EWK Notification Callback
598     evas_object_smart_callback_add(
599         wkView,
600         EWK_NOTIFICATION_SHOW,
601         notificationShowCallback,
602         this);
603     evas_object_smart_callback_add(
604         wkView,
605         EWK_NOTIFICATION_CANCEL,
606         notificationCancelCallback,
607         this);
608     evas_object_smart_callback_add(
609         wkView,
610         EWK_NOTIFICATION_PERMISSION_REQUEST,
611         notificationPermissionRequestCallback,
612         this);
613
614     // EWK Vibration Callback
615     evas_object_smart_callback_add(
616         wkView,
617         EWK_VIBRATION_VIBRATE,
618         vibrationVibrateCallback,
619         this);
620     evas_object_smart_callback_add(
621         wkView,
622         EWK_VIBRATION_CANCEL,
623         vibrationCancelCallback,
624         this);
625     evas_object_smart_callback_add(
626         wkView,
627         EWK_CONTEXT_EXCEEDED_QUOATA,
628         databaseUsagePermissionRequestCallback,
629         this);
630     evas_object_smart_callback_add(
631         wkView,
632         EWK_FILESYSTEM_PERMISSION_REQUEST,
633         fileSystemPermissionRequestCallback,
634         this);
635
636     // EWK Orientation Callback
637     ewk_view_orientation_lock_callback_set(
638         wkView,
639         orientationLockCallback,
640         this);
641
642     // Fullscreen API callbacks
643     evas_object_smart_callback_add(
644         wkView,
645         EWK_FULLSCREEN_ENTER,
646         enterFullscreenCallback,
647         this);
648     evas_object_smart_callback_add(
649         wkView,
650         EWK_FULLSCREEN_EXIT,
651         exitFullscreenCallback,
652         this);
653
654
655      // when ime start to be showed on the webview,
656      // this callback will be called
657     evas_object_smart_callback_add(
658         wkView,
659         EWK_INPUTMETHOD_CHANGED,
660         imeOpenCallback,
661         this);
662
663     // this callback will be called
664     //  when ime finishes to be showed on the webview
665     // "event_info" arg of this callback is always NULL point
666     // if web content should know size of ime,
667     //  use "inputmethod,changed" instead of this.
668     //
669     //evas_object_smart_callback_add(
670     //        wkView,
671     //        "editorclient,ime,opened",
672     //        imeSomethingCallback,
673     //        this);
674
675     // when ime finished to be hidden,
676     // this callback will be called
677     evas_object_smart_callback_add(
678         wkView,
679         EWK_EDITORCLIENT_IME_CLOSED,
680         imeCloseCallback,
681         this);
682
683     // custom content/scheme handlers
684     evas_object_smart_callback_add(
685         wkView,
686         EWK_PROTOCOLHANDLER_REGISTRATION,
687         protocolHandlerRegistrationCallback,
688         this);
689     evas_object_smart_callback_add(
690         wkView,
691         EWK_PROTOCOLHANDLER_ISREGISTERED,
692         protocolHandlerIsRegisteredCallback,
693         this);
694     evas_object_smart_callback_add(
695         wkView,
696         EWK_PROTOCOLHANDLER_UNREGISTRATION,
697         protocolHandlerUnregistrationCallback,
698         this);
699
700     evas_object_smart_callback_add(
701         wkView,
702         EWK_CONTENTHANDLER_REGISTRATION,
703         contentHandlerRegistrationCallback,
704         this);
705     evas_object_smart_callback_add(
706         wkView,
707         EWK_CONTENTHANDLER_ISREGISTERED,
708         contentHandlerIsRegisteredCallback,
709         this);
710     evas_object_smart_callback_add(
711         wkView,
712         EWK_CONTENTHANDLER_UNREGISTRATION,
713         contentHandlerUnregistrationCallback,
714         this);
715 }
716
717 void ViewLogic::ewkClientDeinit(Evas_Object *wkView) {
718     LogDebug("ewkClientDeinit");
719     Assert(NULL != wkView && "ewk_view not created at this point");
720
721     // WKPageLoaderClient
722     evas_object_smart_callback_del(
723         wkView,
724         EWK_LOAD_STARTED,
725         loadStartedCallback);
726     evas_object_smart_callback_del(
727         wkView,
728         EWK_LOAD_FINISHED,
729         loadFinishedCallback);
730     evas_object_smart_callback_del(
731         wkView,
732         EWK_TITLE_CHANGED,
733         titleChangedCallback);
734     evas_object_smart_callback_del(
735         wkView,
736         EWK_LOAD_PROGRESS,
737         loadProgressCallback);
738     evas_object_smart_callback_del(
739         wkView,
740         EWK_LOAD_PROGRESS_FINISHED,
741         loadProgressFinishedCallback);
742     evas_object_smart_callback_del(
743         wkView,
744         EWK_PROCESS_CRASHED,
745         loadProgressCallback);
746
747     // WKPageUIClient
748     evas_object_smart_callback_del(
749         wkView,
750         EWK_CREATE_WINDOW,
751         createWindowCallback);
752     evas_object_smart_callback_del(
753         wkView,
754         EWK_CLOSE_WINDOW,
755         closeWindowCallback);
756
757     // WKPagePolicyClient
758     evas_object_smart_callback_del(
759         wkView,
760         EWK_POLICY_NAVIGATION_DECIDE,
761         policyNavigationDecideCallback);
762     evas_object_smart_callback_del(
763         wkView,
764         EWK_POLICY_NEWWINDOW_DECIDE,
765         policyNewWindowDecideCallback);
766     evas_object_smart_callback_del(
767         wkView,
768         EWK_POLICY_RESPONSE_DECIDE,
769         pageResponseDecideCallback);
770
771     // WKPageContextMenuClient
772     evas_object_smart_callback_del(
773         wkView,
774         EWK_CONTEXTMENU_CUSTOMIZE,
775         contextmenuCustomizeCallback);
776
777     // WKPageFormClient
778     evas_object_smart_callback_del(
779         wkView,
780         EWK_FORM_SUBMIT,
781         formSubmitCallback);
782
783     // EWK Geolocation Callback
784     evas_object_smart_callback_del(
785         wkView,
786         EWK_REQUEST_GEOLOCATION_PERMISSION,
787         geolocationPermissionRequestCallback);
788
789     // EWK Notification Callback
790     evas_object_smart_callback_del(
791         wkView,
792         EWK_NOTIFICATION_SHOW,
793         notificationShowCallback);
794     evas_object_smart_callback_del(
795         wkView,
796         EWK_NOTIFICATION_CANCEL,
797         notificationCancelCallback);
798     evas_object_smart_callback_del(
799         wkView,
800         EWK_NOTIFICATION_PERMISSION_REQUEST,
801         notificationPermissionRequestCallback);
802
803     // EWK Vibration Callback
804     evas_object_smart_callback_del(
805         wkView,
806         EWK_VIBRATION_VIBRATE,
807         vibrationVibrateCallback);
808     evas_object_smart_callback_del(
809         wkView,
810         EWK_VIBRATION_CANCEL,
811         vibrationCancelCallback);
812
813     evas_object_smart_callback_del(
814         wkView,
815         EWK_CONTEXT_EXCEEDED_QUOATA,
816         databaseUsagePermissionRequestCallback);
817     evas_object_smart_callback_del(
818         wkView,
819         EWK_FILESYSTEM_PERMISSION_REQUEST,
820         fileSystemPermissionRequestCallback);
821
822     // EWK Orientation Callback
823     ewk_view_orientation_lock_callback_set(
824         wkView,
825         NULL,
826         NULL);
827
828     // ime show/hide callback
829     evas_object_smart_callback_del(
830         wkView,
831         EWK_INPUTMETHOD_CHANGED,
832         imeOpenCallback);
833     evas_object_smart_callback_del(
834         wkView,
835         EWK_EDITORCLIENT_IME_CLOSED,
836         imeCloseCallback);
837
838     // custom content/scheme handlers
839     evas_object_smart_callback_del(
840         wkView,
841         EWK_PROTOCOLHANDLER_REGISTRATION,
842         protocolHandlerRegistrationCallback);
843     evas_object_smart_callback_del(
844         wkView,
845         EWK_PROTOCOLHANDLER_ISREGISTERED,
846         protocolHandlerIsRegisteredCallback);
847     evas_object_smart_callback_del(
848         wkView,
849         EWK_PROTOCOLHANDLER_UNREGISTRATION,
850         protocolHandlerUnregistrationCallback);
851
852     evas_object_smart_callback_del(
853         wkView,
854         EWK_CONTENTHANDLER_REGISTRATION,
855         contentHandlerRegistrationCallback);
856     evas_object_smart_callback_del(
857         wkView,
858         EWK_CONTENTHANDLER_ISREGISTERED,
859         contentHandlerIsRegisteredCallback);
860     evas_object_smart_callback_del(
861         wkView,
862         EWK_CONTENTHANDLER_UNREGISTRATION,
863         contentHandlerUnregistrationCallback);
864 }
865
866 void ViewLogic::createEwkView(Evas* canvas)
867 {
868     LogDebug("createEwkVeiw");
869     Assert(canvas);
870     ADD_PROFILING_POINT("ewk_view_add_with_context", "start");
871     Evas_Object* newEwkView = ewk_view_add_with_context(
872         canvas,
873         m_ewkContext);
874     ADD_PROFILING_POINT("ewk_view_add_with_context", "stop");
875
876     if (!newEwkView) {
877         LogError("WKView creation failed");
878         Assert(false);
879     }
880
881     // set cookie policy
882     // even arguments pass the ewkContext, this API should be called
883     // after webkit Evas_Object is created
884     ewk_context_cookies_policy_set(m_ewkContext, EWK_COOKIE_JAR_ACCEPT_ALWAYS);
885
886     LogInfo("push webview: " << newEwkView);
887     m_ewkViewList.push_back(newEwkView);
888     m_currentEwkView = newEwkView;
889 }
890
891 void ViewLogic::setStartPage()
892 {
893     /* Start URI (as other uris) is now localized
894      * on WebProcess side */
895     m_currentUri = m_startUrl;
896 }
897
898 void ViewLogic::prepareEwkView(Evas_Object *wkView)
899 {
900     LogDebug("prepareEwkView called");
901     Assert(wkView);
902     Ewk_Settings* settings = ewk_view_settings_get(wkView);
903
904     // set user agent
905     auto userAgentString =
906         ViewModule::UserAgentSupport::getUserAgentFromVconf();
907     if (!userAgentString.empty()) {
908         LogDebug("Setting custom user agent as: " << userAgentString);
909         ewk_view_user_agent_set(wkView, userAgentString.c_str());
910     }
911
912     // set custom header : language
913     using namespace ViewModule::CustomHeaderSupport;
914     std::string customHeaderString = getValueByField(ACCEPT_LANGUAGE);
915     if (!customHeaderString.empty()) {
916         LogDebug("custom field=[" << ACCEPT_LANGUAGE << "]");
917         LogDebug("custom value=[" << customHeaderString << "]");
918         ewk_view_custom_header_add(wkView,
919                                    ACCEPT_LANGUAGE.c_str(),
920                                    customHeaderString.c_str());
921     }
922
923     // webkit NPAPI plugins is always on in wrt
924     ewk_settings_plugins_enabled_set(settings, EINA_TRUE);
925
926     // The followings are not implemeted yet by webkit2
927     //      ewk_view_setting_accelerated_compositing_enable_set(EINA_TRUE);
928     //      ewk_view_mode_set();
929     //      ewk_view_setting_enable_specified_plugin_set(EINA_TRUE, FLASH_MIME_TYPE);
930     //      ewk_view_setting_html5video_external_player_enable_set(EINA_FALSE);
931     //      ewk_view_show_ime_on_autofocus_set(EINA_TRUE);
932     //      elm_webview_show_magnifier_set(EINA_FALSE);
933     ewk_settings_javascript_enabled_set(settings, EINA_TRUE);
934     ewk_settings_loads_images_automatically_set(settings, EINA_TRUE);
935     ewk_settings_auto_fitting_set(settings, EINA_TRUE);
936
937     // disable zoom option when user click the input field
938     // this option is useful with the normal website
939     // for the make user friendly, disable auto zoom in the webapp
940     // The followings are not implemeted yet by webkit2
941     //      elm_webview_input_field_zoom_set(EINA_FALSE);
942
943     // set cookie database path
944     // The followings are not implemeted yet by webkit2
945     //      ewk_cookies_file_set(dao.getCookieDatabasePath().c_str()));
946
947     // set visibility to WebCore. This value will be used for html5.
948     // also, this value will be changed in the suspend, resume
949     // or create window, close window.
950     ewk_view_page_visibility_state_set(wkView,
951                                        EWK_PAGE_VISIBILITY_STATE_VISIBLE,
952                                        EINA_TRUE);
953 }
954
955 void ViewLogic::removeEwkView(Evas_Object *wkView)
956 {
957     LogInfo("removeEwkView called");
958     Assert(wkView);
959     Assert(0 != m_ewkViewList.size());
960
961     // unregister webview callbacks
962     ewkClientDeinit(wkView);
963
964     // suspend NPAPI plugin - Not implemented by Webkit2
965     //    ewk_view_pause_or_resume_plugins();
966     evas_object_del(wkView);
967     m_ewkViewList.remove(wkView);
968 }
969
970 void ViewLogic::resumeEwkView(Evas_Object *wkView)
971 {
972     LogInfo("resumeEwkView called");
973     Assert(wkView);
974
975     // register webview callback
976     ewkClientInit(wkView);
977
978     // resume webkit
979     resumeWebkit(wkView);
980
981     return;
982 }
983
984 void ViewLogic::suspendEwkView(Evas_Object *wkView)
985 {
986     LogInfo("suspendEwkView called");
987     Assert(wkView);
988
989     // suspend webkit
990     suspendWebkit(wkView);
991
992     // unregister webview callbacks
993     ewkClientDeinit(wkView);
994
995     return;
996 }
997
998 void ViewLogic::resumeWebkit(Evas_Object *wkView)
999 {
1000     LogDebug("resumeWebkit");
1001     Assert(wkView);
1002
1003     // resume NPAPI plugin
1004     // The followings are not implemeted yet by webkit2
1005     //      ewk_view_pause_or_resume_plugins(false);
1006     //      ewk_view_pause_or_resume_video_audio(false);
1007     //      ewk_view_javascript_resume();
1008     //      ewk_view_enable_render();
1009     //      ewk_view_reduce_plugins_frame_rate(false);
1010     ewk_view_resume(wkView);
1011     ewk_view_visibility_set(wkView, EINA_TRUE);
1012     ewk_view_page_visibility_state_set(wkView,
1013                                        EWK_PAGE_VISIBILITY_STATE_VISIBLE,
1014                                        EINA_FALSE);
1015     return;
1016 }
1017
1018 void ViewLogic::suspendWebkit(Evas_Object *wkView)
1019 {
1020     LogDebug("suspendWebkit");
1021     Assert(wkView);
1022
1023     // suspend the followings
1024     // The followings are not implemeted yet by webkit2
1025     //      ewk_view_pause_or_resume_plugins(true);
1026     //      ewk_view_pause_or_resume_video_audio(true);
1027
1028     // send visibility event to webpage
1029     ewk_view_page_visibility_state_set(wkView,
1030                                        EWK_PAGE_VISIBILITY_STATE_HIDDEN,
1031                                        EINA_FALSE);
1032     ewk_view_suspend(wkView);
1033     ewk_view_visibility_set(wkView, EINA_FALSE);
1034     return;
1035 }
1036
1037 void ViewLogic::contextMessageFromInjectedBundleCallback(
1038         const char* name,
1039         const char* body,
1040         char** returnData,
1041         void* clientInfo)
1042 {
1043     LogDebug("contextMessageFromInjectedBundleCallback called");
1044     Assert(clientInfo);
1045     ViewLogic* This = static_cast<ViewLogic*>(clientInfo);
1046     // didRecieveMessageFromInjectedBundleCallback - returnData is null
1047     // didReceiveSynchronousMessageCallback - returnData isn't null
1048     // WKContextInjectedBundleClient bundleClient = {
1049     //     kWKContextInjectedBundleClientCurrentVersion,
1050     //     static_cast<void*>(this),
1051     //     &didRecieveMessageFromInjectedBundleCallback,
1052     //     &didReceiveSynchronousMessageCallback
1053     // };
1054     if (NULL == returnData) {
1055         This->didRecieveMessageFromInjectedBundle(name, body);
1056     } else {
1057         This->didReceiveSynchronousMessage(name, body, returnData);
1058     }
1059 }
1060
1061 void ViewLogic::didStartDownloadCallback(
1062         const char* downloadUrl,
1063         void* data)
1064 {
1065     LogDebug("didStartDownloadCallback called");
1066     Assert(data);
1067     ViewLogic* This = static_cast<ViewLogic*>(data);
1068     Assert(downloadUrl);
1069     LogDebug("download url = " << downloadUrl);
1070     This->m_appsSupport->downloadRequest(
1071         downloadUrl,
1072         NULL,
1073         NULL);
1074 }
1075
1076 void ViewLogic::loadStartedCallback(
1077         void* data,
1078         Evas_Object* obj,
1079         void* /*eventInfo*/)
1080 {
1081     LogDebug("loadStartedCallback called");
1082     Assert(data);
1083     ViewLogic* This = static_cast<ViewLogic*>(data);
1084     evas_object_focus_set(This->m_currentEwkView, EINA_TRUE);
1085
1086     // call loadFinish callback to wrt-client
1087     if (!This->m_cbs->loadStart.empty()) {
1088         This->m_cbs->loadStart(obj);
1089     }
1090
1091 }
1092
1093 void ViewLogic::loadFinishedCallback(
1094         void* data,
1095         Evas_Object* obj,
1096         void* /*eventInfo*/)
1097 {
1098     LogDebug("loadFinishedCallback called");
1099     Assert(data);
1100     ViewLogic* This = static_cast<ViewLogic*>(data);
1101
1102     // Fill id/password
1103     const char* url = ewk_view_uri_get(This->m_currentEwkView);
1104     if (NULL == url || strlen(url) == 0) {
1105         LogError("url is empty");
1106     } else {
1107         DPL::OptionalString jsOptionalString =
1108             ViewModule::PasswordSupport::jsForAutoFillData(url);
1109         if (jsOptionalString.IsNull()) {
1110             LogError("Fail to get JS String");
1111         } else {
1112             std::string jsStr = DPL::ToUTF8String(*jsOptionalString).c_str();
1113
1114             if(EINA_FALSE == ewk_view_script_execute(
1115                 This->m_currentEwkView,
1116                 jsStr.c_str(),
1117                 didRunJavaScriptCallback,
1118                 This))
1119             {
1120                 LogError("JS for auto fill data failed.");
1121             }
1122         }
1123     }
1124
1125     // call loadFinish callback to wrt-client
1126     if (!This->m_cbs->loadFinish.empty()) {
1127         This->m_cbs->loadFinish(obj);
1128     }
1129
1130     // set only encoded bundle
1131     double scale = elm_config_scale_get();
1132     PluginModuleSupport::setCustomProperties(
1133         This->m_ewkContext,
1134         &scale,
1135         ApplicationDataSingleton::Instance().getEncodedBundle());
1136     // check if 'appsevice' event is registed at the current frames.
1137     // If so, dispatch the event to frames.
1138     PluginModuleSupport::dispatchJavaScriptEvent(
1139         This->m_ewkContext,
1140         WrtPlugins::W3C::ServiceCustomEvent,
1141         NULL);
1142 }
1143
1144 void ViewLogic::titleChangedCallback(
1145         void* data,
1146         Evas_Object* /*obj*/,
1147         void* eventInfo)
1148 {
1149     LogDebug("titleChangedCallback called");
1150     Assert(data);
1151     ViewLogic* This = static_cast<ViewLogic*>(data);
1152     Assert(eventInfo);
1153     const char* title = static_cast<char*>(eventInfo);
1154
1155     if (0 == strlen(title)) {
1156         LogDebug("title data is empty");
1157         return;
1158     }
1159     LogDebug("Title = [" << title << "]");
1160     This->m_schemeSupport->HandleTizenScheme(title,
1161                                              This->m_window,
1162                                              This->m_currentEwkView);
1163 }
1164
1165 void ViewLogic::loadProgressCallback(
1166         void* /*data*/,
1167         Evas_Object* /*obj*/,
1168         void* eventInfo)
1169 {
1170     double* progress = static_cast<double*>(eventInfo);
1171     LogDebug("didChangeProgressCallback progress = " << *progress);
1172 }
1173
1174 void ViewLogic::loadProgressFinishedCallback(
1175         void* data,
1176         Evas_Object* /*obj*/,
1177         void* /*eventInfo*/)
1178 {
1179     LogDebug("didFinishProgressCallback");
1180     Assert(data);
1181     ViewLogic const * const view = static_cast<ViewLogic const * const>(data);
1182     if (!view->m_cbs->progressFinish.empty()) {
1183         view->m_cbs->progressFinish();
1184     }
1185 }
1186
1187 void ViewLogic::processCrashedCallback(
1188         void* data,
1189         Evas_Object* /*obj*/,
1190         void* eventInfo)
1191 {
1192     LogInfo("processCrashedCallback");
1193     Assert(data);
1194     ViewLogic const * const view =
1195             static_cast<ViewLogic const * const>(data);
1196     if (!view->m_cbs->webCrash.empty()) {
1197         view->m_cbs->webCrash();
1198     }
1199     // This flag will be prevented exit() call in the Webkit side
1200     if (NULL != eventInfo) {
1201         *(static_cast<Eina_Bool*>(eventInfo)) = EINA_TRUE;
1202     }
1203 }
1204
1205 void ViewLogic::createWindowCallback(
1206         void* data,
1207         Evas_Object* obj,
1208         void* eventInfo)
1209 {
1210     LogDebug("createWindowCallback");
1211     Assert(data);
1212     ViewLogic* This = static_cast<ViewLogic*>(data);
1213
1214     // First, current webview should be handled by user callback
1215     if (!This->m_cbs->bufferUnset.empty()) {
1216         This->m_cbs->bufferUnset(obj);
1217     }
1218
1219     // this can be set by executable for specific purpose
1220     Evas* canvas = NULL;
1221     if (!This->m_cbs->windowCreateBefore.empty()) {
1222         // 'obj' is parent webview object
1223         This->m_cbs->windowCreateBefore(&canvas, obj);
1224     }
1225     if (!canvas) {
1226         canvas = evas_object_evas_get(This->m_window);
1227     }
1228
1229     // create new ewkview
1230     This->createEwkView(canvas);
1231     Evas_Object* newEwkView = This->m_currentEwkView;
1232
1233     // initialize new ewkview
1234     This->setStartPage();
1235     This->ewkClientInit(newEwkView);
1236     This->prepareEwkView(newEwkView);
1237
1238     // Specific jobs of child, parent webview are handled by each executable
1239     if (!This->m_cbs->windowCreateAfter.empty()) {
1240         // 'obj' is parent webview, 'newEwkView' is child webview
1241         This->m_cbs->windowCreateAfter(obj, newEwkView);
1242     }
1243
1244     // Lastly, new webview should be handled by user callback
1245     if (!This->m_cbs->bufferSet.empty()) {
1246         This->m_cbs->bufferSet(newEwkView);
1247     }
1248     *(static_cast<Evas_Object **>(eventInfo)) = newEwkView;
1249 }
1250
1251 void ViewLogic::closeWindowCallback(
1252         void* data,
1253         Evas_Object* obj,
1254         void* /*eventInfo*/)
1255 {
1256     LogDebug("closeWindowCallback");
1257     ViewLogic* This = static_cast<ViewLogic*>(data);
1258     This->m_closedEwkView = obj;
1259     ecore_idler_add(windowCloseIdlerCallback, This);
1260 }
1261
1262 void ViewLogic::policyNavigationDecideCallback(
1263         void* data,
1264         Evas_Object* /*obj*/,
1265         void* eventInfo)
1266 {
1267     LogDebug("policyNavigationDecideCallback called");
1268     Assert(data);
1269     ViewLogic* This = static_cast<ViewLogic*>(data);
1270     Assert(eventInfo);
1271     Ewk_Policy_Decision* policyDecision =
1272         static_cast<Ewk_Policy_Decision*>(eventInfo);
1273
1274     if (This->m_schemeSupport->filterURIByScheme(policyDecision,
1275                                                  false,
1276                                                  This->m_model,
1277                                                  This->m_window,
1278                                                  This->m_currentEwkView))
1279     {
1280         LogDebug("use");
1281         ewk_policy_decision_use(policyDecision);
1282     } else {
1283         // check whether this is new empty window
1284         const char* activeUrl = ewk_view_uri_get(This->m_currentEwkView);
1285         if(!activeUrl || 0 == strlen(activeUrl)) {
1286             /*
1287              * The view is empty and scheme has been handled externally. When
1288              * user gets back from the external application he'd see blank page
1289              * and won't be able to navigate back. This happens when window.open
1290              * is used to handle schemes like sms/mms/mailto (for example in
1291              * WAC web standards tests: WS-15XX).
1292              *
1293              * To solve the problem, the empty view is removed from the stack
1294              * and the previous one is shown. This is not an elegant solution
1295              * but we don't have a better one.
1296              */
1297             LogInfo("Scheme has been handled externally. Removing empty view.");
1298             if (ewk_view_back_possible(This->m_currentEwkView)) {
1299                 // go back to previous WKPage
1300                 ewk_view_back(This->m_currentEwkView);
1301             } else {
1302                 // stop current WKPage
1303                 ewk_view_stop(This->m_currentEwkView);
1304                 ecore_idler_add(windowCloseIdlerCallback, This);
1305             }
1306         }
1307
1308         LogDebug("ignore");
1309         ewk_policy_decision_ignore(policyDecision);
1310     }
1311 }
1312
1313 void ViewLogic::policyNewWindowDecideCallback(
1314         void* data,
1315         Evas_Object* /*obj*/,
1316         void* eventInfo)
1317 {
1318     LogDebug("policyNewWindowDecideCallback called");
1319     Assert(data);
1320     ViewLogic* This = static_cast<ViewLogic*>(data);
1321     Assert(eventInfo);
1322     Ewk_Policy_Decision* policyDecision =
1323         static_cast<Ewk_Policy_Decision*>(eventInfo);
1324
1325     if (This->m_schemeSupport->filterURIByScheme(policyDecision,
1326                                                  true,
1327                                                  This->m_model,
1328                                                  This->m_window,
1329                                                  This->m_currentEwkView))
1330     {
1331         ewk_policy_decision_use(policyDecision);
1332     } else {
1333         // scheme handled
1334         ewk_policy_decision_ignore(policyDecision);
1335     }
1336 }
1337
1338 void ViewLogic::pageResponseDecideCallback(
1339         void* data,
1340         Evas_Object* /*obj*/,
1341         void* eventInfo)
1342 {
1343     LogDebug("pageResponseDecideCallback called");
1344     Assert(data);
1345     ViewLogic* This = static_cast<ViewLogic*>(data);
1346     Assert(eventInfo);
1347     Ewk_Policy_Decision* policyDecision =
1348         static_cast<Ewk_Policy_Decision*>(eventInfo);
1349     Ewk_Policy_Decision_Type policyDecisionType =
1350         ewk_policy_decision_type_get(policyDecision);
1351
1352     if (policyDecisionType == EWK_POLICY_DECISION_USE) {
1353         LogDebug("use");
1354         ewk_policy_decision_use(policyDecision);
1355     } else if (policyDecisionType == EWK_POLICY_DECISION_DOWNLOAD) {
1356         LogDebug("download");
1357         ewk_policy_decision_suspend(policyDecision);
1358
1359         // get uri information
1360         const char* url =  ewk_policy_decision_url_get(policyDecision);
1361         if (NULL == url || strlen(url) == 0) {
1362             LogDebug("url data is empty");
1363             ewk_policy_decision_use(policyDecision);
1364             return;
1365         }
1366         LogDebug("url = [" << url << "]");
1367
1368         // get content information
1369         const char* content =
1370             ewk_policy_decision_response_mime_get(policyDecision);
1371         LogDebug("content type = [" << content << "]");
1372
1373         // get cookie information
1374         const char* cookie = ewk_policy_decision_cookie_get(policyDecision);
1375         LogDebug("cookie = [" << cookie << "]");
1376
1377         LogDebug("Content not supported, will be opened in external app");
1378         This->m_appsSupport->downloadRequest(
1379             url,
1380             content,
1381             cookie);
1382         ewk_policy_decision_ignore(policyDecision);
1383     } else if (policyDecisionType == EWK_POLICY_DECISION_IGNORE) {
1384         LogDebug("ignore");
1385         ewk_policy_decision_ignore(policyDecision);
1386     } else {
1387         LogDebug("Type isn't handled");
1388         ewk_policy_decision_ignore(policyDecision);
1389     }
1390 }
1391
1392 void ViewLogic::contextmenuCustomizeCallback(
1393         void* data,
1394         Evas_Object* /*obj*/,
1395         void* eventInfo)
1396 {
1397     LogDebug("contextmenuCustomizeCallback called");
1398     Assert(data);
1399     Assert(eventInfo);
1400     ViewLogic* This = static_cast<ViewLogic*>(const_cast<void*>(data));
1401     Ewk_Context_Menu* menu = static_cast<Ewk_Context_Menu*>(eventInfo);
1402     if ((This->m_model->Type.Get().appType == WrtDB::APP_TYPE_TIZENWEBAPP) &&
1403         (This->m_model->SettingList.Get().getContextMenu()
1404             == ContextMenu_Disable))
1405     {
1406         LogDebug("ContextMenu Disable!!");
1407         for (unsigned int idx = 0; idx < ewk_context_menu_item_count(menu);) {
1408             Ewk_Context_Menu_Item* item = ewk_context_menu_nth_item_get(menu, idx);
1409             Assert(item);
1410             ewk_context_menu_item_remove(menu, item);
1411         }
1412     } else {
1413         LogDebug("ContextMenu Enable!!");
1414         for (unsigned int idx = 0; idx < ewk_context_menu_item_count(menu);) {
1415             Ewk_Context_Menu_Item* item = ewk_context_menu_nth_item_get(menu, idx);
1416             Assert(item);
1417             Ewk_Context_Menu_Item_Tag tag = ewk_context_menu_item_tag_get(item);
1418
1419             switch (tag) {
1420                 case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_IMAGE_IN_NEW_WINDOW:
1421                     ewk_context_menu_item_remove(menu, item);
1422                     break;
1423
1424                 case EWK_CONTEXT_MENU_ITEM_TAG_SEARCH_WEB:
1425                     ewk_context_menu_item_remove(menu, item);
1426                     break;
1427
1428                 default:
1429                     idx++;
1430                     break;
1431             }
1432         }
1433     }
1434 }
1435
1436 void ViewLogic::formSubmitCallback(
1437         void* /*data*/,
1438         Evas_Object* /*obj*/,
1439         void* eventInfo)
1440 {
1441     LogDebug("formSubmitCallback called");
1442     Assert(eventInfo);
1443     Ewk_Form_Data* formData = static_cast<Ewk_Form_Data*>(eventInfo);
1444
1445     const char* uri = ewk_form_data_url_get(formData);
1446     if (!uri) {
1447         LogError("URL is empty");
1448         return;
1449     }
1450
1451     Eina_Hash* userData = ewk_form_data_values_get(formData);
1452     ViewModule::PasswordSupport::submitClicked(uri, userData);
1453 }
1454
1455 void ViewLogic::geolocationPermissionRequestCallback(
1456         void* data,
1457         Evas_Object* /*obj*/,
1458         void* eventInfo)
1459 {
1460     Assert(data);
1461     ViewLogic* This = static_cast<ViewLogic*>(data);
1462     Assert(eventInfo);
1463     ViewModule::GeolocationSupport::Webkit2::geolocationPermissionRequest(
1464         This->m_window,
1465         This->m_securityOriginSupport->getSecurityOriginDAO(),
1466         eventInfo);
1467 }
1468
1469 void ViewLogic::notificationShowCallback(
1470         void* data,
1471         Evas_Object* /*obj*/,
1472         void* eventInfo)
1473 {
1474     LogDebug("notificationShowCallback called");
1475     Assert(data);
1476     ViewLogic* This = static_cast<ViewLogic*>(data);
1477
1478     Assert(eventInfo);
1479     Ewk_Notification* noti = static_cast<Ewk_Notification*>(eventInfo);
1480
1481     using namespace ViewModule::WebNotification;
1482
1483     WebNotificationDataPtr notiData(
1484             new WebNotificationData(
1485                 This->m_model,
1486                 ewk_notification_id_get(noti)));
1487
1488     DPL::OptionalString string =
1489         DPL::FromUTF8String(ewk_notification_icon_url_get(noti));
1490     if (!string.IsNull()) {
1491         notiData->m_iconURL = DPL::ToUTF8String(*string);
1492     }
1493     string = DPL::FromUTF8String(ewk_notification_title_get(noti));
1494     if (!string.IsNull()) {
1495         notiData->m_title = DPL::ToUTF8String(*string);
1496     }
1497     string = DPL::FromUTF8String(ewk_notification_body_get(noti));
1498     if (!string.IsNull()) {
1499         notiData->m_body = DPL::ToUTF8String(*string);
1500     }
1501
1502     LogInfo("notification id : " << notiData->m_id);
1503     LogInfo("notification iconURL : " << notiData->m_iconURL);
1504     LogInfo("notification title : " << notiData->m_title);
1505     LogInfo("notification body : " << notiData->m_body);
1506
1507     showWebNotification(notiData);
1508     ewk_notification_showed(This->m_ewkContext, ewk_notification_id_get(noti));
1509 }
1510
1511 void ViewLogic::notificationCancelCallback(
1512         void* /*data*/,
1513         Evas_Object* /*obj*/,
1514         void* /*eventInfo*/)
1515 {
1516     LogDebug("notificationCancelCallback called");
1517 }
1518
1519 void ViewLogic::notificationPermissionRequestCallback(
1520         void* data,
1521         Evas_Object* /*obj*/,
1522         void* eventInfo)
1523 {
1524     LogDebug("notificationPermissionRequestCallback called");
1525     Assert(data);
1526     ViewLogic* This = static_cast<ViewLogic*>(data);
1527
1528     Assert(eventInfo);
1529     Ewk_Notification_Permission_Request* request =
1530         static_cast<Ewk_Notification_Permission_Request*>(eventInfo);
1531     ewk_notification_permission_request_response(
1532         This->m_ewkContext,
1533         request,
1534         EINA_TRUE);
1535     return;
1536 }
1537
1538 void ViewLogic::vibrationVibrateCallback(
1539         void* data,
1540         Evas_Object* /*obj*/,
1541         void* eventInfo)
1542 {
1543     LogDebug("vibrationVibrateCallback called");
1544     Assert(data);
1545     ViewLogic* This = static_cast<ViewLogic*>(data);
1546
1547     Assert(eventInfo);
1548     const long vibrationTime = *(static_cast<const long*>(eventInfo));
1549
1550     // temp
1551     // This->m_vibrationSupport->startVibration(vibrationTime);
1552
1553     return;
1554 }
1555
1556 void ViewLogic::vibrationCancelCallback(
1557         void* data,
1558         Evas_Object* /*obj*/,
1559         void* /*eventInfo*/)
1560 {
1561     LogDebug("vibrationCancelCallback called");
1562     Assert(data);
1563     ViewLogic* This = static_cast<ViewLogic*>(data);
1564
1565     // temp
1566     // This->m_vibrationSupport->stopVibration();
1567
1568     return;
1569 }
1570
1571 // EWK Orientation Callback
1572 Eina_Bool ViewLogic::orientationLockCallback(
1573         Evas_Object* obj,
1574         Eina_Bool /*needLock*/,
1575         int orientation,
1576         void* data)
1577 {
1578     LogDebug("orientationLockCallback called");
1579     Assert(data);
1580     ViewLogic* This = static_cast<ViewLogic*>(data);
1581
1582     if (orientation & EWK_SCREEN_ORIENTATION_PORTRAIT_PRIMARY) {
1583         LogDebug("orientation is portrait-primary");
1584         elm_win_rotation_with_resize_set(This->m_window, 0);
1585         ewk_view_orientation_send(obj, 0);
1586     } else if(orientation & EWK_SCREEN_ORIENTATION_LANDSCAPE_PRIMARY) {
1587         LogDebug("orientation is landscape-primary");
1588         elm_win_rotation_with_resize_set(This->m_window, 270);
1589         ewk_view_orientation_send(obj, 90);
1590     } else if(orientation & EWK_SCREEN_ORIENTATION_PORTRAIT_SECONDARY) {
1591         LogDebug("orientation is portrait-secondary");
1592         elm_win_rotation_with_resize_set(This->m_window, 180);
1593         ewk_view_orientation_send(obj, 180);
1594     } else if(orientation & EWK_SCREEN_ORIENTATION_LANDSCAPE_SECONDARY) {
1595         LogDebug("orientation is landscape-secondary");
1596         elm_win_rotation_with_resize_set(This->m_window, 90);
1597         ewk_view_orientation_send(obj, -90);
1598     } else {
1599         LogDebug("Wrong orientation is set");
1600         return EINA_FALSE;
1601     }
1602     return EINA_TRUE;
1603 }
1604
1605
1606 // Fullscreen API callbacks
1607 void ViewLogic::enterFullscreenCallback(
1608         void* data,
1609         Evas_Object* /*obj*/,
1610         void* /*eventInfo*/)
1611 {
1612     LogInfo("enterFullscreenCallback called");
1613     Assert(data);
1614     ViewLogic* This = static_cast<ViewLogic*>(data);
1615     if (!This->m_cbs->toggleFullscreen.empty()) {
1616         This->m_cbs->toggleFullscreen(true);
1617     }
1618 }
1619 void ViewLogic::exitFullscreenCallback(
1620         void* data,
1621         Evas_Object* /*obj*/,
1622         void* /*eventInfo*/)
1623 {
1624     LogInfo("exitFullscreenCallback called");
1625     Assert(data);
1626     ViewLogic* This = static_cast<ViewLogic*>(data);
1627     if (!This->m_cbs->toggleFullscreen.empty()) {
1628         This->m_cbs->toggleFullscreen(false);
1629     }
1630 }
1631
1632 void ViewLogic::imeOpenCallback(
1633         void* data,
1634         Evas_Object* /*obj*/,
1635         void* eventInfo)
1636 {
1637     LogDebug("enter");
1638     Assert(data);
1639     Assert(eventInfo);
1640     ViewLogic* This = static_cast<ViewLogic*>(data);
1641     Eina_Rectangle *rect = static_cast<Eina_Rectangle *>(eventInfo);
1642
1643     using namespace WrtPlugins::W3C;
1644     SoftKeyboardChangeArgs args;
1645     args.state = IME_STATE_ON;
1646     args.width = rect->w;
1647     args.height = rect->h;
1648     This->fireJavascriptEvent(
1649             static_cast<int>(SoftKeyboardChangeCustomEvent),
1650             &args);
1651 }
1652
1653 void ViewLogic::imeCloseCallback(
1654         void* data,
1655         Evas_Object* /*obj*/,
1656         void* /*eventInfo*/)
1657 {
1658     LogDebug("enter");
1659     Assert(data);
1660     ViewLogic* This = static_cast<ViewLogic*>(data);
1661
1662     using namespace WrtPlugins::W3C;
1663     SoftKeyboardChangeArgs args;
1664     args.state = IME_STATE_OFF;
1665
1666     This->fireJavascriptEvent(
1667             static_cast<int>(SoftKeyboardChangeCustomEvent),
1668             &args);
1669 }
1670
1671 // helper method
1672 CustomHandlerDB::CustomHandlerPtr getCustomHandlerFromData(void* data)
1673 {
1674     Assert(data);
1675     Ewk_Custom_Handlers_Data* handler =
1676                 static_cast<Ewk_Custom_Handlers_Data*>(data);
1677     CustomHandlerDB::CustomHandlerPtr customHandler(new CustomHandlerDB::CustomHandler());
1678     const char* base_url = ewk_custom_handlers_data_base_url_get(handler);
1679     if (base_url) {
1680         LogDebug("base url: " << base_url);
1681         customHandler->base_url = DPL::FromASCIIString(string(base_url));
1682     }
1683     const char* url = ewk_custom_handlers_data_url_get(handler);
1684     if (url) {
1685         LogDebug("url: " << url);
1686         customHandler->url = DPL::FromASCIIString(string(url));
1687     }
1688     const char* target = ewk_custom_handlers_data_target_get(handler);
1689     if (target) {
1690         LogDebug("target: " << target);
1691         customHandler->target = DPL::FromASCIIString(string(target));
1692     }
1693     const char* title = ewk_custom_handlers_data_title_get(handler);
1694     if (title) {
1695         LogDebug("title: " << title);
1696         customHandler->title = DPL::FromASCIIString(string(title));
1697     }
1698     return customHandler;
1699 }
1700
1701 void ViewLogic::attachToCustomHandlersDao()
1702 {
1703     if (!m_attachedToCustomHandlerDao) {
1704         CustomHandlerDB::Interface::attachDatabaseRW();
1705     }
1706 }
1707
1708 void ViewLogic::detachFromCustomHandlersDao()
1709 {
1710     if (m_attachedToCustomHandlerDao) {
1711         CustomHandlerDB::Interface::detachDatabase();
1712     }
1713 }
1714
1715 void ViewLogic::protocolHandlerRegistrationCallback(void* data,
1716                                                     Evas_Object* obj,
1717                                                     void* eventInfo)
1718 {
1719     Assert(data);
1720     LogDebug("enter");
1721     CustomHandlerDB::CustomHandlerPtr customHandler =
1722             getCustomHandlerFromData(eventInfo);
1723     //TODO: whitelist/blacklist
1724     ViewLogic* This = static_cast<ViewLogic*>(data);
1725     LogDebug("Creating handlers dao");
1726     This->attachToCustomHandlersDao();
1727     CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1728     CustomHandlerDB::CustomHandlerPtr handler =
1729             handlersDao.getProtocolHandler(customHandler->target, customHandler->url);
1730     if (handler) {
1731         LogDebug("Protocol already registered - nothing to do");
1732     } else {
1733         LogDebug("Protocol handler not found");
1734         if (Wrt::Popup::PopupInvoker().askYesNo(PROTOCOL_HANDLER_ASK_TITLE, PROTOCOL_HANDLER_ASK_MSG)) {
1735             LogDebug("User allowed");
1736             customHandler->user_allowed = true;
1737         } else {
1738             LogDebug("User didn't allow");
1739             customHandler->user_allowed = false;
1740         }
1741         handlersDao.registerProtocolHandler(*(customHandler.get()));
1742         LogDebug("Protocal saved");
1743     }
1744 }
1745
1746 void ViewLogic::protocolHandlerIsRegisteredCallback(void* data,
1747                                                     Evas_Object* obj,
1748                                                     void* eventInfo)
1749 {
1750     LogDebug("enter");
1751     getCustomHandlerFromData(eventInfo);
1752     // TODO to be continued...
1753 }
1754
1755 void ViewLogic::protocolHandlerUnregistrationCallback(void* data,
1756                                                       Evas_Object* obj,
1757                                                       void* eventInfo)
1758 {
1759     LogDebug("enter");
1760     getCustomHandlerFromData(eventInfo);
1761     // TODO to be continued...
1762 }
1763
1764 void ViewLogic::contentHandlerRegistrationCallback(void* data,
1765                                                    Evas_Object* obj,
1766                                                    void* eventInfo)
1767 {
1768     Assert(data);
1769     LogDebug("enter");
1770     CustomHandlerDB::CustomHandlerPtr customHandler =
1771             getCustomHandlerFromData(eventInfo);
1772     //TODO: whitelist/blacklist
1773     ViewLogic* This = static_cast<ViewLogic*>(data);
1774     LogDebug("Creating handlers dao");
1775     This->attachToCustomHandlersDao();
1776     CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1777     CustomHandlerDB::CustomHandlerPtr handler =
1778             handlersDao.getContentHandler(customHandler->target, customHandler->url);
1779     if (handler) {
1780         LogDebug("Content already registered - nothing to do");
1781     } else {
1782         LogDebug("Content handler not found");
1783         if (Wrt::Popup::PopupInvoker().askYesNo(CONTENT_HANDLER_ASK_TITLE, CONTENT_HANDLER_ASK_MSG)) {
1784             LogDebug("User allowed");
1785             customHandler->user_allowed = true;
1786         } else {
1787             LogDebug("User didn't allow");
1788             customHandler->user_allowed = false;
1789         }
1790         handlersDao.registerContentHandler(*(customHandler.get()));
1791         LogDebug("Content saved");
1792     }
1793 }
1794
1795 void ViewLogic::contentHandlerIsRegisteredCallback(void* data,
1796                                                    Evas_Object* obj,
1797                                                    void* eventInfo)
1798 {
1799     LogDebug("enter");
1800     getCustomHandlerFromData(eventInfo);
1801     // TODO to be continued...
1802 }
1803
1804 void ViewLogic::contentHandlerUnregistrationCallback(void* data,
1805                                                      Evas_Object* obj,
1806                                                      void* eventInfo)
1807 {
1808     LogDebug("enter");
1809     getCustomHandlerFromData(eventInfo);
1810     // TODO to be continued...
1811 }
1812
1813 void ViewLogic::didRunJavaScriptCallback(
1814         Evas_Object* /*obj*/,
1815         const char* result,
1816         void* /*userData*/)
1817 {
1818     LogInfo("didRunJavaScriptCallback called");
1819     LogInfo("result = " << result);
1820 }
1821
1822 Eina_Bool ViewLogic::windowCloseIdlerCallback(void* data)
1823 {
1824     LogDebug("closeIdlerCallback");
1825     ViewLogic* This = static_cast<ViewLogic*>(data);
1826     This->windowClose();
1827     return ECORE_CALLBACK_CANCEL;
1828 }
1829
1830 int ViewLogic::appcoreLowMemoryCallback(void *data)
1831 {
1832     LogInfo("appcoreLowMemoryCallback");
1833     Assert(data);
1834     ViewLogic* This = static_cast<ViewLogic*>(data);
1835
1836     if (NULL == This->m_ewkContext) {
1837         LogInfo("ewk isn't initialize at this moment");
1838     } else {
1839         ewk_context_cache_clear(This->m_ewkContext);
1840         ewk_context_notify_low_memory(This->m_ewkContext);
1841     }
1842
1843     return 0;
1844 }
1845
1846 void ViewLogic::databaseUsagePermissionRequestCallback(
1847     void* data,
1848     Evas_Object* /*obj*/,
1849     void* eventInfo)
1850 {
1851     LogDebug("databaseUsagePermissionRequestCallback called");
1852     Assert(data);
1853     ViewLogic* This = static_cast<ViewLogic*>(data);
1854
1855     Assert(eventInfo);
1856     ViewModule::WebStorageSupport::webStorageCreatePermissionRequest(
1857         This->m_window,
1858         This->m_securityOriginSupport->getSecurityOriginDAO(),
1859         eventInfo);
1860     return;
1861  }
1862
1863 void ViewLogic::fileSystemPermissionRequestCallback(
1864     void* data,
1865     Evas_Object* /*obj*/,
1866     void* eventInfo)
1867 {
1868     LogDebug("fileSystemPermissionRequestCallback called");
1869     Assert(data);
1870     ViewLogic* This = static_cast<ViewLogic*>(data);
1871     Assert(eventInfo);
1872     ViewModule::FileSystemSupport::fileSystemPermissionRequest(
1873         This->m_window,
1874         This->m_securityOriginSupport->getSecurityOriginDAO(),
1875         eventInfo);
1876 }
1877
1878 void ViewLogic::didRecieveMessageFromInjectedBundle(
1879         const char* name,
1880         const char* /*body*/)
1881 {
1882     LogDebug("did recive message " << name);
1883 }
1884
1885 void ViewLogic::didReceiveSynchronousMessage(
1886         const char* name,
1887         const char* body,
1888         char** returnData)
1889 {
1890     LogDebug("didReceiveSynchronousMessage called");
1891     Assert(name);
1892     Assert(returnData);
1893
1894     if (!body) {
1895         LogDebug("body is empty");
1896         *returnData = NULL;
1897         return;
1898     }
1899     if (!strcmp(name, uriBlockedMessageName)) {
1900         LogDebug("received : " << uriBlockedMessageName);
1901         // Currently WebProcess informs obly about blocked
1902         // URI - URI localization and security chekcs are
1903         // done by WebProcess itself (see: wrt-wk2-bundle.cpp
1904         // and bundle_uri_handling.cpp)
1905         rememberBlockedURI(DPL::FromUTF8String(body));
1906         *returnData = NULL;
1907     } else if (!strcmp(name, uriChangedMessageName)) {
1908         LogDebug("received : " << uriChangedMessageName);
1909         std::string ret = requestUriChanged(DPL::FromUTF8String(body));
1910         *returnData =  strdup(ret.c_str());
1911     }
1912 }
1913
1914 void ViewLogic::rememberBlockedURI(const DPL::String& inputURI)
1915 {
1916     m_blockedUri = DPL::ToUTF8String(inputURI);
1917     LogInfo("set blocked uri to open browser later : " << m_blockedUri);
1918     return;
1919 }
1920
1921 std::string ViewLogic::requestUriChanged(const DPL::String& changedURL)
1922 {
1923     using namespace ViewModule::SecuritySupport;
1924
1925     std::string url = DPL::ToUTF8String(changedURL);
1926     LogInfo("URL = [" << url << "]");
1927
1928     // check WARP
1929     // If url is same to URICHANGE_BLOCKED_URL,
1930     // this url has been already blocked by willsend.
1931     // So current page should be moved to previous page
1932     if (url == URICHANGE_BLOCKED_URL)
1933     {
1934         if (m_model->Type.Get().appType == WrtDB::APP_TYPE_TIZENWEBAPP)
1935         {
1936             // block this page and open it in browser
1937             LogDebug("Request was blocked by WARP: " << url.c_str());
1938             if (!m_blockedUri.empty()) {
1939                 LogDebug("open browser : " << m_blockedUri);
1940                 bundle* bundleData = bundle_create();
1941                 appsvc_set_operation(bundleData, APPSVC_OPERATION_VIEW);
1942                 appsvc_set_uri(bundleData, m_blockedUri.c_str());
1943                 CONTROLLER_POST_EVENT(
1944                     ApplicationLauncher,
1945                     ApplicationLauncherEvents::LaunchApplicationByAppService(
1946                         bundleData,
1947                         NULL,
1948                         NULL));
1949                 m_blockedUri = std::string();
1950             }
1951         }
1952         if (ewk_view_back_possible(m_currentEwkView)) {
1953             // go back to previous page
1954             ewk_view_back(m_currentEwkView);
1955         } else {
1956             // stop current page
1957             ewk_view_stop(m_currentEwkView);
1958             ecore_idler_add(windowCloseIdlerCallback, this);
1959         }
1960
1961         // This is used in case of returning previous page
1962         m_currentUri = url;
1963         return URICHANGE_PLUGIN_NO_CHANGE;
1964     }
1965
1966     m_currentUri = url;
1967
1968     // Check if this url with 'http' or 'https' is included in whitelist,
1969     // which has lists of accessible external documents and
1970     // used for ONLY Tizen app
1971     std::string matchedScheme;
1972     std::string matchedUri;
1973     pcrecpp::RE(PATTERN_URI_CHANGE).PartialMatch(url.c_str(),
1974                                                  &matchedUri,
1975                                                  &matchedScheme);
1976     ViewModule::Scheme scheme(matchedScheme);
1977     if (scheme.GetType() == ViewModule::Scheme::HTTP ||
1978         scheme.GetType() == ViewModule::Scheme::HTTPS)
1979     {
1980         if (m_model->Type.Get().appType == WrtDB::APP_TYPE_TIZENWEBAPP) {
1981             if (!checkWhitelist(url.c_str())) {
1982                 LogInfo("This uri is not included in white document list");
1983                 return URICHANGE_PLUGIN_STOP_ONLY;
1984             }
1985             LogInfo("This url is included in WhiteList");
1986         } else {
1987             // For WAC app, WRT should block access of device api
1988             // for external documents
1989             return URICHANGE_PLUGIN_STOP_ONLY;
1990         }
1991     }
1992
1993     // register javascript object for plugins to be used
1994     LogInfo("Register Plugin Objects");
1995     return URICHANGE_PLUGIN_RESTART;
1996 }
1997
1998 void ViewLogic::windowClose()
1999 {
2000     LogDebug("windowClose");
2001     Assert(m_closedEwkView && "no closed webview");
2002
2003     if (1 >= m_ewkViewList.size()) {
2004         if (!m_cbs->webkitExit.empty()) {
2005             m_cbs->webkitExit();
2006         }
2007     } else {
2008         // call user callbacks
2009         if (!m_cbs->bufferUnset.empty()) {
2010             m_cbs->bufferUnset(m_currentEwkView);
2011         }
2012         if (!m_cbs->windowClose.empty()) {
2013             m_cbs->windowClose(m_closedEwkView);
2014         }
2015         removeEwkView(m_closedEwkView);
2016
2017         // get latest ewkView
2018         m_currentEwkView = m_ewkViewList.back();
2019         const char* uri = ewk_view_uri_get(m_currentEwkView);
2020         if (NULL == uri || 0 == strlen(uri)) {
2021             m_currentUri.clear();
2022         } else {
2023             m_currentUri = uri;
2024         }
2025
2026         // resume ewkView
2027         /* In case we support many pages in parallel
2028            then view is not suspended*/
2029         //resumeEwkView(m_currentEwkView);
2030
2031         // show ewkView
2032         if (!m_cbs->bufferSet.empty()) {
2033             m_cbs->bufferSet(m_currentEwkView);
2034         }
2035     }
2036 }
2037