PageSourceSearch

https://blddb.net/assets/js/main.js

js blddb.net collected 2026-10-06 13:14:36 UTC 6,334 bytes, 166 lines download raw bytes

1/*
2    Copyright 2022 Jim "JimOfLeisure" Nelson
3    https://github.com/JimOfLeisure/html5up-phantom-plus | @JimOfLeisure
4    Free for personal and commercial use under the CCA 3.0 license (https://creativecommons.org/licenses/by/3.0/)
5
6    This file is a vanillajs rewrite of main.js from:
7    Phantom by HTML5 UP
8    html5up.net | @ajlkn
9    Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
10*/
11
12document.addEventListener("DOMContentLoaded", () => {
13    const body = document.querySelector("body");
14    enhanceForms();
15    // enableMenu(body);
16    removePreload(body);
17});
18
19function wrapInner(parent, wrapper, attribute, attributevalue) {
20    // This function from https://codepen.io/kenjiroart/pen/qBmONJ
21    //   It is meant to replace the functionality of jQuery's $.wrapInner
22    if (typeof wrapper === "string") {
23        wrapper = document.createElement(wrapper);
24    }
25    const div = parent.appendChild(wrapper).setAttribute(attribute, attributevalue);
26
27    while (parent.firstChild !== wrapper) {
28        wrapper.appendChild(parent.firstChild);
29    }
30}
31
32function wrapOuter(element, wrapper, attribute, attributevalue) {
33    // Adapting from wrapInner
34    if (typeof wrapper === "string") {
35        wrapper = document.createElement(wrapper);
36    }
37    attribute && wrapper.setAttribute(attribute, attributevalue);
38    // To ensure the wrapper is in the same sibling-related position as element
39    element.parentElement.insertBefore(wrapper, element);
40}
41
42function removePreload(body) {
43    // Play initial animations on page load.
44    //   Wait 100ms to remove is-preload to ensure DOM has had time to update
45    setTimeout(() => body.classList.remove("is-preload"), 100);
46}
47
48// Touch?
49//   Original sets is-touch based on browser detection
50//   Will replace that with @media(hover: none) in scss instead
51
52function enhanceForms() {
53    // Forms.
54    // Find all textareas in forms and loop through each
55    Array.from(document.querySelectorAll("form textarea")).forEach((textarea) => {
56    // Add wrapper div, set some style and attribute
57        wrapOuter(textarea, "div", "class", "textarea-wrapper");
58        textarea.setAttribute("rows", "1");
59        textarea.style.overflow = "hidden";
60        textarea.style.resize = "none";
61
62        // Trim leading and trailing whitespace in textarea on focus change and ctrl-enter
63        const trimElement = (element) => element.value = element.value.trim();
64        ["blur", "focus"].forEach((eventName) => textarea.addEventListener(eventName, (event) => trimElement(event.target)));
65        textarea.addEventListener("keydown", (event) => {
66            if (event.code === 13 && event.ctrlKey) {
67                event.preventDefault();
68                event.stopPropagation();
69                trimElement(event.target);
70            }
71        });
72
73        // Auto-size the height of the textarea
74        const setHeight = (element) => {
75            element.style.height = "auto";
76            element.style.height = `${element.scrollHeight}px`;
77        };
78        // Set height on initial load
79        setHeight(textarea);
80        // Monitor events to resize
81        ["input", "blur", "focus"].forEach((eventName) => textarea.addEventListener(eventName, (event) => setHeight(event.target)));
82
83        // Select text on tab-out
84        //   This is broken, but it's broken in the original code, too
85        //   It exits the field and doesn't select
86        //   It will select the text if youchange keyup to keydown,
87        //   But then the selection is irrelevant when the focus is lost
88        //   You can make it work with keydown and event.preventDefault(),
89        //     But that prevents you from being able to exit the field with tab
90        textarea.addEventListener("keyup", (event) => {
91            if (event.code === "Tab") {
92                event.target.select();
93            }
94        });
95
96        // Limit textarea height for "mobile"
97        // Original code used browser detection; I'll just assume if
98        //   it can't hover we'll limit the height
99        if (matchMedia("(hover: none)").matches) {
100            textarea.style["max-height"] = "10em";
101            textarea.style.overflow = "auto";
102        }
103    });
104}
105
106function enableMenu(body) {
107    // Menu.
108    const menu = document.querySelector("#menu");
109    wrapInner(menu, "div", "class", "inner");
110
111    let menuIsDebouncing = false;
112    const menuDebounced = () => {
113        if (!menuIsDebouncing) {
114            setTimeout(() => menuIsDebouncing = false, 350);
115            menuIsDebouncing = true;
116            return true;
117        }
118        return false;
119    };
120    const menuMove = {
121        "hide": () => menuDebounced() && body.classList.remove("is-menu-visible"),
122        "show": () => menuDebounced() && body.classList.add("is-menu-visible"),
123        "toggle": () => menuDebounced() && body.classList.toggle("is-menu-visible")
124    };
125
126    // The original script moves #menu to the bottom of body
127    // Why though?
128    //   Ok, the styles only work right when it's down there
129    //   Not sure why it's not just there in the first place
130    body.appendChild(menu);
131
132    // This adds the animated X icon to close the menu
133    //   I don't know why it's being added with script
134    //   I'm just aping the original code so far
135    const close = document.createElement("a");
136    close.href = "#menu";
137    close.classList.add("close");
138    close.innerText = "Close";
139    menu.appendChild(close);
140
141    // Add menu toggle to appropriate link targets
142    Array.from(document.querySelectorAll("[href=\"#menu\"]")).forEach((el) => el.addEventListener("click", (event) => {
143        event.preventDefault();
144        event.stopPropagation();
145        menuMove.toggle();
146    }));
147
148    // Prevents unhandled clicks in #menu from propagating to body to close menu
149    menu.addEventListener("click", (event) => {
150        event.stopPropagation();
151    // The original code on link click stops propagation and changes the
152    // location after a delay. I'm not gonna do that.
153    });
154
155    // Hides menu when clicking on body
156    body.addEventListener("click", (event) => {
157        menuMove.hide();
158    });
159
160    // Close menu on ESC key pressed
161    body.addEventListener("keydown", (event) => {
162        if (event.code === "Escape") {
163            menuMove.hide();
164        }
165    });
166}

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.