MOBILE-2651 rte: Don't leak treated URLs to textarea and form control

main
Albert Gasset 2018-10-04 12:15:30 +02:00
parent e0a53d4a08
commit ac2c7f7677
1 changed files with 29 additions and 3 deletions

View File

@ -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();
} }
} }