This is the cherry pick merge for the M73 branch which was approved here: http://crbug.com/927204
[Autofill Assistant] Prompt only shows button if element exists
Before this patch, buttons were always displayed on prompt. That was
incomplete: it did not allow reproducing the behavior we currently have
between scripts where button appear as a result of DOM changes.
With this patch, prompt button reproduce the between-script behavior,
allowing buttons to be shown only conditionally.
Bug: 122825639
Change-Id: I53eee48156cac1f2e5f1b81dd86a48bb25566a0c
Reviewed-on: https://chromium-review.googlesource.com/c/1437084
Commit-Queue: Stephane Zermatten <szermatt@chromium.org>
Reviewed-by: Mathias Carlen <mcarlen@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#626943}(cherry picked from commit 97ac6fc29d0d6832c7329cdb103dfd74f4aee861)
Reviewed-on: https://chromium-review.googlesource.com/c/1448465
Reviewed-by: Stephane Zermatten <szermatt@chromium.org>
Cr-Commit-Position: refs/branch-heads/3683@{#109}
Cr-Branched-From: e51029943e0a38dd794b73caaf6373d5496ae783-refs/heads/master@{#625896}
diff --git a/components/autofill_assistant/browser/actions/prompt_action.cc b/components/autofill_assistant/browser/actions/prompt_action.cc
index 17d1041..f3a83b48 100644
--- a/components/autofill_assistant/browser/actions/prompt_action.cc
+++ b/components/autofill_assistant/browser/actions/prompt_action.cc
@@ -27,9 +27,52 @@
delegate->SetStatusMessage(proto_.prompt().message());
callback_ = std::move(callback);
- auto chips = std::make_unique<std::vector<Chip>>();
DCHECK_GT(proto_.prompt().choices_size(), 0);
+ delegate->Prompt(CreateChips());
+
+ batch_element_checker_ = delegate->CreateBatchElementChecker();
+
+ // Register elements whose existence enable new chips.
+ for (int i = 0; i < proto_.prompt().choices_size(); i++) {
+ auto& choice_proto = proto_.prompt().choices(i);
+ Selector selector(choice_proto.show_only_if_element_exists());
+ if (selector.empty())
+ continue;
+
+ batch_element_checker_->AddElementCheck(
+ kExistenceCheck, selector,
+ base::BindOnce(&PromptAction::OnRequiredElementExists,
+ weak_ptr_factory_.GetWeakPtr(),
+ base::Unretained(delegate), i));
+ }
+
+ // Wait as long as necessary for one of the elements to show up. This is
+ // cancelled by CancelProto()
+ for (const auto& choice_proto : proto_.prompt().choices()) {
+ Selector selector(choice_proto.element_exists());
+ if (selector.empty())
+ continue;
+
+ std::string payload;
+ choice_proto.SerializeToString(&payload);
+ batch_element_checker_->AddElementCheck(
+ kExistenceCheck, selector,
+ base::BindOnce(&PromptAction::OnElementExist,
+ weak_ptr_factory_.GetWeakPtr(), payload));
+ }
+
+ batch_element_checker_->Run(
+ base::TimeDelta::Max(),
+ /* try_done= */
+ base::BindRepeating(&PromptAction::OnElementChecksDone,
+ weak_ptr_factory_.GetWeakPtr(),
+ base::Unretained(delegate)),
+ /* all_done= */ base::DoNothing());
+}
+
+std::unique_ptr<std::vector<Chip>> PromptAction::CreateChips() {
+ auto chips = std::make_unique<std::vector<Chip>>();
// TODO(crbug.com/806868): Surface type in proto instead of guessing it from
// highlight flag.
Chip::Type non_highlight_type = Chip::Type::CHIP_ASSISTIVE;
@@ -40,8 +83,10 @@
}
}
- for (const auto& choice_proto : proto_.prompt().choices()) {
- if (choice_proto.name().empty())
+ for (int i = 0; i < proto_.prompt().choices_size(); i++) {
+ auto& choice_proto = proto_.prompt().choices(i);
+ if (choice_proto.show_only_if_element_exists().selectors_size() > 0 &&
+ required_element_found_.count(i) == 0)
continue;
chips->emplace_back();
@@ -57,29 +102,7 @@
base::BindOnce(&PromptAction::OnSuggestionChosen,
weak_ptr_factory_.GetWeakPtr(), server_payload);
}
- delegate->Prompt(std::move(chips));
-
- batch_element_checker_ = delegate->CreateBatchElementChecker();
- for (const auto& choice_proto : proto_.prompt().choices()) {
- if (choice_proto.element_exists().selectors_size() == 0)
- continue;
-
- std::string payload;
- choice_proto.SerializeToString(&payload);
- batch_element_checker_->AddElementCheck(
- kExistenceCheck, Selector(choice_proto.element_exists()),
- base::BindOnce(&PromptAction::OnElementExist,
- weak_ptr_factory_.GetWeakPtr(), payload));
- }
- // Wait as long as necessary for one of the elements to show up. This is
- // cancelled by OnSuggestionChosen()
- batch_element_checker_->Run(
- base::TimeDelta::Max(),
- /* try_done= */
- base::BindRepeating(&PromptAction::OnElementChecksDone,
- weak_ptr_factory_.GetWeakPtr(),
- base::Unretained(delegate)),
- /* all_done= */ base::DoNothing());
+ return chips;
}
void PromptAction::OnElementExist(const std::string& payload, bool exists) {
@@ -91,6 +114,16 @@
// callback.
}
+void PromptAction::OnRequiredElementExists(ActionDelegate* delegate,
+ int choice_index,
+ bool exists) {
+ if (!exists)
+ return;
+
+ required_element_found_.insert(choice_index);
+ delegate->Prompt(CreateChips());
+}
+
void PromptAction::OnElementChecksDone(ActionDelegate* delegate) {
if (!forced_payload_.empty()) {
delegate->CancelPrompt();
diff --git a/components/autofill_assistant/browser/actions/prompt_action.h b/components/autofill_assistant/browser/actions/prompt_action.h
index 66dd536..49f8192f 100644
--- a/components/autofill_assistant/browser/actions/prompt_action.h
+++ b/components/autofill_assistant/browser/actions/prompt_action.h
@@ -6,12 +6,15 @@
#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_ACTIONS_PROMPT_ACTION_H_
#include <memory>
+#include <set>
#include <string>
+#include <vector>
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "components/autofill_assistant/browser/actions/action.h"
#include "components/autofill_assistant/browser/batch_element_checker.h"
+#include "components/autofill_assistant/browser/chip.h"
namespace autofill_assistant {
@@ -26,7 +29,11 @@
void InternalProcessAction(ActionDelegate* delegate,
ProcessActionCallback callback) override;
+ std::unique_ptr<std::vector<Chip>> CreateChips();
void OnElementExist(const std::string& payload, bool exists);
+ void OnRequiredElementExists(ActionDelegate* delegate,
+ int choice_index,
+ bool exists);
void OnElementChecksDone(ActionDelegate* delegate);
void OnSuggestionChosen(const std::string& payload);
@@ -34,6 +41,10 @@
std::string forced_payload_;
std::unique_ptr<BatchElementChecker> batch_element_checker_;
+
+ // Index of an element in PromptActionProto::choices that has a
+ // show_only_if_element_exists condition that is met.
+ std::set<int> required_element_found_;
base::WeakPtrFactory<PromptAction> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(PromptAction);
diff --git a/components/autofill_assistant/browser/service.proto b/components/autofill_assistant/browser/service.proto
index e0aedf5..843a939 100644
--- a/components/autofill_assistant/browser/service.proto
+++ b/components/autofill_assistant/browser/service.proto
@@ -564,6 +564,9 @@
// Server payload originally sent by the server. This should
// be transmitted as-is by the client without interpreting.
optional bytes server_payload = 5;
+
+ // The chip is only visible if the given element exists.
+ optional ElementReferenceProto show_only_if_element_exists = 6;
}
repeated Choice choices = 4;
}