File: floating_webui_help_bubble_factory.cc

package info (click to toggle)
chromium 138.0.7204.157-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,864 kB
  • sloc: cpp: 34,936,859; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,967; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (86 lines) | stat: -rw-r--r-- 3,107 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/user_education/webui/floating_webui_help_bubble_factory.h"

#include "components/user_education/views/help_bubble_factory_views.h"
#include "components/user_education/views/help_bubble_view.h"
#include "components/user_education/webui/help_bubble_handler.h"
#include "components/user_education/webui/tracked_element_webui.h"
#include "content/public/browser/web_contents.h"
#include "ui/base/interaction/element_tracker.h"
#include "ui/base/interaction/framework_specific_implementation.h"
#include "ui/views/controls/webview/webview.h"
#include "ui/views/view_utils.h"
#include "ui/views/widget/widget.h"

namespace user_education {

namespace {

// Searches `from_view` recursively (depth-first) for a WebView with `contents`.
views::WebView* FindWebViewWithContentsRecursive(
    views::View* from_view,
    const content::WebContents* contents) {
  auto* const web_view = views::AsViewClass<views::WebView>(from_view);
  if (web_view && web_view->web_contents() == contents) {
    return web_view;
  }

  for (views::View* const child_view : from_view->children()) {
    auto* const result = FindWebViewWithContentsRecursive(child_view, contents);
    if (result) {
      return result;
    }
  }

  return nullptr;
}

// Attempts to extract the host WebView from `element`; returns null if
// `element` is not a TrackedElementWebUI or the host view cannot be determined.
views::WebView* GetWebViewForElement(const ui::TrackedElement* element) {
  if (!element->IsA<TrackedElementWebUI>()) {
    return nullptr;
  }
  const auto* const element_webui = element->AsA<TrackedElementWebUI>();
  auto* const contents = element_webui->handler()->GetWebContents();
  if (!contents) {
    return nullptr;
  }
  auto* const widget = views::Widget::GetWidgetForNativeWindow(
      contents->GetTopLevelNativeWindow());
  if (!widget) {
    return nullptr;
  }
  return FindWebViewWithContentsRecursive(widget->GetContentsView(), contents);
}

}  // namespace

FloatingWebUIHelpBubbleFactory::FloatingWebUIHelpBubbleFactory(
    const HelpBubbleDelegate* delegate)
    : HelpBubbleFactoryViews(delegate) {}
FloatingWebUIHelpBubbleFactory::~FloatingWebUIHelpBubbleFactory() = default;

DEFINE_FRAMEWORK_SPECIFIC_METADATA(FloatingWebUIHelpBubbleFactory)

std::unique_ptr<HelpBubble> FloatingWebUIHelpBubbleFactory::CreateBubble(
    ui::TrackedElement* element,
    HelpBubbleParams params) {
  internal::HelpBubbleAnchorParams anchor;
  anchor.view = GetWebViewForElement(element);
  anchor.rect = element->GetScreenBounds();
  auto result = CreateBubbleImpl(element, anchor, std::move(params), nullptr);
  element->AsA<TrackedElementWebUI>()->handler()->OnFloatingHelpBubbleCreated(
      element->identifier(), result.get());
  return result;
}

bool FloatingWebUIHelpBubbleFactory::CanBuildBubbleForTrackedElement(
    const ui::TrackedElement* element) const {
  return GetWebViewForElement(element) != nullptr;
}

}  // namespace user_education