PageSourceSearch

https://fddb.info/static/js/modal.js?t=1789549514

js fddb.info collected 2026-09-24 09:42:13 UTC 6,061 bytes, 209 lines download raw bytes

1// Config
2const isOpenClass = "modal-is-open";
3const openingClass = "modal-is-opening";
4const closingClass = "modal-is-closing";
5const animationDuration = 500; // ms
6let visibleModal = null;
7
8// Toggle modal
9const toggleModal = (event) => {
10  event.preventDefault();
11  const modal = document.getElementById(
12    event.currentTarget.getAttribute("data-target"),
13  );
14  typeof modal != "undefined" && modal != null && isModalOpen(modal)
15    ? closeModal(modal, true)
16    : openModal(modal, true);
17};
18
19// Switch modal
20const switchModal = (event) => {
21  event.preventDefault();
22  const modal = document.getElementById(
23    event.currentTarget.getAttribute("data-target"),
24  );
25  const currentModal = document.getElementById(
26    event.currentTarget.getAttribute("data-current"),
27  );
28  closeModal(currentModal, false);
29  openModal(modal, false);
30};
31
32// Is modal open
33const isModalOpen = (modal) => {
34  return modal.hasAttribute("open") && modal.getAttribute("open") != "false"
35    ? true
36    : false;
37};
38
39// Open modal
40const openModal = (modal, shouldAnimate) => {
41  if (isScrollbarVisible()) {
42    document.documentElement.style.setProperty(
43      "--scrollbar-width",
44      `${getScrollbarWidth()}px`,
45    );
46  }
47  document.documentElement.classList.add(isOpenClass, openingClass);
48  setTimeout(() => {
49    visibleModal = modal;
50    document.documentElement.classList.remove(openingClass);
51  }, shouldAnimate ? animationDuration : 0);
52  modal.setAttribute("open", true);
53  addInputListeners(modal);
54};
55
56const clearErrorStates = (modal) => {
57  const errorStates = modal.querySelectorAll(".error");
58  errorStates.forEach((errorState) => {
59    errorState.classList.remove("error");
60  });
61};
62
63const clearErrorMessages = (modal) => {
64  // error messages are displayed in a p tag that is inside a div with class input-error-container
65  const errorMessages = modal.querySelectorAll(".input-error-container span");
66  errorMessages.forEach((errorMessage) => {
67    errorMessage.remove();
68  });
69};
70
71const clearModalInputs = (modal) => {
72  clearErrorStates(modal);
73  clearErrorMessages(modal);
74  const inputs = modal.querySelectorAll("input");
75  inputs.forEach((input) => {
76    if (input.type !== "hidden") {
77      if (input.type === "checkbox") {
78        input.checked = false;
79      } else {
80        input.value = "";
81      }
82    }
83  });
84};
85
86// find all inputs in the modal and add an event-listener to each
87const addInputListeners = (modal) => {
88  const inputs = modal.querySelectorAll("input");
89  inputs.forEach((input) => {
90    input.addEventListener("input", (e) => {
91      if (e.target.classList.contains("error")) {
92        removeErrorState(e.target);
93      }
94    });
95  });
96};
97
98const removeErrorState = (input) => {
99  input.classList.remove("error");
100};
101
102const makePWInvisible = (modal) => {
103  const visibilityDivs = document.querySelectorAll(".toggle-visibility");
104  const invisibilityDivs = document.querySelectorAll(".toggle-invisibility");
105
106  invisibilityDivs.forEach(function(div) {
107    const targetId = div.getAttribute("data-target");
108    const targetInput = document.getElementById(targetId);
109    const visibilityDiv = document.querySelector(
110      `.toggle-visibility[data-target="${targetId}"]`,
111    );
112
113    targetInput.type = "password";
114    div.style.display = "none";
115    visibilityDiv.style.display = "block";
116  });
117};
118
119// Close modal
120const closeModal = (modal, shouldAnimate) => {
121  visibleModal = null;
122  document.documentElement.classList.add(closingClass);
123  setTimeout(() => {
124    document.documentElement.classList.remove(closingClass, isOpenClass);
125    document.documentElement.style.removeProperty("--scrollbar-width");
126    modal.removeAttribute("open");
127    clearModalInputs(modal);
128    makePWInvisible(modal);
129    modal.querySelector("form").reset();
130  }, shouldAnimate ? animationDuration : 0);
131};
132
133// Close with a click outside
134document.addEventListener("click", (event) => {
135  if (visibleModal != null) {
136    const modalContent = visibleModal.querySelector("article");
137    const isClickInside = modalContent.contains(event.target);
138    !isClickInside && closeModal(visibleModal, true);
139  }
140});
141
142// Close with Esc key
143document.addEventListener("keydown", (event) => {
144  if (event.key === "Escape" && visibleModal != null) {
145    closeModal(visibleModal, true);
146  }
147});
148
149// Get scrollbar width
150const getScrollbarWidth = () => {
151  // Creating invisible container
152  const outer = document.createElement("div");
153  outer.style.visibility = "hidden";
154  outer.style.overflow = "scroll"; // forcing scrollbar to appear
155  outer.style.msOverflowStyle = "scrollbar"; // needed for WinJS apps
156  document.body.appendChild(outer);
157
158  // Creating inner element and placing it in the container
159  const inner = document.createElement("div");
160  outer.appendChild(inner);
161
162  // Calculating difference between container's full width and the child width
163  const scrollbarWidth = outer.offsetWidth - inner.offsetWidth;
164
165  // Removing temporary elements from the DOM
166  outer.parentNode.removeChild(outer);
167
168  return scrollbarWidth;
169};
170
171// Is scrollbar visible
172const isScrollbarVisible = () => {
173  return document.body.scrollHeight > screen.height;
174};
175
176// close all open modals
177const closeAllModals = () => {
178  const modals = document.querySelectorAll("dialog[open]");
179  modals.forEach((modal) => {
180    closeModal(modal);
181  });
182};
183
184// close all open modals and open the modal with the given id
185const openModalById = (id) => {
186  closeAllModals();
187  const modal = document.getElementById(id);
188  openModal(modal);
189};
190
191// Handle keybindings
192function scrollDown() {
193  window.scrollBy(0, 100); // Adjust the scrolling amount as needed
194}
195
196function scrollUp() {
197  // Move the page content up
198  window.scrollBy(0, -100); // Adjust the scrolling amount as needed
199}
200
201function toggleTheme() {
202  // Toggle between light and dark theme
203  const theme = document.documentElement.getAttribute("data-theme");
204  if (theme === "light") {
205    document.documentElement.setAttribute("data-theme", "dark");
206  } else {
207    document.documentElement.setAttribute("data-theme", "light");
208  }
209}

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.