Commit f622af94 authored by Clemens Arbesser's avatar Clemens Arbesser Committed by Commit Bot

[Autofill Assistant] Adds support for text links to the form action.

Clicking a text link will end the action immediately and send the current state of the form action (including the state of counters and checkboxes) to the backend.

This CL also fixes a bug where multi-line radio button descriptions where not correctly vertically centered.

Bug: b/144402029
Change-Id: I6e14f01744edf16bd703df9b560a45c9498bd2fe
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1929820
Commit-Queue: Clemens Arbesser <arbesser@google.com>
Reviewed-by: default avatarMathias Carlen <mcarlen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#719297}
parent 9e9075ca
......@@ -11,7 +11,7 @@
android:layout_weight="1.0"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="fill_horizontal">
android:gravity="fill_horizontal|center_vertical">
<TextView
android:id="@+id/label"
......
......@@ -35,6 +35,7 @@ class AssistantFormCounterInput extends AssistantFormInput {
interface Delegate {
void onCounterChanged(int counterIndex, int value);
void onLinkClicked(int link);
}
private static class CounterViewHolder {
......@@ -100,7 +101,7 @@ class AssistantFormCounterInput extends AssistantFormInput {
if (mLabel.isEmpty()) {
label.setVisibility(View.GONE);
} else {
label.setText(mLabel);
AssistantTextUtils.applyVisualAppearanceTags(label, mLabel, mDelegate::onLinkClicked);
}
// Create the views.
......@@ -194,11 +195,10 @@ class AssistantFormCounterInput extends AssistantFormInput {
AssistantFormCounter counter = counters.get(i);
CounterViewHolder view = views.get(i);
// TODO(b/144402029) Add support for text links.
AssistantTextUtils.applyVisualAppearanceTags(
view.mDescriptionLine1View, counter.getDescriptionLine1(), null);
AssistantTextUtils.applyVisualAppearanceTags(
view.mDescriptionLine2View, counter.getDescriptionLine2(), null);
AssistantTextUtils.applyVisualAppearanceTags(view.mDescriptionLine1View,
counter.getDescriptionLine1(), mDelegate::onLinkClicked);
AssistantTextUtils.applyVisualAppearanceTags(view.mDescriptionLine2View,
counter.getDescriptionLine2(), mDelegate::onLinkClicked);
hideIfEmpty(view.mDescriptionLine1View);
hideIfEmpty(view.mDescriptionLine2View);
......@@ -220,7 +220,8 @@ class AssistantFormCounterInput extends AssistantFormInput {
// Update the label.
String label = counter.getLabel();
label = label.replaceAll(QUOTED_VALUE, Integer.toString(counter.getValue()));
view.mLabelView.setText(label);
AssistantTextUtils.applyVisualAppearanceTags(
view.mLabelView, label, mDelegate::onLinkClicked);
// Update the value view.
view.mValueView.setText(Integer.toString(counter.getValue()));
......
......@@ -28,6 +28,7 @@ class AssistantFormDelegate {
AssistantFormDelegate.this, inputIndex, counterIndex, value);
}
}
void onChoiceSelectionChanged(int inputIndex, int choiceIndex, boolean selected) {
if (mNativeAssistantFormDelegate != 0) {
AssistantFormDelegateJni.get().onChoiceSelectionChanged(mNativeAssistantFormDelegate,
......@@ -35,6 +36,13 @@ class AssistantFormDelegate {
}
}
void onLinkClicked(int link) {
if (mNativeAssistantFormDelegate != 0) {
AssistantFormDelegateJni.get().onLinkClicked(
mNativeAssistantFormDelegate, AssistantFormDelegate.this, link);
}
}
@CalledByNative
private void clearNativePtr() {
mNativeAssistantFormDelegate = 0;
......@@ -46,5 +54,7 @@ class AssistantFormDelegate {
int inputIndex, int counterIndex, long nativeAssistantOverlayDelegate);
void onChoiceSelectionChanged(long nativeAssistantFormDelegate,
AssistantFormDelegate caller, int inputIndex, int choiceIndex, boolean selected);
void onLinkClicked(
long nativeAssistantFormDelegate, AssistantFormDelegate caller, int link);
}
}
......@@ -66,16 +66,34 @@ public abstract class AssistantFormInput {
AssistantFormDelegate delegate) {
return new AssistantFormCounterInput(label, expandText, minimizeText, counters,
minimizedCount, minCountersSum, maxCountersSum,
(counterIndex,
value) -> delegate.onCounterChanged(inputIndex, counterIndex, value));
new AssistantFormCounterInput.Delegate() {
@Override
public void onCounterChanged(int counterIndex, int value) {
delegate.onCounterChanged(inputIndex, counterIndex, value);
}
@Override
public void onLinkClicked(int link) {
delegate.onLinkClicked(link);
}
});
}
@CalledByNative
private static AssistantFormSelectionInput createSelectionInput(int inputIndex, String label,
List<AssistantFormSelectionChoice> choices, boolean allowMultipleChoices,
AssistantFormDelegate delegate) {
return new AssistantFormSelectionInput(label, choices, allowMultipleChoices,
(choiceIndex, selected)
-> delegate.onChoiceSelectionChanged(inputIndex, choiceIndex, selected));
return new AssistantFormSelectionInput(
label, choices, allowMultipleChoices, new AssistantFormSelectionInput.Delegate() {
@Override
public void onChoiceSelectionChanged(int choiceIndex, boolean selected) {
delegate.onChoiceSelectionChanged(inputIndex, choiceIndex, selected);
}
@Override
public void onLinkClicked(int link) {
delegate.onLinkClicked(link);
}
});
}
}
......@@ -21,6 +21,7 @@ import java.util.List;
class AssistantFormSelectionInput extends AssistantFormInput {
interface Delegate {
void onChoiceSelectionChanged(int choiceIndex, boolean selected);
void onLinkClicked(int link);
}
private final String mLabel;
......@@ -46,7 +47,7 @@ class AssistantFormSelectionInput extends AssistantFormInput {
if (mLabel.isEmpty()) {
label.setVisibility(View.GONE);
} else {
label.setText(mLabel);
AssistantTextUtils.applyVisualAppearanceTags(label, mLabel, mDelegate::onLinkClicked);
}
if (mChoices.isEmpty()) {
......@@ -86,11 +87,12 @@ class AssistantFormSelectionInput extends AssistantFormInput {
TextView choiceLabel = choiceView.findViewById(R.id.label);
TextView descriptionLine1 = choiceView.findViewById(R.id.description_line_1);
TextView descriptionLine2 = choiceView.findViewById(R.id.description_line_2);
AssistantTextUtils.applyVisualAppearanceTags(choiceLabel, choice.getLabel(), null);
AssistantTextUtils.applyVisualAppearanceTags(
descriptionLine1, choice.getDescriptionLine1(), null);
choiceLabel, choice.getLabel(), mDelegate::onLinkClicked);
AssistantTextUtils.applyVisualAppearanceTags(
descriptionLine2, choice.getDescriptionLine2(), null);
descriptionLine1, choice.getDescriptionLine1(), mDelegate::onLinkClicked);
AssistantTextUtils.applyVisualAppearanceTags(
descriptionLine2, choice.getDescriptionLine2(), mDelegate::onLinkClicked);
hideIfEmpty(choiceLabel);
hideIfEmpty(descriptionLine1);
hideIfEmpty(descriptionLine2);
......
......@@ -85,7 +85,7 @@ public class AutofillAssistantFormActionTest {
.setMinValue(1)
.setMaxValue(9)
.setLabel("Counter 1")
.setDescriptionLine1("$34.00 per tick")
.setDescriptionLine1("$34.00 per item")
.setDescriptionLine2(
"<link1>Details</link1>"))
.addCounters(
......@@ -93,7 +93,7 @@ public class AutofillAssistantFormActionTest {
.setMinValue(1)
.setMaxValue(9)
.setLabel("Counter 2")
.setDescriptionLine1("$387.00 per tick"))
.setDescriptionLine1("$387.00 per item"))
.setMinimizedCount(1)
.setMinCountersSum(2)
.setMinimizeText("Minimize")
......@@ -113,7 +113,7 @@ public class AutofillAssistantFormActionTest {
.setMinValue(1)
.setMaxValue(9)
.setLabel("Counter 3")
.setDescriptionLine1("$20.00 per tick")
.setDescriptionLine1("$20.00 per item")
.setDescriptionLine2("<link1>Details</link1>"))));
// FormAction.
list.add((ActionProto) ActionProto.newBuilder()
......@@ -168,6 +168,70 @@ public class AutofillAssistantFormActionTest {
onView(withText("Continue")).perform(click());
waitUntilViewMatchesCondition(withText("End"), isCompletelyDisplayed());
// TODO(806868): check that the values were correctly received by the native delegate.
// TODO(b/144978160): check that the values were correctly written to the action response.
}
@Test
@MediumTest
@DisableIf.Build(sdk_is_less_than = 21)
public void testFormActionClickLink() {
ArrayList<ActionProto> list = new ArrayList<>();
// FromProto.Builder, extracted to avoid excessive line widths.
FormProto.Builder formProto =
FormProto.newBuilder().addInputs(FormInputProto.newBuilder().setCounter(
CounterInputProto.newBuilder()
.addCounters(CounterInputProto.Counter.newBuilder()
.setMinValue(1)
.setMaxValue(9)
.setLabel("Counter 1")
.setDescriptionLine1("$34.00 per item")
.setDescriptionLine2("<link4>Details</link4>"))
.addCounters(CounterInputProto.Counter.newBuilder()
.setMinValue(1)
.setMaxValue(9)
.setLabel("Counter 2")
.setDescriptionLine1("$387.00 per item"))
.setMinimizedCount(1)
.setMinCountersSum(2)
.setMinimizeText("Minimize")
.setExpandText("Expand")));
// FormAction.
list.add((ActionProto) ActionProto.newBuilder()
.setShowForm(ShowFormProto.newBuilder()
.setChip(ChipProto.newBuilder()
.setType(ChipType.HIGHLIGHTED_ACTION)
.setText("Continue"))
.setForm(formProto))
.build());
// Prompt.
list.add((ActionProto) ActionProto.newBuilder()
.setPrompt(PromptProto.newBuilder()
.setMessage("Finished")
.addChoices(Choice.newBuilder().setChip(
ChipProto.newBuilder()
.setType(ChipType.DONE_ACTION)
.setText("End"))))
.build());
AutofillAssistantTestScript script = new AutofillAssistantTestScript(
(SupportedScriptProto) SupportedScriptProto.newBuilder()
.setPath("autofill_assistant_target_website.html")
.setPresentation(PresentationProto.newBuilder().setAutostart(true).setChip(
ChipProto.newBuilder().setText("Autostart")))
.build(),
list);
AutofillAssistantTestService testService =
new AutofillAssistantTestService(Collections.singletonList(script));
startAutofillAssistant(mTestRule.getActivity(), testService);
waitUntilViewMatchesCondition(withText("Continue"), isCompletelyDisplayed());
// TODO(b/144690738) Remove the isDisplayed() condition.
onView(allOf(isDisplayed(), withText("Details"))).perform(click());
// TODO(b/144978160) Check that the correct link number was written to the action response.
waitUntilViewMatchesCondition(withText("End"), isCompletelyDisplayed());
}
}
......@@ -40,6 +40,13 @@ void AssistantFormDelegate::OnChoiceSelectionChanged(
ui_controller_->OnChoiceSelectionChanged(input_index, choice_index, selected);
}
void AssistantFormDelegate::OnLinkClicked(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& jcaller,
jint link) {
ui_controller_->OnFormActionLinkClicked(link);
}
base::android::ScopedJavaGlobalRef<jobject>
AssistantFormDelegate::GetJavaObject() {
return java_assistant_form_delegate_;
......
......@@ -28,6 +28,10 @@ class AssistantFormDelegate {
jint choice_index,
jboolean selected);
void OnLinkClicked(JNIEnv* env,
const base::android::JavaParamRef<jobject>& jcaller,
jint link);
base::android::ScopedJavaGlobalRef<jobject> GetJavaObject();
private:
......
......@@ -848,6 +848,10 @@ void UiControllerAndroid::OnTermsAndConditionsLinkClicked(int link) {
ui_delegate_->OnTermsAndConditionsLinkClicked(link);
}
void UiControllerAndroid::OnFormActionLinkClicked(int link) {
ui_delegate_->OnFormActionLinkClicked(link);
}
void UiControllerAndroid::OnDateTimeRangeStartChanged(int year,
int month,
int day,
......
......@@ -123,6 +123,7 @@ class UiControllerAndroid : public ControllerObserver {
void OnTermsAndConditionsChanged(TermsAndConditionsState state);
void OnLoginChoiceChanged(std::string identifier);
void OnTermsAndConditionsLinkClicked(int link);
void OnFormActionLinkClicked(int link);
void OnDateTimeRangeStartChanged(int year,
int month,
int day,
......
......@@ -314,14 +314,15 @@ class ActionDelegate {
// Returns the current client settings.
virtual const ClientSettings& GetSettings() = 0;
// Show a form to the user and call |callback| with its values whenever there
// is a change. |callback| will be called directly with the initial values of
// the form directly after this call. Returns true if the form was correctly
// set, false otherwise. The latter can happen if the form contains
// unsupported or invalid inputs.
// Show a form to the user and call |changed_callback| with its values
// whenever there is a change. |changed_callback| will be called directly with
// the initial values of the form directly after this call. Returns true if
// the form was correctly set, false otherwise. The latter can happen if the
// form contains unsupported or invalid inputs.
virtual bool SetForm(
std::unique_ptr<FormProto> form,
base::RepeatingCallback<void(const FormProto::Result*)> callback) = 0;
base::RepeatingCallback<void(const FormProto::Result*)> changed_callback,
base::OnceCallback<void(const ClientStatus&)> cancel_callback) = 0;
// Force showing the UI if no UI is shown. This is useful when executing a
// direct action which realizes it needs to interact with the user. Once
......
......@@ -220,10 +220,12 @@ class MockActionDelegate : public ActionDelegate {
MOCK_METHOD1(SetPeekMode,
void(ConfigureBottomSheetProto::PeekMode peek_mode));
MOCK_METHOD0(GetPeekMode, ConfigureBottomSheetProto::PeekMode());
MOCK_METHOD2(
MOCK_METHOD3(
SetForm,
bool(std::unique_ptr<FormProto> form,
base::RepeatingCallback<void(const FormProto::Result*)> callback));
base::RepeatingCallback<void(const FormProto::Result*)>
changed_callback,
base::OnceCallback<void(const ClientStatus&)> cancel_callback));
void WaitForWindowHeightChange(
base::OnceCallback<void(const ClientStatus&)> callback) override {
......
......@@ -31,10 +31,11 @@ void ShowFormAction::InternalProcessAction(ProcessActionCallback callback) {
if (!delegate_->SetForm(
std::make_unique<FormProto>(proto_.show_form().form()),
base::BindRepeating(&ShowFormAction::OnFormValuesChanged,
weak_ptr_factory_.GetWeakPtr()))) {
weak_ptr_factory_.GetWeakPtr()),
base::BindOnce(&ShowFormAction::OnCancelForm,
weak_ptr_factory_.GetWeakPtr()))) {
// The form contains unsupported or invalid inputs.
UpdateProcessedAction(UNSUPPORTED);
std::move(callback_).Run(std::move(processed_action_proto_));
EndAction(ClientStatus(UNSUPPORTED));
return;
}
}
......@@ -60,6 +61,10 @@ void ShowFormAction::OnFormValuesChanged(const FormProto::Result* form_result) {
delegate_->Prompt(std::move(user_actions));
}
void ShowFormAction::OnCancelForm(const ClientStatus& status) {
EndAction(status);
}
bool ShowFormAction::IsFormValid(const FormProto& form,
const FormProto::Result& result) {
// TODO(crbug.com/806868): Only check validity of inputs whose value changed
......@@ -175,9 +180,12 @@ bool ShowFormAction::IsSelectionInputValid(
}
void ShowFormAction::OnButtonClicked() {
DCHECK(callback_);
delegate_->SetForm(nullptr, base::DoNothing());
UpdateProcessedAction(ACTION_APPLIED);
EndAction(ClientStatus(ACTION_APPLIED));
}
void ShowFormAction::EndAction(const ClientStatus& status) {
delegate_->SetForm(nullptr, base::DoNothing(), base::DoNothing());
UpdateProcessedAction(status);
std::move(callback_).Run(std::move(processed_action_proto_));
}
......
......@@ -25,6 +25,7 @@ class ShowFormAction : public Action {
void InternalProcessAction(ProcessActionCallback callback) override;
void OnFormValuesChanged(const FormProto::Result* form_result);
void OnCancelForm(const ClientStatus& status);
void OnButtonClicked();
bool IsFormValid(const FormProto& form, const FormProto::Result& result);
bool IsCounterInputValid(const CounterInputProto& input,
......@@ -35,6 +36,7 @@ class ShowFormAction : public Action {
const CounterInputProto::Result& result);
bool IsSelectionInputValid(const SelectionInputProto& input,
const SelectionInputProto::Result& result);
void EndAction(const ClientStatus& status);
ProcessActionCallback callback_;
base::WeakPtrFactory<ShowFormAction> weak_ptr_factory_{this};
......
......@@ -355,10 +355,12 @@ const FormProto* Controller::GetForm() const {
bool Controller::SetForm(
std::unique_ptr<FormProto> form,
base::RepeatingCallback<void(const FormProto::Result*)> callback) {
base::RepeatingCallback<void(const FormProto::Result*)> changed_callback,
base::OnceCallback<void(const ClientStatus&)> cancel_callback) {
form_.reset();
form_result_.reset();
form_callback_ = base::DoNothing();
form_changed_callback_ = base::DoNothing();
form_cancel_callback_ = base::DoNothing::Once<const ClientStatus&>();
if (!form) {
for (ControllerObserver& observer : observers_) {
......@@ -408,10 +410,11 @@ bool Controller::SetForm(
// Form is valid.
form_ = std::move(form);
form_result_ = std::move(form_result);
form_callback_ = callback;
form_changed_callback_ = changed_callback;
form_cancel_callback_ = std::move(cancel_callback);
// Call the callback with initial result.
form_callback_.Run(form_result_.get());
form_changed_callback_.Run(form_result_.get());
for (ControllerObserver& observer : observers_) {
observer.OnFormChanged(form_.get());
......@@ -437,7 +440,7 @@ void Controller::SetCounterValue(int input_index,
}
input_result->mutable_counter()->set_values(counter_index, value);
form_callback_.Run(form_result_.get());
form_changed_callback_.Run(form_result_.get());
}
void Controller::SetChoiceSelected(int input_index,
......@@ -458,7 +461,7 @@ void Controller::SetChoiceSelected(int input_index,
}
input_result->mutable_selection()->set_selected(choice_index, selected);
form_callback_.Run(form_result_.get());
form_changed_callback_.Run(form_result_.get());
}
void Controller::AddObserver(ControllerObserver* observer) {
......@@ -516,7 +519,7 @@ void Controller::EnterStoppedState() {
SetDetails(nullptr);
SetUserActions(nullptr);
SetCollectUserDataOptions(nullptr, nullptr);
SetForm(nullptr, base::DoNothing());
SetForm(nullptr, base::DoNothing(), base::DoNothing());
EnterState(AutofillAssistantState::STOPPED);
}
......@@ -994,6 +997,14 @@ void Controller::OnTermsAndConditionsLinkClicked(int link) {
std::move(callback).Run(link);
}
void Controller::OnFormActionLinkClicked(int link) {
if (form_cancel_callback_ && form_result_ != nullptr) {
form_result_->set_link(link);
form_changed_callback_.Run(form_result_.get());
std::move(form_cancel_callback_).Run(ClientStatus(ACTION_APPLIED));
}
}
void Controller::SetDateTimeRangeStart(int year,
int month,
int day,
......
......@@ -119,9 +119,10 @@ class Controller : public ScriptExecutorDelegate,
std::unique_ptr<std::vector<UserAction>> user_actions) override;
void SetViewportMode(ViewportMode mode) override;
void SetPeekMode(ConfigureBottomSheetProto::PeekMode peek_mode) override;
bool SetForm(std::unique_ptr<FormProto> form,
base::RepeatingCallback<void(const FormProto::Result*)> callback)
override;
bool SetForm(
std::unique_ptr<FormProto> form,
base::RepeatingCallback<void(const FormProto::Result*)> changed_callback,
base::OnceCallback<void(const ClientStatus&)> cancel_callback) override;
bool IsNavigatingToNewDocument() override;
bool HasNavigationError() override;
......@@ -168,6 +169,7 @@ class Controller : public ScriptExecutorDelegate,
TermsAndConditionsState terms_and_conditions) override;
void SetLoginOption(std::string identifier) override;
void OnTermsAndConditionsLinkClicked(int link) override;
void OnFormActionLinkClicked(int link) override;
void SetDateTimeRangeStart(int year,
int month,
int day,
......@@ -369,7 +371,9 @@ class Controller : public ScriptExecutorDelegate,
std::unique_ptr<FormProto> form_;
std::unique_ptr<FormProto::Result> form_result_;
base::RepeatingCallback<void(const FormProto::Result*)> form_callback_ =
base::RepeatingCallback<void(const FormProto::Result*)>
form_changed_callback_ = base::DoNothing();
base::OnceCallback<void(const ClientStatus&)> form_cancel_callback_ =
base::DoNothing();
// Value for ScriptExecutorDelegate::IsNavigatingToNewDocument()
......
......@@ -166,7 +166,8 @@ void FakeScriptExecutorDelegate::RemoveListener(Listener* listener) {
bool FakeScriptExecutorDelegate::SetForm(
std::unique_ptr<FormProto> form,
base::RepeatingCallback<void(const FormProto::Result*)> callback) {
base::RepeatingCallback<void(const FormProto::Result*)> changed_callback,
base::OnceCallback<void(const ClientStatus&)> cancel_callback) {
return true;
}
} // namespace autofill_assistant
......@@ -60,9 +60,10 @@ class FakeScriptExecutorDelegate : public ScriptExecutorDelegate {
ViewportMode GetViewportMode() override;
void SetPeekMode(ConfigureBottomSheetProto::PeekMode peek_mode) override;
ConfigureBottomSheetProto::PeekMode GetPeekMode() override;
bool SetForm(std::unique_ptr<FormProto> form,
base::RepeatingCallback<void(const FormProto::Result*)> callback)
override;
bool SetForm(
std::unique_ptr<FormProto> form,
base::RepeatingCallback<void(const FormProto::Result*)> changed_callback,
base::OnceCallback<void(const ClientStatus&)> cancel_callback) override;
bool HasNavigationError() override;
bool IsNavigatingToNewDocument() override;
void RequireUI() override;
......
......@@ -555,8 +555,10 @@ const ClientSettings& ScriptExecutor::GetSettings() {
bool ScriptExecutor::SetForm(
std::unique_ptr<FormProto> form,
base::RepeatingCallback<void(const FormProto::Result*)> callback) {
return delegate_->SetForm(std::move(form), std::move(callback));
base::RepeatingCallback<void(const FormProto::Result*)> changed_callback,
base::OnceCallback<void(const ClientStatus&)> cancel_callback) {
return delegate_->SetForm(std::move(form), std::move(changed_callback),
std::move(cancel_callback));
}
void ScriptExecutor::RequireUI() {
......
......@@ -209,9 +209,10 @@ class ScriptExecutor : public ActionDelegate,
void WaitForWindowHeightChange(
base::OnceCallback<void(const ClientStatus&)> callback) override;
const ClientSettings& GetSettings() override;
bool SetForm(std::unique_ptr<FormProto> form,
base::RepeatingCallback<void(const FormProto::Result*)> callback)
override;
bool SetForm(
std::unique_ptr<FormProto> form,
base::RepeatingCallback<void(const FormProto::Result*)> changed_callback,
base::OnceCallback<void(const ClientStatus&)> cancel_callback) override;
void RequireUI() override;
private:
......
......@@ -10,6 +10,7 @@
#include <string>
#include <vector>
#include "components/autofill_assistant/browser/client_status.h"
#include "components/autofill_assistant/browser/details.h"
#include "components/autofill_assistant/browser/info_box.h"
#include "components/autofill_assistant/browser/state.h"
......@@ -85,7 +86,8 @@ class ScriptExecutorDelegate {
virtual ConfigureBottomSheetProto::PeekMode GetPeekMode() = 0;
virtual bool SetForm(
std::unique_ptr<FormProto> form,
base::RepeatingCallback<void(const FormProto::Result*)> callback) = 0;
base::RepeatingCallback<void(const FormProto::Result*)> changed_callback,
base::OnceCallback<void(const ClientStatus&)> cancel_callback) = 0;
// Makes no area of the screen touchable.
void ClearTouchableElementArea() {
......
......@@ -1664,8 +1664,16 @@ message ShowFormProto {
message FormProto {
// A result associated to this form, such that |input_results[i]| is the
// result of |inputs[i]|.
message Result { repeated FormInputProto.Result input_results = 1; }
// result of |inputs[i]|. If the user clicks a link while in the form action,
// |link| will be set to the index of the clicked link and |input_results|
// may be incomplete.
message Result {
repeated FormInputProto.Result input_results = 1;
// If this is set, it contains the index of the text link that was clicked.
// E.g., <link4>Details</link4> will populate this field with '4' when
// clicked.
optional int32 link = 2;
}
// The different inputs to display.
repeated FormInputProto inputs = 1;
......@@ -1691,13 +1699,16 @@ message CounterInputProto {
// A single counter.
message Counter {
// The label shown with the counter. All occurrences of the '{value}'
// substring will be replaced by the current counter value.
// substring will be replaced by the current counter value. May contain
// links of the form <link1>Some text</link1>.
optional string label = 1;
// Text shown below the label. Optional.
// Text shown below the label. Optional. May contain links of the form
// <link1>Some text</link1>.
optional string description_line_1 = 5;
// Text shown below |description_line_2|. Optional.
// Text shown below |description_line_2|. Optional. May contain links of the
// form <link1>Some text</link1>.
optional string description_line_2 = 8;
// The possible values this counter can have. If empty, the possible values
......@@ -1827,13 +1838,16 @@ message CounterInputProto {
// |min_choices|.
message SelectionInputProto {
message Choice {
// The label of this choice.
// The label of this choice. May contain links of the form <link1>Some
// text</link1>.
optional string label = 1;
// Text shown below the label. Optional.
// Text shown below the label. Optional. May contain links of the form
// <link1>Some text</link1>.
optional string description_line_1 = 3;
// Text shown below |description_line_2|. Optional.
// Text shown below |description_line_2|. Optional. May contain links of the
// form <link1>Some text</link1>.
optional string description_line_2 = 4;
// Whether this choice is selected by default. If |allow_multiple| is false,
......
......@@ -126,6 +126,9 @@ class UiDelegate {
// Called when the user clicks a link on the terms & conditions message.
virtual void OnTermsAndConditionsLinkClicked(int link) = 0;
// Called when the user clicks a link in the form action.
virtual void OnFormActionLinkClicked(int link) = 0;
// Sets the start of the date/time range.
virtual void SetDateTimeRangeStart(int year,
int month,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment