From 180d0ce38203802b251e0fa29d883c828ca61b59 Mon Sep 17 00:00:00 2001 From: Thibeau Fuhrer Date: Fri, 20 Dec 2024 17:31:24 +0100 Subject: [PATCH] [FIX] #42795 UI: fix rollup config for input fields bundle. (#8774) * Fixes https://mantis.ilias.de/view.php?id=42795 * Changes bundle format from 'es' to 'iife'. * Adds il global as external. --- .../js/Input/Field/dist/input.factory.min.js | 2 +- .../UI/resources/js/Input/Field/rollup.config.js | 13 ++++++++++--- .../resources/js/Input/Field/src/input.factory.js | 2 +- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/components/ILIAS/UI/resources/js/Input/Field/dist/input.factory.min.js b/components/ILIAS/UI/resources/js/Input/Field/dist/input.factory.min.js index 3d04226432ee..1354be7a3360 100644 --- a/components/ILIAS/UI/resources/js/Input/Field/dist/input.factory.min.js +++ b/components/ILIAS/UI/resources/js/Input/Field/dist/input.factory.min.js @@ -12,4 +12,4 @@ * https://www.ilias.de * https://github.com/ILIAS-eLearning */ -class e{textarea;remainder=null;constructor(e){if(this.textarea=document.getElementById(e),null===this.textarea)throw new Error(`Could not find textarea for input-id '${e}'.`);if(this.shouldShowRemainder()){if(this.remainder=this.textarea.parentNode.querySelector('[data-action="remainder"]'),!this.remainder instanceof HTMLSpanElement)throw new Error(`Could not find remainder-element for input-id '${e}'.`);this.textarea.addEventListener("input",(()=>{this.updateRemainderCountHook()}))}}updateRemainderCountHook(){this.shouldShowRemainder()&&null!==this.remainder&&(this.remainder.innerHTML=(this.textarea.maxLength-this.textarea.value.length).toString())}updateTextareaContent(e,t=null,n=null){if(!this.isDisabled()){if(this.isContentTooLarge(e))return this.updateRemainderCountHook(),void this.textarea.focus();t=t??this.textarea.selectionStart,n=n??this.textarea.selectionEnd,this.textarea.value=e,tthis.textarea.selectionEnd?this.textarea.selectionStart:this.textarea.selectionEnd}getLinesBeforeSelection(){return n(this.textarea.value).slice(0,t(this.getTextBeforeSelection()))}getLinesAfterSelection(){const e=n(this.textarea.value);return e.slice(t(this.getTextBeforeSelection()+this.getTextOfSelection())+1,e.length)}getLinesOfSelection(){const e=n(this.textarea.value);return e.slice(this.getLinesBeforeSelection().length,e.length-this.getLinesAfterSelection().length)}isContentTooLarge(e){const t=this.getMaxLength();return!(t<0)&&t0}getMaxLength(){return Number(this.textarea.getAttribute("maxlength")??-1)}isDisabled(){return this.textarea.disabled}}function t(e){return(e.match(/\n/g)??[]).length}function n(e){return e.split(/\n/)}class i{instances=[];init(t){if(void 0!==this.instances[t])throw new Error(`Textarea with input-id '${t}' has already been initialized.`);this.instances[t]=new e(t)}get(e){return this.instances[e]??null}}class r{preview_parameter;preview_url;constructor(e,t){this.preview_parameter=e,this.preview_url=t}async getPreviewHtmlOf(e){if(0===e.length)return"";let t=new FormData;return t.append(this.preview_parameter,e),(await fetch(this.preview_url,{method:"POST",body:t})).text()}}const o="textarea",s="preview";class a extends e{preview_history=[];preview_renderer;content_wrappers;view_controls;actions;constructor(e,t){super(t);const n=this.textarea.closest(".c-field-markdown");if(null===n)throw new Error(`Could not find input-wrapper for input-id '${t}'.`);this.preview_renderer=e,this.content_wrappers=function(e){const t=new Map;return t.set(o,e.querySelector("textarea")),t.set(s,e.querySelector(".c-field-markdown__preview")),t.forEach((e=>{if(null===e)throw new Error("Could not find all content-wrappers for markdown-input.")})),t}(n),this.view_controls=function(e){const t=e.querySelector(".il-viewcontrol-mode")?.getElementsByTagName("button");if(!t instanceof HTMLCollection||2!==t.length)throw new Error("Could not find exactly two view-controls.");return[...t]}(n),this.actions=function(e){const t=e.querySelector(".c-field-markdown__actions")?.getElementsByTagName("button");if(t instanceof HTMLCollection)return[...t];return[]}(n);let i=!0;this.textarea.addEventListener("keydown",(e=>{i=this.handleEnterKeyBeforeInsertionHook(e)})),this.textarea.addEventListener("keyup",(e=>{this.handleEnterKeyAfterInsertionHook(e,i)})),this.actions.forEach((e=>{e.addEventListener("click",(e=>{this.performMarkdownActionHook(e)}))})),this.view_controls.forEach((e=>{e.addEventListener("click",(()=>{this.toggleViewingModeHook()}))}))}handleEnterKeyAfterInsertionHook(e,t){if(!t||!u(e))return;const n=this.getLinesBeforeSelection().pop();void 0!==n&&g(n)?this.applyTransformationToSelection(l):void 0!==n&&f(n)&&this.insertSingleEnumeration()}handleEnterKeyBeforeInsertionHook(e){if(!u(e))return!1;const t=this.getLinesOfSelection().shift();if(void 0===t||!((t.match(/((^(\s*-)|(^(\s*\d+\.)))\s*)$/g)??[]).length>0))return!0;let n=this.getLinesBeforeSelection().join("\n"),i=this.getLinesAfterSelection().join("\n");return n.length>0&&(n+="\n"),i.length>0&&(i=`\n${i}`),this.updateTextareaContent(n+i,this.getAbsoluteSelectionStart()-t.length,this.getAbsoluteSelectionEnd()-t.length),e.preventDefault(),!1}performMarkdownActionHook(e){const t=function(e){const t=e.parentNode.closest("span");if(!t instanceof HTMLSpanElement)return null;if(!t.hasAttribute("data-action"))return null;return t.dataset.action}(e.target);switch(t){case"insert-heading":this.insertCharactersAroundSelection("# ","");break;case"insert-link":this.insertCharactersAroundSelection("[","](url)");break;case"insert-bold":this.insertCharactersAroundSelection("**","**");break;case"insert-italic":this.insertCharactersAroundSelection("_","_");break;case"insert-bullet-points":this.applyTransformationToSelection(l);break;case"insert-enumeration":this.isMultilineTextSelected()?this.applyTransformationToSelection(h):this.insertSingleEnumeration();break;default:throw new Error(`Could not perform markdown-action '${t}'.`)}}toggleViewingModeHook(){this.content_wrappers.forEach((e=>{c(e,"hidden")})),this.view_controls.forEach((e=>{c(e,"engaged")})),this.isDisabled()||this.actions.forEach((e=>{e.disabled=!e.disabled;const t=e.querySelector(".glyph");null!==t&&c(t,"disabled")})),this.maybeUpdatePreviewContent()}insertSingleEnumeration(){const e=this.getLinesOfSelection();if(1!==e.length)return void this.textarea.focus();const t=this.getLinesBeforeSelection(),n=t.length-1;let i=n>=0?function(e){const t=e.match(/([0-9]+)/);if(null!==t)return parseInt(t[0]);return null}(t[n])??0:0;const r=h(e,++i),o=function(e,t=0){if(e.length<1)return[];const n=[];for(const i of e){if(!f(i))break;n.push(i.replace(/([0-9]+)/,(++t).toString()))}n.length>0&&(e=n.concat(e.slice(n.length)));return e}(this.getLinesAfterSelection(),i);let s=t.join("\n");const a=o.join("\n");let l=r.join("\n");s.length>0&&l.length>0&&(s+="\n"),l.length>0&&a.length>0&&(l+="\n");const c=s+l+a,u=c.length-this.textarea.value.length;this.updateTextareaContent(c,this.getAbsoluteSelectionStart()+u,this.getAbsoluteSelectionEnd()+u)}applyTransformationToSelection(e){if(!e instanceof Function)throw new Error(`Transformation must be an instance of Function, ${typeof e} given.`);const t=e(this.getLinesOfSelection());if(!t instanceof Array)throw new Error(`Transformation must return an instance of Array, ${typeof t} returned.`);const n=t.length>1;let i=this.getLinesBeforeSelection().join("\n");const r=this.getLinesAfterSelection().join("\n");let o=t.join("\n");i.length>0&&o.length>0&&(i+="\n"),o.length>0&&r.length>0&&(o+="\n");const s=i+o+r,a=s.length-this.textarea.value.length,l=n?i.length:this.getAbsoluteSelectionStart()+a,h=n?l+o.length-1:this.getAbsoluteSelectionEnd()+a;this.updateTextareaContent(s,l,h)}insertCharactersAroundSelection(e,t){const n=this.getTextBeforeSelection()+e+this.getTextOfSelection()+t+this.getTextAfterSelection(),i=this.getAbsoluteSelectionStart()+e.length,r=this.getAbsoluteSelectionEnd()+e.length;this.updateTextareaContent(n,i,r)}maybeUpdatePreviewContent(){const e=this.preview_history[this.preview_history.length-1]??"",t=this.textarea.value;t!==e&&(this.preview_history.push(t),this.preview_renderer.getPreviewHtmlOf(t).then((e=>{this.content_wrappers.get(s).innerHTML=e})))}getBulletPointTransformation(){return l}getEnumerationTransformation(){return h}}function l(e){const t=[],n=!g(e[0]??"");for(const i of e)t.push(n?`- ${i}`:d(i));return t}function h(e,t=1){const n=[],i=!f(e[0]??"");for(const r of e)n.push(i?`${t++}. ${r}`:d(r));return n}function c(e,t){e.classList.contains(t)?e.classList.remove(t):e.classList.add(t)}function u(e){return e instanceof KeyboardEvent&&"Enter"===e.code}function d(e){return e.replace(/((^(\s*[-])|(^(\s*\d+\.)))\s*)/g,"")}function g(e){return(e.match(/^(\s*[-])/g)??[]).length>0}function f(e){return(e.match(/^(\s*\d+\.)/g)??[]).length>0}class p{instances=[];init(e,t,n){if(void 0!==this.instances[e])throw new Error(`Markdown with input-id '${e}' has already been initialized.`);this.instances[e]=new a(new r(n,t),e)}get(e){return this.instances[e]??null}}var S,w=w||{};w.UI=w.UI||{},w.UI.Input=w.UI.Input||{},(S=w.UI.Input).textarea=new i,S.markdown=new p; +!function(e){"use strict";class t{textarea;remainder=null;constructor(e){if(this.textarea=document.getElementById(e),null===this.textarea)throw new Error(`Could not find textarea for input-id '${e}'.`);if(this.shouldShowRemainder()){if(this.remainder=this.textarea.parentNode.querySelector('[data-action="remainder"]'),!this.remainder instanceof HTMLSpanElement)throw new Error(`Could not find remainder-element for input-id '${e}'.`);this.textarea.addEventListener("input",(()=>{this.updateRemainderCountHook()}))}}updateRemainderCountHook(){this.shouldShowRemainder()&&null!==this.remainder&&(this.remainder.innerHTML=(this.textarea.maxLength-this.textarea.value.length).toString())}updateTextareaContent(e,t=null,n=null){if(!this.isDisabled()){if(this.isContentTooLarge(e))return this.updateRemainderCountHook(),void this.textarea.focus();t=t??this.textarea.selectionStart,n=n??this.textarea.selectionEnd,this.textarea.value=e,tthis.textarea.selectionEnd?this.textarea.selectionStart:this.textarea.selectionEnd}getLinesBeforeSelection(){return i(this.textarea.value).slice(0,n(this.getTextBeforeSelection()))}getLinesAfterSelection(){const e=i(this.textarea.value);return e.slice(n(this.getTextBeforeSelection()+this.getTextOfSelection())+1,e.length)}getLinesOfSelection(){const e=i(this.textarea.value);return e.slice(this.getLinesBeforeSelection().length,e.length-this.getLinesAfterSelection().length)}isContentTooLarge(e){const t=this.getMaxLength();return!(t<0)&&t0}getMaxLength(){return Number(this.textarea.getAttribute("maxlength")??-1)}isDisabled(){return this.textarea.disabled}}function n(e){return(e.match(/\n/g)??[]).length}function i(e){return e.split(/\n/)}class r{instances=[];init(e){if(void 0!==this.instances[e])throw new Error(`Textarea with input-id '${e}' has already been initialized.`);this.instances[e]=new t(e)}get(e){return this.instances[e]??null}}class o{preview_parameter;preview_url;constructor(e,t){this.preview_parameter=e,this.preview_url=t}async getPreviewHtmlOf(e){if(0===e.length)return"";let t=new FormData;return t.append(this.preview_parameter,e),(await fetch(this.preview_url,{method:"POST",body:t})).text()}}const s="textarea",a="preview";class l extends t{preview_history=[];preview_renderer;content_wrappers;view_controls;actions;constructor(e,t){super(t);const n=this.textarea.closest(".c-field-markdown");if(null===n)throw new Error(`Could not find input-wrapper for input-id '${t}'.`);this.preview_renderer=e,this.content_wrappers=function(e){const t=new Map;return t.set(s,e.querySelector("textarea")),t.set(a,e.querySelector(".c-field-markdown__preview")),t.forEach((e=>{if(null===e)throw new Error("Could not find all content-wrappers for markdown-input.")})),t}(n),this.view_controls=function(e){const t=e.querySelector(".il-viewcontrol-mode")?.getElementsByTagName("button");if(!t instanceof HTMLCollection||2!==t.length)throw new Error("Could not find exactly two view-controls.");return[...t]}(n),this.actions=function(e){const t=e.querySelector(".c-field-markdown__actions")?.getElementsByTagName("button");if(t instanceof HTMLCollection)return[...t];return[]}(n);let i=!0;this.textarea.addEventListener("keydown",(e=>{i=this.handleEnterKeyBeforeInsertionHook(e)})),this.textarea.addEventListener("keyup",(e=>{this.handleEnterKeyAfterInsertionHook(e,i)})),this.actions.forEach((e=>{e.addEventListener("click",(e=>{this.performMarkdownActionHook(e)}))})),this.view_controls.forEach((e=>{e.addEventListener("click",(()=>{this.toggleViewingModeHook()}))}))}handleEnterKeyAfterInsertionHook(e,t){if(!t||!d(e))return;const n=this.getLinesBeforeSelection().pop();void 0!==n&&f(n)?this.applyTransformationToSelection(h):void 0!==n&&p(n)&&this.insertSingleEnumeration()}handleEnterKeyBeforeInsertionHook(e){if(!d(e))return!1;const t=this.getLinesOfSelection().shift();if(void 0===t||!((t.match(/((^(\s*-)|(^(\s*\d+\.)))\s*)$/g)??[]).length>0))return!0;let n=this.getLinesBeforeSelection().join("\n"),i=this.getLinesAfterSelection().join("\n");return n.length>0&&(n+="\n"),i.length>0&&(i=`\n${i}`),this.updateTextareaContent(n+i,this.getAbsoluteSelectionStart()-t.length,this.getAbsoluteSelectionEnd()-t.length),e.preventDefault(),!1}performMarkdownActionHook(e){const t=function(e){const t=e.parentNode.closest("span");if(!t instanceof HTMLSpanElement)return null;if(!t.hasAttribute("data-action"))return null;return t.dataset.action}(e.target);switch(t){case"insert-heading":this.insertCharactersAroundSelection("# ","");break;case"insert-link":this.insertCharactersAroundSelection("[","](url)");break;case"insert-bold":this.insertCharactersAroundSelection("**","**");break;case"insert-italic":this.insertCharactersAroundSelection("_","_");break;case"insert-bullet-points":this.applyTransformationToSelection(h);break;case"insert-enumeration":this.isMultilineTextSelected()?this.applyTransformationToSelection(c):this.insertSingleEnumeration();break;default:throw new Error(`Could not perform markdown-action '${t}'.`)}}toggleViewingModeHook(){this.content_wrappers.forEach((e=>{u(e,"hidden")})),this.view_controls.forEach((e=>{u(e,"engaged")})),this.isDisabled()||this.actions.forEach((e=>{e.disabled=!e.disabled;const t=e.querySelector(".glyph");null!==t&&u(t,"disabled")})),this.maybeUpdatePreviewContent()}insertSingleEnumeration(){const e=this.getLinesOfSelection();if(1!==e.length)return void this.textarea.focus();const t=this.getLinesBeforeSelection(),n=t.length-1;let i=n>=0?function(e){const t=e.match(/([0-9]+)/);if(null!==t)return parseInt(t[0]);return null}(t[n])??0:0;const r=c(e,++i),o=function(e,t=0){if(e.length<1)return[];const n=[];for(const i of e){if(!p(i))break;n.push(i.replace(/([0-9]+)/,(++t).toString()))}n.length>0&&(e=n.concat(e.slice(n.length)));return e}(this.getLinesAfterSelection(),i);let s=t.join("\n");const a=o.join("\n");let l=r.join("\n");s.length>0&&l.length>0&&(s+="\n"),l.length>0&&a.length>0&&(l+="\n");const h=s+l+a,u=h.length-this.textarea.value.length;this.updateTextareaContent(h,this.getAbsoluteSelectionStart()+u,this.getAbsoluteSelectionEnd()+u)}applyTransformationToSelection(e){if(!e instanceof Function)throw new Error(`Transformation must be an instance of Function, ${typeof e} given.`);const t=e(this.getLinesOfSelection());if(!t instanceof Array)throw new Error(`Transformation must return an instance of Array, ${typeof t} returned.`);const n=t.length>1;let i=this.getLinesBeforeSelection().join("\n");const r=this.getLinesAfterSelection().join("\n");let o=t.join("\n");i.length>0&&o.length>0&&(i+="\n"),o.length>0&&r.length>0&&(o+="\n");const s=i+o+r,a=s.length-this.textarea.value.length,l=n?i.length:this.getAbsoluteSelectionStart()+a,h=n?l+o.length-1:this.getAbsoluteSelectionEnd()+a;this.updateTextareaContent(s,l,h)}insertCharactersAroundSelection(e,t){const n=this.getTextBeforeSelection()+e+this.getTextOfSelection()+t+this.getTextAfterSelection(),i=this.getAbsoluteSelectionStart()+e.length,r=this.getAbsoluteSelectionEnd()+e.length;this.updateTextareaContent(n,i,r)}maybeUpdatePreviewContent(){const e=this.preview_history[this.preview_history.length-1]??"",t=this.textarea.value;t!==e&&(this.preview_history.push(t),this.preview_renderer.getPreviewHtmlOf(t).then((e=>{this.content_wrappers.get(a).innerHTML=e})))}getBulletPointTransformation(){return h}getEnumerationTransformation(){return c}}function h(e){const t=[],n=!f(e[0]??"");for(const i of e)t.push(n?`- ${i}`:g(i));return t}function c(e,t=1){const n=[],i=!p(e[0]??"");for(const r of e)n.push(i?`${t++}. ${r}`:g(r));return n}function u(e,t){e.classList.contains(t)?e.classList.remove(t):e.classList.add(t)}function d(e){return e instanceof KeyboardEvent&&"Enter"===e.code}function g(e){return e.replace(/((^(\s*[-])|(^(\s*\d+\.)))\s*)/g,"")}function f(e){return(e.match(/^(\s*[-])/g)??[]).length>0}function p(e){return(e.match(/^(\s*\d+\.)/g)??[]).length>0}class S{instances=[];init(e,t,n){if(void 0!==this.instances[e])throw new Error(`Markdown with input-id '${e}' has already been initialized.`);this.instances[e]=new l(new o(n,t),e)}get(e){return this.instances[e]??null}}var w;e.UI=e.UI||{},e.UI.Input=e.UI.Input||{},(w=e.UI.Input).textarea=new r,w.markdown=new S}(il); diff --git a/components/ILIAS/UI/resources/js/Input/Field/rollup.config.js b/components/ILIAS/UI/resources/js/Input/Field/rollup.config.js index 498d5f004e7e..8490a3370c83 100755 --- a/components/ILIAS/UI/resources/js/Input/Field/rollup.config.js +++ b/components/ILIAS/UI/resources/js/Input/Field/rollup.config.js @@ -14,14 +14,21 @@ */ import terser from '@rollup/plugin-terser'; -import copyright from '../../../../../../../scripts/Copyright-Checker/copyright'; -import preserveCopyright from '../../../../../../../scripts/Copyright-Checker/preserveCopyright'; +import copyright from '../../../../../../../scripts/Copyright-Checker/copyright.js'; +import preserveCopyright from '../../../../../../../scripts/Copyright-Checker/preserveCopyright.js'; export default { input: './src/input.factory.js', + external: [ + 'ilias', + ], output: { file: './dist/input.factory.min.js', - format: 'es', + format: 'iife', + banner: copyright, + globals: { + ilias: 'il', + }, plugins: [ terser({ format: { diff --git a/components/ILIAS/UI/resources/js/Input/Field/src/input.factory.js b/components/ILIAS/UI/resources/js/Input/Field/src/input.factory.js index 1cf726e04006..94014cbd5f1d 100755 --- a/components/ILIAS/UI/resources/js/Input/Field/src/input.factory.js +++ b/components/ILIAS/UI/resources/js/Input/Field/src/input.factory.js @@ -24,10 +24,10 @@ * other and are bundled into separate files. */ +import il from 'ilias'; import TextareaFactory from './Textarea/textarea.factory'; import MarkdownFactory from './Markdown/markdown.factory'; -var il = il || {}; il.UI = il.UI || {}; il.UI.Input = il.UI.Input || {};