OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/renderer_host/render_widget_host_view_aura.h" | 5 #include "content/browser/renderer_host/render_widget_host_view_aura.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 | 8 |
9 #include "base/auto_reset.h" | 9 #include "base/auto_reset.h" |
10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
(...skipping 12 matching lines...) Expand all Loading... |
23 #include "content/browser/accessibility/browser_accessibility_manager.h" | 23 #include "content/browser/accessibility/browser_accessibility_manager.h" |
24 #include "content/browser/accessibility/browser_accessibility_state_impl.h" | 24 #include "content/browser/accessibility/browser_accessibility_state_impl.h" |
25 #include "content/browser/bad_message.h" | 25 #include "content/browser/bad_message.h" |
26 #include "content/browser/frame_host/frame_tree.h" | 26 #include "content/browser/frame_host/frame_tree.h" |
27 #include "content/browser/frame_host/frame_tree_node.h" | 27 #include "content/browser/frame_host/frame_tree_node.h" |
28 #include "content/browser/frame_host/render_frame_host_impl.h" | 28 #include "content/browser/frame_host/render_frame_host_impl.h" |
29 #include "content/browser/gpu/compositor_util.h" | 29 #include "content/browser/gpu/compositor_util.h" |
30 #include "content/browser/renderer_host/compositor_resize_lock_aura.h" | 30 #include "content/browser/renderer_host/compositor_resize_lock_aura.h" |
31 #include "content/browser/renderer_host/dip_util.h" | 31 #include "content/browser/renderer_host/dip_util.h" |
32 #include "content/browser/renderer_host/input/synthetic_gesture_target_aura.h" | 32 #include "content/browser/renderer_host/input/synthetic_gesture_target_aura.h" |
33 #include "content/browser/renderer_host/input/touch_selection_controller_client_
aura.h" | |
34 #include "content/browser/renderer_host/input/ui_touch_selection_helper.h" | |
35 #include "content/browser/renderer_host/input/web_input_event_util.h" | 33 #include "content/browser/renderer_host/input/web_input_event_util.h" |
36 #include "content/browser/renderer_host/overscroll_controller.h" | 34 #include "content/browser/renderer_host/overscroll_controller.h" |
37 #include "content/browser/renderer_host/render_view_host_delegate.h" | 35 #include "content/browser/renderer_host/render_view_host_delegate.h" |
38 #include "content/browser/renderer_host/render_view_host_delegate_view.h" | 36 #include "content/browser/renderer_host/render_view_host_delegate_view.h" |
39 #include "content/browser/renderer_host/render_view_host_impl.h" | 37 #include "content/browser/renderer_host/render_view_host_impl.h" |
40 #include "content/browser/renderer_host/render_widget_host_impl.h" | 38 #include "content/browser/renderer_host/render_widget_host_impl.h" |
41 #include "content/browser/renderer_host/ui_events_helper.h" | 39 #include "content/browser/renderer_host/ui_events_helper.h" |
42 #include "content/browser/renderer_host/web_input_event_aura.h" | 40 #include "content/browser/renderer_host/web_input_event_aura.h" |
43 #include "content/common/gpu/client/gl_helper.h" | 41 #include "content/common/gpu/client/gl_helper.h" |
44 #include "content/common/gpu/gpu_messages.h" | 42 #include "content/common/gpu/gpu_messages.h" |
(...skipping 21 matching lines...) Expand all Loading... |
66 #include "ui/aura/window_tree_host.h" | 64 #include "ui/aura/window_tree_host.h" |
67 #include "ui/base/clipboard/scoped_clipboard_writer.h" | 65 #include "ui/base/clipboard/scoped_clipboard_writer.h" |
68 #include "ui/base/hit_test.h" | 66 #include "ui/base/hit_test.h" |
69 #include "ui/base/ime/input_method.h" | 67 #include "ui/base/ime/input_method.h" |
70 #include "ui/base/ui_base_types.h" | 68 #include "ui/base/ui_base_types.h" |
71 #include "ui/compositor/compositor_vsync_manager.h" | 69 #include "ui/compositor/compositor_vsync_manager.h" |
72 #include "ui/compositor/dip_util.h" | 70 #include "ui/compositor/dip_util.h" |
73 #include "ui/events/blink/blink_event_util.h" | 71 #include "ui/events/blink/blink_event_util.h" |
74 #include "ui/events/event.h" | 72 #include "ui/events/event.h" |
75 #include "ui/events/event_utils.h" | 73 #include "ui/events/event_utils.h" |
76 #include "ui/events/gesture_detection/gesture_configuration.h" | |
77 #include "ui/events/gestures/gesture_recognizer.h" | 74 #include "ui/events/gestures/gesture_recognizer.h" |
78 #include "ui/gfx/canvas.h" | 75 #include "ui/gfx/canvas.h" |
79 #include "ui/gfx/display.h" | 76 #include "ui/gfx/display.h" |
80 #include "ui/gfx/geometry/rect_conversions.h" | 77 #include "ui/gfx/geometry/rect_conversions.h" |
81 #include "ui/gfx/geometry/size_conversions.h" | 78 #include "ui/gfx/geometry/size_conversions.h" |
82 #include "ui/gfx/screen.h" | 79 #include "ui/gfx/screen.h" |
83 #include "ui/gfx/skia_util.h" | 80 #include "ui/gfx/skia_util.h" |
84 #include "ui/touch_selection/touch_selection_controller.h" | |
85 #include "ui/wm/public/activation_client.h" | 81 #include "ui/wm/public/activation_client.h" |
86 #include "ui/wm/public/scoped_tooltip_disabler.h" | 82 #include "ui/wm/public/scoped_tooltip_disabler.h" |
87 #include "ui/wm/public/tooltip_client.h" | 83 #include "ui/wm/public/tooltip_client.h" |
88 #include "ui/wm/public/transient_window_client.h" | 84 #include "ui/wm/public/transient_window_client.h" |
89 #include "ui/wm/public/window_types.h" | 85 #include "ui/wm/public/window_types.h" |
90 | 86 |
91 #if defined(OS_WIN) | 87 #if defined(OS_WIN) |
92 #include "content/browser/accessibility/browser_accessibility_manager_win.h" | 88 #include "content/browser/accessibility/browser_accessibility_manager_win.h" |
93 #include "content/browser/accessibility/browser_accessibility_win.h" | 89 #include "content/browser/accessibility/browser_accessibility_win.h" |
94 #include "content/browser/renderer_host/legacy_render_widget_host_win.h" | 90 #include "content/browser/renderer_host/legacy_render_widget_host_win.h" |
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
459 last_swapped_software_frame_scale_factor_(1.f), | 455 last_swapped_software_frame_scale_factor_(1.f), |
460 paint_canvas_(NULL), | 456 paint_canvas_(NULL), |
461 synthetic_move_sent_(false), | 457 synthetic_move_sent_(false), |
462 cursor_visibility_state_in_renderer_(UNKNOWN), | 458 cursor_visibility_state_in_renderer_(UNKNOWN), |
463 #if defined(OS_WIN) | 459 #if defined(OS_WIN) |
464 legacy_render_widget_host_HWND_(NULL), | 460 legacy_render_widget_host_HWND_(NULL), |
465 legacy_window_destroyed_(false), | 461 legacy_window_destroyed_(false), |
466 showing_context_menu_(false), | 462 showing_context_menu_(false), |
467 #endif | 463 #endif |
468 has_snapped_to_boundary_(false), | 464 has_snapped_to_boundary_(false), |
| 465 touch_editing_client_(NULL), |
469 is_guest_view_hack_(is_guest_view_hack), | 466 is_guest_view_hack_(is_guest_view_hack), |
470 begin_frame_observer_proxy_(this), | 467 begin_frame_observer_proxy_(this), |
471 weak_ptr_factory_(this) { | 468 weak_ptr_factory_(this) { |
472 if (!is_guest_view_hack_) | 469 if (!is_guest_view_hack_) |
473 host_->SetView(this); | 470 host_->SetView(this); |
474 | 471 |
475 window_observer_.reset(new WindowObserver(this)); | 472 window_observer_.reset(new WindowObserver(this)); |
476 | 473 |
477 aura::client::SetTooltipText(window_, &tooltip_); | 474 aura::client::SetTooltipText(window_, &tooltip_); |
478 aura::client::SetActivationDelegate(window_, this); | 475 aura::client::SetActivationDelegate(window_, this); |
479 aura::client::SetFocusChangeObserver(window_, this); | 476 aura::client::SetFocusChangeObserver(window_, this); |
480 window_->set_layer_owner_delegate(delegated_frame_host_.get()); | 477 window_->set_layer_owner_delegate(delegated_frame_host_.get()); |
481 gfx::Screen::GetScreenFor(window_)->AddObserver(this); | 478 gfx::Screen::GetScreenFor(window_)->AddObserver(this); |
482 | 479 |
483 bool overscroll_enabled = base::CommandLine::ForCurrentProcess()-> | 480 bool overscroll_enabled = base::CommandLine::ForCurrentProcess()-> |
484 GetSwitchValueASCII(switches::kOverscrollHistoryNavigation) != "0"; | 481 GetSwitchValueASCII(switches::kOverscrollHistoryNavigation) != "0"; |
485 SetOverscrollControllerEnabled(overscroll_enabled); | 482 SetOverscrollControllerEnabled(overscroll_enabled); |
486 | |
487 selection_controller_client_.reset( | |
488 new TouchSelectionControllerClientAura(this)); | |
489 CreateSelectionController(); | |
490 } | 483 } |
491 | 484 |
492 //////////////////////////////////////////////////////////////////////////////// | 485 //////////////////////////////////////////////////////////////////////////////// |
493 // RenderWidgetHostViewAura, RenderWidgetHostView implementation: | 486 // RenderWidgetHostViewAura, RenderWidgetHostView implementation: |
494 | 487 |
495 bool RenderWidgetHostViewAura::OnMessageReceived( | 488 bool RenderWidgetHostViewAura::OnMessageReceived( |
496 const IPC::Message& message) { | 489 const IPC::Message& message) { |
497 bool handled = true; | 490 bool handled = true; |
498 IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostViewAura, message) | 491 IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostViewAura, message) |
499 // TODO(kevers): Move to RenderWidgetHostViewImpl and consolidate IPC | 492 // TODO(kevers): Move to RenderWidgetHostViewImpl and consolidate IPC |
(...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
965 if (text_input_type_ != type || | 958 if (text_input_type_ != type || |
966 text_input_mode_ != input_mode || | 959 text_input_mode_ != input_mode || |
967 can_compose_inline_ != can_compose_inline || | 960 can_compose_inline_ != can_compose_inline || |
968 text_input_flags_ != flags) { | 961 text_input_flags_ != flags) { |
969 text_input_type_ = type; | 962 text_input_type_ = type; |
970 text_input_mode_ = input_mode; | 963 text_input_mode_ = input_mode; |
971 can_compose_inline_ = can_compose_inline; | 964 can_compose_inline_ = can_compose_inline; |
972 text_input_flags_ = flags; | 965 text_input_flags_ = flags; |
973 if (GetInputMethod()) | 966 if (GetInputMethod()) |
974 GetInputMethod()->OnTextInputTypeChanged(this); | 967 GetInputMethod()->OnTextInputTypeChanged(this); |
| 968 if (touch_editing_client_) |
| 969 touch_editing_client_->OnTextInputTypeChanged(text_input_type_); |
975 } | 970 } |
976 } | 971 } |
977 | 972 |
978 void RenderWidgetHostViewAura::OnTextInputStateChanged( | 973 void RenderWidgetHostViewAura::OnTextInputStateChanged( |
979 const ViewHostMsg_TextInputState_Params& params) { | 974 const ViewHostMsg_TextInputState_Params& params) { |
980 text_input_flags_ = params.flags; | 975 text_input_flags_ = params.flags; |
981 if (params.show_ime_if_needed && params.type != ui::TEXT_INPUT_TYPE_NONE) { | 976 if (params.show_ime_if_needed && params.type != ui::TEXT_INPUT_TYPE_NONE) { |
982 if (GetInputMethod()) | 977 if (GetInputMethod()) |
983 GetInputMethod()->ShowImeIfNeeded(); | 978 GetInputMethod()->ShowImeIfNeeded(); |
984 } | 979 } |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1081 } | 1076 } |
1082 } | 1077 } |
1083 | 1078 |
1084 if (anchor_bound == selection_anchor_ && focus_bound == selection_focus_) | 1079 if (anchor_bound == selection_anchor_ && focus_bound == selection_focus_) |
1085 return; | 1080 return; |
1086 | 1081 |
1087 selection_anchor_ = anchor_bound; | 1082 selection_anchor_ = anchor_bound; |
1088 selection_focus_ = focus_bound; | 1083 selection_focus_ = focus_bound; |
1089 if (GetInputMethod()) | 1084 if (GetInputMethod()) |
1090 GetInputMethod()->OnCaretBoundsChanged(this); | 1085 GetInputMethod()->OnCaretBoundsChanged(this); |
| 1086 |
| 1087 if (touch_editing_client_) { |
| 1088 touch_editing_client_->OnSelectionOrCursorChanged( |
| 1089 anchor_bound, focus_bound); |
| 1090 } |
1091 } | 1091 } |
1092 | 1092 |
1093 void RenderWidgetHostViewAura::CopyFromCompositingSurface( | 1093 void RenderWidgetHostViewAura::CopyFromCompositingSurface( |
1094 const gfx::Rect& src_subrect, | 1094 const gfx::Rect& src_subrect, |
1095 const gfx::Size& dst_size, | 1095 const gfx::Size& dst_size, |
1096 ReadbackRequestCallback& callback, | 1096 ReadbackRequestCallback& callback, |
1097 const SkColorType preferred_color_type) { | 1097 const SkColorType preferred_color_type) { |
1098 delegated_frame_host_->CopyFromCompositingSurface( | 1098 delegated_frame_host_->CopyFromCompositingSurface( |
1099 src_subrect, dst_size, callback, preferred_color_type); | 1099 src_subrect, dst_size, callback, preferred_color_type); |
1100 } | 1100 } |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1171 TRACE_EVENT0("content", "RenderWidgetHostViewAura::OnSwapCompositorFrame"); | 1171 TRACE_EVENT0("content", "RenderWidgetHostViewAura::OnSwapCompositorFrame"); |
1172 | 1172 |
1173 last_scroll_offset_ = frame->metadata.root_scroll_offset; | 1173 last_scroll_offset_ = frame->metadata.root_scroll_offset; |
1174 if (frame->delegated_frame_data) { | 1174 if (frame->delegated_frame_data) { |
1175 delegated_frame_host_->SwapDelegatedFrame( | 1175 delegated_frame_host_->SwapDelegatedFrame( |
1176 output_surface_id, | 1176 output_surface_id, |
1177 frame->delegated_frame_data.Pass(), | 1177 frame->delegated_frame_data.Pass(), |
1178 frame->metadata.device_scale_factor, | 1178 frame->metadata.device_scale_factor, |
1179 frame->metadata.latency_info, | 1179 frame->metadata.latency_info, |
1180 &frame->metadata.satisfies_sequences); | 1180 &frame->metadata.satisfies_sequences); |
1181 SelectionUpdated(frame->metadata.selection.is_editable, | |
1182 frame->metadata.selection.is_empty_text_form_control, | |
1183 ConvertSelectionBound(frame->metadata.selection.start), | |
1184 ConvertSelectionBound(frame->metadata.selection.end)); | |
1185 return; | 1181 return; |
1186 } | 1182 } |
1187 | 1183 |
1188 if (frame->software_frame_data) { | 1184 if (frame->software_frame_data) { |
1189 DLOG(ERROR) << "Unable to use software frame in aura"; | 1185 DLOG(ERROR) << "Unable to use software frame in aura"; |
1190 bad_message::ReceivedBadMessage(host_->GetProcess(), | 1186 bad_message::ReceivedBadMessage(host_->GetProcess(), |
1191 bad_message::RWHVA_SHARED_MEMORY); | 1187 bad_message::RWHVA_SHARED_MEMORY); |
1192 return; | 1188 return; |
1193 } | 1189 } |
1194 } | 1190 } |
1195 | 1191 |
1196 void RenderWidgetHostViewAura::DidStopFlinging() { | 1192 void RenderWidgetHostViewAura::DidStopFlinging() { |
1197 selection_controller_client_->OnScrollCompleted(); | 1193 if (touch_editing_client_) |
| 1194 touch_editing_client_->DidStopFlinging(); |
1198 } | 1195 } |
1199 | 1196 |
1200 #if defined(OS_WIN) | 1197 #if defined(OS_WIN) |
1201 void RenderWidgetHostViewAura::SetParentNativeViewAccessible( | 1198 void RenderWidgetHostViewAura::SetParentNativeViewAccessible( |
1202 gfx::NativeViewAccessible accessible_parent) { | 1199 gfx::NativeViewAccessible accessible_parent) { |
1203 } | 1200 } |
1204 | 1201 |
1205 gfx::NativeViewId RenderWidgetHostViewAura::GetParentForWindowlessPlugin() | 1202 gfx::NativeViewId RenderWidgetHostViewAura::GetParentForWindowlessPlugin() |
1206 const { | 1203 const { |
1207 if (legacy_render_widget_host_HWND_) { | 1204 if (legacy_render_widget_host_HWND_) { |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1267 InputEventAckState ack_result) { | 1264 InputEventAckState ack_result) { |
1268 if (overscroll_controller_) { | 1265 if (overscroll_controller_) { |
1269 overscroll_controller_->ReceivedEventACK( | 1266 overscroll_controller_->ReceivedEventACK( |
1270 event, (INPUT_EVENT_ACK_STATE_CONSUMED == ack_result)); | 1267 event, (INPUT_EVENT_ACK_STATE_CONSUMED == ack_result)); |
1271 } | 1268 } |
1272 } | 1269 } |
1273 | 1270 |
1274 void RenderWidgetHostViewAura::GestureEventAck( | 1271 void RenderWidgetHostViewAura::GestureEventAck( |
1275 const blink::WebGestureEvent& event, | 1272 const blink::WebGestureEvent& event, |
1276 InputEventAckState ack_result) { | 1273 InputEventAckState ack_result) { |
| 1274 if (touch_editing_client_) |
| 1275 touch_editing_client_->GestureEventAck(event.type); |
| 1276 |
1277 if (overscroll_controller_) { | 1277 if (overscroll_controller_) { |
1278 overscroll_controller_->ReceivedEventACK( | 1278 overscroll_controller_->ReceivedEventACK( |
1279 event, (INPUT_EVENT_ACK_STATE_CONSUMED == ack_result)); | 1279 event, (INPUT_EVENT_ACK_STATE_CONSUMED == ack_result)); |
1280 } | 1280 } |
1281 } | 1281 } |
1282 | 1282 |
1283 void RenderWidgetHostViewAura::ProcessAckedTouchEvent( | 1283 void RenderWidgetHostViewAura::ProcessAckedTouchEvent( |
1284 const TouchEventWithLatencyInfo& touch, | 1284 const TouchEventWithLatencyInfo& touch, |
1285 InputEventAckState ack_result) { | 1285 InputEventAckState ack_result) { |
1286 ScopedVector<ui::TouchEvent> events; | 1286 ScopedVector<ui::TouchEvent> events; |
(...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1668 return gfx::Rect(origin.x(), | 1668 return gfx::Rect(origin.x(), |
1669 origin.y(), | 1669 origin.y(), |
1670 end.x() - origin.x(), | 1670 end.x() - origin.x(), |
1671 end.y() - origin.y()); | 1671 end.y() - origin.y()); |
1672 } | 1672 } |
1673 | 1673 |
1674 return rect; | 1674 return rect; |
1675 } | 1675 } |
1676 | 1676 |
1677 gfx::Rect RenderWidgetHostViewAura::GetCaretBounds() const { | 1677 gfx::Rect RenderWidgetHostViewAura::GetCaretBounds() const { |
1678 return ConvertRectToScreen( | 1678 gfx::Rect rect = |
1679 ui::RectBetweenSelectionBounds(selection_anchor_, selection_focus_)); | 1679 ui::RectBetweenSelectionBounds(selection_anchor_, selection_focus_); |
| 1680 return ConvertRectToScreen(rect); |
1680 } | 1681 } |
1681 | 1682 |
1682 bool RenderWidgetHostViewAura::GetCompositionCharacterBounds( | 1683 bool RenderWidgetHostViewAura::GetCompositionCharacterBounds( |
1683 uint32 index, | 1684 uint32 index, |
1684 gfx::Rect* rect) const { | 1685 gfx::Rect* rect) const { |
1685 DCHECK(rect); | 1686 DCHECK(rect); |
1686 if (index >= composition_character_bounds_.size()) | 1687 if (index >= composition_character_bounds_.size()) |
1687 return false; | 1688 return false; |
1688 *rect = ConvertRectToScreen(composition_character_bounds_[index]); | 1689 *rect = ConvertRectToScreen(composition_character_bounds_[index]); |
1689 return true; | 1690 return true; |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1853 const gfx::Point& location) { | 1854 const gfx::Point& location) { |
1854 return true; | 1855 return true; |
1855 } | 1856 } |
1856 | 1857 |
1857 bool RenderWidgetHostViewAura::CanFocus() { | 1858 bool RenderWidgetHostViewAura::CanFocus() { |
1858 return popup_type_ == blink::WebPopupTypeNone; | 1859 return popup_type_ == blink::WebPopupTypeNone; |
1859 } | 1860 } |
1860 | 1861 |
1861 void RenderWidgetHostViewAura::OnCaptureLost() { | 1862 void RenderWidgetHostViewAura::OnCaptureLost() { |
1862 host_->LostCapture(); | 1863 host_->LostCapture(); |
| 1864 if (touch_editing_client_) |
| 1865 touch_editing_client_->EndTouchEditing(false); |
1863 } | 1866 } |
1864 | 1867 |
1865 void RenderWidgetHostViewAura::OnPaint(const ui::PaintContext& context) { | 1868 void RenderWidgetHostViewAura::OnPaint(const ui::PaintContext& context) { |
1866 NOTREACHED(); | 1869 NOTREACHED(); |
1867 } | 1870 } |
1868 | 1871 |
1869 void RenderWidgetHostViewAura::OnDeviceScaleFactorChanged( | 1872 void RenderWidgetHostViewAura::OnDeviceScaleFactorChanged( |
1870 float device_scale_factor) { | 1873 float device_scale_factor) { |
1871 if (!host_ || !window_->GetRootWindow()) | 1874 if (!host_ || !window_->GetRootWindow()) |
1872 return; | 1875 return; |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1935 } | 1938 } |
1936 | 1939 |
1937 void RenderWidgetHostViewAura::GetHitTestMask(gfx::Path* mask) const { | 1940 void RenderWidgetHostViewAura::GetHitTestMask(gfx::Path* mask) const { |
1938 } | 1941 } |
1939 | 1942 |
1940 //////////////////////////////////////////////////////////////////////////////// | 1943 //////////////////////////////////////////////////////////////////////////////// |
1941 // RenderWidgetHostViewAura, ui::EventHandler implementation: | 1944 // RenderWidgetHostViewAura, ui::EventHandler implementation: |
1942 | 1945 |
1943 void RenderWidgetHostViewAura::OnKeyEvent(ui::KeyEvent* event) { | 1946 void RenderWidgetHostViewAura::OnKeyEvent(ui::KeyEvent* event) { |
1944 TRACE_EVENT0("input", "RenderWidgetHostViewAura::OnKeyEvent"); | 1947 TRACE_EVENT0("input", "RenderWidgetHostViewAura::OnKeyEvent"); |
| 1948 if (touch_editing_client_ && touch_editing_client_->HandleInputEvent(event)) |
| 1949 return; |
1945 | 1950 |
1946 if (popup_child_host_view_ && popup_child_host_view_->NeedsInputGrab()) { | 1951 if (popup_child_host_view_ && popup_child_host_view_->NeedsInputGrab()) { |
1947 popup_child_host_view_->OnKeyEvent(event); | 1952 popup_child_host_view_->OnKeyEvent(event); |
1948 if (event->handled()) | 1953 if (event->handled()) |
1949 return; | 1954 return; |
1950 } | 1955 } |
1951 | 1956 |
1952 // We need to handle the Escape key for Pepper Flash. | 1957 // We need to handle the Escape key for Pepper Flash. |
1953 if (is_fullscreen_ && event->key_code() == ui::VKEY_ESCAPE) { | 1958 if (is_fullscreen_ && event->key_code() == ui::VKEY_ESCAPE) { |
1954 // Focus the window we were created from. | 1959 // Focus the window we were created from. |
(...skipping 26 matching lines...) Expand all Loading... |
1981 // We don't have to communicate with an input method here. | 1986 // We don't have to communicate with an input method here. |
1982 NativeWebKeyboardEvent webkit_event(*event); | 1987 NativeWebKeyboardEvent webkit_event(*event); |
1983 ForwardKeyboardEvent(webkit_event); | 1988 ForwardKeyboardEvent(webkit_event); |
1984 } | 1989 } |
1985 event->SetHandled(); | 1990 event->SetHandled(); |
1986 } | 1991 } |
1987 | 1992 |
1988 void RenderWidgetHostViewAura::OnMouseEvent(ui::MouseEvent* event) { | 1993 void RenderWidgetHostViewAura::OnMouseEvent(ui::MouseEvent* event) { |
1989 TRACE_EVENT0("input", "RenderWidgetHostViewAura::OnMouseEvent"); | 1994 TRACE_EVENT0("input", "RenderWidgetHostViewAura::OnMouseEvent"); |
1990 | 1995 |
| 1996 if (touch_editing_client_ && touch_editing_client_->HandleInputEvent(event)) |
| 1997 return; |
| 1998 |
1991 if (mouse_locked_) { | 1999 if (mouse_locked_) { |
1992 aura::client::CursorClient* cursor_client = | 2000 aura::client::CursorClient* cursor_client = |
1993 aura::client::GetCursorClient(window_->GetRootWindow()); | 2001 aura::client::GetCursorClient(window_->GetRootWindow()); |
1994 DCHECK(!cursor_client || !cursor_client->IsCursorVisible()); | 2002 DCHECK(!cursor_client || !cursor_client->IsCursorVisible()); |
1995 | 2003 |
1996 if (event->type() == ui::ET_MOUSEWHEEL) { | 2004 if (event->type() == ui::ET_MOUSEWHEEL) { |
1997 blink::WebMouseWheelEvent mouse_wheel_event = | 2005 blink::WebMouseWheelEvent mouse_wheel_event = |
1998 MakeWebMouseWheelEvent(static_cast<ui::MouseWheelEvent&>(*event)); | 2006 MakeWebMouseWheelEvent(static_cast<ui::MouseWheelEvent&>(*event)); |
1999 if (mouse_wheel_event.deltaX != 0 || mouse_wheel_event.deltaY != 0) | 2007 if (mouse_wheel_event.deltaX != 0 || mouse_wheel_event.deltaY != 0) |
2000 host_->ForwardWheelEvent(mouse_wheel_event); | 2008 host_->ForwardWheelEvent(mouse_wheel_event); |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2144 event->ConvertLocationToTarget(window_, window_->parent()); | 2152 event->ConvertLocationToTarget(window_, window_->parent()); |
2145 window_->parent()->delegate()->OnMouseEvent(event); | 2153 window_->parent()->delegate()->OnMouseEvent(event); |
2146 } | 2154 } |
2147 | 2155 |
2148 if (!IsXButtonUpEvent(event)) | 2156 if (!IsXButtonUpEvent(event)) |
2149 event->SetHandled(); | 2157 event->SetHandled(); |
2150 } | 2158 } |
2151 | 2159 |
2152 void RenderWidgetHostViewAura::OnScrollEvent(ui::ScrollEvent* event) { | 2160 void RenderWidgetHostViewAura::OnScrollEvent(ui::ScrollEvent* event) { |
2153 TRACE_EVENT0("input", "RenderWidgetHostViewAura::OnScrollEvent"); | 2161 TRACE_EVENT0("input", "RenderWidgetHostViewAura::OnScrollEvent"); |
| 2162 if (touch_editing_client_ && touch_editing_client_->HandleInputEvent(event)) |
| 2163 return; |
2154 | 2164 |
2155 if (event->type() == ui::ET_SCROLL) { | 2165 if (event->type() == ui::ET_SCROLL) { |
2156 #if !defined(OS_WIN) | 2166 #if !defined(OS_WIN) |
2157 // TODO(ananta) | 2167 // TODO(ananta) |
2158 // Investigate if this is true for Windows 8 Metro ASH as well. | 2168 // Investigate if this is true for Windows 8 Metro ASH as well. |
2159 if (event->finger_count() != 2) | 2169 if (event->finger_count() != 2) |
2160 return; | 2170 return; |
2161 #endif | 2171 #endif |
2162 blink::WebGestureEvent gesture_event = | 2172 blink::WebGestureEvent gesture_event = |
2163 MakeWebGestureEventFlingCancel(); | 2173 MakeWebGestureEventFlingCancel(); |
2164 host_->ForwardGestureEvent(gesture_event); | 2174 host_->ForwardGestureEvent(gesture_event); |
2165 blink::WebMouseWheelEvent mouse_wheel_event = | 2175 blink::WebMouseWheelEvent mouse_wheel_event = |
2166 MakeWebMouseWheelEvent(*event); | 2176 MakeWebMouseWheelEvent(*event); |
2167 host_->ForwardWheelEvent(mouse_wheel_event); | 2177 host_->ForwardWheelEvent(mouse_wheel_event); |
2168 RecordAction(base::UserMetricsAction("TrackpadScroll")); | 2178 RecordAction(base::UserMetricsAction("TrackpadScroll")); |
2169 } else if (event->type() == ui::ET_SCROLL_FLING_START || | 2179 } else if (event->type() == ui::ET_SCROLL_FLING_START || |
2170 event->type() == ui::ET_SCROLL_FLING_CANCEL) { | 2180 event->type() == ui::ET_SCROLL_FLING_CANCEL) { |
2171 blink::WebGestureEvent gesture_event = MakeWebGestureEvent(*event); | 2181 blink::WebGestureEvent gesture_event = MakeWebGestureEvent(*event); |
2172 host_->ForwardGestureEvent(gesture_event); | 2182 host_->ForwardGestureEvent(gesture_event); |
2173 if (event->type() == ui::ET_SCROLL_FLING_START) | 2183 if (event->type() == ui::ET_SCROLL_FLING_START) |
2174 RecordAction(base::UserMetricsAction("TrackpadScrollFling")); | 2184 RecordAction(base::UserMetricsAction("TrackpadScrollFling")); |
2175 } | 2185 } |
2176 | 2186 |
2177 event->SetHandled(); | 2187 event->SetHandled(); |
2178 } | 2188 } |
2179 | 2189 |
2180 void RenderWidgetHostViewAura::OnTouchEvent(ui::TouchEvent* event) { | 2190 void RenderWidgetHostViewAura::OnTouchEvent(ui::TouchEvent* event) { |
2181 TRACE_EVENT0("input", "RenderWidgetHostViewAura::OnTouchEvent"); | 2191 TRACE_EVENT0("input", "RenderWidgetHostViewAura::OnTouchEvent"); |
2182 | 2192 if (touch_editing_client_ && touch_editing_client_->HandleInputEvent(event)) |
2183 bool had_no_pointer = !pointer_state_.GetPointerCount(); | 2193 return; |
2184 | 2194 |
2185 // Update the touch event first. | 2195 // Update the touch event first. |
2186 if (!pointer_state_.OnTouch(*event)) { | 2196 if (!pointer_state_.OnTouch(*event)) { |
2187 event->StopPropagation(); | 2197 event->StopPropagation(); |
2188 return; | 2198 return; |
2189 } | 2199 } |
2190 | 2200 |
2191 blink::WebTouchEvent touch_event; | 2201 blink::WebTouchEvent touch_event = ui::CreateWebTouchEventFromMotionEvent( |
2192 bool handled = selection_controller_->WillHandleTouchEvent(pointer_state_); | 2202 pointer_state_, event->may_cause_scrolling()); |
2193 if (handled) { | |
2194 event->SetHandled(); | |
2195 } else { | |
2196 touch_event = ui::CreateWebTouchEventFromMotionEvent( | |
2197 pointer_state_, event->may_cause_scrolling()); | |
2198 } | |
2199 pointer_state_.CleanupRemovedTouchPoints(*event); | 2203 pointer_state_.CleanupRemovedTouchPoints(*event); |
2200 | 2204 |
2201 if (handled) | |
2202 return; | |
2203 | |
2204 if (had_no_pointer) | |
2205 selection_controller_client_->OnTouchDown(); | |
2206 if (!pointer_state_.GetPointerCount()) | |
2207 selection_controller_client_->OnTouchUp(); | |
2208 | |
2209 // It is important to always mark events as being handled asynchronously when | 2205 // It is important to always mark events as being handled asynchronously when |
2210 // they are forwarded. This ensures that the current event does not get | 2206 // they are forwarded. This ensures that the current event does not get |
2211 // processed by the gesture recognizer before events currently awaiting | 2207 // processed by the gesture recognizer before events currently awaiting |
2212 // dispatch in the touch queue. | 2208 // dispatch in the touch queue. |
2213 event->DisableSynchronousHandling(); | 2209 event->DisableSynchronousHandling(); |
2214 | 2210 |
2215 // Set unchanged touch point to StateStationary for touchmove and | 2211 // Set unchanged touch point to StateStationary for touchmove and |
2216 // touchcancel to make sure only send one ack per WebTouchEvent. | 2212 // touchcancel to make sure only send one ack per WebTouchEvent. |
2217 MarkUnchangedTouchPointsAsStationary(&touch_event, event->touch_id()); | 2213 MarkUnchangedTouchPointsAsStationary(&touch_event, event->touch_id()); |
2218 host_->ForwardTouchEventWithLatencyInfo(touch_event, *event->latency()); | 2214 host_->ForwardTouchEventWithLatencyInfo(touch_event, *event->latency()); |
2219 } | 2215 } |
2220 | 2216 |
2221 void RenderWidgetHostViewAura::OnGestureEvent(ui::GestureEvent* event) { | 2217 void RenderWidgetHostViewAura::OnGestureEvent(ui::GestureEvent* event) { |
2222 TRACE_EVENT0("input", "RenderWidgetHostViewAura::OnGestureEvent"); | 2218 TRACE_EVENT0("input", "RenderWidgetHostViewAura::OnGestureEvent"); |
2223 | |
2224 if ((event->type() == ui::ET_GESTURE_PINCH_BEGIN || | 2219 if ((event->type() == ui::ET_GESTURE_PINCH_BEGIN || |
2225 event->type() == ui::ET_GESTURE_PINCH_UPDATE || | 2220 event->type() == ui::ET_GESTURE_PINCH_UPDATE || |
2226 event->type() == ui::ET_GESTURE_PINCH_END) && !pinch_zoom_enabled_) { | 2221 event->type() == ui::ET_GESTURE_PINCH_END) && !pinch_zoom_enabled_) { |
2227 event->SetHandled(); | 2222 event->SetHandled(); |
2228 return; | 2223 return; |
2229 } | 2224 } |
2230 | 2225 |
2231 HandleGestureForTouchSelection(event); | 2226 if (touch_editing_client_ && touch_editing_client_->HandleInputEvent(event)) |
2232 if (event->handled()) | |
2233 return; | 2227 return; |
2234 | 2228 |
2235 // Confirm existing composition text on TAP gesture, to make sure the input | 2229 // Confirm existing composition text on TAP gesture, to make sure the input |
2236 // caret won't be moved with an ongoing composition text. | 2230 // caret won't be moved with an ongoing composition text. |
2237 if (event->type() == ui::ET_GESTURE_TAP) | 2231 if (event->type() == ui::ET_GESTURE_TAP) |
2238 FinishImeCompositionSession(); | 2232 FinishImeCompositionSession(); |
2239 | 2233 |
2240 blink::WebGestureEvent gesture = MakeWebGestureEvent(*event); | 2234 blink::WebGestureEvent gesture = MakeWebGestureEvent(*event); |
2241 if (event->type() == ui::ET_GESTURE_TAP_DOWN) { | 2235 if (event->type() == ui::ET_GESTURE_TAP_DOWN) { |
2242 // Webkit does not stop a fling-scroll on tap-down. So explicitly send an | 2236 // Webkit does not stop a fling-scroll on tap-down. So explicitly send an |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2315 BrowserAccessibilityManager* manager = | 2309 BrowserAccessibilityManager* manager = |
2316 host_->GetRootBrowserAccessibilityManager(); | 2310 host_->GetRootBrowserAccessibilityManager(); |
2317 if (manager) | 2311 if (manager) |
2318 manager->OnWindowFocused(); | 2312 manager->OnWindowFocused(); |
2319 } else if (window_ == lost_focus) { | 2313 } else if (window_ == lost_focus) { |
2320 host_->SetActive(false); | 2314 host_->SetActive(false); |
2321 host_->Blur(); | 2315 host_->Blur(); |
2322 | 2316 |
2323 DetachFromInputMethod(); | 2317 DetachFromInputMethod(); |
2324 | 2318 |
2325 selection_controller_->HideAndDisallowShowingAutomatically(); | 2319 if (touch_editing_client_) |
| 2320 touch_editing_client_->EndTouchEditing(false); |
2326 | 2321 |
2327 if (overscroll_controller_) | 2322 if (overscroll_controller_) |
2328 overscroll_controller_->Cancel(); | 2323 overscroll_controller_->Cancel(); |
2329 | 2324 |
2330 BrowserAccessibilityManager* manager = | 2325 BrowserAccessibilityManager* manager = |
2331 host_->GetRootBrowserAccessibilityManager(); | 2326 host_->GetRootBrowserAccessibilityManager(); |
2332 if (manager) | 2327 if (manager) |
2333 manager->OnWindowBlurred(); | 2328 manager->OnWindowBlurred(); |
2334 | 2329 |
2335 // If we lose the focus while fullscreen, close the window; Pepper Flash | 2330 // If we lose the focus while fullscreen, close the window; Pepper Flash |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2372 TRACE_EVENT1("ui", "RenderWidgetHostViewAura::OnHostMoved", | 2367 TRACE_EVENT1("ui", "RenderWidgetHostViewAura::OnHostMoved", |
2373 "new_origin", new_origin.ToString()); | 2368 "new_origin", new_origin.ToString()); |
2374 | 2369 |
2375 UpdateScreenInfo(window_); | 2370 UpdateScreenInfo(window_); |
2376 } | 2371 } |
2377 | 2372 |
2378 //////////////////////////////////////////////////////////////////////////////// | 2373 //////////////////////////////////////////////////////////////////////////////// |
2379 // RenderWidgetHostViewAura, private: | 2374 // RenderWidgetHostViewAura, private: |
2380 | 2375 |
2381 RenderWidgetHostViewAura::~RenderWidgetHostViewAura() { | 2376 RenderWidgetHostViewAura::~RenderWidgetHostViewAura() { |
2382 selection_controller_.reset(); | 2377 if (touch_editing_client_) |
2383 selection_controller_client_.reset(); | 2378 touch_editing_client_->OnViewDestroyed(); |
| 2379 |
2384 delegated_frame_host_.reset(); | 2380 delegated_frame_host_.reset(); |
2385 window_observer_.reset(); | 2381 window_observer_.reset(); |
2386 if (window_->GetHost()) | 2382 if (window_->GetHost()) |
2387 window_->GetHost()->RemoveObserver(this); | 2383 window_->GetHost()->RemoveObserver(this); |
2388 UnlockMouse(); | 2384 UnlockMouse(); |
2389 if (popup_parent_host_view_) { | 2385 if (popup_parent_host_view_) { |
2390 DCHECK(popup_parent_host_view_->popup_child_host_view_ == NULL || | 2386 DCHECK(popup_parent_host_view_->popup_child_host_view_ == NULL || |
2391 popup_parent_host_view_->popup_child_host_view_ == this); | 2387 popup_parent_host_view_->popup_child_host_view_ == this); |
2392 popup_parent_host_view_->popup_child_host_view_ = NULL; | 2388 popup_parent_host_view_->popup_child_host_view_ = NULL; |
2393 } | 2389 } |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2550 | 2546 |
2551 has_snapped_to_boundary_ = true; | 2547 has_snapped_to_boundary_ = true; |
2552 } | 2548 } |
2553 | 2549 |
2554 void RenderWidgetHostViewAura::OnShowContextMenu() { | 2550 void RenderWidgetHostViewAura::OnShowContextMenu() { |
2555 #if defined(OS_WIN) | 2551 #if defined(OS_WIN) |
2556 showing_context_menu_ = true; | 2552 showing_context_menu_ = true; |
2557 #endif | 2553 #endif |
2558 } | 2554 } |
2559 | 2555 |
2560 void RenderWidgetHostViewAura::SetSelectionControllerClientForTest( | |
2561 scoped_ptr<TouchSelectionControllerClientAura> client) { | |
2562 selection_controller_client_.swap(client); | |
2563 CreateSelectionController(); | |
2564 } | |
2565 | |
2566 void RenderWidgetHostViewAura::InternalSetBounds(const gfx::Rect& rect) { | 2556 void RenderWidgetHostViewAura::InternalSetBounds(const gfx::Rect& rect) { |
2567 SnapToPhysicalPixelBoundary(); | 2557 SnapToPhysicalPixelBoundary(); |
2568 // Don't recursively call SetBounds if this bounds update is the result of | 2558 // Don't recursively call SetBounds if this bounds update is the result of |
2569 // a Window::SetBoundsInternal call. | 2559 // a Window::SetBoundsInternal call. |
2570 if (!in_bounds_changed_) | 2560 if (!in_bounds_changed_) |
2571 window_->SetBounds(rect); | 2561 window_->SetBounds(rect); |
2572 host_->WasResized(); | 2562 host_->WasResized(); |
2573 delegated_frame_host_->WasResized(); | 2563 delegated_frame_host_->WasResized(); |
| 2564 if (touch_editing_client_) { |
| 2565 touch_editing_client_->OnSelectionOrCursorChanged(selection_anchor_, |
| 2566 selection_focus_); |
| 2567 } |
2574 #if defined(OS_WIN) | 2568 #if defined(OS_WIN) |
2575 // Create the legacy dummy window which corresponds to the bounds of the | 2569 // Create the legacy dummy window which corresponds to the bounds of the |
2576 // webcontents. This will be passed as the container window for windowless | 2570 // webcontents. This will be passed as the container window for windowless |
2577 // plugins. | 2571 // plugins. |
2578 // Plugins like Flash assume the container window which is returned via the | 2572 // Plugins like Flash assume the container window which is returned via the |
2579 // NPNVnetscapeWindow property corresponds to the bounds of the webpage. | 2573 // NPNVnetscapeWindow property corresponds to the bounds of the webpage. |
2580 // This is not true in Aura where we have only HWND which is the main Aura | 2574 // This is not true in Aura where we have only HWND which is the main Aura |
2581 // window. If we return this window to plugins like Flash then it causes the | 2575 // window. If we return this window to plugins like Flash then it causes the |
2582 // coordinate translations done by these plugins to break. | 2576 // coordinate translations done by these plugins to break. |
2583 // Additonally the legacy dummy window is needed for accessibility and for | 2577 // Additonally the legacy dummy window is needed for accessibility and for |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2706 NativeWebKeyboardEvent copy_event(event); | 2700 NativeWebKeyboardEvent copy_event(event); |
2707 copy_event.match_edit_command = true; | 2701 copy_event.match_edit_command = true; |
2708 host_->ForwardKeyboardEvent(copy_event); | 2702 host_->ForwardKeyboardEvent(copy_event); |
2709 return; | 2703 return; |
2710 } | 2704 } |
2711 #endif | 2705 #endif |
2712 | 2706 |
2713 host_->ForwardKeyboardEvent(event); | 2707 host_->ForwardKeyboardEvent(event); |
2714 } | 2708 } |
2715 | 2709 |
2716 void RenderWidgetHostViewAura::SelectionUpdated(bool is_editable, | |
2717 bool is_empty_text_form_control, | |
2718 const ui::SelectionBound& start, | |
2719 const ui::SelectionBound& end) { | |
2720 selection_controller_->OnSelectionEditable(is_editable); | |
2721 selection_controller_->OnSelectionEmpty(is_empty_text_form_control); | |
2722 selection_controller_->OnSelectionBoundsChanged(start, end); | |
2723 } | |
2724 | |
2725 void RenderWidgetHostViewAura::CreateSelectionController() { | |
2726 ui::TouchSelectionController::Config tsc_config; | |
2727 tsc_config.tap_timeout = base::TimeDelta::FromMilliseconds( | |
2728 ui::GestureConfiguration::GetInstance()->show_press_delay_in_ms()); | |
2729 tsc_config.tap_slop = ui::GestureConfiguration::GetInstance() | |
2730 ->max_touch_move_in_pixels_for_click(); | |
2731 tsc_config.show_on_tap_for_empty_editable = true; | |
2732 tsc_config.enable_longpress_drag_selection = false; | |
2733 selection_controller_.reset(new ui::TouchSelectionController( | |
2734 selection_controller_client_.get(), tsc_config)); | |
2735 } | |
2736 | |
2737 void RenderWidgetHostViewAura::HandleGestureForTouchSelection( | |
2738 ui::GestureEvent* event) { | |
2739 switch (event->type()) { | |
2740 case ui::ET_GESTURE_LONG_PRESS: | |
2741 if (selection_controller_->WillHandleLongPressEvent( | |
2742 base::TimeTicks() + event->time_stamp(), event->location_f())) { | |
2743 event->SetHandled(); | |
2744 } | |
2745 break; | |
2746 case ui::ET_GESTURE_TAP: | |
2747 if (selection_controller_->WillHandleTapEvent(event->location_f())) | |
2748 event->SetHandled(); | |
2749 break; | |
2750 case ui::ET_GESTURE_SCROLL_BEGIN: | |
2751 selection_controller_client_->OnScrollStarted(); | |
2752 break; | |
2753 case ui::ET_GESTURE_SCROLL_END: | |
2754 selection_controller_client_->OnScrollCompleted(); | |
2755 break; | |
2756 default: | |
2757 break; | |
2758 } | |
2759 } | |
2760 | |
2761 //////////////////////////////////////////////////////////////////////////////// | 2710 //////////////////////////////////////////////////////////////////////////////// |
2762 // DelegatedFrameHost, public: | 2711 // DelegatedFrameHost, public: |
2763 | 2712 |
2764 ui::Layer* RenderWidgetHostViewAura::DelegatedFrameHostGetLayer() const { | 2713 ui::Layer* RenderWidgetHostViewAura::DelegatedFrameHostGetLayer() const { |
2765 return window_->layer(); | 2714 return window_->layer(); |
2766 } | 2715 } |
2767 | 2716 |
2768 bool RenderWidgetHostViewAura::DelegatedFrameHostIsVisible() const { | 2717 bool RenderWidgetHostViewAura::DelegatedFrameHostIsVisible() const { |
2769 return !host_->is_hidden(); | 2718 return !host_->is_hidden(); |
2770 } | 2719 } |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2837 | 2786 |
2838 //////////////////////////////////////////////////////////////////////////////// | 2787 //////////////////////////////////////////////////////////////////////////////// |
2839 // RenderWidgetHostViewBase, public: | 2788 // RenderWidgetHostViewBase, public: |
2840 | 2789 |
2841 // static | 2790 // static |
2842 void RenderWidgetHostViewBase::GetDefaultScreenInfo(WebScreenInfo* results) { | 2791 void RenderWidgetHostViewBase::GetDefaultScreenInfo(WebScreenInfo* results) { |
2843 GetScreenInfoForWindow(results, NULL); | 2792 GetScreenInfoForWindow(results, NULL); |
2844 } | 2793 } |
2845 | 2794 |
2846 } // namespace content | 2795 } // namespace content |
OLD | NEW |