diff options
Diffstat (limited to 'WebKit/chromium/src/ChromeClientImpl.cpp')
-rw-r--r-- | WebKit/chromium/src/ChromeClientImpl.cpp | 343 |
1 files changed, 268 insertions, 75 deletions
diff --git a/WebKit/chromium/src/ChromeClientImpl.cpp b/WebKit/chromium/src/ChromeClientImpl.cpp index ce2f00c..7b67ede 100644 --- a/WebKit/chromium/src/ChromeClientImpl.cpp +++ b/WebKit/chromium/src/ChromeClientImpl.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2009 Google Inc. All rights reserved. + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -31,25 +32,36 @@ #include "config.h" #include "ChromeClientImpl.h" -#include "AccessibilityObject.h" #include "AXObjectCache.h" +#include "AccessibilityObject.h" #include "CharacterNames.h" #include "Console.h" #include "Cursor.h" #include "DatabaseTracker.h" #include "Document.h" #include "DocumentLoader.h" +#include "ExternalPopupMenu.h" #include "FileChooser.h" #include "FloatRect.h" #include "FrameLoadRequest.h" #include "FrameView.h" +#include "Geolocation.h" +#include "GeolocationService.h" +#include "GeolocationServiceChromium.h" +#include "GraphicsLayer.h" +#include "HTMLNames.h" #include "HitTestResult.h" #include "IntRect.h" +#include "NavigationAction.h" #include "Node.h" #include "NotificationPresenterImpl.h" #include "Page.h" #include "PopupMenuChromium.h" +#include "RenderWidget.h" #include "ScriptController.h" +#include "SearchPopupMenuChromium.h" +#include "SecurityOrigin.h" +#include "Settings.h" #if USE(V8) #include "V8Proxy.h" #endif @@ -59,15 +71,21 @@ #include "WebFileChooserCompletionImpl.h" #include "WebFrameClient.h" #include "WebFrameImpl.h" +#include "WebGeolocationService.h" #include "WebInputEvent.h" #include "WebKit.h" +#include "WebNode.h" +#include "WebPlugin.h" +#include "WebPluginContainerImpl.h" #include "WebPopupMenuImpl.h" #include "WebPopupMenuInfo.h" +#include "WebPopupType.h" #include "WebRect.h" #include "WebTextDirection.h" #include "WebURLRequest.h" #include "WebViewClient.h" #include "WebViewImpl.h" +#include "WebWindowFeatures.h" #include "WindowFeatures.h" #include "WrappedResourceRequest.h" @@ -75,6 +93,60 @@ using namespace WebCore; namespace WebKit { +// Converts a WebCore::PopupContainerType to a WebKit::WebPopupType. +static WebPopupType convertPopupType(PopupContainer::PopupType type) +{ + switch (type) { + case PopupContainer::Select: + return WebPopupTypeSelect; + case PopupContainer::Suggestion: + return WebPopupTypeSuggestion; + default: + ASSERT_NOT_REACHED(); + return WebPopupTypeNone; + } +} + +// Converts a WebCore::AXObjectCache::AXNotification to a WebKit::WebAccessibilityNotification +static WebAccessibilityNotification toWebAccessibilityNotification(AXObjectCache::AXNotification notification) +{ + switch (notification) { + case AXObjectCache::AXActiveDescendantChanged: + return WebAccessibilityNotificationActiveDescendantChanged; + case AXObjectCache::AXCheckedStateChanged: + return WebAccessibilityNotificationCheckedStateChanged; + case AXObjectCache::AXChildrenChanged: + return WebAccessibilityNotificationChildrenChanged; + case AXObjectCache::AXFocusedUIElementChanged: + return WebAccessibilityNotificationFocusedUIElementChanged; + case AXObjectCache::AXLayoutComplete: + return WebAccessibilityNotificationLayoutComplete; + case AXObjectCache::AXLoadComplete: + return WebAccessibilityNotificationLoadComplete; + case AXObjectCache::AXSelectedChildrenChanged: + return WebAccessibilityNotificationSelectedChildrenChanged; + case AXObjectCache::AXSelectedTextChanged: + return WebAccessibilityNotificationSelectedTextChanged; + case AXObjectCache::AXValueChanged: + return WebAccessibilityNotificationValueChanged; + case AXObjectCache::AXScrolledToAnchor: + return WebAccessibilityNotificationScrolledToAnchor; + case AXObjectCache::AXLiveRegionChanged: + return WebAccessibilityNotificationLiveRegionChanged; + case AXObjectCache::AXMenuListValueChanged: + return WebAccessibilityNotificationMenuListValueChanged; + case AXObjectCache::AXRowCountChanged: + return WebAccessibilityNotificationRowCountChanged; + case AXObjectCache::AXRowCollapsed: + return WebAccessibilityNotificationRowCollapsed; + case AXObjectCache::AXRowExpanded: + return WebAccessibilityNotificationRowExpanded; + default: + ASSERT_NOT_REACHED(); + return WebAccessibilityNotificationInvalid; + } +} + ChromeClientImpl::ChromeClientImpl(WebViewImpl* webView) : m_webView(webView) , m_toolbarsVisible(true) @@ -82,7 +154,6 @@ ChromeClientImpl::ChromeClientImpl(WebViewImpl* webView) , m_scrollbarsVisible(true) , m_menubarVisible(true) , m_resizable(true) - , m_ignoreNextSetCursor(false) { } @@ -138,35 +209,8 @@ float ChromeClientImpl::scaleFactor() void ChromeClientImpl::focus() { - if (!m_webView->client()) - return; - - m_webView->client()->didFocus(); - - // If accessibility is enabled, we should notify assistive technology that - // the active AccessibilityObject changed. - const Frame* frame = m_webView->focusedWebCoreFrame(); - if (!frame) - return; - - Document* doc = frame->document(); - - if (doc && doc->axObjectCache()->accessibilityEnabled()) { - Node* focusedNode = m_webView->focusedWebCoreNode(); - - if (!focusedNode) { - // Could not retrieve focused Node. - return; - } - - // Retrieve the focused AccessibilityObject. - AccessibilityObject* focusedAccObj = - doc->axObjectCache()->getOrCreate(focusedNode->renderer()); - - // Alert assistive technology that focus changed. - if (focusedAccObj) - m_webView->client()->focusAccessibilityObject(WebAccessibilityObject(focusedAccObj)); - } + if (m_webView->client()) + m_webView->client()->didFocus(); } void ChromeClientImpl::unfocus() @@ -194,27 +238,33 @@ void ChromeClientImpl::takeFocus(FocusDirection direction) void ChromeClientImpl::focusedNodeChanged(Node* node) { - WebURL focus_url; + m_webView->client()->focusedNodeChanged(WebNode(node)); + + WebURL focusURL; if (node && node->isLink()) { // This HitTestResult hack is the easiest way to get a link URL out of a // WebCore::Node. - HitTestResult hit_test(IntPoint(0, 0)); + HitTestResult hitTest(IntPoint(0, 0)); // This cast must be valid because of the isLink() check. - hit_test.setURLElement(reinterpret_cast<Element*>(node)); - if (hit_test.isLiveLink()) - focus_url = hit_test.absoluteLinkURL(); + hitTest.setURLElement(static_cast<Element*>(node)); + if (hitTest.isLiveLink()) + focusURL = hitTest.absoluteLinkURL(); } - m_webView->client()->setKeyboardFocusURL(focus_url); + m_webView->client()->setKeyboardFocusURL(focusURL); +} + +void ChromeClientImpl::focusedFrameChanged(Frame*) +{ } Page* ChromeClientImpl::createWindow( - Frame* frame, const FrameLoadRequest& r, const WindowFeatures& features) + Frame* frame, const FrameLoadRequest& r, const WindowFeatures& features, const NavigationAction&) { if (!m_webView->client()) return 0; WebViewImpl* newView = static_cast<WebViewImpl*>( - m_webView->client()->createView(WebFrameImpl::fromFrame(frame))); + m_webView->client()->createView(WebFrameImpl::fromFrame(frame), features, r.frameName())); if (!newView) return 0; @@ -321,9 +371,9 @@ bool ChromeClientImpl::statusbarVisible() void ChromeClientImpl::setScrollbarsVisible(bool value) { m_scrollbarsVisible = value; - WebFrameImpl* web_frame = static_cast<WebFrameImpl*>(m_webView->mainFrame()); - if (web_frame) - web_frame->setAllowsScrolling(value); + WebFrameImpl* webFrame = static_cast<WebFrameImpl*>(m_webView->mainFrame()); + if (webFrame) + webFrame->setCanHaveScrollbars(value); } bool ChromeClientImpl::scrollbarsVisible() @@ -462,26 +512,49 @@ IntRect ChromeClientImpl::windowResizerRect() const return result; } -void ChromeClientImpl::repaint( - const IntRect& paintRect, bool contentChanged, bool immediate, - bool repaintContentOnly) +void ChromeClientImpl::invalidateWindow(const IntRect&, bool) { - // Ignore spurious calls. - if (!contentChanged || paintRect.isEmpty()) + notImplemented(); +} + +void ChromeClientImpl::invalidateContentsAndWindow(const IntRect& updateRect, bool /*immediate*/) +{ + if (updateRect.isEmpty()) return; - if (m_webView->client()) - m_webView->client()->didInvalidateRect(paintRect); +#if USE(ACCELERATED_COMPOSITING) + if (!m_webView->isAcceleratedCompositingActive()) { +#endif + if (m_webView->client()) + m_webView->client()->didInvalidateRect(updateRect); +#if USE(ACCELERATED_COMPOSITING) + } else + m_webView->invalidateRootLayerRect(updateRect); +#endif +} + +void ChromeClientImpl::invalidateContentsForSlowScroll(const IntRect& updateRect, bool immediate) +{ + m_webView->hidePopups(); + invalidateContentsAndWindow(updateRect, immediate); } void ChromeClientImpl::scroll( const IntSize& scrollDelta, const IntRect& scrollRect, const IntRect& clipRect) { - if (m_webView->client()) { - int dx = scrollDelta.width(); - int dy = scrollDelta.height(); - m_webView->client()->didScrollRect(dx, dy, clipRect); - } + m_webView->hidePopups(); +#if USE(ACCELERATED_COMPOSITING) + if (!m_webView->isAcceleratedCompositingActive()) { +#endif + if (m_webView->client()) { + int dx = scrollDelta.width(); + int dy = scrollDelta.height(); + m_webView->client()->didScrollRect(dx, dy, clipRect); + } +#if USE(ACCELERATED_COMPOSITING) + } else + m_webView->scrollRootLayerRect(scrollDelta, clipRect); +#endif } IntPoint ChromeClientImpl::screenToWindow(const IntPoint&) const @@ -518,11 +591,25 @@ void ChromeClientImpl::mouseDidMoveOverElement( { if (!m_webView->client()) return; + + WebURL url; // Find out if the mouse is over a link, and if so, let our UI know... if (result.isLiveLink() && !result.absoluteLinkURL().string().isEmpty()) - m_webView->client()->setMouseOverURL(result.absoluteLinkURL()); - else - m_webView->client()->setMouseOverURL(WebURL()); + url = result.absoluteLinkURL(); + else if (result.innerNonSharedNode() + && (result.innerNonSharedNode()->hasTagName(HTMLNames::objectTag) + || result.innerNonSharedNode()->hasTagName(HTMLNames::embedTag))) { + RenderObject* object = result.innerNonSharedNode()->renderer(); + if (object && object->isWidget()) { + Widget* widget = toRenderWidget(object)->widget(); + if (widget && widget->isPluginContainer()) { + WebPluginContainerImpl* plugin = static_cast<WebPluginContainerImpl*>(widget); + url = plugin->plugin()->linkAtPosition(result.point()); + } + } + } + + m_webView->client()->setMouseOverURL(url); } void ChromeClientImpl::setToolTip(const String& tooltipText, TextDirection dir) @@ -552,6 +639,11 @@ void ChromeClientImpl::reachedMaxAppCacheSize(int64_t spaceNeeded) { ASSERT_NOT_REACHED(); } + +void ChromeClientImpl::reachedApplicationCacheOriginQuota(SecurityOrigin*) +{ + ASSERT_NOT_REACHED(); +} #endif void ChromeClientImpl::runOpenPanel(Frame* frame, PassRefPtr<FileChooser> fileChooser) @@ -562,6 +654,11 @@ void ChromeClientImpl::runOpenPanel(Frame* frame, PassRefPtr<FileChooser> fileCh WebFileChooserParams params; params.multiSelect = fileChooser->allowsMultipleFiles(); +#if ENABLE(DIRECTORY_UPLOAD) + params.directory = fileChooser->allowsDirectoryUpload(); +#else + params.directory = false; +#endif params.acceptTypes = fileChooser->acceptTypes(); params.selectedFiles = fileChooser->filenames(); if (params.selectedFiles.size() > 0) @@ -576,9 +673,13 @@ void ChromeClientImpl::runOpenPanel(Frame* frame, PassRefPtr<FileChooser> fileCh chooserCompletion->didChooseFile(WebVector<WebString>()); } +void ChromeClientImpl::chooseIconForFiles(const Vector<WTF::String>&, WebCore::FileChooser*) +{ + notImplemented(); +} + void ChromeClientImpl::popupOpened(PopupContainer* popupContainer, const IntRect& bounds, - bool activatable, bool handleExternally) { if (!m_webView->client()) @@ -589,19 +690,24 @@ void ChromeClientImpl::popupOpened(PopupContainer* popupContainer, WebPopupMenuInfo popupInfo; getPopupMenuInfo(popupContainer, &popupInfo); webwidget = m_webView->client()->createPopupMenu(popupInfo); - } else - webwidget = m_webView->client()->createPopupMenu(activatable); - + } else { + webwidget = m_webView->client()->createPopupMenu( + convertPopupType(popupContainer->popupType())); + // We only notify when the WebView has to handle the popup, as when + // the popup is handled externally, the fact that a popup is showing is + // transparent to the WebView. + m_webView->popupOpened(popupContainer); + } static_cast<WebPopupMenuImpl*>(webwidget)->Init(popupContainer, bounds); } -void ChromeClientImpl::setCursor(const WebCursorInfo& cursor) +void ChromeClientImpl::popupClosed(WebCore::PopupContainer* popupContainer) { - if (m_ignoreNextSetCursor) { - m_ignoreNextSetCursor = false; - return; - } + m_webView->popupClosed(popupContainer); +} +void ChromeClientImpl::setCursor(const WebCursorInfo& cursor) +{ if (m_webView->client()) m_webView->client()->didChangeCursor(cursor); } @@ -609,11 +715,6 @@ void ChromeClientImpl::setCursor(const WebCursorInfo& cursor) void ChromeClientImpl::setCursorForPlugin(const WebCursorInfo& cursor) { setCursor(cursor); - - // Currently, Widget::setCursor is always called after this function in - // EventHandler.cpp and since we don't want that we set a flag indicating - // that the next SetCursor call is to be ignored. - m_ignoreNextSetCursor = true; } void ChromeClientImpl::formStateDidChange(const Node* node) @@ -655,18 +756,19 @@ void ChromeClientImpl::getPopupMenuInfo(PopupContainer* popupContainer, } info->itemHeight = popupContainer->menuItemHeight(); + info->itemFontSize = popupContainer->menuItemFontSize(); info->selectedIndex = popupContainer->selectedIndex(); info->items.swap(outputItems); + info->rightAligned = popupContainer->menuStyle().textDirection() == RTL; } -void ChromeClientImpl::didChangeAccessibilityObjectState(AccessibilityObject* obj) +void ChromeClientImpl::postAccessibilityNotification(AccessibilityObject* obj, AXObjectCache::AXNotification notification) { - // Alert assistive technology about the accessibility object state change + // Alert assistive technology about the accessibility object notification. if (obj) - m_webView->client()->didChangeAccessibilityObjectState(WebAccessibilityObject(obj)); + m_webView->client()->postAccessibilityNotification(WebAccessibilityObject(obj), toWebAccessibilityNotification(notification)); } - #if ENABLE(NOTIFICATIONS) NotificationPresenter* ChromeClientImpl::notificationPresenter() const { @@ -674,4 +776,95 @@ NotificationPresenter* ChromeClientImpl::notificationPresenter() const } #endif +void ChromeClientImpl::requestGeolocationPermissionForFrame(Frame* frame, Geolocation* geolocation) +{ +#if ENABLE(CLIENT_BASED_GEOLOCATION) + // FIXME: Implement Client-based Geolocation Permissions +#else + GeolocationServiceChromium* geolocationService = static_cast<GeolocationServiceChromium*>(geolocation->getGeolocationService()); + geolocationService->geolocationServiceBridge()->attachBridgeIfNeeded(); + m_webView->client()->geolocationService()->requestPermissionForFrame(geolocationService->geolocationServiceBridge()->getBridgeId(), frame->document()->url()); +#endif +} + +void ChromeClientImpl::cancelGeolocationPermissionRequestForFrame(Frame* frame, Geolocation* geolocation) +{ +#if ENABLE(CLIENT_BASED_GEOLOCATION) + // FIXME: Implement Client-based Geolocation Permissions +#else + GeolocationServiceChromium* geolocationService = static_cast<GeolocationServiceChromium*>(geolocation->getGeolocationService()); + m_webView->client()->geolocationService()->cancelPermissionRequestForFrame(geolocationService->geolocationServiceBridge()->getBridgeId(), frame->document()->url()); +#endif +} + +#if USE(ACCELERATED_COMPOSITING) +void ChromeClientImpl::attachRootGraphicsLayer(Frame* frame, GraphicsLayer* graphicsLayer) +{ + m_webView->setRootGraphicsLayer(graphicsLayer ? graphicsLayer->platformLayer() : 0); +} + +void ChromeClientImpl::scheduleCompositingLayerSync() +{ + m_webView->setRootLayerNeedsDisplay(); +} + +ChromeClient::CompositingTriggerFlags ChromeClientImpl::allowedCompositingTriggers() const +{ + if (!m_webView->allowsAcceleratedCompositing()) + return 0; + + CompositingTriggerFlags flags = 0; + Settings* settings = m_webView->page()->settings(); + if (settings->acceleratedCompositingFor3DTransformsEnabled()) + flags |= ThreeDTransformTrigger; + if (settings->acceleratedCompositingForVideoEnabled()) + flags |= VideoTrigger; + if (settings->acceleratedCompositingForPluginsEnabled()) + flags |= PluginTrigger; + if (settings->acceleratedCompositingForAnimationEnabled()) + flags |= AnimationTrigger; + if (settings->acceleratedCompositingForCanvasEnabled()) + flags |= CanvasTrigger; + + return flags; +} +#endif + +bool ChromeClientImpl::supportsFullscreenForNode(const WebCore::Node* node) +{ + if (m_webView->client() && node->hasTagName(WebCore::HTMLNames::videoTag)) + return m_webView->client()->supportsFullscreen(); + return false; +} + +void ChromeClientImpl::enterFullscreenForNode(WebCore::Node* node) +{ + if (m_webView->client()) + m_webView->client()->enterFullscreenForNode(WebNode(node)); +} + +void ChromeClientImpl::exitFullscreenForNode(WebCore::Node* node) +{ + if (m_webView->client()) + m_webView->client()->exitFullscreenForNode(WebNode(node)); +} + +bool ChromeClientImpl::selectItemWritingDirectionIsNatural() +{ + return false; +} + +PassRefPtr<PopupMenu> ChromeClientImpl::createPopupMenu(PopupMenuClient* client) const +{ + if (WebViewImpl::useExternalPopupMenus()) + return adoptRef(new ExternalPopupMenu(client, m_webView->client())); + + return adoptRef(new PopupMenuChromium(client)); +} + +PassRefPtr<SearchPopupMenu> ChromeClientImpl::createSearchPopupMenu(PopupMenuClient* client) const +{ + return adoptRef(new SearchPopupMenuChromium(client)); +} + } // namespace WebKit |