MOBILE-3480 core: Treat SVG images and links in format-text
parent
b67ea14abb
commit
767e8ab38f
|
@ -47,7 +47,7 @@ export class CoreExternalContentDirective implements AfterViewInit, OnChanges {
|
||||||
@Output() onLoad = new EventEmitter(); // Emitted when content is loaded. Only for images.
|
@Output() onLoad = new EventEmitter(); // Emitted when content is loaded. Only for images.
|
||||||
|
|
||||||
loaded = false;
|
loaded = false;
|
||||||
protected element: HTMLElement;
|
protected element: Element;
|
||||||
protected logger;
|
protected logger;
|
||||||
protected initialized = false;
|
protected initialized = false;
|
||||||
|
|
||||||
|
@ -62,8 +62,8 @@ export class CoreExternalContentDirective implements AfterViewInit, OnChanges {
|
||||||
protected urlUtils: CoreUrlUtilsProvider,
|
protected urlUtils: CoreUrlUtilsProvider,
|
||||||
protected appProvider: CoreAppProvider,
|
protected appProvider: CoreAppProvider,
|
||||||
protected utils: CoreUtilsProvider) {
|
protected utils: CoreUtilsProvider) {
|
||||||
// This directive can be added dynamically. In that case, the first param is the HTMLElement.
|
|
||||||
this.element = element.nativeElement || element;
|
this.element = element.nativeElement;
|
||||||
this.logger = logger.getInstance('CoreExternalContentDirective');
|
this.logger = logger.getInstance('CoreExternalContentDirective');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,7 +120,7 @@ export class CoreExternalContentDirective implements AfterViewInit, OnChanges {
|
||||||
protected checkAndHandleExternalContent(): void {
|
protected checkAndHandleExternalContent(): void {
|
||||||
const currentSite = this.sitesProvider.getCurrentSite(),
|
const currentSite = this.sitesProvider.getCurrentSite(),
|
||||||
siteId = this.siteId || (currentSite && currentSite.getId()),
|
siteId = this.siteId || (currentSite && currentSite.getId()),
|
||||||
tagName = this.element.tagName;
|
tagName = this.element.tagName.toUpperCase();
|
||||||
let targetAttr,
|
let targetAttr,
|
||||||
url;
|
url;
|
||||||
|
|
||||||
|
@ -129,7 +129,7 @@ export class CoreExternalContentDirective implements AfterViewInit, OnChanges {
|
||||||
this.logger.error('Error treating inline styles.', this.element);
|
this.logger.error('Error treating inline styles.', this.element);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (tagName === 'A') {
|
if (tagName === 'A' || tagName == 'IMAGE') {
|
||||||
targetAttr = 'href';
|
targetAttr = 'href';
|
||||||
url = this.href;
|
url = this.href;
|
||||||
|
|
||||||
|
|
|
@ -121,16 +121,16 @@ export class CoreFormatTextDirective implements OnChanges {
|
||||||
* @param element Element to add the attributes to.
|
* @param element Element to add the attributes to.
|
||||||
* @return External content instance.
|
* @return External content instance.
|
||||||
*/
|
*/
|
||||||
protected addExternalContent(element: HTMLElement): CoreExternalContentDirective {
|
protected addExternalContent(element: Element): CoreExternalContentDirective {
|
||||||
// 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(new ElementRef(element), this.loggerProvider, this.filepoolProvider,
|
||||||
this.platform, this.sitesProvider, this.domUtils, this.urlUtils, this.appProvider, this.utils);
|
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;
|
||||||
extContent.siteId = this.siteId;
|
extContent.siteId = this.siteId;
|
||||||
extContent.src = element.getAttribute('src');
|
extContent.src = element.getAttribute('src');
|
||||||
extContent.href = element.getAttribute('href');
|
extContent.href = element.getAttribute('href') || element.getAttribute('xlink:href');
|
||||||
extContent.targetSrc = element.getAttribute('target-src');
|
extContent.targetSrc = element.getAttribute('target-src');
|
||||||
extContent.poster = element.getAttribute('poster');
|
extContent.poster = element.getAttribute('poster');
|
||||||
|
|
||||||
|
@ -452,32 +452,27 @@ export class CoreFormatTextDirective implements OnChanges {
|
||||||
const div = document.createElement('div'),
|
const div = document.createElement('div'),
|
||||||
canTreatVimeo = site && site.isVersionGreaterEqualThan(['3.3.4', '3.4']),
|
canTreatVimeo = site && site.isVersionGreaterEqualThan(['3.3.4', '3.4']),
|
||||||
navCtrl = this.svComponent ? this.svComponent.getMasterNav() : this.navCtrl;
|
navCtrl = this.svComponent ? this.svComponent.getMasterNav() : this.navCtrl;
|
||||||
let images,
|
|
||||||
anchors,
|
|
||||||
audios,
|
|
||||||
videos,
|
|
||||||
iframes,
|
|
||||||
buttons,
|
|
||||||
elementsWithInlineStyles,
|
|
||||||
stopClicksElements,
|
|
||||||
frames;
|
|
||||||
|
|
||||||
div.innerHTML = formatted;
|
div.innerHTML = formatted;
|
||||||
images = Array.from(div.querySelectorAll('img'));
|
|
||||||
anchors = Array.from(div.querySelectorAll('a'));
|
const images = Array.from(div.querySelectorAll('img'));
|
||||||
audios = Array.from(div.querySelectorAll('audio'));
|
const anchors = Array.from(div.querySelectorAll('a'));
|
||||||
videos = Array.from(div.querySelectorAll('video'));
|
const audios = Array.from(div.querySelectorAll('audio'));
|
||||||
iframes = Array.from(div.querySelectorAll('iframe'));
|
const videos = Array.from(div.querySelectorAll('video'));
|
||||||
buttons = Array.from(div.querySelectorAll('.button'));
|
const iframes = Array.from(div.querySelectorAll('iframe'));
|
||||||
elementsWithInlineStyles = Array.from(div.querySelectorAll('*[style]'));
|
const buttons = Array.from(div.querySelectorAll('.button'));
|
||||||
stopClicksElements = Array.from(div.querySelectorAll('button,input,select,textarea'));
|
const elementsWithInlineStyles = Array.from(div.querySelectorAll('*[style]'));
|
||||||
frames = Array.from(div.querySelectorAll(CoreIframeUtilsProvider.FRAME_TAGS.join(',').replace(/iframe,?/, '')));
|
const stopClicksElements = Array.from(div.querySelectorAll('button,input,select,textarea'));
|
||||||
|
const frames = Array.from(div.querySelectorAll(CoreIframeUtilsProvider.FRAME_TAGS.join(',').replace(/iframe,?/, '')));
|
||||||
|
const svgImages = Array.from(div.querySelectorAll('image'));
|
||||||
|
|
||||||
// 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.
|
||||||
anchors.forEach((anchor) => {
|
anchors.forEach((anchor) => {
|
||||||
// Angular 2 doesn't let adding directives dynamically. Create the CoreLinkDirective manually.
|
// Angular 2 doesn't let adding directives dynamically. Create the CoreLinkDirective manually.
|
||||||
const linkDir = new CoreLinkDirective(anchor, this.domUtils, this.utils, this.sitesProvider, this.urlUtils,
|
const elementRef = new ElementRef(anchor);
|
||||||
|
|
||||||
|
const linkDir = new CoreLinkDirective(elementRef, this.domUtils, this.utils, this.sitesProvider, this.urlUtils,
|
||||||
this.contentLinksHelper, this.navCtrl, this.content, this.svComponent, this.textUtils, this.urlSchemesProvider);
|
this.contentLinksHelper, this.navCtrl, this.content, this.svComponent, this.textUtils, this.urlSchemesProvider);
|
||||||
linkDir.capture = true;
|
linkDir.capture = true;
|
||||||
linkDir.ngOnInit();
|
linkDir.ngOnInit();
|
||||||
|
@ -514,6 +509,10 @@ export class CoreFormatTextDirective implements OnChanges {
|
||||||
this.treatIframe(iframe, site, canTreatVimeo, navCtrl);
|
this.treatIframe(iframe, site, canTreatVimeo, navCtrl);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
svgImages.forEach((image) => {
|
||||||
|
this.addExternalContent(image);
|
||||||
|
});
|
||||||
|
|
||||||
// Handle buttons with inner links.
|
// Handle buttons with inner links.
|
||||||
buttons.forEach((button: HTMLElement) => {
|
buttons.forEach((button: HTMLElement) => {
|
||||||
// Check if it has a link inside.
|
// Check if it has a link inside.
|
||||||
|
|
|
@ -37,7 +37,7 @@ export class CoreLinkDirective implements OnInit {
|
||||||
// "no" -> Never auto-login.
|
// "no" -> Never auto-login.
|
||||||
// "check" -> Auto-login only if it points to the current site. Default value.
|
// "check" -> Auto-login only if it points to the current site. Default value.
|
||||||
|
|
||||||
protected element: HTMLElement;
|
protected element: Element;
|
||||||
|
|
||||||
constructor(element: ElementRef,
|
constructor(element: ElementRef,
|
||||||
protected domUtils: CoreDomUtilsProvider,
|
protected domUtils: CoreDomUtilsProvider,
|
||||||
|
@ -50,8 +50,8 @@ export class CoreLinkDirective implements OnInit {
|
||||||
@Optional() protected svComponent: CoreSplitViewComponent,
|
@Optional() protected svComponent: CoreSplitViewComponent,
|
||||||
protected textUtils: CoreTextUtilsProvider,
|
protected textUtils: CoreTextUtilsProvider,
|
||||||
protected urlSchemesProvider: CoreCustomURLSchemesProvider) {
|
protected urlSchemesProvider: CoreCustomURLSchemesProvider) {
|
||||||
// This directive can be added dynamically. In that case, the first param is the anchor HTMLElement.
|
|
||||||
this.element = element.nativeElement || element;
|
this.element = element.nativeElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -70,7 +70,7 @@ export class CoreLinkDirective implements OnInit {
|
||||||
this.element.addEventListener('click', (event) => {
|
this.element.addEventListener('click', (event) => {
|
||||||
// If the event prevented default action, do nothing.
|
// If the event prevented default action, do nothing.
|
||||||
if (!event.defaultPrevented) {
|
if (!event.defaultPrevented) {
|
||||||
let href = this.element.getAttribute('href');
|
let href = this.element.getAttribute('href') || this.element.getAttribute('xlink:href');
|
||||||
if (href && this.urlUtils.getUrlScheme(href) != 'javascript') {
|
if (href && this.urlUtils.getUrlScheme(href) != 'javascript') {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
|
@ -32,8 +32,7 @@ export class CoreUserLinkDirective implements OnInit {
|
||||||
@Optional() private navCtrl: NavController,
|
@Optional() private navCtrl: NavController,
|
||||||
@Optional() private svComponent: CoreSplitViewComponent) {
|
@Optional() private svComponent: CoreSplitViewComponent) {
|
||||||
|
|
||||||
// This directive can be added dynamically. In that case, the first param is the anchor HTMLElement.
|
this.element = element.nativeElement;
|
||||||
this.element = element.nativeElement || element;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -99,7 +99,7 @@ export class CoreDomUtilsProvider {
|
||||||
* @param selector Selector to search.
|
* @param selector Selector to search.
|
||||||
* @return Closest ancestor.
|
* @return Closest ancestor.
|
||||||
*/
|
*/
|
||||||
closest(element: HTMLElement, selector: string): Element {
|
closest(element: Element, selector: string): Element {
|
||||||
// Try to use closest if the browser supports it.
|
// Try to use closest if the browser supports it.
|
||||||
if (typeof element.closest == 'function') {
|
if (typeof element.closest == 'function') {
|
||||||
return element.closest(selector);
|
return element.closest(selector);
|
||||||
|
|
Loading…
Reference in New Issue