558 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			558 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /**
 | |
|  * @copyright   (C) 2021 Open Source Matters, Inc. <https://www.joomla.org>
 | |
|  * @license     GNU General Public License version 2 or later; see LICENSE.txt
 | |
|  */
 | |
| if (!Joomla) {
 | |
|   throw new Error('Joomla API is not properly initiated');
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * An object holding all the information of the selected image in media manager
 | |
|  * eg:
 | |
|  * {
 | |
|  *   extension: "png"
 | |
|  *   fileType: "image/png"
 | |
|  *   height: 44
 | |
|  *   path: "local-images:/powered_by.png"
 | |
|  *   thumb: undefined
 | |
|  *   width: 294
 | |
|  * }
 | |
|  */
 | |
| Joomla.selectedMediaFile = {};
 | |
| const supportedExtensions = Joomla.getOptions('media-picker', {});
 | |
| if (!Object.keys(supportedExtensions).length) {
 | |
|   throw new Error('No supported extensions provided');
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Event Listener that updates the Joomla.selectedMediaFile
 | |
|  * to the selected file in the media manager
 | |
|  */
 | |
| document.addEventListener('onMediaFileSelected', async e => {
 | |
|   Joomla.selectedMediaFile = e.detail;
 | |
|   const currentModal = Joomla.Modal.getCurrent();
 | |
|   const container = currentModal.querySelector('.joomla-dialog-body');
 | |
| 
 | |
|   // No extra attributes (lazy, alt) for fields
 | |
|   if (!container || container.closest('.joomla-dialog-media-field')) {
 | |
|     return;
 | |
|   }
 | |
|   const optionsEl = container.querySelector('joomla-field-mediamore');
 | |
|   if (optionsEl) {
 | |
|     optionsEl.parentNode.removeChild(optionsEl);
 | |
|   }
 | |
|   const {
 | |
|     images,
 | |
|     audios,
 | |
|     videos,
 | |
|     documents
 | |
|   } = supportedExtensions;
 | |
|   if (Joomla.selectedMediaFile.path && Joomla.selectedMediaFile.type === 'file') {
 | |
|     let type;
 | |
|     if (images.includes(Joomla.selectedMediaFile.extension.toLowerCase())) {
 | |
|       type = 'images';
 | |
|     } else if (audios.includes(Joomla.selectedMediaFile.extension.toLowerCase())) {
 | |
|       type = 'audios';
 | |
|     } else if (videos.includes(Joomla.selectedMediaFile.extension.toLowerCase())) {
 | |
|       type = 'videos';
 | |
|     } else if (documents.includes(Joomla.selectedMediaFile.extension.toLowerCase())) {
 | |
|       type = 'documents';
 | |
|     }
 | |
|     if (type) {
 | |
|       container.insertAdjacentHTML('afterbegin', `<joomla-field-mediamore
 | |
|   parent-id="${currentModal.id}"
 | |
|   type="${type}"
 | |
|   summary-label="${Joomla.Text._('JFIELD_MEDIA_SUMMARY_LABEL')}"
 | |
|   lazy-label="${Joomla.Text._('JFIELD_MEDIA_LAZY_LABEL')}"
 | |
|   alt-label="${Joomla.Text._('JFIELD_MEDIA_ALT_LABEL')}"
 | |
|   alt-check-label="${Joomla.Text._('JFIELD_MEDIA_ALT_CHECK_LABEL')}"
 | |
|   alt-check-desc-label="${Joomla.Text._('JFIELD_MEDIA_ALT_CHECK_DESC_LABEL')}"
 | |
|   classes-label="${Joomla.Text._('JFIELD_MEDIA_CLASS_LABEL')}"
 | |
|   figure-classes-label="${Joomla.Text._('JFIELD_MEDIA_FIGURE_CLASS_LABEL')}"
 | |
|   figure-caption-label="${Joomla.Text._('JFIELD_MEDIA_FIGURE_CAPTION_LABEL')}"
 | |
|   embed-check-label="${Joomla.Text._('JFIELD_MEDIA_EMBED_CHECK_LABEL')}"
 | |
|   embed-check-desc-label="${Joomla.Text._('JFIELD_MEDIA_EMBED_CHECK_DESC_LABEL')}"
 | |
|   download-check-label="${Joomla.Text._('JFIELD_MEDIA_DOWNLOAD_CHECK_LABEL')}"
 | |
|   download-check-desc-label="${Joomla.Text._('JFIELD_MEDIA_DOWNLOAD_CHECK_DESC_LABEL')}"
 | |
|   title-label="${Joomla.Text._('JFIELD_MEDIA_TITLE_LABEL')}"
 | |
|   width-label="${Joomla.Text._('JFIELD_MEDIA_WIDTH_LABEL')}"
 | |
|   height-label="${Joomla.Text._('JFIELD_MEDIA_HEIGHT_LABEL')}"
 | |
| ></joomla-field-mediamore>
 | |
| `);
 | |
|     }
 | |
|   }
 | |
| });
 | |
| 
 | |
| /**
 | |
|  * Method to check if passed param is HTMLElement
 | |
|  *
 | |
|  * @param o {string|HTMLElement}  Element to be checked
 | |
|  *
 | |
|  * @returns {boolean}
 | |
|  */
 | |
| const isElement = o => typeof HTMLElement === 'object' ? o instanceof HTMLElement : o && typeof o === 'object' && o.nodeType === 1 && typeof o.nodeName === 'string';
 | |
| 
 | |
| /**
 | |
|  * Method to return the image size
 | |
|  *
 | |
|  * @param url {string}
 | |
|  *
 | |
|  * @returns {bool}
 | |
|  */
 | |
| const getImageSize = url => new Promise((resolve, reject) => {
 | |
|   const img = new Image();
 | |
|   img.src = url;
 | |
|   img.onload = () => {
 | |
|     Joomla.selectedMediaFile.width = img.width;
 | |
|     Joomla.selectedMediaFile.height = img.height;
 | |
|     resolve(true);
 | |
|   };
 | |
|   img.onerror = () => {
 | |
|     // eslint-disable-next-line prefer-promise-reject-errors
 | |
|     reject(false);
 | |
|   };
 | |
| });
 | |
| const insertAsImage = async (media, editor, fieldClass) => {
 | |
|   if (media.url) {
 | |
|     const {
 | |
|       rootFull
 | |
|     } = Joomla.getOptions('system.paths');
 | |
|     const parts = media.url.split(rootFull);
 | |
|     if (parts.length > 1) {
 | |
|       // eslint-disable-next-line prefer-destructuring
 | |
|       Joomla.selectedMediaFile.url = parts[1];
 | |
|       if (media.thumb_path) {
 | |
|         Joomla.selectedMediaFile.thumb = media.thumb_path;
 | |
|       } else {
 | |
|         Joomla.selectedMediaFile.thumb = false;
 | |
|       }
 | |
|     } else if (media.thumb_path) {
 | |
|       Joomla.selectedMediaFile.url = media.url;
 | |
|       Joomla.selectedMediaFile.thumb = media.thumb_path;
 | |
|     }
 | |
|   } else {
 | |
|     Joomla.selectedMediaFile.url = false;
 | |
|   }
 | |
|   if (Joomla.selectedMediaFile.url) {
 | |
|     let attribs;
 | |
|     let isLazy = '';
 | |
|     let alt = '';
 | |
|     let appendAlt = '';
 | |
|     let classes = '';
 | |
|     let figClasses = '';
 | |
|     let figCaption = '';
 | |
|     let imageElement = '';
 | |
|     if (!isElement(editor) || editor.replaceSelection) {
 | |
|       const editorInst = editor.replaceSelection ? editor : Joomla.editors.instances[editor];
 | |
|       const currentModal = Joomla.Modal.getCurrent();
 | |
|       attribs = currentModal.querySelector('joomla-field-mediamore');
 | |
|       if (attribs) {
 | |
|         if (attribs.getAttribute('alt-check') === 'true') {
 | |
|           appendAlt = ' alt=""';
 | |
|         }
 | |
|         alt = attribs.getAttribute('alt-value') ? ` alt="${attribs.getAttribute('alt-value')}"` : appendAlt;
 | |
|         classes = attribs.getAttribute('img-classes') ? ` class="${attribs.getAttribute('img-classes')}"` : '';
 | |
|         figClasses = attribs.getAttribute('fig-classes') ? ` class="image ${attribs.getAttribute('fig-classes')}"` : ' class="image"';
 | |
|         figCaption = attribs.getAttribute('fig-caption') ? `${attribs.getAttribute('fig-caption')}` : '';
 | |
|         if (attribs.getAttribute('is-lazy') === 'true') {
 | |
|           isLazy = ` loading="lazy" width="${Joomla.selectedMediaFile.width}" height="${Joomla.selectedMediaFile.height}"`;
 | |
|           if (Joomla.selectedMediaFile.width === 0 || Joomla.selectedMediaFile.height === 0) {
 | |
|             try {
 | |
|               await getImageSize(Joomla.selectedMediaFile.url);
 | |
|               isLazy = ` loading="lazy" width="${Joomla.selectedMediaFile.width}" height="${Joomla.selectedMediaFile.height}"`;
 | |
|             } catch (err) {
 | |
|               isLazy = '';
 | |
|             }
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|       if (figCaption) {
 | |
|         imageElement = `<figure${figClasses}><img src="${Joomla.selectedMediaFile.url}"${classes}${isLazy}${alt} data-path="${Joomla.selectedMediaFile.path}"/><figcaption>${figCaption}</figcaption></figure>`;
 | |
|       } else {
 | |
|         imageElement = `<img src="${Joomla.selectedMediaFile.url}"${classes}${isLazy}${alt} data-path="${Joomla.selectedMediaFile.path}"/>`;
 | |
|       }
 | |
|       if (attribs) {
 | |
|         attribs.parentNode.removeChild(attribs);
 | |
|       }
 | |
|       editorInst.replaceSelection(imageElement);
 | |
|     } else {
 | |
|       if (Joomla.selectedMediaFile.width === 0 || Joomla.selectedMediaFile.height === 0) {
 | |
|         try {
 | |
|           await getImageSize(Joomla.selectedMediaFile.url);
 | |
|           // eslint-disable-next-line no-empty
 | |
|         } catch (err) {
 | |
|           Joomla.selectedMediaFile.height = 0;
 | |
|           Joomla.selectedMediaFile.width = 0;
 | |
|         }
 | |
|       }
 | |
|       fieldClass.markValid();
 | |
|       fieldClass.setValue(`${Joomla.selectedMediaFile.url}#joomlaImage://${media.path.replace(':', '')}?width=${Joomla.selectedMediaFile.width}&height=${Joomla.selectedMediaFile.height}`);
 | |
|     }
 | |
|   }
 | |
| };
 | |
| const insertAsOther = (media, editor, fieldClass, type) => {
 | |
|   if (media.url) {
 | |
|     const {
 | |
|       rootFull
 | |
|     } = Joomla.getOptions('system.paths');
 | |
|     const parts = media.url.split(rootFull);
 | |
|     if (parts.length > 1) {
 | |
|       // eslint-disable-next-line prefer-destructuring
 | |
|       Joomla.selectedMediaFile.url = parts[1];
 | |
|     } else {
 | |
|       Joomla.selectedMediaFile.url = media.url;
 | |
|     }
 | |
|   } else {
 | |
|     Joomla.selectedMediaFile.url = false;
 | |
|   }
 | |
|   let attribs;
 | |
|   if (Joomla.selectedMediaFile.url) {
 | |
|     // Available Only inside an editor
 | |
|     if (!isElement(editor) || editor.replaceSelection) {
 | |
|       let outputText;
 | |
|       const editorInst = editor.replaceSelection ? editor : Joomla.editors.instances[editor];
 | |
|       const currentModal = Joomla.Modal.getCurrent();
 | |
|       attribs = currentModal.querySelector('joomla-field-mediamore');
 | |
|       if (attribs) {
 | |
|         const embedable = attribs.getAttribute('embed-it');
 | |
|         if (embedable && embedable === 'true') {
 | |
|           if (type === 'audios') {
 | |
|             outputText = `<audio controls src="${Joomla.selectedMediaFile.url}"></audio>`;
 | |
|           }
 | |
|           if (type === 'documents') {
 | |
|             // @todo use ${Joomla.selectedMediaFile.filetype} in type
 | |
|             const title = attribs.getAttribute('title');
 | |
|             outputText = `<object type="application/${Joomla.selectedMediaFile.extension}" data="${Joomla.selectedMediaFile.url}" ${title ? `title="${title}"` : ''} width="${attribs.getAttribute('width')}" height="${attribs.getAttribute('height')}">
 | |
|   ${Joomla.Text._('JFIELD_MEDIA_UNSUPPORTED').replace('{tag}', `<a download href="${Joomla.selectedMediaFile.url}">`).replace(/{extension}/g, Joomla.selectedMediaFile.extension)}
 | |
| </object>`;
 | |
|           }
 | |
|           if (type === 'videos') {
 | |
|             outputText = `<video controls width="${attribs.getAttribute('width')}" height="${attribs.getAttribute('height')}">
 | |
|   <source src="${Joomla.selectedMediaFile.url}" type="${Joomla.selectedMediaFile.fileType}">
 | |
| </video>`;
 | |
|           }
 | |
|         } else if (editorInst.getSelection() !== '') {
 | |
|           outputText = `<a download href="${Joomla.selectedMediaFile.url}">${editorInst.getSelection()}</a>`;
 | |
|         } else {
 | |
|           const name = /([\w-]+)\./.exec(Joomla.selectedMediaFile.url);
 | |
|           outputText = `<a download href="${Joomla.selectedMediaFile.url}">${Joomla.Text._('JFIELD_MEDIA_DOWNLOAD_FILE').replace('{file}', name[1])}</a>`;
 | |
|         }
 | |
|       }
 | |
|       if (attribs) {
 | |
|         attribs.parentNode.removeChild(attribs);
 | |
|       }
 | |
|       editorInst.replaceSelection(outputText);
 | |
|     } else {
 | |
|       fieldClass.markValid();
 | |
|       fieldClass.givenType = type;
 | |
|       fieldClass.setValue(Joomla.selectedMediaFile.url);
 | |
|     }
 | |
|   }
 | |
| };
 | |
| 
 | |
| /**
 | |
|  * Method to append the image in an editor or a field
 | |
|  *
 | |
|  * @param {{}} resp
 | |
|  * @param {string|HTMLElement} editor
 | |
|  * @param {string} fieldClass
 | |
|  */
 | |
| const execTransform = async (resp, editor, fieldClass) => {
 | |
|   if (resp.success === true) {
 | |
|     const media = resp.data[0];
 | |
|     const {
 | |
|       images,
 | |
|       audios,
 | |
|       videos,
 | |
|       documents
 | |
|     } = supportedExtensions;
 | |
|     if (Joomla.selectedMediaFile.extension && images.includes(media.extension.toLowerCase())) {
 | |
|       return insertAsImage(media, editor, fieldClass);
 | |
|     }
 | |
|     if (Joomla.selectedMediaFile.extension && audios.includes(media.extension.toLowerCase())) {
 | |
|       return insertAsOther(media, editor, fieldClass, 'audios');
 | |
|     }
 | |
|     if (Joomla.selectedMediaFile.extension && documents.includes(media.extension.toLowerCase())) {
 | |
|       return insertAsOther(media, editor, fieldClass, 'documents');
 | |
|     }
 | |
|     if (Joomla.selectedMediaFile.extension && videos.includes(media.extension.toLowerCase())) {
 | |
|       return insertAsOther(media, editor, fieldClass, 'videos');
 | |
|     }
 | |
|   }
 | |
|   return '';
 | |
| };
 | |
| 
 | |
| /**
 | |
|  * Method that resolves the real url for the selected media file
 | |
|  *
 | |
|  * @param data        {object}         The data for the detail
 | |
|  * @param editor      {string|object}  The data for the detail
 | |
|  * @param fieldClass  {HTMLElement}    The fieldClass for the detail
 | |
|  *
 | |
|  * @returns {void}
 | |
|  */
 | |
| Joomla.getMedia = (data, editor, fieldClass) => new Promise((resolve, reject) => {
 | |
|   if (!data || typeof data === 'object' && (!data.path || data.path === '')) {
 | |
|     Joomla.selectedMediaFile = {};
 | |
|     resolve({
 | |
|       resp: {
 | |
|         success: false
 | |
|       }
 | |
|     });
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   // Compile the url
 | |
|   const apiUrl = Joomla.getOptions('media-picker-api', {}).apiBaseUrl || 'index.php?option=com_media&format=json';
 | |
|   const url = new URL(apiUrl, window.location.origin);
 | |
|   url.searchParams.append('task', 'api.files');
 | |
|   url.searchParams.append('url', true);
 | |
|   url.searchParams.append('path', data.path);
 | |
|   url.searchParams.append('mediatypes', '0,1,2,3');
 | |
|   url.searchParams.append(Joomla.getOptions('csrf.token'), 1);
 | |
|   fetch(url, {
 | |
|     method: 'GET',
 | |
|     headers: {
 | |
|       'Content-Type': 'application/json'
 | |
|     }
 | |
|   }).then(response => response.json()).then(async response => resolve(await execTransform(response, editor, fieldClass))).catch(error => reject(error));
 | |
| });
 | |
| 
 | |
| // For B/C purposes
 | |
| Joomla.getImage = Joomla.getMedia;
 | |
| 
 | |
| /**
 | |
|  * A simple Custom Element for adding alt text and controlling
 | |
|  * the lazy loading on a selected image
 | |
|  *
 | |
|  * Will be rendered only for editor content images
 | |
|  * Attributes:
 | |
|  * - parent-id: the id of the parent media field {string}
 | |
|  * - lazy-label: The text for the checkbox label {string}
 | |
|  * - alt-label: The text for the alt label {string}
 | |
|  * - is-lazy: The value for the lazyloading (calculated, defaults to 'true') {string}
 | |
|  * - alt-value: The value for the alt text (calculated, defaults to '') {string}
 | |
|  */
 | |
| class JoomlaFieldMediaOptions extends HTMLElement {
 | |
|   get type() {
 | |
|     return this.getAttribute('type');
 | |
|   }
 | |
|   get parentId() {
 | |
|     return this.getAttribute('parent-id');
 | |
|   }
 | |
|   get lazytext() {
 | |
|     return this.getAttribute('lazy-label');
 | |
|   }
 | |
|   get alttext() {
 | |
|     return this.getAttribute('alt-label');
 | |
|   }
 | |
|   get altchecktext() {
 | |
|     return this.getAttribute('alt-check-label');
 | |
|   }
 | |
|   get altcheckdesctext() {
 | |
|     return this.getAttribute('alt-check-desc-label');
 | |
|   }
 | |
|   get embedchecktext() {
 | |
|     return this.getAttribute('embed-check-label');
 | |
|   }
 | |
|   get embedcheckdesctext() {
 | |
|     return this.getAttribute('embed-check-desc-label');
 | |
|   }
 | |
|   get downloadchecktext() {
 | |
|     return this.getAttribute('download-check-label');
 | |
|   }
 | |
|   get downloadcheckdesctext() {
 | |
|     return this.getAttribute('download-check-desc-label');
 | |
|   }
 | |
|   get classestext() {
 | |
|     return this.getAttribute('classes-label');
 | |
|   }
 | |
|   get figclassestext() {
 | |
|     return this.getAttribute('figure-classes-label');
 | |
|   }
 | |
|   get figcaptiontext() {
 | |
|     return this.getAttribute('figure-caption-label');
 | |
|   }
 | |
|   get summarytext() {
 | |
|     return this.getAttribute('summary-label');
 | |
|   }
 | |
|   get widthtext() {
 | |
|     return this.getAttribute('width-label');
 | |
|   }
 | |
|   get heighttext() {
 | |
|     return this.getAttribute('height-label');
 | |
|   }
 | |
|   get titletext() {
 | |
|     return this.getAttribute('title-label');
 | |
|   }
 | |
|   connectedCallback() {
 | |
|     if (this.type === 'images') {
 | |
|       this.innerHTML = `<details open>
 | |
| <summary>${this.summarytext}</summary>
 | |
| <div class="">
 | |
|   <div class="form-group">
 | |
|     <div class="input-group">
 | |
|       <label class="input-group-text" for="${this.parentId}-alt">${this.alttext}</label>
 | |
|       <input class="form-control" type="text" id="${this.parentId}-alt" data-is="alt-value" />
 | |
|     </div>
 | |
|   </div>
 | |
|   <div class="form-group">
 | |
|     <div class="form-check">
 | |
|       <input class="form-check-input" type="checkbox" id="${this.parentId}-alt-check">
 | |
|       <label class="form-check-label" for="${this.parentId}-alt-check">${this.altchecktext}</label>
 | |
|       <div><small class="form-text">${this.altcheckdesctext}</small></div>
 | |
|     </div>
 | |
|   </div>
 | |
|   <div class="form-group">
 | |
|     <div class="form-check">
 | |
|       <input class="form-check-input" type="checkbox" id="${this.parentId}-lazy" checked>
 | |
|       <label class="form-check-label" for="${this.parentId}-lazy">${this.lazytext}</label>
 | |
|     </div>
 | |
|   </div>
 | |
|   <div class="form-group">
 | |
|     <div class="input-group">
 | |
|       <label class="input-group-text" for="${this.parentId}-classes">${this.classestext}</label>
 | |
|       <input class="form-control" type="text" id="${this.parentId}-classes" data-is="img-classes"/>
 | |
|     </div>
 | |
|   </div>
 | |
|   <div class="form-group">
 | |
|     <div class="input-group">
 | |
|       <label class="input-group-text" for="${this.parentId}-figclasses">${this.figclassestext}</label>
 | |
|       <input class="form-control" type="text" id="${this.parentId}-figclasses" data-is="fig-classes"/>
 | |
|     </div>
 | |
|   </div>
 | |
|   <div class="form-group">
 | |
|     <div class="input-group">
 | |
|       <label class="input-group-text" for="${this.parentId}-figcaption">${this.figcaptiontext}</label>
 | |
|       <input class="form-control" type="text" id="${this.parentId}-figcaption" data-is="fig-caption"/>
 | |
|     </div>
 | |
|   </div>
 | |
| </div>
 | |
| </details>`;
 | |
|       this.lazyInputFn = this.lazyInputFn.bind(this);
 | |
|       this.altCheckFn = this.altCheckFn.bind(this);
 | |
|       this.inputFn = this.inputFn.bind(this);
 | |
| 
 | |
|       // Add event listeners
 | |
|       this.lazyInput = this.querySelector(`#${this.parentId}-lazy`);
 | |
|       this.lazyInput.addEventListener('change', this.lazyInputFn);
 | |
|       this.altCheck = this.querySelector(`#${this.parentId}-alt-check`);
 | |
|       this.altCheck.addEventListener('input', this.altCheckFn);
 | |
|       [].slice.call(this.querySelectorAll('input[type="text"]')).map(el => {
 | |
|         el.addEventListener('input', this.inputFn);
 | |
|         const {
 | |
|           is
 | |
|         } = el.dataset;
 | |
|         if (is) {
 | |
|           this.setAttribute(is, el.value.replace(/"/g, '"'));
 | |
|         }
 | |
|         return el;
 | |
|       });
 | |
| 
 | |
|       // Set initial values
 | |
|       this.setAttribute('is-lazy', !!this.lazyInput.checked);
 | |
|       this.setAttribute('alt-check', false);
 | |
|     } else if (['audios', 'videos', 'documents'].includes(this.type)) {
 | |
|       this.innerHTML = `<details open>
 | |
| <summary>${this.summarytext}</summary>
 | |
| <div class="">
 | |
|   <div class="form-group">
 | |
|     <div class="form-check">
 | |
|       <input class="form-check-input radio" type="radio" name="flexRadioDefault" id="${this.parentId}-embed-check-2" value="0" checked>
 | |
|       <label class="form-check-label" for="${this.parentId}-embed-check-2">
 | |
|         ${this.downloadchecktext}
 | |
|         <div><small class="form-text">${this.downloadcheckdesctext}</small></div>
 | |
|       </label>
 | |
|     </div>
 | |
|     <div class="form-check">
 | |
|       <input class="form-check-input radio" type="radio" name="flexRadioDefault" id="${this.parentId}-embed-check-1" value="1">
 | |
|       <label class="form-check-label" for="${this.parentId}-embed-check-1">
 | |
|         ${this.embedchecktext}
 | |
|         <div><small class="form-text">${this.embedcheckdesctext}</small></div>
 | |
|       </label>
 | |
|     </div>
 | |
|   </div>
 | |
|   <div class="toggable-parts" style="display: none">
 | |
|     <div style="display: ${this.type === 'audios' ? 'none' : 'block'}">
 | |
|       <div class="form-group">
 | |
|         <div class="input-group">
 | |
|           <label class="input-group-text" for="${this.parentId}-width">${this.widthtext}</label>
 | |
|           <input class="form-control" type="text" id="${this.parentId}-width" value="800" data-is="width"/>
 | |
|         </div>
 | |
|       </div>
 | |
|       <div class="form-group">
 | |
|         <div class="input-group">
 | |
|           <label class="input-group-text" for="${this.parentId}-height">${this.heighttext}</label>
 | |
|           <input class="form-control" type="text" id="${this.parentId}-height" value="600" data-is="height"/>
 | |
|         </div>
 | |
|       </div>
 | |
|       <div style="display: ${this.type === 'document' ? 'block' : 'none'}">
 | |
|         <div class="form-group">
 | |
|           <div class="input-group">
 | |
|             <label class="input-group-text" for="${this.parentId}-title">${this.titletext}</label>
 | |
|             <input class="form-control" type="text" id="${this.parentId}-title" value="" data-is="title"/>
 | |
|           </div>
 | |
|         </div>
 | |
|     </div>
 | |
|   </div>
 | |
| </div>
 | |
| </details>`;
 | |
|       this.embedInputFn = this.embedInputFn.bind(this);
 | |
|       this.inputFn = this.inputFn.bind(this);
 | |
|       [].slice.call(this.querySelectorAll('.form-check-input.radio')).map(el => el.addEventListener('input', this.embedInputFn));
 | |
|       this.setAttribute('embed-it', false);
 | |
|       [].slice.call(this.querySelectorAll('input[type="text"]')).map(el => {
 | |
|         el.addEventListener('input', this.inputFn);
 | |
|         const {
 | |
|           is
 | |
|         } = el.dataset;
 | |
|         if (is) {
 | |
|           this.setAttribute(is, el.value.replace(/"/g, '"'));
 | |
|         }
 | |
|         return el;
 | |
|       });
 | |
|     }
 | |
|   }
 | |
|   disconnectedCallback() {
 | |
|     if (this.type === 'image') {
 | |
|       this.lazyInput.removeEventListener('input', this.lazyInputFn);
 | |
|       this.altInput.removeEventListener('input', this.inputFn);
 | |
|       this.altCheck.removeEventListener('input', this.altCheckFn);
 | |
|     }
 | |
|     if (['audio', 'video', 'document'].includes(this.type)) {
 | |
|       [].slice.call(this.querySelectorAll('.form-check-input.radio')).map(el => el.removeEventListener('input', this.embedInputFn));
 | |
|       [].slice.call(this.querySelectorAll('input[type="text"]')).map(el => el.removeEventListener('input', this.embedInputFn));
 | |
|     }
 | |
|     this.innerHTML = '';
 | |
|   }
 | |
|   lazyInputFn(e) {
 | |
|     this.setAttribute('is-lazy', !!e.target.checked);
 | |
|   }
 | |
|   altCheckFn(e) {
 | |
|     this.setAttribute('alt-check', !!e.target.checked);
 | |
|   }
 | |
|   inputFn(e) {
 | |
|     const {
 | |
|       is
 | |
|     } = e.target.dataset;
 | |
|     if (is) {
 | |
|       this.setAttribute(is, e.target.value.replace(/"/g, '"'));
 | |
|     }
 | |
|   }
 | |
|   embedInputFn(e) {
 | |
|     const {
 | |
|       value
 | |
|     } = e.target;
 | |
|     this.setAttribute('embed-it', value !== '0');
 | |
|     const toggable = this.querySelector('.toggable-parts');
 | |
|     if (toggable) {
 | |
|       if (toggable.style.display !== 'block') {
 | |
|         toggable.style.display = 'block';
 | |
|       } else {
 | |
|         toggable.style.display = 'none';
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| }
 | |
| customElements.define('joomla-field-mediamore', JoomlaFieldMediaOptions);
 |