MOBILE-2364 format-text: Download inline styles files
parent
e6c5607463
commit
c4221f1367
|
@ -20,6 +20,7 @@ import { CoreFilepoolProvider } from '@providers/filepool';
|
||||||
import { CoreSitesProvider } from '@providers/sites';
|
import { CoreSitesProvider } from '@providers/sites';
|
||||||
import { CoreDomUtilsProvider } from '@providers/utils/dom';
|
import { CoreDomUtilsProvider } from '@providers/utils/dom';
|
||||||
import { CoreUrlUtilsProvider } from '@providers/utils/url';
|
import { CoreUrlUtilsProvider } from '@providers/utils/url';
|
||||||
|
import { CoreUtilsProvider } from '@providers/utils/utils';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Directive to handle external content.
|
* Directive to handle external content.
|
||||||
|
@ -28,6 +29,8 @@ import { CoreUrlUtilsProvider } from '@providers/utils/url';
|
||||||
* which we want to have available when the app is offline. Typically media and links.
|
* which we want to have available when the app is offline. Typically media and links.
|
||||||
*
|
*
|
||||||
* If a file is downloaded, its URL will be replaced by the local file URL.
|
* If a file is downloaded, its URL will be replaced by the local file URL.
|
||||||
|
*
|
||||||
|
* From v3.5.2 this directive will also download inline styles, so it can be used in any element as long as it has inline styles.
|
||||||
*/
|
*/
|
||||||
@Directive({
|
@Directive({
|
||||||
selector: '[core-external-content]'
|
selector: '[core-external-content]'
|
||||||
|
@ -42,7 +45,7 @@ export class CoreExternalContentDirective implements AfterViewInit {
|
||||||
|
|
||||||
constructor(element: ElementRef, logger: CoreLoggerProvider, private filepoolProvider: CoreFilepoolProvider,
|
constructor(element: ElementRef, logger: CoreLoggerProvider, private filepoolProvider: CoreFilepoolProvider,
|
||||||
private platform: Platform, private sitesProvider: CoreSitesProvider, private domUtils: CoreDomUtilsProvider,
|
private platform: Platform, private sitesProvider: CoreSitesProvider, private domUtils: CoreDomUtilsProvider,
|
||||||
private urlUtils: CoreUrlUtilsProvider, private appProvider: CoreAppProvider) {
|
private urlUtils: CoreUrlUtilsProvider, private appProvider: CoreAppProvider, private utils: CoreUtilsProvider) {
|
||||||
// This directive can be added dynamically. In that case, the first param is the HTMLElement.
|
// This directive can be added dynamically. In that case, the first param is the HTMLElement.
|
||||||
this.element = element.nativeElement || element;
|
this.element = element.nativeElement || element;
|
||||||
this.logger = logger.getInstance('CoreExternalContentDirective');
|
this.logger = logger.getInstance('CoreExternalContentDirective');
|
||||||
|
@ -58,6 +61,11 @@ export class CoreExternalContentDirective implements AfterViewInit {
|
||||||
let targetAttr,
|
let targetAttr,
|
||||||
sourceAttr;
|
sourceAttr;
|
||||||
|
|
||||||
|
// Always handle inline styles (if any).
|
||||||
|
this.handleInlineStyles(siteId).catch((error) => {
|
||||||
|
this.logger.error('Error treating inline styles.', this.element);
|
||||||
|
});
|
||||||
|
|
||||||
if (tagName === 'A') {
|
if (tagName === 'A') {
|
||||||
targetAttr = 'href';
|
targetAttr = 'href';
|
||||||
sourceAttr = 'href';
|
sourceAttr = 'href';
|
||||||
|
@ -81,9 +89,6 @@ export class CoreExternalContentDirective implements AfterViewInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Unsupported tag.
|
|
||||||
this.logger.warn('Directive attached to non-supported tag: ' + tagName);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,4 +222,39 @@ export class CoreExternalContentDirective implements AfterViewInit {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle inline styles, trying to download referenced files.
|
||||||
|
*
|
||||||
|
* @param {string} siteId Site ID.
|
||||||
|
* @return {Promise<any>} Promise resolved if the element is successfully treated.
|
||||||
|
*/
|
||||||
|
protected handleInlineStyles(siteId: string): Promise<any> {
|
||||||
|
let inlineStyles = this.element.getAttribute('style');
|
||||||
|
|
||||||
|
if (!inlineStyles) {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
let urls = inlineStyles.match(/https?:\/\/[^"'\) ;]*/g);
|
||||||
|
if (!urls || !urls.length) {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
const promises = [];
|
||||||
|
urls = this.utils.uniqueArray(urls); // Remove duplicates.
|
||||||
|
|
||||||
|
urls.forEach((url) => {
|
||||||
|
promises.push(this.filepoolProvider.getUrlByUrl(siteId, url, this.component, this.componentId, 0, true, true)
|
||||||
|
.then((finalUrl) => {
|
||||||
|
|
||||||
|
this.logger.debug('Using URL ' + finalUrl + ' for ' + url + ' in inline styles');
|
||||||
|
inlineStyles = inlineStyles.replace(new RegExp(url, 'gi'), finalUrl);
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
return this.utils.allPromises(promises).then(() => {
|
||||||
|
this.element.setAttribute('style', inlineStyles);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,7 +87,7 @@ export class CoreFormatTextDirective implements OnChanges {
|
||||||
protected addExternalContent(element: HTMLElement): void {
|
protected addExternalContent(element: HTMLElement): void {
|
||||||
// Angular 2 doesn't let adding directives dynamically. Create the CoreExternalContentDirective manually.
|
// Angular 2 doesn't let adding directives dynamically. Create the CoreExternalContentDirective manually.
|
||||||
const extContent = new CoreExternalContentDirective(<any> element, this.loggerProvider, this.filepoolProvider,
|
const extContent = new CoreExternalContentDirective(<any> element, this.loggerProvider, this.filepoolProvider,
|
||||||
this.platform, this.sitesProvider, this.domUtils, this.urlUtils, this.appProvider);
|
this.platform, this.sitesProvider, this.domUtils, this.urlUtils, this.appProvider, this.utils);
|
||||||
|
|
||||||
extContent.component = this.component;
|
extContent.component = this.component;
|
||||||
extContent.componentId = this.componentId;
|
extContent.componentId = this.componentId;
|
||||||
|
@ -313,7 +313,8 @@ export class CoreFormatTextDirective implements OnChanges {
|
||||||
audios,
|
audios,
|
||||||
videos,
|
videos,
|
||||||
iframes,
|
iframes,
|
||||||
buttons;
|
buttons,
|
||||||
|
elementsWithInlineStyles;
|
||||||
|
|
||||||
div.innerHTML = formatted;
|
div.innerHTML = formatted;
|
||||||
images = Array.from(div.querySelectorAll('img'));
|
images = Array.from(div.querySelectorAll('img'));
|
||||||
|
@ -322,6 +323,7 @@ export class CoreFormatTextDirective implements OnChanges {
|
||||||
videos = Array.from(div.querySelectorAll('video'));
|
videos = Array.from(div.querySelectorAll('video'));
|
||||||
iframes = Array.from(div.querySelectorAll('iframe'));
|
iframes = Array.from(div.querySelectorAll('iframe'));
|
||||||
buttons = Array.from(div.querySelectorAll('.button'));
|
buttons = Array.from(div.querySelectorAll('.button'));
|
||||||
|
elementsWithInlineStyles = Array.from(div.querySelectorAll('*[style]'));
|
||||||
|
|
||||||
// Walk through the content to find the links and add our directive to it.
|
// Walk through the content to find the links and add our directive to it.
|
||||||
// Important: We need to look for links first because in 'img' we add new links without core-link.
|
// Important: We need to look for links first because in 'img' we add new links without core-link.
|
||||||
|
@ -370,6 +372,15 @@ export class CoreFormatTextDirective implements OnChanges {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Handle inline styles.
|
||||||
|
elementsWithInlineStyles.forEach((el: HTMLElement) => {
|
||||||
|
// Only add external content for tags that haven't been treated already.
|
||||||
|
if (el.tagName != 'A' && el.tagName != 'IMG' && el.tagName != 'AUDIO' && el.tagName != 'VIDEO'
|
||||||
|
&& el.tagName != 'SOURCE' && el.tagName != 'TRACK') {
|
||||||
|
this.addExternalContent(el);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return div;
|
return div;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue