| // Copyright 2020 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard.h" |
| |
| #include "third_party/blink/renderer/core/css/document_style_environment_variables.h" |
| #include "third_party/blink/renderer/core/css/style_engine.h" |
| #include "third_party/blink/renderer/core/dom/document.h" |
| #include "third_party/blink/renderer/core/editing/ime/input_method_controller.h" |
| #include "third_party/blink/renderer/core/frame/local_dom_window.h" |
| #include "third_party/blink/renderer/core/frame/local_frame.h" |
| #include "third_party/blink/renderer/core/frame/navigator.h" |
| #include "third_party/blink/renderer/core/geometry/dom_rect.h" |
| #include "third_party/blink/renderer/core/inspector/console_message.h" |
| #include "third_party/blink/renderer/modules/event_target_modules.h" |
| #include "third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_geometry_change_event.h" |
| #include "ui/gfx/geometry/rect.h" |
| #include "ui/gfx/geometry/rect_f.h" |
| |
| namespace blink { |
| |
| // static |
| const char VirtualKeyboard::kSupplementName[] = "VirtualKeyboard"; |
| |
| // static |
| VirtualKeyboard* VirtualKeyboard::virtualKeyboard(Navigator& navigator) { |
| auto* keyboard = Supplement<Navigator>::From<VirtualKeyboard>(navigator); |
| if (!keyboard) { |
| keyboard = MakeGarbageCollected<VirtualKeyboard>(navigator); |
| ProvideTo(navigator, keyboard); |
| } |
| return keyboard; |
| } |
| |
| VirtualKeyboard::VirtualKeyboard(Navigator& navigator) |
| : Supplement<Navigator>(navigator), |
| VirtualKeyboardOverlayChangedObserver( |
| navigator.DomWindow() ? navigator.DomWindow()->GetFrame() : nullptr) { |
| bounding_rect_ = DOMRect::Create(); |
| } |
| |
| ExecutionContext* VirtualKeyboard::GetExecutionContext() const { |
| return GetSupplementable()->DomWindow(); |
| } |
| |
| const AtomicString& VirtualKeyboard::InterfaceName() const { |
| return event_target_names::kVirtualKeyboard; |
| } |
| |
| VirtualKeyboard::~VirtualKeyboard() = default; |
| |
| bool VirtualKeyboard::overlaysContent() const { |
| return overlays_content_; |
| } |
| |
| DOMRect* VirtualKeyboard::boundingRect() const { |
| return bounding_rect_; |
| } |
| |
| void VirtualKeyboard::setOverlaysContent(bool overlays_content) { |
| LocalDOMWindow* window = GetSupplementable()->DomWindow(); |
| if (window && window->GetFrame()->IsMainFrame()) { |
| if (overlays_content != overlays_content_) { |
| auto& local_frame_host = window->GetFrame()->GetLocalFrameHostRemote(); |
| local_frame_host.SetVirtualKeyboardOverlayPolicy(overlays_content); |
| overlays_content_ = overlays_content; |
| } |
| } else { |
| GetExecutionContext()->AddConsoleMessage( |
| MakeGarbageCollected<ConsoleMessage>( |
| mojom::blink::ConsoleMessageSource::kJavaScript, |
| mojom::blink::ConsoleMessageLevel::kWarning, |
| "Setting overlaysContent is only supported from " |
| "the top level browsing context")); |
| } |
| } |
| |
| void VirtualKeyboard::VirtualKeyboardOverlayChanged( |
| const gfx::Rect& keyboard_rect) { |
| bounding_rect_ = DOMRect::FromFloatRect(FloatRect(gfx::RectF(keyboard_rect))); |
| LocalDOMWindow* window = GetSupplementable()->DomWindow(); |
| if (window) { |
| DocumentStyleEnvironmentVariables& vars = |
| window->document()->GetStyleEngine().EnsureEnvironmentVariables(); |
| vars.SetVariable(UADefinedVariable::kKeyboardInsetTop, |
| StyleEnvironmentVariables::FormatPx(keyboard_rect.y())); |
| vars.SetVariable(UADefinedVariable::kKeyboardInsetLeft, |
| StyleEnvironmentVariables::FormatPx(keyboard_rect.x())); |
| vars.SetVariable( |
| UADefinedVariable::kKeyboardInsetBottom, |
| StyleEnvironmentVariables::FormatPx(keyboard_rect.bottom())); |
| vars.SetVariable( |
| UADefinedVariable::kKeyboardInsetRight, |
| StyleEnvironmentVariables::FormatPx(keyboard_rect.right())); |
| vars.SetVariable( |
| UADefinedVariable::kKeyboardInsetWidth, |
| StyleEnvironmentVariables::FormatPx(keyboard_rect.width())); |
| vars.SetVariable( |
| UADefinedVariable::kKeyboardInsetHeight, |
| StyleEnvironmentVariables::FormatPx(keyboard_rect.height())); |
| } |
| DispatchEvent(*(MakeGarbageCollected<VirtualKeyboardGeometryChangeEvent>( |
| event_type_names::kGeometrychange))); |
| } |
| |
| void VirtualKeyboard::show() { |
| LocalDOMWindow* window = GetSupplementable()->DomWindow(); |
| if (window && window->GetFrame()->HasStickyUserActivation()) { |
| window->GetInputMethodController().SetVirtualKeyboardVisibilityRequest( |
| ui::mojom::VirtualKeyboardVisibilityRequest::SHOW); |
| } else { |
| GetExecutionContext()->AddConsoleMessage( |
| MakeGarbageCollected<ConsoleMessage>( |
| mojom::blink::ConsoleMessageSource::kJavaScript, |
| mojom::blink::ConsoleMessageLevel::kWarning, |
| "Calling show is only supported if user has " |
| "interacted with the page")); |
| } |
| } |
| |
| void VirtualKeyboard::hide() { |
| if (LocalDOMWindow* window = GetSupplementable()->DomWindow()) { |
| window->GetInputMethodController().SetVirtualKeyboardVisibilityRequest( |
| ui::mojom::VirtualKeyboardVisibilityRequest::HIDE); |
| } |
| } |
| |
| void VirtualKeyboard::Trace(Visitor* visitor) const { |
| visitor->Trace(bounding_rect_); |
| EventTargetWithInlineData::Trace(visitor); |
| Supplement<Navigator>::Trace(visitor); |
| } |
| |
| } // namespace blink |