2 * Copyright (C) 2006 Zack Rusin <zack@kde.org>
3 * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
4 * Copyright (C) 2008 Kenneth Rohde Christiansen
5 * Copyright (C) 2008 Diego Gonzalez
6 * Copyright (C) 2009-2010 ProFUSION embedded systems
7 * Copyright (C) 2009-2010 Samsung Electronics
8 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
10 * All rights reserved.
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
21 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
22 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
25 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
29 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 #include "ChromeClientEfl.h"
37 #if ENABLE(SQL_DATABASE)
39 #include "DatabaseDetails.h"
40 #include "DatabaseTracker.h"
43 #include "FileChooser.h"
44 #include "FileIconLoader.h"
45 #include "FloatRect.h"
46 #include "FrameLoader.h"
47 #include "FrameLoaderClientEfl.h"
48 #include "HitTestResult.h"
51 #include "NavigationAction.h"
52 #if ENABLE(NOTIFICATIONS)
53 #include "NotificationPresenterClientEfl.h"
55 #include "NotImplemented.h"
56 #include "PlatformString.h"
57 #include "PopupMenuEfl.h"
58 #include "SearchPopupMenuEfl.h"
59 #include "SecurityOrigin.h"
60 #include "ViewportArguments.h"
61 #include "WindowFeatures.h"
62 #include "ewk_private.h"
63 #include <Ecore_Evas.h>
65 #include <wtf/text/CString.h>
67 #if ENABLE(TIZEN_MEDIA_QUERY)
71 #if ENABLE(TIZEN_GEOLOCATION)
72 #include "Geolocation.h"
74 ewk_geolocation_permission_dialog_show_callback g_geolocation_permission_dialog_show_callback = 0;
77 using namespace WebCore;
79 static inline Evas_Object* kit(Frame* frame)
84 FrameLoaderClientEfl* client = static_cast<FrameLoaderClientEfl*>(frame->loader()->client());
85 return client ? client->webFrame() : 0;
90 ChromeClientEfl::ChromeClientEfl(Evas_Object* view)
96 ChromeClientEfl::~ChromeClientEfl()
100 void ChromeClientEfl::chromeDestroyed()
105 void ChromeClientEfl::focusedNodeChanged(Node*)
110 void ChromeClientEfl::focusedFrameChanged(Frame*)
114 FloatRect ChromeClientEfl::windowRect()
119 ee = ecore_evas_ecore_evas_get(evas_object_evas_get(m_view));
120 ecore_evas_geometry_get(ee, &x, &y, &w, &h);
121 return FloatRect(x, y, w, h);
124 void ChromeClientEfl::setWindowRect(const FloatRect& rect)
126 if (!ewk_view_setting_enable_auto_resize_window_get(m_view))
130 IntRect intrect = IntRect(rect);
132 ee = ecore_evas_ecore_evas_get(evas_object_evas_get(m_view));
133 ecore_evas_move(ee, intrect.x(), intrect.y());
134 ecore_evas_resize(ee, intrect.width(), intrect.height());
137 FloatRect ChromeClientEfl::pageRect()
139 return ewk_view_page_rect_get(m_view);
142 #if ENABLE(TIZEN_INNER_SCREEN_RECT)
143 FloatRect ChromeClientEfl::innerScreenRect()
146 evas_object_geometry_get(m_view, &x, &y, &w, &h);
147 return FloatRect(x, y, w, h);
151 #if ENABLE(TIZEN_MEDIA_QUERY)
152 int ChromeClientEfl::getDPI()
154 return ecore_x_dpi_get();
158 void ChromeClientEfl::focus()
160 evas_object_focus_set(m_view, EINA_TRUE);
163 void ChromeClientEfl::unfocus()
165 evas_object_focus_set(m_view, EINA_FALSE);
168 #if ENABLE(TIZEN_FORM_SUBMIT_SUPPORT)
169 Page* ChromeClientEfl::createWindow(Frame* frame, const FrameLoadRequest& frameLoadRequest, const WindowFeatures& features, const NavigationAction& action)
171 Page* ChromeClientEfl::createWindow(Frame*, const FrameLoadRequest& frameLoadRequest, const WindowFeatures& features, const NavigationAction&)
174 #if ENABLE(TIZEN_FORM_SUBMIT_SUPPORT)
175 Evas_Object* newView = ewk_view_window_create(m_view, frame, EINA_TRUE, EINA_FALSE, &features, action, frameLoadRequest.frameName());
177 Evas_Object* newView = ewk_view_window_create(m_view, frame, EINA_TRUE, &features);
182 return ewk_view_core_page_get(newView);
185 void ChromeClientEfl::show()
187 ewk_view_ready(m_view);
190 bool ChromeClientEfl::canRunModal()
196 void ChromeClientEfl::runModal()
201 void ChromeClientEfl::setToolbarsVisible(bool visible)
203 ewk_view_toolbars_visible_set(m_view, visible);
206 bool ChromeClientEfl::toolbarsVisible()
210 ewk_view_toolbars_visible_get(m_view, &visible);
214 void ChromeClientEfl::setStatusbarVisible(bool visible)
216 ewk_view_statusbar_visible_set(m_view, visible);
219 bool ChromeClientEfl::statusbarVisible()
223 ewk_view_statusbar_visible_get(m_view, &visible);
227 void ChromeClientEfl::setScrollbarsVisible(bool visible)
229 ewk_view_scrollbars_visible_set(m_view, visible);
232 bool ChromeClientEfl::scrollbarsVisible()
236 ewk_view_scrollbars_visible_get(m_view, &visible);
240 void ChromeClientEfl::setMenubarVisible(bool visible)
242 ewk_view_menubar_visible_set(m_view, visible);
245 bool ChromeClientEfl::menubarVisible()
249 ewk_view_menubar_visible_get(m_view, &visible);
253 void ChromeClientEfl::createSelectPopup(PopupMenuClient* client, int selected, const IntRect& rect)
255 ewk_view_popup_new(m_view, client, selected, rect);
258 bool ChromeClientEfl::destroySelectPopup()
260 return ewk_view_popup_destroy(m_view);
263 void ChromeClientEfl::setResizable(bool)
268 void ChromeClientEfl::closeWindowSoon()
270 ewk_view_window_close(m_view);
273 bool ChromeClientEfl::canTakeFocus(FocusDirection coreDirection)
275 // This is called when cycling through links/focusable objects and we
276 // reach the last focusable object.
277 ASSERT(coreDirection == FocusDirectionForward || coreDirection == FocusDirectionBackward);
279 Ewk_Focus_Direction direction = static_cast<Ewk_Focus_Direction>(coreDirection);
281 return !ewk_view_focus_can_cycle(m_view, direction);
284 void ChromeClientEfl::takeFocus(FocusDirection)
289 bool ChromeClientEfl::canRunBeforeUnloadConfirmPanel()
294 bool ChromeClientEfl::runBeforeUnloadConfirmPanel(const String& message, Frame* frame)
296 return runJavaScriptConfirm(frame, message);
299 void ChromeClientEfl::addMessageToConsole(MessageSource, MessageType, MessageLevel, const String& message,
300 unsigned int lineNumber, const String& sourceID)
302 ewk_view_add_console_message(m_view, message.utf8().data(), lineNumber, sourceID.utf8().data());
305 void ChromeClientEfl::runJavaScriptAlert(Frame* frame, const String& message)
307 ewk_view_run_javascript_alert(m_view, kit(frame), message.utf8().data());
310 bool ChromeClientEfl::runJavaScriptConfirm(Frame* frame, const String& message)
312 return ewk_view_run_javascript_confirm(m_view, kit(frame), message.utf8().data());
315 bool ChromeClientEfl::runJavaScriptPrompt(Frame* frame, const String& message, const String& defaultValue, String& result)
318 ewk_view_run_javascript_prompt(m_view, kit(frame), message.utf8().data(), defaultValue.utf8().data(), &value);
320 result = String::fromUTF8(value);
327 void ChromeClientEfl::setStatusbarText(const String& string)
329 ewk_view_statusbar_text_set(m_view, string.utf8().data());
332 bool ChromeClientEfl::shouldInterruptJavaScript()
334 return ewk_view_should_interrupt_javascript(m_view);
337 KeyboardUIMode ChromeClientEfl::keyboardUIMode()
339 return KeyboardAccessTabsToLinks;
342 IntRect ChromeClientEfl::windowResizerRect() const
345 // Implementing this function will make repaint being
346 // called during resize, but as this will be done with
347 // a minor delay it adds a weird "filling" effect due
348 // to us using an evas image for showing the cairo
349 // context. So instead of implementing this function
350 // we call paint directly during resize with
351 // the new object size as its argument.
355 void ChromeClientEfl::contentsSizeChanged(Frame* frame, const IntSize& size) const
357 ewk_frame_contents_size_changed(kit(frame), size.width(), size.height());
358 if (ewk_view_frame_main_get(m_view) == kit(frame))
359 ewk_view_contents_size_changed(m_view, size.width(), size.height());
362 IntRect ChromeClientEfl::windowToScreen(const IntRect& rect) const
364 #if ENABLE(TIZEN_SUPPORT_PLUGINS) && ENABLE(TIZEN_CAIRO_SCALE_PATCH)
365 // mariusz.g@samsung.com
366 IntRect result(rect);
367 float zoomRatio = ewk_view_zoom_get(m_view);
368 result.setX((int)(zoomRatio * rect.x()));
369 result.setY((int)(zoomRatio * rect.y()));
370 result.setWidth((int)(zoomRatio * rect.width()));
371 result.setHeight((int)(zoomRatio * rect.height()));
379 IntPoint ChromeClientEfl::screenToWindow(const IntPoint& point) const
385 PlatformPageClient ChromeClientEfl::platformPageClient() const
390 void ChromeClientEfl::scrollbarsModeDidChange() const
394 void ChromeClientEfl::mouseDidMoveOverElement(const HitTestResult& hit, unsigned modifierFlags)
396 // FIXME, compare with old link, look at Qt impl.
397 bool isLink = hit.isLiveLink();
399 KURL url = hit.absoluteLinkURL();
400 if (!url.isEmpty() && url != m_hoveredLinkURL) {
403 CString urlStr = url.string().utf8();
404 CString titleStr = hit.title(dir).utf8();
405 link[0] = urlStr.data();
406 link[1] = titleStr.data();
407 ewk_view_mouse_link_hover_in(m_view, link);
408 m_hoveredLinkURL = url;
410 } else if (!isLink && !m_hoveredLinkURL.isEmpty()) {
411 ewk_view_mouse_link_hover_out(m_view);
412 m_hoveredLinkURL = KURL();
416 void ChromeClientEfl::setToolTip(const String& toolTip, TextDirection)
418 ewk_view_tooltip_text_set(m_view, toolTip.utf8().data());
421 void ChromeClientEfl::print(Frame* frame)
426 void ChromeClientEfl::reachedMaxAppCacheSize(int64_t spaceNeeded)
428 // FIXME: Free some space.
432 void ChromeClientEfl::reachedApplicationCacheOriginQuota(SecurityOrigin*, int64_t)
437 #if ENABLE(TOUCH_EVENTS)
438 void ChromeClientEfl::needTouchEvents(bool needed)
440 ewk_view_need_touch_events_set(m_view, needed);
444 #if ENABLE(TIZEN_EVAS_OBJECT_PLUGIN)
445 void ChromeClientEfl::getPluginStorage(PluginStorage* pluginStorage)
447 ewk_view_get_plugin_storage(m_view , pluginStorage);
449 #if ENABLE(TIZEN_SUPPORT_PLUGINS) && ENABLE(TIZEN_DONT_PAN_OVER_SOME_PLUGINS)
450 void ChromeClientEfl::repeatEventsToPlugin(bool enabled)
452 ewk_view_events_repeat_to_plugin(m_view, enabled);
455 void ChromeClientEfl::eventsHandledByPluginChanged(bool newState)
457 ewk_view_events_handled_by_plugin_changed(m_view, newState);
462 #if ENABLE(SQL_DATABASE)
463 void ChromeClientEfl::exceededDatabaseQuota(Frame* frame, const String& databaseName)
466 SecurityOrigin* origin = frame->document()->securityOrigin();
468 DatabaseDetails details = DatabaseTracker::tracker().detailsForNameAndOrigin(databaseName, origin);
469 quota = ewk_view_exceeded_database_quota(m_view,
470 kit(frame), databaseName.utf8().data(),
471 details.currentUsage(), details.expectedUsage());
473 /* if client did not set quota, and database is being created now, the
474 * default quota is applied
476 if (!quota && !DatabaseTracker::tracker().hasEntryForOrigin(origin))
477 quota = ewk_settings_web_database_default_quota_get();
479 DatabaseTracker::tracker().setQuota(origin, quota);
483 #if ENABLE(NOTIFICATIONS)
484 NotificationPresenter* ChromeClientEfl::notificationPresenter() const
491 void ChromeClientEfl::runOpenPanel(Frame* frame, PassRefPtr<FileChooser> prpFileChooser)
493 RefPtr<FileChooser> chooser = prpFileChooser;
494 Eina_List* selectedFilenames = 0;
496 Vector<String> filenames;
498 const FileChooserSettings& settings = chooser->settings();
499 bool confirm = ewk_view_run_open_panel(m_view, kit(frame), settings.allowsMultipleFiles, settings.acceptMIMETypes, &selectedFilenames);
504 EINA_LIST_FREE(selectedFilenames, filename) {
505 filenames.append((char*)filename);
509 if (chooser->settings().allowsMultipleFiles)
510 chooser->chooseFiles(filenames);
512 chooser->chooseFile(filenames[0]);
515 void ChromeClientEfl::formStateDidChange(const Node*)
520 void ChromeClientEfl::setCursor(const Cursor&)
525 void ChromeClientEfl::setCursorHiddenUntilMouseMoves(bool)
530 #if ENABLE(TIZEN_GEOLOCATION)
531 void ChromeClientEfl::requestGeolocationPermissionForFrame(Frame* frame, Geolocation* geolocation)
533 // See the comment in WebCore/page/ChromeClient.h
534 if (g_geolocation_permission_dialog_show_callback) {
535 g_geolocation_permission_dialog_show_callback(
537 frame->document()->url().host().latin1().data()
541 evas_object_smart_callback_call(m_view, "geolocation,request", kit(frame));
544 void ChromeClientEfl::requestGeolocationPermissionForFrame(Frame*, Geolocation*)
546 // See the comment in WebCore/page/ChromeClient.h
551 #if ENABLE(TIZEN_GEOLOCATION)
552 void ChromeClientEfl::cancelGeolocationPermissionRequestForFrame(Frame* frame, Geolocation*)
554 void ChromeClientEfl::cancelGeolocationPermissionRequestForFrame(Frame*, Geolocation*)
557 #if ENABLE(TIZEN_GEOLOCATION)
558 evas_object_smart_callback_call(m_view, "geolocation,request,cancel", kit(frame));
564 void ChromeClientEfl::cancelGeolocationPermissionForFrame(Frame*, Geolocation*)
569 void ChromeClientEfl::invalidateContents(const IntRect& updateRect, bool immediate)
574 void ChromeClientEfl::invalidateWindow(const IntRect& updateRect, bool immediate)
579 void ChromeClientEfl::invalidateContentsAndWindow(const IntRect& updateRect, bool immediate)
581 if (updateRect.isEmpty())
584 Evas_Coord x, y, w, h;
588 w = updateRect.width();
589 h = updateRect.height();
591 ewk_view_repaint(m_view, x, y, w, h);
594 void ChromeClientEfl::invalidateContentsForSlowScroll(const IntRect& updateRect, bool immediate)
596 #if ENABLE(TIZEN_OFFSET_UPDATE)
597 ewk_view_tiled_offset_update(m_view);
599 invalidateContentsAndWindow(updateRect, immediate);
602 void ChromeClientEfl::scroll(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect)
604 ewk_view_scroll(m_view, scrollDelta.width(), scrollDelta.height(), rectToScroll.x(), rectToScroll.y(), rectToScroll.width(), rectToScroll.height(), clipRect.x(), clipRect.y(), clipRect.width(), clipRect.height(), EINA_TRUE);
607 void ChromeClientEfl::cancelGeolocationPermissionRequestForFrame(Frame*)
612 void ChromeClientEfl::iconForFiles(const Vector<String, 0u>&, PassRefPtr<FileChooser>)
617 void ChromeClientEfl::loadIconForFiles(const Vector<String>&, FileIconLoader*)
622 void ChromeClientEfl::dispatchViewportDataDidChange(const ViewportArguments& arguments) const
624 ewk_view_viewport_attributes_set(m_view, arguments);
627 bool ChromeClientEfl::selectItemWritingDirectionIsNatural()
632 bool ChromeClientEfl::selectItemAlignmentFollowsMenuWritingDirection()
637 PassRefPtr<PopupMenu> ChromeClientEfl::createPopupMenu(PopupMenuClient* client) const
639 return adoptRef(new PopupMenuEfl(client));
642 PassRefPtr<SearchPopupMenu> ChromeClientEfl::createSearchPopupMenu(PopupMenuClient* client) const
644 return adoptRef(new SearchPopupMenuEfl(client));
647 #if USE(ACCELERATED_COMPOSITING)
648 void ChromeClientEfl::attachRootGraphicsLayer(Frame* frame, GraphicsLayer* graphicsLayer)
650 #if ENABLE(TIZEN_ACCELERATED_COMPOSITING)
652 ewk_view_root_graphics_layer_set(m_view, graphicsLayer);
653 #endif // ENABLE(TIZEN_ACCELERATED_COMPOSITING)
656 void ChromeClientEfl::setNeedsOneShotDrawingSynchronization()
658 #if ENABLE(TIZEN_ACCELERATED_COMPOSITING)
663 void ChromeClientEfl::scheduleCompositingLayerSync()
665 #if ENABLE(TIZEN_ACCELERATED_COMPOSITING)
667 ewk_view_mark_for_sync(m_view, false);
668 #endif // ENABLE(TIZEN_ACCELERATED_COMPOSITING)
671 bool ChromeClientEfl::allowsAcceleratedCompositing() const
673 #if ENABLE(TIZEN_ACCELERATED_COMPOSITING)
674 Settings* settings = ewk_view_core_page_get(m_view)->settings();
675 return settings->acceleratedCompositingEnabled();
679 ChromeClient::CompositingTriggerFlags ChromeClientEfl::allowedCompositingTriggers() const
681 #if ENABLE(TIZEN_ACCELERATED_COMPOSITING)
682 CompositingTriggerFlags flags = 0;
683 Settings* settings = ewk_view_core_page_get(m_view)->settings();
685 if (settings->acceleratedCompositingFor3DTransformsEnabled())
686 flags |= ThreeDTransformTrigger;
688 if (settings->acceleratedCompositingForVideoEnabled())
689 flags |= VideoTrigger;
691 if (settings->acceleratedCompositingForPluginsEnabled())
692 flags |= PluginTrigger;
694 if (settings->acceleratedCompositingForAnimationEnabled())
695 flags |= AnimationTrigger;
697 if (settings->acceleratedCompositingForCanvasEnabled())
698 flags |= CanvasTrigger;
704 #if ENABLE(CANVAS_CAIRO_GLES_RENDERING)
705 void* ChromeClientEfl::sharedCairoDevice()
707 return (void*)ewk_view_get_shared_cairo_device(m_view);
712 #if ENABLE(TIZEN_SHOULD_ALLOW_OPEN_URL)
713 bool ChromeClientEfl::shouldAllowOpenUrl(const char* url)
715 return static_cast<bool>(ewk_should_allow_open_uri( m_view, url ));
719 #if ENABLE(FULLSCREEN_API)
720 bool ChromeClientEfl::supportsFullScreenForElement(const WebCore::Element* element, bool withKeyboard)
728 void ChromeClientEfl::enterFullScreenForElement(WebCore::Element* element)
730 element->document()->webkitWillEnterFullScreenForElement(element);
731 element->document()->webkitDidEnterFullScreenForElement(element);
734 void ChromeClientEfl::exitFullScreenForElement(WebCore::Element* element)
736 element->document()->webkitWillExitFullScreenForElement(element);
737 element->document()->webkitDidExitFullScreenForElement(element);