WebKit/chromium/src/ChromeClientImpl.cpp
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     1 /*
       
     2  * Copyright (C) 2009 Google Inc. All rights reserved.
       
     3  *
       
     4  * Redistribution and use in source and binary forms, with or without
       
     5  * modification, are permitted provided that the following conditions are
       
     6  * met:
       
     7  *
       
     8  *     * Redistributions of source code must retain the above copyright
       
     9  * notice, this list of conditions and the following disclaimer.
       
    10  *     * Redistributions in binary form must reproduce the above
       
    11  * copyright notice, this list of conditions and the following disclaimer
       
    12  * in the documentation and/or other materials provided with the
       
    13  * distribution.
       
    14  *     * Neither the name of Google Inc. nor the names of its
       
    15  * contributors may be used to endorse or promote products derived from
       
    16  * this software without specific prior written permission.
       
    17  *
       
    18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
       
    19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
       
    20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
       
    21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
       
    22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
       
    23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
       
    24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
       
    25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
       
    26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
       
    27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
       
    28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    29  */
       
    30 
       
    31 #include "config.h"
       
    32 #include "ChromeClientImpl.h"
       
    33 
       
    34 #include "AXObjectCache.h"
       
    35 #include "AccessibilityObject.h"
       
    36 #include "CharacterNames.h"
       
    37 #include "Console.h"
       
    38 #include "Cursor.h"
       
    39 #include "DatabaseTracker.h"
       
    40 #include "Document.h"
       
    41 #include "DocumentLoader.h"
       
    42 #include "FileChooser.h"
       
    43 #include "FloatRect.h"
       
    44 #include "FrameLoadRequest.h"
       
    45 #include "FrameView.h"
       
    46 #include "GLES2Context.h"
       
    47 #include "Geolocation.h"
       
    48 #include "GeolocationService.h"
       
    49 #include "GeolocationServiceChromium.h"
       
    50 #include "GraphicsLayer.h"
       
    51 #include "HTMLNames.h"
       
    52 #include "HitTestResult.h"
       
    53 #include "IntRect.h"
       
    54 #include "Node.h"
       
    55 #include "NotificationPresenterImpl.h"
       
    56 #include "Page.h"
       
    57 #include "PopupMenuChromium.h"
       
    58 #include "ScriptController.h"
       
    59 #include "WebGeolocationService.h"
       
    60 #if USE(V8)
       
    61 #include "V8Proxy.h"
       
    62 #endif
       
    63 #include "WebAccessibilityObject.h"
       
    64 #include "WebConsoleMessage.h"
       
    65 #include "WebCursorInfo.h"
       
    66 #include "WebFileChooserCompletionImpl.h"
       
    67 #include "WebFrameClient.h"
       
    68 #include "WebFrameImpl.h"
       
    69 #include "WebInputEvent.h"
       
    70 #include "WebKit.h"
       
    71 #include "WebNode.h"
       
    72 #include "WebPopupMenuImpl.h"
       
    73 #include "WebPopupMenuInfo.h"
       
    74 #include "WebPopupType.h"
       
    75 #include "WebRect.h"
       
    76 #include "WebTextDirection.h"
       
    77 #include "WebURLRequest.h"
       
    78 #include "WebViewClient.h"
       
    79 #include "WebViewImpl.h"
       
    80 #include "WebWindowFeatures.h"
       
    81 #include "WindowFeatures.h"
       
    82 #include "WrappedResourceRequest.h"
       
    83 
       
    84 using namespace WebCore;
       
    85 
       
    86 namespace WebKit {
       
    87 
       
    88 // Converts a WebCore::PopupContainerType to a WebKit::WebPopupType.
       
    89 static WebPopupType convertPopupType(PopupContainer::PopupType type)
       
    90 {
       
    91     switch (type) {
       
    92     case PopupContainer::Select:
       
    93         return WebPopupTypeSelect;
       
    94     case PopupContainer::Suggestion:
       
    95         return WebPopupTypeSuggestion;
       
    96     default:
       
    97         ASSERT_NOT_REACHED();
       
    98         return WebPopupTypeNone;
       
    99     }
       
   100 }
       
   101 
       
   102 ChromeClientImpl::ChromeClientImpl(WebViewImpl* webView)
       
   103     : m_webView(webView)
       
   104     , m_toolbarsVisible(true)
       
   105     , m_statusbarVisible(true)
       
   106     , m_scrollbarsVisible(true)
       
   107     , m_menubarVisible(true)
       
   108     , m_resizable(true)
       
   109 {
       
   110 }
       
   111 
       
   112 ChromeClientImpl::~ChromeClientImpl()
       
   113 {
       
   114 }
       
   115 
       
   116 void ChromeClientImpl::chromeDestroyed()
       
   117 {
       
   118     // Our lifetime is bound to the WebViewImpl.
       
   119 }
       
   120 
       
   121 void ChromeClientImpl::setWindowRect(const FloatRect& r)
       
   122 {
       
   123     if (m_webView->client())
       
   124         m_webView->client()->setWindowRect(IntRect(r));
       
   125 }
       
   126 
       
   127 FloatRect ChromeClientImpl::windowRect()
       
   128 {
       
   129     WebRect rect;
       
   130     if (m_webView->client())
       
   131         rect = m_webView->client()->rootWindowRect();
       
   132     else {
       
   133         // These numbers will be fairly wrong. The window's x/y coordinates will
       
   134         // be the top left corner of the screen and the size will be the content
       
   135         // size instead of the window size.
       
   136         rect.width = m_webView->size().width;
       
   137         rect.height = m_webView->size().height;
       
   138     }
       
   139     return FloatRect(rect);
       
   140 }
       
   141 
       
   142 FloatRect ChromeClientImpl::pageRect()
       
   143 {
       
   144     // We hide the details of the window's border thickness from the web page by
       
   145     // simple re-using the window position here.  So, from the point-of-view of
       
   146     // the web page, the window has no border.
       
   147     return windowRect();
       
   148 }
       
   149 
       
   150 float ChromeClientImpl::scaleFactor()
       
   151 {
       
   152     // This is supposed to return the scale factor of the web page. It looks like
       
   153     // the implementor of the graphics layer is responsible for doing most of the
       
   154     // operations associated with scaling. However, this value is used ins some
       
   155     // cases by WebCore. For example, this is used as a scaling factor in canvas
       
   156     // so that things drawn in it are scaled just like the web page is.
       
   157     //
       
   158     // We don't currently implement scaling, so just return 1.0 (no scaling).
       
   159     return 1.0;
       
   160 }
       
   161 
       
   162 void ChromeClientImpl::focus()
       
   163 {
       
   164     if (m_webView->client())
       
   165         m_webView->client()->didFocus();
       
   166 }
       
   167 
       
   168 void ChromeClientImpl::unfocus()
       
   169 {
       
   170     if (m_webView->client())
       
   171         m_webView->client()->didBlur();
       
   172 }
       
   173 
       
   174 bool ChromeClientImpl::canTakeFocus(FocusDirection)
       
   175 {
       
   176     // For now the browser can always take focus if we're not running layout
       
   177     // tests.
       
   178     return !layoutTestMode();
       
   179 }
       
   180 
       
   181 void ChromeClientImpl::takeFocus(FocusDirection direction)
       
   182 {
       
   183     if (!m_webView->client())
       
   184         return;
       
   185     if (direction == FocusDirectionBackward)
       
   186         m_webView->client()->focusPrevious();
       
   187     else
       
   188         m_webView->client()->focusNext();
       
   189 }
       
   190 
       
   191 void ChromeClientImpl::focusedNodeChanged(Node* node)
       
   192 {
       
   193     m_webView->client()->focusedNodeChanged(WebNode(node));
       
   194 
       
   195     WebURL focusURL;
       
   196     if (node && node->isLink()) {
       
   197         // This HitTestResult hack is the easiest way to get a link URL out of a
       
   198         // WebCore::Node.
       
   199         HitTestResult hitTest(IntPoint(0, 0));
       
   200         // This cast must be valid because of the isLink() check.
       
   201         hitTest.setURLElement(static_cast<Element*>(node));
       
   202         if (hitTest.isLiveLink())
       
   203             focusURL = hitTest.absoluteLinkURL();
       
   204     }
       
   205     m_webView->client()->setKeyboardFocusURL(focusURL);
       
   206     
       
   207     if (!node)
       
   208         return;
       
   209 
       
   210     // If accessibility is enabled, we should notify assistive technology that
       
   211     // the active AccessibilityObject changed.
       
   212     Document* document = node->document();
       
   213     if (!document) {
       
   214         ASSERT_NOT_REACHED();
       
   215         return;
       
   216     } 
       
   217     if (document && document->axObjectCache()->accessibilityEnabled()) {
       
   218         // Retrieve the focused AccessibilityObject.
       
   219         AccessibilityObject* focusedAccObj =
       
   220             document->axObjectCache()->getOrCreate(node->renderer());
       
   221 
       
   222         // Alert assistive technology that focus changed.
       
   223         if (focusedAccObj)
       
   224             m_webView->client()->focusAccessibilityObject(WebAccessibilityObject(focusedAccObj));
       
   225     }
       
   226 }
       
   227 
       
   228 Page* ChromeClientImpl::createWindow(
       
   229     Frame* frame, const FrameLoadRequest& r, const WindowFeatures& features)
       
   230 {
       
   231     if (!m_webView->client())
       
   232         return 0;
       
   233 
       
   234     WebViewImpl* newView = static_cast<WebViewImpl*>(
       
   235         m_webView->client()->createView(WebFrameImpl::fromFrame(frame), features, r.frameName()));
       
   236     if (!newView)
       
   237         return 0;
       
   238 
       
   239     // The request is empty when we are just being asked to open a blank window.
       
   240     // This corresponds to window.open(""), for example.
       
   241     if (!r.resourceRequest().isEmpty()) {
       
   242         WrappedResourceRequest request(r.resourceRequest());
       
   243         newView->mainFrame()->loadRequest(request);
       
   244     }
       
   245 
       
   246     return newView->page();
       
   247 }
       
   248 
       
   249 static inline bool currentEventShouldCauseBackgroundTab(const WebInputEvent* inputEvent)
       
   250 {
       
   251     if (!inputEvent)
       
   252         return false;
       
   253 
       
   254     if (inputEvent->type != WebInputEvent::MouseUp)
       
   255         return false;
       
   256 
       
   257     const WebMouseEvent* mouseEvent = static_cast<const WebMouseEvent*>(inputEvent);
       
   258 
       
   259     WebNavigationPolicy policy;
       
   260     unsigned short buttonNumber;
       
   261     switch (mouseEvent->button) {
       
   262     case WebMouseEvent::ButtonLeft:
       
   263         buttonNumber = 0;
       
   264         break;
       
   265     case WebMouseEvent::ButtonMiddle:
       
   266         buttonNumber = 1;
       
   267         break;
       
   268     case WebMouseEvent::ButtonRight:
       
   269         buttonNumber = 2;
       
   270         break;
       
   271     default:
       
   272         return false;
       
   273     }
       
   274     bool ctrl = mouseEvent->modifiers & WebMouseEvent::ControlKey;
       
   275     bool shift = mouseEvent->modifiers & WebMouseEvent::ShiftKey;
       
   276     bool alt = mouseEvent->modifiers & WebMouseEvent::AltKey;
       
   277     bool meta = mouseEvent->modifiers & WebMouseEvent::MetaKey;
       
   278 
       
   279     if (!WebViewImpl::navigationPolicyFromMouseEvent(buttonNumber, ctrl, shift, alt, meta, &policy))
       
   280         return false;
       
   281 
       
   282     return policy == WebNavigationPolicyNewBackgroundTab;
       
   283 }
       
   284 
       
   285 void ChromeClientImpl::show()
       
   286 {
       
   287     if (!m_webView->client())
       
   288         return;
       
   289 
       
   290     // If our default configuration was modified by a script or wasn't
       
   291     // created by a user gesture, then show as a popup. Else, let this
       
   292     // new window be opened as a toplevel window.
       
   293     bool asPopup = !m_toolbarsVisible
       
   294         || !m_statusbarVisible
       
   295         || !m_scrollbarsVisible
       
   296         || !m_menubarVisible
       
   297         || !m_resizable;
       
   298 
       
   299     WebNavigationPolicy policy = WebNavigationPolicyNewForegroundTab;
       
   300     if (asPopup)
       
   301         policy = WebNavigationPolicyNewPopup;
       
   302     if (currentEventShouldCauseBackgroundTab(WebViewImpl::currentInputEvent()))
       
   303         policy = WebNavigationPolicyNewBackgroundTab;
       
   304 
       
   305     m_webView->client()->show(policy);
       
   306 }
       
   307 
       
   308 bool ChromeClientImpl::canRunModal()
       
   309 {
       
   310     return !!m_webView->client();
       
   311 }
       
   312 
       
   313 void ChromeClientImpl::runModal()
       
   314 {
       
   315     if (m_webView->client())
       
   316         m_webView->client()->runModal();
       
   317 }
       
   318 
       
   319 void ChromeClientImpl::setToolbarsVisible(bool value)
       
   320 {
       
   321     m_toolbarsVisible = value;
       
   322 }
       
   323 
       
   324 bool ChromeClientImpl::toolbarsVisible()
       
   325 {
       
   326     return m_toolbarsVisible;
       
   327 }
       
   328 
       
   329 void ChromeClientImpl::setStatusbarVisible(bool value)
       
   330 {
       
   331     m_statusbarVisible = value;
       
   332 }
       
   333 
       
   334 bool ChromeClientImpl::statusbarVisible()
       
   335 {
       
   336     return m_statusbarVisible;
       
   337 }
       
   338 
       
   339 void ChromeClientImpl::setScrollbarsVisible(bool value)
       
   340 {
       
   341     m_scrollbarsVisible = value;
       
   342     WebFrameImpl* web_frame = static_cast<WebFrameImpl*>(m_webView->mainFrame());
       
   343     if (web_frame)
       
   344         web_frame->setCanHaveScrollbars(value);
       
   345 }
       
   346 
       
   347 bool ChromeClientImpl::scrollbarsVisible()
       
   348 {
       
   349     return m_scrollbarsVisible;
       
   350 }
       
   351 
       
   352 void ChromeClientImpl::setMenubarVisible(bool value)
       
   353 {
       
   354     m_menubarVisible = value;
       
   355 }
       
   356 
       
   357 bool ChromeClientImpl::menubarVisible()
       
   358 {
       
   359     return m_menubarVisible;
       
   360 }
       
   361 
       
   362 void ChromeClientImpl::setResizable(bool value)
       
   363 {
       
   364     m_resizable = value;
       
   365 }
       
   366 
       
   367 void ChromeClientImpl::addMessageToConsole(MessageSource source,
       
   368                                            MessageType type,
       
   369                                            MessageLevel level,
       
   370                                            const String& message,
       
   371                                            unsigned lineNumber,
       
   372                                            const String& sourceID)
       
   373 {
       
   374     if (m_webView->client()) {
       
   375         m_webView->client()->didAddMessageToConsole(
       
   376             WebConsoleMessage(static_cast<WebConsoleMessage::Level>(level), message),
       
   377             sourceID,
       
   378             lineNumber);
       
   379     }
       
   380 }
       
   381 
       
   382 bool ChromeClientImpl::canRunBeforeUnloadConfirmPanel()
       
   383 {
       
   384     return !!m_webView->client();
       
   385 }
       
   386 
       
   387 bool ChromeClientImpl::runBeforeUnloadConfirmPanel(const String& message, Frame* frame)
       
   388 {
       
   389     if (m_webView->client()) {
       
   390         return m_webView->client()->runModalBeforeUnloadDialog(
       
   391             WebFrameImpl::fromFrame(frame), message);
       
   392     }
       
   393     return false;
       
   394 }
       
   395 
       
   396 void ChromeClientImpl::closeWindowSoon()
       
   397 {
       
   398     // Make sure this Page can no longer be found by JS.
       
   399     m_webView->page()->setGroupName(String());
       
   400 
       
   401     // Make sure that all loading is stopped.  Ensures that JS stops executing!
       
   402     m_webView->mainFrame()->stopLoading();
       
   403 
       
   404     if (m_webView->client())
       
   405         m_webView->client()->closeWidgetSoon();
       
   406 }
       
   407 
       
   408 // Although a Frame is passed in, we don't actually use it, since we
       
   409 // already know our own m_webView.
       
   410 void ChromeClientImpl::runJavaScriptAlert(Frame* frame, const String& message)
       
   411 {
       
   412     if (m_webView->client()) {
       
   413 #if USE(V8)
       
   414         // Before showing the JavaScript dialog, we give the proxy implementation
       
   415         // a chance to process any pending console messages.
       
   416         V8Proxy::processConsoleMessages();
       
   417 #endif
       
   418         m_webView->client()->runModalAlertDialog(
       
   419             WebFrameImpl::fromFrame(frame), message);
       
   420     }
       
   421 }
       
   422 
       
   423 // See comments for runJavaScriptAlert().
       
   424 bool ChromeClientImpl::runJavaScriptConfirm(Frame* frame, const String& message)
       
   425 {
       
   426     if (m_webView->client()) {
       
   427         return m_webView->client()->runModalConfirmDialog(
       
   428             WebFrameImpl::fromFrame(frame), message);
       
   429     }
       
   430     return false;
       
   431 }
       
   432 
       
   433 // See comments for runJavaScriptAlert().
       
   434 bool ChromeClientImpl::runJavaScriptPrompt(Frame* frame,
       
   435                                            const String& message,
       
   436                                            const String& defaultValue,
       
   437                                            String& result)
       
   438 {
       
   439     if (m_webView->client()) {
       
   440         WebString actualValue;
       
   441         bool ok = m_webView->client()->runModalPromptDialog(
       
   442             WebFrameImpl::fromFrame(frame),
       
   443             message,
       
   444             defaultValue,
       
   445             &actualValue);
       
   446         if (ok)
       
   447             result = actualValue;
       
   448         return ok;
       
   449     }
       
   450     return false;
       
   451 }
       
   452 
       
   453 void ChromeClientImpl::setStatusbarText(const String& message)
       
   454 {
       
   455     if (m_webView->client())
       
   456         m_webView->client()->setStatusText(message);
       
   457 }
       
   458 
       
   459 bool ChromeClientImpl::shouldInterruptJavaScript()
       
   460 {
       
   461     // FIXME: implement me
       
   462     return false;
       
   463 }
       
   464 
       
   465 bool ChromeClientImpl::tabsToLinks() const
       
   466 {
       
   467     // Returns true if anchors should accept keyboard focus with the tab key.
       
   468     // This method is used in a convoluted fashion by EventHandler::tabsToLinks.
       
   469     // It's a twisted path (self-evident, but more complicated than seems
       
   470     // necessary), but the net result is that returning true from here, on a
       
   471     // platform other than MAC or QT, lets anchors get keyboard focus.
       
   472     return m_webView->tabsToLinks();
       
   473 }
       
   474 
       
   475 IntRect ChromeClientImpl::windowResizerRect() const
       
   476 {
       
   477     IntRect result;
       
   478     if (m_webView->client())
       
   479         result = m_webView->client()->windowResizerRect();
       
   480     return result;
       
   481 }
       
   482 
       
   483 void ChromeClientImpl::invalidateWindow(const IntRect&, bool)
       
   484 {
       
   485     notImplemented();
       
   486 }
       
   487 
       
   488 void ChromeClientImpl::invalidateContentsAndWindow(const IntRect& updateRect, bool /*immediate*/)
       
   489 {
       
   490     if (updateRect.isEmpty())
       
   491         return;
       
   492     if (m_webView->client())
       
   493         m_webView->client()->didInvalidateRect(updateRect);
       
   494 }
       
   495 
       
   496 void ChromeClientImpl::invalidateContentsForSlowScroll(const IntRect& updateRect, bool immediate)
       
   497 {
       
   498     m_webView->hidePopups();
       
   499     invalidateContentsAndWindow(updateRect, immediate);
       
   500 }
       
   501 
       
   502 void ChromeClientImpl::scroll(
       
   503     const IntSize& scrollDelta, const IntRect& scrollRect,
       
   504     const IntRect& clipRect)
       
   505 {
       
   506     m_webView->hidePopups();
       
   507     if (m_webView->client()) {
       
   508         int dx = scrollDelta.width();
       
   509         int dy = scrollDelta.height();
       
   510         m_webView->client()->didScrollRect(dx, dy, clipRect);
       
   511     }
       
   512 }
       
   513 
       
   514 IntPoint ChromeClientImpl::screenToWindow(const IntPoint&) const
       
   515 {
       
   516     notImplemented();
       
   517     return IntPoint();
       
   518 }
       
   519 
       
   520 IntRect ChromeClientImpl::windowToScreen(const IntRect& rect) const
       
   521 {
       
   522     IntRect screenRect(rect);
       
   523 
       
   524     if (m_webView->client()) {
       
   525         WebRect windowRect = m_webView->client()->windowRect();
       
   526         screenRect.move(windowRect.x, windowRect.y);
       
   527     }
       
   528 
       
   529     return screenRect;
       
   530 }
       
   531 
       
   532 void ChromeClientImpl::contentsSizeChanged(Frame* frame, const IntSize& size) const
       
   533 {
       
   534     WebFrameImpl* webframe = WebFrameImpl::fromFrame(frame);
       
   535     if (webframe->client())
       
   536         webframe->client()->didChangeContentsSize(webframe, size);
       
   537 }
       
   538 
       
   539 void ChromeClientImpl::scrollbarsModeDidChange() const
       
   540 {
       
   541 }
       
   542 
       
   543 void ChromeClientImpl::mouseDidMoveOverElement(
       
   544     const HitTestResult& result, unsigned modifierFlags)
       
   545 {
       
   546     if (!m_webView->client())
       
   547         return;
       
   548     // Find out if the mouse is over a link, and if so, let our UI know...
       
   549     if (result.isLiveLink() && !result.absoluteLinkURL().string().isEmpty())
       
   550         m_webView->client()->setMouseOverURL(result.absoluteLinkURL());
       
   551     else
       
   552         m_webView->client()->setMouseOverURL(WebURL());
       
   553 }
       
   554 
       
   555 void ChromeClientImpl::setToolTip(const String& tooltipText, TextDirection dir)
       
   556 {
       
   557     if (!m_webView->client())
       
   558         return;
       
   559     WebTextDirection textDirection = (dir == RTL) ?
       
   560         WebTextDirectionRightToLeft :
       
   561         WebTextDirectionLeftToRight;
       
   562     m_webView->client()->setToolTipText(
       
   563         tooltipText, textDirection);
       
   564 }
       
   565 
       
   566 void ChromeClientImpl::print(Frame* frame)
       
   567 {
       
   568     if (m_webView->client())
       
   569         m_webView->client()->printPage(WebFrameImpl::fromFrame(frame));
       
   570 }
       
   571 
       
   572 void ChromeClientImpl::exceededDatabaseQuota(Frame* frame, const String& databaseName)
       
   573 {
       
   574     // Chromium users cannot currently change the default quota
       
   575 }
       
   576 
       
   577 #if ENABLE(OFFLINE_WEB_APPLICATIONS)
       
   578 void ChromeClientImpl::reachedMaxAppCacheSize(int64_t spaceNeeded)
       
   579 {
       
   580     ASSERT_NOT_REACHED();
       
   581 }
       
   582 #endif
       
   583 
       
   584 void ChromeClientImpl::runOpenPanel(Frame* frame, PassRefPtr<FileChooser> fileChooser)
       
   585 {
       
   586     WebViewClient* client = m_webView->client();
       
   587     if (!client)
       
   588         return;
       
   589 
       
   590     WebFileChooserParams params;
       
   591     params.multiSelect = fileChooser->allowsMultipleFiles();
       
   592 #if ENABLE(DIRECTORY_UPLOAD)
       
   593     params.directory = fileChooser->allowsDirectoryUpload();
       
   594 #else
       
   595     params.directory = false;
       
   596 #endif
       
   597     params.acceptTypes = fileChooser->acceptTypes();
       
   598     params.selectedFiles = fileChooser->filenames();
       
   599     if (params.selectedFiles.size() > 0)
       
   600         params.initialValue = params.selectedFiles[0];
       
   601     WebFileChooserCompletionImpl* chooserCompletion =
       
   602         new WebFileChooserCompletionImpl(fileChooser);
       
   603 
       
   604     if (client->runFileChooser(params, chooserCompletion))
       
   605         return;
       
   606 
       
   607     // Choosing failed, so do callback with an empty list.
       
   608     chooserCompletion->didChooseFile(WebVector<WebString>());
       
   609 }
       
   610 
       
   611 void ChromeClientImpl::chooseIconForFiles(const Vector<WebCore::String>&, WebCore::FileChooser*)
       
   612 {
       
   613     notImplemented();
       
   614 }
       
   615 
       
   616 void ChromeClientImpl::popupOpened(PopupContainer* popupContainer,
       
   617                                    const IntRect& bounds,
       
   618                                    bool handleExternally)
       
   619 {
       
   620     if (!m_webView->client())
       
   621         return;
       
   622 
       
   623     WebWidget* webwidget;
       
   624     if (handleExternally) {
       
   625         WebPopupMenuInfo popupInfo;
       
   626         getPopupMenuInfo(popupContainer, &popupInfo);
       
   627         webwidget = m_webView->client()->createPopupMenu(popupInfo);
       
   628     } else {
       
   629         webwidget = m_webView->client()->createPopupMenu(
       
   630             convertPopupType(popupContainer->popupType()));
       
   631         // We only notify when the WebView has to handle the popup, as when
       
   632         // the popup is handled externally, the fact that a popup is showing is
       
   633         // transparent to the WebView.
       
   634         m_webView->popupOpened(popupContainer);
       
   635     }
       
   636     static_cast<WebPopupMenuImpl*>(webwidget)->Init(popupContainer, bounds);
       
   637 }
       
   638 
       
   639 void ChromeClientImpl::popupClosed(WebCore::PopupContainer* popupContainer)
       
   640 {
       
   641     m_webView->popupClosed(popupContainer);
       
   642 }
       
   643 
       
   644 void ChromeClientImpl::setCursor(const WebCursorInfo& cursor)
       
   645 {
       
   646     if (m_webView->client())
       
   647         m_webView->client()->didChangeCursor(cursor);
       
   648 }
       
   649 
       
   650 void ChromeClientImpl::setCursorForPlugin(const WebCursorInfo& cursor)
       
   651 {
       
   652     setCursor(cursor);
       
   653 }
       
   654 
       
   655 void ChromeClientImpl::formStateDidChange(const Node* node)
       
   656 {
       
   657     // The current history item is not updated yet.  That happens lazily when
       
   658     // WebFrame::currentHistoryItem is requested.
       
   659     WebFrameImpl* webframe = WebFrameImpl::fromFrame(node->document()->frame());
       
   660     if (webframe->client())
       
   661         webframe->client()->didUpdateCurrentHistoryItem(webframe);
       
   662 }
       
   663 
       
   664 void ChromeClientImpl::getPopupMenuInfo(PopupContainer* popupContainer,
       
   665                                         WebPopupMenuInfo* info)
       
   666 {
       
   667     const Vector<PopupItem*>& inputItems = popupContainer->popupData();
       
   668 
       
   669     WebVector<WebPopupMenuInfo::Item> outputItems(inputItems.size());
       
   670 
       
   671     for (size_t i = 0; i < inputItems.size(); ++i) {
       
   672         const PopupItem& inputItem = *inputItems[i];
       
   673         WebPopupMenuInfo::Item& outputItem = outputItems[i];
       
   674 
       
   675         outputItem.label = inputItem.label;
       
   676         outputItem.enabled = inputItem.enabled;
       
   677 
       
   678         switch (inputItem.type) {
       
   679         case PopupItem::TypeOption:
       
   680             outputItem.type = WebPopupMenuInfo::Item::Option;
       
   681             break;
       
   682         case PopupItem::TypeGroup:
       
   683             outputItem.type = WebPopupMenuInfo::Item::Group;
       
   684             break;
       
   685         case PopupItem::TypeSeparator:
       
   686             outputItem.type = WebPopupMenuInfo::Item::Separator;
       
   687             break;
       
   688         default:
       
   689             ASSERT_NOT_REACHED();
       
   690         }
       
   691     }
       
   692 
       
   693     info->itemHeight = popupContainer->menuItemHeight();
       
   694     info->itemFontSize = popupContainer->menuItemFontSize();
       
   695     info->selectedIndex = popupContainer->selectedIndex();
       
   696     info->items.swap(outputItems);
       
   697     info->rightAligned = popupContainer->menuStyle().textDirection() == RTL;
       
   698 }
       
   699 
       
   700 void ChromeClientImpl::didChangeAccessibilityObjectState(AccessibilityObject* obj)
       
   701 {
       
   702     // Alert assistive technology about the accessibility object state change
       
   703     if (obj)
       
   704         m_webView->client()->didChangeAccessibilityObjectState(WebAccessibilityObject(obj));
       
   705 }
       
   706 
       
   707 #if ENABLE(NOTIFICATIONS)
       
   708 NotificationPresenter* ChromeClientImpl::notificationPresenter() const
       
   709 {
       
   710     return m_webView->notificationPresenterImpl();
       
   711 }
       
   712 #endif
       
   713 
       
   714 void ChromeClientImpl::requestGeolocationPermissionForFrame(Frame* frame, Geolocation* geolocation)
       
   715 {
       
   716     GeolocationServiceChromium* geolocationService = static_cast<GeolocationServiceChromium*>(geolocation->getGeolocationService());
       
   717     geolocationService->geolocationServiceBridge()->attachBridgeIfNeeded();
       
   718     m_webView->client()->geolocationService()->requestPermissionForFrame(geolocationService->geolocationServiceBridge()->getBridgeId(), frame->document()->url());
       
   719 }
       
   720 
       
   721 void ChromeClientImpl::cancelGeolocationPermissionRequestForFrame(Frame* frame, Geolocation* geolocation)
       
   722 {
       
   723     GeolocationServiceChromium* geolocationService = static_cast<GeolocationServiceChromium*>(geolocation->getGeolocationService());
       
   724     m_webView->client()->geolocationService()->cancelPermissionRequestForFrame(geolocationService->geolocationServiceBridge()->getBridgeId(), frame->document()->url());
       
   725 }
       
   726 
       
   727 #if USE(ACCELERATED_COMPOSITING)
       
   728 void ChromeClientImpl::attachRootGraphicsLayer(Frame* frame, GraphicsLayer* graphicsLayer)
       
   729 {
       
   730     m_webView->setRootGraphicsLayer(graphicsLayer ? graphicsLayer->platformLayer() : 0);
       
   731 }
       
   732 
       
   733 void ChromeClientImpl::scheduleCompositingLayerSync()
       
   734 {
       
   735     m_webView->setRootLayerNeedsDisplay();
       
   736 }
       
   737 
       
   738 PassOwnPtr<GLES2Context> ChromeClientImpl::getOnscreenGLES2Context()
       
   739 {
       
   740     return m_webView->getOnscreenGLES2Context();
       
   741 }
       
   742 
       
   743 PassOwnPtr<GLES2Context> ChromeClientImpl::getOffscreenGLES2Context()
       
   744 {
       
   745     return m_webView->getOffscreenGLES2Context();
       
   746 }
       
   747 #endif
       
   748 
       
   749 bool ChromeClientImpl::supportsFullscreenForNode(const WebCore::Node* node)
       
   750 {
       
   751     if (m_webView->client() && node->hasTagName(WebCore::HTMLNames::videoTag))
       
   752         return m_webView->client()->supportsFullscreen();
       
   753     return false;
       
   754 }
       
   755 
       
   756 void ChromeClientImpl::enterFullscreenForNode(WebCore::Node* node)
       
   757 {
       
   758     if (m_webView->client())
       
   759         m_webView->client()->enterFullscreenForNode(WebNode(node));
       
   760 }
       
   761 
       
   762 void ChromeClientImpl::exitFullscreenForNode(WebCore::Node* node)
       
   763 {
       
   764     if (m_webView->client())
       
   765         m_webView->client()->exitFullscreenForNode(WebNode(node));
       
   766 }
       
   767 
       
   768 } // namespace WebKit