Spade
Mini Shell
| Directory:~$ /home/lmsyaran/public_html/joomla5/media/system/js/fields/ |
| [Home] [System Details] [Kill Me] |
import JoomlaDialog from 'joomla.dialog';
/**
* @copyright (C) 2018 Open Source Matters, Inc.
<https://www.joomla.org>
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
if (!window.Joomla) {
throw new Error('Joomla API is not properly initiated');
}
/**
* Extract the extensions
*
* @param {*} path
* @returns {string}
*/
const getExtension = path => {
const parts = path.split(/[#]/);
if (parts.length > 1) {
return parts[1].split(/[?]/)[0].split('.').pop().trim();
}
return path.split(/[#?]/)[0].split('.').pop().trim();
};
class JoomlaFieldMedia extends HTMLElement {
constructor() {
super();
this.show = this.show.bind(this);
this.clearValue = this.clearValue.bind(this);
this.modalClose = this.modalClose.bind(this);
this.setValue = this.setValue.bind(this);
this.updatePreview = this.updatePreview.bind(this);
this.validateValue = this.validateValue.bind(this);
this.markValid = this.markValid.bind(this);
this.markInvalid = this.markInvalid.bind(this);
this.mimeType = '';
}
static get observedAttributes() {
return ['type', 'base-path',
'root-folder', 'url', 'modal-title',
'modal-width', 'modal-height', 'input',
'button-select', 'button-clear', 'preview',
'preview-width', 'preview-height'];
}
get type() {
return this.getAttribute('type');
}
set type(value) {
this.setAttribute('type', value);
}
get basePath() {
return this.getAttribute('base-path');
}
set basePath(value) {
this.setAttribute('base-path', value);
}
get url() {
return this.getAttribute('url');
}
set url(value) {
this.setAttribute('url', value);
}
get input() {
return this.getAttribute('input');
}
set input(value) {
this.setAttribute('input', value);
}
get buttonSelect() {
return this.getAttribute('button-select');
}
set buttonSelect(value) {
this.setAttribute('button-select', value);
}
get buttonClear() {
return this.getAttribute('button-clear');
}
set buttonClear(value) {
this.setAttribute('button-clear', value);
}
get modalWidth() {
return this.getAttribute('modal-width');
}
set modalWidth(value) {
this.setAttribute('modal-width', value);
}
get modalHeight() {
return this.getAttribute('modal-height');
}
set modalHeight(value) {
this.setAttribute('modal-height', value);
}
get modalTitle() {
return this.getAttribute('modal-title');
}
set modalTitle(value) {
this.setAttribute('modal-title', value);
}
get previewWidth() {
return parseInt(this.getAttribute('preview-width'), 10);
}
set previewWidth(value) {
this.setAttribute('preview-width', value);
}
get previewHeight() {
return parseInt(this.getAttribute('preview-height'), 10);
}
set previewHeight(value) {
this.setAttribute('preview-height', value);
}
get preview() {
return this.getAttribute('preview');
}
set preview(value) {
this.setAttribute('preview', value);
}
get previewContainer() {
return this.getAttribute('preview-container');
}
connectedCallback() {
this.button = this.querySelector(this.buttonSelect);
this.inputElement = this.querySelector(this.input);
this.buttonClearEl = this.querySelector(this.buttonClear);
this.previewElement =
this.querySelector('.field-media-preview');
if (!this.button || !this.inputElement || !this.buttonClearEl) {
throw new Error('Misconfiguaration...');
}
this.button.addEventListener('click', this.show);
if (this.buttonClearEl) {
this.buttonClearEl.addEventListener('click',
this.clearValue);
}
this.supportedExtensions = Joomla.getOptions('media-picker',
{});
if (!Object.keys(this.supportedExtensions).length) {
throw new Error('Joomla API is not properly initiated');
}
this.inputElement.removeAttribute('readonly');
this.inputElement.addEventListener('change',
this.validateValue);
this.updatePreview();
}
disconnectedCallback() {
if (this.button) {
this.button.removeEventListener('click', this.show);
}
if (this.buttonClearEl) {
this.buttonClearEl.removeEventListener('click',
this.clearValue);
}
if (this.inputElement) {
this.inputElement.removeEventListener('change',
this.validateValue);
}
if (this.dialog) {
this.dialog.close();
}
}
show() {
// Create and show the dialog
const dialog = new JoomlaDialog({
popupType: 'iframe',
src: this.url,
textHeader: this.modalTitle,
width: this.modalWidth,
height: this.modalHeight,
popupButtons: [{
label: Joomla.Text._('JSELECT'),
className: 'button button-success btn btn-success',
location: 'header',
onClick: () => {
this.modalClose();
}
}, {
label: '',
ariaLabel: Joomla.Text._('JCLOSE'),
className: 'button-close btn-close',
data: {
buttonClose: '',
dialogClose: ''
},
location: 'header'
}]
});
dialog.classList.add('joomla-dialog-media-field');
dialog.show();
Joomla.Modal.setCurrent(dialog);
dialog.addEventListener('joomla-dialog:close', () => {
Joomla.Modal.setCurrent(null);
dialog.destroy();
this.dialog = null;
Joomla.selectedMediaFile = {};
});
this.dialog = dialog;
}
async modalClose() {
try {
await Joomla.getMedia(Joomla.selectedMediaFile, this.inputElement,
this);
} catch (err) {
Joomla.renderMessages({
error: [Joomla.Text._('JLIB_APPLICATION_ERROR_SERVER')]
});
}
Joomla.selectedMediaFile = {};
this.dialog.close();
}
setValue(value) {
this.inputElement.value = value;
this.validatedUrl = value;
this.mimeType = Joomla.selectedMediaFile.fileType;
this.updatePreview();
// trigger change event both on the input and on the custom element
this.inputElement.dispatchEvent(new Event('change'));
this.dispatchEvent(new CustomEvent('change', {
detail: {
value
},
bubbles: true
}));
}
async validateValue(event) {
let {
value
} = event.target;
if (this.validatedUrl === value || value === '') return;
if (/^(http(s)?:\/\/).+$/.test(value)) {
try {
fetch(value).then(response => {
if (response.status === 200) {
this.validatedUrl = value;
this.markValid();
} else {
this.validatedUrl = value;
this.markInvalid();
}
});
} catch (err) {
this.validatedUrl = value;
this.markInvalid();
}
} else {
if (/^\//.test(value)) {
value = value.substring(1);
}
const hashedUrl = value.split('#');
const urlParts = hashedUrl[0].split('/');
const rest = urlParts.slice(1);
fetch(`${Joomla.getOptions('system.paths').rootFull}/${value}`).then(response
=> response.blob()).then(blob => {
if (blob.type.includes('image')) {
const img = new Image();
img.src = URL.createObjectURL(blob);
img.onload = () => {
this.inputElement.value =
`${urlParts[0]}/${rest.join('/')}#joomlaImage://local-${urlParts[0]}/${rest.join('/')}?width=${img.width}&height=${img.height}`;
this.validatedUrl =
`${urlParts[0]}/${rest.join('/')}#joomlaImage://local-${urlParts[0]}/${rest.join('/')}?width=${img.width}&height=${img.height}`;
this.markValid();
};
} else if (blob.type.includes('audio')) {
this.mimeType = blob.type;
this.inputElement.value = value;
this.validatedUrl = value;
this.markValid();
} else if (blob.type.includes('video')) {
this.mimeType = blob.type;
this.inputElement.value = value;
this.validatedUrl = value;
this.markValid();
} else if (blob.type.includes('application/pdf')) {
this.mimeType = blob.type;
this.inputElement.value = value;
this.validatedUrl = value;
this.markValid();
} else {
this.validatedUrl = value;
this.markInvalid();
}
}).catch(() => {
this.setValue(value);
this.validatedUrl = value;
this.markInvalid();
});
}
}
markValid() {
this.inputElement.removeAttribute('required');
this.inputElement.removeAttribute('pattern');
if (document.formvalidator) {
document.formvalidator.validate(this.inputElement);
}
}
markInvalid() {
this.inputElement.setAttribute('required', '');
this.inputElement.setAttribute('pattern',
'/^(http://INVALID/).+$/');
if (document.formvalidator) {
document.formvalidator.validate(this.inputElement);
}
}
clearValue() {
this.setValue('');
this.validatedUrl = '';
this.inputElement.removeAttribute('required');
this.inputElement.removeAttribute('pattern');
if (document.formvalidator) {
document.formvalidator.validate(this.inputElement);
}
}
updatePreview() {
if (['true', 'static'].indexOf(this.preview) === -1
|| this.preview === 'false' || !this.previewElement) {
return;
}
// Reset preview
if (this.preview) {
const {
value
} = this.inputElement;
const {
supportedExtensions
} = this;
if (!value) {
this.buttonClearEl.style.display = 'none';
this.previewElement.innerHTML = Joomla.sanitizeHtml('<span
class="field-media-preview-icon"></span>');
} else {
let type;
this.buttonClearEl.style.display = '';
this.previewElement.innerHTML = '';
const ext = getExtension(value).toLowerCase();
if (supportedExtensions.images.includes(ext)) type =
'images';
if (supportedExtensions.audios.includes(ext)) type =
'audios';
if (supportedExtensions.videos.includes(ext)) type =
'videos';
if (supportedExtensions.documents.includes(ext)) type =
'documents';
let previewElement;
const mediaType = {
images: () => {
if (supportedExtensions.images.includes(ext)) {
previewElement = new Image();
previewElement.src = /http/.test(value) ? value :
Joomla.getOptions('system.paths').rootFull + value;
previewElement.setAttribute('alt', '');
}
},
audios: () => {
if (supportedExtensions.audios.includes(ext)) {
previewElement = document.createElement('audio');
previewElement.src = /http/.test(value) ? value :
Joomla.getOptions('system.paths').rootFull + value;
previewElement.setAttribute('controls',
'');
}
},
videos: () => {
if (supportedExtensions.videos.includes(ext)) {
previewElement = document.createElement('video');
const previewElementSource =
document.createElement('source');
previewElementSource.src = /http/.test(value) ? value :
Joomla.getOptions('system.paths').rootFull + value;
previewElementSource.type = this.mimeType;
previewElement.setAttribute('controls',
'');
previewElement.setAttribute('width',
this.previewWidth);
previewElement.setAttribute('height',
this.previewHeight);
previewElement.appendChild(previewElementSource);
}
},
documents: () => {
if (supportedExtensions.documents.includes(ext)) {
previewElement = document.createElement('object');
previewElement.data = /http/.test(value) ? value :
Joomla.getOptions('system.paths').rootFull + value;
previewElement.type = this.mimeType;
previewElement.setAttribute('width',
this.previewWidth);
previewElement.setAttribute('height',
this.previewHeight);
}
}
};
// @todo more checks
if (this.givenType && ['images',
'audios', 'videos',
'documents'].includes(this.givenType)) {
mediaType[this.givenType]();
} else if (type && ['images', 'audios',
'videos', 'documents'].includes(type)) {
mediaType[type]();
} else {
return;
}
this.previewElement.style.width = this.previewWidth;
this.previewElement.appendChild(previewElement);
}
}
}
}
customElements.define('joomla-field-media', JoomlaFieldMedia);