1 // Copyright 2020 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/autofill_assistant/browser/web/js_snippets.h"
6
7 #include "base/strings/strcat.h"
8 #include "base/strings/string_util.h"
9
10 namespace autofill_assistant {
11
12 JsSnippet::JsSnippet() = default;
13 JsSnippet::~JsSnippet() = default;
ToString() const14 std::string JsSnippet::ToString() const {
15 return base::JoinString(lines_, "\n");
16 }
17
AddLine(const std::string & line)18 void JsSnippet::AddLine(const std::string& line) {
19 lines_.emplace_back(line);
20 }
21
AddLine(const std::vector<std::string> & line)22 void JsSnippet::AddLine(const std::vector<std::string>& line) {
23 lines_.emplace_back(base::StrCat(line));
24 }
25
AddReturnIfOnTop(JsSnippet * out,const std::string & element_var,const std::string & on_top,const std::string & not_on_top,const std::string & not_in_view)26 void AddReturnIfOnTop(JsSnippet* out,
27 const std::string& element_var,
28 const std::string& on_top,
29 const std::string& not_on_top,
30 const std::string& not_in_view) {
31 // clang-format off
32 out->AddLine({"const bounds = ", element_var, R"(.getBoundingClientRect();
33 const x = bounds.x + bounds.width / 2;
34 const y = bounds.y + bounds.height / 2;
35 const targets = [)", element_var, R"(];
36 const labels = )", element_var, R"(.labels;
37 if (labels) {
38 for (let i = 0; i < labels.length; i++) {
39 targets.push(labels[i]);
40 }
41 }
42 let root = document;
43 while (root) {
44 const atPoint = root.elementFromPoint(x, y);
45 if (!atPoint) {
46 return )", not_in_view, R"(;
47 }
48 for (const target of targets) {
49 if (target === atPoint || target.contains(atPoint)) {
50 return )", on_top , R"(;
51 }
52 }
53 root = atPoint.shadowRoot;
54 }
55 return )", not_on_top, ";"});
56 // clang-format on
57 }
58 } // namespace autofill_assistant
59