Merge pull request #2497 from dpalou/MOBILE-3480

MOBILE-3480 core: Treat SVG images and links in format-text
main
Juan Leyva 2020-09-08 16:24:01 +02:00 committed by GitHub
commit eda8ca1fcf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 32 additions and 34 deletions

View File

@ -47,7 +47,7 @@ export class CoreExternalContentDirective implements AfterViewInit, OnChanges {
@Output() onLoad = new EventEmitter(); // Emitted when content is loaded. Only for images.
loaded = false;
protected element: HTMLElement;
protected element: Element;
protected logger;
protected initialized = false;
@ -62,8 +62,8 @@ export class CoreExternalContentDirective implements AfterViewInit, OnChanges {
protected urlUtils: CoreUrlUtilsProvider,
protected appProvider: CoreAppProvider,
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');
}
@ -120,7 +120,7 @@ export class CoreExternalContentDirective implements AfterViewInit, OnChanges {
protected checkAndHandleExternalContent(): void {
const currentSite = this.sitesProvider.getCurrentSite(),
siteId = this.siteId || (currentSite && currentSite.getId()),
tagName = this.element.tagName;
tagName = this.element.tagName.toUpperCase();
let targetAttr,
url;
@ -129,7 +129,7 @@ export class CoreExternalContentDirective implements AfterViewInit, OnChanges {
this.logger.error('Error treating inline styles.', this.element);
});
if (tagName === 'A') {
if (tagName === 'A' || tagName == 'IMAGE') {
targetAttr = 'href';
url = this.href;

View File

@ -121,16 +121,16 @@ export class CoreFormatTextDirective implements OnChanges {
* @param element Element to add the attributes to.
* @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.
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);
extContent.component = this.component;
extContent.componentId = this.componentId;
extContent.siteId = this.siteId;
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.poster = element.getAttribute('poster');
@ -452,32 +452,27 @@ export class CoreFormatTextDirective implements OnChanges {
const div = document.createElement('div'),
canTreatVimeo = site && site.isVersionGreaterEqualThan(['3.3.4', '3.4']),
navCtrl = this.svComponent ? this.svComponent.getMasterNav() : this.navCtrl;
let images,
anchors,
audios,
videos,
iframes,
buttons,
elementsWithInlineStyles,
stopClicksElements,
frames;
div.innerHTML = formatted;
images = Array.from(div.querySelectorAll('img'));
anchors = Array.from(div.querySelectorAll('a'));
audios = Array.from(div.querySelectorAll('audio'));
videos = Array.from(div.querySelectorAll('video'));
iframes = Array.from(div.querySelectorAll('iframe'));
buttons = Array.from(div.querySelectorAll('.button'));
elementsWithInlineStyles = Array.from(div.querySelectorAll('*[style]'));
stopClicksElements = Array.from(div.querySelectorAll('button,input,select,textarea'));
frames = Array.from(div.querySelectorAll(CoreIframeUtilsProvider.FRAME_TAGS.join(',').replace(/iframe,?/, '')));
const images = Array.from(div.querySelectorAll('img'));
const anchors = Array.from(div.querySelectorAll('a'));
const audios = Array.from(div.querySelectorAll('audio'));
const videos = Array.from(div.querySelectorAll('video'));
const iframes = Array.from(div.querySelectorAll('iframe'));
const buttons = Array.from(div.querySelectorAll('.button'));
const elementsWithInlineStyles = Array.from(div.querySelectorAll('*[style]'));
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.
// Important: We need to look for links first because in 'img' we add new links without core-link.
anchors.forEach((anchor) => {
// 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);
linkDir.capture = true;
linkDir.ngOnInit();
@ -514,6 +509,10 @@ export class CoreFormatTextDirective implements OnChanges {
this.treatIframe(iframe, site, canTreatVimeo, navCtrl);
});
svgImages.forEach((image) => {
this.addExternalContent(image);
});
// Handle buttons with inner links.
buttons.forEach((button: HTMLElement) => {
// Check if it has a link inside.

View File

@ -37,7 +37,7 @@ export class CoreLinkDirective implements OnInit {
// "no" -> Never auto-login.
// "check" -> Auto-login only if it points to the current site. Default value.
protected element: HTMLElement;
protected element: Element;
constructor(element: ElementRef,
protected domUtils: CoreDomUtilsProvider,
@ -50,8 +50,8 @@ export class CoreLinkDirective implements OnInit {
@Optional() protected svComponent: CoreSplitViewComponent,
protected textUtils: CoreTextUtilsProvider,
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) => {
// If the event prevented default action, do nothing.
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') {
event.preventDefault();
event.stopPropagation();

View File

@ -32,8 +32,7 @@ export class CoreUserLinkDirective implements OnInit {
@Optional() private navCtrl: NavController,
@Optional() private svComponent: CoreSplitViewComponent) {
// 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;
}
/**

View File

@ -99,7 +99,7 @@ export class CoreDomUtilsProvider {
* @param selector Selector to search.
* @return Closest ancestor.
*/
closest(element: HTMLElement, selector: string): Element {
closest(element: Element, selector: string): Element {
// Try to use closest if the browser supports it.
if (typeof element.closest == 'function') {
return element.closest(selector);