PageSourceSearch

https://hub.farthinghalearms.com/view/theme/redbasic/js/redbasic.js?v=11.4.1

js farthinghalearms.com collected 2026-10-07 21:29:47 UTC 10,442 bytes, 255 lines download raw bytes

1/**
2 * redbasic theme specific JavaScript
3 */
4
5const redbasic_dark_mode = localStorage.getItem('redbasic_dark_mode');
6const redbasic_theme_color = localStorage.getItem('redbasic_theme_color');
7
8if (redbasic_dark_mode == 1) {
9    document.documentElement.setAttribute('data-bs-theme', 'dark');
10}
11
12if (redbasic_dark_mode == 0) {
13    document.documentElement.setAttribute('data-bs-theme', 'light');
14}
15
16if (redbasic_theme_color) {
17    document.querySelector('meta[name=theme-color]').setAttribute('content', redbasic_theme_color);
18}
19
20document.addEventListener('DOMContentLoaded', function () {
21    // provide a fake progress bar for pwa standalone mode
22    if (window.matchMedia('(display-mode: standalone)').matches) {
23        window.addEventListener('beforeunload', function () {
24            if (!document.querySelector('.page-loader')) {
25                let loader = document.createElement('div');
26                loader.classList.add('bg-primary', 'page-loader');
27                document.body.prepend(loader);
28            }
29        });
30    }
31
32    if (redbasic_dark_mode == 1) {
33        document.getElementById('theme-switch-icon').classList.remove('bi-moon');
34        document.getElementById('theme-switch-icon').classList.add('bi-sun');
35        document.querySelector('[data-bs-theme="light"]').setAttribute('data-bs-theme', 'dark');
36    }
37    if (redbasic_dark_mode == 0) {
38        document.getElementById('theme-switch-icon').classList.remove('bi-sun');
39        document.getElementById('theme-switch-icon').classList.add('bi-moon');
40        let darkElements = document.querySelectorAll('[data-bs-theme="dark"]:not(nav)');
41        darkElements.forEach(el => el.setAttribute('data-bs-theme', 'light'));
42    }
43
44    const navBackgroundColor = document.querySelector('nav').style.backgroundColor;
45    if (redbasic_theme_color !== navBackgroundColor) {
46        document.querySelector('meta[name=theme-color]').setAttribute('content', navBackgroundColor);
47        localStorage.setItem('redbasic_theme_color', navBackgroundColor);
48    }
49
50    // CSS3 calc() fallback (for unsupported browsers)
51    const testElem = document.createElement('div');
52    testElem.style.width = 'calc(10px + 10px)';
53    testElem.style.display = 'none';
54    testElem.id = 'css3-calc';
55    document.body.appendChild(testElem);
56
57    if (testElem.offsetWidth === 10) {
58        window.addEventListener('resize', function () {
59            if (window.innerWidth < 992) {
60                document.querySelector('main').style.width = `${window.innerWidth + document.querySelector('aside').offsetWidth}px`;
61            } else {
62                document.querySelector('main').style.width = '100%';
63            }
64        });
65    }
66    testElem.remove(); // Remove the test element
67
68    if (window.innerWidth < 1200) {
69        const rightAsideWrapper = document.getElementById("right_aside_wrapper");
70        const leftAsideWrapper = document.getElementById("left_aside_wrapper");
71        const notificationsWrapper = document.getElementById("notifications_wrapper");
72
73        if (leftAsideWrapper && rightAsideWrapper) {
74            const children = rightAsideWrapper.children;
75            if (children.length) {
76                leftAsideWrapper.append(...children);
77            }
78        }
79
80        if (notificationsWrapper) {
81            notificationsWrapper.classList.add('d-none');
82        }
83    }
84
85    if (document.getElementById('region_1')) {
86        stickyScroll('.aside_spacer_left', '.aside_spacer_top_left', 'section', parseFloat(document.querySelector('main').getBoundingClientRect().top), 20);
87    }
88
89    if (document.getElementById('region_3')) {
90        stickyScroll('.aside_spacer_right', '.aside_spacer_top_right', 'section', parseFloat(document.querySelector('main').getBoundingClientRect().top), 20);
91    }
92
93    document.querySelectorAll('.usermenu').forEach(function (element) {
94        element.addEventListener('click', function () {
95            let navCollapse = document.querySelectorAll('#navbar-collapse-1, #navbar-collapse-2');
96            navCollapse.forEach(function (nav) {
97                if (nav.classList.contains('show')) {
98                    nav.classList.remove('show');
99                }
100            });
101        });
102    });
103
104    document.getElementById('theme-switch').addEventListener('click', function () {
105        const html = document.documentElement;
106        if (html.getAttribute('data-bs-theme') === 'dark') {
107            let nav = document.querySelector('nav');
108            if (nav.dataset.bsTheme === 'dark') {
109                document.querySelectorAll('[data-bs-theme="dark"]:not(nav)').forEach(function (el) {
110                    el.setAttribute('data-bs-theme', 'light');
111                });
112            } else {
113                document.querySelector('[data-bs-theme="dark"]').setAttribute('data-bs-theme', 'light');
114            }
115            localStorage.setItem('redbasic_dark_mode', 0);
116            document.getElementById('theme-switch-icon').classList.remove('bi-sun');
117            document.getElementById('theme-switch-icon').classList.add('bi-moon');
118        } else {
119            document.querySelectorAll('[data-bs-theme="light"]').forEach(function (el) {
120                el.setAttribute('data-bs-theme', 'dark');
121            });
122            localStorage.setItem('redbasic_dark_mode', 1);
123            document.getElementById('theme-switch-icon').classList.remove('bi-moon');
124            document.getElementById('theme-switch-icon').classList.add('bi-sun');
125        }
126        document.querySelector('meta[name=theme-color]').setAttribute('content', document.querySelector('nav').style.backgroundColor);
127        localStorage.setItem('redbasic_theme_color', document.querySelector('nav').style.backgroundColor);
128    });
129
130    document.getElementById('menu-btn').addEventListener('click', function () {
131        const navCollapse = document.getElementById('navbar-collapse-1');
132        if (navCollapse && navCollapse.classList.contains('show')) {
133            navCollapse.classList.remove('show');
134        }
135    });
136
137    $("input[data-role=cat-tagsinput]").tagsinput({
138        tagClass: 'badge rounded-pill bg-warning text-dark'
139    });
140
141    document.querySelectorAll('a.disabled').forEach(function (link) {
142        link.addEventListener('click', function (e) {
143            e.preventDefault();
144            e.stopPropagation();
145        });
146    });
147
148    const doctitle = document.title;
149    function checkNotify() {
150        let notifyUpdateElem = document.getElementById('notify-update');
151        if (notifyUpdateElem && notifyUpdateElem.innerHTML !== '') {
152            document.title = '(' + notifyUpdateElem.innerHTML + ') ' + doctitle;
153        } else {
154            document.title = doctitle;
155        }
156    }
157
158    setInterval(checkNotify, 10 * 1000);
159
160    let touch_start = null;
161    const touch_max = window.innerWidth / 10;
162
163    window.addEventListener('touchstart', function (e) {
164        if (e.touches.length === 1) {
165            touch_start = e.touches[0].clientX;
166            if (touch_start < touch_max) {
167                document.body.style.overflowY = 'hidden';
168            }
169        } else {
170            touch_start = null;
171        }
172    });
173
174    window.addEventListener('touchend', function (e) {
175        document.body.style.overflowY = '';
176        let touch_offset = 30; // at least 30px are a swipe
177        if (touch_start) {
178            let touch_end = e.changedTouches[0].clientX;
179            if (touch_end > (touch_start + touch_offset)) {
180                if (touch_start < touch_max) {
181                    toggleAside();
182                }
183            }
184            if (touch_end < (touch_start - touch_offset)) {
185                // a right -> left swipe
186            }
187        }
188    });
189});
190
191function setStyle(element, cssProperty) {
192    for (let property in cssProperty) {
193        element.style[property] = cssProperty[property];
194    }
195}
196
197function stickyScroll(sticky, stickyTop, container, topOffset, bottomOffset) {
198    let lastScrollTop = 0;
199    let stickyElement = document.querySelector(sticky);
200
201    if (!stickyElement) {
202        return;
203    }
204
205    let stickyHeight = stickyElement.getBoundingClientRect().height;
206    const stickyTopElement = document.querySelector(stickyTop);
207    const content = document.querySelector(container);
208    let diff = window.innerHeight - stickyHeight;
209
210    let h = 0;
211    let lasth = 0;
212    let st = window.pageYOffset || document.documentElement.scrollTop;
213
214    let resizeObserver = new ResizeObserver(function () {
215        stickyHeight = stickyElement.getBoundingClientRect().height;
216        st = window.pageYOffset || document.documentElement.scrollTop;
217        diff = window.innerHeight - stickyHeight;
218    });
219
220    resizeObserver.observe(stickyElement);
221    resizeObserver.observe(content);
222
223    window.addEventListener('scroll', function () {
224        if (window.innerHeight > stickyHeight + topOffset) {
225            setStyle(stickyTopElement, { height: '0px' });
226            setStyle(stickyElement, { position: 'sticky', top: `${topOffset}px` });
227        } else {
228            st = window.pageYOffset || document.documentElement.scrollTop;
229            if (st > lastScrollTop) {
230                setStyle(stickyTopElement, { height: `${lasth}px` });
231                setStyle(stickyElement, { position: 'sticky', top: `${Math.round(diff) - bottomOffset}px`, bottom: '' });
232            } else {
233                h = stickyElement.getBoundingClientRect().top - content.getBoundingClientRect().top;
234                if (Math.round(stickyTopElement.getBoundingClientRect().height) === lasth) {
235                    setStyle(stickyTopElement, { height: `${Math.round(h)}px` });
236                }
237                lasth = Math.round(h);
238                setStyle(stickyElement, { position: 'sticky', top: '', bottom: `${Math.round(diff) - topOffset}px` });
239            }
240            lastScrollTop = st <= 0 ? 0 : st;
241        }
242    }, false);
243}
244
245function makeFullScreen(full) {
246    if (typeof full === 'undefined' || full === true) {
247        document.querySelector('main').classList.add('fullscreen');
248        document.getElementById('fullscreen-btn').style.display = 'none';
249        document.getElementById('inline-btn').style.display = 'inline-block';
250    } else {
251        document.querySelector('main').classList.remove('fullscreen');
252        document.getElementById('fullscreen-btn').style.display = '';
253        document.getElementById('inline-btn').style.display = 'none';
254    }
255}

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.