| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  | // Copyright (c) 2012 The Chromium Authors. All rights reserved.
 | 
					
						
							|  |  |  | // Use of this source code is governed by a BSD-style license that can be
 | 
					
						
							|  |  |  | // found in the LICENSE file.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-19 13:46:59 -07:00
										 |  |  | #include "shell/browser/ui/views/autofill_popup_view.h"
 | 
					
						
							| 
									
										
										
										
											2018-09-12 19:25:56 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <memory>
 | 
					
						
							| 
									
										
										
										
											2019-08-15 16:50:58 -04:00
										 |  |  | #include <utility>
 | 
					
						
							| 
									
										
										
										
											2018-09-12 19:25:56 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  | #include "base/bind.h"
 | 
					
						
							| 
									
										
										
										
											2017-05-21 19:55:19 +02:00
										 |  |  | #include "base/i18n/rtl.h"
 | 
					
						
							| 
									
										
										
										
											2017-07-10 21:19:00 +02:00
										 |  |  | #include "cc/paint/skia_paint_canvas.h"
 | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  | #include "content/public/browser/render_view_host.h"
 | 
					
						
							| 
									
										
										
										
											2019-11-05 18:41:20 -05:00
										 |  |  | #include "ui/accessibility/ax_enums.mojom.h"
 | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  | #include "ui/events/keycodes/keyboard_codes.h"
 | 
					
						
							|  |  |  | #include "ui/gfx/canvas.h"
 | 
					
						
							|  |  |  | #include "ui/gfx/geometry/point.h"
 | 
					
						
							|  |  |  | #include "ui/gfx/geometry/rect.h"
 | 
					
						
							|  |  |  | #include "ui/gfx/text_utils.h"
 | 
					
						
							|  |  |  | #include "ui/views/border.h"
 | 
					
						
							|  |  |  | #include "ui/views/focus/focus_manager.h"
 | 
					
						
							|  |  |  | #include "ui/views/widget/widget.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-19 14:23:04 -07:00
										 |  |  | namespace electron { | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-17 16:47:47 -07:00
										 |  |  | void AutofillPopupChildView::GetAccessibleNodeData(ui::AXNodeData* node_data) { | 
					
						
							| 
									
										
										
										
											2018-04-11 20:45:22 +05:30
										 |  |  |   node_data->role = ax::mojom::Role::kMenuItem; | 
					
						
							| 
									
										
										
										
											2018-04-17 16:47:47 -07:00
										 |  |  |   node_data->SetName(suggestion_); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-17 21:55:30 -04:00
										 |  |  | AutofillPopupView::AutofillPopupView(AutofillPopup* popup, | 
					
						
							|  |  |  |                                      views::Widget* parent_widget) | 
					
						
							| 
									
										
										
										
											2018-05-22 00:18:38 +02:00
										 |  |  |     : popup_(popup), parent_widget_(parent_widget), weak_ptr_factory_(this) { | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  |   CreateChildViews(); | 
					
						
							|  |  |  |   SetFocusBehavior(FocusBehavior::ALWAYS); | 
					
						
							|  |  |  |   set_drag_controller(this); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | AutofillPopupView::~AutofillPopupView() { | 
					
						
							|  |  |  |   if (popup_) { | 
					
						
							| 
									
										
										
										
											2018-05-16 12:12:45 -07:00
										 |  |  |     auto* host = popup_->frame_host_->GetRenderViewHost()->GetWidget(); | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  |     host->RemoveKeyPressEventCallback(keypress_callback_); | 
					
						
							| 
									
										
										
										
											2017-05-26 03:38:27 +02:00
										 |  |  |     popup_->view_ = nullptr; | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  |     popup_ = nullptr; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   RemoveObserver(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-02 01:30:53 +05:30
										 |  |  | #if BUILDFLAG(ENABLE_OSR)
 | 
					
						
							| 
									
										
										
										
											2017-05-21 19:55:19 +02:00
										 |  |  |   if (view_proxy_.get()) { | 
					
						
							|  |  |  |     view_proxy_->ResetView(); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-06-26 11:13:05 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2017-05-21 19:55:19 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  |   if (GetWidget()) { | 
					
						
							|  |  |  |     GetWidget()->Close(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AutofillPopupView::Show() { | 
					
						
							| 
									
										
										
										
											2019-04-17 23:10:04 +02:00
										 |  |  |   bool visible = parent_widget_->IsVisible(); | 
					
						
							|  |  |  | #if BUILDFLAG(ENABLE_OSR)
 | 
					
						
							|  |  |  |   visible = visible || view_proxy_; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |   if (!popup_ || !visible || parent_widget_->IsClosed()) | 
					
						
							| 
									
										
										
										
											2017-05-21 19:55:19 +02:00
										 |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  |   const bool initialize_widget = !GetWidget(); | 
					
						
							|  |  |  |   if (initialize_widget) { | 
					
						
							|  |  |  |     parent_widget_->AddObserver(this); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // The widget is destroyed by the corresponding NativeWidget, so we use
 | 
					
						
							|  |  |  |     // a weak pointer to hold the reference and don't have to worry about
 | 
					
						
							|  |  |  |     // deletion.
 | 
					
						
							|  |  |  |     views::Widget* widget = new views::Widget; | 
					
						
							|  |  |  |     views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP); | 
					
						
							|  |  |  |     params.delegate = this; | 
					
						
							|  |  |  |     params.parent = parent_widget_->GetNativeView(); | 
					
						
							| 
									
										
										
										
											2019-07-24 15:58:51 -07:00
										 |  |  |     params.z_order = ui::ZOrderLevel::kFloatingUIElement; | 
					
						
							| 
									
										
										
										
											2019-08-15 16:50:58 -04:00
										 |  |  |     widget->Init(std::move(params)); | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // No animation for popup appearance (too distracting).
 | 
					
						
							|  |  |  |     widget->SetVisibilityAnimationTransition(views::Widget::ANIMATE_HIDE); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     show_time_ = base::Time::Now(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   SetBorder(views::CreateSolidBorder( | 
					
						
							|  |  |  |       kPopupBorderThickness, | 
					
						
							|  |  |  |       GetNativeTheme()->GetSystemColor( | 
					
						
							|  |  |  |           ui::NativeTheme::kColorId_UnfocusedBorderColor))); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   DoUpdateBoundsAndRedrawPopup(); | 
					
						
							|  |  |  |   GetWidget()->Show(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (initialize_widget) | 
					
						
							|  |  |  |     views::WidgetFocusManager::GetInstance()->AddFocusChangeListener(this); | 
					
						
							| 
									
										
										
										
											2017-05-19 21:52:18 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-01 13:45:08 -07:00
										 |  |  |   keypress_callback_ = base::BindRepeating( | 
					
						
							|  |  |  |       &AutofillPopupView::HandleKeyPressEvent, base::Unretained(this)); | 
					
						
							| 
									
										
										
										
											2018-05-16 12:12:45 -07:00
										 |  |  |   auto* host = popup_->frame_host_->GetRenderViewHost()->GetWidget(); | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  |   host->AddKeyPressEventCallback(keypress_callback_); | 
					
						
							| 
									
										
										
										
											2017-05-26 03:38:27 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-11 20:45:22 +05:30
										 |  |  |   NotifyAccessibilityEvent(ax::mojom::Event::kMenuStart, true); | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AutofillPopupView::Hide() { | 
					
						
							| 
									
										
										
										
											2017-05-21 19:55:19 +02:00
										 |  |  |   if (popup_) { | 
					
						
							| 
									
										
										
										
											2018-05-16 12:12:45 -07:00
										 |  |  |     auto* host = popup_->frame_host_->GetRenderViewHost()->GetWidget(); | 
					
						
							| 
									
										
										
										
											2017-05-21 19:55:19 +02:00
										 |  |  |     host->RemoveKeyPressEventCallback(keypress_callback_); | 
					
						
							| 
									
										
										
										
											2017-05-26 03:38:27 +02:00
										 |  |  |     popup_ = nullptr; | 
					
						
							| 
									
										
										
										
											2017-05-21 19:55:19 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   RemoveObserver(); | 
					
						
							| 
									
										
										
										
											2018-04-11 20:45:22 +05:30
										 |  |  |   NotifyAccessibilityEvent(ax::mojom::Event::kMenuEnd, true); | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (GetWidget()) { | 
					
						
							|  |  |  |     GetWidget()->Close(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AutofillPopupView::OnSuggestionsChanged() { | 
					
						
							| 
									
										
										
										
											2017-05-21 19:55:19 +02:00
										 |  |  |   if (!popup_) | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   CreateChildViews(); | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  |   if (popup_->GetLineCount() == 0) { | 
					
						
							|  |  |  |     popup_->Hide(); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   DoUpdateBoundsAndRedrawPopup(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-18 15:39:45 +05:30
										 |  |  | void AutofillPopupView::WriteDragDataForView(views::View*, | 
					
						
							|  |  |  |                                              const gfx::Point&, | 
					
						
							|  |  |  |                                              ui::OSExchangeData*) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int AutofillPopupView::GetDragOperationsForView(views::View*, | 
					
						
							|  |  |  |                                                 const gfx::Point&) { | 
					
						
							| 
									
										
										
										
											2018-04-17 16:47:47 -07:00
										 |  |  |   return ui::DragDropTypes::DRAG_NONE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-18 15:39:45 +05:30
										 |  |  | bool AutofillPopupView::CanStartDragForView(views::View*, | 
					
						
							|  |  |  |                                             const gfx::Point&, | 
					
						
							|  |  |  |                                             const gfx::Point&) { | 
					
						
							| 
									
										
										
										
											2018-04-17 16:47:47 -07:00
										 |  |  |   return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  | void AutofillPopupView::OnSelectedRowChanged( | 
					
						
							|  |  |  |     base::Optional<int> previous_row_selection, | 
					
						
							|  |  |  |     base::Optional<int> current_row_selection) { | 
					
						
							|  |  |  |   SchedulePaint(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (current_row_selection) { | 
					
						
							| 
									
										
										
										
											2017-05-21 19:55:19 +02:00
										 |  |  |     int selected = current_row_selection.value_or(-1); | 
					
						
							| 
									
										
										
										
											2019-04-30 20:18:22 -04:00
										 |  |  |     if (selected == -1 || static_cast<size_t>(selected) >= children().size()) | 
					
						
							| 
									
										
										
										
											2017-05-21 19:55:19 +02:00
										 |  |  |       return; | 
					
						
							| 
									
										
										
										
											2019-04-30 20:18:22 -04:00
										 |  |  |     children().at(selected)->NotifyAccessibilityEvent( | 
					
						
							|  |  |  |         ax::mojom::Event::kSelection, true); | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AutofillPopupView::DrawAutofillEntry(gfx::Canvas* canvas, | 
					
						
							|  |  |  |                                           int index, | 
					
						
							|  |  |  |                                           const gfx::Rect& entry_rect) { | 
					
						
							| 
									
										
										
										
											2017-05-21 19:55:19 +02:00
										 |  |  |   if (!popup_) | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-17 21:55:30 -04:00
										 |  |  |   canvas->FillRect(entry_rect, GetNativeTheme()->GetSystemColor( | 
					
						
							|  |  |  |                                    popup_->GetBackgroundColorIDForRow(index))); | 
					
						
							| 
									
										
										
										
											2017-05-19 21:52:18 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-21 19:55:19 +02:00
										 |  |  |   const bool is_rtl = base::i18n::IsRTL(); | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  |   const int text_align = | 
					
						
							| 
									
										
										
										
											2018-04-17 21:55:30 -04:00
										 |  |  |       is_rtl ? gfx::Canvas::TEXT_ALIGN_RIGHT : gfx::Canvas::TEXT_ALIGN_LEFT; | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  |   gfx::Rect value_rect = entry_rect; | 
					
						
							|  |  |  |   value_rect.Inset(kEndPadding, 0); | 
					
						
							| 
									
										
										
										
											2017-05-19 21:52:18 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  |   int x_align_left = value_rect.x(); | 
					
						
							|  |  |  |   const int value_width = gfx::GetStringWidth( | 
					
						
							| 
									
										
										
										
											2018-04-17 21:55:30 -04:00
										 |  |  |       popup_->GetValueAt(index), popup_->GetValueFontListForRow(index)); | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  |   int value_x_align_left = x_align_left; | 
					
						
							|  |  |  |   value_x_align_left = | 
					
						
							| 
									
										
										
										
											2018-04-17 21:55:30 -04:00
										 |  |  |       is_rtl ? value_rect.right() - value_width : value_rect.x(); | 
					
						
							| 
									
										
										
										
											2017-05-19 21:52:18 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  |   canvas->DrawStringRectWithFlags( | 
					
						
							| 
									
										
										
										
											2018-04-17 21:55:30 -04:00
										 |  |  |       popup_->GetValueAt(index), popup_->GetValueFontListForRow(index), | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  |       GetNativeTheme()->GetSystemColor( | 
					
						
							| 
									
										
										
										
											2018-04-17 21:55:30 -04:00
										 |  |  |           ui::NativeTheme::kColorId_ResultsTableNormalText), | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  |       gfx::Rect(value_x_align_left, value_rect.y(), value_width, | 
					
						
							|  |  |  |                 value_rect.height()), | 
					
						
							|  |  |  |       text_align); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Draw the label text, if one exists.
 | 
					
						
							|  |  |  |   if (!popup_->GetLabelAt(index).empty()) { | 
					
						
							|  |  |  |     const int label_width = gfx::GetStringWidth( | 
					
						
							| 
									
										
										
										
											2018-04-17 21:55:30 -04:00
										 |  |  |         popup_->GetLabelAt(index), popup_->GetLabelFontListForRow(index)); | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  |     int label_x_align_left = x_align_left; | 
					
						
							| 
									
										
										
										
											2017-05-19 21:52:18 +02:00
										 |  |  |     label_x_align_left = | 
					
						
							| 
									
										
										
										
											2018-04-17 21:55:30 -04:00
										 |  |  |         is_rtl ? value_rect.x() : value_rect.right() - label_width; | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     canvas->DrawStringRectWithFlags( | 
					
						
							| 
									
										
										
										
											2018-04-17 21:55:30 -04:00
										 |  |  |         popup_->GetLabelAt(index), popup_->GetLabelFontListForRow(index), | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  |         GetNativeTheme()->GetSystemColor( | 
					
						
							| 
									
										
										
										
											2019-01-12 06:30:43 +05:30
										 |  |  |             ui::NativeTheme::kColorId_ResultsTableDimmedText), | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  |         gfx::Rect(label_x_align_left, entry_rect.y(), label_width, | 
					
						
							|  |  |  |                   entry_rect.height()), | 
					
						
							|  |  |  |         text_align); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AutofillPopupView::CreateChildViews() { | 
					
						
							| 
									
										
										
										
											2017-05-21 19:55:19 +02:00
										 |  |  |   if (!popup_) | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  |   RemoveAllChildViews(true); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (int i = 0; i < popup_->GetLineCount(); ++i) { | 
					
						
							| 
									
										
										
										
											2018-05-16 12:12:45 -07:00
										 |  |  |     auto* child_view = new AutofillPopupChildView(popup_->GetValueAt(i)); | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  |     child_view->set_drag_controller(this); | 
					
						
							|  |  |  |     AddChildView(child_view); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AutofillPopupView::DoUpdateBoundsAndRedrawPopup() { | 
					
						
							| 
									
										
										
										
											2017-05-21 19:55:19 +02:00
										 |  |  |   if (!popup_) | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  |   GetWidget()->SetBounds(popup_->popup_bounds_); | 
					
						
							| 
									
										
										
										
											2018-10-02 01:30:53 +05:30
										 |  |  | #if BUILDFLAG(ENABLE_OSR)
 | 
					
						
							| 
									
										
										
										
											2018-05-15 03:59:22 +02:00
										 |  |  |   if (view_proxy_.get()) { | 
					
						
							|  |  |  |     view_proxy_->SetBounds(popup_->popup_bounds_in_view()); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  |   SchedulePaint(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AutofillPopupView::OnPaint(gfx::Canvas* canvas) { | 
					
						
							| 
									
										
										
										
											2019-04-30 20:18:22 -04:00
										 |  |  |   if (!popup_ || | 
					
						
							|  |  |  |       static_cast<size_t>(popup_->GetLineCount()) != children().size()) | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  |     return; | 
					
						
							| 
									
										
										
										
											2017-05-21 19:55:19 +02:00
										 |  |  |   gfx::Canvas* draw_canvas = canvas; | 
					
						
							|  |  |  |   SkBitmap bitmap; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-02 01:30:53 +05:30
										 |  |  | #if BUILDFLAG(ENABLE_OSR)
 | 
					
						
							| 
									
										
										
										
											2017-11-03 01:24:27 +01:00
										 |  |  |   std::unique_ptr<cc::SkiaPaintCanvas> paint_canvas; | 
					
						
							| 
									
										
										
										
											2017-05-21 19:55:19 +02:00
										 |  |  |   if (view_proxy_.get()) { | 
					
						
							| 
									
										
										
										
											2018-05-15 03:59:22 +02:00
										 |  |  |     bitmap.allocN32Pixels(popup_->popup_bounds_in_view().width(), | 
					
						
							|  |  |  |                           popup_->popup_bounds_in_view().height(), true); | 
					
						
							| 
									
										
										
										
											2019-09-16 18:12:00 -04:00
										 |  |  |     paint_canvas = std::make_unique<cc::SkiaPaintCanvas>(bitmap); | 
					
						
							| 
									
										
										
										
											2017-11-03 01:24:27 +01:00
										 |  |  |     draw_canvas = new gfx::Canvas(paint_canvas.get(), 1.0); | 
					
						
							| 
									
										
										
										
											2017-05-21 19:55:19 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-06-26 11:13:05 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2017-05-19 21:52:18 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-21 19:55:19 +02:00
										 |  |  |   draw_canvas->DrawColor(GetNativeTheme()->GetSystemColor( | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  |       ui::NativeTheme::kColorId_ResultsTableNormalBackground)); | 
					
						
							| 
									
										
										
										
											2017-05-21 19:55:19 +02:00
										 |  |  |   OnPaintBorder(draw_canvas); | 
					
						
							| 
									
										
										
										
											2017-05-19 21:52:18 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  |   for (int i = 0; i < popup_->GetLineCount(); ++i) { | 
					
						
							|  |  |  |     gfx::Rect line_rect = popup_->GetRowBounds(i); | 
					
						
							| 
									
										
										
										
											2017-05-19 21:52:18 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-21 19:55:19 +02:00
										 |  |  |     DrawAutofillEntry(draw_canvas, i, line_rect); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-02 01:30:53 +05:30
										 |  |  | #if BUILDFLAG(ENABLE_OSR)
 | 
					
						
							| 
									
										
										
										
											2017-05-21 19:55:19 +02:00
										 |  |  |   if (view_proxy_.get()) { | 
					
						
							| 
									
										
										
										
											2018-05-15 03:59:22 +02:00
										 |  |  |     view_proxy_->SetBounds(popup_->popup_bounds_in_view()); | 
					
						
							| 
									
										
										
										
											2017-05-21 19:55:19 +02:00
										 |  |  |     view_proxy_->SetBitmap(bitmap); | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-06-26 11:13:05 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AutofillPopupView::GetAccessibleNodeData(ui::AXNodeData* node_data) { | 
					
						
							| 
									
										
										
										
											2018-04-11 20:45:22 +05:30
										 |  |  |   node_data->role = ax::mojom::Role::kMenu; | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  |   node_data->SetName("Autofill Menu"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AutofillPopupView::OnMouseCaptureLost() { | 
					
						
							|  |  |  |   ClearSelection(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool AutofillPopupView::OnMouseDragged(const ui::MouseEvent& event) { | 
					
						
							|  |  |  |   if (HitTestPoint(event.location())) { | 
					
						
							|  |  |  |     SetSelection(event.location()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // We must return true in order to get future OnMouseDragged and
 | 
					
						
							|  |  |  |     // OnMouseReleased events.
 | 
					
						
							|  |  |  |     return true; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // If we move off of the popup, we lose the selection.
 | 
					
						
							|  |  |  |   ClearSelection(); | 
					
						
							|  |  |  |   return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AutofillPopupView::OnMouseExited(const ui::MouseEvent& event) { | 
					
						
							|  |  |  |   // Pressing return causes the cursor to hide, which will generate an
 | 
					
						
							|  |  |  |   // OnMouseExited event. Pressing return should activate the current selection
 | 
					
						
							|  |  |  |   // via AcceleratorPressed, so we need to let that run first.
 | 
					
						
							|  |  |  |   base::ThreadTaskRunnerHandle::Get()->PostTask( | 
					
						
							| 
									
										
										
										
											2019-05-01 13:45:08 -07:00
										 |  |  |       FROM_HERE, base::BindOnce(&AutofillPopupView::ClearSelection, | 
					
						
							|  |  |  |                                 weak_ptr_factory_.GetWeakPtr())); | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AutofillPopupView::OnMouseMoved(const ui::MouseEvent& event) { | 
					
						
							|  |  |  |   // A synthesized mouse move will be sent when the popup is first shown.
 | 
					
						
							|  |  |  |   // Don't preview a suggestion if the mouse happens to be hovering there.
 | 
					
						
							|  |  |  | #if defined(OS_WIN)
 | 
					
						
							|  |  |  |   if (base::Time::Now() - show_time_ <= base::TimeDelta::FromMilliseconds(50)) | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |   if (event.flags() & ui::EF_IS_SYNTHESIZED) | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (HitTestPoint(event.location())) | 
					
						
							|  |  |  |     SetSelection(event.location()); | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     ClearSelection(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool AutofillPopupView::OnMousePressed(const ui::MouseEvent& event) { | 
					
						
							|  |  |  |   return event.GetClickCount() == 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AutofillPopupView::OnMouseReleased(const ui::MouseEvent& event) { | 
					
						
							|  |  |  |   // We only care about the left click.
 | 
					
						
							|  |  |  |   if (event.IsOnlyLeftMouseButton() && HitTestPoint(event.location())) | 
					
						
							|  |  |  |     AcceptSelection(event.location()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AutofillPopupView::OnGestureEvent(ui::GestureEvent* event) { | 
					
						
							|  |  |  |   switch (event->type()) { | 
					
						
							|  |  |  |     case ui::ET_GESTURE_TAP_DOWN: | 
					
						
							|  |  |  |     case ui::ET_GESTURE_SCROLL_BEGIN: | 
					
						
							|  |  |  |     case ui::ET_GESTURE_SCROLL_UPDATE: | 
					
						
							|  |  |  |       if (HitTestPoint(event->location())) | 
					
						
							|  |  |  |         SetSelection(event->location()); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         ClearSelection(); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     case ui::ET_GESTURE_TAP: | 
					
						
							|  |  |  |     case ui::ET_GESTURE_SCROLL_END: | 
					
						
							|  |  |  |       if (HitTestPoint(event->location())) | 
					
						
							|  |  |  |         AcceptSelection(event->location()); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         ClearSelection(); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     case ui::ET_GESTURE_TAP_CANCEL: | 
					
						
							|  |  |  |     case ui::ET_SCROLL_FLING_START: | 
					
						
							|  |  |  |       ClearSelection(); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   event->SetHandled(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-17 21:55:30 -04:00
										 |  |  | bool AutofillPopupView::AcceleratorPressed(const ui::Accelerator& accelerator) { | 
					
						
							| 
									
										
										
										
											2017-05-21 19:55:19 +02:00
										 |  |  |   if (accelerator.modifiers() != ui::EF_NONE) | 
					
						
							|  |  |  |     return false; | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (accelerator.key_code() == ui::VKEY_ESCAPE) { | 
					
						
							| 
									
										
										
										
											2017-05-21 19:55:19 +02:00
										 |  |  |     if (popup_) | 
					
						
							|  |  |  |       popup_->Hide(); | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  |     return true; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (accelerator.key_code() == ui::VKEY_RETURN) | 
					
						
							|  |  |  |     return AcceptSelectedLine(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool AutofillPopupView::HandleKeyPressEvent( | 
					
						
							|  |  |  |     const content::NativeWebKeyboardEvent& event) { | 
					
						
							| 
									
										
										
										
											2017-05-21 19:55:19 +02:00
										 |  |  |   if (!popup_) | 
					
						
							|  |  |  |     return false; | 
					
						
							| 
									
										
										
										
											2017-06-28 16:58:47 +02:00
										 |  |  |   switch (event.windows_key_code) { | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  |     case ui::VKEY_UP: | 
					
						
							|  |  |  |       SelectPreviousLine(); | 
					
						
							|  |  |  |       return true; | 
					
						
							|  |  |  |     case ui::VKEY_DOWN: | 
					
						
							|  |  |  |       SelectNextLine(); | 
					
						
							|  |  |  |       return true; | 
					
						
							|  |  |  |     case ui::VKEY_PRIOR:  // Page up.
 | 
					
						
							|  |  |  |       SetSelectedLine(0); | 
					
						
							|  |  |  |       return true; | 
					
						
							|  |  |  |     case ui::VKEY_NEXT:  // Page down.
 | 
					
						
							|  |  |  |       SetSelectedLine(popup_->GetLineCount() - 1); | 
					
						
							|  |  |  |       return true; | 
					
						
							|  |  |  |     case ui::VKEY_ESCAPE: | 
					
						
							|  |  |  |       popup_->Hide(); | 
					
						
							|  |  |  |       return true; | 
					
						
							|  |  |  |     case ui::VKEY_TAB: | 
					
						
							|  |  |  |       // A tab press should cause the selected line to be accepted, but still
 | 
					
						
							|  |  |  |       // return false so the tab key press propagates and changes the cursor
 | 
					
						
							|  |  |  |       // location.
 | 
					
						
							|  |  |  |       AcceptSelectedLine(); | 
					
						
							|  |  |  |       return false; | 
					
						
							|  |  |  |     case ui::VKEY_RETURN: | 
					
						
							|  |  |  |       return AcceptSelectedLine(); | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |       return false; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AutofillPopupView::OnNativeFocusChanged(gfx::NativeView focused_now) { | 
					
						
							| 
									
										
										
										
											2017-05-21 19:55:19 +02:00
										 |  |  |   if (GetWidget() && GetWidget()->GetNativeView() != focused_now && popup_) | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  |     popup_->Hide(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AutofillPopupView::OnWidgetBoundsChanged(views::Widget* widget, | 
					
						
							|  |  |  |                                               const gfx::Rect& new_bounds) { | 
					
						
							| 
									
										
										
										
											2017-05-21 19:55:19 +02:00
										 |  |  |   if (widget != parent_widget_) | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   if (popup_) | 
					
						
							|  |  |  |     popup_->Hide(); | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AutofillPopupView::AcceptSuggestion(int index) { | 
					
						
							| 
									
										
										
										
											2017-05-21 19:55:19 +02:00
										 |  |  |   if (!popup_) | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  |   popup_->AcceptSuggestion(index); | 
					
						
							|  |  |  |   popup_->Hide(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool AutofillPopupView::AcceptSelectedLine() { | 
					
						
							| 
									
										
										
										
											2017-05-21 19:55:19 +02:00
										 |  |  |   if (!selected_line_ || selected_line_.value() >= popup_->GetLineCount()) | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  |     return false; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-21 19:55:19 +02:00
										 |  |  |   AcceptSuggestion(selected_line_.value()); | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  |   return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AutofillPopupView::AcceptSelection(const gfx::Point& point) { | 
					
						
							| 
									
										
										
										
											2017-05-21 19:55:19 +02:00
										 |  |  |   if (!popup_) | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  |   SetSelectedLine(popup_->LineFromY(point.y())); | 
					
						
							|  |  |  |   AcceptSelectedLine(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AutofillPopupView::SetSelectedLine(base::Optional<int> selected_line) { | 
					
						
							| 
									
										
										
										
											2017-05-21 19:55:19 +02:00
										 |  |  |   if (!popup_) | 
					
						
							|  |  |  |     return; | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  |   if (selected_line_ == selected_line) | 
					
						
							|  |  |  |     return; | 
					
						
							| 
									
										
										
										
											2017-05-21 19:55:19 +02:00
										 |  |  |   if (selected_line && selected_line.value() >= popup_->GetLineCount()) | 
					
						
							|  |  |  |     return; | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   auto previous_selected_line(selected_line_); | 
					
						
							|  |  |  |   selected_line_ = selected_line; | 
					
						
							|  |  |  |   OnSelectedRowChanged(previous_selected_line, selected_line_); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AutofillPopupView::SetSelection(const gfx::Point& point) { | 
					
						
							| 
									
										
										
										
											2017-05-21 19:55:19 +02:00
										 |  |  |   if (!popup_) | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  |   SetSelectedLine(popup_->LineFromY(point.y())); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AutofillPopupView::SelectNextLine() { | 
					
						
							| 
									
										
										
										
											2017-05-21 19:55:19 +02:00
										 |  |  |   if (!popup_) | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  |   int new_selected_line = selected_line_ ? *selected_line_ + 1 : 0; | 
					
						
							|  |  |  |   if (new_selected_line >= popup_->GetLineCount()) | 
					
						
							|  |  |  |     new_selected_line = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   SetSelectedLine(new_selected_line); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AutofillPopupView::SelectPreviousLine() { | 
					
						
							| 
									
										
										
										
											2017-05-21 19:55:19 +02:00
										 |  |  |   if (!popup_) | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  |   int new_selected_line = selected_line_.value_or(0) - 1; | 
					
						
							|  |  |  |   if (new_selected_line < 0) | 
					
						
							|  |  |  |     new_selected_line = popup_->GetLineCount() - 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   SetSelectedLine(new_selected_line); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AutofillPopupView::ClearSelection() { | 
					
						
							|  |  |  |   SetSelectedLine(base::nullopt); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AutofillPopupView::RemoveObserver() { | 
					
						
							|  |  |  |   parent_widget_->RemoveObserver(this); | 
					
						
							|  |  |  |   views::WidgetFocusManager::GetInstance()->RemoveFocusChangeListener(this); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-19 14:23:04 -07:00
										 |  |  | }  // namespace electron
 |