import { Injectable, Renderer2, RendererFactory2 } from '@angular/core'; @Injectable({ providedIn: 'root', }) export class SoundInitializerService { private renderer: Renderer2; private observer: MutationObserver; constructor(rendererFactory: RendererFactory2) { this.renderer = rendererFactory.createRenderer(null, null); this.observer = new MutationObserver((mutations) => { mutations.forEach((mutation) => { mutation.addedNodes.forEach((node) => { if (node instanceof HTMLElement) { this.processElement(node); } }); }); }); } initialize() { document.querySelectorAll('button, a').forEach((element) => { if (!element.hasAttribute('appPlaySound')) { this.renderer.setAttribute(element, 'appPlaySound', ''); } }); this.observer.observe(document.body, { childList: true, subtree: true, }); } private processElement(element: HTMLElement) { if ( (element.tagName === 'BUTTON' || element.tagName === 'A') && !element.hasAttribute('appPlaySound') ) { this.renderer.setAttribute(element, 'appPlaySound', ''); } element.querySelectorAll('button, a').forEach((child) => { if (!child.hasAttribute('appPlaySound')) { this.renderer.setAttribute(child, 'appPlaySound', ''); } }); } }