summaryrefslogtreecommitdiffstats
path: root/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/PromptController.java
diff options
context:
space:
mode:
Diffstat (limited to 'mobile/android/geckoview/src/main/java/org/mozilla/geckoview/PromptController.java')
-rw-r--r--mobile/android/geckoview/src/main/java/org/mozilla/geckoview/PromptController.java646
1 files changed, 646 insertions, 0 deletions
diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/PromptController.java b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/PromptController.java
new file mode 100644
index 0000000000..72a07c218e
--- /dev/null
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/PromptController.java
@@ -0,0 +1,646 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package org.mozilla.geckoview;
+
+import android.util.Log;
+import java.util.HashMap;
+import java.util.Map;
+import org.json.JSONException;
+import org.mozilla.gecko.util.EventCallback;
+import org.mozilla.gecko.util.GeckoBundle;
+import org.mozilla.geckoview.Autocomplete.AddressSaveOption;
+import org.mozilla.geckoview.Autocomplete.AddressSelectOption;
+import org.mozilla.geckoview.Autocomplete.CreditCardSaveOption;
+import org.mozilla.geckoview.Autocomplete.CreditCardSelectOption;
+import org.mozilla.geckoview.Autocomplete.LoginSaveOption;
+import org.mozilla.geckoview.Autocomplete.LoginSelectOption;
+import org.mozilla.geckoview.GeckoSession.PromptDelegate;
+import org.mozilla.geckoview.GeckoSession.PromptDelegate.AlertPrompt;
+import org.mozilla.geckoview.GeckoSession.PromptDelegate.AuthPrompt;
+import org.mozilla.geckoview.GeckoSession.PromptDelegate.AuthPrompt.AuthOptions;
+import org.mozilla.geckoview.GeckoSession.PromptDelegate.AutocompleteRequest;
+import org.mozilla.geckoview.GeckoSession.PromptDelegate.BasePrompt;
+import org.mozilla.geckoview.GeckoSession.PromptDelegate.BasePrompt.Observer;
+import org.mozilla.geckoview.GeckoSession.PromptDelegate.BeforeUnloadPrompt;
+import org.mozilla.geckoview.GeckoSession.PromptDelegate.ButtonPrompt;
+import org.mozilla.geckoview.GeckoSession.PromptDelegate.ChoicePrompt;
+import org.mozilla.geckoview.GeckoSession.PromptDelegate.ColorPrompt;
+import org.mozilla.geckoview.GeckoSession.PromptDelegate.DateTimePrompt;
+import org.mozilla.geckoview.GeckoSession.PromptDelegate.FilePrompt;
+import org.mozilla.geckoview.GeckoSession.PromptDelegate.PopupPrompt;
+import org.mozilla.geckoview.GeckoSession.PromptDelegate.PromptInstanceDelegate;
+import org.mozilla.geckoview.GeckoSession.PromptDelegate.PromptResponse;
+import org.mozilla.geckoview.GeckoSession.PromptDelegate.RepostConfirmPrompt;
+import org.mozilla.geckoview.GeckoSession.PromptDelegate.SharePrompt;
+import org.mozilla.geckoview.GeckoSession.PromptDelegate.TextPrompt;
+
+/* package */ class PromptController {
+ private static final String LOGTAG = "Prompts";
+
+ private static class PromptStorage implements BasePrompt.Observer {
+ private final Map<String, BasePrompt> mPrompts = new HashMap<>();
+
+ public void addPrompt(final String id, final BasePrompt prompt) {
+ if (mPrompts.containsKey(id)) {
+ Log.e(LOGTAG, "Prompt already exists! id=" + id);
+ if (BuildConfig.DEBUG_BUILD) {
+ throw new RuntimeException("Prompt already exists! id=" + id);
+ }
+ }
+ mPrompts.put(id, prompt);
+ }
+
+ @Override
+ public void onPromptCompleted(final BasePrompt prompt) {
+ // No need to notify this delegate since the prompt has been completed already.
+ mPrompts.remove(prompt.id);
+ }
+
+ public void dismiss(final String id) {
+ final BasePrompt prompt = mPrompts.get(id);
+ if (prompt == null) {
+ return;
+ }
+ final PromptInstanceDelegate delegate = prompt.getDelegate();
+ if (delegate != null) {
+ delegate.onPromptDismiss(prompt);
+ }
+ mPrompts.remove(prompt.id);
+ }
+
+ public boolean contains(final String id) {
+ return mPrompts.containsKey(id);
+ }
+
+ public void update(final BasePrompt prompt) {
+ final BasePrompt previousPrompt = mPrompts.get(prompt.id);
+ if (previousPrompt == null) {
+ return;
+ }
+ final PromptInstanceDelegate delegate = previousPrompt.getDelegate();
+ if (delegate == null) {
+ return;
+ }
+ prompt.setDelegate(delegate);
+ delegate.onPromptUpdate(prompt);
+ mPrompts.put(prompt.id, prompt);
+ }
+ }
+
+ final PromptStorage mStorage = new PromptStorage();
+
+ public void dismissPrompt(final String id) {
+ mStorage.dismiss(id);
+ }
+
+ public void updatePrompt(final GeckoBundle message) {
+ final String type = message.getString("type");
+ final PromptHandler<?> handler = sPromptHandlers.handlerFor(type);
+ if (handler == null) {
+ // Invalid prompt message type to update the prompt.
+ return;
+ }
+ final BasePrompt prompt = handler.newPrompt(message, mStorage);
+ if (prompt == null) {
+ // Invalid prompt message to update the prompt.
+ return;
+ }
+ if (!mStorage.contains(prompt.id)) {
+ // Invalid prompt id to update the prompt. Dismissed?
+ return;
+ }
+
+ mStorage.update(prompt);
+ }
+
+ public void handleEvent(
+ final GeckoSession session, final GeckoBundle message, final EventCallback callback) {
+ Log.d(LOGTAG, "handleEvent " + message.getString("type"));
+ final PromptDelegate delegate = session.getPromptDelegate();
+ if (delegate == null) {
+ // Default behavior is same as calling dismiss() on callback.
+ callback.sendSuccess(null);
+ return;
+ }
+
+ final String type = message.getString("type");
+ final PromptHandler<?> handler = sPromptHandlers.handlerFor(type);
+ if (handler == null) {
+ callback.sendError("Invalid type: " + type);
+ return;
+ }
+ final GeckoResult<PromptResponse> res = getResponse(message, session, delegate, handler);
+
+ if (res == null) {
+ // Adhere to default behavior if the delegate returns null.
+ callback.sendSuccess(null);
+ } else {
+ res.accept(
+ value -> value.dispatch(callback),
+ exception -> callback.sendError("Failed to get prompt response."));
+ }
+ }
+
+ private <PromptType extends BasePrompt> GeckoResult<PromptResponse> getResponse(
+ final GeckoBundle message,
+ final GeckoSession session,
+ final PromptDelegate delegate,
+ final PromptHandler<PromptType> handler) {
+ final PromptType prompt = handler.newPrompt(message, mStorage);
+ if (prompt == null) {
+ try {
+ Log.e(LOGTAG, "Invalid prompt: " + message.toJSONObject().toString());
+ } catch (final JSONException ex) {
+ Log.e(LOGTAG, "Invalid prompt, invalid data", ex);
+ }
+
+ return GeckoResult.fromException(new IllegalArgumentException("Invalid prompt data."));
+ }
+
+ mStorage.addPrompt(prompt.id, prompt);
+ return handler.callDelegate(prompt, session, delegate);
+ }
+
+ private interface PromptHandler<PromptType extends BasePrompt> {
+ PromptType newPrompt(GeckoBundle info, Observer observer);
+
+ GeckoResult<PromptResponse> callDelegate(
+ PromptType prompt, GeckoSession session, PromptDelegate delegate);
+ }
+
+ private static final class AlertHandler implements PromptHandler<AlertPrompt> {
+ @Override
+ public AlertPrompt newPrompt(final GeckoBundle info, final Observer observer) {
+ return new AlertPrompt(
+ info.getString("id"), info.getString("title"), info.getString("msg"), observer);
+ }
+
+ @Override
+ public GeckoResult<PromptResponse> callDelegate(
+ final AlertPrompt prompt, final GeckoSession session, final PromptDelegate delegate) {
+ return delegate.onAlertPrompt(session, prompt);
+ }
+ }
+
+ private static final class BeforeUnloadHandler implements PromptHandler<BeforeUnloadPrompt> {
+ @Override
+ public BeforeUnloadPrompt newPrompt(final GeckoBundle info, final Observer observer) {
+ return new BeforeUnloadPrompt(info.getString("id"), observer);
+ }
+
+ @Override
+ public GeckoResult<PromptResponse> callDelegate(
+ final BeforeUnloadPrompt prompt,
+ final GeckoSession session,
+ final PromptDelegate delegate) {
+ return delegate.onBeforeUnloadPrompt(session, prompt);
+ }
+ }
+
+ private static final class ButtonHandler implements PromptHandler<ButtonPrompt> {
+ @Override
+ public ButtonPrompt newPrompt(final GeckoBundle info, final Observer observer) {
+ return new ButtonPrompt(
+ info.getString("id"), info.getString("title"), info.getString("msg"), observer);
+ }
+
+ @Override
+ public GeckoResult<PromptResponse> callDelegate(
+ final ButtonPrompt prompt, final GeckoSession session, final PromptDelegate delegate) {
+ return delegate.onButtonPrompt(session, prompt);
+ }
+ }
+
+ private static final class TextHandler implements PromptHandler<TextPrompt> {
+ @Override
+ public TextPrompt newPrompt(final GeckoBundle info, final Observer observer) {
+ return new TextPrompt(
+ info.getString("id"),
+ info.getString("title"),
+ info.getString("msg"),
+ info.getString("value"),
+ observer);
+ }
+
+ @Override
+ public GeckoResult<PromptResponse> callDelegate(
+ final TextPrompt prompt, final GeckoSession session, final PromptDelegate delegate) {
+ return delegate.onTextPrompt(session, prompt);
+ }
+ }
+
+ private static final class AuthHandler implements PromptHandler<AuthPrompt> {
+ @Override
+ public AuthPrompt newPrompt(final GeckoBundle info, final Observer observer) {
+ return new AuthPrompt(
+ info.getString("id"),
+ info.getString("title"),
+ info.getString("msg"),
+ new AuthOptions(info.getBundle("options")),
+ observer);
+ }
+
+ @Override
+ public GeckoResult<PromptResponse> callDelegate(
+ final AuthPrompt prompt, final GeckoSession session, final PromptDelegate delegate) {
+ return delegate.onAuthPrompt(session, prompt);
+ }
+ }
+
+ private static final class ChoiceHandler implements PromptHandler<ChoicePrompt> {
+ @Override
+ public ChoicePrompt newPrompt(final GeckoBundle info, final Observer observer) {
+ final int intMode;
+ final String mode = info.getString("mode");
+ if ("menu".equals(mode)) {
+ intMode = ChoicePrompt.Type.MENU;
+ } else if ("single".equals(mode)) {
+ intMode = ChoicePrompt.Type.SINGLE;
+ } else if ("multiple".equals(mode)) {
+ intMode = ChoicePrompt.Type.MULTIPLE;
+ } else {
+ return null;
+ }
+
+ final GeckoBundle[] choiceBundles = info.getBundleArray("choices");
+ final ChoicePrompt.Choice[] choices;
+ if (choiceBundles == null || choiceBundles.length == 0) {
+ choices = new ChoicePrompt.Choice[0];
+ } else {
+ choices = new ChoicePrompt.Choice[choiceBundles.length];
+ for (int i = 0; i < choiceBundles.length; i++) {
+ choices[i] = new ChoicePrompt.Choice(choiceBundles[i]);
+ }
+ }
+
+ return new ChoicePrompt(
+ info.getString("id"),
+ info.getString("title"),
+ info.getString("msg"),
+ intMode,
+ choices,
+ observer);
+ }
+
+ @Override
+ public GeckoResult<PromptResponse> callDelegate(
+ final ChoicePrompt prompt, final GeckoSession session, final PromptDelegate delegate) {
+ return delegate.onChoicePrompt(session, prompt);
+ }
+ }
+
+ private static final class ColorHandler implements PromptHandler<ColorPrompt> {
+ @Override
+ public ColorPrompt newPrompt(final GeckoBundle info, final Observer observer) {
+ return new ColorPrompt(
+ info.getString("id"),
+ info.getString("title"),
+ info.getString("value"),
+ info.getStringArray("predefinedValues"),
+ observer);
+ }
+
+ @Override
+ public GeckoResult<PromptResponse> callDelegate(
+ final ColorPrompt prompt, final GeckoSession session, final PromptDelegate delegate) {
+ return delegate.onColorPrompt(session, prompt);
+ }
+ }
+
+ private static final class DateTimeHandler implements PromptHandler<DateTimePrompt> {
+ @Override
+ public DateTimePrompt newPrompt(final GeckoBundle info, final Observer observer) {
+ final String mode = info.getString("mode");
+ final int intMode;
+ if ("date".equals(mode)) {
+ intMode = DateTimePrompt.Type.DATE;
+ } else if ("month".equals(mode)) {
+ intMode = DateTimePrompt.Type.MONTH;
+ } else if ("week".equals(mode)) {
+ intMode = DateTimePrompt.Type.WEEK;
+ } else if ("time".equals(mode)) {
+ intMode = DateTimePrompt.Type.TIME;
+ } else if ("datetime-local".equals(mode)) {
+ intMode = DateTimePrompt.Type.DATETIME_LOCAL;
+ } else {
+ return null;
+ }
+
+ final String defaultValue = info.getString("value");
+ final String minValue = info.getString("min");
+ final String maxValue = info.getString("max");
+ final String stepValue = info.getString("step");
+ return new DateTimePrompt(
+ info.getString("id"),
+ info.getString("title"),
+ intMode,
+ defaultValue,
+ minValue,
+ maxValue,
+ stepValue,
+ observer);
+ }
+
+ @Override
+ public GeckoResult<PromptResponse> callDelegate(
+ final DateTimePrompt prompt, final GeckoSession session, final PromptDelegate delegate) {
+ return delegate.onDateTimePrompt(session, prompt);
+ }
+ }
+
+ private static final class FileHandler implements PromptHandler<FilePrompt> {
+ @Override
+ public FilePrompt newPrompt(final GeckoBundle info, final Observer observer) {
+ final String mode = info.getString("mode");
+ final int intMode;
+ if ("single".equals(mode)) {
+ intMode = FilePrompt.Type.SINGLE;
+ } else if ("multiple".equals(mode)) {
+ intMode = FilePrompt.Type.MULTIPLE;
+ } else {
+ return null;
+ }
+
+ final String[] mimeTypes = info.getStringArray("mimeTypes");
+ final int capture = info.getInt("capture");
+ return new FilePrompt(
+ info.getString("id"), info.getString("title"), intMode, capture, mimeTypes, observer);
+ }
+
+ @Override
+ public GeckoResult<PromptResponse> callDelegate(
+ final FilePrompt prompt, final GeckoSession session, final PromptDelegate delegate) {
+ return delegate.onFilePrompt(session, prompt);
+ }
+ }
+
+ private static final class PopupHandler implements PromptHandler<PopupPrompt> {
+ @Override
+ public PopupPrompt newPrompt(final GeckoBundle info, final Observer observer) {
+ return new PopupPrompt(info.getString("id"), info.getString("targetUri"), observer);
+ }
+
+ @Override
+ public GeckoResult<PromptResponse> callDelegate(
+ final PopupPrompt prompt, final GeckoSession session, final PromptDelegate delegate) {
+ return delegate.onPopupPrompt(session, prompt);
+ }
+ }
+
+ private static final class RepostHandler implements PromptHandler<RepostConfirmPrompt> {
+ @Override
+ public RepostConfirmPrompt newPrompt(final GeckoBundle info, final Observer observer) {
+ return new RepostConfirmPrompt(info.getString("id"), observer);
+ }
+
+ @Override
+ public GeckoResult<PromptResponse> callDelegate(
+ final RepostConfirmPrompt prompt,
+ final GeckoSession session,
+ final PromptDelegate delegate) {
+ return delegate.onRepostConfirmPrompt(session, prompt);
+ }
+ }
+
+ private static final class ShareHandler implements PromptHandler<SharePrompt> {
+ @Override
+ public SharePrompt newPrompt(final GeckoBundle info, final Observer observer) {
+ return new SharePrompt(
+ info.getString("id"),
+ info.getString("title"),
+ info.getString("text"),
+ info.getString("uri"),
+ observer);
+ }
+
+ @Override
+ public GeckoResult<PromptResponse> callDelegate(
+ final SharePrompt prompt, final GeckoSession session, final PromptDelegate delegate) {
+ return delegate.onSharePrompt(session, prompt);
+ }
+ }
+
+ private static final class LoginSaveHandler
+ implements PromptHandler<AutocompleteRequest<LoginSaveOption>> {
+ @Override
+ public AutocompleteRequest<LoginSaveOption> newPrompt(
+ final GeckoBundle info, final Observer observer) {
+ final int hint = info.getInt("hint");
+ final GeckoBundle[] loginBundles = info.getBundleArray("logins");
+
+ if (loginBundles == null) {
+ return null;
+ }
+
+ final Autocomplete.LoginSaveOption[] options =
+ new Autocomplete.LoginSaveOption[loginBundles.length];
+
+ for (int i = 0; i < options.length; ++i) {
+ options[i] =
+ new Autocomplete.LoginSaveOption(new Autocomplete.LoginEntry(loginBundles[i]), hint);
+ }
+
+ return new AutocompleteRequest<>(info.getString("id"), options, observer);
+ }
+
+ @Override
+ public GeckoResult<PromptResponse> callDelegate(
+ final AutocompleteRequest<LoginSaveOption> prompt,
+ final GeckoSession session,
+ final PromptDelegate delegate) {
+ return delegate.onLoginSave(session, prompt);
+ }
+ }
+
+ private static final class CreditCardSaveHandler
+ implements PromptHandler<AutocompleteRequest<CreditCardSaveOption>> {
+ @Override
+ public AutocompleteRequest<CreditCardSaveOption> newPrompt(
+ final GeckoBundle info, final Observer observer) {
+ final int hint = info.getInt("hint");
+ final GeckoBundle[] creditCardBundles = info.getBundleArray("creditCards");
+
+ if (creditCardBundles == null) {
+ return null;
+ }
+
+ final Autocomplete.CreditCardSaveOption[] options =
+ new Autocomplete.CreditCardSaveOption[creditCardBundles.length];
+
+ for (int i = 0; i < options.length; ++i) {
+ options[i] =
+ new Autocomplete.CreditCardSaveOption(
+ new Autocomplete.CreditCard(creditCardBundles[i]), hint);
+ }
+
+ return new PromptDelegate.AutocompleteRequest<>(info.getString("id"), options, observer);
+ }
+
+ @Override
+ public GeckoResult<PromptResponse> callDelegate(
+ final AutocompleteRequest<CreditCardSaveOption> prompt,
+ final GeckoSession session,
+ final PromptDelegate delegate) {
+ return delegate.onCreditCardSave(session, prompt);
+ }
+ }
+
+ private static final class AddressSaveHandler
+ implements PromptHandler<AutocompleteRequest<AddressSaveOption>> {
+ @Override
+ public AutocompleteRequest<AddressSaveOption> newPrompt(
+ final GeckoBundle info, final Observer observer) {
+ final GeckoBundle[] addressBundles = info.getBundleArray("addresses");
+
+ if (addressBundles == null) {
+ return null;
+ }
+
+ final Autocomplete.AddressSaveOption[] options =
+ new Autocomplete.AddressSaveOption[addressBundles.length];
+
+ final int hint = info.getInt("hint");
+ for (int i = 0; i < options.length; ++i) {
+ options[i] =
+ new Autocomplete.AddressSaveOption(new Autocomplete.Address(addressBundles[i]), hint);
+ }
+
+ return new AutocompleteRequest<>(info.getString("id"), options, observer);
+ }
+
+ @Override
+ public GeckoResult<PromptResponse> callDelegate(
+ final AutocompleteRequest<AddressSaveOption> prompt,
+ final GeckoSession session,
+ final PromptDelegate delegate) {
+ return delegate.onAddressSave(session, prompt);
+ }
+ }
+
+ private static final class LoginSelectHandler
+ implements PromptHandler<AutocompleteRequest<LoginSelectOption>> {
+ @Override
+ public AutocompleteRequest<LoginSelectOption> newPrompt(
+ final GeckoBundle info, final Observer observer) {
+ final GeckoBundle[] optionBundles = info.getBundleArray("options");
+
+ if (optionBundles == null) {
+ return null;
+ }
+
+ final Autocomplete.LoginSelectOption[] options =
+ new Autocomplete.LoginSelectOption[optionBundles.length];
+
+ for (int i = 0; i < options.length; ++i) {
+ options[i] = Autocomplete.LoginSelectOption.fromBundle(optionBundles[i]);
+ }
+
+ return new AutocompleteRequest<>(info.getString("id"), options, observer);
+ }
+
+ @Override
+ public GeckoResult<PromptResponse> callDelegate(
+ final AutocompleteRequest<LoginSelectOption> prompt,
+ final GeckoSession session,
+ final PromptDelegate delegate) {
+ return delegate.onLoginSelect(session, prompt);
+ }
+ }
+
+ private static final class CreditCardSelectHandler
+ implements PromptHandler<AutocompleteRequest<CreditCardSelectOption>> {
+ @Override
+ public AutocompleteRequest<CreditCardSelectOption> newPrompt(
+ final GeckoBundle info, final Observer observer) {
+ final GeckoBundle[] optionBundles = info.getBundleArray("options");
+
+ if (optionBundles == null) {
+ return null;
+ }
+
+ final Autocomplete.CreditCardSelectOption[] options =
+ new Autocomplete.CreditCardSelectOption[optionBundles.length];
+
+ for (int i = 0; i < options.length; ++i) {
+ options[i] = Autocomplete.CreditCardSelectOption.fromBundle(optionBundles[i]);
+ }
+
+ return new AutocompleteRequest<>(info.getString("id"), options, observer);
+ }
+
+ @Override
+ public GeckoResult<PromptResponse> callDelegate(
+ final AutocompleteRequest<CreditCardSelectOption> prompt,
+ final GeckoSession session,
+ final PromptDelegate delegate) {
+ return delegate.onCreditCardSelect(session, prompt);
+ }
+ }
+
+ private static final class AddressSelectHandler
+ implements PromptHandler<AutocompleteRequest<AddressSelectOption>> {
+ @Override
+ public AutocompleteRequest<AddressSelectOption> newPrompt(
+ final GeckoBundle info, final Observer observer) {
+ final GeckoBundle[] optionBundles = info.getBundleArray("options");
+
+ if (optionBundles == null) {
+ return null;
+ }
+
+ final Autocomplete.AddressSelectOption[] options =
+ new Autocomplete.AddressSelectOption[optionBundles.length];
+
+ for (int i = 0; i < options.length; ++i) {
+ options[i] = Autocomplete.AddressSelectOption.fromBundle(optionBundles[i]);
+ }
+
+ return new AutocompleteRequest<>(info.getString("id"), options, observer);
+ }
+
+ @Override
+ public GeckoResult<PromptResponse> callDelegate(
+ final AutocompleteRequest<AddressSelectOption> prompt,
+ final GeckoSession session,
+ final PromptDelegate delegate) {
+ return delegate.onAddressSelect(session, prompt);
+ }
+ }
+
+ private static class PromptHandlers {
+ final Map<String, PromptHandler<?>> mPromptHandlers = new HashMap<>();
+
+ public void register(final PromptHandler<?> handler, final String type) {
+ mPromptHandlers.put(type, handler);
+ }
+
+ public PromptHandler<?> handlerFor(final String type) {
+ return mPromptHandlers.get(type);
+ }
+ }
+
+ private static final PromptHandlers sPromptHandlers = new PromptHandlers();
+
+ static {
+ sPromptHandlers.register(new AlertHandler(), "alert");
+ sPromptHandlers.register(new BeforeUnloadHandler(), "beforeUnload");
+ sPromptHandlers.register(new ButtonHandler(), "button");
+ sPromptHandlers.register(new TextHandler(), "text");
+ sPromptHandlers.register(new AuthHandler(), "auth");
+ sPromptHandlers.register(new ChoiceHandler(), "choice");
+ sPromptHandlers.register(new ColorHandler(), "color");
+ sPromptHandlers.register(new DateTimeHandler(), "datetime");
+ sPromptHandlers.register(new FileHandler(), "file");
+ sPromptHandlers.register(new PopupHandler(), "popup");
+ sPromptHandlers.register(new RepostHandler(), "repost");
+ sPromptHandlers.register(new ShareHandler(), "share");
+ sPromptHandlers.register(new LoginSaveHandler(), "Autocomplete:Save:Login");
+ sPromptHandlers.register(new CreditCardSaveHandler(), "Autocomplete:Save:CreditCard");
+ sPromptHandlers.register(new AddressSaveHandler(), "Autocomplete:Save:Address");
+ sPromptHandlers.register(new LoginSelectHandler(), "Autocomplete:Select:Login");
+ sPromptHandlers.register(new CreditCardSelectHandler(), "Autocomplete:Select:CreditCard");
+ sPromptHandlers.register(new AddressSelectHandler(), "Autocomplete:Select:Address");
+ }
+}