1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/html_viewer/html_widget.h"
7 #include "components/html_viewer/blink_input_events_type_converters.h"
8 #include "components/html_viewer/blink_text_input_type_converters.h"
9 #include "components/html_viewer/global_state.h"
10 #include "components/html_viewer/web_layer_tree_view_impl.h"
11 #include "components/html_viewer/web_storage_namespace_impl.h"
12 #include "components/view_manager/public/cpp/view.h"
13 #include "mojo/application/public/cpp/application_impl.h"
14 #include "third_party/WebKit/public/web/WebFrameWidget.h"
15 #include "third_party/WebKit/public/web/WebInputEvent.h"
16 #include "third_party/WebKit/public/web/WebSettings.h"
17 #include "third_party/WebKit/public/web/WebView.h"
18 #include "ui/gfx/geometry/dip_util.h"
20 namespace html_viewer
{
23 scoped_ptr
<WebLayerTreeViewImpl
> CreateWebLayerTreeView(
24 GlobalState
* global_state
) {
25 return make_scoped_ptr(new WebLayerTreeViewImpl(
26 global_state
->compositor_thread(),
27 global_state
->gpu_memory_buffer_manager(),
28 global_state
->raster_thread_helper()->task_graph_runner()));
31 void InitializeWebLayerTreeView(WebLayerTreeViewImpl
* web_layer_tree_view
,
32 mojo::ApplicationImpl
* app
,
34 blink::WebWidget
* widget
) {
36 mojo::URLRequestPtr
request(mojo::URLRequest::New());
37 request
->url
= mojo::String::From("mojo:view_manager");
38 mojo::GpuPtr gpu_service
;
39 app
->ConnectToService(request
.Pass(), &gpu_service
);
40 web_layer_tree_view
->Initialize(gpu_service
.Pass(), view
, widget
);
43 void UpdateWebViewSizeFromViewSize(mojo::View
* view
,
44 blink::WebWidget
* web_widget
,
45 WebLayerTreeViewImpl
* web_layer_tree_view
) {
46 const gfx::Size
size_in_pixels(view
->bounds().width
, view
->bounds().height
);
47 const gfx::Size size_in_dips
= gfx::ConvertSizeToDIP(
48 view
->viewport_metrics().device_pixel_ratio
, size_in_pixels
);
50 blink::WebSize(size_in_dips
.width(), size_in_dips
.height()));
51 web_layer_tree_view
->setViewportSize(size_in_pixels
);
54 void ConfigureSettings(blink::WebSettings
* settings
) {
55 settings
->setCookieEnabled(true);
56 settings
->setDefaultFixedFontSize(13);
57 settings
->setDefaultFontSize(16);
58 settings
->setLoadsImagesAutomatically(true);
59 settings
->setJavaScriptEnabled(true);
64 // HTMLWidgetRootRemote -------------------------------------------------------
66 HTMLWidgetRootRemote::HTMLWidgetRootRemote()
67 : web_view_(blink::WebView::create(nullptr)) {
68 ConfigureSettings(web_view_
->settings());
71 HTMLWidgetRootRemote::~HTMLWidgetRootRemote() {}
73 blink::WebWidget
* HTMLWidgetRootRemote::GetWidget() {
77 void HTMLWidgetRootRemote::OnViewBoundsChanged(mojo::View
* view
) {}
79 // HTMLWidgetRootLocal --------------------------------------------------------
81 HTMLWidgetRootLocal::CreateParams::CreateParams(mojo::ApplicationImpl
* app
,
82 GlobalState
* global_state
,
84 : app(app
), global_state(global_state
), view(view
) {}
86 HTMLWidgetRootLocal::CreateParams::~CreateParams() {}
88 HTMLWidgetRootLocal::HTMLWidgetRootLocal(CreateParams
* create_params
)
89 : app_(create_params
->app
),
90 global_state_(create_params
->global_state
),
91 view_(create_params
->view
),
93 web_view_
= blink::WebView::create(this);
94 // Creating the widget calls initializeLayerTreeView() to create the
95 // |web_layer_tree_view_impl_|. As we haven't yet assigned the |web_view_|
96 // we have to set it here.
97 if (web_layer_tree_view_impl_
) {
98 InitializeWebLayerTreeView(web_layer_tree_view_impl_
.get(), app_
, view_
,
100 UpdateWebViewSizeFromViewSize(view_
, web_view_
,
101 web_layer_tree_view_impl_
.get());
103 ConfigureSettings(web_view_
->settings());
106 HTMLWidgetRootLocal::~HTMLWidgetRootLocal() {}
108 blink::WebStorageNamespace
*
109 HTMLWidgetRootLocal::createSessionStorageNamespace() {
110 return new WebStorageNamespaceImpl();
113 void HTMLWidgetRootLocal::didCancelCompositionOnSelectionChange() {
114 // TODO(penghuang): Update text input state.
117 void HTMLWidgetRootLocal::didChangeContents() {
118 // TODO(penghuang): Update text input state.
121 void HTMLWidgetRootLocal::initializeLayerTreeView() {
122 web_layer_tree_view_impl_
= CreateWebLayerTreeView(global_state_
);
125 blink::WebLayerTreeView
* HTMLWidgetRootLocal::layerTreeView() {
126 return web_layer_tree_view_impl_
.get();
129 void HTMLWidgetRootLocal::resetInputMethod() {
130 // When this method gets called, WebWidgetClient implementation should
131 // reset the input method by cancelling any ongoing composition.
132 // TODO(penghuang): Reset IME.
135 void HTMLWidgetRootLocal::didHandleGestureEvent(
136 const blink::WebGestureEvent
& event
,
137 bool event_cancelled
) {
138 // Called when a gesture event is handled.
142 if (event
.type
== blink::WebInputEvent::GestureTap
) {
143 const bool show_ime
= true;
144 UpdateTextInputState(show_ime
);
145 } else if (event
.type
== blink::WebInputEvent::GestureLongPress
) {
146 // Only show IME if the textfield contains text.
147 const bool show_ime
= !web_view_
->textInputInfo().value
.isEmpty();
148 UpdateTextInputState(show_ime
);
152 void HTMLWidgetRootLocal::didUpdateTextOfFocusedElementByNonUserInput() {
153 // Called when value of focused textfield gets dirty, e.g. value is
154 // modified by script, not by user input.
155 const bool show_ime
= false;
156 UpdateTextInputState(show_ime
);
159 void HTMLWidgetRootLocal::showImeIfNeeded() {
160 // Request the browser to show the IME for current input type.
161 const bool show_ime
= true;
162 UpdateTextInputState(show_ime
);
165 void HTMLWidgetRootLocal::UpdateTextInputState(bool show_ime
) {
166 blink::WebTextInputInfo new_info
= web_view_
->textInputInfo();
167 // Only show IME if the focused element is editable.
168 show_ime
= show_ime
&& new_info
.type
!= blink::WebTextInputTypeNone
;
169 if (show_ime
|| text_input_info_
!= new_info
) {
170 text_input_info_
= new_info
;
171 mojo::TextInputStatePtr state
= mojo::TextInputState::New();
172 state
->type
= mojo::ConvertTo
<mojo::TextInputType
>(new_info
.type
);
173 state
->flags
= new_info
.flags
;
174 state
->text
= mojo::String::From(new_info
.value
.utf8());
175 state
->selection_start
= new_info
.selectionStart
;
176 state
->selection_end
= new_info
.selectionEnd
;
177 state
->composition_start
= new_info
.compositionStart
;
178 state
->composition_end
= new_info
.compositionEnd
;
180 view_
->SetImeVisibility(true, state
.Pass());
182 view_
->SetTextInputState(state
.Pass());
186 blink::WebWidget
* HTMLWidgetRootLocal::GetWidget() {
190 void HTMLWidgetRootLocal::OnViewBoundsChanged(mojo::View
* view
) {
191 UpdateWebViewSizeFromViewSize(view
, web_view_
,
192 web_layer_tree_view_impl_
.get());
195 // HTMLWidgetLocalRoot --------------------------------------------------------
197 HTMLWidgetLocalRoot::HTMLWidgetLocalRoot(mojo::ApplicationImpl
* app
,
198 GlobalState
* global_state
,
200 blink::WebLocalFrame
* web_local_frame
)
201 : app_(app
), global_state_(global_state
), web_frame_widget_(nullptr) {
202 web_frame_widget_
= blink::WebFrameWidget::create(this, web_local_frame
);
203 // Creating the widget calls initializeLayerTreeView() to create the
204 // |web_layer_tree_view_impl_|. As we haven't yet assigned the
205 // |web_frame_widget_|
206 // we have to set it here.
207 if (web_layer_tree_view_impl_
) {
208 InitializeWebLayerTreeView(web_layer_tree_view_impl_
.get(), app_
, view
,
210 UpdateWebViewSizeFromViewSize(view
, web_frame_widget_
,
211 web_layer_tree_view_impl_
.get());
215 HTMLWidgetLocalRoot::~HTMLWidgetLocalRoot() {}
217 blink::WebWidget
* HTMLWidgetLocalRoot::GetWidget() {
218 return web_frame_widget_
;
221 void HTMLWidgetLocalRoot::OnViewBoundsChanged(mojo::View
* view
) {
222 UpdateWebViewSizeFromViewSize(view
, web_frame_widget_
,
223 web_layer_tree_view_impl_
.get());
226 void HTMLWidgetLocalRoot::initializeLayerTreeView() {
227 web_layer_tree_view_impl_
= CreateWebLayerTreeView(global_state_
);
230 blink::WebLayerTreeView
* HTMLWidgetLocalRoot::layerTreeView() {
231 return web_layer_tree_view_impl_
.get();
234 } // namespace html_viewer