| // Copyright 2015 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 "components/html_viewer/html_widget.h" |
| |
| #include "components/html_viewer/blink_input_events_type_converters.h" |
| #include "components/html_viewer/blink_text_input_type_converters.h" |
| #include "components/html_viewer/global_state.h" |
| #include "components/html_viewer/web_layer_tree_view_impl.h" |
| #include "components/html_viewer/web_storage_namespace_impl.h" |
| #include "components/view_manager/public/cpp/view.h" |
| #include "mojo/application/public/cpp/application_impl.h" |
| #include "third_party/WebKit/public/web/WebFrameWidget.h" |
| #include "third_party/WebKit/public/web/WebInputEvent.h" |
| #include "third_party/WebKit/public/web/WebSettings.h" |
| #include "third_party/WebKit/public/web/WebView.h" |
| #include "ui/gfx/geometry/dip_util.h" |
| |
| namespace html_viewer { |
| namespace { |
| |
| scoped_ptr<WebLayerTreeViewImpl> CreateWebLayerTreeView( |
| GlobalState* global_state) { |
| return make_scoped_ptr(new WebLayerTreeViewImpl( |
| global_state->compositor_thread(), |
| global_state->gpu_memory_buffer_manager(), |
| global_state->raster_thread_helper()->task_graph_runner())); |
| } |
| |
| void InitializeWebLayerTreeView(WebLayerTreeViewImpl* web_layer_tree_view, |
| mojo::ApplicationImpl* app, |
| mojo::View* view, |
| blink::WebWidget* widget) { |
| DCHECK(view); |
| mojo::URLRequestPtr request(mojo::URLRequest::New()); |
| request->url = mojo::String::From("mojo:view_manager"); |
| mojo::GpuPtr gpu_service; |
| app->ConnectToService(request.Pass(), &gpu_service); |
| web_layer_tree_view->Initialize(gpu_service.Pass(), view, widget); |
| } |
| |
| void UpdateWebViewSizeFromViewSize(mojo::View* view, |
| blink::WebWidget* web_widget, |
| WebLayerTreeViewImpl* web_layer_tree_view) { |
| const gfx::Size size_in_pixels(view->bounds().width, view->bounds().height); |
| const gfx::Size size_in_dips = gfx::ConvertSizeToDIP( |
| view->viewport_metrics().device_pixel_ratio, size_in_pixels); |
| web_widget->resize( |
| blink::WebSize(size_in_dips.width(), size_in_dips.height())); |
| web_layer_tree_view->setViewportSize(size_in_pixels); |
| } |
| |
| void ConfigureSettings(blink::WebSettings* settings) { |
| settings->setCookieEnabled(true); |
| settings->setDefaultFixedFontSize(13); |
| settings->setDefaultFontSize(16); |
| settings->setLoadsImagesAutomatically(true); |
| settings->setJavaScriptEnabled(true); |
| } |
| |
| } // namespace |
| |
| // HTMLWidgetRootRemote ------------------------------------------------------- |
| |
| HTMLWidgetRootRemote::HTMLWidgetRootRemote() |
| : web_view_(blink::WebView::create(nullptr)) { |
| ConfigureSettings(web_view_->settings()); |
| } |
| |
| HTMLWidgetRootRemote::~HTMLWidgetRootRemote() {} |
| |
| blink::WebWidget* HTMLWidgetRootRemote::GetWidget() { |
| return web_view_; |
| } |
| |
| void HTMLWidgetRootRemote::OnViewBoundsChanged(mojo::View* view) {} |
| |
| // HTMLWidgetRootLocal -------------------------------------------------------- |
| |
| HTMLWidgetRootLocal::CreateParams::CreateParams(mojo::ApplicationImpl* app, |
| GlobalState* global_state, |
| mojo::View* view) |
| : app(app), global_state(global_state), view(view) {} |
| |
| HTMLWidgetRootLocal::CreateParams::~CreateParams() {} |
| |
| HTMLWidgetRootLocal::HTMLWidgetRootLocal(CreateParams* create_params) |
| : app_(create_params->app), |
| global_state_(create_params->global_state), |
| view_(create_params->view), |
| web_view_(nullptr) { |
| web_view_ = blink::WebView::create(this); |
| // Creating the widget calls initializeLayerTreeView() to create the |
| // |web_layer_tree_view_impl_|. As we haven't yet assigned the |web_view_| |
| // we have to set it here. |
| if (web_layer_tree_view_impl_) { |
| InitializeWebLayerTreeView(web_layer_tree_view_impl_.get(), app_, view_, |
| web_view_); |
| UpdateWebViewSizeFromViewSize(view_, web_view_, |
| web_layer_tree_view_impl_.get()); |
| } |
| ConfigureSettings(web_view_->settings()); |
| } |
| |
| HTMLWidgetRootLocal::~HTMLWidgetRootLocal() {} |
| |
| blink::WebStorageNamespace* |
| HTMLWidgetRootLocal::createSessionStorageNamespace() { |
| return new WebStorageNamespaceImpl(); |
| } |
| |
| void HTMLWidgetRootLocal::didCancelCompositionOnSelectionChange() { |
| // TODO(penghuang): Update text input state. |
| } |
| |
| void HTMLWidgetRootLocal::didChangeContents() { |
| // TODO(penghuang): Update text input state. |
| } |
| |
| void HTMLWidgetRootLocal::initializeLayerTreeView() { |
| web_layer_tree_view_impl_ = CreateWebLayerTreeView(global_state_); |
| } |
| |
| blink::WebLayerTreeView* HTMLWidgetRootLocal::layerTreeView() { |
| return web_layer_tree_view_impl_.get(); |
| } |
| |
| void HTMLWidgetRootLocal::resetInputMethod() { |
| // When this method gets called, WebWidgetClient implementation should |
| // reset the input method by cancelling any ongoing composition. |
| // TODO(penghuang): Reset IME. |
| } |
| |
| void HTMLWidgetRootLocal::didHandleGestureEvent( |
| const blink::WebGestureEvent& event, |
| bool event_cancelled) { |
| // Called when a gesture event is handled. |
| if (event_cancelled) |
| return; |
| |
| if (event.type == blink::WebInputEvent::GestureTap) { |
| const bool show_ime = true; |
| UpdateTextInputState(show_ime); |
| } else if (event.type == blink::WebInputEvent::GestureLongPress) { |
| // Only show IME if the textfield contains text. |
| const bool show_ime = !web_view_->textInputInfo().value.isEmpty(); |
| UpdateTextInputState(show_ime); |
| } |
| } |
| |
| void HTMLWidgetRootLocal::didUpdateTextOfFocusedElementByNonUserInput() { |
| // Called when value of focused textfield gets dirty, e.g. value is |
| // modified by script, not by user input. |
| const bool show_ime = false; |
| UpdateTextInputState(show_ime); |
| } |
| |
| void HTMLWidgetRootLocal::showImeIfNeeded() { |
| // Request the browser to show the IME for current input type. |
| const bool show_ime = true; |
| UpdateTextInputState(show_ime); |
| } |
| |
| void HTMLWidgetRootLocal::UpdateTextInputState(bool show_ime) { |
| blink::WebTextInputInfo new_info = web_view_->textInputInfo(); |
| // Only show IME if the focused element is editable. |
| show_ime = show_ime && new_info.type != blink::WebTextInputTypeNone; |
| if (show_ime || text_input_info_ != new_info) { |
| text_input_info_ = new_info; |
| mojo::TextInputStatePtr state = mojo::TextInputState::New(); |
| state->type = mojo::ConvertTo<mojo::TextInputType>(new_info.type); |
| state->flags = new_info.flags; |
| state->text = mojo::String::From(new_info.value.utf8()); |
| state->selection_start = new_info.selectionStart; |
| state->selection_end = new_info.selectionEnd; |
| state->composition_start = new_info.compositionStart; |
| state->composition_end = new_info.compositionEnd; |
| if (show_ime) |
| view_->SetImeVisibility(true, state.Pass()); |
| else |
| view_->SetTextInputState(state.Pass()); |
| } |
| } |
| |
| blink::WebWidget* HTMLWidgetRootLocal::GetWidget() { |
| return web_view_; |
| } |
| |
| void HTMLWidgetRootLocal::OnViewBoundsChanged(mojo::View* view) { |
| UpdateWebViewSizeFromViewSize(view, web_view_, |
| web_layer_tree_view_impl_.get()); |
| } |
| |
| // HTMLWidgetLocalRoot -------------------------------------------------------- |
| |
| HTMLWidgetLocalRoot::HTMLWidgetLocalRoot(mojo::ApplicationImpl* app, |
| GlobalState* global_state, |
| mojo::View* view, |
| blink::WebLocalFrame* web_local_frame) |
| : app_(app), global_state_(global_state), web_frame_widget_(nullptr) { |
| web_frame_widget_ = blink::WebFrameWidget::create(this, web_local_frame); |
| // Creating the widget calls initializeLayerTreeView() to create the |
| // |web_layer_tree_view_impl_|. As we haven't yet assigned the |
| // |web_frame_widget_| |
| // we have to set it here. |
| if (web_layer_tree_view_impl_) { |
| InitializeWebLayerTreeView(web_layer_tree_view_impl_.get(), app_, view, |
| web_frame_widget_); |
| UpdateWebViewSizeFromViewSize(view, web_frame_widget_, |
| web_layer_tree_view_impl_.get()); |
| } |
| } |
| |
| HTMLWidgetLocalRoot::~HTMLWidgetLocalRoot() {} |
| |
| blink::WebWidget* HTMLWidgetLocalRoot::GetWidget() { |
| return web_frame_widget_; |
| } |
| |
| void HTMLWidgetLocalRoot::OnViewBoundsChanged(mojo::View* view) { |
| UpdateWebViewSizeFromViewSize(view, web_frame_widget_, |
| web_layer_tree_view_impl_.get()); |
| } |
| |
| void HTMLWidgetLocalRoot::initializeLayerTreeView() { |
| web_layer_tree_view_impl_ = CreateWebLayerTreeView(global_state_); |
| } |
| |
| blink::WebLayerTreeView* HTMLWidgetLocalRoot::layerTreeView() { |
| return web_layer_tree_view_impl_.get(); |
| } |
| |
| } // namespace html_viewer |