2 * Copyright (C) 2009 Google Inc. All rights reserved.
3 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
15 * * Neither the name of Google Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 #include "web/ChromeClientImpl.h"
35 #include "bindings/core/v8/ScriptController.h"
36 #include "core/HTMLNames.h"
37 #include "core/dom/AXObjectCache.h"
38 #include "core/dom/Document.h"
39 #include "core/dom/Fullscreen.h"
40 #include "core/dom/Node.h"
41 #include "core/events/UIEventWithKeyState.h"
42 #include "core/frame/Console.h"
43 #include "core/frame/FrameHost.h"
44 #include "core/frame/FrameView.h"
45 #include "core/frame/Settings.h"
46 #include "core/html/HTMLInputElement.h"
47 #include "core/html/forms/ColorChooser.h"
48 #include "core/html/forms/ColorChooserClient.h"
49 #include "core/html/forms/DateTimeChooser.h"
50 #include "core/layout/HitTestResult.h"
51 #include "core/layout/LayoutPart.h"
52 #include "core/layout/compositing/CompositedSelection.h"
53 #include "core/loader/DocumentLoader.h"
54 #include "core/loader/FrameLoadRequest.h"
55 #include "core/page/Page.h"
56 #include "core/page/PopupOpeningObserver.h"
57 #include "modules/accessibility/AXObject.h"
58 #include "platform/Cursor.h"
59 #include "platform/FileChooser.h"
60 #include "platform/KeyboardCodes.h"
61 #include "platform/RuntimeEnabledFeatures.h"
62 #include "platform/exported/WrappedResourceRequest.h"
63 #include "platform/geometry/IntRect.h"
64 #include "platform/graphics/GraphicsLayer.h"
65 #include "platform/weborigin/SecurityOrigin.h"
66 #include "public/platform/Platform.h"
67 #include "public/platform/WebCursorInfo.h"
68 #include "public/platform/WebRect.h"
69 #include "public/platform/WebURLRequest.h"
70 #include "public/web/WebAXObject.h"
71 #include "public/web/WebAutofillClient.h"
72 #include "public/web/WebColorChooser.h"
73 #include "public/web/WebColorSuggestion.h"
74 #include "public/web/WebConsoleMessage.h"
75 #include "public/web/WebFrameClient.h"
76 #include "public/web/WebInputElement.h"
77 #include "public/web/WebInputEvent.h"
78 #include "public/web/WebKit.h"
79 #include "public/web/WebNode.h"
80 #include "public/web/WebPlugin.h"
81 #include "public/web/WebPopupMenuInfo.h"
82 #include "public/web/WebSelection.h"
83 #include "public/web/WebSettings.h"
84 #include "public/web/WebTextDirection.h"
85 #include "public/web/WebTouchAction.h"
86 #include "public/web/WebUserGestureIndicator.h"
87 #include "public/web/WebUserGestureToken.h"
88 #include "public/web/WebViewClient.h"
89 #include "public/web/WebWindowFeatures.h"
90 #include "web/ColorChooserPopupUIController.h"
91 #include "web/ColorChooserUIController.h"
92 #include "web/DateTimeChooserImpl.h"
93 #include "web/ExternalDateTimeChooser.h"
94 #include "web/ExternalPopupMenu.h"
95 #include "web/PopupMenuImpl.h"
96 #include "web/WebFileChooserCompletionImpl.h"
97 #include "web/WebFrameWidgetImpl.h"
98 #include "web/WebInputEventConversion.h"
99 #include "web/WebLocalFrameImpl.h"
100 #include "web/WebPluginContainerImpl.h"
101 #include "web/WebSettingsImpl.h"
102 #include "web/WebViewImpl.h"
103 #include "wtf/text/CString.h"
104 #include "wtf/text/CharacterNames.h"
105 #include "wtf/text/StringBuilder.h"
106 #include "wtf/text/StringConcatenate.h"
110 class WebCompositorAnimationTimeline
;
112 // Converts a AXObjectCache::AXNotification to a WebAXEvent
113 static WebAXEvent
toWebAXEvent(AXObjectCache::AXNotification notification
)
115 // These enums have the same values; enforced in AssertMatchingEnums.cpp.
116 return static_cast<WebAXEvent
>(notification
);
119 ChromeClientImpl::ChromeClientImpl(WebViewImpl
* webView
)
121 , m_cursorOverridden(false)
125 ChromeClientImpl::~ChromeClientImpl()
129 PassOwnPtrWillBeRawPtr
<ChromeClientImpl
> ChromeClientImpl::create(WebViewImpl
* webView
)
131 return adoptPtrWillBeNoop(new ChromeClientImpl(webView
));
134 void* ChromeClientImpl::webView() const
136 return static_cast<void*>(m_webView
);
139 void ChromeClientImpl::chromeDestroyed()
141 // Our lifetime is bound to the WebViewImpl.
144 void ChromeClientImpl::setWindowRect(const IntRect
& r
)
146 if (m_webView
->client())
147 m_webView
->client()->setWindowRect(r
);
150 IntRect
ChromeClientImpl::windowRect()
153 if (m_webView
->client()) {
154 rect
= m_webView
->client()->rootWindowRect();
156 // These numbers will be fairly wrong. The window's x/y coordinates will
157 // be the top left corner of the screen and the size will be the content
158 // size instead of the window size.
159 rect
.width
= m_webView
->size().width
;
160 rect
.height
= m_webView
->size().height
;
162 return IntRect(rect
);
165 IntRect
ChromeClientImpl::pageRect()
167 // We hide the details of the window's border thickness from the web page by
168 // simple re-using the window position here. So, from the point-of-view of
169 // the web page, the window has no border.
173 void ChromeClientImpl::focus()
175 if (m_webView
->client())
176 m_webView
->client()->didFocus();
179 bool ChromeClientImpl::canTakeFocus(WebFocusType
)
181 // For now the browser can always take focus if we're not running layout
183 return !layoutTestMode();
186 void ChromeClientImpl::takeFocus(WebFocusType type
)
188 if (!m_webView
->client())
190 if (type
== WebFocusTypeBackward
)
191 m_webView
->client()->focusPrevious();
193 m_webView
->client()->focusNext();
196 void ChromeClientImpl::focusedNodeChanged(Node
* fromNode
, Node
* toNode
)
198 if (!m_webView
->client())
201 m_webView
->client()->focusedNodeChanged(WebNode(fromNode
), WebNode(toNode
));
204 if (toNode
&& toNode
->isElementNode() && toElement(toNode
)->isLiveLink() && toNode
->shouldHaveFocusAppearance())
205 focusURL
= toElement(toNode
)->hrefURL();
206 m_webView
->client()->setKeyboardFocusURL(focusURL
);
209 void ChromeClientImpl::focusedFrameChanged(LocalFrame
* frame
)
211 WebLocalFrameImpl
* webframe
= WebLocalFrameImpl::fromFrame(frame
);
212 if (webframe
&& webframe
->client())
213 webframe
->client()->frameFocused();
216 bool ChromeClientImpl::hadFormInteraction() const
218 return m_webView
->pageImportanceSignals() && m_webView
->pageImportanceSignals()->hadFormInteraction();
223 void updatePolicyForEvent(const WebInputEvent
* inputEvent
, NavigationPolicy
* policy
)
228 unsigned short buttonNumber
= 0;
229 if (inputEvent
->type
== WebInputEvent::MouseUp
) {
231 const WebMouseEvent
* mouseEvent
= static_cast<const WebMouseEvent
*>(inputEvent
);
233 switch (mouseEvent
->button
) {
234 case WebMouseEvent::ButtonLeft
:
237 case WebMouseEvent::ButtonMiddle
:
240 case WebMouseEvent::ButtonRight
:
246 } else if ((WebInputEvent::isKeyboardEventType(inputEvent
->type
) && static_cast<const WebKeyboardEvent
*>(inputEvent
)->windowsKeyCode
== VKEY_RETURN
) || WebInputEvent::isGestureEventType(inputEvent
->type
)) {
247 // Keyboard and gesture events can simulate mouse events.
253 bool ctrl
= inputEvent
->modifiers
& WebInputEvent::ControlKey
;
254 bool shift
= inputEvent
->modifiers
& WebInputEvent::ShiftKey
;
255 bool alt
= inputEvent
->modifiers
& WebInputEvent::AltKey
;
256 bool meta
= inputEvent
->modifiers
& WebInputEvent::MetaKey
;
258 NavigationPolicy userPolicy
= *policy
;
259 navigationPolicyFromMouseEvent(buttonNumber
, ctrl
, shift
, alt
, meta
, &userPolicy
);
261 // When the input event suggests a download, but the navigation was initiated
262 // by script, we should not override it.
263 if (userPolicy
== NavigationPolicyDownload
&& *policy
!= NavigationPolicyIgnore
)
266 // User and app agree that we want a new window; let the app override the decorations.
267 if (userPolicy
== NavigationPolicyNewWindow
&& *policy
== NavigationPolicyNewPopup
)
269 *policy
= userPolicy
;
272 WebNavigationPolicy
getNavigationPolicy(const WindowFeatures
& features
)
274 // If our default configuration was modified by a script or wasn't
275 // created by a user gesture, then show as a popup. Else, let this
276 // new window be opened as a toplevel window.
277 bool asPopup
= !features
.toolBarVisible
278 || !features
.statusBarVisible
279 || !features
.scrollbarsVisible
280 || !features
.menuBarVisible
281 || !features
.resizable
;
283 NavigationPolicy policy
= NavigationPolicyNewForegroundTab
;
285 policy
= NavigationPolicyNewPopup
;
286 updatePolicyForEvent(WebViewImpl::currentInputEvent(), &policy
);
288 return static_cast<WebNavigationPolicy
>(policy
);
291 WebNavigationPolicy
effectiveNavigationPolicy(NavigationPolicy navigationPolicy
, const WindowFeatures
& features
)
293 WebNavigationPolicy policy
= static_cast<WebNavigationPolicy
>(navigationPolicy
);
294 if (policy
== WebNavigationPolicyIgnore
)
295 return getNavigationPolicy(features
);
296 if (policy
== WebNavigationPolicyNewBackgroundTab
&& getNavigationPolicy(features
) != WebNavigationPolicyNewBackgroundTab
&& !UIEventWithKeyState::newTabModifierSetFromIsolatedWorld())
297 return WebNavigationPolicyNewForegroundTab
;
304 Page
* ChromeClientImpl::createWindow(LocalFrame
* frame
, const FrameLoadRequest
& r
, const WindowFeatures
& features
,
305 NavigationPolicy navigationPolicy
, ShouldSendReferrer shouldSendReferrer
)
307 if (!m_webView
->client())
310 WebNavigationPolicy policy
= effectiveNavigationPolicy(navigationPolicy
, features
);
311 ASSERT(frame
->document());
312 Fullscreen::fullyExitFullscreen(*frame
->document());
314 WebViewImpl
* newView
= toWebViewImpl(
315 m_webView
->client()->createView(WebLocalFrameImpl::fromFrame(frame
), WrappedResourceRequest(r
.resourceRequest()), features
, r
.frameName(), policy
, shouldSendReferrer
== NeverSendReferrer
));
318 return newView
->page();
321 void ChromeClientImpl::didOverscroll(const FloatSize
& unusedDelta
, const FloatSize
& accumulatedRootOverScroll
, const FloatPoint
& position
, const FloatSize
& velocity
)
323 if (!m_webView
->client())
326 m_webView
->client()->didOverscroll(unusedDelta
, accumulatedRootOverScroll
, position
, velocity
);
329 void ChromeClientImpl::show(NavigationPolicy navigationPolicy
)
331 if (m_webView
->client())
332 m_webView
->client()->show(effectiveNavigationPolicy(navigationPolicy
, m_windowFeatures
));
335 void ChromeClientImpl::setToolbarsVisible(bool value
)
337 m_windowFeatures
.toolBarVisible
= value
;
340 bool ChromeClientImpl::toolbarsVisible()
342 return m_windowFeatures
.toolBarVisible
;
345 void ChromeClientImpl::setStatusbarVisible(bool value
)
347 m_windowFeatures
.statusBarVisible
= value
;
350 bool ChromeClientImpl::statusbarVisible()
352 return m_windowFeatures
.statusBarVisible
;
355 void ChromeClientImpl::setScrollbarsVisible(bool value
)
357 m_windowFeatures
.scrollbarsVisible
= value
;
358 if (WebLocalFrameImpl
* webFrame
= toWebLocalFrameImpl(m_webView
->mainFrame()))
359 webFrame
->setCanHaveScrollbars(value
);
362 bool ChromeClientImpl::scrollbarsVisible()
364 return m_windowFeatures
.scrollbarsVisible
;
367 void ChromeClientImpl::setMenubarVisible(bool value
)
369 m_windowFeatures
.menuBarVisible
= value
;
372 bool ChromeClientImpl::menubarVisible()
374 return m_windowFeatures
.menuBarVisible
;
377 void ChromeClientImpl::setResizable(bool value
)
379 m_windowFeatures
.resizable
= value
;
382 bool ChromeClientImpl::shouldReportDetailedMessageForSource(LocalFrame
& localFrame
, const String
& url
)
384 WebLocalFrameImpl
* webframe
= WebLocalFrameImpl::fromFrame(localFrame
.localFrameRoot());
385 return webframe
&& webframe
->client() && webframe
->client()->shouldReportDetailedMessageForSource(url
);
388 void ChromeClientImpl::addMessageToConsole(LocalFrame
* localFrame
, MessageSource source
, MessageLevel level
, const String
& message
, unsigned lineNumber
, const String
& sourceID
, const String
& stackTrace
)
390 WebLocalFrameImpl
* frame
= WebLocalFrameImpl::fromFrame(localFrame
);
391 if (frame
&& frame
->client()) {
392 frame
->client()->didAddMessageToConsole(
393 WebConsoleMessage(static_cast<WebConsoleMessage::Level
>(level
), message
),
400 bool ChromeClientImpl::canOpenBeforeUnloadConfirmPanel()
402 return !!m_webView
->client();
405 bool ChromeClientImpl::openBeforeUnloadConfirmPanelDelegate(LocalFrame
* frame
, const String
& message
)
407 notifyPopupOpeningObservers();
408 WebLocalFrameImpl
* webframe
= WebLocalFrameImpl::fromFrame(frame
);
410 WebDataSource
* ds
= webframe
->provisionalDataSource();
411 bool isReload
= ds
&& (ds
->navigationType() == WebNavigationTypeReload
);
413 if (webframe
->client())
414 return webframe
->client()->runModalBeforeUnloadDialog(isReload
, message
);
418 void ChromeClientImpl::closeWindowSoon()
420 // Make sure this Page can no longer be found by JS.
421 Page::ordinaryPages().remove(m_webView
->page());
423 // Make sure that all loading is stopped. Ensures that JS stops executing!
424 m_webView
->mainFrame()->stopLoading();
426 if (m_webView
->client())
427 m_webView
->client()->closeWidgetSoon();
430 // Although a LocalFrame is passed in, we don't actually use it, since we
431 // already know our own m_webView.
432 bool ChromeClientImpl::openJavaScriptAlertDelegate(LocalFrame
* frame
, const String
& message
)
434 notifyPopupOpeningObservers();
435 WebLocalFrameImpl
* webframe
= WebLocalFrameImpl::fromFrame(frame
);
436 if (webframe
->client()) {
437 if (WebUserGestureIndicator::isProcessingUserGesture())
438 WebUserGestureIndicator::currentUserGestureToken().setJavascriptPrompt();
439 webframe
->client()->runModalAlertDialog(message
);
445 // See comments for openJavaScriptAlertDelegate().
446 bool ChromeClientImpl::openJavaScriptConfirmDelegate(LocalFrame
* frame
, const String
& message
)
448 notifyPopupOpeningObservers();
449 WebLocalFrameImpl
* webframe
= WebLocalFrameImpl::fromFrame(frame
);
450 if (webframe
->client()) {
451 if (WebUserGestureIndicator::isProcessingUserGesture())
452 WebUserGestureIndicator::currentUserGestureToken().setJavascriptPrompt();
453 return webframe
->client()->runModalConfirmDialog(message
);
458 // See comments for openJavaScriptAlertDelegate().
459 bool ChromeClientImpl::openJavaScriptPromptDelegate(LocalFrame
* frame
, const String
& message
, const String
& defaultValue
, String
& result
)
461 notifyPopupOpeningObservers();
462 WebLocalFrameImpl
* webframe
= WebLocalFrameImpl::fromFrame(frame
);
463 if (webframe
->client()) {
464 if (WebUserGestureIndicator::isProcessingUserGesture())
465 WebUserGestureIndicator::currentUserGestureToken().setJavascriptPrompt();
466 WebString actualValue
;
467 bool ok
= webframe
->client()->runModalPromptDialog(message
, defaultValue
, &actualValue
);
469 result
= actualValue
;
475 void ChromeClientImpl::setStatusbarText(const String
& message
)
477 if (m_webView
->client())
478 m_webView
->client()->setStatusText(message
);
481 bool ChromeClientImpl::tabsToLinks()
483 return m_webView
->tabsToLinks();
486 IntRect
ChromeClientImpl::windowResizerRect() const
488 if (m_webView
->client())
489 return m_webView
->client()->windowResizerRect();
493 void ChromeClientImpl::invalidateRect(const IntRect
& updateRect
)
495 if (!updateRect
.isEmpty())
496 m_webView
->invalidateRect(updateRect
);
499 void ChromeClientImpl::scheduleAnimation()
501 m_webView
->scheduleAnimation();
504 void ChromeClientImpl::scheduleAnimationForFrame(LocalFrame
* localRoot
)
506 ASSERT(WebLocalFrameImpl::fromFrame(localRoot
));
507 // If the frame is still being created, it might not yet have a WebWidget.
508 // FIXME: Is this the right thing to do? Is there a way to avoid having
509 // a local frame root that doesn't have a WebWidget? During initialization
510 // there is no content to draw so this call serves no purpose.
511 if (WebLocalFrameImpl::fromFrame(localRoot
)->frameWidget())
512 toWebFrameWidgetImpl(WebLocalFrameImpl::fromFrame(localRoot
)->frameWidget())->scheduleAnimation();
515 IntRect
ChromeClientImpl::viewportToScreen(const IntRect
& rectInViewport
) const
517 IntRect
screenRect(rectInViewport
);
519 if (m_webView
->client()) {
520 WebRect windowRect
= m_webView
->client()->windowRect();
521 screenRect
.move(windowRect
.x
, windowRect
.y
);
527 WebScreenInfo
ChromeClientImpl::screenInfo() const
529 return m_webView
->client() ? m_webView
->client()->screenInfo() : WebScreenInfo();
532 void ChromeClientImpl::contentsSizeChanged(LocalFrame
* frame
, const IntSize
& size
) const
534 m_webView
->didChangeContentsSize();
536 WebLocalFrameImpl
* webframe
= WebLocalFrameImpl::fromFrame(frame
);
537 webframe
->didChangeContentsSize(size
);
540 void ChromeClientImpl::pageScaleFactorChanged() const
542 m_webView
->pageScaleFactorChanged();
545 float ChromeClientImpl::clampPageScaleFactorToLimits(float scale
) const
547 return m_webView
->clampPageScaleFactorToLimits(scale
);
550 void ChromeClientImpl::layoutUpdated(LocalFrame
* frame
) const
552 m_webView
->layoutUpdated(WebLocalFrameImpl::fromFrame(frame
));
555 void ChromeClientImpl::showMouseOverURL(const HitTestResult
& result
)
557 if (!m_webView
->client())
561 // Find out if the mouse is over a link, and if so, let our UI know...
562 if (result
.isLiveLink() && !result
.absoluteLinkURL().string().isEmpty()) {
563 url
= result
.absoluteLinkURL();
564 } else if (result
.innerNode()
565 && (isHTMLObjectElement(*result
.innerNode())
566 || isHTMLEmbedElement(*result
.innerNode()))) {
567 LayoutObject
* object
= result
.innerNode()->layoutObject();
568 if (object
&& object
->isLayoutPart()) {
569 Widget
* widget
= toLayoutPart(object
)->widget();
570 if (widget
&& widget
->isPluginContainer()) {
571 WebPluginContainerImpl
* plugin
= toWebPluginContainerImpl(widget
);
572 url
= plugin
->plugin()->linkAtPosition(result
.roundedPointInInnerNodeFrame());
577 m_webView
->client()->setMouseOverURL(url
);
580 void ChromeClientImpl::setToolTip(const String
& tooltipText
, TextDirection dir
)
582 if (m_webView
->client())
583 m_webView
->client()->setToolTipText(tooltipText
, toWebTextDirection(dir
));
586 void ChromeClientImpl::dispatchViewportPropertiesDidChange(const ViewportDescription
& description
) const
588 m_webView
->updatePageDefinedViewportConstraints(description
);
591 void ChromeClientImpl::printDelegate(LocalFrame
* frame
)
593 if (m_webView
->client())
594 m_webView
->client()->printPage(WebLocalFrameImpl::fromFrame(frame
));
597 PassOwnPtrWillBeRawPtr
<ColorChooser
> ChromeClientImpl::openColorChooser(LocalFrame
* frame
, ColorChooserClient
* chooserClient
, const Color
&)
599 notifyPopupOpeningObservers();
600 OwnPtrWillBeRawPtr
<ColorChooserUIController
> controller
= nullptr;
601 if (RuntimeEnabledFeatures::pagePopupEnabled())
602 controller
= ColorChooserPopupUIController::create(frame
, this, chooserClient
);
604 controller
= ColorChooserUIController::create(frame
, chooserClient
);
605 controller
->openUI();
606 return controller
.release();
609 PassRefPtr
<DateTimeChooser
> ChromeClientImpl::openDateTimeChooser(DateTimeChooserClient
* pickerClient
, const DateTimeChooserParameters
& parameters
)
611 notifyPopupOpeningObservers();
612 #if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
613 return DateTimeChooserImpl::create(this, pickerClient
, parameters
);
615 return ExternalDateTimeChooser::create(this, m_webView
->client(), pickerClient
, parameters
);
619 void ChromeClientImpl::openFileChooser(LocalFrame
* frame
, PassRefPtr
<FileChooser
> fileChooser
)
621 notifyPopupOpeningObservers();
622 WebViewClient
* client
= m_webView
->client();
626 WebFileChooserParams params
;
627 params
.multiSelect
= fileChooser
->settings().allowsMultipleFiles
;
628 params
.directory
= fileChooser
->settings().allowsDirectoryUpload
;
629 params
.acceptTypes
= fileChooser
->settings().acceptTypes();
630 params
.selectedFiles
= fileChooser
->settings().selectedFiles
;
631 if (params
.selectedFiles
.size() > 0)
632 params
.initialValue
= params
.selectedFiles
[0];
633 params
.useMediaCapture
= fileChooser
->settings().useMediaCapture
;
634 params
.needLocalPath
= fileChooser
->settings().allowsDirectoryUpload
;
636 WebFileChooserCompletionImpl
* chooserCompletion
= new WebFileChooserCompletionImpl(fileChooser
);
637 if (client
->runFileChooser(params
, chooserCompletion
))
639 // Choosing failed, so do callback with an empty list.
640 chooserCompletion
->didChooseFile(WebVector
<WebString
>());
643 void ChromeClientImpl::enumerateChosenDirectory(FileChooser
* fileChooser
)
645 WebViewClient
* client
= m_webView
->client();
649 WebFileChooserCompletionImpl
* chooserCompletion
= new WebFileChooserCompletionImpl(fileChooser
);
652 ASSERT(fileChooser
->settings().selectedFiles
.size());
654 // If the enumeration can't happen, call the callback with an empty list.
655 if (!client
->enumerateChosenDirectory(fileChooser
->settings().selectedFiles
[0], chooserCompletion
))
656 chooserCompletion
->didChooseFile(WebVector
<WebString
>());
659 Cursor
ChromeClientImpl::lastSetCursorForTesting() const
661 return m_lastSetMouseCursorForTesting
;
664 void ChromeClientImpl::setCursor(const Cursor
& cursor
)
666 m_lastSetMouseCursorForTesting
= cursor
;
667 setCursor(WebCursorInfo(cursor
));
670 void ChromeClientImpl::setCursor(const WebCursorInfo
& cursor
)
672 if (m_cursorOverridden
)
676 // On Mac the mousemove event propagates to both the popup and main window.
677 // If a popup is open we don't want the main window to change the cursor.
678 if (m_webView
->hasOpenedPopup())
681 if (m_webView
->client())
682 m_webView
->client()->didChangeCursor(cursor
);
685 void ChromeClientImpl::setCursorForPlugin(const WebCursorInfo
& cursor
)
690 void ChromeClientImpl::setCursorOverridden(bool overridden
)
692 m_cursorOverridden
= overridden
;
695 void ChromeClientImpl::postAccessibilityNotification(AXObject
* obj
, AXObjectCache::AXNotification notification
)
697 // Alert assistive technology about the accessibility object notification.
698 if (!obj
|| !obj
->document())
701 WebLocalFrameImpl
* webframe
= WebLocalFrameImpl::fromFrame(obj
->document()->axObjectCacheOwner().frame());
702 if (webframe
&& webframe
->client())
703 webframe
->client()->postAccessibilityEvent(WebAXObject(obj
), toWebAXEvent(notification
));
706 String
ChromeClientImpl::acceptLanguages()
708 return m_webView
->client()->acceptLanguages();
711 GraphicsLayerFactory
* ChromeClientImpl::graphicsLayerFactory() const
713 return m_webView
->graphicsLayerFactory();
716 void ChromeClientImpl::attachRootGraphicsLayer(GraphicsLayer
* rootLayer
, LocalFrame
* localRoot
)
718 // FIXME: For top-level frames we still use the WebView as a WebWidget. This
719 // special case will be removed when top-level frames get WebFrameWidgets.
720 if (localRoot
->isMainFrame()) {
721 m_webView
->setRootGraphicsLayer(rootLayer
);
723 WebLocalFrameImpl
* webFrame
= WebLocalFrameImpl::fromFrame(localRoot
);
724 // FIXME: The following conditional is only needed for staging until the
725 // Chromium patch lands that instantiates a WebFrameWidget.
726 if (!webFrame
->frameWidget()) {
727 m_webView
->setRootGraphicsLayer(rootLayer
);
731 ASSERT(webFrame
->frameWidget());
732 toWebFrameWidgetImpl(webFrame
->frameWidget())->setRootGraphicsLayer(rootLayer
);
736 void ChromeClientImpl::setCompositedDisplayList(PassOwnPtr
<CompositedDisplayList
> compositedDisplayList
)
738 m_webView
->setCompositedDisplayList(compositedDisplayList
);
741 CompositedDisplayList
* ChromeClientImpl::compositedDisplayListForTesting()
743 if (WebCompositedDisplayList
* compositedDisplayList
= m_webView
->compositedDisplayList())
744 return compositedDisplayList
->compositedDisplayListForTesting();
748 void ChromeClientImpl::attachCompositorAnimationTimeline(WebCompositorAnimationTimeline
* compositorTimeline
, LocalFrame
* localRoot
)
750 // FIXME: For top-level frames we still use the WebView as a WebWidget. This
751 // special case will be removed when top-level frames get WebFrameWidgets.
752 if (localRoot
->isMainFrame()) {
753 m_webView
->attachCompositorAnimationTimeline(compositorTimeline
);
755 WebLocalFrameImpl
* webFrame
= WebLocalFrameImpl::fromFrame(localRoot
);
756 // FIXME: The following conditional is only needed for staging until the
757 // Chromium patch lands that instantiates a WebFrameWidget.
758 if (!webFrame
->frameWidget()) {
759 m_webView
->attachCompositorAnimationTimeline(compositorTimeline
);
763 ASSERT(webFrame
->frameWidget());
764 toWebFrameWidgetImpl(webFrame
->frameWidget())->attachCompositorAnimationTimeline(compositorTimeline
);
768 void ChromeClientImpl::detachCompositorAnimationTimeline(WebCompositorAnimationTimeline
* compositorTimeline
, LocalFrame
* localRoot
)
770 // FIXME: For top-level frames we still use the WebView as a WebWidget. This
771 // special case will be removed when top-level frames get WebFrameWidgets.
772 if (localRoot
->isMainFrame()) {
773 m_webView
->detachCompositorAnimationTimeline(compositorTimeline
);
775 WebLocalFrameImpl
* webFrame
= WebLocalFrameImpl::fromFrame(localRoot
);
776 // FIXME: The following conditional is only needed for staging until the
777 // Chromium patch lands that instantiates a WebFrameWidget.
778 if (!webFrame
->frameWidget()) {
779 m_webView
->detachCompositorAnimationTimeline(compositorTimeline
);
783 ASSERT(webFrame
->frameWidget());
784 toWebFrameWidgetImpl(webFrame
->frameWidget())->detachCompositorAnimationTimeline(compositorTimeline
);
788 void ChromeClientImpl::enterFullScreenForElement(Element
* element
)
790 m_webView
->enterFullScreenForElement(element
);
793 void ChromeClientImpl::exitFullScreenForElement(Element
* element
)
795 m_webView
->exitFullScreenForElement(element
);
798 void ChromeClientImpl::clearCompositedSelection()
800 m_webView
->clearCompositedSelection();
803 void ChromeClientImpl::updateCompositedSelection(const CompositedSelection
& selection
)
805 m_webView
->updateCompositedSelection(WebSelection(selection
));
808 bool ChromeClientImpl::hasOpenedPopup() const
810 return m_webView
->hasOpenedPopup();
813 PassRefPtrWillBeRawPtr
<PopupMenu
> ChromeClientImpl::openPopupMenu(LocalFrame
& frame
, HTMLSelectElement
& select
)
815 notifyPopupOpeningObservers();
816 if (WebViewImpl::useExternalPopupMenus())
817 return adoptRefWillBeNoop(new ExternalPopupMenu(frame
, select
, *m_webView
));
819 ASSERT(RuntimeEnabledFeatures::pagePopupEnabled());
820 return PopupMenuImpl::create(this, select
);
823 PagePopup
* ChromeClientImpl::openPagePopup(PagePopupClient
* client
)
825 return m_webView
->openPagePopup(client
);
828 void ChromeClientImpl::closePagePopup(PagePopup
* popup
)
830 m_webView
->closePagePopup(popup
);
833 DOMWindow
* ChromeClientImpl::pagePopupWindowForTesting() const
835 return m_webView
->pagePopupWindow();
838 bool ChromeClientImpl::shouldOpenModalDialogDuringPageDismissal(const DialogType
& dialogType
, const String
& dialogMessage
, Document::PageDismissalType dismissalType
) const
840 const char* kDialogs
[] = {"alert", "confirm", "prompt"};
841 int dialog
= static_cast<int>(dialogType
);
842 ASSERT_WITH_SECURITY_IMPLICATION(0 <= dialog
);
843 ASSERT_WITH_SECURITY_IMPLICATION(dialog
< static_cast<int>(arraysize(kDialogs
)));
845 const char* kDismissals
[] = {"beforeunload", "pagehide", "unload"};
846 int dismissal
= static_cast<int>(dismissalType
) - 1; // Exclude NoDismissal.
847 ASSERT_WITH_SECURITY_IMPLICATION(0 <= dismissal
);
848 ASSERT_WITH_SECURITY_IMPLICATION(dismissal
< static_cast<int>(arraysize(kDismissals
)));
850 Platform::current()->histogramEnumeration("Renderer.ModalDialogsDuringPageDismissal", dismissal
* arraysize(kDialogs
) + dialog
, arraysize(kDialogs
) * arraysize(kDismissals
));
852 String message
= String("Blocked ") + kDialogs
[dialog
] + "('" + dialogMessage
+ "') during " + kDismissals
[dismissal
] + ".";
853 m_webView
->mainFrame()->addMessageToConsole(WebConsoleMessage(WebConsoleMessage::LevelError
, message
));
858 void ChromeClientImpl::needTouchEvents(bool needsTouchEvents
)
860 m_webView
->hasTouchEventHandlers(needsTouchEvents
);
863 void ChromeClientImpl::setTouchAction(TouchAction touchAction
)
865 if (WebViewClient
* client
= m_webView
->client())
866 client
->setTouchAction(static_cast<WebTouchAction
>(touchAction
));
869 bool ChromeClientImpl::requestPointerLock()
871 return m_webView
->requestPointerLock();
874 void ChromeClientImpl::requestPointerUnlock()
876 return m_webView
->requestPointerUnlock();
879 void ChromeClientImpl::annotatedRegionsChanged()
881 if (WebViewClient
* client
= m_webView
->client())
882 client
->draggableRegionsChanged();
885 void ChromeClientImpl::didAssociateFormControls(const WillBeHeapVector
<RefPtrWillBeMember
<Element
>>& elements
, LocalFrame
* frame
)
887 WebLocalFrameImpl
* webframe
= WebLocalFrameImpl::fromFrame(frame
);
888 if (webframe
->autofillClient())
889 webframe
->autofillClient()->didAssociateFormControls(elements
);
892 void ChromeClientImpl::didCancelCompositionOnSelectionChange()
894 if (m_webView
->client())
895 m_webView
->client()->didCancelCompositionOnSelectionChange();
898 void ChromeClientImpl::willSetInputMethodState()
900 if (m_webView
->client())
901 m_webView
->client()->resetInputMethod();
904 void ChromeClientImpl::didUpdateTextOfFocusedElementByNonUserInput()
906 if (m_webView
->client())
907 m_webView
->client()->didUpdateTextOfFocusedElementByNonUserInput();
910 void ChromeClientImpl::showImeIfNeeded()
912 if (m_webView
->client())
913 m_webView
->client()->showImeIfNeeded();
916 void ChromeClientImpl::showUnhandledTapUIIfNeeded(IntPoint tappedPositionInViewport
, Node
* tappedNode
, bool pageChanged
)
918 if (m_webView
->client())
919 m_webView
->client()->showUnhandledTapUIIfNeeded(WebPoint(tappedPositionInViewport
), WebNode(tappedNode
), pageChanged
);
922 void ChromeClientImpl::onMouseDown(Node
* mouseDownNode
)
924 if (m_webView
->client())
925 m_webView
->client()->onMouseDown(WebNode(mouseDownNode
));
928 void ChromeClientImpl::handleKeyboardEventOnTextField(HTMLInputElement
& inputElement
, KeyboardEvent
& event
)
930 WebLocalFrameImpl
* webframe
= WebLocalFrameImpl::fromFrame(inputElement
.document().frame());
931 if (webframe
->autofillClient())
932 webframe
->autofillClient()->textFieldDidReceiveKeyDown(WebInputElement(&inputElement
), WebKeyboardEventBuilder(event
));
935 void ChromeClientImpl::didChangeValueInTextField(HTMLFormControlElement
& element
)
937 WebLocalFrameImpl
* webframe
= WebLocalFrameImpl::fromFrame(element
.document().frame());
938 if (webframe
->autofillClient())
939 webframe
->autofillClient()->textFieldDidChange(WebFormControlElement(&element
));
941 m_webView
->pageImportanceSignals()->setHadFormInteraction();
944 void ChromeClientImpl::didEndEditingOnTextField(HTMLInputElement
& inputElement
)
946 WebLocalFrameImpl
* webframe
= WebLocalFrameImpl::fromFrame(inputElement
.document().frame());
947 if (webframe
->autofillClient())
948 webframe
->autofillClient()->textFieldDidEndEditing(WebInputElement(&inputElement
));
951 void ChromeClientImpl::openTextDataListChooser(HTMLInputElement
& input
)
953 notifyPopupOpeningObservers();
954 WebLocalFrameImpl
* webframe
= WebLocalFrameImpl::fromFrame(input
.document().frame());
955 if (webframe
->autofillClient())
956 webframe
->autofillClient()->openTextDataListChooser(WebInputElement(&input
));
959 void ChromeClientImpl::textFieldDataListChanged(HTMLInputElement
& input
)
961 WebLocalFrameImpl
* webframe
= WebLocalFrameImpl::fromFrame(input
.document().frame());
962 if (webframe
->autofillClient())
963 webframe
->autofillClient()->dataListOptionsChanged(WebInputElement(&input
));
966 void ChromeClientImpl::ajaxSucceeded(LocalFrame
* frame
)
968 WebLocalFrameImpl
* webframe
= WebLocalFrameImpl::fromFrame(frame
);
969 if (webframe
->autofillClient())
970 webframe
->autofillClient()->ajaxSucceeded();
973 void ChromeClientImpl::registerViewportLayers() const
975 if (m_webView
->rootGraphicsLayer() && m_webView
->layerTreeView())
976 m_webView
->page()->frameHost().visualViewport().registerLayersWithTreeView(m_webView
->layerTreeView());
979 void ChromeClientImpl::didUpdateTopControls() const
981 m_webView
->didUpdateTopControls();
984 void ChromeClientImpl::registerPopupOpeningObserver(PopupOpeningObserver
* observer
)
987 m_popupOpeningObservers
.append(observer
);
990 void ChromeClientImpl::unregisterPopupOpeningObserver(PopupOpeningObserver
* observer
)
992 size_t index
= m_popupOpeningObservers
.find(observer
);
993 ASSERT(index
!= kNotFound
);
994 m_popupOpeningObservers
.remove(index
);
997 void ChromeClientImpl::notifyPopupOpeningObservers() const
999 const Vector
<PopupOpeningObserver
*> observers(m_popupOpeningObservers
);
1000 for (const auto& observer
: observers
)
1001 observer
->willOpenPopup();
1004 FloatSize
ChromeClientImpl::elasticOverscroll() const
1006 return m_webView
->elasticOverscroll();
1009 } // namespace blink