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

Side by Side Diff: chrome/browser/views/frame/browser_view.cc

Issue 155242: Add temporary TabStripWrapper interface that is implemented by both TabStrip ... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 11 years, 5 months 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2009 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 "chrome/browser/views/frame/browser_view.h" 5 #include "chrome/browser/views/frame/browser_view.h"
6 6
7 #if defined(OS_LINUX) 7 #if defined(OS_LINUX)
8 #include <gtk/gtk.h> 8 #include <gtk/gtk.h>
9 #endif 9 #endif
10 10
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 if (UILayoutIsRightToLeft()) 424 if (UILayoutIsRightToLeft())
425 bounding_box.set_x(bounding_box.x() + scrollbar_width); 425 bounding_box.set_x(bounding_box.x() + scrollbar_width);
426 426
427 return bounding_box; 427 return bounding_box;
428 } 428 }
429 429
430 int BrowserView::GetTabStripHeight() const { 430 int BrowserView::GetTabStripHeight() const {
431 // We want to return tabstrip_->height(), but we might be called in the midst 431 // We want to return tabstrip_->height(), but we might be called in the midst
432 // of layout, when that hasn't yet been updated to reflect the current state. 432 // of layout, when that hasn't yet been updated to reflect the current state.
433 // So return what the tabstrip height _ought_ to be right now. 433 // So return what the tabstrip height _ought_ to be right now.
434 views::View* tabstrip = 434 return IsTabStripVisible() ? tabstrip_->GetView()->GetPreferredSize().height()
435 TabStrip2::Enabled() ? static_cast<views::View*>(bts_) 435 : 0;
436 : static_cast<views::View*>(tabstrip_);
437 return IsTabStripVisible() ? tabstrip->GetPreferredSize().height() : 0;
438 } 436 }
439 437
440 gfx::Rect BrowserView::GetTabStripBounds() const { 438 gfx::Rect BrowserView::GetTabStripBounds() const {
441 return frame_->GetBoundsForTabStrip(tabstrip_); 439 return frame_->GetBoundsForTabStrip(tabstrip_);
442 } 440 }
443 441
444 bool BrowserView::IsToolbarVisible() const { 442 bool BrowserView::IsToolbarVisible() const {
445 return browser_->SupportsWindowFeature(Browser::FEATURE_TOOLBAR) || 443 return browser_->SupportsWindowFeature(Browser::FEATURE_TOOLBAR) ||
446 browser_->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR); 444 browser_->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR);
447 } 445 }
(...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after
938 936
939 void BrowserView::ShowHTMLDialog(HtmlDialogUIDelegate* delegate, 937 void BrowserView::ShowHTMLDialog(HtmlDialogUIDelegate* delegate,
940 gfx::NativeWindow parent_window) { 938 gfx::NativeWindow parent_window) {
941 // Default to using our window as the parent if the argument is not specified. 939 // Default to using our window as the parent if the argument is not specified.
942 gfx::NativeWindow parent = parent_window ? parent_window 940 gfx::NativeWindow parent = parent_window ? parent_window
943 : GetNativeHandle(); 941 : GetNativeHandle();
944 browser::ShowHtmlDialogView(parent, browser_.get(), delegate); 942 browser::ShowHtmlDialogView(parent, browser_.get(), delegate);
945 } 943 }
946 944
947 void BrowserView::ContinueDraggingDetachedTab(const gfx::Rect& tab_bounds) { 945 void BrowserView::ContinueDraggingDetachedTab(const gfx::Rect& tab_bounds) {
948 DCHECK(TabStrip2::Enabled()); 946 tabstrip_->SetDraggedTabBounds(0, tab_bounds);
949 bts_->SetDraggedTabBounds(0, tab_bounds);
950 frame_->ContinueDraggingDetachedTab(); 947 frame_->ContinueDraggingDetachedTab();
951 } 948 }
952 949
953 void BrowserView::UserChangedTheme() { 950 void BrowserView::UserChangedTheme() {
954 frame_->GetWindow()->FrameTypeChanged(); 951 frame_->GetWindow()->FrameTypeChanged();
955 GetRootView()->ThemeChanged(); 952 GetRootView()->ThemeChanged();
956 GetRootView()->SchedulePaint(); 953 GetRootView()->SchedulePaint();
957 } 954 }
958 955
959 int BrowserView::GetExtraRenderViewHeight() const { 956 int BrowserView::GetExtraRenderViewHeight() const {
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
1221 set_window(window); 1218 set_window(window);
1222 return this; 1219 return this;
1223 } 1220 }
1224 1221
1225 /////////////////////////////////////////////////////////////////////////////// 1222 ///////////////////////////////////////////////////////////////////////////////
1226 // BrowserView, views::ClientView overrides: 1223 // BrowserView, views::ClientView overrides:
1227 1224
1228 bool BrowserView::CanClose() const { 1225 bool BrowserView::CanClose() const {
1229 // You cannot close a frame for which there is an active originating drag 1226 // You cannot close a frame for which there is an active originating drag
1230 // session. 1227 // session.
1231 if (!TabStrip2::Enabled() && tabstrip_->IsDragSessionActive()) 1228 if (tabstrip_->IsDragSessionActive())
1232 return false; 1229 return false;
1233 1230
1234 // Give beforeunload handlers the chance to cancel the close before we hide 1231 // Give beforeunload handlers the chance to cancel the close before we hide
1235 // the window below. 1232 // the window below.
1236 if (!browser_->ShouldCloseWindow()) 1233 if (!browser_->ShouldCloseWindow())
1237 return false; 1234 return false;
1238 1235
1239 if (!browser_->tabstrip_model()->empty()) { 1236 if (!browser_->tabstrip_model()->empty()) {
1240 // Tab strip isn't empty. Hide the frame (so it appears to have closed 1237 // Tab strip isn't empty. Hide the frame (so it appears to have closed
1241 // immediately) and close all the tabs, allowing the renderers to shut 1238 // immediately) and close all the tabs, allowing the renderers to shut
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1279 #endif 1276 #endif
1280 } 1277 }
1281 1278
1282 // Determine if the TabStrip exists and is capable of being clicked on. We 1279 // Determine if the TabStrip exists and is capable of being clicked on. We
1283 // might be a popup window without a TabStrip. 1280 // might be a popup window without a TabStrip.
1284 if (IsTabStripVisible()) { 1281 if (IsTabStripVisible()) {
1285 gfx::Point point_in_view_coords(point); 1282 gfx::Point point_in_view_coords(point);
1286 View::ConvertPointToView(GetParent(), this, &point_in_view_coords); 1283 View::ConvertPointToView(GetParent(), this, &point_in_view_coords);
1287 1284
1288 // See if the mouse pointer is within the bounds of the TabStrip. 1285 // See if the mouse pointer is within the bounds of the TabStrip.
1289 if (!TabStrip2::Enabled()) { 1286 gfx::Point point_in_tabstrip_coords(point);
1290 gfx::Point point_in_tabstrip_coords(point); 1287 View::ConvertPointToView(GetParent(), tabstrip_->GetView(),
1291 View::ConvertPointToView(GetParent(), tabstrip_, &point_in_tabstrip_coords ); 1288 &point_in_tabstrip_coords);
1292 if (tabstrip_->HitTest(point_in_tabstrip_coords)) { 1289 if (tabstrip_->GetView()->HitTest(point_in_tabstrip_coords)) {
1293 if (tabstrip_->PointIsWithinWindowCaption(point_in_tabstrip_coords)) 1290 if (tabstrip_->PointIsWithinWindowCaption(point_in_tabstrip_coords))
1294 return HTCAPTION; 1291 return HTCAPTION;
1295 return HTCLIENT; 1292 return HTCLIENT;
1296 }
1297 } 1293 }
1298 1294
1299 // The top few pixels of the TabStrip are a drop-shadow - as we're pretty 1295 // The top few pixels of the TabStrip are a drop-shadow - as we're pretty
1300 // starved of dragable area, let's give it to window dragging (this also 1296 // starved of dragable area, let's give it to window dragging (this also
1301 // makes sense visually). 1297 // makes sense visually).
1302 if (!TabStrip2::Enabled() && !IsMaximized() && 1298 if (!IsMaximized() &&
1303 (point_in_view_coords.y() < tabstrip_->y() + kTabShadowSize)) { 1299 (point_in_view_coords.y() <
1300 (tabstrip_->GetView()->y() + kTabShadowSize))) {
1304 // We return HTNOWHERE as this is a signal to our containing 1301 // We return HTNOWHERE as this is a signal to our containing
1305 // NonClientView that it should figure out what the correct hit-test 1302 // NonClientView that it should figure out what the correct hit-test
1306 // code is given the mouse position... 1303 // code is given the mouse position...
1307 return HTNOWHERE; 1304 return HTNOWHERE;
1308 } 1305 }
1309 } 1306 }
1310 1307
1311 // If the point's y coordinate is below the top of the toolbar and otherwise 1308 // If the point's y coordinate is below the top of the toolbar and otherwise
1312 // within the bounds of this view, the point is considered to be within the 1309 // within the bounds of this view, the point is considered to be within the
1313 // client area. 1310 // client area.
1314 gfx::Rect bv_bounds = bounds(); 1311 gfx::Rect bv_bounds = bounds();
1315 if (TabStrip2::Enabled()) { 1312 bv_bounds.Offset(0, toolbar_->y());
1316 bv_bounds.Offset(0, bts_->y()); 1313 bv_bounds.set_height(bv_bounds.height() - toolbar_->y());
1317 bv_bounds.set_height(bv_bounds.height() - bts_->y());
1318 } else {
1319 bv_bounds.Offset(0, toolbar_->y());
1320 bv_bounds.set_height(bv_bounds.height() - toolbar_->y());
1321 }
1322 if (bv_bounds.Contains(point)) 1314 if (bv_bounds.Contains(point))
1323 return HTCLIENT; 1315 return HTCLIENT;
1324 1316
1325 // If the point's y coordinate is above the top of the toolbar, but not in 1317 // If the point's y coordinate is above the top of the toolbar, but not in
1326 // the tabstrip (per previous checking in this function), then we consider it 1318 // the tabstrip (per previous checking in this function), then we consider it
1327 // in the window caption (e.g. the area to the right of the tabstrip 1319 // in the window caption (e.g. the area to the right of the tabstrip
1328 // underneath the window controls). However, note that we DO NOT return 1320 // underneath the window controls). However, note that we DO NOT return
1329 // HTCAPTION here, because when the window is maximized the window controls 1321 // HTCAPTION here, because when the window is maximized the window controls
1330 // will fall into this space (since the BrowserView is sized to entire size 1322 // will fall into this space (since the BrowserView is sized to entire size
1331 // of the window at that point), and the HTCAPTION value will cause the 1323 // of the window at that point), and the HTCAPTION value will cause the
1332 // window controls not to work. So we return HTNOWHERE so that the caller 1324 // window controls not to work. So we return HTNOWHERE so that the caller
1333 // will hit-test the window controls before finally falling back to 1325 // will hit-test the window controls before finally falling back to
1334 // HTCAPTION. 1326 // HTCAPTION.
1335 bv_bounds = bounds(); 1327 bv_bounds = bounds();
1336 bv_bounds.set_height(toolbar_->y()); 1328 bv_bounds.set_height(toolbar_->y());
1337 if (bv_bounds.Contains(point)) 1329 if (bv_bounds.Contains(point))
1338 return HTNOWHERE; 1330 return HTNOWHERE;
1339 1331
1340 // If the point is somewhere else, delegate to the default implementation. 1332 // If the point is somewhere else, delegate to the default implementation.
1341 return views::ClientView::NonClientHitTest(point); 1333 return views::ClientView::NonClientHitTest(point);
1342 } 1334 }
1343 1335
1344 gfx::Size BrowserView::GetMinimumSize() { 1336 gfx::Size BrowserView::GetMinimumSize() {
1345 views::View* tabstrip =
1346 TabStrip2::Enabled() ? static_cast<views::View*>(bts_)
1347 : static_cast<views::View*>(tabstrip_);
1348 // TODO(noname): In theory the tabstrip width should probably be 1337 // TODO(noname): In theory the tabstrip width should probably be
1349 // (OTR + tabstrip + caption buttons) width. 1338 // (OTR + tabstrip + caption buttons) width.
1350 gfx::Size tabstrip_size( 1339 gfx::Size tabstrip_size(
1351 browser_->SupportsWindowFeature(Browser::FEATURE_TABSTRIP) ? 1340 browser_->SupportsWindowFeature(Browser::FEATURE_TABSTRIP) ?
1352 tabstrip->GetMinimumSize() : gfx::Size()); 1341 tabstrip_->GetView()->GetMinimumSize() : gfx::Size());
1353 gfx::Size toolbar_size( 1342 gfx::Size toolbar_size(
1354 (browser_->SupportsWindowFeature(Browser::FEATURE_TOOLBAR) || 1343 (browser_->SupportsWindowFeature(Browser::FEATURE_TOOLBAR) ||
1355 browser_->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR)) ? 1344 browser_->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR)) ?
1356 toolbar_->GetMinimumSize() : gfx::Size()); 1345 toolbar_->GetMinimumSize() : gfx::Size());
1357 if (tabstrip_size.height() && toolbar_size.height()) 1346 if (tabstrip_size.height() && toolbar_size.height())
1358 toolbar_size.Enlarge(0, -kToolbarTabStripVerticalOverlap); 1347 toolbar_size.Enlarge(0, -kToolbarTabStripVerticalOverlap);
1359 gfx::Size bookmark_bar_size; 1348 gfx::Size bookmark_bar_size;
1360 if (active_bookmark_bar_ && 1349 if (active_bookmark_bar_ &&
1361 browser_->SupportsWindowFeature(Browser::FEATURE_BOOKMARKBAR)) { 1350 browser_->SupportsWindowFeature(Browser::FEATURE_BOOKMARKBAR)) {
1362 bookmark_bar_size = active_bookmark_bar_->GetMinimumSize(); 1351 bookmark_bar_size = active_bookmark_bar_->GetMinimumSize();
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1431 // Start a hung plugin window detector for this browser object (as long as 1420 // Start a hung plugin window detector for this browser object (as long as
1432 // hang detection is not disabled). 1421 // hang detection is not disabled).
1433 if (!CommandLine::ForCurrentProcess()->HasSwitch( 1422 if (!CommandLine::ForCurrentProcess()->HasSwitch(
1434 switches::kDisableHangMonitor)) { 1423 switches::kDisableHangMonitor)) {
1435 InitHangMonitor(); 1424 InitHangMonitor();
1436 } 1425 }
1437 1426
1438 LoadAccelerators(); 1427 LoadAccelerators();
1439 SetAccessibleName(l10n_util::GetString(IDS_PRODUCT_NAME)); 1428 SetAccessibleName(l10n_util::GetString(IDS_PRODUCT_NAME));
1440 1429
1441 if (TabStrip2::Enabled()) { 1430 tabstrip_ = TabStripWrapper::CreateTabStrip(browser_->tabstrip_model());
1442 bts_ = new BrowserTabStrip(browser_->tabstrip_model()); 1431 tabstrip_->GetView()->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_TABST RIP));
1443 AddChildView(bts_); 1432 AddChildView(tabstrip_->GetView());
1444 } else { 1433 frame_->TabStripCreated(tabstrip_);
1445 tabstrip_ = new TabStrip(browser_->tabstrip_model());
1446 tabstrip_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_TABSTRIP));
1447 AddChildView(tabstrip_);
1448 tabstrip_->InitTabStripButtons();
1449 frame_->TabStripCreated(tabstrip_);
1450 }
1451 1434
1452 toolbar_ = new ToolbarView(browser_.get()); 1435 toolbar_ = new ToolbarView(browser_.get());
1453 AddChildView(toolbar_); 1436 AddChildView(toolbar_);
1454 toolbar_->SetID(VIEW_ID_TOOLBAR); 1437 toolbar_->SetID(VIEW_ID_TOOLBAR);
1455 toolbar_->Init(browser_->profile()); 1438 toolbar_->Init(browser_->profile());
1456 toolbar_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_TOOLBAR)); 1439 toolbar_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_TOOLBAR));
1457 1440
1458 infobar_container_ = new InfoBarContainer(this); 1441 infobar_container_ = new InfoBarContainer(this);
1459 AddChildView(infobar_container_); 1442 AddChildView(infobar_container_);
1460 1443
(...skipping 28 matching lines...) Expand all
1489 BuildSystemMenuForPopupWindow(); 1472 BuildSystemMenuForPopupWindow();
1490 system_menu_.reset( 1473 system_menu_.reset(
1491 new views::NativeMenuWin(system_menu_contents_.get(), 1474 new views::NativeMenuWin(system_menu_contents_.get(),
1492 frame_->GetWindow()->GetNativeWindow())); 1475 frame_->GetWindow()->GetNativeWindow()));
1493 system_menu_->Rebuild(); 1476 system_menu_->Rebuild();
1494 } 1477 }
1495 #endif 1478 #endif
1496 1479
1497 int BrowserView::LayoutTabStrip() { 1480 int BrowserView::LayoutTabStrip() {
1498 gfx::Rect tabstrip_bounds; 1481 gfx::Rect tabstrip_bounds;
1499 if (TabStrip2::Enabled()) { 1482 tabstrip_bounds = frame_->GetBoundsForTabStrip(tabstrip_);
1500 tabstrip_bounds = gfx::Rect(0, 0, width(), 1483 tabstrip_->SetBackgroundOffset(
1501 bts_->GetPreferredSize().height()); 1484 gfx::Point(tabstrip_bounds.x(), tabstrip_bounds.y()));
1502 } else {
1503 tabstrip_bounds = frame_->GetBoundsForTabStrip(tabstrip_);
1504 tabstrip_->SetBackgroundOffset(
1505 gfx::Point(tabstrip_bounds.x(), tabstrip_bounds.y()));
1506 }
1507 gfx::Point tabstrip_origin = tabstrip_bounds.origin(); 1485 gfx::Point tabstrip_origin = tabstrip_bounds.origin();
1508 ConvertPointToView(GetParent(), this, &tabstrip_origin); 1486 ConvertPointToView(GetParent(), this, &tabstrip_origin);
1509 tabstrip_bounds.set_origin(tabstrip_origin); 1487 tabstrip_bounds.set_origin(tabstrip_origin);
1510 bool visible = IsTabStripVisible(); 1488 bool visible = IsTabStripVisible();
1511 int y = visible ? tabstrip_bounds.y() : 0; 1489 int y = visible ? tabstrip_bounds.y() : 0;
1512 int height = visible ? tabstrip_bounds.height() : 0; 1490 int height = visible ? tabstrip_bounds.height() : 0;
1513 int bottom = y + height; 1491 int bottom = y + height;
1514 if (TabStrip2::Enabled()) { 1492 tabstrip_->GetView()->SetVisible(visible);
1515 gfx::Size btsps = bts_->GetPreferredSize(); 1493 tabstrip_->GetView()->SetBounds(tabstrip_bounds.x(), y,
1516 bts_->SetBounds(tabstrip_bounds.x(), y, width(), btsps.height()); 1494 tabstrip_bounds.width(), height);
1517 } else {
1518 tabstrip_->SetVisible(visible);
1519 tabstrip_->SetBounds(tabstrip_bounds.x(), y, tabstrip_bounds.width(), height );
1520 }
1521 return bottom; 1495 return bottom;
1522 } 1496 }
1523 1497
1524 int BrowserView::LayoutToolbar(int top) { 1498 int BrowserView::LayoutToolbar(int top) {
1525 int browser_view_width = width(); 1499 int browser_view_width = width();
1526 bool visible = IsToolbarVisible(); 1500 bool visible = IsToolbarVisible();
1527 toolbar_->location_bar()->SetFocusable(visible); 1501 toolbar_->location_bar()->SetFocusable(visible);
1528 int y = top - 1502 int y = top -
1529 ((visible && IsTabStripVisible()) ? kToolbarTabStripVerticalOverlap : 0); 1503 ((visible && IsTabStripVisible()) ? kToolbarTabStripVerticalOverlap : 0);
1530 int height = visible ? toolbar_->GetPreferredSize().height() : 0; 1504 int height = visible ? toolbar_->GetPreferredSize().height() : 0;
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after
1827 #endif 1801 #endif
1828 } 1802 }
1829 1803
1830 void BrowserView::LoadingAnimationCallback() { 1804 void BrowserView::LoadingAnimationCallback() {
1831 if (browser_->type() == Browser::TYPE_NORMAL) { 1805 if (browser_->type() == Browser::TYPE_NORMAL) {
1832 // Loading animations are shown in the tab for tabbed windows. We check the 1806 // Loading animations are shown in the tab for tabbed windows. We check the
1833 // browser type instead of calling IsTabStripVisible() because the latter 1807 // browser type instead of calling IsTabStripVisible() because the latter
1834 // will return false for fullscreen windows, but we still need to update 1808 // will return false for fullscreen windows, but we still need to update
1835 // their animations (so that when they come out of fullscreen mode they'll 1809 // their animations (so that when they come out of fullscreen mode they'll
1836 // be correct). 1810 // be correct).
1837 if (!TabStrip2::Enabled()) 1811 tabstrip_->UpdateLoadingAnimations();
1838 tabstrip_->UpdateLoadingAnimations();
1839 } else if (ShouldShowWindowIcon()) { 1812 } else if (ShouldShowWindowIcon()) {
1840 // ... or in the window icon area for popups and app windows. 1813 // ... or in the window icon area for popups and app windows.
1841 TabContents* tab_contents = browser_->GetSelectedTabContents(); 1814 TabContents* tab_contents = browser_->GetSelectedTabContents();
1842 // GetSelectedTabContents can return NULL for example under Purify when 1815 // GetSelectedTabContents can return NULL for example under Purify when
1843 // the animations are running slowly and this function is called on a timer 1816 // the animations are running slowly and this function is called on a timer
1844 // through LoadingAnimationCallback. 1817 // through LoadingAnimationCallback.
1845 frame_->UpdateThrobber(tab_contents && tab_contents->is_loading()); 1818 frame_->UpdateThrobber(tab_contents && tab_contents->is_loading());
1846 } 1819 }
1847 } 1820 }
1848 1821
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1892 1865
1893 // static 1866 // static
1894 FindBar* BrowserWindow::CreateFindBar(Browser* browser) { 1867 FindBar* BrowserWindow::CreateFindBar(Browser* browser) {
1895 return browser::CreateFindBar(static_cast<BrowserView*>(browser->window())); 1868 return browser::CreateFindBar(static_cast<BrowserView*>(browser->window()));
1896 } 1869 }
1897 1870
1898 // static 1871 // static
1899 void BrowserList::AllBrowsersClosed() { 1872 void BrowserList::AllBrowsersClosed() {
1900 views::Window::CloseAllSecondaryWindows(); 1873 views::Window::CloseAllSecondaryWindows();
1901 } 1874 }
OLDNEW
« no previous file with comments | « chrome/browser/views/frame/browser_view.h ('k') | chrome/browser/views/frame/glass_browser_frame_view.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698