/*
 * 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
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "web/ChromeClientImpl.h"

#include "bindings/core/v8/ScriptController.h"
#include "core/HTMLNames.h"
#include "core/dom/AXObjectCache.h"
#include "core/dom/Document.h"
#include "core/dom/Fullscreen.h"
#include "core/dom/Node.h"
#include "core/events/UIEventWithKeyState.h"
#include "core/frame/FrameHost.h"
#include "core/frame/FrameView.h"
#include "core/frame/Settings.h"
#include "core/frame/VisualViewport.h"
#include "core/html/HTMLInputElement.h"
#include "core/html/forms/ColorChooser.h"
#include "core/html/forms/ColorChooserClient.h"
#include "core/html/forms/DateTimeChooser.h"
#include "core/layout/HitTestResult.h"
#include "core/layout/LayoutPart.h"
#include "core/layout/compositing/CompositedSelection.h"
#include "core/loader/DocumentLoader.h"
#include "core/loader/FrameLoadRequest.h"
#include "core/page/Page.h"
#include "core/page/PopupOpeningObserver.h"
#include "modules/accessibility/AXObject.h"
#include "modules/audio_output_devices/AudioOutputDeviceClient.h"
#include "modules/bluetooth/BluetoothSupplement.h"
#include "modules/installedapp/InstalledAppController.h"
#include "modules/mediastream/UserMediaController.h"
#include "modules/presentation/PresentationController.h"
#include "modules/push_messaging/PushController.h"
#include "modules/screen_orientation/ScreenOrientationControllerImpl.h"
#include "modules/vr/VRController.h"
#include "platform/Cursor.h"
#include "platform/FileChooser.h"
#include "platform/Histogram.h"
#include "platform/KeyboardCodes.h"
#include "platform/RuntimeEnabledFeatures.h"
#include "platform/WebFrameScheduler.h"
#include "platform/exported/WrappedResourceRequest.h"
#include "platform/geometry/IntRect.h"
#include "platform/graphics/GraphicsLayer.h"
#include "platform/weborigin/SecurityOrigin.h"
#include "public/platform/WebCursorInfo.h"
#include "public/platform/WebFloatRect.h"
#include "public/platform/WebInputEvent.h"
#include "public/platform/WebRect.h"
#include "public/platform/WebURLRequest.h"
#include "public/platform/WebViewScheduler.h"
#include "public/web/WebAXObject.h"
#include "public/web/WebAutofillClient.h"
#include "public/web/WebColorChooser.h"
#include "public/web/WebColorSuggestion.h"
#include "public/web/WebConsoleMessage.h"
#include "public/web/WebFrameClient.h"
#include "public/web/WebInputElement.h"
#include "public/web/WebKit.h"
#include "public/web/WebNode.h"
#include "public/web/WebPageImportanceSignals.h"
#include "public/web/WebPlugin.h"
#include "public/web/WebPopupMenuInfo.h"
#include "public/web/WebSelection.h"
#include "public/web/WebSettings.h"
#include "public/web/WebTextDirection.h"
#include "public/web/WebTouchAction.h"
#include "public/web/WebUserGestureIndicator.h"
#include "public/web/WebUserGestureToken.h"
#include "public/web/WebViewClient.h"
#include "public/web/WebWindowFeatures.h"
#include "web/AudioOutputDeviceClientImpl.h"
#include "web/ColorChooserPopupUIController.h"
#include "web/ColorChooserUIController.h"
#include "web/DateTimeChooserImpl.h"
#include "web/DevToolsEmulator.h"
#include "web/ExternalDateTimeChooser.h"
#include "web/ExternalPopupMenu.h"
#include "web/IndexedDBClientImpl.h"
#include "web/LocalFileSystemClient.h"
#include "web/NavigatorContentUtilsClientImpl.h"
#include "web/PopupMenuImpl.h"
#include "web/WebFileChooserCompletionImpl.h"
#include "web/WebFrameWidgetImpl.h"
#include "web/WebInputEventConversion.h"
#include "web/WebLocalFrameImpl.h"
#include "web/WebPluginContainerImpl.h"
#include "web/WebSettingsImpl.h"
#include "web/WebViewImpl.h"
#include "wtf/Optional.h"
#include "wtf/PtrUtil.h"
#include "wtf/text/CString.h"
#include "wtf/text/CharacterNames.h"
#include "wtf/text/StringBuilder.h"
#include "wtf/text/StringConcatenate.h"
#include <memory>

namespace blink {

namespace {

const char* dialogTypeToString(ChromeClient::DialogType dialogType) {
  switch (dialogType) {
    case ChromeClient::AlertDialog:
      return "alert";
    case ChromeClient::ConfirmDialog:
      return "confirm";
    case ChromeClient::PromptDialog:
      return "prompt";
    case ChromeClient::HTMLDialog:
      NOTREACHED();
  }
  NOTREACHED();
  return "";
}

const char* dismissalTypeToString(Document::PageDismissalType dismissalType) {
  switch (dismissalType) {
    case Document::BeforeUnloadDismissal:
      return "beforeunload";
    case Document::PageHideDismissal:
      return "pagehide";
    case Document::UnloadVisibilityChangeDismissal:
      return "visibilitychange";
    case Document::UnloadDismissal:
      return "unload";
    case Document::NoDismissal:
      NOTREACHED();
  }
  NOTREACHED();
  return "";
}

}  // namespace

class CompositorAnimationTimeline;

// Converts a AXObjectCache::AXNotification to a WebAXEvent
static WebAXEvent toWebAXEvent(AXObjectCache::AXNotification notification) {
  // These enums have the same values; enforced in AssertMatchingEnums.cpp.
  return static_cast<WebAXEvent>(notification);
}

ChromeClientImpl::ChromeClientImpl(WebViewImpl* webView)
    : m_webView(webView),
      m_cursorOverridden(false),
      m_didRequestNonEmptyToolTip(false) {}

ChromeClientImpl::~ChromeClientImpl() {}

ChromeClientImpl* ChromeClientImpl::create(WebViewImpl* webView) {
  return new ChromeClientImpl(webView);
}

void* ChromeClientImpl::webView() const {
  return static_cast<void*>(m_webView);
}

void ChromeClientImpl::chromeDestroyed() {
  // Our lifetime is bound to the WebViewImpl.
}

void ChromeClientImpl::setWindowRect(const IntRect& r, LocalFrame& frame) {
  DCHECK_EQ(&frame, m_webView->mainFrameImpl()->frame());
  WebWidgetClient* client =
      WebLocalFrameImpl::fromFrame(&frame)->frameWidget()->client();
  client->setWindowRect(r);
}

IntRect ChromeClientImpl::rootWindowRect() {
  WebRect rect;
  if (m_webView->client()) {
    rect = m_webView->client()->rootWindowRect();
  } else {
    // These numbers will be fairly wrong. The window's x/y coordinates will
    // be the top left corner of the screen and the size will be the content
    // size instead of the window size.
    rect.width = m_webView->size().width;
    rect.height = m_webView->size().height;
  }
  return IntRect(rect);
}

IntRect ChromeClientImpl::pageRect() {
  // We hide the details of the window's border thickness from the web page by
  // simple re-using the window position here.  So, from the point-of-view of
  // the web page, the window has no border.
  return rootWindowRect();
}

void ChromeClientImpl::focus() {
  if (m_webView->client())
    m_webView->client()->didFocus();
}

bool ChromeClientImpl::canTakeFocus(WebFocusType) {
  // For now the browser can always take focus if we're not running layout
  // tests.
  return !layoutTestMode();
}

void ChromeClientImpl::takeFocus(WebFocusType type) {
  if (!m_webView->client())
    return;
  if (type == WebFocusTypeBackward)
    m_webView->client()->focusPrevious();
  else
    m_webView->client()->focusNext();
}

void ChromeClientImpl::focusedNodeChanged(Node* fromNode, Node* toNode) {
  if (!m_webView->client())
    return;

  m_webView->client()->focusedNodeChanged(WebNode(fromNode), WebNode(toNode));

  WebURL focusURL;
  if (toNode && toNode->isElementNode() && toElement(toNode)->isLiveLink() &&
      toNode->shouldHaveFocusAppearance())
    focusURL = toElement(toNode)->hrefURL();
  m_webView->client()->setKeyboardFocusURL(focusURL);
}

bool ChromeClientImpl::hadFormInteraction() const {
  return m_webView->pageImportanceSignals() &&
         m_webView->pageImportanceSignals()->hadFormInteraction();
}

void ChromeClientImpl::startDragging(LocalFrame* frame,
                                     const WebDragData& dragData,
                                     WebDragOperationsMask mask,
                                     const WebImage& dragImage,
                                     const WebPoint& dragImageOffset) {
  WebLocalFrameImpl* webFrame = WebLocalFrameImpl::fromFrame(frame);
  WebReferrerPolicy policy = webFrame->document().getReferrerPolicy();
  webFrame->localRoot()->frameWidget()->startDragging(
      policy, dragData, mask, dragImage, dragImageOffset);
}

bool ChromeClientImpl::acceptsLoadDrops() const {
  return !m_webView->client() || m_webView->client()->acceptsLoadDrops();
}

namespace {

void updatePolicyForEvent(const WebInputEvent* inputEvent,
                          NavigationPolicy* policy) {
  if (!inputEvent)
    return;

  unsigned short buttonNumber = 0;
  if (inputEvent->type == WebInputEvent::MouseUp) {
    const WebMouseEvent* mouseEvent =
        static_cast<const WebMouseEvent*>(inputEvent);

    switch (mouseEvent->button) {
      case WebMouseEvent::Button::Left:
        buttonNumber = 0;
        break;
      case WebMouseEvent::Button::Middle:
        buttonNumber = 1;
        break;
      case WebMouseEvent::Button::Right:
        buttonNumber = 2;
        break;
      default:
        return;
    }
  } else if ((WebInputEvent::isKeyboardEventType(inputEvent->type) &&
              static_cast<const WebKeyboardEvent*>(inputEvent)
                      ->windowsKeyCode == VKEY_RETURN) ||
             WebInputEvent::isGestureEventType(inputEvent->type)) {
    // Keyboard and gesture events can simulate mouse events.
    buttonNumber = 0;
  } else {
    return;
  }

  bool ctrl = inputEvent->modifiers & WebInputEvent::ControlKey;
  bool shift = inputEvent->modifiers & WebInputEvent::ShiftKey;
  bool alt = inputEvent->modifiers & WebInputEvent::AltKey;
  bool meta = inputEvent->modifiers & WebInputEvent::MetaKey;

  NavigationPolicy userPolicy = *policy;
  navigationPolicyFromMouseEvent(buttonNumber, ctrl, shift, alt, meta,
                                 &userPolicy);

  // When the input event suggests a download, but the navigation was initiated
  // by script, we should not override it.
  if (userPolicy == NavigationPolicyDownload &&
      *policy != NavigationPolicyIgnore)
    return;

  // User and app agree that we want a new window; let the app override the
  // decorations.
  if (userPolicy == NavigationPolicyNewWindow &&
      *policy == NavigationPolicyNewPopup)
    return;
  *policy = userPolicy;
}

WebNavigationPolicy getNavigationPolicy(const WindowFeatures& features) {
  // If our default configuration was modified by a script or wasn't
  // created by a user gesture, then show as a popup. Else, let this
  // new window be opened as a toplevel window.
  bool asPopup = !features.toolBarVisible || !features.statusBarVisible ||
                 !features.scrollbarsVisible || !features.menuBarVisible ||
                 !features.resizable;

  NavigationPolicy policy = NavigationPolicyNewForegroundTab;
  if (asPopup)
    policy = NavigationPolicyNewPopup;
  updatePolicyForEvent(WebViewImpl::currentInputEvent(), &policy);

  return static_cast<WebNavigationPolicy>(policy);
}

WebNavigationPolicy effectiveNavigationPolicy(NavigationPolicy navigationPolicy,
                                              const WindowFeatures& features) {
  WebNavigationPolicy policy =
      static_cast<WebNavigationPolicy>(navigationPolicy);
  if (policy == WebNavigationPolicyIgnore)
    return getNavigationPolicy(features);
  if (policy == WebNavigationPolicyNewBackgroundTab &&
      getNavigationPolicy(features) != WebNavigationPolicyNewBackgroundTab &&
      !UIEventWithKeyState::newTabModifierSetFromIsolatedWorld())
    return WebNavigationPolicyNewForegroundTab;

  return policy;
}

}  // namespace

Page* ChromeClientImpl::createWindow(LocalFrame* frame,
                                     const FrameLoadRequest& r,
                                     const WindowFeatures& features,
                                     NavigationPolicy navigationPolicy) {
  if (!m_webView->client())
    return nullptr;

  if (!frame->page() || frame->page()->suspended())
    return nullptr;

  WebNavigationPolicy policy =
      effectiveNavigationPolicy(navigationPolicy, features);
  DCHECK(frame->document());
  Fullscreen::fullyExitFullscreen(*frame->document());

  WebViewImpl* newView = toWebViewImpl(m_webView->client()->createView(
      WebLocalFrameImpl::fromFrame(frame),
      WrappedResourceRequest(r.resourceRequest()), features, r.frameName(),
      policy, r.getShouldSetOpener() == NeverSetOpener || features.noopener));
  if (!newView)
    return nullptr;
  return newView->page();
}

void ChromeClientImpl::didOverscroll(const FloatSize& overscrollDelta,
                                     const FloatSize& accumulatedOverscroll,
                                     const FloatPoint& positionInViewport,
                                     const FloatSize& velocityInViewport) {
  if (!m_webView->client())
    return;

  m_webView->client()->didOverscroll(overscrollDelta, accumulatedOverscroll,
                                     positionInViewport, velocityInViewport);
}

void ChromeClientImpl::show(NavigationPolicy navigationPolicy) {
  if (m_webView->client())
    m_webView->client()->show(
        effectiveNavigationPolicy(navigationPolicy, m_windowFeatures));
}

void ChromeClientImpl::setToolbarsVisible(bool value) {
  m_windowFeatures.toolBarVisible = value;
}

bool ChromeClientImpl::toolbarsVisible() {
  return m_windowFeatures.toolBarVisible;
}

void ChromeClientImpl::setStatusbarVisible(bool value) {
  m_windowFeatures.statusBarVisible = value;
}

bool ChromeClientImpl::statusbarVisible() {
  return m_windowFeatures.statusBarVisible;
}

void ChromeClientImpl::setScrollbarsVisible(bool value) {
  m_windowFeatures.scrollbarsVisible = value;
  if (WebLocalFrameImpl* webFrame = toWebLocalFrameImpl(m_webView->mainFrame()))
    webFrame->setCanHaveScrollbars(value);
}

bool ChromeClientImpl::scrollbarsVisible() {
  return m_windowFeatures.scrollbarsVisible;
}

void ChromeClientImpl::setMenubarVisible(bool value) {
  m_windowFeatures.menuBarVisible = value;
}

bool ChromeClientImpl::menubarVisible() {
  return m_windowFeatures.menuBarVisible;
}

void ChromeClientImpl::setResizable(bool value) {
  m_windowFeatures.resizable = value;
}

bool ChromeClientImpl::shouldReportDetailedMessageForSource(
    LocalFrame& localFrame,
    const String& url) {
  WebLocalFrameImpl* webframe =
      WebLocalFrameImpl::fromFrame(localFrame.localFrameRoot());
  return webframe && webframe->client() &&
         webframe->client()->shouldReportDetailedMessageForSource(url);
}

void ChromeClientImpl::addMessageToConsole(LocalFrame* localFrame,
                                           MessageSource source,
                                           MessageLevel level,
                                           const String& message,
                                           unsigned lineNumber,
                                           const String& sourceID,
                                           const String& stackTrace) {
  WebLocalFrameImpl* frame = WebLocalFrameImpl::fromFrame(localFrame);
  if (frame && frame->client()) {
    frame->client()->didAddMessageToConsole(
        WebConsoleMessage(static_cast<WebConsoleMessage::Level>(level),
                          message),
        sourceID, lineNumber, stackTrace);
  }
}

bool ChromeClientImpl::canOpenBeforeUnloadConfirmPanel() {
  return !!m_webView->client();
}

bool ChromeClientImpl::openBeforeUnloadConfirmPanelDelegate(LocalFrame* frame,
                                                            bool isReload) {
  notifyPopupOpeningObservers();
  WebLocalFrameImpl* webframe = WebLocalFrameImpl::fromFrame(frame);
  return webframe->client() &&
         webframe->client()->runModalBeforeUnloadDialog(isReload);
}

void ChromeClientImpl::closeWindowSoon() {
  if (m_webView->client())
    m_webView->client()->closeWidgetSoon();
}

// Although a LocalFrame is passed in, we don't actually use it, since we
// already know our own m_webView.
bool ChromeClientImpl::openJavaScriptAlertDelegate(LocalFrame* frame,
                                                   const String& message) {
  notifyPopupOpeningObservers();
  WebLocalFrameImpl* webframe = WebLocalFrameImpl::fromFrame(frame);
  if (webframe->client()) {
    if (WebUserGestureIndicator::isProcessingUserGesture())
      WebUserGestureIndicator::currentUserGestureToken().setJavascriptPrompt();
    webframe->client()->runModalAlertDialog(message);
    return true;
  }
  return false;
}

// See comments for openJavaScriptAlertDelegate().
bool ChromeClientImpl::openJavaScriptConfirmDelegate(LocalFrame* frame,
                                                     const String& message) {
  notifyPopupOpeningObservers();
  WebLocalFrameImpl* webframe = WebLocalFrameImpl::fromFrame(frame);
  if (webframe->client()) {
    if (WebUserGestureIndicator::isProcessingUserGesture())
      WebUserGestureIndicator::currentUserGestureToken().setJavascriptPrompt();
    return webframe->client()->runModalConfirmDialog(message);
  }
  return false;
}

// See comments for openJavaScriptAlertDelegate().
bool ChromeClientImpl::openJavaScriptPromptDelegate(LocalFrame* frame,
                                                    const String& message,
                                                    const String& defaultValue,
                                                    String& result) {
  notifyPopupOpeningObservers();
  WebLocalFrameImpl* webframe = WebLocalFrameImpl::fromFrame(frame);
  if (webframe->client()) {
    if (WebUserGestureIndicator::isProcessingUserGesture())
      WebUserGestureIndicator::currentUserGestureToken().setJavascriptPrompt();
    WebString actualValue;
    bool ok = webframe->client()->runModalPromptDialog(message, defaultValue,
                                                       &actualValue);
    if (ok)
      result = actualValue;
    return ok;
  }
  return false;
}

void ChromeClientImpl::setStatusbarText(const String& message) {
  if (m_webView->client())
    m_webView->client()->setStatusText(message);
}

bool ChromeClientImpl::tabsToLinks() {
  return m_webView->tabsToLinks();
}

void ChromeClientImpl::invalidateRect(const IntRect& updateRect) {
  if (!updateRect.isEmpty())
    m_webView->invalidateRect(updateRect);
}

void ChromeClientImpl::scheduleAnimation(Widget* widget) {
  DCHECK(widget->isFrameView());
  FrameView* view = toFrameView(widget);
  LocalFrame* frame = view->frame().localFrameRoot();

  // If the frame is still being created, it might not yet have a WebWidget.
  // FIXME: Is this the right thing to do? Is there a way to avoid having
  // a local frame root that doesn't have a WebWidget? During initialization
  // there is no content to draw so this call serves no purpose.
  if (WebLocalFrameImpl::fromFrame(frame) &&
      WebLocalFrameImpl::fromFrame(frame)->frameWidget())
    WebLocalFrameImpl::fromFrame(frame)->frameWidget()->scheduleAnimation();
}

IntRect ChromeClientImpl::viewportToScreen(const IntRect& rectInViewport,
                                           const Widget* widget) const {
  WebRect screenRect(rectInViewport);

  DCHECK(widget->isFrameView());
  const FrameView* view = toFrameView(widget);
  LocalFrame* frame = view->frame().localFrameRoot();

  WebWidgetClient* client =
      WebLocalFrameImpl::fromFrame(frame)->frameWidget()->client();

  if (client) {
    client->convertViewportToWindow(&screenRect);
    WebRect viewRect = client->viewRect();
    screenRect.x += viewRect.x;
    screenRect.y += viewRect.y;
  }

  return screenRect;
}

float ChromeClientImpl::windowToViewportScalar(const float scalarValue) const {
  if (!m_webView->client())
    return scalarValue;
  WebFloatRect viewportRect(0, 0, scalarValue, 0);
  m_webView->client()->convertWindowToViewport(&viewportRect);
  return viewportRect.width;
}

WebScreenInfo ChromeClientImpl::screenInfo() const {
  return m_webView->client() ? m_webView->client()->screenInfo()
                             : WebScreenInfo();
}

WTF::Optional<IntRect> ChromeClientImpl::visibleContentRectForPainting() const {
  return m_webView->devToolsEmulator()->visibleContentRectForPainting();
}

void ChromeClientImpl::contentsSizeChanged(LocalFrame* frame,
                                           const IntSize& size) const {
  m_webView->didChangeContentsSize();

  WebLocalFrameImpl* webframe = WebLocalFrameImpl::fromFrame(frame);
  webframe->didChangeContentsSize(size);
}

void ChromeClientImpl::pageScaleFactorChanged() const {
  m_webView->pageScaleFactorChanged();
}

void ChromeClientImpl::mainFrameScrollOffsetChanged() const {
  m_webView->mainFrameScrollOffsetChanged();
}

float ChromeClientImpl::clampPageScaleFactorToLimits(float scale) const {
  return m_webView->clampPageScaleFactorToLimits(scale);
}

void ChromeClientImpl::layoutUpdated(LocalFrame* frame) const {
  m_webView->layoutUpdated(WebLocalFrameImpl::fromFrame(frame));
}

void ChromeClientImpl::showMouseOverURL(const HitTestResult& result) {
  if (!m_webView->client())
    return;

  WebURL url;

  // Ignore URL if hitTest include scrollbar since we might have both a
  // scrollbar and an element in the case of overlay scrollbars.
  if (!result.scrollbar()) {
    // Find out if the mouse is over a link, and if so, let our UI know...
    if (result.isLiveLink() &&
        !result.absoluteLinkURL().getString().isEmpty()) {
      url = result.absoluteLinkURL();
    } else if (result.innerNode() &&
               (isHTMLObjectElement(*result.innerNode()) ||
                isHTMLEmbedElement(*result.innerNode()))) {
      LayoutObject* object = result.innerNode()->layoutObject();
      if (object && object->isLayoutPart()) {
        Widget* widget = toLayoutPart(object)->widget();
        if (widget && widget->isPluginContainer()) {
          WebPluginContainerImpl* plugin = toWebPluginContainerImpl(widget);
          url = plugin->plugin()->linkAtPosition(
              result.roundedPointInInnerNodeFrame());
        }
      }
    }
  }

  m_webView->client()->setMouseOverURL(url);
}

void ChromeClientImpl::setToolTip(LocalFrame& frame,
                                  const String& tooltipText,
                                  TextDirection dir) {
  WebLocalFrameImpl* webFrame =
      WebLocalFrameImpl::fromFrame(&frame)->localRoot();
  if (!tooltipText.isEmpty()) {
    webFrame->frameWidget()->client()->setToolTipText(tooltipText,
                                                      toWebTextDirection(dir));
    m_didRequestNonEmptyToolTip = true;
  } else if (m_didRequestNonEmptyToolTip) {
    // WebWidgetClient::setToolTipText will send an IPC message.  We'd like to
    // reduce the number of setToolTipText calls.
    webFrame->frameWidget()->client()->setToolTipText(tooltipText,
                                                      toWebTextDirection(dir));
    m_didRequestNonEmptyToolTip = false;
  }
}

void ChromeClientImpl::dispatchViewportPropertiesDidChange(
    const ViewportDescription& description) const {
  m_webView->updatePageDefinedViewportConstraints(description);
}

void ChromeClientImpl::printDelegate(LocalFrame* frame) {
  if (m_webView->client())
    m_webView->client()->printPage(WebLocalFrameImpl::fromFrame(frame));
}

ColorChooser* ChromeClientImpl::openColorChooser(
    LocalFrame* frame,
    ColorChooserClient* chooserClient,
    const Color&) {
  notifyPopupOpeningObservers();
  ColorChooserUIController* controller = nullptr;
  if (RuntimeEnabledFeatures::pagePopupEnabled())
    controller =
        ColorChooserPopupUIController::create(frame, this, chooserClient);
  else
    controller = ColorChooserUIController::create(frame, chooserClient);
  controller->openUI();
  return controller;
}

DateTimeChooser* ChromeClientImpl::openDateTimeChooser(
    DateTimeChooserClient* pickerClient,
    const DateTimeChooserParameters& parameters) {
  notifyPopupOpeningObservers();
  if (RuntimeEnabledFeatures::inputMultipleFieldsUIEnabled())
    return DateTimeChooserImpl::create(this, pickerClient, parameters);
  return ExternalDateTimeChooser::create(this, m_webView->client(),
                                         pickerClient, parameters);
}

void ChromeClientImpl::openFileChooser(LocalFrame* frame,
                                       PassRefPtr<FileChooser> fileChooser) {
  notifyPopupOpeningObservers();
  WebFrameClient* client = WebLocalFrameImpl::fromFrame(frame)->client();
  if (!client)
    return;

  WebFileChooserParams params;
  params.multiSelect = fileChooser->settings().allowsMultipleFiles;
  params.directory = fileChooser->settings().allowsDirectoryUpload;
  params.acceptTypes = fileChooser->settings().acceptTypes();
  params.selectedFiles = fileChooser->settings().selectedFiles;
  params.useMediaCapture = fileChooser->settings().useMediaCapture;
  params.needLocalPath = fileChooser->settings().allowsDirectoryUpload;
  params.requestor = frame->document()->url();

  WebFileChooserCompletionImpl* chooserCompletion =
      new WebFileChooserCompletionImpl(std::move(fileChooser));
  if (client->runFileChooser(params, chooserCompletion))
    return;
  // Choosing failed, so do callback with an empty list.
  chooserCompletion->didChooseFile(WebVector<WebString>());
}

void ChromeClientImpl::enumerateChosenDirectory(FileChooser* fileChooser) {
  WebViewClient* client = m_webView->client();
  if (!client)
    return;

  WebFileChooserCompletionImpl* chooserCompletion =
      new WebFileChooserCompletionImpl(fileChooser);

  DCHECK(fileChooser);
  DCHECK(fileChooser->settings().selectedFiles.size());

  // If the enumeration can't happen, call the callback with an empty list.
  if (!client->enumerateChosenDirectory(
          fileChooser->settings().selectedFiles[0], chooserCompletion))
    chooserCompletion->didChooseFile(WebVector<WebString>());
}

Cursor ChromeClientImpl::lastSetCursorForTesting() const {
  return m_lastSetMouseCursorForTesting;
}

void ChromeClientImpl::setCursor(const Cursor& cursor, LocalFrame* localFrame) {
  m_lastSetMouseCursorForTesting = cursor;
  setCursor(WebCursorInfo(cursor), localFrame);
}

void ChromeClientImpl::setCursor(const WebCursorInfo& cursor,
                                 LocalFrame* localFrame) {
  if (m_cursorOverridden)
    return;

#if OS(MACOSX)
  // On Mac the mousemove event propagates to both the popup and main window.
  // If a popup is open we don't want the main window to change the cursor.
  if (m_webView->hasOpenedPopup())
    return;
#endif

  LocalFrame* localRoot = localFrame->localFrameRoot();
  if (WebFrameWidgetBase* widget =
          WebLocalFrameImpl::fromFrame(localRoot)->frameWidget())
    widget->client()->didChangeCursor(cursor);
}

void ChromeClientImpl::setCursorForPlugin(const WebCursorInfo& cursor,
                                          LocalFrame* localFrame) {
  setCursor(cursor, localFrame);
}

void ChromeClientImpl::setCursorOverridden(bool overridden) {
  m_cursorOverridden = overridden;
}

void ChromeClientImpl::postAccessibilityNotification(
    AXObject* obj,
    AXObjectCache::AXNotification notification) {
  // Alert assistive technology about the accessibility object notification.
  if (!obj || !obj->getDocument())
    return;

  WebLocalFrameImpl* webframe = WebLocalFrameImpl::fromFrame(
      obj->getDocument()->axObjectCacheOwner().frame());
  if (webframe && webframe->client())
    webframe->client()->postAccessibilityEvent(WebAXObject(obj),
                                               toWebAXEvent(notification));
}

String ChromeClientImpl::acceptLanguages() {
  return m_webView->client()->acceptLanguages();
}

void ChromeClientImpl::attachRootGraphicsLayer(GraphicsLayer* rootLayer,
                                               LocalFrame* localFrame) {
  DCHECK(!RuntimeEnabledFeatures::slimmingPaintV2Enabled());
  WebLocalFrameImpl* webFrame =
      WebLocalFrameImpl::fromFrame(localFrame)->localRoot();

  // This method can be called while the frame is being detached. In that
  // case, the rootLayer is null, and the widget is already destroyed.
  DCHECK(webFrame->frameWidget() || !rootLayer);
  if (webFrame->frameWidget())
    webFrame->frameWidget()->setRootGraphicsLayer(rootLayer);
}

void ChromeClientImpl::attachRootLayer(WebLayer* rootLayer,
                                       LocalFrame* localFrame) {
  WebLocalFrameImpl* webFrame =
      WebLocalFrameImpl::fromFrame(localFrame)->localRoot();

  // This method can be called while the frame is being detached. In that
  // case, the rootLayer is null, and the widget is already destroyed.
  DCHECK(webFrame->frameWidget() || !rootLayer);
  if (webFrame->frameWidget())
    webFrame->frameWidget()->setRootLayer(rootLayer);
}

void ChromeClientImpl::attachCompositorAnimationTimeline(
    CompositorAnimationTimeline* compositorTimeline,
    LocalFrame* localFrame) {
  WebLocalFrameImpl* webFrame =
      WebLocalFrameImpl::fromFrame(localFrame)->localRoot();
  webFrame->frameWidget()->attachCompositorAnimationTimeline(
      compositorTimeline);
}

void ChromeClientImpl::detachCompositorAnimationTimeline(
    CompositorAnimationTimeline* compositorTimeline,
    LocalFrame* localFrame) {
  WebLocalFrameImpl* webFrame =
      WebLocalFrameImpl::fromFrame(localFrame)->localRoot();

  // This method can be called when the frame is being detached, after the
  // widget is destroyed.
  if (webFrame->frameWidget())
    webFrame->frameWidget()->detachCompositorAnimationTimeline(
        compositorTimeline);
}

void ChromeClientImpl::enterFullscreen(LocalFrame& frame) {
  m_webView->enterFullscreen(frame);
}

void ChromeClientImpl::exitFullscreen(LocalFrame& frame) {
  m_webView->exitFullscreen(frame);
}

void ChromeClientImpl::fullscreenElementChanged(Element* fromElement,
                                                Element* toElement) {
  m_webView->fullscreenElementChanged(fromElement, toElement);
}

void ChromeClientImpl::clearCompositedSelection(LocalFrame* frame) {
  LocalFrame* localRoot = frame->localFrameRoot();
  auto client =
      WebLocalFrameImpl::fromFrame(localRoot)->frameWidget()->client();
  if (!client)
    return;

  auto layerTreeView = client->layerTreeView();
  if (layerTreeView)
    layerTreeView->clearSelection();
}

void ChromeClientImpl::updateCompositedSelection(
    LocalFrame* frame,
    const CompositedSelection& selection) {
  LocalFrame* localRoot = frame->localFrameRoot();
  WebWidgetClient* client =
      WebLocalFrameImpl::fromFrame(localRoot)->frameWidget()->client();
  if (!client)
    return;

  WebLayerTreeView* layerTreeView = client->layerTreeView();
  if (layerTreeView)
    layerTreeView->registerSelection(WebSelection(selection));
}

bool ChromeClientImpl::hasOpenedPopup() const {
  return m_webView->hasOpenedPopup();
}

PopupMenu* ChromeClientImpl::openPopupMenu(LocalFrame& frame,
                                           HTMLSelectElement& select) {
  notifyPopupOpeningObservers();
  if (WebViewImpl::useExternalPopupMenus())
    return new ExternalPopupMenu(frame, select, *m_webView);

  DCHECK(RuntimeEnabledFeatures::pagePopupEnabled());
  return PopupMenuImpl::create(this, select);
}

PagePopup* ChromeClientImpl::openPagePopup(PagePopupClient* client) {
  return m_webView->openPagePopup(client);
}

void ChromeClientImpl::closePagePopup(PagePopup* popup) {
  m_webView->closePagePopup(popup);
}

DOMWindow* ChromeClientImpl::pagePopupWindowForTesting() const {
  return m_webView->pagePopupWindow();
}

bool ChromeClientImpl::shouldOpenModalDialogDuringPageDismissal(
    const DialogType& dialogType,
    const String& dialogMessage,
    Document::PageDismissalType dismissalType) const {
  String message = String("Blocked ") + dialogTypeToString(dialogType) + "('" +
                   dialogMessage + "') during " +
                   dismissalTypeToString(dismissalType) + ".";
  m_webView->mainFrame()->addMessageToConsole(
      WebConsoleMessage(WebConsoleMessage::LevelError, message));

  return false;
}

void ChromeClientImpl::setEventListenerProperties(
    WebEventListenerClass eventClass,
    WebEventListenerProperties properties) {
  if (WebLayerTreeView* treeView = m_webView->layerTreeView()) {
    treeView->setEventListenerProperties(eventClass, properties);
    if (eventClass == WebEventListenerClass::TouchStartOrMove) {
      m_webView->hasTouchEventHandlers(
          properties != WebEventListenerProperties::Nothing ||
          eventListenerProperties(WebEventListenerClass::TouchEndOrCancel) !=
              WebEventListenerProperties::Nothing);
    } else if (eventClass == WebEventListenerClass::TouchEndOrCancel) {
      m_webView->hasTouchEventHandlers(
          properties != WebEventListenerProperties::Nothing ||
          eventListenerProperties(WebEventListenerClass::TouchStartOrMove) !=
              WebEventListenerProperties::Nothing);
    }
  } else {
    m_webView->hasTouchEventHandlers(true);
  }
}

void ChromeClientImpl::beginLifecycleUpdates() {
  if (WebLayerTreeView* treeView = m_webView->layerTreeView()) {
    treeView->setDeferCommits(false);
    treeView->setNeedsBeginFrame();
  }
}

WebEventListenerProperties ChromeClientImpl::eventListenerProperties(
    WebEventListenerClass eventClass) const {
  if (WebLayerTreeView* treeView = m_webView->layerTreeView())
    return treeView->eventListenerProperties(eventClass);
  return WebEventListenerProperties::Nothing;
}

void ChromeClientImpl::setHasScrollEventHandlers(bool hasEventHandlers) {
  if (WebLayerTreeView* treeView = m_webView->layerTreeView())
    treeView->setHaveScrollEventHandlers(hasEventHandlers);
}

bool ChromeClientImpl::hasScrollEventHandlers() const {
  if (WebLayerTreeView* treeView = m_webView->layerTreeView())
    return treeView->haveScrollEventHandlers();
  return false;
}

void ChromeClientImpl::setTouchAction(TouchAction touchAction) {
  if (WebViewClient* client = m_webView->client())
    client->setTouchAction(static_cast<WebTouchAction>(touchAction));
}

bool ChromeClientImpl::requestPointerLock(LocalFrame* frame) {
  LocalFrame* localRoot = frame->localFrameRoot();
  return WebLocalFrameImpl::fromFrame(localRoot)
      ->frameWidget()
      ->client()
      ->requestPointerLock();
}

void ChromeClientImpl::requestPointerUnlock(LocalFrame* frame) {
  LocalFrame* localRoot = frame->localFrameRoot();
  return WebLocalFrameImpl::fromFrame(localRoot)
      ->frameWidget()
      ->client()
      ->requestPointerUnlock();
}

void ChromeClientImpl::annotatedRegionsChanged() {
  if (WebViewClient* client = m_webView->client())
    client->draggableRegionsChanged();
}

void ChromeClientImpl::didAssociateFormControlsAfterLoad(LocalFrame* frame) {
  WebLocalFrameImpl* webframe = WebLocalFrameImpl::fromFrame(frame);
  if (webframe->autofillClient())
    webframe->autofillClient()->didAssociateFormControlsDynamically();
}

void ChromeClientImpl::didCancelCompositionOnSelectionChange() {
  if (m_webView->client())
    m_webView->client()->didCancelCompositionOnSelectionChange();
}

void ChromeClientImpl::resetInputMethod() {
  if (m_webView->client())
    m_webView->client()->resetInputMethod();
}

void ChromeClientImpl::showImeIfNeeded() {
  if (m_webView->client())
    m_webView->client()->showImeIfNeeded();
}

void ChromeClientImpl::showUnhandledTapUIIfNeeded(
    IntPoint tappedPositionInViewport,
    Node* tappedNode,
    bool pageChanged) {
  if (m_webView->client())
    m_webView->client()->showUnhandledTapUIIfNeeded(
        WebPoint(tappedPositionInViewport), WebNode(tappedNode), pageChanged);
}

void ChromeClientImpl::onMouseDown(Node* mouseDownNode) {
  if (m_webView->client())
    m_webView->client()->onMouseDown(WebNode(mouseDownNode));
}

void ChromeClientImpl::handleKeyboardEventOnTextField(
    HTMLInputElement& inputElement,
    KeyboardEvent& event) {
  WebLocalFrameImpl* webframe =
      WebLocalFrameImpl::fromFrame(inputElement.document().frame());
  if (webframe->autofillClient())
    webframe->autofillClient()->textFieldDidReceiveKeyDown(
        WebInputElement(&inputElement), WebKeyboardEventBuilder(event));
}

void ChromeClientImpl::didChangeValueInTextField(
    HTMLFormControlElement& element) {
  WebLocalFrameImpl* webframe =
      WebLocalFrameImpl::fromFrame(element.document().frame());
  if (webframe->autofillClient())
    webframe->autofillClient()->textFieldDidChange(
        WebFormControlElement(&element));

  m_webView->pageImportanceSignals()->setHadFormInteraction();
}

void ChromeClientImpl::didEndEditingOnTextField(
    HTMLInputElement& inputElement) {
  WebLocalFrameImpl* webframe =
      WebLocalFrameImpl::fromFrame(inputElement.document().frame());
  if (webframe->autofillClient())
    webframe->autofillClient()->textFieldDidEndEditing(
        WebInputElement(&inputElement));
}

void ChromeClientImpl::openTextDataListChooser(HTMLInputElement& input) {
  notifyPopupOpeningObservers();
  WebLocalFrameImpl* webframe =
      WebLocalFrameImpl::fromFrame(input.document().frame());
  if (webframe->autofillClient())
    webframe->autofillClient()->openTextDataListChooser(
        WebInputElement(&input));
}

void ChromeClientImpl::textFieldDataListChanged(HTMLInputElement& input) {
  WebLocalFrameImpl* webframe =
      WebLocalFrameImpl::fromFrame(input.document().frame());
  if (webframe->autofillClient())
    webframe->autofillClient()->dataListOptionsChanged(WebInputElement(&input));
}

void ChromeClientImpl::ajaxSucceeded(LocalFrame* frame) {
  WebLocalFrameImpl* webframe = WebLocalFrameImpl::fromFrame(frame);
  if (webframe->autofillClient())
    webframe->autofillClient()->ajaxSucceeded();
}

void ChromeClientImpl::registerViewportLayers() const {
  if (m_webView->rootGraphicsLayer() && m_webView->layerTreeView())
    m_webView->registerViewportLayersWithCompositor();
}

void ChromeClientImpl::didUpdateBrowserControls() const {
  m_webView->didUpdateBrowserControls();
}

CompositorProxyClient* ChromeClientImpl::createCompositorProxyClient(
    LocalFrame* frame) {
  WebLocalFrameImpl* webFrame = WebLocalFrameImpl::fromFrame(frame);
  return webFrame->localRoot()->frameWidget()->createCompositorProxyClient();
}

void ChromeClientImpl::registerPopupOpeningObserver(
    PopupOpeningObserver* observer) {
  DCHECK(observer);
  m_popupOpeningObservers.append(observer);
}

void ChromeClientImpl::unregisterPopupOpeningObserver(
    PopupOpeningObserver* observer) {
  size_t index = m_popupOpeningObservers.find(observer);
  DCHECK_NE(index, kNotFound);
  m_popupOpeningObservers.remove(index);
}

void ChromeClientImpl::notifyPopupOpeningObservers() const {
  const Vector<PopupOpeningObserver*> observers(m_popupOpeningObservers);
  for (const auto& observer : observers)
    observer->willOpenPopup();
}

FloatSize ChromeClientImpl::elasticOverscroll() const {
  return m_webView->elasticOverscroll();
}

void ChromeClientImpl::didObserveNonGetFetchFromScript() const {
  if (m_webView->pageImportanceSignals())
    m_webView->pageImportanceSignals()->setIssuedNonGetFetchFromScript();
}

std::unique_ptr<WebFrameScheduler> ChromeClientImpl::createFrameScheduler(
    BlameContext* blameContext) {
  return WTF::wrapUnique(
      m_webView->scheduler()->createFrameScheduler(blameContext).release());
}

double ChromeClientImpl::lastFrameTimeMonotonic() const {
  return m_webView->lastFrameTimeMonotonic();
}

void ChromeClientImpl::installSupplements(LocalFrame& frame) {
  WebLocalFrameImpl* webFrame = WebLocalFrameImpl::fromFrame(&frame);
  WebFrameClient* client = webFrame->client();
  DCHECK(client);
  providePushControllerTo(frame, client->pushClient());
  provideUserMediaTo(frame,
                     UserMediaClientImpl::create(client->userMediaClient()));
  provideIndexedDBClientTo(frame, IndexedDBClientImpl::create());
  provideLocalFileSystemTo(frame, LocalFileSystemClient::create());
  provideNavigatorContentUtilsTo(
      frame, NavigatorContentUtilsClientImpl::create(webFrame));

  if (RuntimeEnabledFeatures::webBluetoothEnabled())
    BluetoothSupplement::provideTo(frame, client->bluetooth());

  ScreenOrientationControllerImpl::provideTo(
      frame, client->webScreenOrientationClient());
  if (RuntimeEnabledFeatures::presentationEnabled())
    PresentationController::provideTo(frame, client->presentationClient());
  if (RuntimeEnabledFeatures::audioOutputDevicesEnabled())
    provideAudioOutputDeviceClientTo(frame,
                                     AudioOutputDeviceClientImpl::create());
  if (RuntimeEnabledFeatures::installedAppEnabled())
    InstalledAppController::provideTo(frame, client->installedAppClient());
}

}  // namespace blink
