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