| 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 "chrome/browser/ui/views/tabs/tab.h" |    5 #include "chrome/browser/ui/views/tabs/tab.h" | 
|    6  |    6  | 
|    7 #include "base/i18n/rtl.h" |    7 #include "base/i18n/rtl.h" | 
|    8 #include "base/strings/utf_string_conversions.h" |    8 #include "base/strings/utf_string_conversions.h" | 
|    9 #include "chrome/browser/ui/tabs/tab_utils.h" |    9 #include "chrome/browser/ui/tabs/tab_utils.h" | 
|   10 #include "chrome/browser/ui/views/tabs/media_indicator_button.h" |   10 #include "chrome/browser/ui/views/tabs/media_indicator_button.h" | 
|   11 #include "chrome/browser/ui/views/tabs/tab_controller.h" |   11 #include "chrome/browser/ui/views/tabs/tab_controller.h" | 
|   12 #include "testing/gtest/include/gtest/gtest.h" |   12 #include "testing/gtest/include/gtest/gtest.h" | 
|   13 #include "ui/base/models/list_selection_model.h" |   13 #include "ui/base/models/list_selection_model.h" | 
|   14 #include "ui/views/controls/button/image_button.h" |   14 #include "ui/views/controls/button/image_button.h" | 
|   15 #include "ui/views/controls/label.h" |   15 #include "ui/views/controls/label.h" | 
|   16 #include "ui/views/test/views_test_base.h" |   16 #include "ui/views/test/views_test_base.h" | 
|   17 #include "ui/views/widget/widget.h" |   17 #include "ui/views/widget/widget.h" | 
|   18  |   18  | 
|   19 using views::Widget; |   19 using views::Widget; | 
|   20  |   20  | 
|   21 class FakeTabController : public TabController { |   21 class FakeTabController : public TabController { | 
|   22  public: |   22  public: | 
|   23   FakeTabController() : immersive_style_(false), active_tab_(false) { |   23   FakeTabController() {} | 
|   24   } |  | 
|   25   ~FakeTabController() override {} |  | 
|   26  |   24  | 
|   27   void set_immersive_style(bool value) { immersive_style_ = value; } |   25   void set_immersive_style(bool value) { immersive_style_ = value; } | 
|   28   void set_active_tab(bool value) { active_tab_ = value; } |   26   void set_active_tab(bool value) { active_tab_ = value; } | 
 |   27   void set_paint_throbber_to_layer(bool value) { | 
 |   28     paint_throbber_to_layer_ = value; | 
 |   29   } | 
|   29  |   30  | 
|   30   const ui::ListSelectionModel& GetSelectionModel() override { |   31   const ui::ListSelectionModel& GetSelectionModel() override { | 
|   31     return selection_model_; |   32     return selection_model_; | 
|   32   } |   33   } | 
|   33   bool SupportsMultipleSelection() override { return false; } |   34   bool SupportsMultipleSelection() override { return false; } | 
|   34   bool ShouldHideCloseButtonForInactiveTabs() override { |   35   bool ShouldHideCloseButtonForInactiveTabs() override { | 
|   35     return false; |   36     return false; | 
|   36   } |   37   } | 
|   37   void SelectTab(Tab* tab) override {} |   38   void SelectTab(Tab* tab) override {} | 
|   38   void ExtendSelectionTo(Tab* tab) override {} |   39   void ExtendSelectionTo(Tab* tab) override {} | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
|   52       const ui::ListSelectionModel& original_selection) override {} |   53       const ui::ListSelectionModel& original_selection) override {} | 
|   53   void ContinueDrag(views::View* view, const ui::LocatedEvent& event) override { |   54   void ContinueDrag(views::View* view, const ui::LocatedEvent& event) override { | 
|   54   } |   55   } | 
|   55   bool EndDrag(EndDragReason reason) override { return false; } |   56   bool EndDrag(EndDragReason reason) override { return false; } | 
|   56   Tab* GetTabAt(Tab* tab, const gfx::Point& tab_in_tab_coordinates) override { |   57   Tab* GetTabAt(Tab* tab, const gfx::Point& tab_in_tab_coordinates) override { | 
|   57     return NULL; |   58     return NULL; | 
|   58   } |   59   } | 
|   59   void OnMouseEventInTab(views::View* source, |   60   void OnMouseEventInTab(views::View* source, | 
|   60                          const ui::MouseEvent& event) override {} |   61                          const ui::MouseEvent& event) override {} | 
|   61   bool ShouldPaintTab(const Tab* tab, gfx::Rect* clip) override { return true; } |   62   bool ShouldPaintTab(const Tab* tab, gfx::Rect* clip) override { return true; } | 
 |   63   bool CanPaintThrobberToLayer() const override { | 
 |   64     return paint_throbber_to_layer_; | 
 |   65   } | 
|   62   bool IsImmersiveStyle() const override { return immersive_style_; } |   66   bool IsImmersiveStyle() const override { return immersive_style_; } | 
|   63   void UpdateTabAccessibilityState(const Tab* tab, |   67   void UpdateTabAccessibilityState(const Tab* tab, | 
|   64                                    ui::AXViewState* state) override{}; |   68                                    ui::AXViewState* state) override{}; | 
|   65  |   69  | 
|   66  private: |   70  private: | 
|   67   ui::ListSelectionModel selection_model_; |   71   ui::ListSelectionModel selection_model_; | 
|   68   bool immersive_style_; |   72   bool immersive_style_ = false; | 
|   69   bool active_tab_; |   73   bool active_tab_ = false; | 
 |   74   bool paint_throbber_to_layer_ = true; | 
|   70  |   75  | 
|   71   DISALLOW_COPY_AND_ASSIGN(FakeTabController); |   76   DISALLOW_COPY_AND_ASSIGN(FakeTabController); | 
|   72 }; |   77 }; | 
|   73  |   78  | 
|   74 class TabTest : public views::ViewsTestBase, |   79 class TabTest : public views::ViewsTestBase, | 
|   75                 public ::testing::WithParamInterface<bool> { |   80                 public ::testing::WithParamInterface<bool> { | 
|   76  public: |   81  public: | 
|   77   TabTest() {} |   82   TabTest() {} | 
|   78   virtual ~TabTest() {} |   83   virtual ~TabTest() {} | 
|   79  |   84  | 
|   80   bool testing_for_rtl_locale() const { return GetParam(); } |   85   bool testing_for_rtl_locale() const { return GetParam(); } | 
|   81  |   86  | 
|   82   void SetUp() override { |   87   void SetUp() override { | 
|   83     if (testing_for_rtl_locale()) { |   88     if (testing_for_rtl_locale()) { | 
|   84       original_locale_ = base::i18n::GetConfiguredLocale(); |   89       original_locale_ = base::i18n::GetConfiguredLocale(); | 
|   85       base::i18n::SetICUDefaultLocale("he"); |   90       base::i18n::SetICUDefaultLocale("he"); | 
|   86     } |   91     } | 
|   87     views::ViewsTestBase::SetUp(); |   92     views::ViewsTestBase::SetUp(); | 
|   88   } |   93   } | 
|   89  |   94  | 
|   90   void TearDown() override { |   95   void TearDown() override { | 
|   91     views::ViewsTestBase::TearDown(); |   96     views::ViewsTestBase::TearDown(); | 
|   92     if (testing_for_rtl_locale()) |   97     if (testing_for_rtl_locale()) | 
|   93       base::i18n::SetICUDefaultLocale(original_locale_); |   98       base::i18n::SetICUDefaultLocale(original_locale_); | 
|   94   } |   99   } | 
|   95  |  100  | 
 |  101   static views::ImageButton* GetCloseButton(const Tab& tab) { | 
 |  102     return tab.close_button_; | 
 |  103   } | 
 |  104  | 
 |  105   static views::View* GetThrobberView(const Tab& tab) { | 
 |  106     // Reinterpret to keep the definition encapsulated (which works so long as | 
 |  107     // multiple inheritance isn't involved). | 
 |  108     return reinterpret_cast<views::View*>(tab.throbber_); | 
 |  109   } | 
 |  110  | 
 |  111   static gfx::Rect GetFaviconBounds(const Tab& tab) { | 
 |  112     return tab.favicon_bounds_; | 
 |  113   } | 
 |  114  | 
 |  115   static void LayoutTab(Tab* tab) { tab->Layout(); } | 
 |  116  | 
|   96   static void CheckForExpectedLayoutAndVisibilityOfElements(const Tab& tab) { |  117   static void CheckForExpectedLayoutAndVisibilityOfElements(const Tab& tab) { | 
|   97     // Check whether elements are visible when they are supposed to be, given |  118     // Check whether elements are visible when they are supposed to be, given | 
|   98     // Tab size and TabRendererData state. |  119     // Tab size and TabRendererData state. | 
|   99     if (tab.data_.pinned) { |  120     if (tab.data_.pinned) { | 
|  100       EXPECT_EQ(1, tab.IconCapacity()); |  121       EXPECT_EQ(1, tab.IconCapacity()); | 
|  101       if (tab.data_.media_state != TAB_MEDIA_STATE_NONE) { |  122       if (tab.data_.media_state != TAB_MEDIA_STATE_NONE) { | 
|  102         EXPECT_FALSE(tab.ShouldShowIcon()); |  123         EXPECT_FALSE(tab.ShouldShowIcon()); | 
|  103         EXPECT_TRUE(tab.ShouldShowMediaIndicator()); |  124         EXPECT_TRUE(tab.ShouldShowMediaIndicator()); | 
|  104       } else { |  125       } else { | 
|  105         EXPECT_TRUE(tab.ShouldShowIcon()); |  126         EXPECT_TRUE(tab.ShouldShowIcon()); | 
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  380 // shouldn't change the insets of the close button. |  401 // shouldn't change the insets of the close button. | 
|  381 TEST_P(TabTest, CloseButtonLayout) { |  402 TEST_P(TabTest, CloseButtonLayout) { | 
|  382   if (testing_for_rtl_locale() && !base::i18n::IsRTL()) { |  403   if (testing_for_rtl_locale() && !base::i18n::IsRTL()) { | 
|  383     LOG(WARNING) << "Testing of RTL locale not supported on current platform."; |  404     LOG(WARNING) << "Testing of RTL locale not supported on current platform."; | 
|  384     return; |  405     return; | 
|  385   } |  406   } | 
|  386  |  407  | 
|  387   FakeTabController tab_controller; |  408   FakeTabController tab_controller; | 
|  388   Tab tab(&tab_controller); |  409   Tab tab(&tab_controller); | 
|  389   tab.SetBounds(0, 0, 100, 50); |  410   tab.SetBounds(0, 0, 100, 50); | 
|  390   tab.Layout(); |  411   LayoutTab(&tab); | 
|  391   gfx::Insets close_button_insets = tab.close_button_->GetInsets(); |  412   gfx::Insets close_button_insets = GetCloseButton(tab)->GetInsets(); | 
|  392   tab.Layout(); |  413   LayoutTab(&tab); | 
|  393   gfx::Insets close_button_insets_2 = tab.close_button_->GetInsets(); |  414   gfx::Insets close_button_insets_2 = GetCloseButton(tab)->GetInsets(); | 
|  394   EXPECT_EQ(close_button_insets.top(), close_button_insets_2.top()); |  415   EXPECT_EQ(close_button_insets.top(), close_button_insets_2.top()); | 
|  395   EXPECT_EQ(close_button_insets.left(), close_button_insets_2.left()); |  416   EXPECT_EQ(close_button_insets.left(), close_button_insets_2.left()); | 
|  396   EXPECT_EQ(close_button_insets.bottom(), close_button_insets_2.bottom()); |  417   EXPECT_EQ(close_button_insets.bottom(), close_button_insets_2.bottom()); | 
|  397   EXPECT_EQ(close_button_insets.right(), close_button_insets_2.right()); |  418   EXPECT_EQ(close_button_insets.right(), close_button_insets_2.right()); | 
|  398  |  419  | 
|  399   // Also make sure the close button is sized as large as the tab. |  420   // Also make sure the close button is sized as large as the tab. | 
|  400   EXPECT_EQ(50, tab.close_button_->bounds().height()); |  421   EXPECT_EQ(50, GetCloseButton(tab)->bounds().height()); | 
 |  422 } | 
 |  423  | 
 |  424 // Tests expected changes to the ThrobberView state when the WebContents loading | 
 |  425 // state changes or the animation timer (usually in BrowserView) triggers. | 
 |  426 TEST_P(TabTest, LayeredThrobber) { | 
 |  427   if (testing_for_rtl_locale() && !base::i18n::IsRTL()) { | 
 |  428     LOG(WARNING) << "Testing of RTL locale not supported on current platform."; | 
 |  429     return; | 
 |  430   } | 
 |  431  | 
 |  432   Widget widget; | 
 |  433   InitWidget(&widget); | 
 |  434  | 
 |  435   FakeTabController tab_controller; | 
 |  436   Tab tab(&tab_controller); | 
 |  437   widget.GetContentsView()->AddChildView(&tab); | 
 |  438   tab.SetBoundsRect(gfx::Rect(Tab::GetStandardSize())); | 
 |  439  | 
 |  440   views::View* throbber = GetThrobberView(tab); | 
 |  441   EXPECT_FALSE(throbber->visible()); | 
 |  442   EXPECT_EQ(TabRendererData::NETWORK_STATE_NONE, tab.data().network_state); | 
 |  443   EXPECT_EQ(throbber->bounds(), GetFaviconBounds(tab)); | 
 |  444  | 
 |  445   tab.UpdateLoadingAnimation(TabRendererData::NETWORK_STATE_NONE); | 
 |  446   EXPECT_FALSE(throbber->visible()); | 
 |  447  | 
 |  448   // Simulate a "normal" tab load: should paint to a layer. | 
 |  449   tab.UpdateLoadingAnimation(TabRendererData::NETWORK_STATE_WAITING); | 
 |  450   EXPECT_TRUE(tab_controller.CanPaintThrobberToLayer()); | 
 |  451   EXPECT_TRUE(throbber->visible()); | 
 |  452   EXPECT_TRUE(throbber->layer()); | 
 |  453   tab.UpdateLoadingAnimation(TabRendererData::NETWORK_STATE_LOADING); | 
 |  454   EXPECT_TRUE(throbber->visible()); | 
 |  455   EXPECT_TRUE(throbber->layer()); | 
 |  456   tab.UpdateLoadingAnimation(TabRendererData::NETWORK_STATE_NONE); | 
 |  457   EXPECT_FALSE(throbber->visible()); | 
 |  458  | 
 |  459   // Simulate a drag started and stopped during a load: layer painting stops | 
 |  460   // temporarily. | 
 |  461   tab.UpdateLoadingAnimation(TabRendererData::NETWORK_STATE_WAITING); | 
 |  462   EXPECT_TRUE(throbber->visible()); | 
 |  463   EXPECT_TRUE(throbber->layer()); | 
 |  464   tab_controller.set_paint_throbber_to_layer(false); | 
 |  465   tab.UpdateLoadingAnimation(TabRendererData::NETWORK_STATE_WAITING); | 
 |  466   EXPECT_TRUE(throbber->visible()); | 
 |  467   EXPECT_FALSE(throbber->layer()); | 
 |  468   tab_controller.set_paint_throbber_to_layer(true); | 
 |  469   tab.UpdateLoadingAnimation(TabRendererData::NETWORK_STATE_WAITING); | 
 |  470   EXPECT_TRUE(throbber->visible()); | 
 |  471   EXPECT_TRUE(throbber->layer()); | 
 |  472   tab.UpdateLoadingAnimation(TabRendererData::NETWORK_STATE_NONE); | 
 |  473   EXPECT_FALSE(throbber->visible()); | 
 |  474  | 
 |  475   // Simulate a tab load starting and stopping during tab dragging (or with | 
 |  476   // stacked tabs): no layer painting. | 
 |  477   tab_controller.set_paint_throbber_to_layer(false); | 
 |  478   tab.UpdateLoadingAnimation(TabRendererData::NETWORK_STATE_WAITING); | 
 |  479   EXPECT_TRUE(throbber->visible()); | 
 |  480   EXPECT_FALSE(throbber->layer()); | 
 |  481   tab.UpdateLoadingAnimation(TabRendererData::NETWORK_STATE_NONE); | 
 |  482   EXPECT_FALSE(throbber->visible()); | 
|  401 } |  483 } | 
|  402  |  484  | 
|  403 // Test in both a LTR and a RTL locale.  Note: The fact that the UI code is |  485 // Test in both a LTR and a RTL locale.  Note: The fact that the UI code is | 
|  404 // configured for an RTL locale does *not* change how the coordinates are |  486 // configured for an RTL locale does *not* change how the coordinates are | 
|  405 // examined in the tests above because views::View and friends are supposed to |  487 // examined in the tests above because views::View and friends are supposed to | 
|  406 // auto-mirror the widgets when painting.  Thus, what we're testing here is that |  488 // auto-mirror the widgets when painting.  Thus, what we're testing here is that | 
|  407 // there's no code in Tab that will erroneously subvert this automatic |  489 // there's no code in Tab that will erroneously subvert this automatic | 
|  408 // coordinate translation.  http://crbug.com/384179 |  490 // coordinate translation.  http://crbug.com/384179 | 
|  409 INSTANTIATE_TEST_CASE_P(, TabTest, ::testing::Values(false, true)); |  491 INSTANTIATE_TEST_CASE_P(, TabTest, ::testing::Values(false, true)); | 
| OLD | NEW |