Files
Toju/src/app/core/platform/external-link.service.ts
2026-03-20 03:05:29 +01:00

61 lines
1.6 KiB
TypeScript

import { Injectable, inject } from '@angular/core';
import { ElectronBridgeService } from './electron/electron-bridge.service';
/**
* Opens URLs in the system default browser (Electron) or a new tab (browser).
*
* Usage:
* inject(ExternalLinkService).open('https://example.com');
*/
@Injectable({ providedIn: 'root' })
export class ExternalLinkService {
private readonly electronBridge = inject(ElectronBridgeService);
/** Open a URL externally. Only http/https URLs are allowed. */
open(url: string): void {
if (!url || !(url.startsWith('http://') || url.startsWith('https://')))
return;
const electronApi = this.electronBridge.getApi();
if (electronApi) {
void electronApi.openExternal(url);
return;
}
window.open(url, '_blank', 'noopener,noreferrer');
}
/**
* Click handler for anchor elements. Call from a (click) binding or HostListener.
* Returns true if the click was handled (link opened externally), false otherwise.
*/
handleClick(evt: MouseEvent): boolean {
const target = (evt.target as HTMLElement)?.closest('a') as HTMLAnchorElement | null;
if (!target)
return false;
const href = target.href;
if (!href)
return false;
if (href.startsWith('javascript:') || href.startsWith('blob:') || href.startsWith('data:'))
return false;
const rawAttr = target.getAttribute('href');
if (rawAttr?.startsWith('#'))
return false;
if (target.hasAttribute('routerlink') || target.hasAttribute('ng-reflect-router-link'))
return false;
evt.preventDefault();
evt.stopPropagation();
this.open(href);
return true;
}
}