2 Copyright (C) 2011 Samsung Electronics
3 Copyright (C) 2012 Intel Corporation. All rights reserved.
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
22 #include "EwkViewImpl.h"
24 #include "EflScreenUtilities.h"
25 #include "FindClientEfl.h"
26 #include "FormClientEfl.h"
27 #include "InputMethodContextEfl.h"
28 #include "PageClientImpl.h"
29 #include "PageLoadClientEfl.h"
30 #include "PagePolicyClientEfl.h"
31 #include "PageUIClientEfl.h"
32 #if ENABLE(WAIT_UPVERSION)
33 #include "PageViewportController.h"
34 #include "PageViewportControllerClientEfl.h"
36 #include "ResourceLoadClientEfl.h"
37 #include "WKColorPickerResultListener.h"
39 #include "WebPageProxy.h"
40 #include "WebPopupMenuProxyEfl.h"
41 #include "ewk_back_forward_list_private.h"
42 #include "ewk_context_private.h"
43 #include "ewk_favicon_database_private.h"
44 #include "ewk_popup_menu_item_private.h"
45 #include "ewk_private.h"
46 #include "ewk_settings_private.h"
48 #include "ewk_view_private.h"
49 #include <Ecore_Evas.h>
51 #include <WebCore/Cursor.h>
54 #if ENABLE(TIZEN_GEOLOCATION)
55 #include "ewk_geolocation_private.h"
57 #if ENABLE(TIZEN_MEDIA_STREAM)
58 #include "ewk_user_media_private.h"
60 #if ENABLE(TIZEN_NOTIFICATIONS)
61 #include "ewk_notification_private.h"
63 #if ENABLE(TIZEN_WEBKIT2_CREATE_VIEW_WITH_CREATED_PAGE_GROUP_WITH_IDENTIFIER)
64 #include "WebPageGroup.h"
66 #if ENABLE(TIZEN_SUPPORT_WEBAPP_META_TAG)
67 #include "ewk_web_application_icon_data_private.h"
71 using namespace WebCore;
72 using namespace WebKit;
74 static const int defaultCursorSize = 16;
76 EwkViewImpl::PageViewMap EwkViewImpl::pageViewMap;
78 void EwkViewImpl::addToPageViewMap(const Evas_Object* ewkView)
80 EwkViewImpl* viewImpl = EwkViewImpl::fromEvasObject(ewkView);
82 PageViewMap::AddResult result = pageViewMap.add(viewImpl->wkPage(), ewkView);
83 ASSERT_UNUSED(result, result.isNewEntry);
86 void EwkViewImpl::removeFromPageViewMap(const Evas_Object* ewkView)
88 EwkViewImpl* viewImpl = EwkViewImpl::fromEvasObject(ewkView);
90 ASSERT(pageViewMap.contains(viewImpl->wkPage()));
91 pageViewMap.remove(viewImpl->wkPage());
94 const Evas_Object* EwkViewImpl::viewFromPageViewMap(const WKPageRef page)
98 return pageViewMap.get(page);
101 #if ENABLE(TIZEN_WEBKIT2_CREATE_VIEW_WITH_CREATED_PAGE_GROUP_WITH_IDENTIFIER)
102 static uint64_t generatePageGroupIdentifierID()
104 static uint64_t uniquePageGroupIdentifierID = 1;
105 return uniquePageGroupIdentifierID++;
109 EwkViewImpl::EwkViewImpl(Evas_Object* view)
112 #if USE(ACCELERATED_COMPOSITING)
118 #if ENABLE(TIZEN_ORIENTATION_EVENTS)
121 , javascriptGlobalContext(0)
122 #if ENABLE(TIZEN_SUPPORT_WEBAPP_META_TAG)
125 , isWaitingForJavaScriptPopupReply(false)
128 , openPanelListener(0)
129 #if ENABLE(TIZEN_CERTIFICATE_HANDLING)
130 , certificatePolicyDecision(0)
132 #if ENABLE(TIZEN_MEDIA_STREAM)
133 , userMediaPermissionRequests(0)
135 #if ENABLE(TIZEN_GEOLOCATION)
137 , geolocationPermissionRequests(0)
139 , suspendRequested(false)
140 , suspendedPainting(false)
141 , suspendedResources(false)
142 #if ENABLE(TIZEN_NOTIFICATIONS)
144 , notificationPermissionRequests(0)
146 #if ENABLE(TIZEN_SQL_DATABASE)
147 , exceededDatabaseQuota(0)
149 #if ENABLE(TIZEN_WEBKIT2_POPUP_INTERNAL)
152 , isVerticalEdge(false)
153 , isHorizontalEdge(false)
154 #if ENABLE(TIZEN_GESTURE)
155 #if ENABLE(TOUCH_EVENTS)
156 , exceedTouchMoveThreshold(false)
157 , wasHandledTouchStart(false)
158 , wasHandledTouchMove(false)
160 , holdHorizontalPanning(false)
161 , holdVerticalPanning(false)
162 #endif // #if ENABLE(TIZEN_GESTURE)
163 #if ENABLE(TIZEN_RUNTIME_BACKEND_SELECTION)
164 , compositionAnimator(0)
166 #if ENABLE(TIZEN_DATALIST_ELEMENT)
169 #if ENABLE(TIZEN_APPLICATION_CACHE)
170 , applicationCachePermissionOrigin(0)
171 , isWaitingForApplicationCachePermission(false)
173 , exceededQuotaOrigin(0)
174 , isWaitingForExceededQuotaPopupReply(false)
175 #endif // #if OS(TIZEN)
177 , m_settings(Ewk_Settings::create(this))
178 , m_mouseEventsEnabled(false)
179 #if ENABLE(TOUCH_EVENTS)
180 , m_touchEventsEnabled(false)
182 , m_displayTimer(this, &EwkViewImpl::displayTimerFired)
183 , m_inputMethodContext(InputMethodContextEfl::create(this, smartData()->base.evas))
185 #if USE(TILED_BACKING_STORE)
188 #endif // #if OS(TIZEN)
192 // Enable mouse events by default
193 setMouseEventsEnabled(true);
196 javascriptPopup = adoptPtr<JavaScriptPopup>(new JavaScriptPopup(m_view));
197 openPanel = adoptPtr<OpenPanel>(new OpenPanel(m_view));
199 #if ENABLE(TIZEN_INPUT_TAG_EXTENSION)
200 inputPicker = adoptPtr<InputPicker>(new InputPicker(m_view));
203 #if ENABLE(TIZEN_GESTURE)
204 #if ENABLE(TOUCH_EVENTS)
205 touchDownPoint.x = 0;
206 touchDownPoint.y = 0;
210 #if ENABLE(TIZEN_GESTURE)
211 gestureRecognizer = GestureRecognizer::create(m_view);
212 gestureClient = GestureClient::create(this);
215 #if ENABLE(TIZEN_WEBKIT2_TILED_SCROLLBAR)
216 const char* hideScrollbar = getenv("TIZEN_WEBKIT2_TILED_SCROLLBAR_HIDE");
217 if (hideScrollbar && atoi(hideScrollbar) == 1)
218 mainFrameScrollbarVisibility = false;
220 mainFrameScrollbarVisibility = true;
223 #if ENABLE(TIZEN_SCREEN_ORIENTATION_SUPPORT_INTERNAL)
224 orientationLock.callback = 0;
225 orientationLock.data = 0;
228 #if ENABLE(TIZEN_WEBKIT2_CREATE_VIEW_WITH_CREATED_PAGE_GROUP_WITH_IDENTIFIER)
229 String pageGroupIdentifierID = String::number(generatePageGroupIdentifierID());
230 String pageGroupIdentifier = String::format("PageGroup%s", pageGroupIdentifierID.utf8().data());
232 WKRetainPtr<WKStringRef> pageGroupIdentifierRef(AdoptWK, WKStringCreateWithUTF8CString(pageGroupIdentifier.utf8().data()));
233 pageGroup = WebPageGroup::create(toWTFString(pageGroupIdentifierRef.get()));
235 #endif // #if OS(TIZEN)
238 EwkViewImpl::~EwkViewImpl()
241 EINA_LIST_FREE(popupMenuItems, item)
242 delete static_cast<Ewk_Popup_Menu_Item*>(item);
245 if (javascriptGlobalContext)
246 JSGlobalContextRelease(javascriptGlobalContext);
248 #if ENABLE(TIZEN_SUPPORT_WEBAPP_META_TAG)
249 if (webAppIconURLs) {
251 EINA_LIST_FREE(webAppIconURLs, data)
252 ewkWebAppIconDataDelete(static_cast<Ewk_Web_App_Icon_Data*>(data));
257 ewkAuthChallengeDelete(authChallenge);
259 ewkPolicyDecisionDelete(policyDecision);
261 #if ENABLE(TIZEN_CERTIFICATE_HANDLING)
262 if (certificatePolicyDecision)
263 ewkCertificatePolicyDecisionDelete(certificatePolicyDecision);
266 #if ENABLE(TIZEN_MEDIA_STREAM)
267 if (userMediaPermissionRequests)
268 ewkUserMediaDeletePermissionRequestList(userMediaPermissionRequests);
271 #if ENABLE(TIZEN_DATALIST_ELEMENT)
275 #if ENABLE(TIZEN_GEOLOCATION)
277 ewkGeolocationDeleteGeolocation(geolocation);
278 if (geolocationPermissionRequests)
279 ewkGeolocationDeletePermissionRequestList(geolocationPermissionRequests);
282 #if ENABLE(TIZEN_NOTIFICATIONS)
284 ewkNotificationDeleteNotificationList(notifications);
285 if (notificationPermissionRequests)
286 ewkNotificationDeletePermissionRequestList(notificationPermissionRequests);
289 #if ENABLE(TIZEN_SQL_DATABASE)
290 if (exceededDatabaseQuota)
291 ewkContextDeleteExceededQuota(exceededDatabaseQuota);
294 #if ENABLE(TIZEN_RUNTIME_BACKEND_SELECTION)
295 if (compositionAnimator)
296 ecore_animator_del(compositionAnimator);
299 #if ENABLE(TIZEN_APPLICATION_CACHE)
300 if (applicationCachePermissionOrigin)
301 deleteSecurityOrigin(applicationCachePermissionOrigin);
304 if (exceededQuotaOrigin)
305 deleteSecurityOrigin(exceededQuotaOrigin);
306 #endif // #if OS(TIZEN)
309 Ewk_View_Smart_Data* EwkViewImpl::smartData() const
311 return static_cast<Ewk_View_Smart_Data*>(evas_object_smart_data_get(m_view));
314 EwkViewImpl* EwkViewImpl::fromEvasObject(const Evas_Object* view)
317 Ewk_View_Smart_Data* sd = static_cast<Ewk_View_Smart_Data*>(evas_object_smart_data_get(view));
325 * Retrieves the internal WKPage for this view.
327 WKPageRef EwkViewImpl::wkPage()
329 return toAPI(pageProxy.get());
332 void EwkViewImpl::setCursor(const Cursor& cursor)
334 Ewk_View_Smart_Data* sd = smartData();
336 const char* group = cursor.platformCursor();
337 if (!group || group == m_cursorGroup)
340 m_cursorGroup = group;
341 m_cursorObject = adoptRef(edje_object_add(sd->base.evas));
343 Ecore_Evas* ecoreEvas = ecore_evas_ecore_evas_get(sd->base.evas);
344 if (!m_theme || !edje_object_file_set(m_cursorObject.get(), m_theme, group)) {
345 m_cursorObject.clear();
347 ecore_evas_object_cursor_set(ecoreEvas, 0, 0, 0, 0);
349 if (WebCore::isUsingEcoreX(sd->base.evas))
350 WebCore::applyFallbackCursor(ecoreEvas, group);
355 Evas_Coord width, height;
356 edje_object_size_min_get(m_cursorObject.get(), &width, &height);
357 if (width <= 0 || height <= 0)
358 edje_object_size_min_calc(m_cursorObject.get(), &width, &height);
359 if (width <= 0 || height <= 0) {
360 width = defaultCursorSize;
361 height = defaultCursorSize;
363 evas_object_resize(m_cursorObject.get(), width, height);
367 data = edje_object_data_get(m_cursorObject.get(), "hot.x");
369 hotspotX = atoi(data);
372 data = edje_object_data_get(m_cursorObject.get(), "hot.y");
374 hotspotY = atoi(data);
376 ecore_evas_object_cursor_set(ecoreEvas, m_cursorObject.get(), EVAS_LAYER_MAX, hotspotX, hotspotY);
379 void EwkViewImpl::displayTimerFired(WebCore::Timer<EwkViewImpl>*)
381 Ewk_View_Smart_Data* sd = smartData();
386 #if USE(COORDINATED_GRAPHICS)
387 EWK_VIEW_IMPL_GET_OR_RETURN(sd, viewImpl);
391 for (Vector<IntRect>::iterator it = m_dirtyRects.begin(); it != m_dirtyRects.end(); ++it)
392 dirtyRegion.unite(*it);
394 m_dirtyRects.clear();
396 Vector<IntRect> rects = dirtyRegion.rects();
397 Vector<IntRect>::iterator end = rects.end();
399 for (Vector<IntRect>::iterator it = rects.begin(); it != end; ++it) {
401 #if USE(COORDINATED_GRAPHICS)
402 evas_gl_make_current(viewImpl->evasGl, viewImpl->evasGlSurface, viewImpl->evasGlContext);
403 viewImpl->pageViewportControllerClient->display(rect, IntPoint(sd->view.x, sd->view.y));
406 evas_object_image_data_update_add(sd->image, rect.x(), rect.y(), rect.width(), rect.height());
410 void EwkViewImpl::redrawRegion(const IntRect& rect)
412 if (!m_displayTimer.isActive())
413 m_displayTimer.startOneShot(0);
414 m_dirtyRects.append(rect);
419 * A download for that view was cancelled.
421 * Emits signal: "download,cancelled" with pointer to a Ewk_Download_Job.
423 void EwkViewImpl::informDownloadJobCancelled(Ewk_Download_Job* download)
425 evas_object_smart_callback_call(m_view, "download,cancelled", download);
430 * A download for that view has failed.
432 * Emits signal: "download,failed" with pointer to a Ewk_Download_Job_Error.
434 void EwkViewImpl::informDownloadJobFailed(Ewk_Download_Job* download, Ewk_Error* error)
436 Ewk_Download_Job_Error downloadError = { download, error };
437 evas_object_smart_callback_call(m_view, "download,failed", &downloadError);
442 * A download for that view finished successfully.
444 * Emits signal: "download,finished" with pointer to a Ewk_Download_Job.
446 void EwkViewImpl::informDownloadJobFinished(Ewk_Download_Job* download)
448 evas_object_smart_callback_call(m_view, "download,finished", download);
453 * A new download has been requested for that view.
455 * Emits signal: "download,request" with pointer to a Ewk_Download_Job.
457 void EwkViewImpl::informDownloadJobRequested(Ewk_Download_Job* download)
459 evas_object_smart_callback_call(m_view, "download,request", download);
464 * informs that a form request is about to be submitted.
466 * Emits signal: "form,submission,request" with pointer to Ewk_Form_Submission_Request.
468 void EwkViewImpl::informNewFormSubmissionRequest(Ewk_Form_Submission_Request* request)
470 evas_object_smart_callback_call(m_view, "form,submission,request", request);
473 #if ENABLE(FULLSCREEN_API)
476 * Calls fullscreen_enter callback or falls back to default behavior and enables fullscreen mode.
478 void EwkViewImpl::enterFullScreen()
480 Ewk_View_Smart_Data* sd = smartData();
482 if (!sd->api->fullscreen_enter || !sd->api->fullscreen_enter(sd)) {
483 Ecore_Evas* ecoreEvas = ecore_evas_ecore_evas_get(sd->base.evas);
484 ecore_evas_fullscreen_set(ecoreEvas, true);
488 ewk_view_main_frame_scrollbar_visible_set(m_view, false);
489 evas_object_smart_callback_call(m_view, "fullscreen,enterfullscreen", 0);
495 * Calls fullscreen_exit callback or falls back to default behavior and disables fullscreen mode.
497 void EwkViewImpl::exitFullScreen()
499 Ewk_View_Smart_Data* sd = smartData();
501 if (!sd->api->fullscreen_exit || !sd->api->fullscreen_exit(sd)) {
502 Ecore_Evas* ecoreEvas = ecore_evas_ecore_evas_get(sd->base.evas);
503 ecore_evas_fullscreen_set(ecoreEvas, false);
507 ewk_view_main_frame_scrollbar_visible_set(m_view, true);
508 evas_object_smart_callback_call(m_view, "fullscreen,exitfullscreen", 0);
513 void EwkViewImpl::setImageData(void* imageData, const IntSize& size)
515 Ewk_View_Smart_Data* sd = smartData();
516 if (!imageData || !sd->image)
519 evas_object_resize(sd->image, size.width(), size.height());
520 evas_object_image_size_set(sd->image, size.width(), size.height());
521 evas_object_image_data_copy_set(sd->image, imageData);
524 #if ENABLE(INPUT_TYPE_COLOR)
525 bool EwkViewImpl::setColorPickerColor(const WebCore::Color& color)
527 if (!m_colorPickerResultListener)
530 WKRetainPtr<WKStringRef> colorString(AdoptWK, WKStringCreateWithUTF8CString(color.serialized().utf8().data()));
531 WKColorPickerResultListenerSetColor(m_colorPickerResultListener.get(), colorString.get());
532 m_colorPickerResultListener.clear();
540 * informs load failed with error information.
542 * Emits signal: "load,error" with pointer to Ewk_Error.
544 void EwkViewImpl::informLoadError(Ewk_Error* error)
546 evas_object_smart_callback_call(m_view, "load,error", error);
551 * informs load finished.
553 * Emits signal: "load,finished".
555 void EwkViewImpl::informLoadFinished()
558 evas_object_smart_callback_call(m_view, "load,finished", 0);
561 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
562 pageProxy->setLoadingFinished(true);
564 if (pageClient->wasViewportFitsToContent())
565 pageClient->fitViewportToContent();
567 #if ENABLE(TIZEN_WEBKIT2_FORM_DATABASE)
568 ewk_view_form_password_data_fill(m_view);
571 if (!suspendRequested)
574 suspendRequested = false;
576 if (!suspendedPainting) {
577 pageProxy->suspendPainting();
578 suspendedPainting = true;
580 if (!suspendedResources) {
581 pageProxy->suspendJavaScriptAndResource();
582 suspendedResources = true;
589 * informs load progress changed.
591 * Emits signal: "load,progress" with pointer to a double from 0.0 to 1.0.
593 void EwkViewImpl::informLoadProgress(double progress)
595 evas_object_smart_callback_call(m_view, "load,progress", &progress);
600 * informs view provisional load failed with error information.
602 * Emits signal: "load,provisional,failed" with pointer to Ewk_Error.
604 void EwkViewImpl::informProvisionalLoadFailed(Ewk_Error* error)
606 evas_object_smart_callback_call(m_view, "load,provisional,failed", error);
609 #if ENABLE(WAIT_UPVERSION)
610 #if USE(TILED_BACKING_STORE)
611 void EwkViewImpl::informLoadCommitted()
613 pageViewportController->didCommitLoad();
620 * informs view received redirect for provisional load.
622 * Emits signal: "load,provisional,redirect".
624 void EwkViewImpl::informProvisionalLoadRedirect()
627 evas_object_smart_callback_call(m_view, "load,provisional,redirect", 0);
632 * informs view provisional load started.
634 * Emits signal: "load,provisional,started".
636 void EwkViewImpl::informProvisionalLoadStarted()
639 evas_object_smart_callback_call(m_view, "load,started", 0);
642 #if ENABLE(TIZEN_DRAG_SUPPORT)
643 if (pageClient->isDragMode())
644 pageClient->setDragMode(false);
647 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
648 pageProxy->setLoadingFinished(false);
652 evas_object_smart_callback_call(m_view, "load,provisional,started", 0);
657 * informs that a navigation policy decision should be taken.
659 * Emits signal: "policy,decision,navigation".
661 void EwkViewImpl::informNavigationPolicyDecision(Ewk_Navigation_Policy_Decision* decision)
663 evas_object_smart_callback_call(m_view, "policy,decision,navigation", decision);
668 * informs that a new window policy decision should be taken.
670 * Emits signal: "policy,decision,new,window".
672 void EwkViewImpl::informNewWindowPolicyDecision(Ewk_Navigation_Policy_Decision* decision)
674 evas_object_smart_callback_call(m_view, "policy,decision,new,window", decision);
679 * Load was initiated for a resource in the view.
681 * Emits signal: "resource,request,new" with pointer to resource request.
683 void EwkViewImpl::informResourceLoadStarted(Ewk_Resource* resource, Ewk_Url_Request* request)
685 Ewk_Resource_Request resourceRequest = {resource, request, 0};
687 evas_object_smart_callback_call(m_view, "resource,request,new", &resourceRequest);
692 * Received a response to a resource load request in the view.
694 * Emits signal: "resource,request,response" with pointer to resource response.
696 void EwkViewImpl::informResourceLoadResponse(Ewk_Resource* resource, Ewk_Url_Response* response)
698 Ewk_Resource_Load_Response resourceLoadResponse = {resource, response};
699 evas_object_smart_callback_call(m_view, "resource,request,response", &resourceLoadResponse);
704 * Failed loading a resource in the view.
706 * Emits signal: "resource,request,finished" with pointer to the resource load error.
708 void EwkViewImpl::informResourceLoadFailed(Ewk_Resource* resource, Ewk_Error* error)
710 Ewk_Resource_Load_Error resourceLoadError = {resource, error};
711 evas_object_smart_callback_call(m_view, "resource,request,failed", &resourceLoadError);
716 * Finished loading a resource in the view.
718 * Emits signal: "resource,request,finished" with pointer to the resource.
720 void EwkViewImpl::informResourceLoadFinished(Ewk_Resource* resource)
722 evas_object_smart_callback_call(m_view, "resource,request,finished", resource);
727 * Request was sent for a resource in the view.
729 * Emits signal: "resource,request,sent" with pointer to resource request and possible redirect response.
731 void EwkViewImpl::informResourceRequestSent(Ewk_Resource* resource, Ewk_Url_Request* request, Ewk_Url_Response* redirectResponse)
733 Ewk_Resource_Request resourceRequest = {resource, request, redirectResponse};
734 evas_object_smart_callback_call(m_view, "resource,request,sent", &resourceRequest);
739 * The view title was changed by the frame loader.
741 * Emits signal: "title,changed" with pointer to new title string.
743 void EwkViewImpl::informTitleChange(const String& title)
745 evas_object_smart_callback_call(m_view, "title,changed", const_cast<char*>(title.utf8().data()));
751 void EwkViewImpl::informTooltipTextChange(const String& text)
754 evas_object_smart_callback_call(m_view, "tooltip,text,unset", 0);
756 evas_object_smart_callback_call(m_view, "tooltip,text,set", const_cast<char*>(text.utf8().data()));
762 * informs that the requested text was found.
764 * Emits signal: "text,found" with the number of matches.
766 void EwkViewImpl::informTextFound(unsigned matchCount)
768 evas_object_smart_callback_call(m_view, "text,found", &matchCount);
771 IntSize EwkViewImpl::size() const
774 evas_object_geometry_get(m_view, 0, 0, &width, &height);
775 return IntSize(width, height);
778 bool EwkViewImpl::isFocused() const
780 return evas_object_focus_get(m_view);
783 bool EwkViewImpl::isVisible() const
785 return evas_object_visible_get(m_view);
788 const char* EwkViewImpl::title() const
790 m_title = pageProxy->pageTitle().utf8().data();
797 * This function may return @c NULL.
799 InputMethodContextEfl* EwkViewImpl::inputMethodContext()
801 return m_inputMethodContext.get();
804 const char* EwkViewImpl::themePath() const
809 void EwkViewImpl::setThemePath(const char* theme)
811 if (m_theme != theme) {
813 pageProxy->setThemePath(theme);
817 const char* EwkViewImpl::customTextEncodingName() const
819 String customEncoding = pageProxy->customTextEncodingName();
820 if (customEncoding.isEmpty())
823 m_customEncoding = customEncoding.utf8().data();
825 return m_customEncoding;
828 void EwkViewImpl::setCustomTextEncodingName(const char* encoding)
830 m_customEncoding = encoding;
831 pageProxy->setCustomTextEncodingName(encoding ? encoding : String());
834 void EwkViewImpl::setMouseEventsEnabled(bool enabled)
836 if (m_mouseEventsEnabled == enabled)
839 m_mouseEventsEnabled = enabled;
841 Ewk_View_Smart_Data* sd = smartData();
842 evas_object_event_callback_add(m_view, EVAS_CALLBACK_MOUSE_DOWN, onMouseDown, sd);
843 evas_object_event_callback_add(m_view, EVAS_CALLBACK_MOUSE_UP, onMouseUp, sd);
844 evas_object_event_callback_add(m_view, EVAS_CALLBACK_MOUSE_MOVE, onMouseMove, sd);
846 evas_object_event_callback_del(m_view, EVAS_CALLBACK_MOUSE_DOWN, onMouseDown);
847 evas_object_event_callback_del(m_view, EVAS_CALLBACK_MOUSE_UP, onMouseUp);
848 evas_object_event_callback_del(m_view, EVAS_CALLBACK_MOUSE_MOVE, onMouseMove);
852 #if ENABLE(TOUCH_EVENTS)
853 void EwkViewImpl::setTouchEventsEnabled(bool enabled)
855 if (m_touchEventsEnabled == enabled)
858 m_touchEventsEnabled = enabled;
861 // FIXME: We have to connect touch callbacks with mouse and multi events
862 // because the Evas creates mouse events for first touch and multi events
863 // for second and third touches. Below codes should be fixed when the Evas
864 // supports the touch events.
865 // See https://bugs.webkit.org/show_bug.cgi?id=97785 for details.
866 Ewk_View_Smart_Data* sd = smartData();
867 evas_object_event_callback_add(m_view, EVAS_CALLBACK_MOUSE_DOWN, onTouchDown, sd);
868 evas_object_event_callback_add(m_view, EVAS_CALLBACK_MOUSE_UP, onTouchUp, sd);
869 evas_object_event_callback_add(m_view, EVAS_CALLBACK_MOUSE_MOVE, onTouchMove, sd);
870 evas_object_event_callback_add(m_view, EVAS_CALLBACK_MULTI_DOWN, onTouchDown, sd);
871 evas_object_event_callback_add(m_view, EVAS_CALLBACK_MULTI_UP, onTouchUp, sd);
872 evas_object_event_callback_add(m_view, EVAS_CALLBACK_MULTI_MOVE, onTouchMove, sd);
874 evas_object_event_callback_del(m_view, EVAS_CALLBACK_MOUSE_DOWN, onTouchDown);
875 evas_object_event_callback_del(m_view, EVAS_CALLBACK_MOUSE_UP, onTouchUp);
876 evas_object_event_callback_del(m_view, EVAS_CALLBACK_MOUSE_MOVE, onTouchMove);
877 evas_object_event_callback_del(m_view, EVAS_CALLBACK_MULTI_DOWN, onTouchDown);
878 evas_object_event_callback_del(m_view, EVAS_CALLBACK_MULTI_UP, onTouchUp);
879 evas_object_event_callback_del(m_view, EVAS_CALLBACK_MULTI_MOVE, onTouchMove);
886 * Update the view's favicon and emits a "icon,changed" signal if it has
889 * This function is called whenever the URL has changed or when the icon for
890 * the current page URL has changed.
892 void EwkViewImpl::informIconChange()
894 Ewk_Favicon_Database* iconDatabase = context->faviconDatabase();
895 ASSERT(iconDatabase);
897 m_faviconURL = ewk_favicon_database_icon_url_get(iconDatabase, m_url);
898 evas_object_smart_callback_call(m_view, "icon,changed", 0);
901 #if ENABLE(WEB_INTENTS)
904 * The view received a new intent request.
906 * Emits signal: "intent,request,new" with pointer to a Ewk_Intent.
908 void EwkViewImpl::informIntentRequest(Ewk_Intent* ewkIntent)
910 evas_object_smart_callback_call(m_view, "intent,request,new", ewkIntent);
914 #if ENABLE(WEB_INTENTS_TAG)
917 * The view received a new intent service registration.
919 * Emits signal: "intent,service,register" with pointer to a Ewk_Intent_Service.
921 void EwkViewImpl::informIntentServiceRegistration(Ewk_Intent_Service* ewkIntentService)
923 evas_object_smart_callback_call(m_view, "intent,service,register", ewkIntentService);
925 #endif // ENABLE(WEB_INTENTS_TAG)
927 #if USE(ACCELERATED_COMPOSITING)
928 bool EwkViewImpl::createGLSurface(const IntSize& viewSize)
930 Ewk_View_Smart_Data* sd = smartData();
932 Evas_GL_Config evasGlConfig = {
935 EVAS_GL_STENCIL_NONE,
936 EVAS_GL_OPTIONS_NONE,
937 EVAS_GL_MULTISAMPLE_NONE
940 ASSERT(!evasGlSurface);
941 evasGlSurface = evas_gl_surface_create(evasGl, &evasGlConfig, viewSize.width(), viewSize.height());
945 Evas_Native_Surface nativeSurface;
946 evas_gl_native_surface_get(evasGl, evasGlSurface, &nativeSurface);
947 evas_object_image_native_surface_set(sd->image, &nativeSurface);
952 bool EwkViewImpl::enterAcceleratedCompositingMode()
955 EINA_LOG_DOM_WARN(_ewk_log_dom, "Accelerated compositing mode already entered.");
959 Evas* evas = evas_object_evas_get(m_view);
960 evasGl = evas_gl_new(evas);
964 evasGlContext = evas_gl_context_create(evasGl, 0);
965 if (!evasGlContext) {
966 evas_gl_free(evasGl);
971 if (!createGLSurface(size())) {
972 evas_gl_context_destroy(evasGl, evasGlContext);
975 evas_gl_free(evasGl);
980 #if ENABLE(WAIT_UPVERSION)
981 pageViewportControllerClient->setRendererActive(true);
986 bool EwkViewImpl::exitAcceleratedCompositingMode()
988 EINA_SAFETY_ON_NULL_RETURN_VAL(evasGl, false);
991 evas_gl_surface_destroy(evasGl, evasGlSurface);
996 evas_gl_context_destroy(evasGl, evasGlContext);
1000 evas_gl_free(evasGl);
1007 #if ENABLE(INPUT_TYPE_COLOR)
1010 * Requests to show external color picker.
1012 void EwkViewImpl::requestColorPicker(int r, int g, int b, int a, WKColorPickerResultListenerRef listener)
1014 Ewk_View_Smart_Data* sd = smartData();
1015 EINA_SAFETY_ON_NULL_RETURN(sd->api->input_picker_color_request);
1017 m_colorPickerResultListener = listener;
1019 sd->api->input_picker_color_request(sd, r, g, b, a);
1024 * Requests to hide external color picker.
1026 void EwkViewImpl::dismissColorPicker()
1028 Ewk_View_Smart_Data* sd = smartData();
1029 EINA_SAFETY_ON_NULL_RETURN(sd->api->input_picker_color_dismiss);
1031 m_colorPickerResultListener.clear();
1033 sd->api->input_picker_color_dismiss(sd);
1039 * informs that the view's back / forward list has changed.
1041 * Emits signal: "back,forward,list,changed".
1043 void EwkViewImpl::informBackForwardListChange()
1045 evas_object_smart_callback_call(m_view, "back,forward,list,changed", 0);
1050 * Web process has crashed.
1052 * Emits signal: "webprocess,crashed" with pointer to crash handling boolean.
1054 void EwkViewImpl::informWebProcessCrashed()
1056 bool handled = false;
1057 evas_object_smart_callback_call(m_view, "webprocess,crashed", &handled);
1060 CString url = pageProxy->urlAtProcessExit().utf8();
1061 WARN("WARNING: The web process experienced a crash on '%s'.\n", url.data());
1063 // Display an error page
1064 ewk_view_html_string_load(m_view, "The web process has crashed.", 0, url.data());
1068 void EwkViewImpl::informContentsSizeChange(const IntSize& size)
1070 #if USE(COORDINATED_GRAPHICS)
1071 pageViewportControllerClient->didChangeContentsSize(size);
1077 COMPILE_ASSERT_MATCHING_ENUM(EWK_TEXT_DIRECTION_RIGHT_TO_LEFT, RTL);
1078 COMPILE_ASSERT_MATCHING_ENUM(EWK_TEXT_DIRECTION_LEFT_TO_RIGHT, LTR);
1080 #if ENABLE(TIZEN_MULTIPLE_SELECT)
1081 void EwkViewImpl::requestPopupMenu(WebPopupMenuProxyEfl* popupMenu, const IntRect& rect, TextDirection textDirection, double pageScaleFactor, const Vector<WebPopupItem>& items, int32_t selectedIndex, bool multiple)
1083 void EwkViewImpl::requestPopupMenu(WebPopupMenuProxyEfl* popupMenu, const IntRect& rect, TextDirection textDirection, double pageScaleFactor, const Vector<WebPopupItem>& items, int32_t selectedIndex)
1086 Ewk_View_Smart_Data* sd = smartData();
1091 #if ENABLE(TIZEN_MULTIPLE_SELECT)
1092 if (multiple ? !sd->api->multiple_popup_menu_show : !sd->api->popup_menu_show)
1094 if (!sd->api->popup_menu_show)
1099 ewk_view_popup_menu_close(m_view);
1100 popupMenuProxy = popupMenu;
1102 Eina_List* popupItems = 0;
1103 const size_t size = items.size();
1104 for (size_t i = 0; i < size; ++i)
1105 popupItems = eina_list_append(popupItems, Ewk_Popup_Menu_Item::create(items[i]).leakPtr());
1106 popupMenuItems = popupItems;
1108 #if ENABLE(TIZEN_WEBKIT2_POPUP_INTERNAL)
1109 #if ENABLE(TIZEN_MULTIPLE_SELECT)
1110 if (multiple ? sd->api->multiple_popup_menu_show(sd, rect, static_cast<Ewk_Text_Direction>(textDirection), pageScaleFactor, popupMenuItems)
1111 : sd->api->popup_menu_show(sd, rect, static_cast<Ewk_Text_Direction>(textDirection), pageScaleFactor, popupMenuItems, selectedIndex)) {
1113 if (sd->api->popup_menu_show(sd, rect, static_cast<Ewk_Text_Direction>(textDirection), pageScaleFactor, popupMenuItems, selectedIndex)) {
1115 /* maps.google.com generate mouse event in touch down without preventDefault.
1116 * So, popup menu is opend in touch down event and closed via fake mouse down
1117 * which generated by endTap.
1118 * In order to fix select of maps.google.com (based on touch behavior),
1119 * We should disable touch events when select popup is open.
1122 #if ENABLE(TIZEN_GESTURE)
1123 gestureClient->reset();
1125 ewk_view_touch_events_enabled_set(m_view, false);
1128 sd->api->popup_menu_show(sd, rect, static_cast<Ewk_Text_Direction>(textDirection), pageScaleFactor, popupItems, selectedIndex);
1134 * Calls a smart member function for javascript alert().
1136 void EwkViewImpl::requestJSAlertPopup(const WKEinaSharedString& message)
1138 Ewk_View_Smart_Data* sd = smartData();
1141 if (!sd->api->run_javascript_alert)
1144 sd->api->run_javascript_alert(sd, message);
1149 * Calls a smart member function for javascript confirm() and returns a value from the function. Returns false by default.
1151 bool EwkViewImpl::requestJSConfirmPopup(const WKEinaSharedString& message)
1153 Ewk_View_Smart_Data* sd = smartData();
1156 if (!sd->api->run_javascript_confirm)
1159 return sd->api->run_javascript_confirm(sd, message);
1164 * Calls a smart member function for javascript prompt() and returns a value from the function. Returns null string by default.
1166 WKEinaSharedString EwkViewImpl::requestJSPromptPopup(const WKEinaSharedString& message, const WKEinaSharedString& defaultValue)
1168 Ewk_View_Smart_Data* sd = smartData();
1171 if (!sd->api->run_javascript_prompt)
1172 return WKEinaSharedString();
1174 return WKEinaSharedString::adopt(sd->api->run_javascript_prompt(sd, message, defaultValue));
1177 #if ENABLE(SQL_DATABASE)
1180 * Calls exceeded_database_quota callback or falls back to default behavior returns default database quota.
1182 unsigned long long EwkViewImpl::informDatabaseQuotaReached(const String& databaseName, const String& displayName, unsigned long long currentQuota, unsigned long long currentOriginUsage, unsigned long long currentDatabaseUsage, unsigned long long expectedUsage)
1184 Ewk_View_Smart_Data* sd = smartData();
1187 static const unsigned long long defaultQuota = 5 * 1024 * 1204; // 5 MB
1188 if (sd->api->exceeded_database_quota)
1189 return sd->api->exceeded_database_quota(sd, databaseName.utf8().data(), displayName.utf8().data(), currentQuota, currentOriginUsage, currentDatabaseUsage, expectedUsage);
1191 return defaultQuota;
1197 * The url of view was changed by the frame loader.
1199 * Emits signal: "url,changed" with pointer to new url string.
1201 void EwkViewImpl::informURLChange()
1203 String activeURL = pageProxy->activeURL();
1204 if (activeURL.isEmpty())
1207 CString rawActiveURL = activeURL.utf8();
1208 if (m_url == rawActiveURL.data())
1211 m_url = rawActiveURL.data();
1212 const char* callbackArgument = static_cast<const char*>(m_url);
1213 evas_object_smart_callback_call(m_view, "url,changed", const_cast<char*>(callbackArgument));
1215 evas_object_smart_callback_call(m_view, "uri,changed", const_cast<char*>(callbackArgument));
1218 // Update the view's favicon.
1222 WKPageRef EwkViewImpl::createNewPage()
1224 Evas_Object* newEwkView = 0;
1225 evas_object_smart_callback_call(m_view, "create,window", &newEwkView);
1230 EwkViewImpl* newViewImpl = EwkViewImpl::fromEvasObject(newEwkView);
1231 ASSERT(newViewImpl);
1233 return static_cast<WKPageRef>(WKRetain(newViewImpl->page()));
1236 void EwkViewImpl::closePage()
1238 evas_object_smart_callback_call(m_view, "close,window", 0);
1241 void EwkViewImpl::onMouseDown(void* data, Evas*, Evas_Object*, void* eventInfo)
1243 Evas_Event_Mouse_Down* downEvent = static_cast<Evas_Event_Mouse_Down*>(eventInfo);
1244 Ewk_View_Smart_Data* sd = static_cast<Ewk_View_Smart_Data*>(data);
1245 EINA_SAFETY_ON_NULL_RETURN(sd->api);
1246 EINA_SAFETY_ON_NULL_RETURN(sd->api->mouse_down);
1247 sd->api->mouse_down(sd, downEvent);
1250 void EwkViewImpl::onMouseUp(void* data, Evas*, Evas_Object*, void* eventInfo)
1252 Evas_Event_Mouse_Up* upEvent = static_cast<Evas_Event_Mouse_Up*>(eventInfo);
1253 Ewk_View_Smart_Data* sd = static_cast<Ewk_View_Smart_Data*>(data);
1254 EINA_SAFETY_ON_NULL_RETURN(sd->api);
1255 EINA_SAFETY_ON_NULL_RETURN(sd->api->mouse_up);
1256 sd->api->mouse_up(sd, upEvent);
1259 void EwkViewImpl::onMouseMove(void* data, Evas*, Evas_Object*, void* eventInfo)
1261 Evas_Event_Mouse_Move* moveEvent = static_cast<Evas_Event_Mouse_Move*>(eventInfo);
1262 Ewk_View_Smart_Data* sd = static_cast<Ewk_View_Smart_Data*>(data);
1263 EINA_SAFETY_ON_NULL_RETURN(sd->api);
1264 EINA_SAFETY_ON_NULL_RETURN(sd->api->mouse_move);
1265 sd->api->mouse_move(sd, moveEvent);
1268 #if ENABLE(TOUCH_EVENTS)
1269 void EwkViewImpl::feedTouchEvents(Ewk_Touch_Event_Type type)
1271 Ewk_View_Smart_Data* sd = smartData();
1273 unsigned count = evas_touch_point_list_count(sd->base.evas);
1277 Eina_List* points = 0;
1278 for (unsigned i = 0; i < count; ++i) {
1279 Ewk_Touch_Point* point = new Ewk_Touch_Point;
1280 point->id = evas_touch_point_list_nth_id_get(sd->base.evas, i);
1281 evas_touch_point_list_nth_xy_get(sd->base.evas, i, &point->x, &point->y);
1282 point->state = evas_touch_point_list_nth_state_get(sd->base.evas, i);
1283 #if ENABLE(TOUCH_EVENTS) && ENABLE(TIZEN_GESTURE)
1284 if (type == EWK_TOUCH_CANCEL)
1285 point->state = EVAS_TOUCH_POINT_CANCEL;
1287 points = eina_list_append(points, point);
1290 ewk_view_feed_touch_event(m_view, type, points, evas_key_modifier_get(sd->base.evas));
1293 EINA_LIST_FREE(points, data)
1294 delete static_cast<Ewk_Touch_Point*>(data);
1297 void EwkViewImpl::onTouchDown(void* /* data */, Evas* /* canvas */, Evas_Object* ewkView, void* /* eventInfo */)
1299 EwkViewImpl* viewImpl = EwkViewImpl::fromEvasObject(ewkView);
1300 viewImpl->feedTouchEvents(EWK_TOUCH_START);
1303 void EwkViewImpl::onTouchUp(void* /* data */, Evas* /* canvas */, Evas_Object* ewkView, void* /* eventInfo */)
1305 EwkViewImpl* viewImpl = EwkViewImpl::fromEvasObject(ewkView);
1306 viewImpl->feedTouchEvents(EWK_TOUCH_END);
1309 void EwkViewImpl::onTouchMove(void* /* data */, Evas* /* canvas */, Evas_Object* ewkView, void* /* eventInfo */)
1311 EwkViewImpl* viewImpl = EwkViewImpl::fromEvasObject(ewkView);
1312 viewImpl->feedTouchEvents(EWK_TOUCH_MOVE);
1317 #if ENABLE(TIZEN_WEBKIT2_TILED_BACKING_STORE)
1318 AffineTransform EwkViewImpl::transformFromView() const
1320 AffineTransform transform;
1321 transform.scale(1 / m_scaleFactor);
1322 transform.translate(m_scrollPosition.x(), m_scrollPosition.y());
1327 AffineTransform EwkViewImpl::transformToView() const
1329 return transformFromView().inverse();
1333 AffineTransform EwkViewImpl::transformFromScene() const
1335 AffineTransform transform;
1337 #if USE(TILED_BACKING_STORE)
1338 // FIXME: We have to scale firstly unlike open source, because we are using scaled scroll position.
1339 //transform.translate(m_scrollPosition.x(), m_scrollPosition.y());
1340 //transform.scale(1 / m_scaleFactor);
1341 transform.scale(1 / m_scaleFactor);
1342 transform.translate(m_scrollPosition.x(), m_scrollPosition.y());
1345 Ewk_View_Smart_Data* sd = smartData();
1346 transform.translate(-sd->view.x, -sd->view.y);
1351 AffineTransform EwkViewImpl::transformToScene() const
1353 return transformFromScene().inverse();
1356 AffineTransform EwkViewImpl::transformToScreen() const
1358 AffineTransform transform;
1360 int windowGlobalX = 0;
1361 int windowGlobalY = 0;
1363 Ewk_View_Smart_Data* sd = smartData();
1366 Ecore_Evas* ecoreEvas = ecore_evas_ecore_evas_get(sd->base.evas);
1367 Ecore_X_Window window = ecore_evas_software_x11_window_get(ecoreEvas); // Returns 0 if none.
1369 int x, y; // x, y are relative to parent (in a reparenting window manager).
1371 ecore_x_window_geometry_get(window, &x, &y, 0, 0);
1374 window = ecore_x_window_parent_get(window);
1378 transform.translate(-sd->view.x, -sd->view.y);
1379 transform.translate(windowGlobalX, windowGlobalY);
1384 #if ENABLE(TIZEN_WEBKIT2_SEPERATE_LOAD_PROGRESS)
1385 void EwkViewImpl::informLoadProgressStarted()
1387 evas_object_smart_callback_call(m_view, "load,progress,started", 0);
1390 void EwkViewImpl::informLoadProgressFinished()
1392 evas_object_smart_callback_call(m_view, "load,progress,finished", 0);
1396 #if ENABLE(TIZEN_DATALIST_ELEMENT)
1397 void EwkViewImpl::deleteDataList()
1399 EINA_SAFETY_ON_NULL_RETURN(dataList);
1402 EINA_LIST_FREE(dataList, item)
1403 eina_stringshare_del(static_cast<char*>(item));
1409 #if ENABLE(TOUCH_EVENTS) && ENABLE(TIZEN_GESTURE)
1410 void EwkViewImpl::feedTouchEventsByType(Ewk_Touch_Event_Type type)
1412 feedTouchEvents(type);
1415 #endif //#if OS(TIZEN)