PageSourceSearch

https://airplus.com/static/scripts/drawer.js?134244241380000000

js airplus.com collected 2026-09-25 14:03:46 UTC 3,810 bytes, 141 lines download raw bytes

1/**
2 * Drawer Component - ES Module
3 *
4 * Usage:
5 * 1. Include this script in your page
6 * 2. Add data attributes to your HTML:
7 *    - data-drawer-id="unique-id" on the drawer element
8 *    - data-drawer-trigger="unique-id" on any element that should open the drawer
9 *    - data-drawer-close="unique-id" on any element inside the drawer that should close it
10 * 3. Use data-drawer-anchor to specify the drawer position (left, right, top, bottom)
11 */
12
13import { openDialog } from "./dialog.js";
14
15const drawerState = {};
16let closeButtonHandlers = new Map();
17let triggerHandlers = new Map();
18let backdropClickHandler = null;
19let keyupHandler = null;
20
21function initializeDrawer(drawer) {
22  const id = drawer.dataset.drawerId;
23  if (!id) return;
24
25  drawerState[id] = {
26    isOpen: false,
27    element: drawer,
28  };
29
30  const closeButtons = drawer.querySelectorAll(`[data-drawer-close="${id}"]`);
31  closeButtons.forEach((btn) => {
32    const handler = () => closeDrawer(id);
33    btn.addEventListener("click", handler);
34    closeButtonHandlers.set(btn, handler);
35  });
36}
37
38function initializeDrawerTriggers() {
39  const triggers = document.querySelectorAll("[data-drawer-trigger]");
40  triggers.forEach((trigger) => {
41    const id = trigger.dataset.drawerTrigger;
42    const handler = (e) => {
43      e.preventDefault();
44      openDrawer(id);
45    };
46    trigger.addEventListener("click", handler);
47    triggerHandlers.set(trigger, handler);
48  });
49}
50
51function setupGlobalEventListeners() {
52  backdropClickHandler = () => {
53    Object.keys(drawerState).forEach((id) => {
54      if (drawerState[id].isOpen) {
55        closeDrawer(id);
56      }
57    });
58  };
59  document.addEventListener("backdrop:clicked", backdropClickHandler);
60
61  keyupHandler = (e) => {
62    if (e.key === "Escape") {
63      Object.keys(drawerState).forEach((id) => {
64        if (drawerState[id].isOpen) {
65          closeDrawer(id);
66        }
67      });
68    }
69  };
70  document.addEventListener("keyup", keyupHandler);
71}
72
73export function openDrawer(id) {
74  let state = drawerState[id];
75  if (!state) {
76    const drawer = document.querySelector(`[data-drawer-id="${id}"]`);
77    if (!drawer) {
78      return;
79    }
80    initializeDrawer(drawer);
81    state = drawerState[id];
82  }
83  if (!state) return;
84
85  state.isOpen = true;
86  state.element.classList.add("open");
87
88  // Use showModal for <dialog> elements
89  if (state.element.tagName === "DIALOG" && !state.element.open) {
90    //state.element.showModal();
91    openDialog({ contentId: state.element.getAttribute("data-drawer-id") });
92  }
93
94  const openBackdropEvent = new CustomEvent("backdrop:open");
95  document.dispatchEvent(openBackdropEvent);
96}
97
98export function closeDrawer(id) {
99  const state = drawerState[id];
100  if (!state) return;
101
102  state.isOpen = false;
103  state.element.classList.remove("open");
104
105  // Close <dialog> elements properly
106  if (state.element.tagName === "DIALOG" && state.element.open) {
107    state.element.close();
108  }
109
110  const closeBackdropEvent = new CustomEvent("backdrop:close");
111  document.dispatchEvent(closeBackdropEvent);
112}
113
114export function destroyDrawer() {
115  closeButtonHandlers.forEach((handler, btn) => {
116    btn.removeEventListener("click", handler);
117  });
118  closeButtonHandlers.clear();
119
120  triggerHandlers.forEach((handler, trigger) => {
121    trigger.removeEventListener("click", handler);
122  });
123  triggerHandlers.clear();
124
125  if (backdropClickHandler) {
126    document.removeEventListener("backdrop:clicked", backdropClickHandler);
127    backdropClickHandler = null;
128  }
129  if (keyupHandler) {
130    document.removeEventListener("keyup", keyupHandler);
131    keyupHandler = null;
132  }
133}
134
135export function initDrawer() {
136  const drawers = document.querySelectorAll("[data-drawer-id]");
137  drawers.forEach(initializeDrawer);
138  initializeDrawerTriggers();
139  setupGlobalEventListeners();
140}
141initDrawer();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.