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

Unified Diff: ui/views/view_unittest.cc

Issue 2877483003: Implements core logic for Pixel Canvas (Closed)
Patch Set: nits Created 3 years, 6 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 side-by-side diff with in-line comments
Download patch
« ui/views/view.h ('K') | « ui/views/view.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/views/view_unittest.cc
diff --git a/ui/views/view_unittest.cc b/ui/views/view_unittest.cc
index b4b4bba130c014ae9f21636d5fe701d3c8b49218..61396a84d11342127b342e26855eb2c36da6663e 100644
--- a/ui/views/view_unittest.cc
+++ b/ui/views/view_unittest.cc
@@ -526,8 +526,9 @@ TEST_F(ViewTest, PaintEmptyView) {
// Paint "everything".
gfx::Rect first_paint(1, 1);
- auto list = base::MakeRefCounted<cc::DisplayItemList>();
- root_view->Paint(ui::PaintContext(list.get(), 1.f, first_paint));
+ auto list = make_scoped_refptr(new cc::DisplayItemList);
+ root_view->Paint(
+ ui::PaintContext(list.get(), 1.f, first_paint, first_paint.size()));
// The empty view has nothing to paint so it doesn't try build a cache, nor do
// its children which would be clipped by its (empty) self.
@@ -547,9 +548,9 @@ TEST_F(ViewTest, PaintWithMovedViewUsesCache) {
// invalidation.
gfx::Rect pixel_rect = gfx::Rect(1, 1);
float device_scale_factor = 1.f;
- auto list = base::MakeRefCounted<cc::DisplayItemList>();
- root_view->Paint(
- ui::PaintContext(list.get(), device_scale_factor, pixel_rect));
+ auto list = make_scoped_refptr(new cc::DisplayItemList);
+ root_view->Paint(ui::PaintContext(list.get(), device_scale_factor, pixel_rect,
+ pixel_rect.size()));
EXPECT_TRUE(v1->did_paint_);
v1->Reset();
// The visual rects for (clip, drawing, transform) should be in layer space.
@@ -563,16 +564,16 @@ TEST_F(ViewTest, PaintWithMovedViewUsesCache) {
list->VisualRectForTesting(item_index));
// If invalidation doesn't intersect v1, we paint with the cache.
- list = base::MakeRefCounted<cc::DisplayItemList>();
- root_view->Paint(
- ui::PaintContext(list.get(), device_scale_factor, pixel_rect));
+ list = make_scoped_refptr(new cc::DisplayItemList);
+ root_view->Paint(ui::PaintContext(list.get(), device_scale_factor, pixel_rect,
+ root_view->size()));
EXPECT_FALSE(v1->did_paint_);
v1->Reset();
// If invalidation does intersect v1, we don't paint with the cache.
- list = base::MakeRefCounted<cc::DisplayItemList>();
- root_view->Paint(
- ui::PaintContext(list.get(), device_scale_factor, v1->bounds()));
+ list = make_scoped_refptr(new cc::DisplayItemList);
+ root_view->Paint(ui::PaintContext(list.get(), device_scale_factor,
+ v1->bounds(), root_view->size()));
EXPECT_TRUE(v1->did_paint_);
v1->Reset();
@@ -580,8 +581,8 @@ TEST_F(ViewTest, PaintWithMovedViewUsesCache) {
// intersect v1.
list = base::MakeRefCounted<cc::DisplayItemList>();
v1->SetX(9);
- root_view->Paint(
- ui::PaintContext(list.get(), device_scale_factor, pixel_rect));
+ root_view->Paint(ui::PaintContext(list.get(), device_scale_factor, pixel_rect,
+ root_view->size()));
EXPECT_FALSE(v1->did_paint_);
v1->Reset();
item_index = 3;
@@ -597,9 +598,10 @@ TEST_F(ViewTest, PaintWithMovedViewUsesCache) {
// invalidation.
list = base::MakeRefCounted<cc::DisplayItemList>();
v1->SetX(8);
- root_view->Paint(ui::PaintContext(
- ui::PaintContext(list.get(), device_scale_factor, pixel_rect),
- ui::PaintContext::CLONE_WITHOUT_INVALIDATION));
+ root_view->Paint(
+ ui::PaintContext(ui::PaintContext(list.get(), device_scale_factor,
+ pixel_rect, root_view->size()),
+ ui::PaintContext::CLONE_WITHOUT_INVALIDATION));
EXPECT_TRUE(v1->did_paint_);
v1->Reset();
item_index = 3;
@@ -624,9 +626,9 @@ TEST_F(ViewTest, PaintWithMovedViewUsesCacheInRTL) {
// invalidation.
gfx::Rect pixel_rect = gfx::Rect(1, 1);
float device_scale_factor = 1.f;
- auto list = base::MakeRefCounted<cc::DisplayItemList>();
- root_view->Paint(
- ui::PaintContext(list.get(), device_scale_factor, pixel_rect));
+ auto list = make_scoped_refptr(new cc::DisplayItemList);
+ root_view->Paint(ui::PaintContext(list.get(), device_scale_factor, pixel_rect,
+ root_view->size()));
EXPECT_TRUE(v1->did_paint_);
v1->Reset();
// The visual rects for (clip, drawing, transform) should be in layer space.
@@ -641,16 +643,16 @@ TEST_F(ViewTest, PaintWithMovedViewUsesCacheInRTL) {
list->VisualRectForTesting(item_index));
// If invalidation doesn't intersect v1, we paint with the cache.
- list = base::MakeRefCounted<cc::DisplayItemList>();
- root_view->Paint(
- ui::PaintContext(list.get(), device_scale_factor, pixel_rect));
+ list = make_scoped_refptr(new cc::DisplayItemList);
+ root_view->Paint(ui::PaintContext(list.get(), device_scale_factor, pixel_rect,
+ root_view->size()));
EXPECT_FALSE(v1->did_paint_);
v1->Reset();
// If invalidation does intersect v1, we don't paint with the cache.
- list = base::MakeRefCounted<cc::DisplayItemList>();
- root_view->Paint(
- ui::PaintContext(list.get(), device_scale_factor, v1->bounds()));
+ list = make_scoped_refptr(new cc::DisplayItemList);
+ root_view->Paint(ui::PaintContext(list.get(), device_scale_factor,
+ v1->bounds(), root_view->size()));
EXPECT_TRUE(v1->did_paint_);
v1->Reset();
@@ -658,8 +660,8 @@ TEST_F(ViewTest, PaintWithMovedViewUsesCacheInRTL) {
// intersect v1.
list = base::MakeRefCounted<cc::DisplayItemList>();
v1->SetX(9);
- root_view->Paint(
- ui::PaintContext(list.get(), device_scale_factor, pixel_rect));
+ root_view->Paint(ui::PaintContext(list.get(), device_scale_factor, pixel_rect,
+ root_view->size()));
EXPECT_FALSE(v1->did_paint_);
v1->Reset();
item_index = 3;
@@ -676,9 +678,10 @@ TEST_F(ViewTest, PaintWithMovedViewUsesCacheInRTL) {
// invalidation.
list = base::MakeRefCounted<cc::DisplayItemList>();
v1->SetX(8);
- root_view->Paint(ui::PaintContext(
- ui::PaintContext(list.get(), device_scale_factor, pixel_rect),
- ui::PaintContext::CLONE_WITHOUT_INVALIDATION));
+ root_view->Paint(
+ ui::PaintContext(ui::PaintContext(list.get(), device_scale_factor,
+ pixel_rect, root_view->size()),
+ ui::PaintContext::CLONE_WITHOUT_INVALIDATION));
EXPECT_TRUE(v1->did_paint_);
v1->Reset();
item_index = 3;
@@ -707,8 +710,9 @@ TEST_F(ViewTest, PaintWithUnknownInvalidation) {
// Paint everything once, since it has to build its cache. Then we can test
// invalidation.
gfx::Rect first_paint(1, 1);
- auto list = base::MakeRefCounted<cc::DisplayItemList>();
- root_view->Paint(ui::PaintContext(list.get(), 1.f, first_paint));
+ auto list = make_scoped_refptr(new cc::DisplayItemList);
+ root_view->Paint(
+ ui::PaintContext(list.get(), 1.f, first_paint, root_view->size()));
v1->Reset();
v2->Reset();
@@ -719,14 +723,15 @@ TEST_F(ViewTest, PaintWithUnknownInvalidation) {
// With a known invalidation, v1 and v2 are not painted.
EXPECT_FALSE(v1->did_paint_);
EXPECT_FALSE(v2->did_paint_);
- root_view->Paint(ui::PaintContext(list.get(), 1.f, paint_area));
+ root_view->Paint(
+ ui::PaintContext(list.get(), 1.f, paint_area, root_view->size()));
EXPECT_FALSE(v1->did_paint_);
EXPECT_FALSE(v2->did_paint_);
// With unknown invalidation, v1 and v2 are painted.
- root_view->Paint(
- ui::PaintContext(ui::PaintContext(list.get(), 1.f, paint_area),
- ui::PaintContext::CLONE_WITHOUT_INVALIDATION));
+ root_view->Paint(ui::PaintContext(
+ ui::PaintContext(list.get(), 1.f, paint_area, root_view->size()),
+ ui::PaintContext::CLONE_WITHOUT_INVALIDATION));
EXPECT_TRUE(v1->did_paint_);
EXPECT_TRUE(v2->did_paint_);
}
@@ -746,8 +751,9 @@ TEST_F(ViewTest, PaintContainsChildren) {
// Paint everything once, since it has to build its cache. Then we can test
// invalidation.
gfx::Rect first_paint(1, 1);
- auto list = base::MakeRefCounted<cc::DisplayItemList>();
- root_view->Paint(ui::PaintContext(list.get(), 1.f, first_paint));
+ auto list = make_scoped_refptr(new cc::DisplayItemList);
+ root_view->Paint(
+ ui::PaintContext(list.get(), 1.f, first_paint, root_view->size()));
v1->Reset();
v2->Reset();
@@ -757,7 +763,8 @@ TEST_F(ViewTest, PaintContainsChildren) {
EXPECT_FALSE(v1->did_paint_);
EXPECT_FALSE(v2->did_paint_);
- root_view->Paint(ui::PaintContext(list.get(), 1.f, paint_area));
+ root_view->Paint(
+ ui::PaintContext(list.get(), 1.f, paint_area, root_view->size()));
EXPECT_TRUE(v1->did_paint_);
EXPECT_TRUE(v2->did_paint_);
}
@@ -789,8 +796,9 @@ TEST_F(ViewTest, PaintContainsChildrenInRTL) {
// Paint everything once, since it has to build its cache. Then we can test
// invalidation.
gfx::Rect first_paint(1, 1);
- auto list = base::MakeRefCounted<cc::DisplayItemList>();
- root_view->Paint(ui::PaintContext(list.get(), 1.f, first_paint));
+ auto list = make_scoped_refptr(new cc::DisplayItemList);
+ root_view->Paint(
+ ui::PaintContext(list.get(), 1.f, first_paint, root_view->size()));
v1->Reset();
v2->Reset();
@@ -800,7 +808,8 @@ TEST_F(ViewTest, PaintContainsChildrenInRTL) {
EXPECT_FALSE(v1->did_paint_);
EXPECT_FALSE(v2->did_paint_);
- root_view->Paint(ui::PaintContext(list.get(), 1.f, paint_area));
+ root_view->Paint(
+ ui::PaintContext(list.get(), 1.f, paint_area, root_view->size()));
EXPECT_TRUE(v1->did_paint_);
EXPECT_TRUE(v2->did_paint_);
}
@@ -820,8 +829,9 @@ TEST_F(ViewTest, PaintIntersectsChildren) {
// Paint everything once, since it has to build its cache. Then we can test
// invalidation.
gfx::Rect first_paint(1, 1);
- auto list = base::MakeRefCounted<cc::DisplayItemList>();
- root_view->Paint(ui::PaintContext(list.get(), 1.f, first_paint));
+ auto list = make_scoped_refptr(new cc::DisplayItemList);
+ root_view->Paint(
+ ui::PaintContext(list.get(), 1.f, first_paint, root_view->size()));
v1->Reset();
v2->Reset();
@@ -831,7 +841,8 @@ TEST_F(ViewTest, PaintIntersectsChildren) {
EXPECT_FALSE(v1->did_paint_);
EXPECT_FALSE(v2->did_paint_);
- root_view->Paint(ui::PaintContext(list.get(), 1.f, paint_area));
+ root_view->Paint(
+ ui::PaintContext(list.get(), 1.f, paint_area, root_view->size()));
EXPECT_TRUE(v1->did_paint_);
EXPECT_TRUE(v2->did_paint_);
}
@@ -863,8 +874,9 @@ TEST_F(ViewTest, PaintIntersectsChildrenInRTL) {
// Paint everything once, since it has to build its cache. Then we can test
// invalidation.
gfx::Rect first_paint(1, 1);
- auto list = base::MakeRefCounted<cc::DisplayItemList>();
- root_view->Paint(ui::PaintContext(list.get(), 1.f, first_paint));
+ auto list = make_scoped_refptr(new cc::DisplayItemList);
+ root_view->Paint(
+ ui::PaintContext(list.get(), 1.f, first_paint, root_view->size()));
v1->Reset();
v2->Reset();
@@ -874,7 +886,8 @@ TEST_F(ViewTest, PaintIntersectsChildrenInRTL) {
EXPECT_FALSE(v1->did_paint_);
EXPECT_FALSE(v2->did_paint_);
- root_view->Paint(ui::PaintContext(list.get(), 1.f, paint_area));
+ root_view->Paint(
+ ui::PaintContext(list.get(), 1.f, paint_area, root_view->size()));
EXPECT_TRUE(v1->did_paint_);
EXPECT_TRUE(v2->did_paint_);
}
@@ -894,8 +907,9 @@ TEST_F(ViewTest, PaintIntersectsChildButNotGrandChild) {
// Paint everything once, since it has to build its cache. Then we can test
// invalidation.
gfx::Rect first_paint(1, 1);
- auto list = base::MakeRefCounted<cc::DisplayItemList>();
- root_view->Paint(ui::PaintContext(list.get(), 1.f, first_paint));
+ auto list = make_scoped_refptr(new cc::DisplayItemList);
+ root_view->Paint(
+ ui::PaintContext(list.get(), 1.f, first_paint, root_view->size()));
v1->Reset();
v2->Reset();
@@ -905,7 +919,8 @@ TEST_F(ViewTest, PaintIntersectsChildButNotGrandChild) {
EXPECT_FALSE(v1->did_paint_);
EXPECT_FALSE(v2->did_paint_);
- root_view->Paint(ui::PaintContext(list.get(), 1.f, paint_area));
+ root_view->Paint(
+ ui::PaintContext(list.get(), 1.f, paint_area, root_view->size()));
EXPECT_TRUE(v1->did_paint_);
EXPECT_FALSE(v2->did_paint_);
}
@@ -937,8 +952,9 @@ TEST_F(ViewTest, PaintIntersectsChildButNotGrandChildInRTL) {
// Paint everything once, since it has to build its cache. Then we can test
// invalidation.
gfx::Rect first_paint(1, 1);
- auto list = base::MakeRefCounted<cc::DisplayItemList>();
- root_view->Paint(ui::PaintContext(list.get(), 1.f, first_paint));
+ auto list = make_scoped_refptr(new cc::DisplayItemList);
+ root_view->Paint(
+ ui::PaintContext(list.get(), 1.f, first_paint, root_view->size()));
v1->Reset();
v2->Reset();
@@ -948,7 +964,8 @@ TEST_F(ViewTest, PaintIntersectsChildButNotGrandChildInRTL) {
EXPECT_FALSE(v1->did_paint_);
EXPECT_FALSE(v2->did_paint_);
- root_view->Paint(ui::PaintContext(list.get(), 1.f, paint_area));
+ root_view->Paint(
+ ui::PaintContext(list.get(), 1.f, paint_area, root_view->size()));
EXPECT_TRUE(v1->did_paint_);
EXPECT_FALSE(v2->did_paint_);
}
@@ -968,8 +985,9 @@ TEST_F(ViewTest, PaintIntersectsNoChildren) {
// Paint everything once, since it has to build its cache. Then we can test
// invalidation.
gfx::Rect first_paint(1, 1);
- auto list = base::MakeRefCounted<cc::DisplayItemList>();
- root_view->Paint(ui::PaintContext(list.get(), 1.f, first_paint));
+ auto list = make_scoped_refptr(new cc::DisplayItemList);
+ root_view->Paint(
+ ui::PaintContext(list.get(), 1.f, first_paint, root_view->size()));
v1->Reset();
v2->Reset();
@@ -979,7 +997,8 @@ TEST_F(ViewTest, PaintIntersectsNoChildren) {
EXPECT_FALSE(v1->did_paint_);
EXPECT_FALSE(v2->did_paint_);
- root_view->Paint(ui::PaintContext(list.get(), 1.f, paint_area));
+ root_view->Paint(
+ ui::PaintContext(list.get(), 1.f, paint_area, root_view->size()));
EXPECT_FALSE(v1->did_paint_);
EXPECT_FALSE(v2->did_paint_);
}
@@ -1011,8 +1030,9 @@ TEST_F(ViewTest, PaintIntersectsNoChildrenInRTL) {
// Paint everything once, since it has to build its cache. Then we can test
// invalidation.
gfx::Rect first_paint(1, 1);
- auto list = base::MakeRefCounted<cc::DisplayItemList>();
- root_view->Paint(ui::PaintContext(list.get(), 1.f, first_paint));
+ auto list = make_scoped_refptr(new cc::DisplayItemList);
+ root_view->Paint(
+ ui::PaintContext(list.get(), 1.f, first_paint, root_view->size()));
v1->Reset();
v2->Reset();
@@ -1022,7 +1042,8 @@ TEST_F(ViewTest, PaintIntersectsNoChildrenInRTL) {
EXPECT_FALSE(v1->did_paint_);
EXPECT_FALSE(v2->did_paint_);
- root_view->Paint(ui::PaintContext(list.get(), 1.f, paint_area));
+ root_view->Paint(
+ ui::PaintContext(list.get(), 1.f, paint_area, root_view->size()));
EXPECT_FALSE(v1->did_paint_);
EXPECT_FALSE(v2->did_paint_);
}
@@ -1042,8 +1063,9 @@ TEST_F(ViewTest, PaintIntersectsOneChild) {
// Paint everything once, since it has to build its cache. Then we can test
// invalidation.
gfx::Rect first_paint(1, 1);
- auto list = base::MakeRefCounted<cc::DisplayItemList>();
- root_view->Paint(ui::PaintContext(list.get(), 1.f, first_paint));
+ auto list = make_scoped_refptr(new cc::DisplayItemList);
+ root_view->Paint(
+ ui::PaintContext(list.get(), 1.f, first_paint, root_view->size()));
v1->Reset();
v2->Reset();
@@ -1054,7 +1076,8 @@ TEST_F(ViewTest, PaintIntersectsOneChild) {
EXPECT_FALSE(v1->did_paint_);
EXPECT_FALSE(v2->did_paint_);
- root_view->Paint(ui::PaintContext(list.get(), 1.f, paint_area));
+ root_view->Paint(
+ ui::PaintContext(list.get(), 1.f, paint_area, root_view->size()));
EXPECT_FALSE(v1->did_paint_);
EXPECT_TRUE(v2->did_paint_);
@@ -1065,7 +1088,8 @@ TEST_F(ViewTest, PaintIntersectsOneChild) {
v2->Reset();
EXPECT_FALSE(v1->did_paint_);
EXPECT_FALSE(v2->did_paint_);
- root_view->Paint(ui::PaintContext(list.get(), 1.f, paint_area));
+ root_view->Paint(
+ ui::PaintContext(list.get(), 1.f, paint_area, root_view->size()));
EXPECT_TRUE(v1->did_paint_);
EXPECT_FALSE(v2->did_paint_);
}
@@ -1097,8 +1121,9 @@ TEST_F(ViewTest, PaintIntersectsOneChildInRTL) {
// Paint everything once, since it has to build its cache. Then we can test
// invalidation.
gfx::Rect first_paint(1, 1);
- auto list = base::MakeRefCounted<cc::DisplayItemList>();
- root_view->Paint(ui::PaintContext(list.get(), 1.f, first_paint));
+ auto list = make_scoped_refptr(new cc::DisplayItemList);
+ root_view->Paint(
+ ui::PaintContext(list.get(), 1.f, first_paint, root_view->size()));
v1->Reset();
v2->Reset();
@@ -1109,7 +1134,8 @@ TEST_F(ViewTest, PaintIntersectsOneChildInRTL) {
EXPECT_FALSE(v1->did_paint_);
EXPECT_FALSE(v2->did_paint_);
- root_view->Paint(ui::PaintContext(list.get(), 1.f, paint_area));
+ root_view->Paint(
+ ui::PaintContext(list.get(), 1.f, paint_area, root_view->size()));
EXPECT_TRUE(v1->did_paint_);
EXPECT_FALSE(v2->did_paint_);
@@ -1120,7 +1146,8 @@ TEST_F(ViewTest, PaintIntersectsOneChildInRTL) {
v2->Reset();
EXPECT_FALSE(v1->did_paint_);
EXPECT_FALSE(v2->did_paint_);
- root_view->Paint(ui::PaintContext(list.get(), 1.f, paint_area));
+ root_view->Paint(
+ ui::PaintContext(list.get(), 1.f, paint_area, root_view->size()));
EXPECT_FALSE(v1->did_paint_);
EXPECT_TRUE(v2->did_paint_);
}
@@ -1141,8 +1168,8 @@ TEST_F(ViewTest, PaintInPromotedToLayer) {
// Paint everything once, since it has to build its cache. Then we can test
// invalidation.
gfx::Rect first_paint(1, 1);
- auto list = base::MakeRefCounted<cc::DisplayItemList>();
- v1->Paint(ui::PaintContext(list.get(), 1.f, first_paint));
+ auto list = make_scoped_refptr(new cc::DisplayItemList);
+ v1->Paint(ui::PaintContext(list.get(), 1.f, first_paint, v1->size()));
v1->Reset();
v2->Reset();
@@ -1152,7 +1179,8 @@ TEST_F(ViewTest, PaintInPromotedToLayer) {
auto list = base::MakeRefCounted<cc::DisplayItemList>();
// The promoted views are not painted as they are separate paint roots.
- root_view->Paint(ui::PaintContext(list.get(), 1.f, paint_area));
+ root_view->Paint(
+ ui::PaintContext(list.get(), 1.f, paint_area, root_view->size()));
EXPECT_FALSE(v1->did_paint_);
EXPECT_FALSE(v2->did_paint_);
}
@@ -1164,7 +1192,7 @@ TEST_F(ViewTest, PaintInPromotedToLayer) {
// The |v1| view is painted. If it used its offset incorrect, it would think
// its at (10,11) instead of at (0,0) since it is the paint root.
- v1->Paint(ui::PaintContext(list.get(), 1.f, paint_area));
+ v1->Paint(ui::PaintContext(list.get(), 1.f, paint_area, v1->size()));
EXPECT_TRUE(v1->did_paint_);
EXPECT_FALSE(v2->did_paint_);
}
@@ -1178,7 +1206,7 @@ TEST_F(ViewTest, PaintInPromotedToLayer) {
// The |v2| view is painted also. If it used its offset incorrect, it would
// think its at (13,15) instead of at (3,4) since |v1| is the paint root.
- v1->Paint(ui::PaintContext(list.get(), 1.f, paint_area));
+ v1->Paint(ui::PaintContext(list.get(), 1.f, paint_area, v1->size()));
EXPECT_TRUE(v1->did_paint_);
EXPECT_TRUE(v2->did_paint_);
}
@@ -1220,8 +1248,8 @@ TEST_F(ViewTest, PaintLocalBounds) {
EXPECT_EQ(gfx::Rect(0, 0, 100, 1100), v1->GetLocalBounds());
EXPECT_EQ(gfx::Rect(0, 1000, 100, 100), v1->GetVisibleBounds());
- auto list = base::MakeRefCounted<cc::DisplayItemList>();
- ui::PaintContext context(list.get(), 1.f, gfx::Rect());
+ auto list = make_scoped_refptr(new cc::DisplayItemList);
+ ui::PaintContext context(list.get(), 1.f, gfx::Rect(), gfx::Size());
v1->Paint(context);
EXPECT_TRUE(v1->did_paint_);
« ui/views/view.h ('K') | « ui/views/view.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698