{"version":3,"file":"bootprompt.min.js","sources":["../../src/bootprompt.ts"],"sourcesContent":["/**\n * bootprompt.js\n * license: MIT\n * http://github.com/lddubeau/bootprompt\n */\n\n// tslint:disable-next-line:no-import-side-effect\nimport \"bootstrap\";\n// tslint:disable-next-line:import-name match-default-export-name\nimport $ from \"jquery\";\n\n// We use this to keep versync happy.\nconst version = \"5.0.0\";\n\n// But export this.\nexport const VERSION = version;\n\nexport type LocaleField = \"OK\" | \"CANCEL\" | \"CONFIRM\";\nexport type LocaleSpec = Record;\nexport interface Locale {\n name: string;\n spec: LocaleSpec;\n}\n\nconst LOCALE_FIELDS: LocaleField[] = [\"OK\", \"CANCEL\", \"CONFIRM\"];\n\nconst definedLocales: Record = Object.create(null);\n\nexport type StringOrDocumentContent =\n string | Element | DocumentFragment | Text | JQuery;\n\nexport type GeneralCallback =\n (this: JQuery, event: JQuery.TriggeredEvent) => boolean | void;\n\nexport interface Button {\n label?: string;\n className?: string;\n callback?: GeneralCallback;\n}\n\ninterface SanitizedButton extends Button {\n label: string;\n className: string;\n}\n\nexport type ButtonSpec = Button | GeneralCallback;\n\nexport interface Buttons {\n // We want | undefined here so that we can declare specific names as being\n // optional.\n [key: string]: ButtonSpec | undefined;\n}\n\ninterface SanitizedButtons extends Buttons {\n [key: string]: SanitizedButton;\n}\n\nexport interface OkButton extends Buttons {\n ok: ButtonSpec;\n}\n\nexport interface ConfirmCancelButtons extends Buttons {\n confirm?: ButtonSpec;\n cancel?: ButtonSpec;\n}\n\n// tslint:disable-next-line:no-any\nexport interface CommonOptions {\n message?: StringOrDocumentContent;\n title?: StringOrDocumentContent;\n callback?(...args: T): boolean | void;\n onEscape?: boolean | GeneralCallback;\n show?: boolean;\n backdrop?: boolean | \"static\";\n closeButton?: boolean;\n animate?: boolean;\n className?: string;\n size?: \"large\" | \"small\";\n locale?: string;\n buttons?: Buttons;\n swapButtonOrder?: boolean;\n centerVertical?: boolean;\n container?: string | Element | JQuery;\n}\n\n// tslint:disable-next-line:no-any\nexport interface DialogOptions extends CommonOptions{\n message: StringOrDocumentContent;\n}\n\ninterface SanitizedDialogOptions extends DialogOptions {\n container: string | Element | JQuery;\n buttons: SanitizedButtons;\n}\n\nexport interface AlertOptions extends CommonOptions<[]> {\n buttons?: OkButton;\n}\n\nexport interface ConfirmOptions extends CommonOptions<[boolean]> {\n message: StringOrDocumentContent;\n buttons?: ConfirmCancelButtons;\n}\n\nexport interface PromptCommonOptions\n extends CommonOptions {\n title: StringOrDocumentContent;\n buttons?: ConfirmCancelButtons;\n pattern?: string;\n}\n\nexport interface TextPromptOptions extends\nPromptCommonOptions<[string | null]> {\n inputType?: \"text\" | \"password\" | \"textarea\" | \"email\";\n value?: string;\n maxlength?: number;\n placeholder?: string;\n required?: boolean;\n}\n\nexport interface NumericPromptOptions extends\nPromptCommonOptions<[string | null]> {\n inputType: \"number\" | \"range\";\n placeholder?: string;\n value?: string;\n min?: string;\n max?: string;\n step?: string;\n required?: boolean;\n}\n\nexport interface TimePromptOptions\nextends PromptCommonOptions<[string | null]> {\n inputType: \"time\";\n placeholder?: string;\n value?: string;\n min?: string;\n max?: string;\n step?: string;\n required?: boolean;\n}\n\nexport interface DatePromptOptions\nextends PromptCommonOptions<[string | null]> {\n inputType: \"date\";\n placeholder?: string;\n value?: string;\n min?: string;\n max?: string;\n required?: boolean;\n}\n\nexport interface InputOption {\n text: string;\n value: string;\n group?: string;\n}\n\nexport interface CommonSelectOptions\n extends PromptCommonOptions {\n inputType: \"select\";\n inputOptions: InputOption[];\n required?: boolean;\n}\n\nexport interface MultipleSelectPromptOptions\nextends CommonSelectOptions<[string[] | null]> {\n value?: string[] | string;\n multiple: true;\n}\n\nexport interface SingleSelectPromptOptions\nextends CommonSelectOptions<[string | null]> {\n value?: string;\n multiple?: false;\n}\n\nexport type SelectPromptOptions =\n MultipleSelectPromptOptions | SingleSelectPromptOptions;\n\nexport interface CheckboxPromptOptions\nextends PromptCommonOptions<[string | string[] | null]> {\n inputType: \"checkbox\";\n value?: string | string[];\n inputOptions: InputOption[];\n}\n\nexport interface RadioPromptOptions\nextends PromptCommonOptions<[string | null]> {\n inputType: \"radio\";\n value?: string;\n inputOptions: InputOption[];\n}\n\nexport type PromptOptions = TextPromptOptions | SelectPromptOptions |\n NumericPromptOptions | TimePromptOptions | DatePromptOptions |\n CheckboxPromptOptions | RadioPromptOptions;\n\n// On platforms that support Object.assign, use it.\n// tslint:disable:no-any\nconst assign = (Object as any).assign !== undefined ?\n ((a: {}, b: {}) => (Object as any).assign(a, b)) :\n // For coverage purposes we don't run the tests on platforms that don't\n // have assign.\n /* istanbul ignore next */\n ((a: any, b: any) => $.extend(a, b));\n// tslint:enable:no-any\n\nconst templates = {\n dialog: `\\\n
\\\n
\\\n
\\\n
\\\n
\\\n
\\\n
`,\n header: `\\\n
\\\n
\\\n
`,\n footer: `
`,\n closeButton: `\n`,\n form: `
`,\n button: ``,\n option: \"\",\n promptMessage: `
`,\n inputs: {\n text: `\\\n`,\n textarea: `\\\n`,\n email: `\\\n`,\n select: `\\\n`,\n checkbox: `\\\n
`,\n radio: `\\\n
`,\n date: `\\\n`,\n time: `\\\n`,\n number: `\\\n`,\n password: `\\\n`,\n range: `\\\n`,\n },\n};\n\n// tslint:disable-next-line:no-any\nconst defaults: Record = {\n // default language\n locale: \"en\",\n // show backdrop or not. Default to static so user has to interact with dialog\n backdrop: \"static\",\n // animate the modal in/out\n animate: true,\n // additional class string applied to the top level dialog\n className: undefined,\n // whether or not to include a close button\n closeButton: true,\n // show the dialog immediately by default\n show: true,\n // dialog container\n container: \"body\",\n // default value (used by the prompt helper)\n value: undefined,\n // default input type (used by the prompt helper)\n inputType: \"text\",\n // switch button order from cancel/confirm (default) to confirm/cancel\n swapButtonOrder: false,\n // center modal vertically in page\n centerVertical: false,\n // Append `multiple` property to the select when using the `prompt` helper\n multiple: false,\n};\n\n//\n// PUBLIC FUNCTIONS\n//\n\n// Return all currently registered locales, or a specific locale if \"name\" is\n// defined\nexport function locales(): Record;\nexport function locales(name: string): LocaleSpec | undefined;\nexport function locales(name?: string):\nRecord | LocaleSpec | undefined {\n return name !== undefined ? definedLocales[name] : definedLocales;\n}\n\n// Register localized strings for the OK, Confirm, and Cancel buttons\nexport function addLocale(name: string, values: LocaleSpec): void {\n for (const field of LOCALE_FIELDS) {\n if (typeof values[field] !== \"string\") {\n throw new Error(`Please supply a translation for \"${field}\"`);\n }\n }\n\n definedLocales[name] = values;\n}\n\n// Remove a previously-registered locale\nexport function removeLocale(name: string): void {\n if (name !== \"en\") {\n delete definedLocales[name];\n }\n else {\n throw new Error(`\"en\" is used as the default and fallback locale and \\\ncannot be removed.`);\n }\n}\n\nexport function setLocale(name: string): void {\n setDefaults(\"locale\", name);\n}\n\nexport function setDefaults(defaults: Record): void;\nexport function setDefaults(name: string, value: unknown): void;\nexport function setDefaults(name: string | Record,\n value?: unknown): void {\n if (arguments.length === 2) {\n // allow passing of single key/value...\n defaults[name as string] = value;\n } else {\n // ... and as an object too\n assign(defaults, name);\n }\n}\n\n// Hides all currently active Bootprompt modals\nexport function hideAll(): void {\n $(\".bootprompt\").modal(\"hide\");\n}\n\n//\n// CORE HELPER FUNCTIONS\n//\n\n// tslint:disable-next-line:no-any\nconst fnModal = $.fn.modal as any;\n/* istanbul ignore if: we do not test with incorrect environments. */\nif (fnModal === undefined) {\n throw new Error(\n `\"$.fn.modal\" is not defined; please double check you have included \\\nthe Bootstrap JavaScript library. See http://getbootstrap.com/javascript/ \\\nfor more details.`);\n}\n\n/* istanbul ignore if: we do not test with incorrect environments. */\nif (!fnModal.Constructor.VERSION) {\n throw new Error(\"Bootprompt cannot determine the version of Bootstrap used\");\n}\n\nconst fullBootstrapVersion = fnModal.Constructor.VERSION;\nconst bootstrapVersion =\n Number(fullBootstrapVersion.substring(0,\n fullBootstrapVersion.indexOf(\".\")));\n\n/* istanbul ignore if: we do not test with incorrect environments. */\nif (bootstrapVersion < 3) {\n throw new Error(\"Bootprompt does not work with Bootstrap 2 and lower.\");\n}\n\n// Core dialog function\n// tslint:disable-next-line:max-func-body-length cyclomatic-complexity\nexport function dialog(options: DialogOptions): JQuery {\n const finalOptions = sanitize(options);\n\n const $modal = $(templates.dialog);\n const modal = $modal[0];\n const innerDialog = modal.getElementsByClassName(\"modal-dialog\")[0];\n const body = modal.getElementsByClassName(\"modal-body\")[0] as HTMLElement;\n const footer = $(templates.footer)[0];\n\n const callbacks: Record = {\n onEscape: finalOptions.onEscape,\n };\n\n const { buttons, backdrop, className, closeButton, message, size,\n title } = finalOptions;\n // tslint:disable-next-line:no-non-null-assertion\n const bpBody = body.getElementsByClassName(\"bootprompt-body\")[0];\n if (typeof message === \"string\") {\n // tslint:disable-next-line:no-inner-html\n bpBody.innerHTML = message;\n }\n else {\n // tslint:disable-next-line:no-inner-html\n bpBody.innerHTML = \"\";\n $(bpBody).append(message);\n }\n\n let hadButtons = false;\n // tslint:disable-next-line:forin\n for (const key in buttons) {\n hadButtons = true;\n const b = buttons[key];\n const $button = $(templates.button);\n const button = $button[0];\n $button.data(\"bp-handler\", key);\n // On IE10/11 it is not possible to just do x.classList.add(a, b, c).\n for (const cl of b.className.split(\" \")) {\n button.classList.add(cl);\n }\n\n switch (key) {\n case \"ok\":\n case \"confirm\":\n button.classList.add(\"bootprompt-accept\");\n break;\n\n case \"cancel\":\n button.classList.add(\"bootprompt-cancel\");\n break;\n default:\n }\n\n // tslint:disable-next-line:no-inner-html\n button.innerHTML = b.label;\n footer.appendChild(button);\n\n callbacks[key] = b.callback;\n }\n\n // Only attempt to create buttons if at least one has been defined in the\n // options object.\n if (hadButtons) {\n // tslint:disable-next-line:no-non-null-assertion\n body.parentNode!.insertBefore(footer, body.nextSibling);\n }\n\n if (finalOptions.animate === true) {\n modal.classList.add(\"fade\");\n }\n\n if (className !== undefined) {\n // On IE10/11 it is not possible to just do x.classList.add(a, b, c).\n for (const cl of className.split(\" \")) {\n modal.classList.add(cl);\n }\n }\n\n if (size !== undefined) {\n // Requires Bootstrap 3.1.0 or higher\n /* istanbul ignore if: we don't systematically test with old versions */\n if (fullBootstrapVersion.substring(0, 3) < \"3.1\") {\n console.warn(`\"size\" requires Bootstrap 3.1.0 or higher. You appear \\\nto be using ${fullBootstrapVersion}. Please upgrade to use this option.`);\n }\n\n switch (size) {\n case \"large\":\n innerDialog.classList.add(\"modal-lg\");\n break;\n case \"small\":\n innerDialog.classList.add(\"modal-sm\");\n break;\n default:\n const q: never = size;\n throw new Error(`unknown size value: ${q}`);\n }\n }\n\n if (title !== undefined) {\n // tslint:disable-next-line:no-non-null-assertion\n body.parentNode!.insertBefore($(templates.header)[0], body);\n const modalTitle = modal.getElementsByClassName(\"modal-title\")[0];\n if (typeof title === \"string\") {\n // tslint:disable-next-line:no-inner-html\n modalTitle.innerHTML = title;\n }\n else {\n // tslint:disable-next-line:no-inner-html\n modalTitle.innerHTML = \"\";\n $(modalTitle).append(title);\n }\n }\n\n if (closeButton === true) {\n const closeButtonEl = $(templates.closeButton)[0];\n\n if (title !== undefined) {\n const modalHeader = modal.getElementsByClassName(\"modal-header\")[0];\n /* istanbul ignore else: we don't systematically test on old versions */\n if (bootstrapVersion > 3) {\n modalHeader.appendChild(closeButtonEl);\n }\n else {\n modalHeader.insertBefore(closeButtonEl, modalHeader.firstChild);\n }\n } else {\n body.insertBefore(closeButtonEl, body.firstChild);\n }\n }\n\n if (finalOptions.centerVertical !== undefined){\n // Requires Bootstrap 4.0.0 or higher\n /* istanbul ignore if: we don't systematically test with old versions */\n if (fullBootstrapVersion < \"4.0.0\") {\n console.warn(`\"centerVertical\" requires Bootstrap 4.0.0 or \\\nhigher. You appear to be using ${fullBootstrapVersion}. Please upgrade to use \\\nthis option.`);\n }\n\n innerDialog.classList.add(\"modal-dialog-centered\");\n }\n\n // Bootstrap event listeners; these handle extra setup & teardown required\n // after the underlying modal has performed certain actions.\n\n // make sure we unbind any listeners once the dialog has definitively been\n // dismissed\n $modal.one(\"hide.bs.modal\", function (e: JQuery.TriggeredEvent): void {\n // tslint:disable-next-line:no-invalid-this\n if (e.target === this) {\n $modal.off(\"escape.close.bp\");\n $modal.off(\"click\");\n }\n });\n\n $modal.one(\"hidden.bs.modal\", function (e: JQuery.TriggeredEvent): void {\n // ensure we don't accidentally intercept hidden events triggered by\n // children of the current dialog. We shouldn't need to handle this anymore,\n // now that Bootstrap namespaces its events, but still worth doing.\n // tslint:disable-next-line:no-invalid-this\n if (e.target === this) {\n $modal.remove();\n }\n });\n\n $modal.one(\"shown.bs.modal\", () => {\n // tslint:disable-next-line:no-non-null-assertion\n $(modal.querySelector(\".btn-primary\")!).trigger(\"focus\");\n });\n\n // Bootprompt event listeners; used to decouple some\n // behaviours from their respective triggers\n\n if (backdrop !== \"static\") {\n // A boolean true/false according to the Bootstrap docs\n // should show a dialog the user can dismiss by clicking on\n // the background.\n // We always only ever pass static/false to the actual\n // $.modal function because with \"true\" we can't trap\n // this event (the .modal-backdrop swallows it)\n // However, we still want to sort of respect true\n // and invoke the escape mechanism instead\n $modal.on(\"click.dismiss.bs.modal\", (e: JQuery.TriggeredEvent) => {\n // The target varies in 3.3.x releases since the modal backdrop moved\n // *inside* the outer dialog rather than *alongside* it\n const backdrops =\n modal.getElementsByClassName(\"modal-backdrop\");\n\n const target = backdrops.length !== 0 ?\n /* istanbul ignore next: we don't systematically test with 3.3.x */\n backdrops[0] :\n e.currentTarget;\n\n if (e.target !== target) {\n return;\n }\n\n $modal.trigger(\"escape.close.bp\");\n });\n }\n\n $modal.on(\"escape.close.bp\", (e: JQuery.TriggeredEvent) => {\n // the if statement looks redundant but it isn't; without it\n // if we *didn't* have an onEscape handler then processCallback\n // would automatically dismiss the dialog\n if (callbacks.onEscape === true ||\n typeof callbacks.onEscape === \"function\") {\n processCallback(e, $modal, callbacks.onEscape);\n }\n });\n\n $modal.on(\"click\", \".modal-footer button\",\n function (e: JQuery.TriggeredEvent): void {\n // tslint:disable-next-line:no-invalid-this\n const callbackKey = $(this).data(\"bp-handler\");\n\n processCallback(e, $modal, callbacks[callbackKey]);\n });\n\n $modal.on(\"click\", \".bootprompt-close-button\", (e) => {\n // onEscape might be falsy but that's fine; the fact is\n // if the user has managed to click the close button we\n // have to close the dialog, callback or not\n processCallback(e, $modal, callbacks.onEscape);\n });\n\n $modal.on(\"keyup\", (e) => {\n if (e.which === 27) {\n $modal.trigger(\"escape.close.bp\");\n }\n });\n\n // The interface defined for $ messes up type inferrence so we have to assert\n // the type here.\n $(finalOptions.container as JQuery).append($modal);\n\n $modal.modal({\n backdrop: (backdrop === true || backdrop === \"static\") ? \"static\" : false,\n keyboard: false,\n show: false,\n });\n\n if (finalOptions.show === true) {\n $modal.modal(\"show\");\n }\n\n return $modal;\n}\n\n// Helper function to simulate the native alert() behavior. **NOTE**: This is\n// non-blocking, so any code that must happen after the alert is dismissed\n// should be placed within the callback function for this alert.\nexport function alert(options: AlertOptions): JQuery;\nexport function alert(message: string,\n callback?: AlertOptions[\"callback\"]): JQuery;\nexport function alert(messageOrOptions: string | AlertOptions,\n callback?: AlertOptions[\"callback\"]): JQuery {\n const finalOptions =\n mergeDialogOptions(\"alert\", [\"ok\"], [\"message\", \"callback\"],\n messageOrOptions, callback);\n\n const { callback: finalCallback } = finalOptions;\n\n // tslint:disable-next-line:no-suspicious-comment\n // @TODO: can this move inside exports.dialog when we're iterating over each\n // button and checking its button.callback value instead?\n if (finalCallback !== undefined && typeof finalCallback !== \"function\") {\n throw new Error(\"alert requires callback property to be a function when \\\nprovided\");\n }\n\n // override the ok and escape callback to make sure they just invoke the\n // single user-supplied one (if provided)\n // tslint:disable-next-line:no-non-null-assertion\n (finalOptions.buttons.ok as Button).callback = finalOptions.onEscape =\n function (): boolean | void {\n return typeof finalCallback === \"function\" ?\n // tslint:disable-next-line:no-invalid-this\n finalCallback.call(this) : true;\n };\n\n return dialog(finalOptions);\n}\n\n// Helper function to simulate the native confirm() behavior. **NOTE**: This is\n// non-blocking, so any code that must happen after the confirm is dismissed\n// should be placed within the callback function for this confirm.\nexport function confirm(options: ConfirmOptions): JQuery;\nexport function confirm(message: string,\n callback: ConfirmOptions[\"callback\"]): JQuery;\nexport function confirm(messageOrOptions: string | ConfirmOptions,\n callback?: ConfirmOptions[\"callback\"]): JQuery {\n const finalOptions = mergeDialogOptions(\"confirm\", [\"cancel\", \"confirm\"],\n [\"message\", \"callback\"],\n messageOrOptions, callback);\n\n const { callback: finalCallback, buttons } = finalOptions;\n\n // confirm specific validation; they don't make sense without a callback so\n // make sure it's present\n if (typeof finalCallback !== \"function\") {\n throw new Error(\"confirm requires a callback\");\n }\n\n // overrides; undo anything the user tried to set they shouldn't have\n // tslint:disable-next-line:no-non-null-assertion\n (buttons.cancel as Button).callback = finalOptions.onEscape =\n function (): boolean | void {\n // tslint:disable-next-line:no-invalid-this\n return finalCallback.call(this, false);\n };\n\n // tslint:disable-next-line:no-non-null-assertion\n (buttons.confirm as Button).callback = function (): boolean | void {\n // tslint:disable-next-line:no-invalid-this\n return finalCallback.call(this, true);\n };\n\n return dialog(finalOptions);\n}\n\nfunction setupTextualInput(input: JQuery,\n options: TextPromptOptions & DialogOptions): void {\n const { value, placeholder, pattern, maxlength, required } = options;\n\n input.val(value as string);\n\n if (placeholder !== undefined) {\n input.attr(\"placeholder\", placeholder);\n }\n\n if (pattern !== undefined) {\n input.attr(\"pattern\", pattern);\n }\n\n if (maxlength !== undefined) {\n input.attr(\"maxlength\", maxlength);\n }\n\n if (required === true) {\n input.prop({ required: true });\n }\n}\n\nfunction setupNumberLikeInput(input: JQuery,\n options: NumericPromptOptions |\n DatePromptOptions | TimePromptOptions): void {\n const { value, placeholder, pattern, required, inputType } = options;\n\n if (value !== undefined) {\n input.val(String(value));\n }\n\n if (placeholder !== undefined) {\n input.attr(\"placeholder\", placeholder);\n }\n\n if (pattern !== undefined) {\n input.attr(\"pattern\", pattern);\n }\n\n if (required === true) {\n input.prop({ required: true });\n }\n\n // These input types have extra attributes which affect their input\n // validation. Warning: For most browsers, date inputs are buggy in their\n // implementation of 'step', so this attribute will have no\n // effect. Therefore, we don't set the attribute for date inputs. @see\n // tslint:disable-next-line:max-line-length\n // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/date#Setting_maximum_and_minimum_dates\n if (inputType !== \"date\") {\n const step = (options as TimePromptOptions | NumericPromptOptions).step;\n if (step !== undefined) {\n const stepNumber = Number(step);\n if (step === \"any\" || (!isNaN(stepNumber) && stepNumber > 0)) {\n input.attr(\"step\", step);\n }\n else {\n throw new Error(`\"step\" must be a valid positive number or the \\\nvalue \"any\". See \\\nhttps://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attr-step \\\nfor more information.`);\n }\n }\n }\n\n validateMinOrMaxValue(input, \"min\", options);\n validateMinOrMaxValue(input, \"max\", options);\n}\n\nfunction validateInputOptions(inputOptions: InputOption[]): void {\n for (const { value, text } of inputOptions) {\n if (value === undefined || text === undefined) {\n throw new Error(`each option needs a \"value\" and a \"text\" property`);\n }\n\n if (typeof value === \"number\") {\n throw new Error(`bootprompt does not allow numbers for \"value\" in \\\ninputOptions`);\n }\n }\n}\n\nfunction setupSelectInput(input: JQuery, options: SelectPromptOptions): void {\n const inputOptions = options.inputOptions !== undefined ?\n options.inputOptions : [];\n\n if (!Array.isArray(inputOptions)) {\n throw new Error(\"Please pass an array of input options\");\n }\n\n if (inputOptions.length === 0) {\n throw new Error(\"prompt with select requires at least one option \\\nvalue\");\n }\n\n const { required, multiple } = options;\n\n if (required === true) {\n input.prop({ required: true });\n }\n\n if (multiple === true) {\n input.prop({ multiple: true });\n }\n\n validateInputOptions(inputOptions);\n\n let firstValue: string | undefined;\n const groups: Record = Object.create(null);\n for (const { value, text, group } of inputOptions) {\n // assume the element to attach to is the input...\n let elem = input[0];\n\n // ... but override that element if this option sits in a group\n if (group !== undefined && group !== \"\") {\n let groupEl = groups[group];\n if (groupEl === undefined) {\n groups[group] = groupEl = document.createElement(\"optgroup\");\n groupEl.setAttribute(\"label\", group);\n }\n\n elem = groupEl;\n }\n\n const o = $(templates.option);\n o.attr(\"value\", value).text(text);\n elem.appendChild(o[0]);\n if (firstValue === undefined) {\n firstValue = value;\n }\n }\n\n // Conditions are such that an undefined firstValue here is an internal error.\n /* istanbul ignore if: we cannot cause this intentionally */\n if (firstValue === undefined) {\n throw new Error(\"firstValue cannot be undefined at this point\");\n }\n\n // tslint:disable-next-line:forin\n for (const groupName in groups) {\n input.append(groups[groupName]);\n }\n\n input.val(options.value !== undefined ? options.value : firstValue);\n}\n\nfunction setupCheckbox(input: JQuery, options: CheckboxPromptOptions,\n inputTemplate: string): void {\n const checkboxValues =\n Array.isArray(options.value) ? options.value : [options.value];\n const inputOptions = options.inputOptions !== undefined ?\n options.inputOptions : [];\n\n if (inputOptions.length === 0) {\n throw new Error(\"prompt with checkbox requires options\");\n }\n\n validateInputOptions(inputOptions);\n\n for (const { value, text } of inputOptions) {\n const checkbox = $(inputTemplate);\n\n checkbox.find(\"input\").attr(\"value\", value);\n checkbox.find(\"label\").append(`\\n${text}`);\n\n if (checkboxValues.indexOf(value) !== -1) {\n checkbox.find(\"input\").prop(\"checked\", true);\n }\n\n input.append(checkbox);\n }\n}\n\nfunction setupRadio(input: JQuery, options: RadioPromptOptions,\n inputTemplate: string): void {\n // Make sure that value is not an array (only a single radio can ever be\n // checked)\n const { value: initialValue } = options;\n if (initialValue !== undefined && Array.isArray(initialValue)) {\n throw new Error(`prompt with radio requires a single, non-array value \\\nfor \"value\".`);\n }\n\n const inputOptions = options.inputOptions !== undefined ?\n options.inputOptions : [];\n\n if (inputOptions.length === 0) {\n throw new Error(\"prompt with radio requires options\");\n }\n\n validateInputOptions(inputOptions);\n\n // Radiobuttons should always have an initial checked input checked in a\n // \"group\". If value is undefined or doesn't match an input option,\n // select the first radiobutton\n let checkFirstRadio = true;\n\n for (const { value, text } of inputOptions) {\n const radio = $(inputTemplate);\n\n radio.find(\"input\").attr(\"value\", value);\n radio.find(\"label\").append(`\\n${text}`);\n\n if (initialValue !== undefined && value === initialValue) {\n radio.find(\"input\").prop(\"checked\", true);\n checkFirstRadio = false;\n }\n\n input.append(radio);\n }\n\n if (checkFirstRadio) {\n input.find(\"input[type='radio']\").first().prop(\"checked\", true);\n }\n}\n\n// Helper function to simulate the native prompt() behavior. **NOTE**: This is\n// non-blocking, so any code that must happen after the prompt is dismissed\n// should be placed within the callback function for this prompt.\nexport function prompt(options: PromptOptions): JQuery;\nexport function prompt(message: string,\n callback: PromptOptions[\"callback\"]): JQuery;\n// tslint:disable-next-line:max-func-body-length\nexport function prompt(messageOrOptions: string | PromptOptions,\n callback?: PromptOptions[\"callback\"]): JQuery {\n // prompt defaults are more complex than others in that users can override\n // more defaults\n const finalOptions = mergeDialogOptions(\"prompt\", [\"cancel\", \"confirm\"],\n [\"title\", \"callback\"],\n messageOrOptions, callback);\n if (finalOptions.value === undefined) {\n finalOptions.value = defaults.value;\n }\n\n if (typeof finalOptions.value === \"number\") {\n throw new Error(\"bootprompt does not allow numbers as values\");\n }\n\n if (finalOptions.inputType === undefined) {\n // tslint:disable-next-line:no-any\n (finalOptions as any).inputType = defaults.inputType;\n }\n\n // capture the user's show value; we always set this to false before spawning\n // the dialog to give us a chance to attach some handlers to it, but we need\n // to make sure we respect a preference not to show it\n const shouldShow = (finalOptions.show === undefined) ? defaults.show :\n finalOptions.show;\n // This is required prior to calling the dialog builder below - we need to add\n // an event handler just before the prompt is shown\n finalOptions.show = false;\n\n // prompt-specific validation\n if (finalOptions.title === undefined || finalOptions.title === \"\") {\n throw new Error(\"prompt requires a title\");\n }\n\n const { callback: finalCallback, buttons } = finalOptions;\n if (typeof finalCallback !== \"function\") {\n throw new Error(\"prompt requires a callback\");\n }\n\n if (finalOptions.inputType === undefined) {\n finalOptions.inputType = \"text\";\n }\n\n const inputTemplate = templates.inputs[finalOptions.inputType];\n let input: JQuery;\n switch (finalOptions.inputType) {\n case \"text\":\n case \"textarea\":\n case \"email\":\n case \"password\":\n input = $(inputTemplate);\n setupTextualInput(input, finalOptions);\n break;\n case \"date\":\n case \"time\":\n case \"number\":\n case \"range\":\n input = $(inputTemplate);\n setupNumberLikeInput(input, finalOptions);\n break;\n case \"select\":\n input = $(inputTemplate);\n setupSelectInput(input, finalOptions);\n break;\n case \"checkbox\":\n // checkboxes have to nest within a containing element\n input = $(`
`);\n setupCheckbox(input, finalOptions, inputTemplate);\n break;\n case \"radio\":\n // radio buttons have to nest within a containing element\n // tslint:disable-next-line:no-jquery-raw-elements\n input = $(\"
\");\n setupRadio(input, finalOptions, inputTemplate);\n break;\n default:\n // tslint:disable-next-line:no-any\n const q: never = (finalOptions as any).inputType as never;\n throw new Error(`Unknown input type: ${q}`);\n }\n\n // Handles the 'cancel' action\n (buttons.cancel as Button).callback = finalOptions.onEscape =\n function (): boolean | void {\n // tslint:disable-next-line:no-invalid-this\n return finalCallback.call(this, null);\n };\n\n // Prompt submitted - extract the prompt value. This requires a bit of work,\n // given the different input types available.\n // tslint:disable-next-line:no-non-null-assertion\n (buttons.confirm as Button).callback = function (): boolean | void {\n let value: string | string[];\n\n switch (finalOptions.inputType) {\n case \"checkbox\":\n value = input.find(\"input:checked\").map(function (): string {\n // tslint:disable-next-line:no-invalid-this\n return $(this).val() as string;\n }).get();\n break;\n case \"radio\":\n value = input.find(\"input:checked\").val() as string;\n break;\n default:\n const rawInput = input[0] as unknown as { checkValidity(): boolean };\n if (rawInput.checkValidity !== undefined && !rawInput.checkValidity()) {\n // prevents button callback from being called\n return false;\n }\n\n if (finalOptions.inputType === \"select\" &&\n finalOptions.multiple === true) {\n value = input.find(\"option:selected\").map(function (): string {\n // tslint:disable-next-line:no-invalid-this\n return $(this).val() as string;\n }).get();\n }\n else {\n value = input.val() as string;\n }\n }\n\n // tslint:disable-next-line:no-invalid-this\n return finalCallback.call(this, value);\n };\n\n const form = $(templates.form);\n form.append(input);\n\n const { message } = finalOptions;\n if (typeof message === \"string\" && message.trim() !== \"\") {\n // Add the form to whatever content the user may have added.\n // tslint:disable-next-line:no-inner-html\n form.prepend($(templates.promptMessage).html(message));\n }\n\n finalOptions.message = form;\n\n // Generate the dialog\n const promptDialog = dialog(finalOptions);\n\n form.on(\"submit\", (e) => {\n e.preventDefault();\n // Fix for SammyJS (or similar JS routing library) hijacking the form post.\n e.stopPropagation();\n\n // tslint:disable-next-line:no-suspicious-comment\n // @TODO can we actually click *the* button object instead?\n // e.g. buttons.confirm.click() or similar\n promptDialog.find(\".bootprompt-accept\").trigger(\"click\");\n });\n\n // clear the existing handler focusing the submit button...\n // ...and replace it with one focusing our input, if possible\n promptDialog.off(\"shown.bs.modal\").on(\"shown.bs.modal\", () => {\n input.focus();\n });\n\n if (shouldShow === true) {\n promptDialog.modal(\"show\");\n }\n\n return promptDialog;\n}\n\n//\n// INTERNAL FUNCTIONS\n//\n\n/**\n * Get localized text from a locale. Defaults to ``en`` locale if no locale\n * provided or a non-registered locale is requested.\n *\n * @param key The field to get from the locale.\n *\n * @param locale The locale name.\n *\n * @returns The field from the locale.\n */\nfunction getText(key: LocaleField, locale: string): string {\n const labels = definedLocales[locale];\n\n return labels !== undefined ? labels[key] : definedLocales.en[key];\n}\n\ntype ButtonName = \"ok\" | \"cancel\" | \"confirm\";\n\n/**\n *\n * Make buttons from a series of labels. All this does is normalise the given\n * labels and translate them where possible.\n *\n * @param labels The button labels.\n *\n * @param locale A locale name.\n *\n * @returns The created buttons.\n *\n */\nfunction makeButtons(labels: ButtonName[], locale: string): Buttons {\n const buttons: Buttons = Object.create(null);\n\n for (const label of labels) {\n buttons[label.toLowerCase()] = {\n label: getText(label.toUpperCase() as LocaleField, locale),\n };\n }\n\n return buttons;\n}\n\ntype SpecializedOptions = AlertOptions | ConfirmOptions | PromptOptions;\n\n/**\n * Produce a DialogOptions object from the options, or arguments passed to the\n * specialized functions (alert, confirm, prompt).\n *\n * @param kind The kind of specialized function that was called.\n *\n * @param labels The button labels that the specialized function uses.\n *\n * @param properties The properties to which the ``options`` and ``callback``\n * arguments should be mapped.\n *\n * @param optionsOrString: The first argument of the specialized functions is\n * either an options object, or a string. The value of that first argument must\n * be passed here.\n *\n * @param callback The second argument (optional) to the specialized functions\n * is a callback. It must be passed here.\n *\n * @returns Options to pass to [[dialog]].\n */\nfunction mergeDialogOptions(\n kind: string,\n labels: ButtonName[],\n properties: [keyof T, keyof T],\n optionsOrString: string | T,\n callback?: T[\"callback\"]):\nT & DialogOptions & { buttons: Buttons } {\n let locale;\n let swapButtons;\n if (typeof optionsOrString !== \"string\") {\n locale = optionsOrString.locale !== undefined ? optionsOrString.locale :\n defaults.locale;\n swapButtons = optionsOrString.swapButtonOrder !== undefined ?\n optionsOrString.swapButtonOrder : defaults.swapButtonOrder;\n }\n else {\n ({ locale, swapButtons } = defaults);\n }\n\n const orderedLabels = swapButtons ? labels.slice().reverse() : labels;\n\n // build up a base set of dialog properties\n const baseOptions = {\n className: `bootprompt-${kind}`,\n buttons: makeButtons(orderedLabels, locale),\n };\n\n // merge the generated base properties with user supplied arguments\n const merged =\n $.extend(\n true, // deep merge\n {}, // ensure the target is an empty, unreferenced object\n baseOptions, // the base options for this dialog (often just buttons)\n // args could be an object or array; if it's an array properties will\n // map it to a proper options object\n (callback !== undefined || typeof optionsOrString === \"string\") ? {\n __proto__: null,\n [properties[0]]: optionsOrString,\n [properties[1]]: callback,\n } as unknown as T :\n optionsOrString,\n ) as T & DialogOptions & typeof baseOptions;\n\n // Ensure the buttons properties generated, *after* merging with user args are\n // still valid against the supplied labels\n\n // An earlier implementation was building a hash from ``buttons``. However,\n // the ``buttons`` array is very small. Profiling in other projects have shown\n // that for very small arrays, there's no benefit to creating a table for\n // lookup.\n for (const key in merged.buttons) {\n // tslint:disable-next-line:no-any\n if (orderedLabels.indexOf(key as any) === -1) {\n throw new Error(`button key \"${key}\" is not allowed (options are \\\n${orderedLabels.join(\" \")})`);\n }\n }\n\n return merged;\n}\n\n// Filter and tidy up any user supplied parameters to this dialog.\n// Also looks for any shorthands used and ensures that the options\n// which are returned are all normalized properly\nfunction sanitize(options: DialogOptions): SanitizedDialogOptions {\n if (typeof options !== \"object\") {\n throw new Error(\"Please supply an object of options\");\n }\n\n if (options.message === undefined) {\n throw new Error(\"Please specify a message\");\n }\n\n // make sure any supplied options take precedence over defaults\n const finalOptions = {...defaults, ...options};\n\n // no buttons is still a valid dialog but it's cleaner to always have\n // a buttons object to iterate over, even if it's empty\n let { buttons } = finalOptions;\n if (buttons === undefined) {\n buttons = finalOptions.buttons = Object.create(null) as {};\n }\n\n const total = Object.keys(buttons).length;\n\n let index = 0;\n // tslint:disable-next-line:forin\n for (const key in buttons) {\n let button = buttons[key];\n if (typeof button === \"function\") {\n // short form, assume value is our callback. Since button\n // isn't an object it isn't a reference either so re-assign it\n button = buttons[key] = {\n callback: button,\n };\n }\n\n // before any further checks make sure by now button is the correct type\n if (typeof button !== \"object\") {\n throw new Error(`button with key \"${key}\" must be an object`);\n }\n\n if (button.label === undefined) {\n // the lack of an explicit label means we'll assume the key is good enough\n button.label = key;\n }\n\n if (button.className === undefined) {\n const isPrimary =\n index === (finalOptions.swapButtonOrder === true ? 0 : total - 1);\n\n // always add a primary to the main option in a one or two-button dialog\n button.className = (total <= 2 && isPrimary) ?\n \"btn-primary\" :\n \"btn-secondary btn-default\";\n }\n index++;\n }\n\n // TS cannot infer that we have SanitizedDialogOptions at this point.\n return finalOptions as SanitizedDialogOptions;\n}\n\nfunction throwMaxMinError(name: string): never {\n throw new Error(`\"max\" must be greater than \"min\". See \\\nhttps://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attr-${name} \\\nfor more information.`);\n}\n\n// Handle the invoked dialog callback\nfunction processCallback(e: JQuery.TriggeredEvent,\n $forDialog: JQuery,\n callback:\n ((this: JQuery,\n e: JQuery.TriggeredEvent) => boolean | void) |\n boolean | undefined):\nvoid {\n e.stopPropagation();\n e.preventDefault();\n\n // By default we assume a callback will get rid of the dialog, although it is\n // given the opportunity to override this so, if the callback can be invoked\n // and it *explicitly returns false* then we keep the dialog active...\n // otherwise we'll bin it\n if (!(typeof callback === \"function\" &&\n callback.call($forDialog, e) === false)) {\n $forDialog.modal(\"hide\");\n }\n}\n\n// Helper function, since the logic for validating min and max attributes is\n// almost identical\nfunction validateMinOrMaxValue(input: JQuery,\n name: \"min\" | \"max\",\n options: NumericPromptOptions |\n DatePromptOptions | TimePromptOptions): void {\n const value = options[name];\n if (value === undefined) {\n return;\n }\n\n const compareValue = options[name === \"min\" ? \"max\" : \"min\"];\n input.attr(name, value);\n\n const { min , max } = options;\n\n // Type inference fails to realize the real type of value...\n switch (options.inputType) {\n case \"date\":\n /* istanbul ignore if: we don't test the positive case */\n if (!/(\\d{4})-(\\d{2})-(\\d{2})/.test(value)) {\n console.warn(`Browsers which natively support the \"date\" input type \\\nexpect date values to be of the form \"YYYY-MM-DD\" (see ISO-8601 \\\nhttps://www.iso.org/iso-8601-date-and-time-format.html). Bootprompt does not \\\nenforce this rule, but your ${name} value may not be enforced by this \\\nbrowser.`);\n }\n break;\n case \"time\":\n if (!/([01][0-9]|2[0-3]):[0-5][0-9]?:[0-5][0-9]/.test(value)) {\n throw new Error(`\"${name}\" is not a valid time. See \\\nhttps://www.w3.org/TR/2012/WD-html-markup-20120315/datatypes.html\\\n#form.data.time for more information.`);\n }\n\n // tslint:disable-next-line:no-non-null-assertion\n if (!(compareValue === undefined || max! > min!)) {\n return throwMaxMinError(name);\n }\n break;\n default:\n // Yes we force the string into isNaN. It works.\n if (isNaN(value as unknown as number)) {\n throw new Error(`\"${name}\" must be a valid number. See \\\nhttps://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attr-${name} \\\nfor more information.`);\n }\n\n const minNumber = Number(min);\n const maxNumber = Number(max);\n\n // tslint:disable-next-line:no-non-null-assertion\n if (!(compareValue === undefined || maxNumber > minNumber) &&\n // Yes we force the string into isNaN. It works.\n !isNaN(compareValue as unknown as number)) {\n return throwMaxMinError(name);\n }\n }\n}\n\n// Register the default locale\naddLocale(\"en\", {\n OK: \"OK\",\n CANCEL: \"Cancel\",\n CONFIRM: \"OK\",\n});\n"],"names":["LOCALE_FIELDS","definedLocales","Object","create","assign","undefined","a","b","$","extend","templates","dialog","header","footer","closeButton","form","button","option","promptMessage","inputs","text","textarea","email","select","checkbox","radio","date","time","number","password","range","defaults","locale","backdrop","animate","className","show","container","value","inputType","swapButtonOrder","centerVertical","multiple","addLocale","name","values","LOCALE_FIELDS_1","__values","field","Error","setDefaults","arguments","length","fnModal","fn","modal","Constructor","VERSION","fullBootstrapVersion","bootstrapVersion","Number","substring","indexOf","options","finalOptions","message","buttons","total","keys","index","key","callback","label","isPrimary","sanitize","$modal","innerDialog","getElementsByClassName","body","callbacks","onEscape","size","title","bpBody","innerHTML","append","hadButtons","$button","data","_c","split","cl","classList","add","appendChild","parentNode","insertBefore","nextSibling","_e","console","warn","modalTitle","closeButtonEl","modalHeader","firstChild","one","e","target","this","off","remove","querySelector","trigger","on","backdrops","currentTarget","processCallback","callbackKey","which","keyboard","validateInputOptions","inputOptions","inputOptions_1","_b","getText","labels","en","makeButtons","labels_1","toLowerCase","toUpperCase","mergeDialogOptions","kind","properties","optionsOrString","swapButtons","orderedLabels","slice","reverse","baseOptions","merged","_a","__proto__","join","throwMaxMinError","$forDialog","stopPropagation","preventDefault","call","validateMinOrMaxValue","input","compareValue","attr","min","max","test","isNaN","minNumber","maxNumber","OK","CANCEL","CONFIRM","messageOrOptions","finalCallback","ok","cancel","confirm","shouldShow","inputTemplate","placeholder","pattern","maxlength","required","val","prop","setupTextualInput","String","step","stepNumber","setupNumberLikeInput","Array","isArray","firstValue","groups","inputOptions_2","group","elem","groupEl","document","createElement","setAttribute","o","groupName","setupSelectInput","checkboxValues","inputOptions_3","find","setupCheckbox","initialValue","checkFirstRadio","inputOptions_4","first","setupRadio","q","map","get","rawInput","checkValidity","trim","prepend","html","promptDialog","focus"],"mappings":"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"}