| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-03 12:43:42 +01:00
										 |  |  | #include "base/functional/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"
 | 
					
						
							| 
									
										
										
										
											2020-08-12 11:33:58 -07:00
										 |  |  | #include "ui/base/dragdrop/drag_drop_types.h"
 | 
					
						
							| 
									
										
										
										
											2022-02-25 13:17:35 -05:00
										 |  |  | #include "ui/color/color_provider.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"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace electron { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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_); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-28 13:40:12 -08:00
										 |  |  | BEGIN_METADATA(AutofillPopupChildView) | 
					
						
							|  |  |  | END_METADATA | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-17 21:55:30 -04:00
										 |  |  | AutofillPopupView::AutofillPopupView(AutofillPopup* popup, | 
					
						
							|  |  |  |                                      views::Widget* parent_widget) | 
					
						
							| 
									
										
										
										
											2021-01-26 19:16:21 +01:00
										 |  |  |     : popup_(popup), parent_widget_(parent_widget) { | 
					
						
							| 
									
										
										
										
											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(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-21 19:55:19 +02:00
										 |  |  |   if (view_proxy_.get()) { | 
					
						
							|  |  |  |     view_proxy_->ResetView(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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(); | 
					
						
							|  |  |  |   visible = visible || view_proxy_; | 
					
						
							|  |  |  |   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.
 | 
					
						
							| 
									
										
										
										
											2020-10-26 11:56:31 -07:00
										 |  |  |     auto* widget = new views::Widget; | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  |     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, | 
					
						
							| 
									
										
										
										
											2022-02-25 13:17:35 -05:00
										 |  |  |       GetColorProvider()->GetColor(ui::kColorUnfocusedBorder))); | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   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(); | 
					
						
							| 
									
										
										
										
											2024-02-09 03:29:14 -06:00
										 |  |  |   if (popup_->line_count() == 0) { | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  |     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( | 
					
						
							| 
									
										
										
										
											2024-01-10 23:23:35 +01:00
										 |  |  |     std::optional<int> previous_row_selection, | 
					
						
							|  |  |  |     std::optional<int> current_row_selection) { | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  |   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; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-25 13:17:35 -05:00
										 |  |  |   canvas->FillRect(entry_rect, GetColorProvider()->GetColor( | 
					
						
							| 
									
										
										
										
											2018-04-17 21:55:30 -04:00
										 |  |  |                                    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; | 
					
						
							| 
									
										
										
										
											2022-06-29 10:14:03 +02:00
										 |  |  |   value_rect.Inset(gfx::Insets::VH(0, kEndPadding)); | 
					
						
							| 
									
										
										
										
											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( | 
					
						
							| 
									
										
										
										
											2024-02-09 03:29:14 -06:00
										 |  |  |       popup_->value_at(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( | 
					
						
							| 
									
										
										
										
											2024-02-09 03:29:14 -06:00
										 |  |  |       popup_->value_at(index), popup_->GetValueFontListForRow(index), | 
					
						
							| 
									
										
										
										
											2022-02-25 13:17:35 -05:00
										 |  |  |       GetColorProvider()->GetColor(ui::kColorResultsTableNormalText), | 
					
						
							| 
									
										
										
										
											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.
 | 
					
						
							| 
									
										
										
										
											2024-02-09 03:29:14 -06:00
										 |  |  |   if (auto const& label = popup_->label_at(index); !label.empty()) { | 
					
						
							|  |  |  |     const int label_width = | 
					
						
							|  |  |  |         gfx::GetStringWidth(label, 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( | 
					
						
							| 
									
										
										
										
											2024-02-09 03:29:14 -06:00
										 |  |  |         label, popup_->GetLabelFontListForRow(index), | 
					
						
							| 
									
										
										
										
											2022-02-25 13:17:35 -05:00
										 |  |  |         GetColorProvider()->GetColor(ui::kColorResultsTableDimmedText), | 
					
						
							| 
									
										
										
										
											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; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-23 20:52:17 -04:00
										 |  |  |   RemoveAllChildViews(); | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-09 03:29:14 -06:00
										 |  |  |   for (int i = 0; i < popup_->line_count(); ++i) { | 
					
						
							|  |  |  |     auto* child_view = new AutofillPopupChildView(popup_->value_at(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; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-27 01:50:19 -08:00
										 |  |  |   // Clamp popup_bounds_ to ensure it's never zero-width.
 | 
					
						
							|  |  |  |   popup_->popup_bounds_.Union( | 
					
						
							|  |  |  |       gfx::Rect(popup_->popup_bounds_.origin(), gfx::Size(1, 1))); | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  |   GetWidget()->SetBounds(popup_->popup_bounds_); | 
					
						
							| 
									
										
										
										
											2018-05-15 03:59:22 +02:00
										 |  |  |   if (view_proxy_.get()) { | 
					
						
							|  |  |  |     view_proxy_->SetBounds(popup_->popup_bounds_in_view()); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  |   SchedulePaint(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AutofillPopupView::OnPaint(gfx::Canvas* canvas) { | 
					
						
							| 
									
										
										
										
											2024-02-09 03:29:14 -06:00
										 |  |  |   if (!popup_ || static_cast<size_t>(popup_->line_count()) != 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; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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-05-19 21:52:18 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-25 13:17:35 -05:00
										 |  |  |   draw_canvas->DrawColor( | 
					
						
							|  |  |  |       GetColorProvider()->GetColor(ui::kColorResultsTableNormalBackground)); | 
					
						
							| 
									
										
										
										
											2017-05-21 19:55:19 +02:00
										 |  |  |   OnPaintBorder(draw_canvas); | 
					
						
							| 
									
										
										
										
											2017-05-19 21:52:18 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-09 03:29:14 -06:00
										 |  |  |   for (int i = 0; i < popup_->line_count(); ++i) { | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  |     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); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   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
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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.
 | 
					
						
							| 
									
										
										
										
											2023-02-03 12:43:42 +01:00
										 |  |  |   base::SingleThreadTaskRunner::GetCurrentDefault()->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.
 | 
					
						
							| 
									
										
										
										
											2022-02-09 18:58:52 -08:00
										 |  |  | #if BUILDFLAG(IS_WIN)
 | 
					
						
							| 
									
										
										
										
											2021-11-24 09:45:59 +01:00
										 |  |  |   if (base::Time::Now() - show_time_ <= base::Milliseconds(50)) | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  |     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( | 
					
						
							| 
									
										
										
										
											2024-06-07 17:18:35 -04:00
										 |  |  |     const input::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.
 | 
					
						
							| 
									
										
										
										
											2024-02-09 03:29:14 -06:00
										 |  |  |       SetSelectedLine(popup_->line_count() - 1); | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  |       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() { | 
					
						
							| 
									
										
										
										
											2024-02-09 03:29:14 -06:00
										 |  |  |   if (!selected_line_ || selected_line_.value() >= popup_->line_count()) | 
					
						
							| 
									
										
										
										
											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(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-10 23:23:35 +01:00
										 |  |  | void AutofillPopupView::SetSelectedLine(std::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; | 
					
						
							| 
									
										
										
										
											2024-02-09 03:29:14 -06:00
										 |  |  |   if (selected_line && selected_line.value() >= popup_->line_count()) | 
					
						
							| 
									
										
										
										
											2017-05-21 19:55:19 +02:00
										 |  |  |     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; | 
					
						
							| 
									
										
										
										
											2024-02-09 03:29:14 -06:00
										 |  |  |   if (new_selected_line >= popup_->line_count()) | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  |     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) | 
					
						
							| 
									
										
										
										
											2024-02-09 03:29:14 -06:00
										 |  |  |     new_selected_line = popup_->line_count() - 1; | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   SetSelectedLine(new_selected_line); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AutofillPopupView::ClearSelection() { | 
					
						
							| 
									
										
										
										
											2024-01-10 23:23:35 +01:00
										 |  |  |   SetSelectedLine(std::nullopt); | 
					
						
							| 
									
										
										
										
											2017-05-19 21:35:13 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AutofillPopupView::RemoveObserver() { | 
					
						
							|  |  |  |   parent_widget_->RemoveObserver(this); | 
					
						
							|  |  |  |   views::WidgetFocusManager::GetInstance()->RemoveFocusChangeListener(this); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-19 21:52:18 +02:00
										 |  |  | }  // namespace electron
 |