Skip to content
95 changes: 95 additions & 0 deletions build/media_source/system/js/fields/joomla-field-media.w-c.es6.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ class JoomlaFieldMedia extends HTMLElement {
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);
}

static get observedAttributes() {
Expand Down Expand Up @@ -130,6 +133,8 @@ class JoomlaFieldMedia extends HTMLElement {
}

this.updatePreview();
this.inputElement.removeAttribute('readonly');
this.inputElement.addEventListener('change', this.validateValue);
}

disconnectedCallback() {
Expand All @@ -139,6 +144,9 @@ class JoomlaFieldMedia extends HTMLElement {
if (this.buttonClearEl) {
this.buttonClearEl.removeEventListener('click', this.clearValue);
}
if (this.inputElement) {
this.inputElement.removeEventListener('change', this.validateValue);
}
}

onSelected(event) {
Expand Down Expand Up @@ -172,6 +180,7 @@ class JoomlaFieldMedia extends HTMLElement {

setValue(value) {
this.inputElement.value = value;
this.validatedUrl = value;
this.updatePreview();

// trigger change event both on the input and on the custom element
Expand All @@ -182,8 +191,94 @@ class JoomlaFieldMedia extends HTMLElement {
}));
}

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.inputElement.value = value;
this.validatedUrl = value;
this.markValid();
} else if (blob.type.includes('video')) {
this.inputElement.value = value;
this.validatedUrl = value;
this.markValid();
} else if (blob.type.includes('application/pdf')) {
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() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,8 +197,8 @@ const insertAsImage = async (media, editor, fieldClass) => {
Joomla.selectedMediaFile.width = 0;
}
}
editor.value = `${Joomla.selectedMediaFile.url}#joomlaImage://${media.path.replace(':', '')}?width=${Joomla.selectedMediaFile.width}&height=${Joomla.selectedMediaFile.height}`;
fieldClass.updatePreview();
fieldClass.markValid();
fieldClass.setValue(`${Joomla.selectedMediaFile.url}#joomlaImage://${media.path.replace(':', '')}?width=${Joomla.selectedMediaFile.width}&height=${Joomla.selectedMediaFile.height}`);
}
}
};
Expand Down Expand Up @@ -256,9 +256,9 @@ const insertAsOther = (media, editor, fieldClass, type) => {

Joomla.editors.instances[editor].replaceSelection(outputText);
} else {
editor.value = Joomla.selectedMediaFile.url;
fieldClass.markValid();
fieldClass.givenType = type;
fieldClass.updatePreview();
fieldClass.setValue(Joomla.selectedMediaFile.url);
}
}
};
Expand Down
2 changes: 1 addition & 1 deletion layouts/joomla/form/field/media.php
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@
</div>
<?php endif; ?>
<div class="input-group">
<input type="text" name="<?php echo $name; ?>" id="<?php echo $id; ?>" value="<?php echo htmlspecialchars($value, ENT_COMPAT, 'UTF-8'); ?>" readonly="readonly" <?php echo $attr; ?>>
<input type="text" name="<?php echo $name; ?>" id="<?php echo $id; ?>" value="<?php echo htmlspecialchars($value, ENT_COMPAT, 'UTF-8'); ?>" <?php echo $attr; ?>>
<?php if ($disabled != true) : ?>
<button type="button" class="btn btn-success button-select"><?php echo Text::_('JLIB_FORM_BUTTON_SELECT'); ?></button>
<button type="button" class="btn btn-danger button-clear"><span class="icon-times" aria-hidden="true"></span><span class="visually-hidden"><?php echo Text::_('JLIB_FORM_BUTTON_CLEAR'); ?></span></button>
Expand Down