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 { CoreDomUtilsProvider } from '@providers/utils/dom';
|
||||
import { CoreUrlUtilsProvider } from '@providers/utils/url';
|
||||
import { CoreUtilsProvider } from '@providers/utils/utils';
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* 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({
|
||||
selector: '[core-external-content]'
|
||||
|
@ -42,7 +45,7 @@ export class CoreExternalContentDirective implements AfterViewInit {
|
|||
|
||||
constructor(element: ElementRef, logger: CoreLoggerProvider, private filepoolProvider: CoreFilepoolProvider,
|
||||
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.element = element.nativeElement || element;
|
||||
this.logger = logger.getInstance('CoreExternalContentDirective');
|
||||
|
@ -58,6 +61,11 @@ export class CoreExternalContentDirective implements AfterViewInit {
|
|||
let targetAttr,
|
||||
sourceAttr;
|
||||
|
||||
// Always handle inline styles (if any).
|
||||
this.handleInlineStyles(siteId).catch((error) => {
|
||||
this.logger.error('Error treating inline styles.', this.element);
|
||||
});
|
||||
|
||||
if (tagName === 'A') {
|
||||
targetAttr = 'href';
|
||||
sourceAttr = 'href';
|
||||
|
@ -81,9 +89,6 @@ export class CoreExternalContentDirective implements AfterViewInit {
|
|||
}
|
||||
|
||||
} else {
|
||||
// Unsupported tag.
|
||||
this.logger.warn('Directive attached to non-supported tag: ' + tagName);
|
||||
|
||||
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 {
|
||||
// Angular 2 doesn't let adding directives dynamically. Create the CoreExternalContentDirective manually.
|
||||
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.componentId = this.componentId;
|
||||
|
@ -313,7 +313,8 @@ export class CoreFormatTextDirective implements OnChanges {
|
|||
audios,
|
||||
videos,
|
||||
iframes,
|
||||
buttons;
|
||||
buttons,
|
||||
elementsWithInlineStyles;
|
||||
|
||||
div.innerHTML = formatted;
|
||||
images = Array.from(div.querySelectorAll('img'));
|
||||
|
@ -322,6 +323,7 @@ export class CoreFormatTextDirective implements OnChanges {
|
|||
videos = Array.from(div.querySelectorAll('video'));
|
||||
iframes = Array.from(div.querySelectorAll('iframe'));
|
||||
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.
|
||||
// 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;
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue