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);
565 #if ENABLE(TIZEN_WEBKIT2_FORM_DATABASE)
566 ewk_view_form_password_data_fill(m_view);
569 if (!suspendRequested)
572 suspendRequested = false;
574 if (!suspendedPainting) {
575 pageProxy->suspendPainting();
576 suspendedPainting = true;
578 if (!suspendedResources) {
579 pageProxy->suspendJavaScriptAndResource();
580 suspendedResources = true;
587 * informs load progress changed.
589 * Emits signal: "load,progress" with pointer to a double from 0.0 to 1.0.
591 void EwkViewImpl::informLoadProgress(double progress)
593 evas_object_smart_callback_call(m_view, "load,progress", &progress);
598 * informs view provisional load failed with error information.
600 * Emits signal: "load,provisional,failed" with pointer to Ewk_Error.
602 void EwkViewImpl::informProvisionalLoadFailed(Ewk_Error* error)
604 evas_object_smart_callback_call(m_view, "load,provisional,failed", error);
607 #if ENABLE(WAIT_UPVERSION)
608 #if USE(TILED_BACKING_STORE)
609 void EwkViewImpl::informLoadCommitted()
611 pageViewportController->didCommitLoad();
618 * informs view received redirect for provisional load.
620 * Emits signal: "load,provisional,redirect".
622 void EwkViewImpl::informProvisionalLoadRedirect()
625 evas_object_smart_callback_call(m_view, "load,provisional,redirect", 0);
630 * informs view provisional load started.
632 * Emits signal: "load,provisional,started".
634 void EwkViewImpl::informProvisionalLoadStarted()
637 evas_object_smart_callback_call(m_view, "load,started", 0);
640 #if ENABLE(TIZEN_DRAG_SUPPORT)
641 if (pageClient->isDragMode())
642 pageClient->setDragMode(false);
645 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
646 pageProxy->setLoadingFinished(false);
650 evas_object_smart_callback_call(m_view, "load,provisional,started", 0);
655 * informs that a navigation policy decision should be taken.
657 * Emits signal: "policy,decision,navigation".
659 void EwkViewImpl::informNavigationPolicyDecision(Ewk_Navigation_Policy_Decision* decision)
661 evas_object_smart_callback_call(m_view, "policy,decision,navigation", decision);
666 * informs that a new window policy decision should be taken.
668 * Emits signal: "policy,decision,new,window".
670 void EwkViewImpl::informNewWindowPolicyDecision(Ewk_Navigation_Policy_Decision* decision)
672 evas_object_smart_callback_call(m_view, "policy,decision,new,window", decision);
677 * Load was initiated for a resource in the view.
679 * Emits signal: "resource,request,new" with pointer to resource request.
681 void EwkViewImpl::informResourceLoadStarted(Ewk_Resource* resource, Ewk_Url_Request* request)
683 Ewk_Resource_Request resourceRequest = {resource, request, 0};
685 evas_object_smart_callback_call(m_view, "resource,request,new", &resourceRequest);
690 * Received a response to a resource load request in the view.
692 * Emits signal: "resource,request,response" with pointer to resource response.
694 void EwkViewImpl::informResourceLoadResponse(Ewk_Resource* resource, Ewk_Url_Response* response)
696 Ewk_Resource_Load_Response resourceLoadResponse = {resource, response};
697 evas_object_smart_callback_call(m_view, "resource,request,response", &resourceLoadResponse);
702 * Failed loading a resource in the view.
704 * Emits signal: "resource,request,finished" with pointer to the resource load error.
706 void EwkViewImpl::informResourceLoadFailed(Ewk_Resource* resource, Ewk_Error* error)
708 Ewk_Resource_Load_Error resourceLoadError = {resource, error};
709 evas_object_smart_callback_call(m_view, "resource,request,failed", &resourceLoadError);
714 * Finished loading a resource in the view.
716 * Emits signal: "resource,request,finished" with pointer to the resource.
718 void EwkViewImpl::informResourceLoadFinished(Ewk_Resource* resource)
720 evas_object_smart_callback_call(m_view, "resource,request,finished", resource);
725 * Request was sent for a resource in the view.
727 * Emits signal: "resource,request,sent" with pointer to resource request and possible redirect response.
729 void EwkViewImpl::informResourceRequestSent(Ewk_Resource* resource, Ewk_Url_Request* request, Ewk_Url_Response* redirectResponse)
731 Ewk_Resource_Request resourceRequest = {resource, request, redirectResponse};
732 evas_object_smart_callback_call(m_view, "resource,request,sent", &resourceRequest);
737 * The view title was changed by the frame loader.
739 * Emits signal: "title,changed" with pointer to new title string.
741 void EwkViewImpl::informTitleChange(const String& title)
743 evas_object_smart_callback_call(m_view, "title,changed", const_cast<char*>(title.utf8().data()));
749 void EwkViewImpl::informTooltipTextChange(const String& text)
752 evas_object_smart_callback_call(m_view, "tooltip,text,unset", 0);
754 evas_object_smart_callback_call(m_view, "tooltip,text,set", const_cast<char*>(text.utf8().data()));
760 * informs that the requested text was found.
762 * Emits signal: "text,found" with the number of matches.
764 void EwkViewImpl::informTextFound(unsigned matchCount)
766 evas_object_smart_callback_call(m_view, "text,found", &matchCount);
769 IntSize EwkViewImpl::size() const
772 evas_object_geometry_get(m_view, 0, 0, &width, &height);
773 return IntSize(width, height);
776 bool EwkViewImpl::isFocused() const
778 return evas_object_focus_get(m_view);
781 bool EwkViewImpl::isVisible() const
783 return evas_object_visible_get(m_view);
786 const char* EwkViewImpl::title() const
788 m_title = pageProxy->pageTitle().utf8().data();
795 * This function may return @c NULL.
797 InputMethodContextEfl* EwkViewImpl::inputMethodContext()
799 return m_inputMethodContext.get();
802 const char* EwkViewImpl::themePath() const
807 void EwkViewImpl::setThemePath(const char* theme)
809 if (m_theme != theme) {
811 pageProxy->setThemePath(theme);
815 const char* EwkViewImpl::customTextEncodingName() const
817 String customEncoding = pageProxy->customTextEncodingName();
818 if (customEncoding.isEmpty())
821 m_customEncoding = customEncoding.utf8().data();
823 return m_customEncoding;
826 void EwkViewImpl::setCustomTextEncodingName(const char* encoding)
828 m_customEncoding = encoding;
829 pageProxy->setCustomTextEncodingName(encoding ? encoding : String());
832 void EwkViewImpl::setMouseEventsEnabled(bool enabled)
834 if (m_mouseEventsEnabled == enabled)
837 m_mouseEventsEnabled = enabled;
839 Ewk_View_Smart_Data* sd = smartData();
840 evas_object_event_callback_add(m_view, EVAS_CALLBACK_MOUSE_DOWN, onMouseDown, sd);
841 evas_object_event_callback_add(m_view, EVAS_CALLBACK_MOUSE_UP, onMouseUp, sd);
842 evas_object_event_callback_add(m_view, EVAS_CALLBACK_MOUSE_MOVE, onMouseMove, sd);
844 evas_object_event_callback_del(m_view, EVAS_CALLBACK_MOUSE_DOWN, onMouseDown);
845 evas_object_event_callback_del(m_view, EVAS_CALLBACK_MOUSE_UP, onMouseUp);
846 evas_object_event_callback_del(m_view, EVAS_CALLBACK_MOUSE_MOVE, onMouseMove);
850 #if ENABLE(TOUCH_EVENTS)
851 void EwkViewImpl::setTouchEventsEnabled(bool enabled)
853 if (m_touchEventsEnabled == enabled)
856 m_touchEventsEnabled = enabled;
859 // FIXME: We have to connect touch callbacks with mouse and multi events
860 // because the Evas creates mouse events for first touch and multi events
861 // for second and third touches. Below codes should be fixed when the Evas
862 // supports the touch events.
863 // See https://bugs.webkit.org/show_bug.cgi?id=97785 for details.
864 Ewk_View_Smart_Data* sd = smartData();
865 evas_object_event_callback_add(m_view, EVAS_CALLBACK_MOUSE_DOWN, onTouchDown, sd);
866 evas_object_event_callback_add(m_view, EVAS_CALLBACK_MOUSE_UP, onTouchUp, sd);
867 evas_object_event_callback_add(m_view, EVAS_CALLBACK_MOUSE_MOVE, onTouchMove, sd);
868 evas_object_event_callback_add(m_view, EVAS_CALLBACK_MULTI_DOWN, onTouchDown, sd);
869 evas_object_event_callback_add(m_view, EVAS_CALLBACK_MULTI_UP, onTouchUp, sd);
870 evas_object_event_callback_add(m_view, EVAS_CALLBACK_MULTI_MOVE, onTouchMove, sd);
872 evas_object_event_callback_del(m_view, EVAS_CALLBACK_MOUSE_DOWN, onTouchDown);
873 evas_object_event_callback_del(m_view, EVAS_CALLBACK_MOUSE_UP, onTouchUp);
874 evas_object_event_callback_del(m_view, EVAS_CALLBACK_MOUSE_MOVE, onTouchMove);
875 evas_object_event_callback_del(m_view, EVAS_CALLBACK_MULTI_DOWN, onTouchDown);
876 evas_object_event_callback_del(m_view, EVAS_CALLBACK_MULTI_UP, onTouchUp);
877 evas_object_event_callback_del(m_view, EVAS_CALLBACK_MULTI_MOVE, onTouchMove);
884 * Update the view's favicon and emits a "icon,changed" signal if it has
887 * This function is called whenever the URL has changed or when the icon for
888 * the current page URL has changed.
890 void EwkViewImpl::informIconChange()
892 Ewk_Favicon_Database* iconDatabase = context->faviconDatabase();
893 ASSERT(iconDatabase);
895 m_faviconURL = ewk_favicon_database_icon_url_get(iconDatabase, m_url);
896 evas_object_smart_callback_call(m_view, "icon,changed", 0);
899 #if ENABLE(WEB_INTENTS)
902 * The view received a new intent request.
904 * Emits signal: "intent,request,new" with pointer to a Ewk_Intent.
906 void EwkViewImpl::informIntentRequest(Ewk_Intent* ewkIntent)
908 evas_object_smart_callback_call(m_view, "intent,request,new", ewkIntent);
912 #if ENABLE(WEB_INTENTS_TAG)
915 * The view received a new intent service registration.
917 * Emits signal: "intent,service,register" with pointer to a Ewk_Intent_Service.
919 void EwkViewImpl::informIntentServiceRegistration(Ewk_Intent_Service* ewkIntentService)
921 evas_object_smart_callback_call(m_view, "intent,service,register", ewkIntentService);
923 #endif // ENABLE(WEB_INTENTS_TAG)
925 #if USE(ACCELERATED_COMPOSITING)
926 bool EwkViewImpl::createGLSurface(const IntSize& viewSize)
928 Ewk_View_Smart_Data* sd = smartData();
930 Evas_GL_Config evasGlConfig = {
933 EVAS_GL_STENCIL_NONE,
934 EVAS_GL_OPTIONS_NONE,
935 EVAS_GL_MULTISAMPLE_NONE
938 ASSERT(!evasGlSurface);
939 evasGlSurface = evas_gl_surface_create(evasGl, &evasGlConfig, viewSize.width(), viewSize.height());
943 Evas_Native_Surface nativeSurface;
944 evas_gl_native_surface_get(evasGl, evasGlSurface, &nativeSurface);
945 evas_object_image_native_surface_set(sd->image, &nativeSurface);
950 bool EwkViewImpl::enterAcceleratedCompositingMode()
953 EINA_LOG_DOM_WARN(_ewk_log_dom, "Accelerated compositing mode already entered.");
957 Evas* evas = evas_object_evas_get(m_view);
958 evasGl = evas_gl_new(evas);
962 evasGlContext = evas_gl_context_create(evasGl, 0);
963 if (!evasGlContext) {
964 evas_gl_free(evasGl);
969 if (!createGLSurface(size())) {
970 evas_gl_context_destroy(evasGl, evasGlContext);
973 evas_gl_free(evasGl);
978 #if ENABLE(WAIT_UPVERSION)
979 pageViewportControllerClient->setRendererActive(true);
984 bool EwkViewImpl::exitAcceleratedCompositingMode()
986 EINA_SAFETY_ON_NULL_RETURN_VAL(evasGl, false);
989 evas_gl_surface_destroy(evasGl, evasGlSurface);
994 evas_gl_context_destroy(evasGl, evasGlContext);
998 evas_gl_free(evasGl);
1005 #if ENABLE(INPUT_TYPE_COLOR)
1008 * Requests to show external color picker.
1010 void EwkViewImpl::requestColorPicker(int r, int g, int b, int a, WKColorPickerResultListenerRef listener)
1012 Ewk_View_Smart_Data* sd = smartData();
1013 EINA_SAFETY_ON_NULL_RETURN(sd->api->input_picker_color_request);
1015 m_colorPickerResultListener = listener;
1017 sd->api->input_picker_color_request(sd, r, g, b, a);
1022 * Requests to hide external color picker.
1024 void EwkViewImpl::dismissColorPicker()
1026 Ewk_View_Smart_Data* sd = smartData();
1027 EINA_SAFETY_ON_NULL_RETURN(sd->api->input_picker_color_dismiss);
1029 m_colorPickerResultListener.clear();
1031 sd->api->input_picker_color_dismiss(sd);
1037 * informs that the view's back / forward list has changed.
1039 * Emits signal: "back,forward,list,changed".
1041 void EwkViewImpl::informBackForwardListChange()
1043 evas_object_smart_callback_call(m_view, "back,forward,list,changed", 0);
1048 * Web process has crashed.
1050 * Emits signal: "webprocess,crashed" with pointer to crash handling boolean.
1052 void EwkViewImpl::informWebProcessCrashed()
1054 bool handled = false;
1055 evas_object_smart_callback_call(m_view, "webprocess,crashed", &handled);
1058 CString url = pageProxy->urlAtProcessExit().utf8();
1059 WARN("WARNING: The web process experienced a crash on '%s'.\n", url.data());
1061 // Display an error page
1062 ewk_view_html_string_load(m_view, "The web process has crashed.", 0, url.data());
1066 void EwkViewImpl::informContentsSizeChange(const IntSize& size)
1068 #if USE(COORDINATED_GRAPHICS)
1069 pageViewportControllerClient->didChangeContentsSize(size);
1075 COMPILE_ASSERT_MATCHING_ENUM(EWK_TEXT_DIRECTION_RIGHT_TO_LEFT, RTL);
1076 COMPILE_ASSERT_MATCHING_ENUM(EWK_TEXT_DIRECTION_LEFT_TO_RIGHT, LTR);
1078 #if ENABLE(TIZEN_MULTIPLE_SELECT)
1079 void EwkViewImpl::requestPopupMenu(WebPopupMenuProxyEfl* popupMenu, const IntRect& rect, TextDirection textDirection, double pageScaleFactor, const Vector<WebPopupItem>& items, int32_t selectedIndex, bool multiple)
1081 void EwkViewImpl::requestPopupMenu(WebPopupMenuProxyEfl* popupMenu, const IntRect& rect, TextDirection textDirection, double pageScaleFactor, const Vector<WebPopupItem>& items, int32_t selectedIndex)
1084 Ewk_View_Smart_Data* sd = smartData();
1089 #if ENABLE(TIZEN_MULTIPLE_SELECT)
1090 if (multiple ? !sd->api->multiple_popup_menu_show : !sd->api->popup_menu_show)
1092 if (!sd->api->popup_menu_show)
1097 ewk_view_popup_menu_close(m_view);
1098 popupMenuProxy = popupMenu;
1100 Eina_List* popupItems = 0;
1101 const size_t size = items.size();
1102 for (size_t i = 0; i < size; ++i)
1103 popupItems = eina_list_append(popupItems, Ewk_Popup_Menu_Item::create(items[i]).leakPtr());
1104 popupMenuItems = popupItems;
1106 #if ENABLE(TIZEN_WEBKIT2_POPUP_INTERNAL)
1107 #if ENABLE(TIZEN_MULTIPLE_SELECT)
1108 if (multiple ? sd->api->multiple_popup_menu_show(sd, rect, static_cast<Ewk_Text_Direction>(textDirection), pageScaleFactor, popupMenuItems)
1109 : sd->api->popup_menu_show(sd, rect, static_cast<Ewk_Text_Direction>(textDirection), pageScaleFactor, popupMenuItems, selectedIndex)) {
1111 if (sd->api->popup_menu_show(sd, rect, static_cast<Ewk_Text_Direction>(textDirection), pageScaleFactor, popupMenuItems, selectedIndex)) {
1113 /* maps.google.com generate mouse event in touch down without preventDefault.
1114 * So, popup menu is opend in touch down event and closed via fake mouse down
1115 * which generated by endTap.
1116 * In order to fix select of maps.google.com (based on touch behavior),
1117 * We should disable touch events when select popup is open.
1120 #if ENABLE(TIZEN_GESTURE)
1121 gestureClient->reset();
1123 ewk_view_touch_events_enabled_set(m_view, false);
1126 sd->api->popup_menu_show(sd, rect, static_cast<Ewk_Text_Direction>(textDirection), pageScaleFactor, popupItems, selectedIndex);
1132 * Calls a smart member function for javascript alert().
1134 void EwkViewImpl::requestJSAlertPopup(const WKEinaSharedString& message)
1136 Ewk_View_Smart_Data* sd = smartData();
1139 if (!sd->api->run_javascript_alert)
1142 sd->api->run_javascript_alert(sd, message);
1147 * Calls a smart member function for javascript confirm() and returns a value from the function. Returns false by default.
1149 bool EwkViewImpl::requestJSConfirmPopup(const WKEinaSharedString& message)
1151 Ewk_View_Smart_Data* sd = smartData();
1154 if (!sd->api->run_javascript_confirm)
1157 return sd->api->run_javascript_confirm(sd, message);
1162 * Calls a smart member function for javascript prompt() and returns a value from the function. Returns null string by default.
1164 WKEinaSharedString EwkViewImpl::requestJSPromptPopup(const WKEinaSharedString& message, const WKEinaSharedString& defaultValue)
1166 Ewk_View_Smart_Data* sd = smartData();
1169 if (!sd->api->run_javascript_prompt)
1170 return WKEinaSharedString();
1172 return WKEinaSharedString::adopt(sd->api->run_javascript_prompt(sd, message, defaultValue));
1175 #if ENABLE(SQL_DATABASE)
1178 * Calls exceeded_database_quota callback or falls back to default behavior returns default database quota.
1180 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)
1182 Ewk_View_Smart_Data* sd = smartData();
1185 static const unsigned long long defaultQuota = 5 * 1024 * 1204; // 5 MB
1186 if (sd->api->exceeded_database_quota)
1187 return sd->api->exceeded_database_quota(sd, databaseName.utf8().data(), displayName.utf8().data(), currentQuota, currentOriginUsage, currentDatabaseUsage, expectedUsage);
1189 return defaultQuota;
1195 * The url of view was changed by the frame loader.
1197 * Emits signal: "url,changed" with pointer to new url string.
1199 void EwkViewImpl::informURLChange()
1201 String activeURL = pageProxy->activeURL();
1202 if (activeURL.isEmpty())
1205 CString rawActiveURL = activeURL.utf8();
1206 if (m_url == rawActiveURL.data())
1209 m_url = rawActiveURL.data();
1210 const char* callbackArgument = static_cast<const char*>(m_url);
1211 evas_object_smart_callback_call(m_view, "url,changed", const_cast<char*>(callbackArgument));
1213 evas_object_smart_callback_call(m_view, "uri,changed", const_cast<char*>(callbackArgument));
1216 // Update the view's favicon.
1220 WKPageRef EwkViewImpl::createNewPage()
1222 Evas_Object* newEwkView = 0;
1223 evas_object_smart_callback_call(m_view, "create,window", &newEwkView);
1228 EwkViewImpl* newViewImpl = EwkViewImpl::fromEvasObject(newEwkView);
1229 ASSERT(newViewImpl);
1231 return static_cast<WKPageRef>(WKRetain(newViewImpl->page()));
1234 void EwkViewImpl::closePage()
1236 evas_object_smart_callback_call(m_view, "close,window", 0);
1239 void EwkViewImpl::onMouseDown(void* data, Evas*, Evas_Object*, void* eventInfo)
1241 Evas_Event_Mouse_Down* downEvent = static_cast<Evas_Event_Mouse_Down*>(eventInfo);
1242 Ewk_View_Smart_Data* sd = static_cast<Ewk_View_Smart_Data*>(data);
1243 EINA_SAFETY_ON_NULL_RETURN(sd->api);
1244 EINA_SAFETY_ON_NULL_RETURN(sd->api->mouse_down);
1245 sd->api->mouse_down(sd, downEvent);
1248 void EwkViewImpl::onMouseUp(void* data, Evas*, Evas_Object*, void* eventInfo)
1250 Evas_Event_Mouse_Up* upEvent = static_cast<Evas_Event_Mouse_Up*>(eventInfo);
1251 Ewk_View_Smart_Data* sd = static_cast<Ewk_View_Smart_Data*>(data);
1252 EINA_SAFETY_ON_NULL_RETURN(sd->api);
1253 EINA_SAFETY_ON_NULL_RETURN(sd->api->mouse_up);
1254 sd->api->mouse_up(sd, upEvent);
1257 void EwkViewImpl::onMouseMove(void* data, Evas*, Evas_Object*, void* eventInfo)
1259 Evas_Event_Mouse_Move* moveEvent = static_cast<Evas_Event_Mouse_Move*>(eventInfo);
1260 Ewk_View_Smart_Data* sd = static_cast<Ewk_View_Smart_Data*>(data);
1261 EINA_SAFETY_ON_NULL_RETURN(sd->api);
1262 EINA_SAFETY_ON_NULL_RETURN(sd->api->mouse_move);
1263 sd->api->mouse_move(sd, moveEvent);
1266 #if ENABLE(TOUCH_EVENTS)
1267 void EwkViewImpl::feedTouchEvents(Ewk_Touch_Event_Type type)
1269 Ewk_View_Smart_Data* sd = smartData();
1271 unsigned count = evas_touch_point_list_count(sd->base.evas);
1275 Eina_List* points = 0;
1276 for (unsigned i = 0; i < count; ++i) {
1277 Ewk_Touch_Point* point = new Ewk_Touch_Point;
1278 point->id = evas_touch_point_list_nth_id_get(sd->base.evas, i);
1279 evas_touch_point_list_nth_xy_get(sd->base.evas, i, &point->x, &point->y);
1280 point->state = evas_touch_point_list_nth_state_get(sd->base.evas, i);
1281 #if ENABLE(TOUCH_EVENTS) && ENABLE(TIZEN_GESTURE)
1282 if (type == EWK_TOUCH_CANCEL)
1283 point->state = EVAS_TOUCH_POINT_CANCEL;
1285 points = eina_list_append(points, point);
1288 ewk_view_feed_touch_event(m_view, type, points, evas_key_modifier_get(sd->base.evas));
1291 EINA_LIST_FREE(points, data)
1292 delete static_cast<Ewk_Touch_Point*>(data);
1295 void EwkViewImpl::onTouchDown(void* /* data */, Evas* /* canvas */, Evas_Object* ewkView, void* /* eventInfo */)
1297 EwkViewImpl* viewImpl = EwkViewImpl::fromEvasObject(ewkView);
1298 viewImpl->feedTouchEvents(EWK_TOUCH_START);
1301 void EwkViewImpl::onTouchUp(void* /* data */, Evas* /* canvas */, Evas_Object* ewkView, void* /* eventInfo */)
1303 EwkViewImpl* viewImpl = EwkViewImpl::fromEvasObject(ewkView);
1304 viewImpl->feedTouchEvents(EWK_TOUCH_END);
1307 void EwkViewImpl::onTouchMove(void* /* data */, Evas* /* canvas */, Evas_Object* ewkView, void* /* eventInfo */)
1309 EwkViewImpl* viewImpl = EwkViewImpl::fromEvasObject(ewkView);
1310 viewImpl->feedTouchEvents(EWK_TOUCH_MOVE);
1315 #if ENABLE(TIZEN_WEBKIT2_TILED_BACKING_STORE)
1316 AffineTransform EwkViewImpl::transformFromView() const
1318 AffineTransform transform;
1319 transform.scale(1 / m_scaleFactor);
1320 transform.translate(m_scrollPosition.x(), m_scrollPosition.y());
1325 AffineTransform EwkViewImpl::transformToView() const
1327 return transformFromView().inverse();
1331 AffineTransform EwkViewImpl::transformFromScene() const
1333 AffineTransform transform;
1335 #if USE(TILED_BACKING_STORE)
1336 // FIXME: We have to scale firstly unlike open source, because we are using scaled scroll position.
1337 //transform.translate(m_scrollPosition.x(), m_scrollPosition.y());
1338 //transform.scale(1 / m_scaleFactor);
1339 transform.scale(1 / m_scaleFactor);
1340 transform.translate(m_scrollPosition.x(), m_scrollPosition.y());
1343 Ewk_View_Smart_Data* sd = smartData();
1344 transform.translate(-sd->view.x, -sd->view.y);
1349 AffineTransform EwkViewImpl::transformToScene() const
1351 return transformFromScene().inverse();
1354 AffineTransform EwkViewImpl::transformToScreen() const
1356 AffineTransform transform;
1358 int windowGlobalX = 0;
1359 int windowGlobalY = 0;
1361 Ewk_View_Smart_Data* sd = smartData();
1364 Ecore_Evas* ecoreEvas = ecore_evas_ecore_evas_get(sd->base.evas);
1365 Ecore_X_Window window = ecore_evas_software_x11_window_get(ecoreEvas); // Returns 0 if none.
1367 int x, y; // x, y are relative to parent (in a reparenting window manager).
1369 ecore_x_window_geometry_get(window, &x, &y, 0, 0);
1372 window = ecore_x_window_parent_get(window);
1376 transform.translate(-sd->view.x, -sd->view.y);
1377 transform.translate(windowGlobalX, windowGlobalY);
1382 #if ENABLE(TIZEN_WEBKIT2_SEPERATE_LOAD_PROGRESS)
1383 void EwkViewImpl::informLoadProgressStarted()
1385 evas_object_smart_callback_call(m_view, "load,progress,started", 0);
1388 void EwkViewImpl::informLoadProgressFinished()
1390 evas_object_smart_callback_call(m_view, "load,progress,finished", 0);
1394 #if ENABLE(TIZEN_DATALIST_ELEMENT)
1395 void EwkViewImpl::deleteDataList()
1397 EINA_SAFETY_ON_NULL_RETURN(dataList);
1400 EINA_LIST_FREE(dataList, item)
1401 eina_stringshare_del(static_cast<char*>(item));
1407 #if ENABLE(TOUCH_EVENTS) && ENABLE(TIZEN_GESTURE)
1408 void EwkViewImpl::feedTouchEventsByType(Ewk_Touch_Event_Type type)
1410 feedTouchEvents(type);
1413 #endif //#if OS(TIZEN)