Task TT-75 Implement "Main page loading UI" view
[profile/tv/apps/web/browser.git] / services / WebKitEngineService / WebView.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
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 /*
18  * WebView.cpp
19  *
20  *  Created on: Apr 1, 2014
21  *      Author: p.rafalski
22  */
23
24 #include "WebView.h"
25
26 #if defined(USE_EWEBKIT)
27 #include <ewk_chromium.h>
28 #endif
29
30 #include <boost/format.hpp>
31 #include <boost/regex.hpp>
32 #include <boost/algorithm/string/regex.hpp>
33 #include <boost/algorithm/string/classification.hpp>
34 #include <boost/algorithm/string/split.hpp>
35 #include <Elementary.h>
36 #include <Evas.h>
37
38 #include "AbstractWebEngine/AbstractWebEngine.h"
39 #include "AbstractWebEngine/TabThumbCache.h"
40 #include "BrowserAssert.h"
41 #include "BrowserLogger.h"
42 #include "EflTools.h"
43 #include "GeneralTools.h"
44 #include "Tools/WorkQueue.h"
45 #include "ServiceManager.h"
46
47 #define certificate_crt_path CERTS_DIR
48 #if MERGE_ME
49 #define APPLICATION_NAME_FOR_USER_AGENT "SamsungBrowser/1.0"
50 #else
51 #define APPLICATION_NAME_FOR_USER_AGENT "Mozilla/5.0 (X11; SMART-TV; Linux) AppleWebkit/538.1 (KHTML, like Gecko) Safari/538.1"
52 #endif
53
54 using namespace tizen_browser::tools;
55
56 namespace tizen_browser {
57 namespace basic_webengine {
58 namespace webkitengine_service {
59
60 WebView::WebView(Evas_Object * obj, TabId tabId)
61     : m_parent(obj)
62     , m_tabId(tabId)
63     , m_title(std::string())
64     , m_ewkView(nullptr)
65     , m_isLoading(false)
66     , m_loadError(false)
67 {
68     config.load("whatever");
69 }
70
71 WebView::~WebView()
72 {
73     BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
74
75     if (m_ewkView) {
76         unregisterCallbacks();
77     }
78 }
79
80 void WebView::init(Evas_Object * opener)
81 {
82 #if defined(USE_EWEBKIT)
83
84 #if 0 //not using smart class
85     static Ewk_View_Smart_Class *clasz = nullptr;
86     Ewk_Context *context = ewk_context_default_get();
87     if (!clasz) {
88         clasz = smartClass();
89         ewk_view_smart_class_set(clasz);
90
91 //        clasz->run_javascript_alert = onJavascriptAlert;
92 //        clasz->run_javascript_confirm = onJavascriptConfirm;
93 //        clasz->run_javascript_prompt = onJavascriptPrompt;
94 //        clasz->window_create = onWindowCreate;
95 //        clasz->window_close = onWindowClose;
96
97
98         ewk_context_cache_model_set(context, EWK_CACHE_MODEL_PRIMARY_WEBBROWSER);
99         ewk_context_certificate_file_set(context, certificate_crt_path);
100
101     }
102
103     Evas_Smart *smart = evas_smart_class_new(&clasz->sc);
104
105     /// \todo: Consider process model. Now, One UIProcess / One WebProcess.
106 //    if (opener)
107 //        m_ewkView = ewk_view_smart_add(evas_object_evas_get(m_parent), smart, context, ewk_view_page_group_get(opener));
108 //    else
109         m_ewkView = ewk_view_smart_add(evas_object_evas_get(m_parent), smart, context, ewk_page_group_create(nullptr));
110 #else
111         m_ewkView = ewk_view_add(evas_object_evas_get(m_parent));
112 //      Ewk_Context *context = ewk_view_context_get(m_ewkView);
113 #endif
114
115     evas_object_data_set(m_ewkView, "_container", this);
116     BROWSER_LOGD("%s:%d %s self=%p", __FILE__, __LINE__, __func__, this);
117
118     evas_object_color_set(m_ewkView, 255, 255, 255, 255);
119     evas_object_size_hint_weight_set(m_ewkView, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
120     evas_object_size_hint_align_set(m_ewkView, EVAS_HINT_FILL, EVAS_HINT_FILL);
121     ewk_view_application_name_for_user_agent_set(m_ewkView, APPLICATION_NAME_FOR_USER_AGENT);
122     //\todo: when value is other than 1.0, scroller is located improperly
123 //    ewk_view_device_pixel_ratio_set(m_ewkView, 1.0f);
124
125 #if PLATFORM(TIZEN)
126     ewk_view_resume(m_ewkView);
127 #endif
128 #if 0
129     // set local storage, favion, cookies
130     std::string webkit_path =  boost::any_cast <std::string> (config.get("webkit/dir"));
131 //    ewk_context_web_storage_path_set(context, (webkit_path + std::string("/storage")).c_str());
132     ewk_context_favicon_database_directory_set(context, (webkit_path + std::string("/favicon")).c_str());
133     ewk_cookie_manager_persistent_storage_set(ewk_context_cookie_manager_get(context)
134                                              , (webkit_path + std::string("/cookies.db")).c_str()
135                                              , EWK_COOKIE_PERSISTENT_STORAGE_SQLITE);
136
137 ///\note Odroid modification - not exists in WebKit API
138 //     ewk_cookie_manager_widget_cookie_directory_set(ewk_context_cookie_manager_get(context), webkit_path.c_str());
139
140     ewk_favicon_database_icon_change_callback_add(ewk_context_favicon_database_get(context), __faviconChanged, this);
141 #endif
142     setupEwkSettings();
143     registerCallbacks();
144 #else
145     m_ewkView = evas_object_rectangle_add(evas_object_evas_get(m_parent));
146 #endif
147 }
148
149 void WebView::registerCallbacks()
150 {
151 #if defined(USE_EWEBKIT)
152     evas_object_smart_callback_add(m_ewkView, "load,started", __loadStarted, this);
153     evas_object_smart_callback_add(m_ewkView, "load,stop", __loadStop, this);
154     evas_object_smart_callback_add(m_ewkView, "load,finished", __loadFinished, this);
155     evas_object_smart_callback_add(m_ewkView, "load,progress", __loadProgress, this);
156     evas_object_smart_callback_add(m_ewkView, "load,error", __loadError, this);
157
158     evas_object_smart_callback_add(m_ewkView, "title,changed", __titleChanged, this);
159     evas_object_smart_callback_add(m_ewkView, "url,changed", __urlChanged, this);
160
161     evas_object_smart_callback_add(m_ewkView, "back,forward,list,changed", __backForwardListChanged, this);
162
163     evas_object_smart_callback_add(m_ewkView, "create,window", __OnNewWindowRequest, this);
164
165     evas_object_smart_callback_add(m_ewkView, "geolocation,permission,request", __geolocationPermissionRequest, this);
166     evas_object_smart_callback_add(m_ewkView, "usermedia,permission,request", __usermediaPermissionRequest, this);
167     evas_object_smart_callback_add(m_ewkView, "notification,permission,request", __notificationPermissionRequest, this);
168     evas_object_smart_callback_add(m_ewkView, "authentication,request", __authenticationRequest, this);
169     evas_object_smart_callback_add(m_ewkView, "request,certificate,confirm", __requestCertificationConfirm, this);
170
171     evas_object_event_callback_add(m_ewkView, EVAS_CALLBACK_MOUSE_DOWN, __setFocusToEwkView, this);
172     evas_object_smart_callback_add(m_ewkView, "favicon,changed", onFaviconChaged, this);
173
174     evas_object_smart_callback_add(m_ewkView, "editorclient,ime,closed", __IMEClosed, this);
175     evas_object_smart_callback_add(m_ewkView, "editorclient,ime,opened", __IMEOpened, this);
176 #endif
177 }
178
179 void WebView::unregisterCallbacks()
180 {
181 #if defined(USE_EWEBKIT)
182     evas_object_smart_callback_del_full(m_ewkView, "load,started", __loadStarted, this);
183     evas_object_smart_callback_del_full(m_ewkView, "load,stop", __loadStop, this);
184     evas_object_smart_callback_del_full(m_ewkView, "load,finished", __loadFinished, this);
185     evas_object_smart_callback_del_full(m_ewkView, "load,progress", __loadProgress, this);
186     evas_object_smart_callback_del_full(m_ewkView, "load,error", __loadError, this);
187
188     evas_object_smart_callback_del_full(m_ewkView, "title,changed", __titleChanged, this);
189     evas_object_smart_callback_del_full(m_ewkView, "url,changed", __urlChanged, this);
190
191     evas_object_smart_callback_del_full(m_ewkView, "back,forward,list,changed", __backForwardListChanged, this);
192
193     evas_object_smart_callback_del_full(m_ewkView, "create,window", __OnNewWindowRequest, this);
194
195     evas_object_smart_callback_del_full(m_ewkView, "geolocation,permission,request", __geolocationPermissionRequest, this);
196     evas_object_smart_callback_del_full(m_ewkView, "usermedia,permission,request", __usermediaPermissionRequest, this);
197     evas_object_smart_callback_del_full(m_ewkView, "notification,permission,request", __notificationPermissionRequest, this);
198     evas_object_smart_callback_del_full(m_ewkView, "authentication,request", __authenticationRequest, this);
199     evas_object_smart_callback_del_full(m_ewkView, "request,certificate,confirm", __requestCertificationConfirm, this);
200
201     evas_object_event_callback_del(m_ewkView, EVAS_CALLBACK_MOUSE_DOWN, __setFocusToEwkView);
202     evas_object_smart_callback_del_full(m_ewkView, "favicon,changed", onFaviconChaged, this);
203
204     evas_object_smart_callback_del_full(m_ewkView, "editorclient,ime,closed", __IMEClosed, this);
205     evas_object_smart_callback_del_full(m_ewkView, "editorclient,ime,opened", __IMEOpened, this);
206 #endif
207 }
208
209 void WebView::setupEwkSettings()
210 {
211 #if defined(USE_EWEBKIT)
212 #if PLATFORM(TIZEN)
213     Ewk_Settings * settings = ewk_view_settings_get(m_ewkView);
214     ewk_settings_uses_keypad_without_user_action_set(settings, EINA_FALSE);
215 #endif
216 #endif
217 }
218
219 Evas_Object * WebView::getLayout()
220 {
221     return m_ewkView;
222 }
223
224 void WebView::setURI(const std::string & uri)
225 {
226     BROWSER_LOGD("%s:%d %s uri=%s", __FILE__, __LINE__, __func__, uri.c_str());
227 #if defined(USE_EWEBKIT)
228     BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
229     ewk_view_url_set(m_ewkView, uri.c_str());
230     m_loadError = false;
231 #endif
232 }
233
234 std::string WebView::getURI(void)
235 {
236 #if defined(USE_EWEBKIT)
237     BROWSER_LOGD("%s:%d %s uri=%s", __FILE__, __LINE__, __func__, ewk_view_url_get(m_ewkView));
238     return tizen_browser::tools::fromChar(ewk_view_url_get(m_ewkView));
239 #else
240     return std::string();
241 #endif
242 }
243
244 std::string WebView::getTitle(void)
245 {
246     return m_title;
247 }
248
249 void WebView::stopLoading(void)
250 {
251 #if defined(USE_EWEBKIT)
252     ewk_view_stop(m_ewkView);
253 #endif
254     loadStop();
255 }
256
257 void WebView::reload(void)
258 {
259 #if defined(USE_EWEBKIT)
260     if(m_loadError)
261     {
262         m_loadError = false;
263         ewk_view_url_set(m_ewkView, ewk_view_url_get(m_ewkView));
264     }
265     else
266         ewk_view_reload(m_ewkView);
267 #endif
268 }
269
270 void WebView::back(void)
271 {
272 #if defined(USE_EWEBKIT)
273     m_loadError = false;
274     ewk_view_back(m_ewkView);
275 #endif
276 }
277
278 void WebView::forward(void)
279 {
280 #if defined(USE_EWEBKIT)
281     m_loadError = false;
282     ewk_view_forward(m_ewkView);
283 #endif
284 }
285
286 bool WebView::isBackEnabled(void)
287 {
288 #if defined(USE_EWEBKIT)
289     return ewk_view_back_possible(m_ewkView);
290 #else
291     return false;
292 #endif
293 }
294
295 bool WebView::isForwardEnabled(void)
296 {
297 #if defined(USE_EWEBKIT)
298     return ewk_view_forward_possible(m_ewkView);
299 #else
300     return false;
301 #endif
302 }
303
304 bool WebView::isLoading()
305 {
306     return m_isLoading;
307 }
308
309 bool WebView::isLoadError() const
310 {
311     return m_loadError;
312 }
313
314
315 void WebView::setPrivateMode(bool state)
316 {
317     BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
318     M_ASSERT(m_ewkView);
319
320 #if defined(USE_EWEBKIT)
321 #if PLATFORM(TIZEN)
322     Ewk_Settings * settings = ewk_view_settings_get(m_ewkView);
323 #else
324     Ewk_Settings * settings = ewk_page_group_settings_get(ewk_view_page_group_get(m_ewkView));
325 #endif
326     ewk_settings_private_browsing_enabled_set(settings, state);
327     if(state){
328          ewk_cookie_manager_accept_policy_set(ewk_context_cookie_manager_get(ewk_context_default_get()), EWK_COOKIE_ACCEPT_POLICY_NEVER);
329     }
330     else{
331          ewk_cookie_manager_accept_policy_set(ewk_context_cookie_manager_get(ewk_context_default_get()), EWK_COOKIE_ACCEPT_POLICY_ALWAYS);
332     }
333 #endif
334 }
335
336 void WebView::confirmationResult(WebConfirmationPtr confirmation)
337 {
338     BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
339
340 #if defined(USE_EWEBKIT)
341 #if PLATFORM(TIZEN)
342     switch(confirmation->getConfirmationType()) {
343     case WebConfirmation::ConfirmationType::Geolocation: {
344         Ewk_Geolocation_Permission_Request *request = m_confirmationGeolocationMap[confirmation];
345         Eina_Bool result;
346         if (confirmation->getResult() == WebConfirmation::ConfirmationResult::Confirmed)
347             result = EINA_TRUE;
348         else if (confirmation->getResult() == WebConfirmation::ConfirmationResult::Rejected)
349             result = EINA_FALSE;
350         else {
351             BROWSER_LOGE("Wrong ConfirmationResult");
352             break;
353         }
354         // set geolocation permission
355         ewk_geolocation_permission_request_set(request, result );
356
357         // remove from map
358         m_confirmationGeolocationMap.erase(confirmation);
359         break;
360     }
361     case WebConfirmation::ConfirmationType::UserMedia: {
362         Ewk_User_Media_Permission_Request *request = m_confirmationUserMediaMap[confirmation];
363         Eina_Bool result;
364         if (confirmation->getResult() == WebConfirmation::ConfirmationResult::Confirmed)
365             result = EINA_TRUE;
366         else if (confirmation->getResult() == WebConfirmation::ConfirmationResult::Rejected)
367             result = EINA_FALSE;
368         else {
369             BROWSER_LOGE("Wrong ConfirmationResult");
370             break;
371         };
372
373         // set usermedia permission
374         ewk_user_media_permission_request_set(request, result);
375
376         // remove from map
377         m_confirmationUserMediaMap.erase(confirmation);
378         break;
379     }
380     case WebConfirmation::ConfirmationType::Notification: {
381         Ewk_Notification_Permission_Request *request = m_confirmationNotificationMap[confirmation];
382         Eina_Bool result;
383         if (confirmation->getResult() == WebConfirmation::ConfirmationResult::Confirmed)
384             result = EINA_TRUE;
385         else if (confirmation->getResult() == WebConfirmation::ConfirmationResult::Rejected)
386             result = EINA_FALSE;
387         else {
388             BROWSER_LOGE("Wrong ConfirmationResult");
389             break;
390         }
391
392         // set notification permission
393         ewk_notification_permission_request_set(request, result);
394
395         // remove from map
396         m_confirmationNotificationMap.erase(confirmation);
397         break;
398     }
399     case WebConfirmation::ConfirmationType::CertificateConfirmation: {
400         CertificateConfirmationPtr cert = std::dynamic_pointer_cast<CertificateConfirmation, WebConfirmation>(confirmation);
401         Ewk_Certificate_Policy_Decision *request = m_confirmationCertificatenMap[cert];
402         Eina_Bool result;
403         if (cert->getResult() == WebConfirmation::ConfirmationResult::Confirmed)
404             result = EINA_TRUE;
405         else if (cert->getResult() == WebConfirmation::ConfirmationResult::Rejected)
406             result = EINA_FALSE;
407         else {
408             BROWSER_LOGE("Wrong ConfirmationResult");
409             break;
410         }
411
412         // set certificate confirmation
413         ewk_certificate_policy_decision_allowed_set(request, result);
414
415         // remove from map
416         m_confirmationCertificatenMap.erase(cert);
417         break;
418     }
419         case WebConfirmation::ConfirmationType::Authentication: {
420         AuthenticationConfirmationPtr auth = std::dynamic_pointer_cast<AuthenticationConfirmation, WebConfirmation>(confirmation);
421         Ewk_Auth_Request *request = m_confirmationAuthenticationMap[auth];
422         if (auth->getResult() == WebConfirmation::ConfirmationResult::Confirmed) {
423             // set auth challange credential
424             ewk_auth_request_authenticate(request, const_cast<char*>(auth->getLogin().c_str()), const_cast<char*>(auth->getPassword().c_str()));
425 //            ewk_object_unref(request);
426         } else if (auth->getResult() == WebConfirmation::ConfirmationResult::Rejected) {
427             ewk_auth_request_cancel(request);
428 //            ewk_object_unref(request);
429         } else {
430             BROWSER_LOGE("Wrong ConfirmationResult");
431             break;
432         }
433
434         // remove from map
435         m_confirmationAuthenticationMap.erase(auth);
436         break;
437     }
438     case WebConfirmation::ConfirmationType::ScriptAlert:
439         // set alert reply
440         ewk_view_javascript_alert_reply(m_ewkView);
441         break;
442     case WebConfirmation::ConfirmationType::ScriptConfirmation: {
443         Eina_Bool result;
444         if (confirmation->getResult() == WebConfirmation::ConfirmationResult::Confirmed)
445             result = EINA_TRUE;
446         else if (confirmation->getResult() == WebConfirmation::ConfirmationResult::Rejected)
447             result = EINA_FALSE;
448         else {
449             BROWSER_LOGE("Wrong ConfirmationResult");
450             break;
451         };
452
453         // set confirm reply
454         ewk_view_javascript_confirm_reply(m_ewkView, result);
455         break;
456     }
457     case WebConfirmation::ConfirmationType::ScriptPrompt: {
458         ScriptPromptPtr prompt = std::dynamic_pointer_cast<ScriptPrompt, WebConfirmation>(confirmation);
459         Eina_Bool result;
460         if (confirmation->getResult() == WebConfirmation::ConfirmationResult::Confirmed)
461             result = EINA_TRUE;
462         else if (confirmation->getResult() == WebConfirmation::ConfirmationResult::Rejected)
463             result = EINA_FALSE;
464         else {
465             BROWSER_LOGE("Wrong ConfirmationResult");
466             break;
467         };
468
469         // set prompt reply
470         ewk_view_javascript_prompt_reply(m_ewkView, prompt->getUserData().c_str());
471         break;
472     }
473     default:
474         break;
475     }
476 #else
477    (void)confirmation;
478 #endif
479 #endif
480 }
481
482 std::shared_ptr<tizen_browser::tools::BrowserImage> WebView::captureSnapshot(int targetWidth, int targetHeight)
483 {
484     BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
485     M_ASSERT(m_ewkView);
486     M_ASSERT(targetWidth);
487     M_ASSERT(targetHeight);
488     Evas_Coord vw, vh;
489     std::shared_ptr<tizen_browser::tools::BrowserImage> noImage = std::make_shared<tizen_browser::tools::BrowserImage>();
490     evas_object_geometry_get(m_ewkView, nullptr, nullptr, &vw, &vh);
491     if (vw == 0 || vh == 0)
492         return noImage;
493
494     Eina_Rectangle area;
495     double snapshotProportions = (double)(targetWidth) /(double)(targetHeight);
496     double webkitProportions = (double)(vw) /(double)(vh);
497     if (webkitProportions >= snapshotProportions) {
498         // centring position of screenshot
499         area.x = (vw*getZoomFactor()/2) - (vh*getZoomFactor()*snapshotProportions/2);
500         area.y = 0;
501         area.w = vh*getZoomFactor()*snapshotProportions;
502         area.h = vh*getZoomFactor();
503     }
504     else {
505         area.x = 0;
506         area.y = 0;
507         area.w = vw*getZoomFactor();
508         area.h = vw*getZoomFactor()/snapshotProportions;
509     }
510     if (area.w == 0 || area.h == 0)
511         return noImage;
512
513     double scaleW = (double)targetWidth / (double)(area.w);
514     double scaleH = (double)targetHeight / (double)(area.h);
515
516     BROWSER_LOGD("[%s:%d] Before snapshot (screenshot) - look at the time of taking snapshot below",__func__, __LINE__);
517 #if defined(USE_EWEBKIT)
518 #if PLATFORM(TIZEN)
519     Evas_Object *snapshot = ewk_view_screenshot_contents_get( m_ewkView, area, scaleW > scaleH ? scaleW : scaleH, evas_object_evas_get(m_ewkView));
520     BROWSER_LOGD("[%s:%d] Snapshot (screenshot) catched, evas pointer: %p",__func__, __LINE__, snapshot);
521     if (snapshot)
522         return tizen_browser::tools::EflTools::getBrowserImage(snapshot);
523 #endif
524 #endif
525
526     return std::shared_ptr<tizen_browser::tools::BrowserImage> ();
527 }
528
529 #if defined(USE_EWEBKIT)
530 void WebView::__setFocusToEwkView(void * data, Evas * /* e */, Evas_Object * /* obj */, void * /* event_info */)
531 {
532     BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
533
534     WebView * self = reinterpret_cast<WebView *>(data);
535
536     if(!self->hasFocus())
537         self->ewkViewClicked();
538 }
539
540 Ewk_View_Smart_Class * WebView::smartClass()
541 {
542     static Ewk_View_Smart_Class clasz = EWK_VIEW_SMART_CLASS_INIT_NAME_VERSION("BrowserView");
543
544     return &clasz;
545 }
546
547 void WebView::onJavascriptAlert(Ewk_View_Smart_Data */*smartData*/, const char * /*message*/)
548 {
549     BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
550     /*\todo FIX, because is not working propetly
551     WebView * self = reinterpret_cast<WebView *>(evas_object_data_get(smartData->self, "_container"));
552     BROWSER_LOGD("%s:%d %s self=%p", __FILE__, __LINE__, __func__, self);
553     std::string msg = tizen_browser::tools::fromChar(message);
554
555     WebConfirmationPtr c = std::make_shared<WebConfirmation>(WebConfirmation::ScriptAlert, self->m_tabId, std::string(), msg);
556     self->cofirmationRequest(c);
557     */
558 }
559
560 Eina_Bool WebView::onJavascriptConfirm(Ewk_View_Smart_Data */*smartData*/, const char * /*message*/)
561 {
562     BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
563     /*\todo FIX, because is not working propetly
564     WebView * self = reinterpret_cast<WebView *>(evas_object_data_get(smartData->self, "_container"));
565     BROWSER_LOGD("%s:%d %s self=%p", __FILE__, __LINE__, __func__, self);
566     std::string msg = tizen_browser::tools::fromChar(message);
567
568     WebConfirmationPtr c = std::make_shared<WebConfirmation>(WebConfirmation::ScriptConfirmation, self->m_tabId, std::string(), msg);
569     self->cofirmationRequest(c);
570 */
571     return EINA_TRUE;
572 }
573
574 const char * WebView::onJavascriptPrompt(Ewk_View_Smart_Data */*smartData*/, const char * /* message */, const char */*defaultValue*/)
575 {
576     BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
577     /*/*\todo FIX, because is not working propetly
578     WebView * self = reinterpret_cast<WebView *>(evas_object_data_get(smartData->self, "_container"));
579     BROWSER_LOGD("%s:%d %s self=%p", __FILE__, __LINE__, __func__, self);
580
581     std::string msg = tizen_browser::tools::fromChar(message);
582     std::string userdata = tizen_browser::tools::fromChar(defaultValue);
583     ScriptPromptPtr c = std::make_shared<ScriptPrompt>(self->m_tabId, std::string(), msg);
584     c->setUserData(userdata);
585
586     self->cofirmationRequest(c);
587 */
588     return "none";
589 }
590
591 Evas_Object * WebView::onWindowCreate(Ewk_View_Smart_Data *smartData, const Ewk_Window_Features *)
592 {
593     BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
594
595     WebView * self = reinterpret_cast<WebView *>(evas_object_data_get(smartData->self, "_container"));
596     BROWSER_LOGD("%s:%d %s self=%p", __FILE__, __LINE__, __func__, self);
597     BROWSER_LOGD("Window creating in tab: %s", self->getTabId().toString().c_str());
598     std::shared_ptr<basic_webengine::AbstractWebEngine<Evas_Object>>  m_webEngine;
599     m_webEngine = std::dynamic_pointer_cast
600     <
601         basic_webengine::AbstractWebEngine<Evas_Object>,tizen_browser::core::AbstractService
602     >
603     (tizen_browser::core::ServiceManager::getInstance().getService("org.tizen.browser.webkitengineservice"));
604     M_ASSERT(m_webEngine);
605
606     /// \todo: Choose newly created tab.
607     TabId id = m_webEngine->addTab(std::string(), &self->getTabId());
608     BROWSER_LOGD("Created tab: %s", id.toString().c_str());
609
610     Evas_Object* tab_ewk_view = m_webEngine->getTabView(id);
611     return tab_ewk_view;
612 }
613
614 void WebView::onWindowClose(Ewk_View_Smart_Data *smartData)
615 {
616     BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
617     WebView * self = reinterpret_cast<WebView *>(evas_object_data_get(smartData->self, "_container"));
618     std::shared_ptr<AbstractWebEngine<Evas_Object>> m_webEngine =
619                 std::dynamic_pointer_cast
620                 <basic_webengine::AbstractWebEngine<Evas_Object>,tizen_browser::core::AbstractService>
621                 (tizen_browser::core::ServiceManager::getInstance().getService("org.tizen.browser.webkitengineservice"));
622     m_webEngine->closeTab(self->getTabId());
623 }
624
625 void WebView::__loadStarted(void * data, Evas_Object * /* obj */, void * /* event_info */)
626 {
627     WebView * self = reinterpret_cast<WebView *>(data);
628
629     BROWSER_LOGD("%s:%d\n\t %s", __func__, __LINE__, ewk_view_url_get(self->m_ewkView));
630
631     self->m_isLoading = true;
632     self->loadStarted();
633     tizen_browser::services::TabThumbCache* cache = tizen_browser::services::TabThumbCache::getInstance();
634     cache->clearThumb(self->m_tabId);
635 }
636
637 void WebView::__loadStop(void * data, Evas_Object * /* obj */, void * /* event_info */)
638 {
639     BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
640
641     WebView * self = reinterpret_cast<WebView *>(data);
642     self->m_isLoading = false;
643
644     self->loadStop();
645 }
646
647 void WebView::__loadFinished(void * data, Evas_Object * /* obj */, void * /* event_info */)
648 {
649     BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
650
651     WebView * self = reinterpret_cast<WebView *>(data);
652     self->m_isLoading = false;
653     self->m_loadProgress = 1;
654
655     self->loadFinished();
656     self->loadProgress(self->m_loadProgress);
657     tizen_browser::services::TabThumbCache* cache = tizen_browser::services::TabThumbCache::getInstance();
658     cache->updateThumb(self->m_tabId);
659 }
660
661 void WebView::__loadProgress(void * data, Evas_Object * /* obj */, void * event_info)
662 {
663     BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
664
665     WebView * self = reinterpret_cast<WebView *>(data);
666     self->m_loadProgress = *(double *)event_info;
667
668     self->loadProgress(self->m_loadProgress);
669 }
670
671 void WebView::__loadError(void* data, Evas_Object * obj, void* ewkError)
672 {
673     BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
674
675     WebView *self = reinterpret_cast<WebView*>(data);
676     Ewk_Error *error = reinterpret_cast<Ewk_Error*>(ewkError);
677     Ewk_Error_Type errorType = ewk_error_type_get(error);
678
679     BROWSER_LOGD("[%s:%d] ewk_error_type: %d ",
680                  __PRETTY_FUNCTION__, __LINE__, errorType);
681
682     BROWSER_LOGD("[%s:%d] emiting signal ", __PRETTY_FUNCTION__, __LINE__);
683     int errorCode = ewk_error_code_get(error);
684     if(errorCode == EWK_ERROR_NETWORK_STATUS_CANCELLED)
685     {
686         BROWSER_LOGD("Stop signal emitted");
687         BROWSER_LOGD("Error description: %s", ewk_error_description_get(error));
688         evas_object_smart_callback_call(obj, "load,stop", nullptr);
689     }
690     else
691     {
692         self->loadError();
693         self->m_loadError=true;
694     }
695 }
696
697 void WebView::__titleChanged(void * data, Evas_Object * obj, void * /* event_info */)
698 {
699     BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
700
701     WebView * self = reinterpret_cast<WebView *>(data);
702     self->m_title = tizen_browser::tools::fromChar(ewk_view_title_get(obj));
703
704     self->titleChanged(self->m_title);
705 }
706
707 void WebView::__urlChanged(void * data, Evas_Object * /* obj */, void * event_info)
708 {
709     BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
710
711     WebView * self = reinterpret_cast<WebView *>(data);
712     BROWSER_LOGD("URL changed for tab: %s", self->getTabId().toString().c_str());
713     std::shared_ptr<basic_webengine::AbstractWebEngine<Evas_Object>> m_webEngine;
714     m_webEngine = std::dynamic_pointer_cast<basic_webengine::AbstractWebEngine<Evas_Object>, tizen_browser::core::AbstractService>(
715             tizen_browser::core::ServiceManager::getInstance().getService("org.tizen.browser.webkitengineservice"));
716     M_ASSERT(m_webEngine);
717     self->uriChanged(tizen_browser::tools::fromChar(reinterpret_cast<const char *>(event_info)));
718     self->tabIdChecker(self->m_tabId);
719 }
720
721 void WebView::__backForwardListChanged(void * data, Evas_Object * /* obj */, void * /* event_info */)
722 {
723     BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
724
725     WebView * self = reinterpret_cast<WebView *>(data);
726     self->backwardEnableChanged(self->isBackEnabled());
727     self->forwardEnableChanged(self->isForwardEnabled());
728 }
729
730 void WebView::__OnNewWindowRequest(void *data, Evas_Object*, void* out)
731 {
732   BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
733
734   WebView * self = reinterpret_cast<WebView *>(data);
735   BROWSER_LOGD("Window creating in tab: %s", self->getTabId().toString().c_str());
736
737   std::shared_ptr<basic_webengine::AbstractWebEngine<Evas_Object>>      m_webEngine;
738   m_webEngine = std::dynamic_pointer_cast
739   <
740           basic_webengine::AbstractWebEngine<Evas_Object>,tizen_browser::core::AbstractService
741   >
742   (tizen_browser::core::ServiceManager::getInstance().getService("org.tizen.browser.webkitengineservice"));
743   M_ASSERT(m_webEngine);
744
745   /// \todo: Choose newly created tab.
746   TabId id = m_webEngine->addTab(std::string(), &self->getTabId());
747   BROWSER_LOGD("Created tab: %s", id.toString().c_str());
748
749   Evas_Object* tab_ewk_view = m_webEngine->getTabView(id);
750   *static_cast<Evas_Object**>(out) = tab_ewk_view;
751 }
752
753
754 #if PLATFORM(TIZEN)
755 void WebView::__faviconChanged(const char * uri, void * data)
756 #else
757 void WebView::__faviconChanged(Ewk_Favicon_Database * database, const char * uri, void * data)
758 #endif
759 {
760     WebView * self = reinterpret_cast<WebView *>(data);
761     BROWSER_LOGD("[%s:%d] \n\turi:%s", __PRETTY_FUNCTION__, __LINE__, uri);
762
763 #if PLATFORM(TIZEN)
764     Ewk_Favicon_Database * database = ewk_context_favicon_database_get(ewk_view_context_get(self->m_ewkView));
765 #endif
766
767     Evas_Object *favicon = ewk_favicon_database_icon_get(database, uri, evas_object_evas_get(self->m_parent));
768     BROWSER_LOGD("Favicon: %p",favicon);
769     if (favicon) {
770         BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
771         self->faviconImage = tizen_browser::tools::EflTools::getBrowserImage(favicon);
772         evas_object_unref(favicon);
773         BROWSER_LOGD("[%s:%d] Favicon loaded, emiting favIconChanged(...)", __PRETTY_FUNCTION__, __LINE__);
774         self->favIconChanged(self->faviconImage);
775     }
776 }
777
778 void WebView::onFaviconChaged(void* data, Evas_Object*, void*)
779 {
780     WebView* self = reinterpret_cast<WebView*>(data);
781 //#if PLATFORM(TIZEN)
782 //    Evas_Object * favicon = ewk_view_favicon_get(self->m_ewkView);
783 //#else
784     Ewk_Favicon_Database * database = ewk_context_favicon_database_get(ewk_view_context_get(self->m_ewkView));
785     Evas_Object * favicon = ewk_favicon_database_icon_get(database, ewk_view_url_get(self->m_ewkView), evas_object_evas_get(self->m_parent));
786 //#endif
787     BROWSER_LOGD("[%s:%d] &favicon: %x ", __PRETTY_FUNCTION__, __LINE__, favicon);
788     if (favicon) {
789         self->favIconChanged(tizen_browser::tools::EflTools::getBrowserImage(favicon));
790         evas_object_unref(favicon);
791     }
792 }
793
794 void WebView::__IMEClosed(void* data, Evas_Object*, void*)
795 {
796     BROWSER_LOGD("%s", __func__);
797     WebView * self = reinterpret_cast<WebView *>(data);
798     self->IMEStateChanged(false);
799 }
800
801 void WebView::__IMEOpened(void* data, Evas_Object*, void*)
802 {
803     BROWSER_LOGD("%s", __func__);
804     WebView * self = reinterpret_cast<WebView *>(data);
805     self->IMEStateChanged(true);
806 }
807
808 std::string WebView::securityOriginToUri(const Ewk_Security_Origin *origin)
809 {
810     std::string protocol = tizen_browser::tools::fromChar(ewk_security_origin_protocol_get(origin));
811     std::string uri = tizen_browser::tools::fromChar(ewk_security_origin_host_get(origin));
812     int port = ewk_security_origin_port_get(origin);
813     std::string url;
814     if (port)
815         url = (boost::format("%1%:%2%//%3%") % protocol % port % uri).str();
816     else
817         url = (boost::format("%1%://%2%") % protocol % uri).str();
818     return url;
819 }
820
821 void WebView::__geolocationPermissionRequest(void * data, Evas_Object * /* obj */, void * event_info)
822 {
823     BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
824 #if PLATFORM(TIZEN)
825     WebView * self = reinterpret_cast<WebView *>(data);
826
827     Ewk_Geolocation_Permission_Request *request = reinterpret_cast<Ewk_Geolocation_Permission_Request *>(event_info);
828     if (!request)
829         return;
830
831     // suspend webview
832     ewk_geolocation_permission_request_suspend(request);
833
834     std::string url = WebView::securityOriginToUri(ewk_geolocation_permission_request_origin_get(request));
835
836     ///\todo add translations
837     std::string message = (boost::format("%1% Requests your location") % url).str();
838
839     WebConfirmationPtr c = std::make_shared<WebConfirmation>(WebConfirmation::ConfirmationType::Geolocation, self->m_tabId, url, message);
840
841     // store
842     self->m_confirmationGeolocationMap[c] = request;
843
844     self->cofirmationRequest(c);
845 #endif
846 }
847
848 void WebView::__usermediaPermissionRequest(void * data, Evas_Object * /* obj */, void * event_info)
849 {
850     BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
851 #if PLATFORM(TIZEN)
852     WebView * self = reinterpret_cast<WebView *>(data);
853
854     Ewk_User_Media_Permission_Request *request = reinterpret_cast<Ewk_User_Media_Permission_Request *>(event_info);
855     if (!request)
856         return;
857
858     // suspend webview
859     ewk_user_media_permission_request_suspend(request);
860
861     ///\todo add translations
862     std::string message = "User media permission request";
863
864     WebConfirmationPtr c = std::make_shared<WebConfirmation>(WebConfirmation::ConfirmationType::UserMedia, self->m_tabId, std::string(), message);
865
866     // store
867     self->m_confirmationUserMediaMap[c] = request;
868
869     self->cofirmationRequest(c);
870 #endif
871 }
872
873 void WebView::__notificationPermissionRequest(void * data, Evas_Object * /* obj */, void * event_info)
874 {
875     BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
876 #if PLATFORM(TIZEN)
877     WebView * self = reinterpret_cast<WebView *>(data);
878
879     Ewk_Notification_Permission_Request *request = reinterpret_cast<Ewk_Notification_Permission_Request *>(event_info);
880     if (!request)
881         return;
882
883     // suspend webview
884     ewk_notification_permission_request_suspend(request);
885
886     std::string url = WebView::securityOriginToUri(ewk_notification_permission_request_origin_get(request));
887
888     ///\todo add translations
889     std::string message = (boost::format("%1% wants to display notifications") % url).str();
890
891     WebConfirmationPtr c = std::make_shared<WebConfirmation>(WebConfirmation::ConfirmationType::Notification, self->m_tabId, url, message);
892
893     // store
894     self->m_confirmationNotificationMap[c] = request;
895
896     self->cofirmationRequest(c);
897 #endif
898 }
899
900 void WebView::__authenticationRequest(void * data, Evas_Object * /* obj */, void * event_info)
901 {
902     BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
903 #if PLATFORM(TIZEN)
904     WebView * self = reinterpret_cast<WebView *>(data);
905
906     Ewk_Auth_Request *request = reinterpret_cast<Ewk_Auth_Request *>(event_info);
907     EINA_SAFETY_ON_NULL_RETURN(request);
908
909     std::string realm = tizen_browser::tools::fromChar(ewk_auth_request_realm_get(request));
910 //    std::string url = tizen_browser::tools::fromChar(ewk_auth_request_host_get(request));
911
912 //    ewk_object_ref(request);
913
914     ///\todo add translations
915 //    std::string message = (boost::format("A username and password are being requested by %1%. The site says: \"%2%\"") % url % realm).str();
916
917 //    AuthenticationConfirmationPtr c = std::make_shared<AuthenticationConfirmation>(self->m_tabId, url, message);
918
919     // store
920 //    self->m_confirmationAuthenticationMap[c] = request;
921
922 //    self->cofirmationRequest(c);
923 #endif
924 }
925
926 void WebView::__requestCertificationConfirm(void * data , Evas_Object * /* obj */, void * event_info)
927 {
928     BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
929 #if PLATFORM(TIZEN)
930     WebView * self = reinterpret_cast<WebView *>(data);
931
932     Ewk_Certificate_Policy_Decision *request = reinterpret_cast<Ewk_Certificate_Policy_Decision *>(event_info);
933     if (!request)
934         return;
935
936     // suspend webview
937     ewk_certificate_policy_decision_suspend(request);
938
939     std::string url = tizen_browser::tools::fromChar(ewk_certificate_policy_decision_url_get(request));
940
941     ///\todo add translations
942     std::string message = (boost::format("There are problems with the security certificate for this site.<br>%1%") % url).str();
943
944     CertificateConfirmationPtr c = std::make_shared<CertificateConfirmation>(self->m_tabId, url, message);
945
946     c->setResult(tizen_browser::basic_webengine::WebConfirmation::ConfirmationResult::Confirmed);
947
948     // store
949     self->m_confirmationCertificatenMap[c] = request;
950
951     self->cofirmationRequest(c);
952 #endif
953 }
954 #endif
955
956 void WebView::setFocus()
957 {
958     elm_object_focus_set(m_ewkView, EINA_TRUE);
959 }
960
961 void WebView::clearFocus()
962 {
963     elm_object_focus_set(m_ewkView, EINA_FALSE);
964 }
965
966 bool WebView::hasFocus() const
967 {
968     return elm_object_focus_get(m_ewkView) == EINA_TRUE ? true : false;
969 }
970
971 double WebView::getZoomFactor() const
972 {
973     if(EINA_UNLIKELY(m_ewkView == nullptr)){
974         return 1.0;
975     }
976
977 #if defined(USE_EWEBKIT)
978     return ewk_view_text_zoom_get(m_ewkView);
979 #else
980     return 1.0;
981 #endif
982 }
983
984 void WebView::setZoomFactor(double zoomFactor)
985 {
986 #if defined(USE_EWEBKIT)
987     if(m_ewkView){
988         //using zoomFactor = 0 sets zoom "fit to screen"
989
990         ewk_view_text_zoom_set(m_ewkView, zoomFactor);
991     }
992 #endif
993 }
994
995
996 const TabId& WebView::getTabId(){
997     return m_tabId;
998 }
999
1000
1001 std::shared_ptr<tizen_browser::tools::BrowserImage> WebView::getFavicon() {
1002     BROWSER_LOGD("%s:%d, TabId: %s", __PRETTY_FUNCTION__, __LINE__, m_tabId.toString().c_str());
1003     M_ASSERT(m_ewkView);
1004
1005 #if defined(USE_EWEBKIT)
1006     if (faviconImage.get() == nullptr) {
1007 #if MERGE_ME
1008 //#if PLATFORM(TIZEN)
1009     Evas_Object * favicon = ewk_view_favicon_get(m_ewkView);
1010     Evas_Object * favicon = ewk_context_icon_database_icon_object_add(ewk_view_context_get(m_ewkView), ewk_view_url_get(m_ewkView),evas_object_evas_get(m_ewkView));
1011 #else
1012     Ewk_Favicon_Database * database = ewk_context_favicon_database_get(ewk_view_context_get(m_ewkView));
1013     Evas_Object * favicon = ewk_favicon_database_icon_get(database, ewk_view_url_get(m_ewkView), evas_object_evas_get(m_ewkView));
1014 #endif
1015 #ifndef NDEBUG
1016         int w = 0, h = 0;
1017         evas_object_image_size_get(favicon, &w, &h);
1018         BROWSER_LOGD("[%s]: Info about favicon: w:%d h:%d, type: %s", __func__, w, h, evas_object_type_get(favicon));
1019 #endif
1020         if (favicon) {
1021             std::shared_ptr<tizen_browser::tools::BrowserImage>
1022                 image = tizen_browser::tools::EflTools::getBrowserImage(favicon);
1023
1024             evas_object_unref(favicon);
1025
1026             return image;
1027         }
1028     } else {
1029         return faviconImage;
1030     }
1031 #endif
1032
1033     BROWSER_LOGE("[%s:%d]: Returned favicon is empty!", __PRETTY_FUNCTION__, __LINE__);
1034     return std::make_shared<tizen_browser::tools::BrowserImage>();
1035 }
1036
1037 void WebView::clearPrivateData()
1038 {
1039     BROWSER_LOGD("Clearing private data");
1040 #if defined(USE_EWEBKIT)
1041     Ewk_Context * context = ewk_context_default_get();
1042     ewk_context_web_storage_delete_all(context);
1043     ewk_cookie_manager_cookies_clear(ewk_context_cookie_manager_get(context));
1044 #endif
1045 }
1046
1047 void WebView::searchOnWebsite(const std::string & searchString, int flags)
1048 {
1049     ///\todo: it should be "0" instead of "1024" for unlimited match count but it doesn't work properly in WebKit
1050     Eina_Bool result = ewk_view_text_find(m_ewkView, searchString.c_str(), static_cast<Ewk_Find_Options>(flags), 1024);
1051     BROWSER_LOGD("Ewk search; word: %s, result: %d", searchString.c_str(), result);
1052 }
1053
1054 } /* namespace webkitengine_service */
1055 } /* end of basic_webengine */
1056 } /* end of tizen_browser */