import { NavigationDelegate } from './NavigationDelegate.js';
/**
* Browser navigation delegate interacting with window, location, document.title,
* and hashchange/click events.
* @augments NavigationDelegate
*/
export class BrowserNavigationDelegate extends NavigationDelegate {
/**
* Creates an instance of BrowserNavigationDelegate.
*/
constructor() {
super();
this.hashListeners = new Set();
this.linkClickListeners = new Set();
this.onWindowHashChange = () => {
for (const listener of this.hashListeners) {
listener(this.getHash());
}
};
this.onWindowClick = (e) => {
if (typeof window === 'undefined' || !e || !e.target || typeof e.target.closest !== 'function') {
return;
}
const target = e.target.closest('[data-ax-link]');
if (target) {
e.preventDefault();
const route = target.getAttribute('data-ax-link');
if (route) {
for (const listener of this.linkClickListeners) {
listener(route);
}
}
}
};
if (typeof window !== 'undefined') {
window.addEventListener('hashchange', this.onWindowHashChange);
window.addEventListener('click', this.onWindowClick);
if (!window.__avenx_routers) {
window.__avenx_routers = new Set();
}
}
}
/** @override */
getHash() {
if (typeof window !== 'undefined' && window.location) {
return window.location.hash || '#/';
}
return '#/';
}
/** @override */
setHash(hash, options = {}) {
if (typeof window !== 'undefined' && window.location) {
// window.location.hash = hash;
if (options.replace) {
window.location.replace(hash);
} else {
window.location.hash = hash;
}
}
}
/** @override */
back() {
if (typeof window !== 'undefined' && window.history && typeof window.history.back === 'function') {
window.history.back();
}
}
/** @override */
forward() {
if (typeof window !== 'undefined' && window.history && typeof window.history.forward === 'function') {
window.history.forward();
}
}
/** @override */
go(delta) {
if (typeof window !== 'undefined' && window.history && typeof window.history.go === 'function') {
window.history.go(delta);
}
}
/** @override */
onHashChange(callback) {
this.hashListeners.add(callback);
return () => this.hashListeners.delete(callback);
}
/** @override */
onLinkClick(callback) {
this.linkClickListeners.add(callback);
return () => this.linkClickListeners.delete(callback);
}
/** @override */
setTitle(title) {
if (typeof document !== 'undefined') {
document.title = title;
}
}
/** @override */
registerRouter(router) {
if (typeof window !== 'undefined') {
if (!window.__avenx_routers) {
window.__avenx_routers = new Set();
}
window.__avenx_routers.add(router);
}
}
/** @override */
unregisterRouter(router) {
if (typeof window !== 'undefined' && window.__avenx_routers) {
window.__avenx_routers.delete(router);
}
}
/** @override */
getActiveRouters() {
if (typeof window !== 'undefined' && window.__avenx_routers) {
return window.__avenx_routers;
}
return new Set();
}
/** @override */
destroy() {
if (typeof window !== 'undefined') {
window.removeEventListener('hashchange', this.onWindowHashChange);
window.removeEventListener('click', this.onWindowClick);
}
this.hashListeners.clear();
this.linkClickListeners.clear();
}
}