| Index: chrome/browser/ui/views/tabs/tab.cc
|
| diff --git a/chrome/browser/ui/views/tabs/tab.cc b/chrome/browser/ui/views/tabs/tab.cc
|
| index 4e894358c45078d50ad84550318e0cc457fed2ce..f536b591234df62fdf34c04de7d59cfb1addd0bf 100644
|
| --- a/chrome/browser/ui/views/tabs/tab.cc
|
| +++ b/chrome/browser/ui/views/tabs/tab.cc
|
| @@ -494,7 +494,8 @@ bool Tab::ThrobberView::CanProcessEventsWithinSubtree() const {
|
|
|
| void Tab::ThrobberView::OnPaint(gfx::Canvas* canvas) {
|
| const TabRendererData::NetworkState state = owner_->data().network_state;
|
| - if (state == TabRendererData::NETWORK_STATE_NONE)
|
| + if (state == TabRendererData::NETWORK_STATE_NONE ||
|
| + state == TabRendererData::NETWORK_STATE_ERROR)
|
| return;
|
|
|
| const ui::ThemeProvider* tp = GetThemeProvider();
|
| @@ -674,9 +675,10 @@ void Tab::SetData(const TabRendererData& data) {
|
|
|
| void Tab::UpdateLoadingAnimation(TabRendererData::NetworkState state) {
|
| if (state == data_.network_state &&
|
| - state == TabRendererData::NETWORK_STATE_NONE) {
|
| - // If the network state is none and hasn't changed, do nothing. Otherwise we
|
| - // need to advance the animation frame.
|
| + (state == TabRendererData::NETWORK_STATE_NONE ||
|
| + state == TabRendererData::NETWORK_STATE_ERROR)) {
|
| + // If the network state is none or is a network error and hasn't changed,
|
| + // do nothing. Otherwise we need to advance the animation frame.
|
| return;
|
| }
|
|
|
| @@ -764,6 +766,58 @@ float Tab::GetInverseDiagonalSlope() {
|
| (GetMinimumInactiveSize().height() - 4);
|
| }
|
|
|
| +base::string16 Tab::GetAccessibleTabLabel() {
|
| + base::string16 tab_label;
|
| +
|
| + if (data_.IsCrashed()) {
|
| + // Tab has crashed.
|
| + tab_label = l10n_util::GetStringFUTF16(IDS_TAB_AX_LABEL_CRASHED_FORMAT,
|
| + data_.title);
|
| + } else if (data_.network_state == TabRendererData::NETWORK_STATE_ERROR) {
|
| + // Network error interstitial.
|
| + tab_label = l10n_util::GetStringFUTF16(
|
| + IDS_TAB_AX_LABEL_NETWORK_ERROR_FORMAT, data_.title);
|
| + } else {
|
| + // Alert tab states.
|
| + switch (data_.alert_state) {
|
| + case TabAlertState::AUDIO_PLAYING:
|
| + tab_label = l10n_util::GetStringFUTF16(
|
| + IDS_TAB_AX_LABEL_AUDIO_PLAYING_FORMAT, data_.title);
|
| + break;
|
| + case TabAlertState::USB_CONNECTED:
|
| + tab_label = l10n_util::GetStringFUTF16(
|
| + IDS_TAB_AX_LABEL_USB_CONNECTED_FORMAT, data_.title);
|
| + break;
|
| + case TabAlertState::BLUETOOTH_CONNECTED:
|
| + tab_label = l10n_util::GetStringFUTF16(
|
| + IDS_TAB_AX_LABEL_BLUETOOTH_CONNECTED_FORMAT, data_.title);
|
| + break;
|
| + case TabAlertState::MEDIA_RECORDING:
|
| + tab_label = l10n_util::GetStringFUTF16(
|
| + IDS_TAB_AX_LABEL_MEDIA_RECORDING_FORMAT, data_.title);
|
| + break;
|
| + case TabAlertState::AUDIO_MUTING:
|
| + tab_label = l10n_util::GetStringFUTF16(
|
| + IDS_TAB_AX_LABEL_AUDIO_MUTING_FORMAT, data_.title);
|
| + break;
|
| + case TabAlertState::TAB_CAPTURING:
|
| + tab_label = l10n_util::GetStringFUTF16(
|
| + IDS_TAB_AX_LABEL_TAB_CAPTURING_FORMAT, data_.title);
|
| + break;
|
| + case TabAlertState::NONE:
|
| + default:
|
| + tab_label = data_.title;
|
| + break;
|
| + }
|
| + }
|
| + // Indicate tab is incognito in addition to other tab status.
|
| + if (data_.incognito) {
|
| + tab_label = l10n_util::GetStringFUTF16(
|
| + IDS_ACCESSIBLE_INCOGNITO_WINDOW_TITLE_FORMAT, tab_label);
|
| + }
|
| + return tab_label;
|
| +}
|
| +
|
| ////////////////////////////////////////////////////////////////////////////////
|
| // Tab, AnimationDelegate overrides:
|
|
|
| @@ -1100,7 +1154,7 @@ void Tab::OnGestureEvent(ui::GestureEvent* event) {
|
|
|
| void Tab::GetAccessibleNodeData(ui::AXNodeData* node_data) {
|
| node_data->role = ui::AX_ROLE_TAB;
|
| - node_data->SetName(data_.title);
|
| + node_data->SetName(GetAccessibleTabLabel());
|
| node_data->AddStateFlag(ui::AX_STATE_MULTISELECTABLE);
|
| node_data->AddStateFlag(ui::AX_STATE_SELECTABLE);
|
| controller_->UpdateTabAccessibilityState(this, node_data);
|
| @@ -1185,7 +1239,8 @@ void Tab::PaintImmersiveTab(gfx::Canvas* canvas) {
|
| // Paint network activity indicator.
|
| // TODO(jamescook): Replace this placeholder animation with a real one.
|
| // For now, let's go with a Cylon eye effect, but in blue.
|
| - if (data().network_state != TabRendererData::NETWORK_STATE_NONE) {
|
| + if (data().network_state != TabRendererData::NETWORK_STATE_NONE &&
|
| + data().network_state != TabRendererData::NETWORK_STATE_ERROR) {
|
| const SkColor kEyeColor = SkColorSetARGB(alpha, 71, 138, 217);
|
| int eye_width = bar_rect.width() / 3;
|
| int eye_offset = bar_rect.width() * immersive_loading_step_ /
|
| @@ -1390,9 +1445,10 @@ void Tab::PaintIcon(gfx::Canvas* canvas) {
|
| return;
|
|
|
| // Throbber will do its own painting.
|
| - if (data().network_state != TabRendererData::NETWORK_STATE_NONE)
|
| + if (data().network_state != TabRendererData::NETWORK_STATE_NONE &&
|
| + data().network_state != TabRendererData::NETWORK_STATE_ERROR) {
|
| return;
|
| -
|
| + }
|
| // Ensure that |favicon_| is created.
|
| if (favicon_.isNull()) {
|
| ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance();
|
| @@ -1442,7 +1498,8 @@ void Tab::AdvanceLoadingAnimation() {
|
| return;
|
| }
|
|
|
| - if (state == TabRendererData::NETWORK_STATE_NONE) {
|
| + if (state == TabRendererData::NETWORK_STATE_NONE ||
|
| + state == TabRendererData::NETWORK_STATE_ERROR) {
|
| throbber_->ResetStartTimes();
|
| throbber_->SetVisible(false);
|
| ScheduleIconPaint();
|
|
|