PromptRequest.kt
/* 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 mozilla.components.concept.engine.prompt
import android.content.Context
import android.net.Uri
import mozilla.components.concept.engine.prompt.PromptRequest.Authentication.Level
import mozilla.components.concept.engine.prompt.PromptRequest.Authentication.Method
import mozilla.components.concept.engine.prompt.PromptRequest.File
import mozilla.components.concept.engine.prompt.PromptRequest.TimeSelection.Type
import mozilla.components.concept.identitycredential.Account
import mozilla.components.concept.identitycredential.Provider
import mozilla.components.concept.storage.Address
import mozilla.components.concept.storage.CreditCardEntry
import mozilla.components.concept.storage.Login
import mozilla.components.concept.storage.LoginEntry
import java.util.UUID
/**
* Value type that represents a request for showing a native dialog for prompt web content.
*
* @param shouldDismissOnLoad Whether or not the dialog should automatically be dismissed when a new page is loaded.
* Defaults to `true`.
* @param uid [PromptRequest] unique identifier. Defaults to a random UUID.
* (This two parameters, though present in all subclasses are not evaluated in subclasses equals() calls)
*/
sealed class PromptRequest(
val shouldDismissOnLoad: Boolean = true,
val uid: String = UUID.randomUUID().toString(),
) {
/**
* Value type that represents a request for a single choice prompt.
* @property choices All the possible options.
* @property onConfirm A callback indicating which option was selected.
* @property onDismiss A callback executed when dismissed.
*/
data class SingleChoice(
val choices: Array<Choice>,
val onConfirm: (Choice) -> Unit,
override val onDismiss: () -> Unit,
) : PromptRequest(), Dismissible
/**
* Value type that represents a request for a multiple choice prompt.
* @property choices All the possible options.
* @property onConfirm A callback indicating witch options has been selected.
* @property onDismiss A callback executed when dismissed.
*/
data class MultipleChoice(
val choices: Array<Choice>,
val onConfirm: (Array<Choice>) -> Unit,
override val onDismiss: () -> Unit,
) : PromptRequest(), Dismissible
/**
* Value type that represents a request for a menu choice prompt.
* @property choices All the possible options.
* @property onConfirm A callback indicating which option was selected.
* @property onDismiss A callback executed when dismissed.
*/
data class MenuChoice(
val choices: Array<Choice>,
val onConfirm: (Choice) -> Unit,
override val onDismiss: () -> Unit,
) : PromptRequest(), Dismissible
/**
* Value type that represents a request for an alert prompt.
* @property title of the dialog.
* @property message the body of the dialog.
* @property hasShownManyDialogs tells if this page has shown multiple prompts within a short period of time.
* @property onConfirm tells the web page if it should continue showing alerts or not.
* @property onDismiss callback to let the page know the user dismissed the dialog.
*/
data class Alert(
val title: String,
val message: String,
val hasShownManyDialogs: Boolean = false,
val onConfirm: (Boolean) -> Unit,
override val onDismiss: () -> Unit,
) : PromptRequest(), Dismissible
/**
* BeforeUnloadPrompt represents the onbeforeunload prompt.
* This prompt is shown when a user is leaving a website and there is formation pending to be saved.
* For more information see https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onbeforeunload.
* @property title of the dialog.
* @property onLeave callback to notify that the user wants leave the site.
* @property onStay callback to notify that the user wants stay in the site.
* @property onDismiss callback to let the page know the user dismissed the dialog.
*/
data class BeforeUnload(
val title: String,
val onLeave: () -> Unit,
val onStay: () -> Unit,
override val onDismiss: () -> Unit,
) : PromptRequest(shouldDismissOnLoad = false), Dismissible
/**
* Value type that represents a request for a client authentication certificate prompt.
* @property host the domain (or IP address) that requested the certificate.
* @property onComplete callback that is called with the chosen certificate alias (or null if
* none was chosen) when the user deals with the prompt.
*/
data class CertificateRequest(
val host: String,
val onComplete: (String?) -> Unit,
) : PromptRequest()
/**
* Value type that represents a request for a save credit card prompt.
* @property creditCard the [CreditCardEntry] to save or update.
* @property onConfirm callback that is called when the user confirms the save credit card request.
* @property onDismiss callback to let the page know the user dismissed the dialog.
*/
data class SaveCreditCard(
val creditCard: CreditCardEntry,
val onConfirm: (CreditCardEntry) -> Unit,
override val onDismiss: () -> Unit,
) : PromptRequest(shouldDismissOnLoad = false), Dismissible
/**
* Value type that represents Identity Credential request prompts.
* @property onDismiss callback to let the page know the user dismissed the dialog.
*/
sealed class IdentityCredential(
override val onDismiss: () -> Unit,
) : PromptRequest(shouldDismissOnLoad = false), Dismissible {
/**
* Value type that represents Identity Credential request for selecting a [Provider] prompt.
* @property providers A list of providers which the user could select from.
* @property onConfirm callback to let the page know the user selected a provider.
* @property onDismiss callback to let the page know the user dismissed the dialog.
*/
data class SelectProvider(
val providers: List<Provider>,
val onConfirm: (Provider) -> Unit,
override val onDismiss: () -> Unit,
) : IdentityCredential(onDismiss), Dismissible
/**
* Value type that represents Identity Credential request for selecting an [Account] prompt.
* @property accounts A list of accounts which the user could select from.
* @property providerName The name of the provider that will be used for the login
* @property onConfirm callback to let the page know the user selected an account.
* @property onDismiss callback to let the page know the user dismissed the dialog.
*/
data class SelectAccount(
val accounts: List<Account>,
val provider: Provider,
val onConfirm: (Account) -> Unit,
override val onDismiss: () -> Unit,
) : IdentityCredential(onDismiss), Dismissible
/**
* Value type that represents Identity Credential request for a privacy policy prompt.
* @property privacyPolicyUrl A The URL where the policy for using this provider is hosted.
* @property termsOfServiceUrl The URL where the terms of service for using this provider are.
* @property providerDomain The domain of the provider.
* @property host The host of the provider.
* @property icon A base64 string for given icon for the provider; may be null.
* @property onConfirm callback to let the page know the user have confirmed or not the privacy policy.
* @property onDismiss callback to let the page know the user dismissed the dialog.
*/
data class PrivacyPolicy(
val privacyPolicyUrl: String,
val termsOfServiceUrl: String,
val providerDomain: String,
val host: String,
val icon: String?,
val onConfirm: (Boolean) -> Unit,
override val onDismiss: () -> Unit,
) : IdentityCredential(onDismiss), Dismissible
}
/**
* Value type that represents a request for a select credit card prompt.
* @property creditCards a list of [CreditCardEntry]s to select from.
* @property onConfirm callback that is called when the user confirms the credit card selection.
* @property onDismiss callback to let the page know the user dismissed the dialog.
*/
data class SelectCreditCard(
val creditCards: List<CreditCardEntry>,
val onConfirm: (CreditCardEntry) -> Unit,
override val onDismiss: () -> Unit,
) : PromptRequest(), Dismissible
/**
* Value type that represents a request for a save login prompt.
* @property hint a value that helps to determine the appropriate prompting behavior.
* @property logins a list of logins that are associated with the current domain.
* @property onConfirm callback that is called when the user wants to save the login.
* @property onDismiss callback to let the page know the user dismissed the dialog.
*/
data class SaveLoginPrompt(
val hint: Int,
val logins: List<LoginEntry>,
val onConfirm: (LoginEntry) -> Unit,
override val onDismiss: () -> Unit,
) : PromptRequest(shouldDismissOnLoad = false), Dismissible
/**
* Value type that represents a request for a select login prompt.
* @property logins a list of logins that are associated with the current domain.
* @property generatedPassword the suggested strong password that was generated.
* @property onConfirm callback that is called when the user wants to select the login.
* @property onDismiss callback to let the page know the user dismissed the dialog.
*/
data class SelectLoginPrompt(
val logins: List<Login>,
val generatedPassword: String?,
val onConfirm: (Login) -> Unit,
override val onDismiss: () -> Unit,
) : PromptRequest(), Dismissible
/**
* Value type that represents a request for a select address prompt.
*
* This prompt is triggered by the user focusing on an address field.
*
* @property addresses List of addresses for the user to choose from.
* @property onConfirm Callback used to confirm the selected address.
* @property onDismiss Callback used to dismiss the address prompt.
*/
data class SelectAddress(
val addresses: List<Address>,
val onConfirm: (Address) -> Unit,
override val onDismiss: () -> Unit,
) : PromptRequest(), Dismissible
/**
* Value type that represents a request for an alert prompt to enter a message.
* @property title title of the dialog.
* @property inputLabel the label of the field the user should fill.
* @property inputValue the default value of the field.
* @property hasShownManyDialogs tells if this page has shown multiple prompts within a short period of time.
* @property onConfirm tells the web page if it should continue showing alerts or not.
* @property onDismiss callback to let the page know the user dismissed the dialog.
*/
data class TextPrompt(
val title: String,
val inputLabel: String,
val inputValue: String,
val hasShownManyDialogs: Boolean = false,
val onConfirm: (Boolean, String) -> Unit,
override val onDismiss: () -> Unit,
) : PromptRequest(), Dismissible
/**
* Value type that represents a request for a date prompt for picking a year, month, and day.
* @property title of the dialog.
* @property initialDate date that dialog should be set by default.
* @property minimumDate date allow to be selected.
* @property maximumDate date allow to be selected.
* @property type indicate which [Type] of selection de user wants.
* @property onConfirm callback that is called when the date is selected.
* @property onClear callback that is called when the user requests the picker to be clear up.
* @property onDismiss A callback executed when dismissed.
*/
@Suppress("LongParameterList")
class TimeSelection(
val title: String,
val initialDate: java.util.Date,
val minimumDate: java.util.Date?,
val maximumDate: java.util.Date?,
val stepValue: String? = null,
val type: Type = Type.DATE,
val onConfirm: (java.util.Date) -> Unit,
val onClear: () -> Unit,
override val onDismiss: () -> Unit,
) : PromptRequest(), Dismissible {
enum class Type {
DATE, DATE_AND_TIME, TIME, MONTH
}
}
/**
* Value type that represents a request for a selecting one or multiple files.
* @property mimeTypes a set of allowed mime types. Only these file types can be selected.
* @property isMultipleFilesSelection true if the user can select more that one file false otherwise.
* @property captureMode indicates if the local media capturing capabilities should be used,
* such as the camera or microphone.
* @property onSingleFileSelected callback to notify that the user has selected a single file.
* @property onMultipleFilesSelected callback to notify that the user has selected multiple files.
* @property onDismiss callback to notify that the user has canceled the file selection.
*/
data class File(
val mimeTypes: Array<out String>,
val isMultipleFilesSelection: Boolean = false,
val captureMode: FacingMode = FacingMode.NONE,
val onSingleFileSelected: (Context, Uri) -> Unit,
val onMultipleFilesSelected: (Context, Array<Uri>) -> Unit,
override val onDismiss: () -> Unit,
) : PromptRequest(), Dismissible {
/**
* @deprecated Use the new primary constructor.
*/
constructor(
mimeTypes: Array<out String>,
isMultipleFilesSelection: Boolean,
onSingleFileSelected: (Context, Uri) -> Unit,
onMultipleFilesSelected: (Context, Array<Uri>) -> Unit,
onDismiss: () -> Unit,
) : this(
mimeTypes,
isMultipleFilesSelection,
FacingMode.NONE,
onSingleFileSelected,
onMultipleFilesSelected,
onDismiss,
)
enum class FacingMode {
NONE, ANY, FRONT_CAMERA, BACK_CAMERA
}
companion object {
/**
* Default default directory name for temporary uploads.
*/
const val DEFAULT_UPLOADS_DIR_NAME = "/uploads"
}
}
/**
* Value type that represents a request for an authentication prompt.
* For more related info take a look at
* <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication>MDN docs</a>
* @property uri The URI for the auth request or null if unknown.
* @property title of the dialog.
* @property message the body of the dialog.
* @property userName default value provide for this session.
* @property password default value provide for this session.
* @property method type of authentication, valid values [Method.HOST] and [Method.PROXY].
* @property level indicates the level of security of the authentication like [Level.NONE],
* [Level.SECURED] and [Level.PASSWORD_ENCRYPTED].
* @property onlyShowPassword indicates if the dialog should only include a password field.
* @property previousFailed indicates if this request is the result of a previous failed attempt to login.
* @property isCrossOrigin indicates if this request is from a cross-origin sub-resource.
* @property onConfirm callback to indicate the user want to start the authentication flow.
* @property onDismiss callback to indicate the user dismissed this request.
*/
data class Authentication(
val uri: String?,
val title: String,
val message: String,
val userName: String,
val password: String,
val method: Method,
val level: Level,
val onlyShowPassword: Boolean = false,
val previousFailed: Boolean = false,
val isCrossOrigin: Boolean = false,
val onConfirm: (String, String) -> Unit,
override val onDismiss: () -> Unit,
) : PromptRequest(), Dismissible {
enum class Level {
NONE, PASSWORD_ENCRYPTED, SECURED
}
enum class Method {
HOST, PROXY
}
}
/**
* Value type that represents a request for a selecting one or multiple files.
* @property defaultColor true if the user can select more that one file false otherwise.
* @property onConfirm callback to notify that the user has selected a color.
* @property onDismiss callback to notify that the user has canceled the dialog.
*/
data class Color(
val defaultColor: String,
val onConfirm: (String) -> Unit,
override val onDismiss: () -> Unit,
) : PromptRequest(), Dismissible
/**
* Value type that represents a request for showing a pop-pup prompt.
* This occurs when content attempts to open a new window,
* in a way that doesn't appear to be the result of user input.
*
* @property targetUri the uri that the page is trying to open.
* @property onAllow callback to notify that the user wants to open the [targetUri].
* @property onDeny callback to notify that the user doesn't want to open the [targetUri].
*/
data class Popup(
val targetUri: String,
val onAllow: () -> Unit,
val onDeny: () -> Unit,
override val onDismiss: () -> Unit = { onDeny() },
) : PromptRequest(), Dismissible
/**
* Value type that represents a request for showing a
* <a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/confirm>confirm prompt</a>.
*
* The prompt can have up to three buttons, they could be positive, negative and neutral.
*
* @property title of the dialog.
* @property message the body of the dialog.
* @property hasShownManyDialogs tells if this page has shown multiple prompts within a short period of time.
* @property positiveButtonTitle optional title for the positive button.
* @property negativeButtonTitle optional title for the negative button.
* @property neutralButtonTitle optional title for the neutral button.
* @property onConfirmPositiveButton callback to notify that the user has clicked the positive button.
* @property onConfirmNegativeButton callback to notify that the user has clicked the negative button.
* @property onConfirmNeutralButton callback to notify that the user has clicked the neutral button.
* @property onDismiss callback to notify that the user has canceled the dialog.
*/
data class Confirm(
val title: String,
val message: String,
val hasShownManyDialogs: Boolean = false,
val positiveButtonTitle: String = "",
val negativeButtonTitle: String = "",
val neutralButtonTitle: String = "",
val onConfirmPositiveButton: (Boolean) -> Unit,
val onConfirmNegativeButton: (Boolean) -> Unit,
val onConfirmNeutralButton: (Boolean) -> Unit,
override val onDismiss: () -> Unit,
) : PromptRequest(), Dismissible
/**
* Value type that represents a request to share data.
* https://w3c.github.io/web-share/
* @property data Share data containing title, text, and url of the request.
* @property onSuccess Callback to notify that the user hared with another app successfully.
* @property onFailure Callback to notify that the user attempted to share with another app, but it failed.
* @property onDismiss Callback to notify that the user aborted the share.
*/
data class Share(
val data: ShareData,
val onSuccess: () -> Unit,
val onFailure: () -> Unit,
override val onDismiss: () -> Unit,
) : PromptRequest(), Dismissible
/**
* Value type that represents a request for a repost prompt.
*
* This prompt is shown whenever refreshing or navigating to a page needs resubmitting
* POST data that has been submitted already.
*
* @property onConfirm callback to notify that the user wants to refresh the webpage.
* @property onDismiss callback to notify that the user wants stay in the current webpage and not refresh it.
*/
data class Repost(
val onConfirm: () -> Unit,
override val onDismiss: () -> Unit,
) : PromptRequest(), Dismissible
interface Dismissible {
val onDismiss: () -> Unit
}
}
/**
* Checks if the current [PromptRequest] is a request to pick an image.
*
* @return true if the current request is a request for selecting one or more images, false otherwise.
*/
fun PromptRequest?.isPhotoRequest(): Boolean {
return this is File && mimeTypes.any { it.startsWith("image/") }
}
/**
* Checks if the current [PromptRequest] is a request to pick a video.
*
* @return true if the current request is a request for selecting one or more videos, false otherwise.
*/
fun PromptRequest?.isVideoRequest(): Boolean {
return this is File && mimeTypes.any { it.startsWith("video/") }
}