Skip to content
Snippets Groups Projects
Commit 438dea9c authored by Andreas Fernandez's avatar Andreas Fernandez
Browse files

[TASK] Allow `Element` and `DocumentFragment` in now stricter Modal API

The configuration definition of `content` in the Modal API is extended
to accept objects of types `Element` and `DocumentFragment` as well,
which allows passing arbitrary DOM nodes to the API, if TypeScript is
used. Since jQuery is still the main actor in the Modal API, no further
adjustments are required for now as jQuery can consume the added types.

In the same run, the API definition got stricter as `Modal.advanced()`
allowed to pass any arbitrary configuration not covered by the internal
`Configuration` interface.

Resolves: #98164
Releases: main, 11.5
Change-Id: Ibf7cc836fcffa870a1eb4c5d4615c44e046cf192
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/75488


Tested-by: default avatarcore-ci <typo3@b13.com>
Tested-by: default avatarFrank Nägler <frank.naegler@typo3.com>
Tested-by: default avatarBenjamin Franzke <bfr@qbus.de>
Tested-by: default avatarAndreas Fernandez <a.fernandez@scripting-base.de>
Reviewed-by: default avatarFrank Nägler <frank.naegler@typo3.com>
Reviewed-by: default avatarBenjamin Franzke <bfr@qbus.de>
Reviewed-by: default avatarAndreas Fernandez <a.fernandez@scripting-base.de>
parent b9df005d
Branches
Tags
No related merge requests found
......@@ -56,19 +56,19 @@ enum Types {
interface Button {
text: string;
active: boolean;
active?: boolean;
btnClass: string;
name: string;
trigger: (e: JQueryEventObject) => {};
dataAttributes: { [key: string]: string };
icon: string;
action: AbstractAction;
name?: string;
trigger?: (e?: JQueryEventObject) => void;
dataAttributes?: { [key: string]: string };
icon?: string;
action?: AbstractAction;
}
interface Configuration {
type: Types;
title: string;
content: string | JQuery;
content: string | JQuery | Element | DocumentFragment;
severity: SeverityEnum;
buttons: Array<Button>;
style: string;
......@@ -170,7 +170,7 @@ class Modal {
* - confirm.button.ok
*
* @param {string} title The title for the confirm modal
* @param {string | JQuery} content The content for the conform modal, e.g. the main question
* @param {string | JQuery | Element | DocumentFragment} content The content for the conform modal, e.g. the main question
* @param {SeverityEnum} severity Default SeverityEnum.warning
* @param {Array<Button>} buttons An array with buttons, default no buttons
* @param {Array<string>} additionalCssClasses Additional css classes to add to the modal
......@@ -178,20 +178,20 @@ class Modal {
*/
public confirm(
title: string,
content: string | JQuery,
content: string | JQuery | Element | DocumentFragment,
severity: SeverityEnum = SeverityEnum.warning,
buttons: Array<Object> = [],
buttons: Array<Button> = [],
additionalCssClasses?: Array<string>,
): JQuery {
if (buttons.length === 0) {
buttons.push(
{
<Button>{
text: $(this).data('button-close-text') || TYPO3.lang['button.cancel'] || 'Cancel',
active: true,
btnClass: 'btn-default',
name: 'cancel',
},
{
<Button>{
text: $(this).data('button-ok-text') || TYPO3.lang['button.ok'] || 'OK',
btnClass: 'btn-' + Severity.getCssClass(severity),
name: 'ok',
......@@ -232,7 +232,7 @@ class Modal {
public loadUrl(
title: string,
severity: SeverityEnum = SeverityEnum.info,
buttons: Array<Object>,
buttons: Array<Button>,
url: string,
callback?: Function,
target?: string,
......@@ -252,17 +252,17 @@ class Modal {
* Shows a dialog
*
* @param {string} title
* @param {string | JQuery} content
* @param {string | JQuery | Element | DocumentFragment} content
* @param {number} severity
* @param {Array<Object>} buttons
* @param {Array<Button>} buttons
* @param {Array<string>} additionalCssClasses
* @returns {JQuery}
*/
public show(
title: string,
content: string | JQuery,
content: string | JQuery | Element | DocumentFragment,
severity: SeverityEnum = SeverityEnum.info,
buttons?: Array<Object>,
buttons?: Array<Button>,
additionalCssClasses?: Array<string>,
): JQuery {
return this.advanced({
......@@ -277,10 +277,8 @@ class Modal {
/**
* Loads modal by configuration
*
* @param {object} configuration configuration for the modal
*/
public advanced(configuration: { [key: string]: any }): JQuery {
public advanced(configuration: Partial<Configuration>): JQuery {
// Validation of configuration
configuration.type = typeof configuration.type === 'string' && configuration.type in Types
? configuration.type
......@@ -310,7 +308,7 @@ class Modal {
? configuration.ajaxTarget
: this.defaultConfiguration.ajaxTarget;
return this.generate(<Configuration>configuration);
return this.generate(configuration);
}
/**
......@@ -380,9 +378,11 @@ class Modal {
evt.preventDefault();
const $element = $(evt.currentTarget);
const content = $element.data('bs-content') || 'Are you sure?';
const severity = typeof SeverityEnum[$element.data('severity')] !== 'undefined'
? SeverityEnum[$element.data('severity')]
: SeverityEnum.info;
let severity = SeverityEnum.info;
if ($element.data('severity') in SeverityEnum) {
const severityKey: keyof typeof SeverityEnum = $element.data('severity');
severity = SeverityEnum[severityKey];
}
let url = $element.data('url') || null;
if (url !== null) {
const separator = url.includes('?') ? '&' : '?';
......@@ -445,10 +445,7 @@ class Modal {
});
}
/**
* @param {Configuration} configuration
*/
private generate(configuration: Configuration): JQuery {
private generate(configuration: Partial<Configuration>): JQuery {
const currentModal = this.$template.clone();
if (configuration.additionalCssClasses.length > 0) {
for (let additionalClass of configuration.additionalCssClasses) {
......
......@@ -10,4 +10,4 @@
*
* The TYPO3 project - inspiring people to share!
*/
import"bootstrap";import $ from"jquery";import{html,render}from"lit";import{SeverityEnum}from"@typo3/backend/enum/severity.js";import AjaxRequest from"@typo3/core/ajax/ajax-request.js";import SecurityUtility from"@typo3/core/security-utility.js";import Icons from"@typo3/backend/icons.js";import Severity from"@typo3/backend/severity.js";var Identifiers,Sizes,Styles,Types;!function(t){t.modal=".t3js-modal",t.content=".t3js-modal-content",t.title=".t3js-modal-title",t.close=".t3js-modal-close",t.body=".t3js-modal-body",t.footer=".t3js-modal-footer",t.iframe=".t3js-modal-iframe",t.iconPlaceholder=".t3js-modal-icon-placeholder"}(Identifiers||(Identifiers={})),function(t){t.small="small",t.default="default",t.medium="medium",t.large="large",t.full="full"}(Sizes||(Sizes={})),function(t){t.default="default",t.light="light",t.dark="dark"}(Styles||(Styles={})),function(t){t.default="default",t.ajax="ajax",t.iframe="iframe"}(Types||(Types={}));class Modal{constructor(t){this.sizes=Sizes,this.styles=Styles,this.types=Types,this.currentModal=null,this.instances=[],this.$template=$('\n <div class="t3js-modal modal fade">\n <div class="modal-dialog">\n <div class="t3js-modal-content modal-content">\n <div class="modal-header">\n <h4 class="t3js-modal-title modal-title"></h4>\n <button class="t3js-modal-close close">\n <span aria-hidden="true">\n <span class="t3js-modal-icon-placeholder" data-icon="actions-close"></span>\n </span>\n <span class="visually-hidden"></span>\n </button>\n </div>\n <div class="t3js-modal-body modal-body"></div>\n <div class="t3js-modal-footer modal-footer"></div>\n </div>\n </div>\n </div>'),this.defaultConfiguration={type:Types.default,title:"Information",content:"No content provided, please check your <code>Modal</code> configuration.",severity:SeverityEnum.notice,buttons:[],style:Styles.default,size:Sizes.default,additionalCssClasses:[],callback:$.noop(),ajaxCallback:$.noop(),ajaxTarget:null},this.securityUtility=t,$(document).on("modal-dismiss",this.dismiss),this.initializeMarkupTrigger(document)}static resolveEventNameTargetElement(t){const e=t.target,a=t.currentTarget;return e.dataset&&e.dataset.eventName?e:a.dataset&&a.dataset.eventName?a:null}static createModalResponseEventFromElement(t,e){return t&&t.dataset.eventName?new CustomEvent(t.dataset.eventName,{bubbles:!0,detail:{result:e,payload:t.dataset.eventPayload||null}}):null}dismiss(){this.currentModal&&this.currentModal.modal("hide")}confirm(t,e,a=SeverityEnum.warning,n=[],s){return 0===n.length&&n.push({text:$(this).data("button-close-text")||TYPO3.lang["button.cancel"]||"Cancel",active:!0,btnClass:"btn-default",name:"cancel"},{text:$(this).data("button-ok-text")||TYPO3.lang["button.ok"]||"OK",btnClass:"btn-"+Severity.getCssClass(a),name:"ok"}),this.advanced({title:t,content:e,severity:a,buttons:n,additionalCssClasses:s,callback:t=>{t.on("button.clicked",t=>{"cancel"===t.target.getAttribute("name")?$(t.currentTarget).trigger("confirm.button.cancel"):"ok"===t.target.getAttribute("name")&&$(t.currentTarget).trigger("confirm.button.ok")})}})}loadUrl(t,e=SeverityEnum.info,a,n,s,i){return this.advanced({type:Types.ajax,title:t,severity:e,buttons:a,ajaxCallback:s,ajaxTarget:i,content:n})}show(t,e,a=SeverityEnum.info,n,s){return this.advanced({type:Types.default,title:t,content:e,severity:a,buttons:n,additionalCssClasses:s})}advanced(t){return t.type="string"==typeof t.type&&t.type in Types?t.type:this.defaultConfiguration.type,t.title="string"==typeof t.title?t.title:this.defaultConfiguration.title,t.content="string"==typeof t.content||"object"==typeof t.content?t.content:this.defaultConfiguration.content,t.severity=void 0!==t.severity?t.severity:this.defaultConfiguration.severity,t.buttons=t.buttons||this.defaultConfiguration.buttons,t.size="string"==typeof t.size&&t.size in Sizes?t.size:this.defaultConfiguration.size,t.style="string"==typeof t.style&&t.style in Styles?t.style:this.defaultConfiguration.style,t.additionalCssClasses=t.additionalCssClasses||this.defaultConfiguration.additionalCssClasses,t.callback="function"==typeof t.callback?t.callback:this.defaultConfiguration.callback,t.ajaxCallback="function"==typeof t.ajaxCallback?t.ajaxCallback:this.defaultConfiguration.ajaxCallback,t.ajaxTarget="string"==typeof t.ajaxTarget?t.ajaxTarget:this.defaultConfiguration.ajaxTarget,this.generate(t)}setButtons(t){const e=this.currentModal.find(Identifiers.footer);if(t.length>0){e.empty();for(let a=0;a<t.length;a++){const n=t[a],s=$("<button />",{class:"btn"});s.html("<span>"+this.securityUtility.encodeHtml(n.text,!1)+"</span>"),n.active&&s.addClass("t3js-active"),""!==n.btnClass&&s.addClass(n.btnClass),""!==n.name&&s.attr("name",n.name),n.action?s.on("click",()=>{e.find("button").not(s).addClass("disabled"),n.action.execute(s.get(0)).then(()=>{this.currentModal.modal("hide")})}):n.trigger&&s.on("click",n.trigger),n.dataAttributes&&Object.keys(n.dataAttributes).length>0&&Object.keys(n.dataAttributes).map(t=>{s.attr("data-"+t,n.dataAttributes[t])}),n.icon&&s.prepend('<span class="t3js-modal-icon-placeholder" data-icon="'+n.icon+'"></span>'),e.append(s)}e.show(),e.find("button").on("click",t=>{$(t.currentTarget).trigger("button.clicked")})}else e.hide();return this.currentModal}initializeMarkupTrigger(t){$(t).on("click",".t3js-modal-trigger",t=>{t.preventDefault();const e=$(t.currentTarget),a=e.data("bs-content")||"Are you sure?",n=void 0!==SeverityEnum[e.data("severity")]?SeverityEnum[e.data("severity")]:SeverityEnum.info;let s=e.data("url")||null;if(null!==s){const t=s.includes("?")?"&":"?";s=s+t+$.param({data:e.data()})}this.advanced({type:null!==s?Types.ajax:Types.default,title:e.data("title")||"Alert",content:null!==s?s:a,severity:n,buttons:[{text:e.data("button-close-text")||TYPO3.lang["button.close"]||"Close",active:!0,btnClass:"btn-default",trigger:()=>{this.currentModal.trigger("modal-dismiss");const e=Modal.resolveEventNameTargetElement(t),a=Modal.createModalResponseEventFromElement(e,!1);null!==a&&e.dispatchEvent(a)}},{text:e.data("button-ok-text")||TYPO3.lang["button.ok"]||"OK",btnClass:"btn-"+Severity.getCssClass(n),trigger:()=>{this.currentModal.trigger("modal-dismiss");const a=Modal.resolveEventNameTargetElement(t),n=Modal.createModalResponseEventFromElement(a,!0);null!==n&&a.dispatchEvent(n);let s=e.attr("data-uri")||e.data("href")||e.attr("href");s&&"#"!==s&&(t.target.ownerDocument.location.href=s),"submit"===t.currentTarget.getAttribute("type")&&(t.currentTarget.closest("form")?.submit(),"BUTTON"===t.currentTarget.tagName&&t.currentTarget.hasAttribute("form")&&t.target.ownerDocument.querySelector("form#"+t.currentTarget.getAttribute("form"))?.submit()),t.currentTarget.hasAttribute("data-target-form")&&t.target.ownerDocument.querySelector("form#"+t.currentTarget.getAttribute("data-target-form"))?.submit()}}]})})}generate(t){const e=this.$template.clone();if(t.additionalCssClasses.length>0)for(let a of t.additionalCssClasses)e.addClass(a);if(e.addClass("modal-type-"+t.type),e.addClass("modal-severity-"+Severity.getCssClass(t.severity)),e.addClass("modal-style-"+t.style),e.addClass("modal-size-"+t.size),e.attr("tabindex","-1"),e.find(Identifiers.title).text(t.title),e.find(Identifiers.close).on("click",()=>{e.modal("hide")}),"ajax"===t.type){const a=t.ajaxTarget?t.ajaxTarget:Identifiers.body,n=e.find(a);Icons.getIcon("spinner-circle",Icons.sizes.default,null,null,Icons.markupIdentifiers.inline).then(e=>{n.html('<div class="modal-loading">'+e+"</div>"),new AjaxRequest(t.content).get().finally(async()=>{this.currentModal.parent().length||this.currentModal.appendTo("body")}).then(async e=>{const n=await e.raw().text();this.currentModal.find(a).empty().append(n),t.ajaxCallback&&t.ajaxCallback(),this.currentModal.trigger("modal-loaded")}).catch(async e=>{const n=await e.raw().text(),s=this.currentModal.find(a).empty();n?s.append(n):render(html`<p><strong>Oops, received a ${e.response.status} response from </strong> <span class="text-break">${t.content}</span>.</p>`,s[0])})})}else"iframe"===t.type?(e.find(Identifiers.body).append($("<iframe />",{src:t.content,name:"modal_frame",class:"modal-iframe t3js-modal-iframe"})),e.find(Identifiers.iframe).on("load",()=>{e.find(Identifiers.title).text(e.find(Identifiers.iframe).get(0).contentDocument.title)})):("string"==typeof t.content&&(t.content=$("<p />").html(this.securityUtility.encodeHtml(t.content))),e.find(Identifiers.body).append(t.content));return e.on("shown.bs.modal",t=>{const e=$(t.currentTarget),a=e.prev(".modal-backdrop"),n=1e3+10*this.instances.length,s=n-10;e.css("z-index",n),a.css("z-index",s),e.find(Identifiers.footer).find(".t3js-active").first().focus(),e.find(Identifiers.iconPlaceholder).each((t,e)=>{Icons.getIcon($(e).data("icon"),Icons.sizes.small,null,null,Icons.markupIdentifiers.inline).then(t=>{this.currentModal.find(Identifiers.iconPlaceholder+"[data-icon="+$(t).data("identifier")+"]").replaceWith(t)})})}),e.on("hide.bs.modal",()=>{if(this.instances.length>0){const t=this.instances.length-1;this.instances.splice(t,1),this.currentModal=this.instances[t-1]}}),e.on("hidden.bs.modal",t=>{e.trigger("modal-destroyed"),$(t.currentTarget).remove(),this.instances.length>0&&$("body").addClass("modal-open")}),e.on("show.bs.modal",e=>{this.currentModal=$(e.currentTarget),this.setButtons(t.buttons),this.instances.push(this.currentModal)}),e.on("modal-dismiss",t=>{$(t.currentTarget).modal("hide")}),t.callback&&t.callback(e),e.modal("show"),e}}let modalObject=null;try{parent&&parent.window.TYPO3&&parent.window.TYPO3.Modal?(parent.window.TYPO3.Modal.initializeMarkupTrigger(document),modalObject=parent.window.TYPO3.Modal):top&&top.TYPO3.Modal&&(top.TYPO3.Modal.initializeMarkupTrigger(document),modalObject=top.TYPO3.Modal)}catch{}modalObject||(modalObject=new Modal(new SecurityUtility),TYPO3.Modal=modalObject);export default modalObject;
\ No newline at end of file
import"bootstrap";import $ from"jquery";import{html,render}from"lit";import{SeverityEnum}from"@typo3/backend/enum/severity.js";import AjaxRequest from"@typo3/core/ajax/ajax-request.js";import SecurityUtility from"@typo3/core/security-utility.js";import Icons from"@typo3/backend/icons.js";import Severity from"@typo3/backend/severity.js";var Identifiers,Sizes,Styles,Types;!function(t){t.modal=".t3js-modal",t.content=".t3js-modal-content",t.title=".t3js-modal-title",t.close=".t3js-modal-close",t.body=".t3js-modal-body",t.footer=".t3js-modal-footer",t.iframe=".t3js-modal-iframe",t.iconPlaceholder=".t3js-modal-icon-placeholder"}(Identifiers||(Identifiers={})),function(t){t.small="small",t.default="default",t.medium="medium",t.large="large",t.full="full"}(Sizes||(Sizes={})),function(t){t.default="default",t.light="light",t.dark="dark"}(Styles||(Styles={})),function(t){t.default="default",t.ajax="ajax",t.iframe="iframe"}(Types||(Types={}));class Modal{constructor(t){this.sizes=Sizes,this.styles=Styles,this.types=Types,this.currentModal=null,this.instances=[],this.$template=$('\n <div class="t3js-modal modal fade">\n <div class="modal-dialog">\n <div class="t3js-modal-content modal-content">\n <div class="modal-header">\n <h4 class="t3js-modal-title modal-title"></h4>\n <button class="t3js-modal-close close">\n <span aria-hidden="true">\n <span class="t3js-modal-icon-placeholder" data-icon="actions-close"></span>\n </span>\n <span class="visually-hidden"></span>\n </button>\n </div>\n <div class="t3js-modal-body modal-body"></div>\n <div class="t3js-modal-footer modal-footer"></div>\n </div>\n </div>\n </div>'),this.defaultConfiguration={type:Types.default,title:"Information",content:"No content provided, please check your <code>Modal</code> configuration.",severity:SeverityEnum.notice,buttons:[],style:Styles.default,size:Sizes.default,additionalCssClasses:[],callback:$.noop(),ajaxCallback:$.noop(),ajaxTarget:null},this.securityUtility=t,$(document).on("modal-dismiss",this.dismiss),this.initializeMarkupTrigger(document)}static resolveEventNameTargetElement(t){const e=t.target,a=t.currentTarget;return e.dataset&&e.dataset.eventName?e:a.dataset&&a.dataset.eventName?a:null}static createModalResponseEventFromElement(t,e){return t&&t.dataset.eventName?new CustomEvent(t.dataset.eventName,{bubbles:!0,detail:{result:e,payload:t.dataset.eventPayload||null}}):null}dismiss(){this.currentModal&&this.currentModal.modal("hide")}confirm(t,e,a=SeverityEnum.warning,n=[],s){return 0===n.length&&n.push({text:$(this).data("button-close-text")||TYPO3.lang["button.cancel"]||"Cancel",active:!0,btnClass:"btn-default",name:"cancel"},{text:$(this).data("button-ok-text")||TYPO3.lang["button.ok"]||"OK",btnClass:"btn-"+Severity.getCssClass(a),name:"ok"}),this.advanced({title:t,content:e,severity:a,buttons:n,additionalCssClasses:s,callback:t=>{t.on("button.clicked",t=>{"cancel"===t.target.getAttribute("name")?$(t.currentTarget).trigger("confirm.button.cancel"):"ok"===t.target.getAttribute("name")&&$(t.currentTarget).trigger("confirm.button.ok")})}})}loadUrl(t,e=SeverityEnum.info,a,n,s,i){return this.advanced({type:Types.ajax,title:t,severity:e,buttons:a,ajaxCallback:s,ajaxTarget:i,content:n})}show(t,e,a=SeverityEnum.info,n,s){return this.advanced({type:Types.default,title:t,content:e,severity:a,buttons:n,additionalCssClasses:s})}advanced(t){return t.type="string"==typeof t.type&&t.type in Types?t.type:this.defaultConfiguration.type,t.title="string"==typeof t.title?t.title:this.defaultConfiguration.title,t.content="string"==typeof t.content||"object"==typeof t.content?t.content:this.defaultConfiguration.content,t.severity=void 0!==t.severity?t.severity:this.defaultConfiguration.severity,t.buttons=t.buttons||this.defaultConfiguration.buttons,t.size="string"==typeof t.size&&t.size in Sizes?t.size:this.defaultConfiguration.size,t.style="string"==typeof t.style&&t.style in Styles?t.style:this.defaultConfiguration.style,t.additionalCssClasses=t.additionalCssClasses||this.defaultConfiguration.additionalCssClasses,t.callback="function"==typeof t.callback?t.callback:this.defaultConfiguration.callback,t.ajaxCallback="function"==typeof t.ajaxCallback?t.ajaxCallback:this.defaultConfiguration.ajaxCallback,t.ajaxTarget="string"==typeof t.ajaxTarget?t.ajaxTarget:this.defaultConfiguration.ajaxTarget,this.generate(t)}setButtons(t){const e=this.currentModal.find(Identifiers.footer);if(t.length>0){e.empty();for(let a=0;a<t.length;a++){const n=t[a],s=$("<button />",{class:"btn"});s.html("<span>"+this.securityUtility.encodeHtml(n.text,!1)+"</span>"),n.active&&s.addClass("t3js-active"),""!==n.btnClass&&s.addClass(n.btnClass),""!==n.name&&s.attr("name",n.name),n.action?s.on("click",()=>{e.find("button").not(s).addClass("disabled"),n.action.execute(s.get(0)).then(()=>{this.currentModal.modal("hide")})}):n.trigger&&s.on("click",n.trigger),n.dataAttributes&&Object.keys(n.dataAttributes).length>0&&Object.keys(n.dataAttributes).map(t=>{s.attr("data-"+t,n.dataAttributes[t])}),n.icon&&s.prepend('<span class="t3js-modal-icon-placeholder" data-icon="'+n.icon+'"></span>'),e.append(s)}e.show(),e.find("button").on("click",t=>{$(t.currentTarget).trigger("button.clicked")})}else e.hide();return this.currentModal}initializeMarkupTrigger(t){$(t).on("click",".t3js-modal-trigger",t=>{t.preventDefault();const e=$(t.currentTarget),a=e.data("bs-content")||"Are you sure?";let n=SeverityEnum.info;if(e.data("severity")in SeverityEnum){const t=e.data("severity");n=SeverityEnum[t]}let s=e.data("url")||null;if(null!==s){const t=s.includes("?")?"&":"?";s=s+t+$.param({data:e.data()})}this.advanced({type:null!==s?Types.ajax:Types.default,title:e.data("title")||"Alert",content:null!==s?s:a,severity:n,buttons:[{text:e.data("button-close-text")||TYPO3.lang["button.close"]||"Close",active:!0,btnClass:"btn-default",trigger:()=>{this.currentModal.trigger("modal-dismiss");const e=Modal.resolveEventNameTargetElement(t),a=Modal.createModalResponseEventFromElement(e,!1);null!==a&&e.dispatchEvent(a)}},{text:e.data("button-ok-text")||TYPO3.lang["button.ok"]||"OK",btnClass:"btn-"+Severity.getCssClass(n),trigger:()=>{this.currentModal.trigger("modal-dismiss");const a=Modal.resolveEventNameTargetElement(t),n=Modal.createModalResponseEventFromElement(a,!0);null!==n&&a.dispatchEvent(n);let s=e.attr("data-uri")||e.data("href")||e.attr("href");s&&"#"!==s&&(t.target.ownerDocument.location.href=s),"submit"===t.currentTarget.getAttribute("type")&&(t.currentTarget.closest("form")?.submit(),"BUTTON"===t.currentTarget.tagName&&t.currentTarget.hasAttribute("form")&&t.target.ownerDocument.querySelector("form#"+t.currentTarget.getAttribute("form"))?.submit()),t.currentTarget.hasAttribute("data-target-form")&&t.target.ownerDocument.querySelector("form#"+t.currentTarget.getAttribute("data-target-form"))?.submit()}}]})})}generate(t){const e=this.$template.clone();if(t.additionalCssClasses.length>0)for(let a of t.additionalCssClasses)e.addClass(a);if(e.addClass("modal-type-"+t.type),e.addClass("modal-severity-"+Severity.getCssClass(t.severity)),e.addClass("modal-style-"+t.style),e.addClass("modal-size-"+t.size),e.attr("tabindex","-1"),e.find(Identifiers.title).text(t.title),e.find(Identifiers.close).on("click",()=>{e.modal("hide")}),"ajax"===t.type){const a=t.ajaxTarget?t.ajaxTarget:Identifiers.body,n=e.find(a);Icons.getIcon("spinner-circle",Icons.sizes.default,null,null,Icons.markupIdentifiers.inline).then(e=>{n.html('<div class="modal-loading">'+e+"</div>"),new AjaxRequest(t.content).get().finally(async()=>{this.currentModal.parent().length||this.currentModal.appendTo("body")}).then(async e=>{const n=await e.raw().text();this.currentModal.find(a).empty().append(n),t.ajaxCallback&&t.ajaxCallback(),this.currentModal.trigger("modal-loaded")}).catch(async e=>{const n=await e.raw().text(),s=this.currentModal.find(a).empty();n?s.append(n):render(html`<p><strong>Oops, received a ${e.response.status} response from </strong> <span class="text-break">${t.content}</span>.</p>`,s[0])})})}else"iframe"===t.type?(e.find(Identifiers.body).append($("<iframe />",{src:t.content,name:"modal_frame",class:"modal-iframe t3js-modal-iframe"})),e.find(Identifiers.iframe).on("load",()=>{e.find(Identifiers.title).text(e.find(Identifiers.iframe).get(0).contentDocument.title)})):("string"==typeof t.content&&(t.content=$("<p />").html(this.securityUtility.encodeHtml(t.content))),e.find(Identifiers.body).append(t.content));return e.on("shown.bs.modal",t=>{const e=$(t.currentTarget),a=e.prev(".modal-backdrop"),n=1e3+10*this.instances.length,s=n-10;e.css("z-index",n),a.css("z-index",s),e.find(Identifiers.footer).find(".t3js-active").first().focus(),e.find(Identifiers.iconPlaceholder).each((t,e)=>{Icons.getIcon($(e).data("icon"),Icons.sizes.small,null,null,Icons.markupIdentifiers.inline).then(t=>{this.currentModal.find(Identifiers.iconPlaceholder+"[data-icon="+$(t).data("identifier")+"]").replaceWith(t)})})}),e.on("hide.bs.modal",()=>{if(this.instances.length>0){const t=this.instances.length-1;this.instances.splice(t,1),this.currentModal=this.instances[t-1]}}),e.on("hidden.bs.modal",t=>{e.trigger("modal-destroyed"),$(t.currentTarget).remove(),this.instances.length>0&&$("body").addClass("modal-open")}),e.on("show.bs.modal",e=>{this.currentModal=$(e.currentTarget),this.setButtons(t.buttons),this.instances.push(this.currentModal)}),e.on("modal-dismiss",t=>{$(t.currentTarget).modal("hide")}),t.callback&&t.callback(e),e.modal("show"),e}}let modalObject=null;try{parent&&parent.window.TYPO3&&parent.window.TYPO3.Modal?(parent.window.TYPO3.Modal.initializeMarkupTrigger(document),modalObject=parent.window.TYPO3.Modal):top&&top.TYPO3.Modal&&(top.TYPO3.Modal.initializeMarkupTrigger(document),modalObject=top.TYPO3.Modal)}catch{}modalObject||(modalObject=new Modal(new SecurityUtility),TYPO3.Modal=modalObject);export default modalObject;
\ No newline at end of file
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