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_impl.h" | 5 #include "content/browser/renderer_host/render_widget_host_impl.h" |
6 | 6 |
7 #include <math.h> | 7 #include <math.h> |
8 #include <set> | 8 #include <set> |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
66 #include "content/browser/renderer_host/backing_store_gtk.h" | 66 #include "content/browser/renderer_host/backing_store_gtk.h" |
67 #elif defined(OS_MACOSX) | 67 #elif defined(OS_MACOSX) |
68 #include "content/browser/renderer_host/backing_store_mac.h" | 68 #include "content/browser/renderer_host/backing_store_mac.h" |
69 #elif defined(OS_WIN) | 69 #elif defined(OS_WIN) |
70 #include "content/common/plugin_constants_win.h" | 70 #include "content/common/plugin_constants_win.h" |
71 #endif | 71 #endif |
72 | 72 |
73 using base::Time; | 73 using base::Time; |
74 using base::TimeDelta; | 74 using base::TimeDelta; |
75 using base::TimeTicks; | 75 using base::TimeTicks; |
76 using WebKit::WebGestureEvent; | 76 using blink::WebGestureEvent; |
77 using WebKit::WebInputEvent; | 77 using blink::WebInputEvent; |
78 using WebKit::WebKeyboardEvent; | 78 using blink::WebKeyboardEvent; |
79 using WebKit::WebMouseEvent; | 79 using blink::WebMouseEvent; |
80 using WebKit::WebMouseWheelEvent; | 80 using blink::WebMouseWheelEvent; |
81 using WebKit::WebTextDirection; | 81 using blink::WebTextDirection; |
82 | 82 |
83 namespace content { | 83 namespace content { |
84 namespace { | 84 namespace { |
85 | 85 |
86 bool g_check_for_pending_resize_ack = true; | 86 bool g_check_for_pending_resize_ack = true; |
87 | 87 |
88 // How long to (synchronously) wait for the renderer to respond with a | 88 // How long to (synchronously) wait for the renderer to respond with a |
89 // PaintRect message, when our backing-store is invalid, before giving up and | 89 // PaintRect message, when our backing-store is invalid, before giving up and |
90 // returning a null or incorrectly sized backing-store from GetBackingStore. | 90 // returning a null or incorrectly sized backing-store from GetBackingStore. |
91 // This timeout impacts the "choppiness" of our window resize perf. | 91 // This timeout impacts the "choppiness" of our window resize perf. |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
175 accessibility_mode_(AccessibilityModeOff), | 175 accessibility_mode_(AccessibilityModeOff), |
176 needs_repainting_on_restore_(false), | 176 needs_repainting_on_restore_(false), |
177 is_unresponsive_(false), | 177 is_unresponsive_(false), |
178 in_flight_event_count_(0), | 178 in_flight_event_count_(0), |
179 in_get_backing_store_(false), | 179 in_get_backing_store_(false), |
180 abort_get_backing_store_(false), | 180 abort_get_backing_store_(false), |
181 view_being_painted_(false), | 181 view_being_painted_(false), |
182 ignore_input_events_(false), | 182 ignore_input_events_(false), |
183 input_method_active_(false), | 183 input_method_active_(false), |
184 text_direction_updated_(false), | 184 text_direction_updated_(false), |
185 text_direction_(WebKit::WebTextDirectionLeftToRight), | 185 text_direction_(blink::WebTextDirectionLeftToRight), |
186 text_direction_canceled_(false), | 186 text_direction_canceled_(false), |
187 suppress_next_char_events_(false), | 187 suppress_next_char_events_(false), |
188 pending_mouse_lock_request_(false), | 188 pending_mouse_lock_request_(false), |
189 allow_privileged_mouse_lock_(false), | 189 allow_privileged_mouse_lock_(false), |
190 has_touch_handler_(false), | 190 has_touch_handler_(false), |
191 weak_factory_(this), | 191 weak_factory_(this), |
192 last_input_number_(0) { | 192 last_input_number_(0) { |
193 CHECK(delegate_); | 193 CHECK(delegate_); |
194 if (routing_id_ == MSG_ROUTING_NONE) { | 194 if (routing_id_ == MSG_ROUTING_NONE) { |
195 routing_id_ = process_->GetNextRoutingID(); | 195 routing_id_ = process_->GetNextRoutingID(); |
(...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
624 bool side_payload_changed = | 624 bool side_payload_changed = |
625 screen_info_out_of_date_ || | 625 screen_info_out_of_date_ || |
626 old_physical_backing_size != physical_backing_size_ || | 626 old_physical_backing_size != physical_backing_size_ || |
627 was_fullscreen != is_fullscreen_ || | 627 was_fullscreen != is_fullscreen_ || |
628 old_overdraw_bottom_height != overdraw_bottom_height_; | 628 old_overdraw_bottom_height != overdraw_bottom_height_; |
629 | 629 |
630 if (!size_changed && !side_payload_changed) | 630 if (!size_changed && !side_payload_changed) |
631 return; | 631 return; |
632 | 632 |
633 if (!screen_info_) { | 633 if (!screen_info_) { |
634 screen_info_.reset(new WebKit::WebScreenInfo); | 634 screen_info_.reset(new blink::WebScreenInfo); |
635 GetWebScreenInfo(screen_info_.get()); | 635 GetWebScreenInfo(screen_info_.get()); |
636 } | 636 } |
637 | 637 |
638 // We don't expect to receive an ACK when the requested size or the physical | 638 // We don't expect to receive an ACK when the requested size or the physical |
639 // backing size is empty, or when the main viewport size didn't change. | 639 // backing size is empty, or when the main viewport size didn't change. |
640 if (!new_size.IsEmpty() && !physical_backing_size_.IsEmpty() && size_changed) | 640 if (!new_size.IsEmpty() && !physical_backing_size_.IsEmpty() && size_changed) |
641 resize_ack_pending_ = g_check_for_pending_resize_ack; | 641 resize_ack_pending_ = g_check_for_pending_resize_ack; |
642 | 642 |
643 ViewMsg_Resize_Params params; | 643 ViewMsg_Resize_Params params; |
644 params.screen_info = *screen_info_; | 644 params.screen_info = *screen_info_; |
(...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1002 if (IgnoreInputEvents()) | 1002 if (IgnoreInputEvents()) |
1003 return; | 1003 return; |
1004 | 1004 |
1005 if (delegate_->PreHandleWheelEvent(wheel_event.event)) | 1005 if (delegate_->PreHandleWheelEvent(wheel_event.event)) |
1006 return; | 1006 return; |
1007 | 1007 |
1008 input_router_->SendWheelEvent(wheel_event); | 1008 input_router_->SendWheelEvent(wheel_event); |
1009 } | 1009 } |
1010 | 1010 |
1011 void RenderWidgetHostImpl::ForwardGestureEvent( | 1011 void RenderWidgetHostImpl::ForwardGestureEvent( |
1012 const WebKit::WebGestureEvent& gesture_event) { | 1012 const blink::WebGestureEvent& gesture_event) { |
1013 ForwardGestureEventWithLatencyInfo(gesture_event, ui::LatencyInfo()); | 1013 ForwardGestureEventWithLatencyInfo(gesture_event, ui::LatencyInfo()); |
1014 } | 1014 } |
1015 | 1015 |
1016 void RenderWidgetHostImpl::ForwardGestureEventWithLatencyInfo( | 1016 void RenderWidgetHostImpl::ForwardGestureEventWithLatencyInfo( |
1017 const WebKit::WebGestureEvent& gesture_event, | 1017 const blink::WebGestureEvent& gesture_event, |
1018 const ui::LatencyInfo& ui_latency) { | 1018 const ui::LatencyInfo& ui_latency) { |
1019 TRACE_EVENT0("input", "RenderWidgetHostImpl::ForwardGestureEvent"); | 1019 TRACE_EVENT0("input", "RenderWidgetHostImpl::ForwardGestureEvent"); |
1020 // Early out if necessary, prior to performing latency logic. | 1020 // Early out if necessary, prior to performing latency logic. |
1021 if (IgnoreInputEvents()) | 1021 if (IgnoreInputEvents()) |
1022 return; | 1022 return; |
1023 | 1023 |
1024 ui::LatencyInfo latency_info = CreateRWHLatencyInfoIfNotExist(&ui_latency); | 1024 ui::LatencyInfo latency_info = CreateRWHLatencyInfoIfNotExist(&ui_latency); |
1025 | 1025 |
1026 if (gesture_event.type == WebKit::WebInputEvent::GestureScrollUpdate) { | 1026 if (gesture_event.type == blink::WebInputEvent::GestureScrollUpdate) { |
1027 latency_info.AddLatencyNumber( | 1027 latency_info.AddLatencyNumber( |
1028 ui::INPUT_EVENT_LATENCY_SCROLL_UPDATE_RWH_COMPONENT, | 1028 ui::INPUT_EVENT_LATENCY_SCROLL_UPDATE_RWH_COMPONENT, |
1029 GetLatencyComponentId(), | 1029 GetLatencyComponentId(), |
1030 ++last_input_number_); | 1030 ++last_input_number_); |
1031 | 1031 |
1032 // Make a copy of the INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT with a | 1032 // Make a copy of the INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT with a |
1033 // different name INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT. | 1033 // different name INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT. |
1034 // So we can track the latency specifically for scroll update events. | 1034 // So we can track the latency specifically for scroll update events. |
1035 ui::LatencyInfo::LatencyComponent original_component; | 1035 ui::LatencyInfo::LatencyComponent original_component; |
1036 if (latency_info.FindLatency(ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, | 1036 if (latency_info.FindLatency(ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, |
1037 0, | 1037 0, |
1038 &original_component)) { | 1038 &original_component)) { |
1039 latency_info.AddLatencyNumberWithTimestamp( | 1039 latency_info.AddLatencyNumberWithTimestamp( |
1040 ui::INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT, | 1040 ui::INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT, |
1041 GetLatencyComponentId(), | 1041 GetLatencyComponentId(), |
1042 original_component.sequence_number, | 1042 original_component.sequence_number, |
1043 original_component.event_time, | 1043 original_component.event_time, |
1044 original_component.event_count, | 1044 original_component.event_count, |
1045 true); | 1045 true); |
1046 } | 1046 } |
1047 } | 1047 } |
1048 | 1048 |
1049 GestureEventWithLatencyInfo gesture_with_latency(gesture_event, latency_info); | 1049 GestureEventWithLatencyInfo gesture_with_latency(gesture_event, latency_info); |
1050 input_router_->SendGestureEvent(gesture_with_latency); | 1050 input_router_->SendGestureEvent(gesture_with_latency); |
1051 } | 1051 } |
1052 | 1052 |
1053 void RenderWidgetHostImpl::ForwardTouchEventWithLatencyInfo( | 1053 void RenderWidgetHostImpl::ForwardTouchEventWithLatencyInfo( |
1054 const WebKit::WebTouchEvent& touch_event, | 1054 const blink::WebTouchEvent& touch_event, |
1055 const ui::LatencyInfo& ui_latency) { | 1055 const ui::LatencyInfo& ui_latency) { |
1056 TRACE_EVENT0("input", "RenderWidgetHostImpl::ForwardTouchEvent"); | 1056 TRACE_EVENT0("input", "RenderWidgetHostImpl::ForwardTouchEvent"); |
1057 | 1057 |
1058 // Always forward TouchEvents for touch stream consistency. They will be | 1058 // Always forward TouchEvents for touch stream consistency. They will be |
1059 // ignored if appropriate in FilterInputEvent(). | 1059 // ignored if appropriate in FilterInputEvent(). |
1060 | 1060 |
1061 ui::LatencyInfo latency_info = CreateRWHLatencyInfoIfNotExist(&ui_latency); | 1061 ui::LatencyInfo latency_info = CreateRWHLatencyInfoIfNotExist(&ui_latency); |
1062 TouchEventWithLatencyInfo touch_with_latency(touch_event, latency_info); | 1062 TouchEventWithLatencyInfo touch_with_latency(touch_event, latency_info); |
1063 input_router_->SendTouchEvent(touch_with_latency); | 1063 input_router_->SendTouchEvent(touch_with_latency); |
1064 } | 1064 } |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1184 void RenderWidgetHostImpl::RemoveMouseEventCallback( | 1184 void RenderWidgetHostImpl::RemoveMouseEventCallback( |
1185 const MouseEventCallback& callback) { | 1185 const MouseEventCallback& callback) { |
1186 for (size_t i = 0; i < mouse_event_callbacks_.size(); ++i) { | 1186 for (size_t i = 0; i < mouse_event_callbacks_.size(); ++i) { |
1187 if (mouse_event_callbacks_[i].Equals(callback)) { | 1187 if (mouse_event_callbacks_[i].Equals(callback)) { |
1188 mouse_event_callbacks_.erase(mouse_event_callbacks_.begin() + i); | 1188 mouse_event_callbacks_.erase(mouse_event_callbacks_.begin() + i); |
1189 return; | 1189 return; |
1190 } | 1190 } |
1191 } | 1191 } |
1192 } | 1192 } |
1193 | 1193 |
1194 void RenderWidgetHostImpl::GetWebScreenInfo(WebKit::WebScreenInfo* result) { | 1194 void RenderWidgetHostImpl::GetWebScreenInfo(blink::WebScreenInfo* result) { |
1195 TRACE_EVENT0("renderer_host", "RenderWidgetHostImpl::GetWebScreenInfo"); | 1195 TRACE_EVENT0("renderer_host", "RenderWidgetHostImpl::GetWebScreenInfo"); |
1196 if (GetView()) | 1196 if (GetView()) |
1197 static_cast<RenderWidgetHostViewPort*>(GetView())->GetScreenInfo(result); | 1197 static_cast<RenderWidgetHostViewPort*>(GetView())->GetScreenInfo(result); |
1198 else | 1198 else |
1199 RenderWidgetHostViewPort::GetDefaultScreenInfo(result); | 1199 RenderWidgetHostViewPort::GetDefaultScreenInfo(result); |
1200 screen_info_out_of_date_ = false; | 1200 screen_info_out_of_date_ = false; |
1201 } | 1201 } |
1202 | 1202 |
1203 const NativeWebKeyboardEvent* | 1203 const NativeWebKeyboardEvent* |
1204 RenderWidgetHostImpl::GetLastKeyboardEvent() const { | 1204 RenderWidgetHostImpl::GetLastKeyboardEvent() const { |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1317 } | 1317 } |
1318 } | 1318 } |
1319 | 1319 |
1320 void RenderWidgetHostImpl::SetInputMethodActive(bool activate) { | 1320 void RenderWidgetHostImpl::SetInputMethodActive(bool activate) { |
1321 input_method_active_ = activate; | 1321 input_method_active_ = activate; |
1322 Send(new ViewMsg_SetInputMethodActive(GetRoutingID(), activate)); | 1322 Send(new ViewMsg_SetInputMethodActive(GetRoutingID(), activate)); |
1323 } | 1323 } |
1324 | 1324 |
1325 void RenderWidgetHostImpl::ImeSetComposition( | 1325 void RenderWidgetHostImpl::ImeSetComposition( |
1326 const string16& text, | 1326 const string16& text, |
1327 const std::vector<WebKit::WebCompositionUnderline>& underlines, | 1327 const std::vector<blink::WebCompositionUnderline>& underlines, |
1328 int selection_start, | 1328 int selection_start, |
1329 int selection_end) { | 1329 int selection_end) { |
1330 Send(new ViewMsg_ImeSetComposition( | 1330 Send(new ViewMsg_ImeSetComposition( |
1331 GetRoutingID(), text, underlines, selection_start, selection_end)); | 1331 GetRoutingID(), text, underlines, selection_start, selection_end)); |
1332 } | 1332 } |
1333 | 1333 |
1334 void RenderWidgetHostImpl::ImeConfirmComposition( | 1334 void RenderWidgetHostImpl::ImeConfirmComposition( |
1335 const string16& text, | 1335 const string16& text, |
1336 const gfx::Range& replacement_range, | 1336 const gfx::Range& replacement_range, |
1337 bool keep_selection) { | 1337 bool keep_selection) { |
1338 Send(new ViewMsg_ImeConfirmComposition( | 1338 Send(new ViewMsg_ImeConfirmComposition( |
1339 GetRoutingID(), text, replacement_range, keep_selection)); | 1339 GetRoutingID(), text, replacement_range, keep_selection)); |
1340 } | 1340 } |
1341 | 1341 |
1342 void RenderWidgetHostImpl::ImeCancelComposition() { | 1342 void RenderWidgetHostImpl::ImeCancelComposition() { |
1343 Send(new ViewMsg_ImeSetComposition(GetRoutingID(), string16(), | 1343 Send(new ViewMsg_ImeSetComposition(GetRoutingID(), string16(), |
1344 std::vector<WebKit::WebCompositionUnderline>(), 0, 0)); | 1344 std::vector<blink::WebCompositionUnderline>(), 0, 0)); |
1345 } | 1345 } |
1346 | 1346 |
1347 void RenderWidgetHostImpl::ExtendSelectionAndDelete( | 1347 void RenderWidgetHostImpl::ExtendSelectionAndDelete( |
1348 size_t before, | 1348 size_t before, |
1349 size_t after) { | 1349 size_t after) { |
1350 Send(new ViewMsg_ExtendSelectionAndDelete(GetRoutingID(), before, after)); | 1350 Send(new ViewMsg_ExtendSelectionAndDelete(GetRoutingID(), before, after)); |
1351 } | 1351 } |
1352 | 1352 |
1353 gfx::Rect RenderWidgetHostImpl::GetRootWindowResizerRect() const { | 1353 gfx::Rect RenderWidgetHostImpl::GetRootWindowResizerRect() const { |
1354 return gfx::Rect(); | 1354 return gfx::Rect(); |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1454 // To get around this we only wrap the string when we deem it necessary i.e. | 1454 // To get around this we only wrap the string when we deem it necessary i.e. |
1455 // when the locale direction is different than the tooltip direction hint. | 1455 // when the locale direction is different than the tooltip direction hint. |
1456 // | 1456 // |
1457 // Currently, we use element's directionality as the tooltip direction hint. | 1457 // Currently, we use element's directionality as the tooltip direction hint. |
1458 // An alternate solution would be to set the overall directionality based on | 1458 // An alternate solution would be to set the overall directionality based on |
1459 // trying to detect the directionality from the tooltip text rather than the | 1459 // trying to detect the directionality from the tooltip text rather than the |
1460 // element direction. One could argue that would be a preferable solution | 1460 // element direction. One could argue that would be a preferable solution |
1461 // but we use the current approach to match Fx & IE's behavior. | 1461 // but we use the current approach to match Fx & IE's behavior. |
1462 string16 wrapped_tooltip_text = tooltip_text; | 1462 string16 wrapped_tooltip_text = tooltip_text; |
1463 if (!tooltip_text.empty()) { | 1463 if (!tooltip_text.empty()) { |
1464 if (text_direction_hint == WebKit::WebTextDirectionLeftToRight) { | 1464 if (text_direction_hint == blink::WebTextDirectionLeftToRight) { |
1465 // Force the tooltip to have LTR directionality. | 1465 // Force the tooltip to have LTR directionality. |
1466 wrapped_tooltip_text = | 1466 wrapped_tooltip_text = |
1467 base::i18n::GetDisplayStringInLTRDirectionality(wrapped_tooltip_text); | 1467 base::i18n::GetDisplayStringInLTRDirectionality(wrapped_tooltip_text); |
1468 } else if (text_direction_hint == WebKit::WebTextDirectionRightToLeft && | 1468 } else if (text_direction_hint == blink::WebTextDirectionRightToLeft && |
1469 !base::i18n::IsRTL()) { | 1469 !base::i18n::IsRTL()) { |
1470 // Force the tooltip to have RTL directionality. | 1470 // Force the tooltip to have RTL directionality. |
1471 base::i18n::WrapStringWithRTLFormatting(&wrapped_tooltip_text); | 1471 base::i18n::WrapStringWithRTLFormatting(&wrapped_tooltip_text); |
1472 } | 1472 } |
1473 } | 1473 } |
1474 if (GetView()) | 1474 if (GetView()) |
1475 view_->SetTooltipText(wrapped_tooltip_text); | 1475 view_->SetTooltipText(wrapped_tooltip_text); |
1476 } | 1476 } |
1477 | 1477 |
1478 void RenderWidgetHostImpl::OnUpdateScreenRectsAck() { | 1478 void RenderWidgetHostImpl::OnUpdateScreenRectsAck() { |
(...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1964 if (current_size != original_size) { | 1964 if (current_size != original_size) { |
1965 DCHECK_EQ(original_size - 1, current_size); | 1965 DCHECK_EQ(original_size - 1, current_size); |
1966 --i; | 1966 --i; |
1967 } | 1967 } |
1968 } | 1968 } |
1969 | 1969 |
1970 return false; | 1970 return false; |
1971 } | 1971 } |
1972 | 1972 |
1973 InputEventAckState RenderWidgetHostImpl::FilterInputEvent( | 1973 InputEventAckState RenderWidgetHostImpl::FilterInputEvent( |
1974 const WebKit::WebInputEvent& event, const ui::LatencyInfo& latency_info) { | 1974 const blink::WebInputEvent& event, const ui::LatencyInfo& latency_info) { |
1975 // Don't ignore touch cancel events, since they may be sent while input | 1975 // Don't ignore touch cancel events, since they may be sent while input |
1976 // events are being ignored in order to keep the renderer from getting | 1976 // events are being ignored in order to keep the renderer from getting |
1977 // confused about how many touches are active. | 1977 // confused about how many touches are active. |
1978 if (IgnoreInputEvents() && event.type != WebInputEvent::TouchCancel) | 1978 if (IgnoreInputEvents() && event.type != WebInputEvent::TouchCancel) |
1979 return INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS; | 1979 return INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS; |
1980 | 1980 |
1981 if (!process_->HasConnection()) | 1981 if (!process_->HasConnection()) |
1982 return INPUT_EVENT_ACK_STATE_UNKNOWN; | 1982 return INPUT_EVENT_ACK_STATE_UNKNOWN; |
1983 | 1983 |
1984 if (event.type == WebInputEvent::MouseDown) | 1984 if (event.type == WebInputEvent::MouseDown) |
(...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2498 continue; | 2498 continue; |
2499 } | 2499 } |
2500 RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(rwh); | 2500 RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(rwh); |
2501 if (rwhi_set.insert(rwhi).second) | 2501 if (rwhi_set.insert(rwhi).second) |
2502 rwhi->FrameSwapped(latency_info); | 2502 rwhi->FrameSwapped(latency_info); |
2503 } | 2503 } |
2504 } | 2504 } |
2505 } | 2505 } |
2506 | 2506 |
2507 } // namespace content | 2507 } // namespace content |
OLD | NEW |