MOBILE-4015 core: Support data-app-url attribute
parent
0143c23395
commit
910d557b87
|
@ -13,6 +13,7 @@
|
|||
// limitations under the License.
|
||||
|
||||
import { Directive, ElementRef, OnInit, Output, EventEmitter } from '@angular/core';
|
||||
import { CoreDom } from '@singletons/dom';
|
||||
|
||||
/**
|
||||
* Directive to emulate click and key actions following aria role button.
|
||||
|
@ -36,22 +37,7 @@ export class CoreAriaButtonClickDirective implements OnInit {
|
|||
* Initialize actions.
|
||||
*/
|
||||
ngOnInit(): void {
|
||||
this.element.addEventListener('click', async (event) => {
|
||||
this.ariaButtonClick.emit(event);
|
||||
});
|
||||
|
||||
this.element.addEventListener('keydown', async (event) => {
|
||||
if ((event.key == ' ' || event.key == 'Enter')) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}
|
||||
});
|
||||
|
||||
this.element.addEventListener('keyup', async (event) => {
|
||||
if ((event.key == ' ' || event.key == 'Enter')) {
|
||||
this.ariaButtonClick.emit(event);
|
||||
}
|
||||
});
|
||||
CoreDom.onActivate(this.element, (event) => this.ariaButtonClick.emit(event));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -452,9 +452,16 @@ export class CoreFormatTextDirective implements OnChanges, OnDestroy, AsyncCompo
|
|||
const svgImages = Array.from(div.querySelectorAll('image'));
|
||||
const promises: Promise<void>[] = [];
|
||||
|
||||
this.treatAppUrlElements(div, site);
|
||||
|
||||
// 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) => {
|
||||
if (anchor.getAttribute('data-app-url')) {
|
||||
// Link already treated in data-app-url, ignore it.
|
||||
return;
|
||||
}
|
||||
|
||||
// Angular 2 doesn't let adding directives dynamically. Create the CoreLinkDirective manually.
|
||||
const linkDir = new CoreLinkDirective(new ElementRef(anchor), this.content);
|
||||
linkDir.capture = this.captureLinks ?? true;
|
||||
|
@ -546,6 +553,57 @@ export class CoreFormatTextDirective implements OnChanges, OnDestroy, AsyncCompo
|
|||
await Promise.all(promises);
|
||||
}
|
||||
|
||||
/**
|
||||
* Treat elements with an app-url data attribute.
|
||||
*
|
||||
* @param div Div containing the elements.
|
||||
* @param site Site.
|
||||
*/
|
||||
protected treatAppUrlElements(div: HTMLElement, site?: CoreSite): void {
|
||||
const appUrlElements = Array.from(div.querySelectorAll<HTMLElement>('*[data-app-url]'));
|
||||
|
||||
appUrlElements.forEach((element) => {
|
||||
const url = element.getAttribute('data-app-url');
|
||||
if (!url) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (element.tagName !== 'BUTTON' && element.tagName !== 'A') {
|
||||
element.setAttribute('tabindex', '0');
|
||||
element.setAttribute('role', 'button');
|
||||
}
|
||||
|
||||
CoreDom.onActivate(element, async (event) => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
site = site || CoreSites.getCurrentSite();
|
||||
if (!site) {
|
||||
return;
|
||||
}
|
||||
|
||||
const confirmMessage = element.getAttribute('data-app-url-confirm');
|
||||
const openInApp = element.getAttribute('data-open-in') === 'app';
|
||||
|
||||
if (confirmMessage) {
|
||||
try {
|
||||
await CoreDomUtils.showConfirm(Translate.instant(confirmMessage));
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (openInApp) {
|
||||
site.openInAppWithAutoLoginIfSameSite(url);
|
||||
} else {
|
||||
site.openInBrowserWithAutoLoginIfSameSite(url, undefined, {
|
||||
showBrowserWarning: !confirmMessage,
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the element width in pixels.
|
||||
*
|
||||
|
|
|
@ -48,7 +48,7 @@ export class CoreLinkDirective implements OnInit {
|
|||
@Input() autoLogin = 'check';
|
||||
@Input() showBrowserWarning = true; // Whether to show a warning before opening browser. Defaults to true.
|
||||
|
||||
protected element: Element;
|
||||
protected element: HTMLElement;
|
||||
|
||||
constructor(
|
||||
element: ElementRef,
|
||||
|
@ -68,22 +68,7 @@ export class CoreLinkDirective implements OnInit {
|
|||
this.element.setAttribute('role', 'button');
|
||||
}
|
||||
|
||||
this.element.addEventListener('click', async (event) => {
|
||||
this.performAction(event);
|
||||
});
|
||||
|
||||
this.element.addEventListener('keydown', (event: KeyboardEvent) => {
|
||||
if ((event.key == ' ' || event.key == 'Enter')) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}
|
||||
});
|
||||
|
||||
this.element.addEventListener('keyup', (event: KeyboardEvent) => {
|
||||
if ((event.key == ' ' || event.key == 'Enter')) {
|
||||
this.performAction(event);
|
||||
}
|
||||
});
|
||||
CoreDom.onActivate(this.element, (event) => this.performAction(event));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -481,6 +481,29 @@ export class CoreDom {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Listen to click and Enter/Space keys in an element.
|
||||
*
|
||||
* @param element Element to listen to events.
|
||||
* @param callback Callback to call when clicked or the key is pressed.
|
||||
*/
|
||||
static onActivate(element: HTMLElement, callback: (event: MouseEvent | KeyboardEvent) => void): void {
|
||||
element.addEventListener('click', (event) => callback(event));
|
||||
|
||||
element.addEventListener('keydown', (event) => {
|
||||
if ((event.key == ' ' || event.key == 'Enter')) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}
|
||||
});
|
||||
|
||||
element.addEventListener('keyup', (event) => {
|
||||
if ((event.key == ' ' || event.key == 'Enter')) {
|
||||
callback(event);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue