MOBILE-2651 rte: Don't leak treated URLs to textarea and form control
parent
e0a53d4a08
commit
ac2c7f7677
|
@ -106,8 +106,6 @@ export class CoreRichTextEditorComponent implements AfterContentInit, OnDestroy
|
||||||
// Use paragraph on enter.
|
// Use paragraph on enter.
|
||||||
document.execCommand('DefaultParagraphSeparator', false, 'p');
|
document.execCommand('DefaultParagraphSeparator', false, 'p');
|
||||||
|
|
||||||
this.treatExternalContent();
|
|
||||||
|
|
||||||
this.resizeFunction = this.maximizeEditorSize.bind(this);
|
this.resizeFunction = this.maximizeEditorSize.bind(this);
|
||||||
window.addEventListener('resize', this.resizeFunction);
|
window.addEventListener('resize', this.resizeFunction);
|
||||||
|
|
||||||
|
@ -223,10 +221,14 @@ export class CoreRichTextEditorComponent implements AfterContentInit, OnDestroy
|
||||||
if (this.isNullOrWhiteSpace(this.editorElement.innerText)) {
|
if (this.isNullOrWhiteSpace(this.editorElement.innerText)) {
|
||||||
this.clearText();
|
this.clearText();
|
||||||
} else {
|
} else {
|
||||||
|
// The textarea and the form control must receive the original URLs.
|
||||||
|
this.restoreExternalContent();
|
||||||
// Don't emit event so our valueChanges doesn't get notified by this change.
|
// Don't emit event so our valueChanges doesn't get notified by this change.
|
||||||
this.control.setValue(this.editorElement.innerHTML, {emitEvent: false});
|
this.control.setValue(this.editorElement.innerHTML, {emitEvent: false});
|
||||||
this.control.markAsDirty();
|
this.control.markAsDirty();
|
||||||
this.textarea.value = this.editorElement.innerHTML;
|
this.textarea.value = this.editorElement.innerHTML;
|
||||||
|
// Treat URLs again for the editor.
|
||||||
|
this.treatExternalContent();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (this.isNullOrWhiteSpace(this.textarea.value)) {
|
if (this.isNullOrWhiteSpace(this.textarea.value)) {
|
||||||
|
@ -405,6 +407,11 @@ export class CoreRichTextEditorComponent implements AfterContentInit, OnDestroy
|
||||||
siteId = this.sitesProvider.getCurrentSiteId(),
|
siteId = this.sitesProvider.getCurrentSiteId(),
|
||||||
canDownloadFiles = this.sitesProvider.getCurrentSite().canDownloadFiles();
|
canDownloadFiles = this.sitesProvider.getCurrentSite().canDownloadFiles();
|
||||||
elements.forEach((el) => {
|
elements.forEach((el) => {
|
||||||
|
if (el.getAttribute('data-original-src')) {
|
||||||
|
// Already treated.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const url = el.src;
|
const url = el.src;
|
||||||
|
|
||||||
if (!url || !this.urlUtils.isDownloadableUrl(url) || (!canDownloadFiles && this.urlUtils.isPluginFileUrl(url))) {
|
if (!url || !this.urlUtils.isDownloadableUrl(url) || (!canDownloadFiles && this.urlUtils.isPluginFileUrl(url))) {
|
||||||
|
@ -414,11 +421,29 @@ export class CoreRichTextEditorComponent implements AfterContentInit, OnDestroy
|
||||||
|
|
||||||
// Check if it's downloaded.
|
// Check if it's downloaded.
|
||||||
return this.filepoolProvider.getSrcByUrl(siteId, url, this.component, this.componentId).then((finalUrl) => {
|
return this.filepoolProvider.getSrcByUrl(siteId, url, this.component, this.componentId).then((finalUrl) => {
|
||||||
|
// Check again if it's already treated, this function can be called concurrently more than once.
|
||||||
|
if (!el.getAttribute('data-original-src')) {
|
||||||
|
el.setAttribute('data-original-src', el.src);
|
||||||
el.setAttribute('src', finalUrl);
|
el.setAttribute('src', finalUrl);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverts changes made by treatExternalContent.
|
||||||
|
*/
|
||||||
|
protected restoreExternalContent(): void {
|
||||||
|
const elements = Array.from(this.editorElement.querySelectorAll('img'));
|
||||||
|
elements.forEach((el) => {
|
||||||
|
const originalUrl = el.getAttribute('data-original-src');
|
||||||
|
if (originalUrl) {
|
||||||
|
el.setAttribute('src', originalUrl);
|
||||||
|
el.removeAttribute('data-original-src');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if text is empty.
|
* Check if text is empty.
|
||||||
* @param {string} value text
|
* @param {string} value text
|
||||||
|
@ -446,6 +471,7 @@ export class CoreRichTextEditorComponent implements AfterContentInit, OnDestroy
|
||||||
} else {
|
} else {
|
||||||
this.editorElement.innerHTML = value;
|
this.editorElement.innerHTML = value;
|
||||||
this.textarea.value = value;
|
this.textarea.value = value;
|
||||||
|
this.treatExternalContent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue