Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(825)

Side by Side Diff: content/browser/web_contents/web_contents_view_aura.cc

Issue 698253004: Reland: Implement Aura side of unified touch text selection for contents (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/web_contents/web_contents_view_aura.h" 5 #include "content/browser/web_contents/web_contents_view_aura.h"
6 6
7 #include "base/auto_reset.h" 7 #include "base/auto_reset.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/files/file_util.h" 9 #include "base/files/file_util.h"
10 #include "base/metrics/histogram.h" 10 #include "base/metrics/histogram.h"
11 #include "base/strings/utf_string_conversions.h" 11 #include "base/strings/utf_string_conversions.h"
12 #include "content/browser/browser_plugin/browser_plugin_guest.h" 12 #include "content/browser/browser_plugin/browser_plugin_guest.h"
13 #include "content/browser/download/drag_download_util.h" 13 #include "content/browser/download/drag_download_util.h"
14 #include "content/browser/frame_host/interstitial_page_impl.h" 14 #include "content/browser/frame_host/interstitial_page_impl.h"
15 #include "content/browser/frame_host/navigation_entry_impl.h" 15 #include "content/browser/frame_host/navigation_entry_impl.h"
16 #include "content/browser/renderer_host/dip_util.h" 16 #include "content/browser/renderer_host/dip_util.h"
17 #include "content/browser/renderer_host/overscroll_controller.h" 17 #include "content/browser/renderer_host/overscroll_controller.h"
18 #include "content/browser/renderer_host/render_view_host_factory.h" 18 #include "content/browser/renderer_host/render_view_host_factory.h"
19 #include "content/browser/renderer_host/render_view_host_impl.h" 19 #include "content/browser/renderer_host/render_view_host_impl.h"
20 #include "content/browser/renderer_host/render_widget_host_impl.h" 20 #include "content/browser/renderer_host/render_widget_host_impl.h"
21 #include "content/browser/renderer_host/render_widget_host_view_aura.h" 21 #include "content/browser/renderer_host/render_widget_host_view_aura.h"
22 #include "content/browser/renderer_host/web_input_event_aura.h" 22 #include "content/browser/renderer_host/web_input_event_aura.h"
23 #include "content/browser/web_contents/aura/gesture_nav_simple.h" 23 #include "content/browser/web_contents/aura/gesture_nav_simple.h"
24 #include "content/browser/web_contents/aura/image_window_delegate.h" 24 #include "content/browser/web_contents/aura/image_window_delegate.h"
25 #include "content/browser/web_contents/aura/overscroll_navigation_overlay.h" 25 #include "content/browser/web_contents/aura/overscroll_navigation_overlay.h"
26 #include "content/browser/web_contents/aura/shadow_layer_delegate.h" 26 #include "content/browser/web_contents/aura/shadow_layer_delegate.h"
27 #include "content/browser/web_contents/aura/window_slider.h" 27 #include "content/browser/web_contents/aura/window_slider.h"
28 #include "content/browser/web_contents/touch_editable_impl_aura.h"
29 #include "content/browser/web_contents/web_contents_impl.h" 28 #include "content/browser/web_contents/web_contents_impl.h"
30 #include "content/public/browser/content_browser_client.h" 29 #include "content/public/browser/content_browser_client.h"
31 #include "content/public/browser/notification_observer.h" 30 #include "content/public/browser/notification_observer.h"
32 #include "content/public/browser/notification_registrar.h" 31 #include "content/public/browser/notification_registrar.h"
33 #include "content/public/browser/notification_source.h" 32 #include "content/public/browser/notification_source.h"
34 #include "content/public/browser/notification_types.h" 33 #include "content/public/browser/notification_types.h"
35 #include "content/public/browser/overscroll_configuration.h" 34 #include "content/public/browser/overscroll_configuration.h"
36 #include "content/public/browser/render_view_host.h" 35 #include "content/public/browser/render_view_host.h"
37 #include "content/public/browser/render_widget_host.h" 36 #include "content/public/browser/render_widget_host.h"
38 #include "content/public/browser/render_widget_host_view.h" 37 #include "content/public/browser/render_widget_host_view.h"
(...skipping 580 matching lines...) Expand 10 before | Expand all | Expand 10 after
619 } 618 }
620 #endif 619 #endif
621 } 620 }
622 } 621 }
623 622
624 void OnWindowBoundsChanged(aura::Window* window, 623 void OnWindowBoundsChanged(aura::Window* window,
625 const gfx::Rect& old_bounds, 624 const gfx::Rect& old_bounds,
626 const gfx::Rect& new_bounds) override { 625 const gfx::Rect& new_bounds) override {
627 if (window == host_window_ || window == view_->window_) { 626 if (window == host_window_ || window == view_->window_) {
628 SendScreenRects(); 627 SendScreenRects();
629 if (view_->touch_editable_) 628 if (old_bounds.origin() != new_bounds.origin()) {
630 view_->touch_editable_->UpdateEditingController(); 629 RenderWidgetHostViewAura* rwhv = ToRenderWidgetHostViewAura(
630 view_->web_contents_->GetRenderWidgetHostView());
631 if (rwhv)
632 rwhv->selection_controller()->OnWindowMoved();
633 }
631 #if defined(OS_WIN) 634 #if defined(OS_WIN)
632 } else { 635 } else {
633 UpdateConstrainedWindows(NULL); 636 UpdateConstrainedWindows(NULL);
634 #endif 637 #endif
635 } 638 }
636 } 639 }
637 640
638 void OnWindowDestroying(aura::Window* window) override { 641 void OnWindowDestroying(aura::Window* window) override {
639 if (window == host_window_) { 642 if (window == host_window_) {
640 host_window_->RemoveObserver(this); 643 host_window_->RemoveObserver(this);
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
746 WebContentsImpl* web_contents, 749 WebContentsImpl* web_contents,
747 WebContentsViewDelegate* delegate) 750 WebContentsViewDelegate* delegate)
748 : web_contents_(web_contents), 751 : web_contents_(web_contents),
749 delegate_(delegate), 752 delegate_(delegate),
750 current_drag_op_(blink::WebDragOperationNone), 753 current_drag_op_(blink::WebDragOperationNone),
751 drag_dest_delegate_(NULL), 754 drag_dest_delegate_(NULL),
752 current_rvh_for_drag_(NULL), 755 current_rvh_for_drag_(NULL),
753 overscroll_change_brightness_(false), 756 overscroll_change_brightness_(false),
754 current_overscroll_gesture_(OVERSCROLL_NONE), 757 current_overscroll_gesture_(OVERSCROLL_NONE),
755 completed_overscroll_gesture_(OVERSCROLL_NONE), 758 completed_overscroll_gesture_(OVERSCROLL_NONE),
756 touch_editable_(TouchEditableImplAura::Create()),
757 is_or_was_visible_(false) { 759 is_or_was_visible_(false) {
758 } 760 }
759 761
760 //////////////////////////////////////////////////////////////////////////////// 762 ////////////////////////////////////////////////////////////////////////////////
761 // WebContentsViewAura, private: 763 // WebContentsViewAura, private:
762 764
763 WebContentsViewAura::~WebContentsViewAura() { 765 WebContentsViewAura::~WebContentsViewAura() {
764 if (!window_) 766 if (!window_)
765 return; 767 return;
766 768
767 window_observer_.reset(); 769 window_observer_.reset();
768 window_->RemoveObserver(this); 770 window_->RemoveObserver(this);
769 771
770 // Window needs a valid delegate during its destructor, so we explicitly 772 // Window needs a valid delegate during its destructor, so we explicitly
771 // delete it here. 773 // delete it here.
772 window_.reset(); 774 window_.reset();
773 } 775 }
774 776
775 void WebContentsViewAura::SetTouchEditableForTest(
776 TouchEditableImplAura* touch_editable) {
777 touch_editable_.reset(touch_editable);
778 AttachTouchEditableToRenderView();
779 }
780
781 void WebContentsViewAura::SizeChangedCommon(const gfx::Size& size) { 777 void WebContentsViewAura::SizeChangedCommon(const gfx::Size& size) {
782 if (web_contents_->GetInterstitialPage()) 778 if (web_contents_->GetInterstitialPage())
783 web_contents_->GetInterstitialPage()->SetSize(size); 779 web_contents_->GetInterstitialPage()->SetSize(size);
784 RenderWidgetHostView* rwhv = 780 RenderWidgetHostView* rwhv =
785 web_contents_->GetRenderWidgetHostView(); 781 web_contents_->GetRenderWidgetHostView();
786 if (rwhv) 782 if (rwhv)
787 rwhv->SetSize(size); 783 rwhv->SetSize(size);
788 } 784 }
789 785
790 void WebContentsViewAura::EndDrag(blink::WebDragOperationsMask ops) { 786 void WebContentsViewAura::EndDrag(blink::WebDragOperationsMask ops) {
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
984 ratio = 1.f - ratio; 980 ratio = 1.f - ratio;
985 float brightness = current_overscroll_gesture_ == OVERSCROLL_WEST ? 981 float brightness = current_overscroll_gesture_ == OVERSCROLL_WEST ?
986 kBrightnessMin + ratio * (kBrightnessMax - kBrightnessMin) : 982 kBrightnessMin + ratio * (kBrightnessMax - kBrightnessMin) :
987 kBrightnessMax - ratio * (kBrightnessMax - kBrightnessMin); 983 kBrightnessMax - ratio * (kBrightnessMax - kBrightnessMin);
988 brightness = std::max(kBrightnessMin, brightness); 984 brightness = std::max(kBrightnessMin, brightness);
989 brightness = std::min(kBrightnessMax, brightness); 985 brightness = std::min(kBrightnessMax, brightness);
990 aura::Window* window = GetWindowToAnimateForOverscroll(); 986 aura::Window* window = GetWindowToAnimateForOverscroll();
991 window->layer()->SetLayerBrightness(brightness); 987 window->layer()->SetLayerBrightness(brightness);
992 } 988 }
993 989
994 void WebContentsViewAura::AttachTouchEditableToRenderView() {
995 if (!touch_editable_)
996 return;
997 RenderWidgetHostViewAura* rwhva = ToRenderWidgetHostViewAura(
998 web_contents_->GetRenderWidgetHostView());
999 touch_editable_->AttachToView(rwhva);
1000 }
1001
1002 void WebContentsViewAura::OverscrollUpdateForWebContentsDelegate( 990 void WebContentsViewAura::OverscrollUpdateForWebContentsDelegate(
1003 float delta_y) { 991 float delta_y) {
1004 if (web_contents_->GetDelegate() && IsScrollEndEffectEnabled()) 992 if (web_contents_->GetDelegate() && IsScrollEndEffectEnabled())
1005 web_contents_->GetDelegate()->OverscrollUpdate(delta_y); 993 web_contents_->GetDelegate()->OverscrollUpdate(delta_y);
1006 } 994 }
1007 995
1008 //////////////////////////////////////////////////////////////////////////////// 996 ////////////////////////////////////////////////////////////////////////////////
1009 // WebContentsViewAura, WebContentsView implementation: 997 // WebContentsViewAura, WebContentsView implementation:
1010 998
1011 gfx::NativeView WebContentsViewAura::GetNativeView() const { 999 gfx::NativeView WebContentsViewAura::GetNativeView() const {
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
1170 1158
1171 // We listen to drag drop events in the newly created view's window. 1159 // We listen to drag drop events in the newly created view's window.
1172 aura::client::SetDragDropDelegate(view->GetNativeView(), this); 1160 aura::client::SetDragDropDelegate(view->GetNativeView(), this);
1173 1161
1174 if (view->overscroll_controller() && 1162 if (view->overscroll_controller() &&
1175 (!web_contents_->GetDelegate() || 1163 (!web_contents_->GetDelegate() ||
1176 web_contents_->GetDelegate()->CanOverscrollContent())) { 1164 web_contents_->GetDelegate()->CanOverscrollContent())) {
1177 InstallOverscrollControllerDelegate(view); 1165 InstallOverscrollControllerDelegate(view);
1178 } 1166 }
1179 1167
1180 AttachTouchEditableToRenderView(); 1168 //AttachTouchEditableToRenderView();
1181 1169
1182 #if defined(OS_WIN) 1170 #if defined(OS_WIN)
1183 if (legacy_hwnd_) 1171 if (legacy_hwnd_)
1184 view->SetLegacyRenderWidgetHostHWND(legacy_hwnd_.get()); 1172 view->SetLegacyRenderWidgetHostHWND(legacy_hwnd_.get());
1185 #endif 1173 #endif
1186 1174
1187 return view; 1175 return view;
1188 } 1176 }
1189 1177
1190 RenderWidgetHostViewBase* WebContentsViewAura::CreateViewForPopupWidget( 1178 RenderWidgetHostViewBase* WebContentsViewAura::CreateViewForPopupWidget(
(...skipping 10 matching lines...) Expand all
1201 void WebContentsViewAura::SetPageTitle(const base::string16& title) { 1189 void WebContentsViewAura::SetPageTitle(const base::string16& title) {
1202 window_->SetTitle(title); 1190 window_->SetTitle(title);
1203 } 1191 }
1204 1192
1205 void WebContentsViewAura::RenderViewCreated(RenderViewHost* host) { 1193 void WebContentsViewAura::RenderViewCreated(RenderViewHost* host) {
1206 } 1194 }
1207 1195
1208 void WebContentsViewAura::RenderViewSwappedIn(RenderViewHost* host) { 1196 void WebContentsViewAura::RenderViewSwappedIn(RenderViewHost* host) {
1209 if (navigation_overlay_.get() && navigation_overlay_->has_window()) 1197 if (navigation_overlay_.get() && navigation_overlay_->has_window())
1210 navigation_overlay_->StartObserving(); 1198 navigation_overlay_->StartObserving();
1211 AttachTouchEditableToRenderView(); 1199 //AttachTouchEditableToRenderView();
1212 } 1200 }
1213 1201
1214 void WebContentsViewAura::SetOverscrollControllerEnabled(bool enabled) { 1202 void WebContentsViewAura::SetOverscrollControllerEnabled(bool enabled) {
1215 RenderWidgetHostViewAura* view = 1203 RenderWidgetHostViewAura* view =
1216 ToRenderWidgetHostViewAura(web_contents_->GetRenderWidgetHostView()); 1204 ToRenderWidgetHostViewAura(web_contents_->GetRenderWidgetHostView());
1217 if (view) { 1205 if (view) {
1218 view->SetOverscrollControllerEnabled(enabled); 1206 view->SetOverscrollControllerEnabled(enabled);
1219 if (enabled) 1207 if (enabled)
1220 InstallOverscrollControllerDelegate(view); 1208 InstallOverscrollControllerDelegate(view);
1221 } 1209 }
1222 1210
1223 if (!enabled) 1211 if (!enabled)
1224 navigation_overlay_.reset(); 1212 navigation_overlay_.reset();
1225 else if (!navigation_overlay_) 1213 else if (!navigation_overlay_)
1226 navigation_overlay_.reset(new OverscrollNavigationOverlay(web_contents_)); 1214 navigation_overlay_.reset(new OverscrollNavigationOverlay(web_contents_));
1227 } 1215 }
1228 1216
1229 //////////////////////////////////////////////////////////////////////////////// 1217 ////////////////////////////////////////////////////////////////////////////////
1230 // WebContentsViewAura, RenderViewHostDelegateView implementation: 1218 // WebContentsViewAura, RenderViewHostDelegateView implementation:
1231 1219
1232 void WebContentsViewAura::ShowContextMenu(RenderFrameHost* render_frame_host, 1220 void WebContentsViewAura::ShowContextMenu(RenderFrameHost* render_frame_host,
1233 const ContextMenuParams& params) { 1221 const ContextMenuParams& params) {
1234 if (touch_editable_) { 1222 RenderWidgetHostViewAura* rwhv =
1235 touch_editable_->EndTouchEditing(false); 1223 ToRenderWidgetHostViewAura(web_contents_->GetRenderWidgetHostView());
1236 } 1224 if (rwhv)
1225 rwhv->selection_controller()->HideAndDisallowShowingAutomatically();
1237 if (delegate_) { 1226 if (delegate_) {
1238 delegate_->ShowContextMenu(render_frame_host, params); 1227 delegate_->ShowContextMenu(render_frame_host, params);
1239 // WARNING: we may have been deleted during the call to ShowContextMenu(). 1228 // WARNING: we may have been deleted during the call to ShowContextMenu().
1240 } 1229 }
1241 } 1230 }
1242 1231
1243 void WebContentsViewAura::StartDragging( 1232 void WebContentsViewAura::StartDragging(
1244 const DropData& drop_data, 1233 const DropData& drop_data,
1245 blink::WebDragOperationsMask operations, 1234 blink::WebDragOperationsMask operations,
1246 const gfx::ImageSkia& image, 1235 const gfx::ImageSkia& image,
1247 const gfx::Vector2d& image_offset, 1236 const gfx::Vector2d& image_offset,
1248 const DragEventSourceInfo& event_info) { 1237 const DragEventSourceInfo& event_info) {
1249 aura::Window* root_window = GetNativeView()->GetRootWindow(); 1238 aura::Window* root_window = GetNativeView()->GetRootWindow();
1250 if (!aura::client::GetDragDropClient(root_window)) { 1239 if (!aura::client::GetDragDropClient(root_window)) {
1251 web_contents_->SystemDragEnded(); 1240 web_contents_->SystemDragEnded();
1252 return; 1241 return;
1253 } 1242 }
1254 1243
1255 if (touch_editable_) 1244 RenderWidgetHostViewAura* rwhv =
1256 touch_editable_->EndTouchEditing(false); 1245 ToRenderWidgetHostViewAura(web_contents_->GetRenderWidgetHostView());
1246 if (rwhv)
1247 rwhv->selection_controller()->HideAndDisallowShowingAutomatically();
1257 1248
1258 ui::OSExchangeData::Provider* provider = ui::OSExchangeData::CreateProvider(); 1249 ui::OSExchangeData::Provider* provider = ui::OSExchangeData::CreateProvider();
1259 PrepareDragData(drop_data, provider, web_contents_); 1250 PrepareDragData(drop_data, provider, web_contents_);
1260 1251
1261 ui::OSExchangeData data(provider); // takes ownership of |provider|. 1252 ui::OSExchangeData data(provider); // takes ownership of |provider|.
1262 1253
1263 if (!image.isNull()) 1254 if (!image.isNull())
1264 drag_utils::SetDragImageOnDataObject(image, image_offset, &data); 1255 drag_utils::SetDragImageOnDataObject(image, image_offset, &data);
1265 1256
1266 scoped_ptr<WebDragSourceAura> drag_source( 1257 scoped_ptr<WebDragSourceAura> drag_source(
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1379 } 1370 }
1380 1371
1381 void WebContentsViewAura::OnOverscrollModeChange(OverscrollMode old_mode, 1372 void WebContentsViewAura::OnOverscrollModeChange(OverscrollMode old_mode,
1382 OverscrollMode new_mode) { 1373 OverscrollMode new_mode) {
1383 // Reset any in-progress overscroll animation first. 1374 // Reset any in-progress overscroll animation first.
1384 ResetOverscrollTransform(); 1375 ResetOverscrollTransform();
1385 1376
1386 if (old_mode == OVERSCROLL_NORTH || old_mode == OVERSCROLL_SOUTH) 1377 if (old_mode == OVERSCROLL_NORTH || old_mode == OVERSCROLL_SOUTH)
1387 OverscrollUpdateForWebContentsDelegate(0); 1378 OverscrollUpdateForWebContentsDelegate(0);
1388 1379
1389 if (new_mode != OVERSCROLL_NONE && touch_editable_) 1380 if (new_mode != OVERSCROLL_NONE) {
1390 touch_editable_->OverscrollStarted(); 1381 RenderWidgetHostViewAura* rwhv =
1382 ToRenderWidgetHostViewAura(web_contents_->GetRenderWidgetHostView());
1383 if (rwhv)
1384 rwhv->selection_controller()->OnOverscrollStarted();
1385 }
1391 1386
1392 if (new_mode == OVERSCROLL_NONE || 1387 if (new_mode == OVERSCROLL_NONE ||
1393 !GetContentNativeView() || 1388 !GetContentNativeView() ||
1394 ((new_mode == OVERSCROLL_EAST || new_mode == OVERSCROLL_WEST) && 1389 ((new_mode == OVERSCROLL_EAST || new_mode == OVERSCROLL_WEST) &&
1395 navigation_overlay_.get() && navigation_overlay_->has_window())) { 1390 navigation_overlay_.get() && navigation_overlay_->has_window())) {
1396 current_overscroll_gesture_ = OVERSCROLL_NONE; 1391 current_overscroll_gesture_ = OVERSCROLL_NONE;
1397 } else { 1392 } else {
1398 aura::Window* target = GetWindowToAnimateForOverscroll(); 1393 aura::Window* target = GetWindowToAnimateForOverscroll();
1399 if (target) { 1394 if (target) {
1400 StopObservingImplicitAnimations(); 1395 StopObservingImplicitAnimations();
(...skipping 21 matching lines...) Expand all
1422 1417
1423 if (ShouldNavigateForward(web_contents_->GetController(), 1418 if (ShouldNavigateForward(web_contents_->GetController(),
1424 completed_overscroll_gesture_)) { 1419 completed_overscroll_gesture_)) {
1425 web_contents_->GetController().GoForward(); 1420 web_contents_->GetController().GoForward();
1426 PrepareOverscrollNavigationOverlay(); 1421 PrepareOverscrollNavigationOverlay();
1427 } else if (ShouldNavigateBack(web_contents_->GetController(), 1422 } else if (ShouldNavigateBack(web_contents_->GetController(),
1428 completed_overscroll_gesture_)) { 1423 completed_overscroll_gesture_)) {
1429 web_contents_->GetController().GoBack(); 1424 web_contents_->GetController().GoBack();
1430 PrepareOverscrollNavigationOverlay(); 1425 PrepareOverscrollNavigationOverlay();
1431 } else { 1426 } else {
1432 if (touch_editable_) 1427 RenderWidgetHostViewAura* rwhv =
1433 touch_editable_->OverscrollCompleted(); 1428 ToRenderWidgetHostViewAura(web_contents_->GetRenderWidgetHostView());
1429 if (rwhv)
1430 rwhv->selection_controller()->OnOverscrollCompleted();
1434 } 1431 }
1435 1432
1436 aura::Window* content = GetContentNativeView(); 1433 aura::Window* content = GetContentNativeView();
1437 if (content) { 1434 if (content) {
1438 content->SetTransform(gfx::Transform()); 1435 content->SetTransform(gfx::Transform());
1439 content->layer()->SetLayerBrightness(0.f); 1436 content->layer()->SetLayerBrightness(0.f);
1440 } 1437 }
1441 current_overscroll_gesture_ = OVERSCROLL_NONE; 1438 current_overscroll_gesture_ = OVERSCROLL_NONE;
1442 completed_overscroll_gesture_ = OVERSCROLL_NONE; 1439 completed_overscroll_gesture_ = OVERSCROLL_NONE;
1443 overscroll_window_.reset(); 1440 overscroll_window_.reset();
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
1700 BrowserAccessibilityManager* manager = 1697 BrowserAccessibilityManager* manager =
1701 web_contents_->GetRootBrowserAccessibilityManager(); 1698 web_contents_->GetRootBrowserAccessibilityManager();
1702 if (!manager) 1699 if (!manager)
1703 return nullptr; 1700 return nullptr;
1704 1701
1705 return manager->GetRoot()->ToBrowserAccessibilityWin(); 1702 return manager->GetRoot()->ToBrowserAccessibilityWin();
1706 } 1703 }
1707 #endif 1704 #endif
1708 1705
1709 } // namespace content 1706 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698