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