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

Side by Side Diff: content/browser/frame_host/render_frame_host_manager.cc

Issue 616133002: Make RenderFrame(Host) own a RenderWidget(Host). (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed a conflict with the RF creation flag word Created 6 years 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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/frame_host/render_frame_host_manager.h" 5 #include "content/browser/frame_host/render_frame_host_manager.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/debug/trace_event.h" 10 #include "base/debug/trace_event.h"
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 if (!pending_render_frame_host_) 108 if (!pending_render_frame_host_)
109 return NULL; 109 return NULL;
110 return pending_render_frame_host_->render_view_host(); 110 return pending_render_frame_host_->render_view_host();
111 } 111 }
112 112
113 RenderWidgetHostView* RenderFrameHostManager::GetRenderWidgetHostView() const { 113 RenderWidgetHostView* RenderFrameHostManager::GetRenderWidgetHostView() const {
114 if (interstitial_page_) 114 if (interstitial_page_)
115 return interstitial_page_->GetView(); 115 return interstitial_page_->GetView();
116 if (!render_frame_host_) 116 if (!render_frame_host_)
117 return NULL; 117 return NULL;
118 return render_frame_host_->render_view_host()->GetView(); 118 return static_cast<RenderFrameHostImpl*>(render_frame_host_->
119 render_view_host()->GetMainFrame())->GetView();
ncarter (slow) 2014/12/15 19:53:07 In the browser_test TaskManagerOOPIFBrowserTest.Ki
119 } 120 }
120 121
121 RenderFrameProxyHost* RenderFrameHostManager::GetProxyToParent() { 122 RenderFrameProxyHost* RenderFrameHostManager::GetProxyToParent() {
122 if (frame_tree_node_->IsMainFrame()) 123 if (frame_tree_node_->IsMainFrame())
123 return NULL; 124 return NULL;
124 125
125 RenderFrameProxyHostMap::iterator iter = 126 RenderFrameProxyHostMap::iterator iter =
126 proxy_hosts_.find(frame_tree_node_->parent() 127 proxy_hosts_.find(frame_tree_node_->parent()
127 ->render_manager() 128 ->render_manager()
128 ->current_frame_host() 129 ->current_frame_host()
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
201 if (!InitRenderView(dest_render_frame_host->render_view_host(), 202 if (!InitRenderView(dest_render_frame_host->render_view_host(),
202 opener_route_id, 203 opener_route_id,
203 MSG_ROUTING_NONE, 204 MSG_ROUTING_NONE,
204 frame_tree_node_->IsMainFrame())) 205 frame_tree_node_->IsMainFrame()))
205 return NULL; 206 return NULL;
206 207
207 // Now that we've created a new renderer, be sure to hide it if it isn't 208 // Now that we've created a new renderer, be sure to hide it if it isn't
208 // our primary one. Otherwise, we might crash if we try to call Show() 209 // our primary one. Otherwise, we might crash if we try to call Show()
209 // on it later. 210 // on it later.
210 if (dest_render_frame_host != render_frame_host_ && 211 if (dest_render_frame_host != render_frame_host_ &&
211 dest_render_frame_host->render_view_host()->GetView()) { 212 dest_render_frame_host->GetView()) {
212 dest_render_frame_host->render_view_host()->GetView()->Hide(); 213 dest_render_frame_host->GetView()->Hide();
213 } else { 214 } else {
214 // Notify here as we won't be calling CommitPending (which does the 215 // Notify here as we won't be calling CommitPending (which does the
215 // notify). 216 // notify).
216 delegate_->NotifySwappedFromRenderManager( 217 delegate_->NotifySwappedFromRenderManager(
217 NULL, render_frame_host_.get(), frame_tree_node_->IsMainFrame()); 218 NULL, render_frame_host_.get(), frame_tree_node_->IsMainFrame());
218 } 219 }
219 } 220 }
220 221
221 // If entry includes the request ID of a request that is being transferred, 222 // If entry includes the request ID of a request that is being transferred,
222 // the destination render frame will take ownership, so release ownership of 223 // the destination render frame will take ownership, so release ownership of
(...skipping 803 matching lines...) Expand 10 before | Expand all | Expand 10 after
1026 SiteInstance* new_instance, 1027 SiteInstance* new_instance,
1027 bool is_main_frame) { 1028 bool is_main_frame) {
1028 int create_render_frame_flags = 0; 1029 int create_render_frame_flags = 0;
1029 if (is_main_frame) 1030 if (is_main_frame)
1030 create_render_frame_flags |= CREATE_RF_FOR_MAIN_FRAME_NAVIGATION; 1031 create_render_frame_flags |= CREATE_RF_FOR_MAIN_FRAME_NAVIGATION;
1031 1032
1032 if (delegate_->IsHidden()) 1033 if (delegate_->IsHidden())
1033 create_render_frame_flags |= CREATE_RF_HIDDEN; 1034 create_render_frame_flags |= CREATE_RF_HIDDEN;
1034 1035
1035 int opener_route_id = 1036 int opener_route_id =
1036 CreateOpenerRenderViewsIfNeeded(old_instance, new_instance); 1037 CreateOpenerRenderViewsIfNeeded(old_instance, new_instance,
1038 create_render_frame_flags);
1037 1039
1038 if (pending_render_frame_host_) 1040 if (pending_render_frame_host_)
1039 CancelPending(); 1041 CancelPending();
1040 1042
1041 // Create a non-swapped-out RFH with the given opener. 1043 // Create a non-swapped-out RFH with the given opener.
1042 pending_render_frame_host_ = 1044 pending_render_frame_host_ =
1043 CreateRenderFrame(new_instance, pending_web_ui(), opener_route_id, 1045 CreateRenderFrame(new_instance, pending_web_ui(), opener_route_id,
1044 create_render_frame_flags, nullptr); 1046 create_render_frame_flags, nullptr);
1045 } 1047 }
1046 1048
1047 int RenderFrameHostManager::CreateOpenerRenderViewsIfNeeded( 1049 int RenderFrameHostManager::CreateOpenerRenderViewsIfNeeded(
1048 SiteInstance* old_instance, 1050 SiteInstance* old_instance,
1049 SiteInstance* new_instance) { 1051 SiteInstance* new_instance,
1052 int& create_render_frame_flags) {
1050 int opener_route_id = MSG_ROUTING_NONE; 1053 int opener_route_id = MSG_ROUTING_NONE;
1051 if (new_instance->IsRelatedSiteInstance(old_instance)) { 1054 if (new_instance->IsRelatedSiteInstance(old_instance)) {
1052 opener_route_id = 1055 opener_route_id =
1053 delegate_->CreateOpenerRenderViewsForRenderManager(new_instance); 1056 delegate_->CreateOpenerRenderViewsForRenderManager(new_instance);
1054 if (CommandLine::ForCurrentProcess()->HasSwitch( 1057 if (CommandLine::ForCurrentProcess()->HasSwitch(
1055 switches::kSitePerProcess)) { 1058 switches::kSitePerProcess)) {
1056 // Ensure that the frame tree has RenderFrameProxyHosts for the new 1059 // Ensure that the frame tree has RenderFrameProxyHosts for the new
1057 // SiteInstance in all nodes except the current one. 1060 // SiteInstance in all nodes except the current one.
1058 frame_tree_node_->frame_tree()->CreateProxiesForSiteInstance( 1061 frame_tree_node_->frame_tree()->CreateProxiesForSiteInstance(
1059 frame_tree_node_, new_instance); 1062 frame_tree_node_, new_instance);
1063 // RenderFrames in different processes from their parent RenderFrames
1064 // in the frame tree require RenderWidgets for rendering and processing
1065 // input events.
1066 if (frame_tree_node_->parent() &&
1067 frame_tree_node_->parent()->render_manager()->
1068 current_frame_host()->GetSiteInstance() != new_instance)
1069 create_render_frame_flags |= CREATE_RF_NEEDS_RENDER_WIDGET_HOST;
1060 } 1070 }
1061 } 1071 }
1062 return opener_route_id; 1072 return opener_route_id;
1063 } 1073 }
1064 1074
1065 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrameHost( 1075 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrameHost(
1066 SiteInstance* site_instance, 1076 SiteInstance* site_instance,
1067 int view_routing_id, 1077 int view_routing_id,
1068 int frame_routing_id, 1078 int frame_routing_id,
1069 int flags) { 1079 int flags) {
1070 if (frame_routing_id == MSG_ROUTING_NONE) 1080 if (frame_routing_id == MSG_ROUTING_NONE)
1071 frame_routing_id = site_instance->GetProcess()->GetNextRoutingID(); 1081 frame_routing_id = site_instance->GetProcess()->GetNextRoutingID();
1072 1082
1073 bool swapped_out = !!(flags & CREATE_RF_SWAPPED_OUT); 1083 bool swapped_out = flags & CREATE_RF_SWAPPED_OUT;
1074 bool hidden = !!(flags & CREATE_RF_HIDDEN); 1084 bool hidden = !!(flags & CREATE_RF_HIDDEN);
1075 1085
1076 // Create a RVH for main frames, or find the existing one for subframes. 1086 // Create a RVH for main frames, or find the existing one for subframes.
1077 FrameTree* frame_tree = frame_tree_node_->frame_tree(); 1087 FrameTree* frame_tree = frame_tree_node_->frame_tree();
1078 RenderViewHostImpl* render_view_host = NULL; 1088 RenderViewHostImpl* render_view_host = NULL;
1079 if (frame_tree_node_->IsMainFrame()) { 1089 if (frame_tree_node_->IsMainFrame()) {
1080 render_view_host = frame_tree->CreateRenderViewHost( 1090 render_view_host = frame_tree->CreateRenderViewHost(
1081 site_instance, view_routing_id, frame_routing_id, swapped_out, hidden); 1091 site_instance,
1092 view_routing_id,
1093 frame_routing_id,
1094 swapped_out,
1095 hidden);
1082 } else { 1096 } else {
1083 render_view_host = frame_tree->GetRenderViewHost(site_instance); 1097 render_view_host = frame_tree->GetRenderViewHost(site_instance);
1084 1098
1085 CHECK(render_view_host); 1099 CHECK(render_view_host);
1086 } 1100 }
1087 1101
1088 // TODO(creis): Pass hidden to RFH. 1102 // TODO(creis): Pass hidden to RFH.
1089 scoped_ptr<RenderFrameHostImpl> render_frame_host = 1103 scoped_ptr<RenderFrameHostImpl> render_frame_host =
1090 make_scoped_ptr(RenderFrameHostFactory::Create( 1104 make_scoped_ptr(RenderFrameHostFactory::Create(
1091 render_view_host, render_frame_delegate_, frame_tree, 1105 render_view_host, render_frame_delegate_, render_widge t_delegate_, frame_tree,
1092 frame_tree_node_, frame_routing_id, flags).release()); 1106 frame_tree_node_, frame_routing_id, flags).release());
1093 return render_frame_host.Pass(); 1107 return render_frame_host.Pass();
1094 } 1108 }
1095 1109
1096 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrame( 1110 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrame(
1097 SiteInstance* instance, 1111 SiteInstance* instance,
1098 WebUIImpl* web_ui, 1112 WebUIImpl* web_ui,
1099 int opener_route_id, 1113 int opener_route_id,
1100 int flags, 1114 int flags,
1101 int* view_routing_id_ptr) { 1115 int* view_routing_id_ptr) {
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1169 if (frame_tree_node_->IsMainFrame()) 1183 if (frame_tree_node_->IsMainFrame())
1170 proxy->TakeFrameHostOwnership(new_render_frame_host.Pass()); 1184 proxy->TakeFrameHostOwnership(new_render_frame_host.Pass());
1171 } 1185 }
1172 1186
1173 success = 1187 success =
1174 InitRenderView(render_view_host, opener_route_id, proxy_routing_id, 1188 InitRenderView(render_view_host, opener_route_id, proxy_routing_id,
1175 !!(flags & CREATE_RF_FOR_MAIN_FRAME_NAVIGATION)); 1189 !!(flags & CREATE_RF_FOR_MAIN_FRAME_NAVIGATION));
1176 if (success) { 1190 if (success) {
1177 if (frame_tree_node_->IsMainFrame()) { 1191 if (frame_tree_node_->IsMainFrame()) {
1178 // Don't show the main frame's view until we get a DidNavigate from it. 1192 // Don't show the main frame's view until we get a DidNavigate from it.
1179 render_view_host->GetView()->Hide(); 1193 // Only top-level RenderViewHosts have RenderWidgetHostViews;
1194 // RenderWidgetHosts for out-of-process iframes will be created
1195 // later and hidden.
1196 if (render_view_host->GetView())
1197 render_view_host->GetView()->Hide();
1180 } else if (!swapped_out) { 1198 } else if (!swapped_out) {
1181 // Init the RFH, so a RenderFrame is created in the renderer. 1199 // Init the RFH, so a RenderFrame is created in the renderer.
1182 DCHECK(new_render_frame_host.get()); 1200 DCHECK(new_render_frame_host.get());
1183 success = InitRenderFrame(new_render_frame_host.get()); 1201 success = InitRenderFrame(new_render_frame_host.get());
1184 } 1202 }
1185 if (success) { 1203 if (success) {
1186 if (view_routing_id_ptr) 1204 if (view_routing_id_ptr)
1187 *view_routing_id_ptr = render_view_host->GetRoutingID(); 1205 *view_routing_id_ptr = render_view_host->GetRoutingID();
1188 // If a brand new RFH was created, announce it to observers. 1206 // If a brand new RFH was created, announce it to observers.
1189 if (new_render_frame_host) { 1207 if (new_render_frame_host) {
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
1317 // committing above and we're done. 1335 // committing above and we're done.
1318 if (!pending_render_frame_host_) { 1336 if (!pending_render_frame_host_) {
1319 if (will_focus_location_bar) 1337 if (will_focus_location_bar)
1320 delegate_->SetFocusToLocationBar(false); 1338 delegate_->SetFocusToLocationBar(false);
1321 return; 1339 return;
1322 } 1340 }
1323 1341
1324 // Remember if the page was focused so we can focus the new renderer in 1342 // Remember if the page was focused so we can focus the new renderer in
1325 // that case. 1343 // that case.
1326 bool focus_render_view = !will_focus_location_bar && 1344 bool focus_render_view = !will_focus_location_bar &&
1327 render_frame_host_->render_view_host()->GetView() && 1345 render_frame_host_->GetView() &&
1328 render_frame_host_->render_view_host()->GetView()->HasFocus(); 1346 render_frame_host_->GetView()->HasFocus();
1329 1347
1330 bool is_main_frame = frame_tree_node_->IsMainFrame(); 1348 bool is_main_frame = frame_tree_node_->IsMainFrame();
1331 1349
1332 // Swap in the pending frame and make it active. Also ensure the FrameTree 1350 // Swap in the pending frame and make it active. Also ensure the FrameTree
1333 // stays in sync. 1351 // stays in sync.
1334 scoped_ptr<RenderFrameHostImpl> old_render_frame_host = 1352 scoped_ptr<RenderFrameHostImpl> old_render_frame_host =
1335 SetRenderFrameHost(pending_render_frame_host_.Pass()); 1353 SetRenderFrameHost(pending_render_frame_host_.Pass());
1336 if (is_main_frame) 1354 if (is_main_frame)
1337 render_frame_host_->render_view_host()->AttachToFrameTree(); 1355 render_frame_host_->render_view_host()->AttachToFrameTree();
1338 1356
1339 // The process will no longer try to exit, so we can decrement the count. 1357 // The process will no longer try to exit, so we can decrement the count.
1340 render_frame_host_->GetProcess()->RemovePendingView(); 1358 render_frame_host_->GetProcess()->RemovePendingView();
1341 1359
1342 // Show the new view (or a sad tab) if necessary. 1360 // Show the new view (or a sad tab) if necessary.
1343 bool new_rfh_has_view = !!render_frame_host_->render_view_host()->GetView(); 1361 bool new_rfh_has_view = !!render_frame_host_->GetView();
1344 if (!delegate_->IsHidden() && new_rfh_has_view) { 1362 if (!delegate_->IsHidden() && new_rfh_has_view) {
1345 // In most cases, we need to show the new view. 1363 // In most cases, we need to show the new view.
1346 render_frame_host_->render_view_host()->GetView()->Show(); 1364 render_frame_host_->GetView()->Show();
1347 } 1365 }
1348 if (!new_rfh_has_view) { 1366 if (!new_rfh_has_view) {
1349 // If the view is gone, then this RenderViewHost died while it was hidden. 1367 // If the view is gone, then this RenderViewHost died while it was hidden.
1350 // We ignored the RenderProcessGone call at the time, so we should send it 1368 // We ignored the RenderProcessGone call at the time, so we should send it
1351 // now to make sure the sad tab shows up, etc. 1369 // now to make sure the sad tab shows up, etc.
1352 DCHECK(!render_frame_host_->IsRenderFrameLive()); 1370 DCHECK(!render_frame_host_->IsRenderFrameLive());
1353 DCHECK(!render_frame_host_->render_view_host()->IsRenderViewLive()); 1371 DCHECK(!render_frame_host_->render_view_host()->IsRenderViewLive());
1354 delegate_->RenderProcessGoneFromRenderManager( 1372 delegate_->RenderProcessGoneFromRenderManager(
1355 render_frame_host_->render_view_host()); 1373 render_frame_host_->render_view_host());
1356 } 1374 }
1357 1375
1358 // For top-level frames, also hide the old RenderViewHost's view. 1376 // For top-level frames, also hide the old RenderViewHost's view.
1359 // TODO(creis): As long as show/hide are on RVH, we don't want to hide on 1377 // TODO(creis): As long as show/hide are on RVH, we don't want to hide on
1360 // subframe navigations or we will interfere with the top-level frame. 1378 // subframe navigations or we will interfere with the top-level frame.
1361 if (is_main_frame && old_render_frame_host->render_view_host()->GetView()) 1379 if (is_main_frame && old_render_frame_host->render_view_host()->GetView())
1362 old_render_frame_host->render_view_host()->GetView()->Hide(); 1380 old_render_frame_host->render_view_host()->GetView()->Hide();
1363 1381
1364 // Make sure the size is up to date. (Fix for bug 1079768.) 1382 // Make sure the size is up to date. (Fix for bug 1079768.)
1365 delegate_->UpdateRenderViewSizeForRenderManager(); 1383 delegate_->UpdateRenderViewSizeForRenderManager();
1366 1384
1367 if (will_focus_location_bar) { 1385 if (will_focus_location_bar) {
1368 delegate_->SetFocusToLocationBar(false); 1386 delegate_->SetFocusToLocationBar(false);
1369 } else if (focus_render_view && 1387 } else if (focus_render_view &&
1370 render_frame_host_->render_view_host()->GetView()) { 1388 render_frame_host_->GetView()) {
1371 render_frame_host_->render_view_host()->GetView()->Focus(); 1389 render_frame_host_->GetView()->Focus();
1372 } 1390 }
1373 1391
1374 // Notify that we've swapped RenderFrameHosts. We do this before shutting down 1392 // Notify that we've swapped RenderFrameHosts. We do this before shutting down
1375 // the RFH so that we can clean up RendererResources related to the RFH first. 1393 // the RFH so that we can clean up RendererResources related to the RFH first.
1376 delegate_->NotifySwappedFromRenderManager( 1394 delegate_->NotifySwappedFromRenderManager(
1377 old_render_frame_host.get(), render_frame_host_.get(), is_main_frame); 1395 old_render_frame_host.get(), render_frame_host_.get(), is_main_frame);
1378 1396
1379 // Swap out the old frame now that the new one is visible. 1397 // Swap out the old frame now that the new one is visible.
1380 // This will swap it out and then put it on the proxy list (if there are other 1398 // This will swap it out and then put it on the proxy list (if there are other
1381 // active views in its SiteInstance) or schedule it for deletion when the swap 1399 // active views in its SiteInstance) or schedule it for deletion when the swap
1382 // out ack arrives (or immediately if the process isn't live). 1400 // out ack arrives (or immediately if the process isn't live).
1383 // In the --site-per-process case, old subframe RHFs are not kept alive inside 1401 // In the --site-per-process case, old subframe RHFs are not kept alive inside
1384 // the proxy. 1402 // the proxy.
1385 SwapOutOldFrame(old_render_frame_host.Pass()); 1403 SwapOutOldFrame(old_render_frame_host.Pass());
1386 1404
1387 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess) && 1405 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess) &&
1388 !is_main_frame) { 1406 !is_main_frame) {
1389 // If this is a subframe, it should have a CrossProcessFrameConnector 1407 // If this is a subframe, it should have a CrossProcessFrameConnector
1390 // created already. Use it to link the new RFH's view to the proxy that 1408 // created already. Use it to link the new RFH's view to the proxy that
1391 // belongs to the parent frame's SiteInstance. 1409 // belongs to the parent frame's SiteInstance.
1392 // Note: We do this after swapping out the old RFH because that may create 1410 // Note: We do this after swapping out the old RFH because that may create
1393 // the proxy we're looking for. 1411 // the proxy we're looking for.
1394 RenderFrameProxyHost* proxy_to_parent = GetProxyToParent(); 1412 RenderFrameProxyHost* proxy_to_parent = GetProxyToParent();
1395 if (proxy_to_parent) { 1413 if (proxy_to_parent) {
1396 proxy_to_parent->SetChildRWHView( 1414 proxy_to_parent->SetChildRWHView(
1397 render_frame_host_->render_view_host()->GetView()); 1415 render_frame_host_->GetView());
1398 } 1416 }
1399 1417
1400 // Since the new RenderFrameHost is now committed, there must be no proxies 1418 // Since the new RenderFrameHost is now committed, there must be no proxies
1401 // for its SiteInstance. Delete any existing ones. 1419 // for its SiteInstance. Delete any existing ones.
1402 RenderFrameProxyHostMap::iterator iter = 1420 RenderFrameProxyHostMap::iterator iter =
1403 proxy_hosts_.find(render_frame_host_->GetSiteInstance()->GetId()); 1421 proxy_hosts_.find(render_frame_host_->GetSiteInstance()->GetId());
1404 if (iter != proxy_hosts_.end()) { 1422 if (iter != proxy_hosts_.end()) {
1405 delete iter->second; 1423 delete iter->second;
1406 proxy_hosts_.erase(iter); 1424 proxy_hosts_.erase(iter);
1407 } 1425 }
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
1679 void RenderFrameHostManager::DeleteRenderFrameProxyHost( 1697 void RenderFrameHostManager::DeleteRenderFrameProxyHost(
1680 SiteInstance* instance) { 1698 SiteInstance* instance) {
1681 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find(instance->GetId()); 1699 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find(instance->GetId());
1682 if (iter != proxy_hosts_.end()) { 1700 if (iter != proxy_hosts_.end()) {
1683 delete iter->second; 1701 delete iter->second;
1684 proxy_hosts_.erase(iter); 1702 proxy_hosts_.erase(iter);
1685 } 1703 }
1686 } 1704 }
1687 1705
1688 } // namespace content 1706 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698