### Sidebar Integration Example Source: https://context7.com/wicg/close-watcher/llms.txt Demonstrates wiring a hamburger-menu sidebar to `CloseWatcher` so that the Android back button and Esc key animate and hide the sidebar. It also shows how outside-click detection can be routed through the same watcher. ```APIDOC ## Sidebar Integration — Real-world component example Demonstrates wiring a hamburger-menu sidebar to `CloseWatcher` so that the Android back button and Esc key animate and hide the sidebar, while outside-click detection also routes through the same watcher. ### Example ```js const hamburgerBtn = document.querySelector('#hamburger-menu-button'); const sidebar = document.querySelector('#sidebar'); hamburgerBtn.addEventListener('click', () => { // Slide in sidebar.animate( [{ transform: 'translateX(-200px)' }, { transform: 'translateX(0)' }], { duration: 300, fill: 'forwards' } ); const watcher = new CloseWatcher(); watcher.onclose = () => { // Slide out on any platform close request sidebar.animate( [{ transform: 'translateX(0)' }, { transform: 'translateX(-200px)' }], { duration: 300, fill: 'forwards' } ); }; // Also close on outside click by routing through the same watcher document.body.addEventListener('click', (e) => { if (!e.target.closest('#sidebar')) { watcher.requestClose(); // goes straight to onclose (no cancel needed for sidebar) } }, { once: true }); }); ``` ``` -------------------------------- ### Sidebar Integration with CloseWatcher Source: https://context7.com/wicg/close-watcher/llms.txt Example of integrating a hamburger-menu sidebar with CloseWatcher. This allows the Android back button and Esc key to hide the sidebar, and outside clicks are also routed through the same watcher. ```javascript const hamburgerBtn = document.querySelector('#hamburger-menu-button'); const sidebar = document.querySelector('#sidebar'); hamburgerBtn.addEventListener('click', () => { // Slide in sidebar.animate( [{ transform: 'translateX(-200px)' }, { transform: 'translateX(0)' }], { duration: 300, fill: 'forwards' } ); const watcher = new CloseWatcher(); watcher.onclose = () => { // Slide out on any platform close request sidebar.animate( [{ transform: 'translateX(0)' }, { transform: 'translateX(-200px)' }], { duration: 300, fill: 'forwards' } ); }; // Also close on outside click by routing through the same watcher document.body.addEventListener('click', (e) => { if (!e.target.closest('#sidebar')) { watcher.requestClose(); // goes straight to onclose (no cancel needed for sidebar) } }, { once: true }); }); ``` -------------------------------- ### Platform Close Request Mapping Comparison Source: https://context7.com/wicg/close-watcher/llms.txt Illustrates the difference between legacy, platform-specific close request handling and the modern, unified approach using CloseWatcher. ```js // Before CloseWatcher: fragile platform-specific code function legacySetup(modal) { // Desktop only document.addEventListener('keydown', (e) => { if (e.key === 'Escape') modal.close(); }); // Android back button hack — breaks routers, non-cancelable, fragile history.pushState({ modalOpen: true }, ''); window.addEventListener('popstate', (e) => { if (e.state?.modalOpen) modal.close(); }); } // After CloseWatcher: one API, all platforms function modernSetup(modal) { const watcher = new CloseWatcher(); watcher.onclose = () => modal.close(); } ``` -------------------------------- ### new CloseWatcher([options]) Source: https://context7.com/wicg/close-watcher/llms.txt Constructs a new CloseWatcher instance and adds it to the per-window close watcher stack. The most recent watcher receives close events. An optional AbortSignal can be provided to automatically destroy the watcher. ```APIDOC ## new CloseWatcher([options]) — Construct a close watcher Creates a new `CloseWatcher` instance and pushes it onto the per-window close watcher stack. Only the most recently constructed active watcher receives close events. A watcher becomes inactive after its `close` event fires or after `destroy()` is called. An optional `signal` (an `AbortSignal`) can be passed to destroy the watcher automatically when the signal is aborted. ### Example ```javascript // Basic usage: intercept Esc (desktop) or back button (Android) to close a modal const modal = document.querySelector('#my-modal'); const openButton = document.querySelector('#open-modal'); openButton.addEventListener('click', () => { modal.hidden = false; const watcher = new CloseWatcher(); // Fires on platform close request (Esc, Android back button, VoiceOver dismiss, etc.) watcher.onclose = () => { modal.hidden = true; }; // Properly destroy the watcher when the user closes via an in-page button, // freeing the "free close watcher slot" for future use. modal.querySelector('.close-btn').addEventListener('click', () => { watcher.destroy(); modal.hidden = true; }); }); ``` ``` -------------------------------- ### CloseWatcher Constructor and Event Handling Source: https://github.com/wicg/close-watcher/blob/main/README.md Demonstrates how to create a new CloseWatcher instance and attach an event listener for the 'close' event. The 'onclose' handler is invoked when a user-initiated close request is detected. ```APIDOC ## new CloseWatcher() ### Description Creates a new CloseWatcher instance. This watcher will listen for user-initiated close requests. ### Method `new CloseWatcher()` ### Parameters None ### Event Handlers #### onclose - **Type**: Function - **Description**: A callback function that is executed when a close request is received (e.g., Esc key press, Android back button). The function should contain the logic to close the associated component. ### Request Example ```javascript const watcher = new CloseWatcher(); watcher.onclose = () => { myModal.close(); }; ``` ### Response #### Success Response - **Type**: CloseWatcher instance - **Description**: Returns a new CloseWatcher object. ``` -------------------------------- ### Manage CloseWatcher Instances with User Activation Source: https://github.com/wicg/close-watcher/blob/main/README.md Demonstrates how user activation affects CloseWatcher construction. Without activation, multiple watchers can be grouped. User activation (like button clicks) or calling `watcher.destroy()` resets this grouping behavior. ```javascript window.onload = () => { // This will work as normal: it is the first close watcher created without user activation. (new CloseWatcher()).onclose = () => { /* ... */ }; }; button1.onclick = () => { // This will work as normal: the button click counts as user activation. (new CloseWatcher()).onclose = () => { /* ... */ }; }; button2.onclick = () => { // These will be grouped together, and both will close in response to a singe close request. (new CloseWatcher()).onclose = () => { /* ... */ }; (new CloseWatcher()).onclose = () => { /* ... */ }; }; ``` -------------------------------- ### User Activation Grouping for CloseWatchers Source: https://context7.com/wicg/close-watcher/llms.txt Demonstrates how multiple CloseWatchers created within a single user activation are grouped. A single close request destroys all grouped watchers to prevent trapping users. Each new user activation grants a fresh slot for an independent watcher. ```javascript // ✅ Each button click provides user activation → each watcher is independent button1.addEventListener('click', () => { const watcher1 = new CloseWatcher(); watcher1.onclose = () => closeComponent1(); // closed by 1st close request }); button2.addEventListener('click', () => { const watcher2 = new CloseWatcher(); watcher2.onclose = () => closeComponent2(); // closed by 1st close request }); // ⚠️ Two watchers in one handler → grouped; both close on one request button3.addEventListener('click', () => { const watcherA = new CloseWatcher(); const watcherB = new CloseWatcher(); // grouped with watcherA watcherA.onclose = () => closeComponentA(); watcherB.onclose = () => closeComponentB(); // A single Esc key press closes BOTH components }); // ✅ Properly ungrouped by destroying the first before creating the second button4.addEventListener('click', () => { const watcherA = new CloseWatcher(); watcherA.onclose = () => { closeComponentA(); // watcher is auto-destroyed after close fires; slot is freed }; watcherA.destroy(); // explicitly free slot before creating next watcher const watcherB = new CloseWatcher(); watcherB.onclose = () => closeComponentB(); }); ``` -------------------------------- ### `new CloseWatcher({ signal })` Source: https://context7.com/wicg/close-watcher/llms.txt Accepts an `AbortSignal` via the options object. When the signal is aborted, the watcher is destroyed automatically, integrating naturally with patterns that already use `AbortController` to clean up multiple resources. ```APIDOC ## `new CloseWatcher({ signal })` — Destroy via `AbortSignal` Accepts an `AbortSignal` via the options object. When the signal is aborted, the watcher is destroyed automatically. This integrates naturally with patterns that already use `AbortController` to clean up multiple resources or event listeners at once. ### Example ```js const controller = new AbortController(); const { signal } = controller; // Register multiple cleanup operations under one controller document.addEventListener('keydown', handleKeydown, { signal }); someStream.pipeTo(writableStream, { signal }); const watcher = new CloseWatcher({ signal }); watcher.onclose = () => { document.querySelector('#panel').hidden = true; }; // Abort everything — the CloseWatcher is destroyed alongside the other resources function teardown() { controller.abort(); } document.querySelector('#panel .done-btn').addEventListener('click', teardown); ``` ``` -------------------------------- ### Basic CloseWatcher Usage Source: https://github.com/wicg/close-watcher/blob/main/README.md Instantiate a CloseWatcher and define its behavior when a close request is received. Ensure watchers are destroyed when no longer needed to prevent memory leaks and unexpected behavior. ```javascript const watcher = new CloseWatcher(); // This fires when the user sends a close request, e.g. by pressing Esc on // desktop or by pressing Android's back button. watcher.onclose = () => { myModal.close(); }; // You should destroy watchers which are no longer needed, e.g. if the // modal closes normally. This will prevent future events on this watcher. myModalCloseButton.onclick = () => { watcher.destroy(); myModal.close(); }; ``` -------------------------------- ### Implement Picker Close Behavior with CloseWatcher Source: https://github.com/wicg/close-watcher/blob/main/README.md Integrate CloseWatcher into a custom element (e.g., a picker) to handle its closing. The picker's overlay is hidden and shown using the watcher's lifecycle. ```javascript class MyPicker extends HTMLElement { #button; #overlay; #watcher; constructor() { super(); this.#button = /* ... */; this.#overlay = /* ... */; this.#overlay.hidden = true; this.#overlay.querySelector('.close-button').addEventListener('click', () => { this.#watcher.requestClose(); }); this.#button.onclick = () => { this.overlay.hidden = false; this.#watcher = new CloseWatcher(); this.#watcher.onclose = () => this.overlay.hidden = true; } } } ``` -------------------------------- ### Handle Cancel Event for Confirmation with CloseWatcher Source: https://context7.com/wicg/close-watcher/llms.txt Implement the `oncancel` handler to provide an opportunity to confirm before closing, especially when unsaved data is present. Use `event.preventDefault()` to abort the close and `watcher.close()` to manually proceed if confirmed. This event is gated on transient user activation. ```javascript let hasUnsavedData = false; const watcher = new CloseWatcher(); watcher.oncancel = async (event) => { if (hasUnsavedData) { // Prevent the automatic close event.preventDefault(); const confirmed = await showConfirmDialog( 'You have unsaved changes. Close anyway?' ); if (confirmed) { hasUnsavedData = false; watcher.close(); // manually proceed to close } // If not confirmed, the modal remains open } }; watcher.onclose = () => { document.querySelector('#editor-modal').hidden = true; }; async function showConfirmDialog(message) { // Custom in-page confirmation UI (not window.confirm) return new Promise(resolve => { const dialog = document.querySelector('#confirm-dialog'); dialog.querySelector('p').textContent = message; dialog.hidden = false; dialog.querySelector('.yes').onclick = () => { dialog.hidden = true; resolve(true); }; dialog.querySelector('.no').onclick = () => { dialog.hidden = true; resolve(false); }; }); } ``` -------------------------------- ### Requesting a Close Manually Source: https://github.com/wicg/close-watcher/blob/main/README.md Shows how to use the `requestClose()` method to programmatically trigger a close event. This is useful for centralizing close-handling logic. ```APIDOC ## watcher.requestClose() ### Description Simulates a user-initiated close request. This method triggers the `onclose` event handler as if the user had performed a close action (e.g., pressing Esc). ### Method `requestClose()` ### Parameters None ### Request Example ```javascript myModalCloseButton.onclick = () => { watcher.requestClose(); }; ``` ### Notes Calling `requestClose()` will inactivate the `CloseWatcher` after the `close` event is handled, meaning it will not receive further events. ``` -------------------------------- ### User Activation Grouping Source: https://context7.com/wicg/close-watcher/llms.txt When multiple `CloseWatcher` instances are created within a single user activation, they are grouped. A single close request destroys all watchers in the group, preventing pages from stacking unlimited watchers to trap users. Each new user activation grants a fresh slot for an independent watcher. ```APIDOC ## User Activation Grouping — Preventing back-button trapping When more than one `CloseWatcher` is created within a single user activation (e.g., two watchers created inside one `onclick` handler), the second watcher is grouped with the first. A single close request destroys both, preventing malicious pages from stacking unlimited watchers to trap users. Each new user activation grants a fresh slot for an independent, ungrouped watcher. ### Example ```js // ✅ Each button click provides user activation → each watcher is independent button1.addEventListener('click', () => { const watcher1 = new CloseWatcher(); watcher1.onclose = () => closeComponent1(); // closed by 1st close request }); button2.addEventListener('click', () => { const watcher2 = new CloseWatcher(); watcher2.onclose = () => closeComponent2(); // closed by 1st close request }); // ⚠️ Two watchers in one handler → grouped; both close on one request button3.addEventListener('click', () => { const watcherA = new CloseWatcher(); const watcherB = new CloseWatcher(); // grouped with watcherA watcherA.onclose = () => closeComponentA(); watcherB.onclose = () => closeComponentB(); // A single Esc key press closes BOTH components }); // ✅ Properly ungrouped by destroying the first before creating the second button4.addEventListener('click', () => { const watcherA = new CloseWatcher(); watcherA.onclose = () => { closeComponentA(); // watcher is auto-destroyed after close fires; slot is freed }; watcherA.destroy(); // explicitly free slot before creating next watcher const watcherB = new CloseWatcher(); watcherB.onclose = () => closeComponentB(); }); ``` ``` -------------------------------- ### watcher.requestClose() Source: https://context7.com/wicg/close-watcher/llms.txt Programmatically triggers a close request, simulating user interaction. If called within a transient user activation context, it fires the `cancel` event first; otherwise, it proceeds directly to the `close` event. ```APIDOC ## watcher.requestClose() — Programmatically trigger a close request Programmatically acts as if the user sent a close request. If called within a transient user activation context, it fires the `cancel` event first (allowing confirmation logic to run); otherwise it skips straight to `close`. This centralizes all close-handling logic into the `onclose` handler, eliminating duplicated teardown code. ### Example ```javascript const modal = document.querySelector('#my-modal'); openButton.addEventListener('click', () => { modal.hidden = false; const watcher = new CloseWatcher(); // All close logic lives in one place watcher.onclose = () => { modal.hidden = true; console.log('Modal closed'); }; // Both the close button and the platform gesture route through the same handler modal.querySelector('.close-btn').addEventListener('click', () => { watcher.requestClose(); // triggers onclose above }); }); ``` ``` -------------------------------- ### Programmatically Request Close with CloseWatcher Source: https://context7.com/wicg/close-watcher/llms.txt Use `requestClose()` to programmatically trigger a close request, centralizing all close-handling logic into the `onclose` handler. This ensures both programmatic triggers and platform gestures route through the same logic. ```javascript const modal = document.querySelector('#my-modal'); openButton.addEventListener('click', () => { modal.hidden = false; const watcher = new CloseWatcher(); // All close logic lives in one place watcher.onclose = () => { modal.hidden = true; console.log('Modal closed'); }; // Both the close button and the platform gesture route through the same handler modal.querySelector('.close-btn').addEventListener('click', () => { watcher.requestClose(); // triggers onclose above }); }); ``` -------------------------------- ### Handle Close Confirmation with Unsaved Data Source: https://github.com/wicg/close-watcher/blob/main/README.md Use the `oncancel` event to prevent closing if there's unsaved data and ask the user for confirmation. This event only fires with transient user activation and prevents abuse by not firing again without activation. ```javascript watcher.oncancel = async (e) => { if (hasUnsavedData) { e.preventDefault(); const userReallyWantsToClose = await askForConfirmation("Are you sure you want to close this dialog?"); if (userReallyWantsToClose) { hasUnsavedData = false; watcher.close(); } } }; ``` -------------------------------- ### Custom Date Picker with CloseWatcher Source: https://context7.com/wicg/close-watcher/llms.txt Encapsulates CloseWatcher lifecycle within a custom element. Creates and destroys watchers as the picker opens and closes, ensuring compatibility with host application routing. ```js class MyDatePicker extends HTMLElement { #watcher = null; #overlay = null; connectedCallback() { this.innerHTML = ` `; this.#overlay = this.querySelector('.overlay'); this.querySelector('.trigger').addEventListener('click', () => this.#open()); this.querySelector('.close-btn').addEventListener('click', () => { // Route through requestClose so onclose is the single source of truth this.#watcher?.requestClose(); }); } #open() { this.#overlay.hidden = false; this.#watcher = new CloseWatcher(); this.#watcher.onclose = () => { this.#overlay.hidden = true; this.#watcher = null; this.dispatchEvent(new CustomEvent('picker-closed', { detail: { value: this.querySelector('input').value } })); }; } } customElements.define('my-date-picker', MyDatePicker); // Usage const picker = document.querySelector('my-date-picker'); picker.addEventListener('picker-closed', (e) => { console.log('Selected date:', e.detail.value); // Expected output: "Selected date: 2024-03-15" }); ``` -------------------------------- ### watcher.oncancel / cancel event Source: https://context7.com/wicg/close-watcher/llms.txt The `cancel` event fires before the `close` event, allowing developers to present a confirmation prompt and prevent the close by calling `event.preventDefault()`. This is useful for components with unsaved data. The event is gated on transient user activation. ```APIDOC ## watcher.oncancel / cancel event — Confirm before closing The `cancel` event fires before `close`, giving developers an opportunity to show a confirmation prompt and call `event.preventDefault()` to abort the close. This is useful when the component contains unsaved data. The `cancel` event is gated on transient user activation: it will not fire twice in a row without an intervening user interaction, ensuring close requests always eventually go through. ### Example ```javascript let hasUnsavedData = false; const watcher = new CloseWatcher(); watcher.oncancel = async (event) => { if (hasUnsavedData) { // Prevent the automatic close event.preventDefault(); const confirmed = await showConfirmDialog( 'You have unsaved changes. Close anyway?' ); if (confirmed) { hasUnsavedData = false; watcher.close(); // manually proceed to close } // If not confirmed, the modal remains open } }; watcher.onclose = () => { document.querySelector('#editor-modal').hidden = true; }; async function showConfirmDialog(message) { // Custom in-page confirmation UI (not window.confirm) return new Promise(resolve => { const dialog = document.querySelector('#confirm-dialog'); dialog.querySelector('p').textContent = message; dialog.hidden = false; dialog.querySelector('.yes').onclick = () => { dialog.hidden = true; resolve(true); }; dialog.querySelector('.no').onclick = () => { dialog.hidden = true; resolve(false); }; }); } ``` ``` -------------------------------- ### Destroy CloseWatcher via AbortSignal Source: https://context7.com/wicg/close-watcher/llms.txt Integrate CloseWatcher destruction with AbortController for cleanup. When the signal is aborted, the watcher is destroyed automatically, cleaning up multiple resources simultaneously. ```javascript const controller = new AbortController(); const { signal } = controller; // Register multiple cleanup operations under one controller document.addEventListener('keydown', handleKeydown, { signal }); someStream.pipeTo(writableStream, { signal }); const watcher = new CloseWatcher({ signal }); watcher.onclose = () => { document.querySelector('#panel').hidden = true; }; // Abort everything — the CloseWatcher is destroyed alongside the other resources function teardown() { controller.abort(); } document.querySelector('#panel .done-btn').addEventListener('click', teardown); ``` -------------------------------- ### Construct and Use CloseWatcher Source: https://context7.com/wicg/close-watcher/llms.txt Basic usage for intercepting platform close requests (e.g., Esc, Android back button) to close a modal. Ensure the watcher is properly destroyed when the modal is closed via an in-page button. ```javascript const modal = document.querySelector('#my-modal'); const openButton = document.querySelector('#open-modal'); openButton.addEventListener('click', () => { modal.hidden = false; const watcher = new CloseWatcher(); // Fires on platform close request (Esc, Android back button, VoiceOver dismiss, etc.) watcher.onclose = () => { modal.hidden = true; }; // Properly destroy the watcher when the user closes via an in-page button, // freeing the "free close watcher slot" for future use. modal.querySelector('.close-btn').addEventListener('click', () => { watcher.destroy(); modal.hidden = true; }); }); ``` -------------------------------- ### Add Contributor to Pull Request Source: https://github.com/wicg/close-watcher/blob/main/CONTRIBUTING.md Use this syntax in a pull request comment to add a GitHub username as a contributor. ```text +@github_username ``` -------------------------------- ### Destroying a CloseWatcher Source: https://github.com/wicg/close-watcher/blob/main/README.md Illustrates how to explicitly destroy a CloseWatcher instance when it is no longer needed. This prevents future close events from being triggered by this watcher. ```APIDOC ## watcher.destroy() ### Description Destroys the CloseWatcher instance, preventing it from receiving any further close events. This should be called when the associated component is closed or no longer requires watching. ### Method `destroy()` ### Parameters None ### Request Example ```javascript myModalCloseButton.onclick = () => { watcher.destroy(); myModal.close(); }; ``` ``` -------------------------------- ### Implement Sidebar Close Behavior with CloseWatcher Source: https://github.com/wicg/close-watcher/blob/main/README.md Use CloseWatcher to manage the closing of a sidebar triggered by clicks outside the sidebar or other user actions. Requires DOM elements for the sidebar and a hamburger menu button. ```javascript const hamburgerMenuButton = document.querySelector('#hamburger-menu-button'); const sidebar = document.querySelector('#sidebar'); hamburgerMenuButton.addEventListener('click', () => { const watcher = new CloseWatcher(); sidebar.animate([{ transform: 'translateX(-200px)' }, { transform: 'translateX(0)' }]); watcher.onclose = () => { sidebar.animate([{ transform: 'translateX(0)' }, { transform: 'translateX(-200px)' }]); }; // Close on clicks outside the sidebar. document.body.addEventListener('click', e => { if (e.target.closest('#sidebar') === null) { watcher.close(); } }); }); ``` -------------------------------- ### Requesting Close with CloseWatcher Source: https://github.com/wicg/close-watcher/blob/main/README.md Use the `requestClose()` method to programmatically trigger the close event. This is useful for centralizing close-handling logic within the `onclose` handler, deduplicating calls to `myModal.close()`. ```javascript watcher.onclose = () => myModal.close(); myModalCloseButton.onclick = () => watcher.requestClose(); ``` -------------------------------- ### Destroy CloseWatcher with AbortSignal Source: https://github.com/wicg/close-watcher/blob/main/README.md Integrate CloseWatcher destruction with an AbortController's signal. This is useful for managing multiple ongoing operations or resources that share the same AbortSignal. ```javascript const controller = new AbortController(); const watcher = new CloseWatcher({ signal: controller.signal }); // ... later ... controller.abort(); ``` -------------------------------- ### Remove Contributor from Pull Request Source: https://github.com/wicg/close-watcher/blob/main/CONTRIBUTING.md Use this syntax in a pull request comment to remove a GitHub username as a contributor, or to remove yourself if you made a mistake or had no part in designing the feature. ```text -@github_username ``` -------------------------------- ### Deactivate CloseWatcher with destroy() Source: https://context7.com/wicg/close-watcher/llms.txt Explicitly deactivate a CloseWatcher without firing events. Call this when a component closes via means other than a platform close request to free up the 'free close watcher slot'. ```javascript window.addEventListener('load', () => { // This is the one free (non-user-activation) close watcher slot const timeoutWatcher = new CloseWatcher(); timeoutWatcher.onclose = () => { document.querySelector('#timeout-dialog').hidden = true; }; // If the user dismisses via the dialog's own button, destroy the watcher document.querySelector('#timeout-dialog .dismiss-btn').addEventListener('click', () => { timeoutWatcher.destroy(); // frees the slot; no events fired document.querySelector('#timeout-dialog').hidden = true; }); }); ``` -------------------------------- ### `watcher.destroy()` Source: https://context7.com/wicg/close-watcher/llms.txt Explicitly deactivates a `CloseWatcher` without firing any events. This is important to call when a component closes through means other than a platform close request to free up the 'free close watcher slot'. ```APIDOC ## `watcher.destroy()` — Deactivate a close watcher Explicitly deactivates a `CloseWatcher` without firing any events. This is important to call when a component closes through means other than a platform close request (e.g., clicking a Done button), because it frees the "free close watcher slot" — the one slot that allows creating a `CloseWatcher` without user activation for legitimate system-initiated dialogs (e.g., session timeout alerts). ### Example ```js // Without destroy(), a timeout dialog could consume the free slot needed later window.addEventListener('load', () => { // This is the one free (non-user-activation) close watcher slot const timeoutWatcher = new CloseWatcher(); timeoutWatcher.onclose = () => { document.querySelector('#timeout-dialog').hidden = true; }; // If the user dismisses via the dialog's own button, destroy the watcher document.querySelector('#timeout-dialog .dismiss-btn').addEventListener('click', () => { timeoutWatcher.destroy(); // frees the slot; no events fired document.querySelector('#timeout-dialog').hidden = true; }); }); ``` ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.