1// Vanilla JavaScript Helper Library - jQuery Replacement 2(function() { 3 'use strict'; 4 5 // DOM Ready function 6 function ready(fn) { 7 if (document.readyState !== 'loading') { 8 fn(); 9 } else { 10 document.addEventListener('DOMContentLoaded', fn); 11 } 12 } 13 14 // Query selector helper (replaces $) 15 function $(selector, context) { 16 context = context || document; 17 if (typeof selector === 'string') { 18 const elements = context.querySelectorAll(selector); 19 if (elements.length === 0) return null; 20 if (elements.length === 1) return elements[0]; 21 // Return array-like object with jQuery-like methods 22 const arr = Array.from(elements); 23 arr.each = function(callback) { 24 this.forEach(callback); 25 return this; 26 }; 27 arr.on = function(event, handler) { 28 this.forEach(el => el.addEventListener(event, handler)); 29 return this; 30 }; 31 arr.prop = function(name, value) { 32 if (value === undefined) { 33 return this[0] ? this[0][name] : undefined; 34 } 35 this.forEach(el => el[name] = value); 36 return this; 37 }; 38 arr.data = function(name, value) { 39 if (value === undefined) { 40 return this[0] ? (this[0].dataset[name] || this[0].getAttribute('data-' + name)) : undefined; 41 } 42 this.forEach(el => el.dataset[name] = value); 43 return this; 44 }; 45 arr.attr = function(name, value) { 46 if (value === undefined) { 47 return this[0] ? this[0].getAttribute(name) : undefined; 48 } 49 this.forEach(el => el.setAttribute(name, value)); 50 return this; 51 }; 52 arr.text = function(text) { 53 if (text === undefined) { 54 return this[0] ? this[0].textContent : undefined; 55 } 56 this.forEach(el => el.textContent = text); 57 return this; 58 }; 59 arr.hide = function() { 60 this.forEach(el => el.style.display = 'none'); 61 return this; 62 }; 63 arr.show = function() { 64 this.forEach(el => el.style.display = ''); 65 return this; 66 }; 67 arr.css = function(prop, value) { 68 if (typeof prop === 'object') { 69 this.forEach(el => { 70 Object.keys(prop).forEach(key => { 71 el.style[key] = prop[key]; 72 }); 73 }); 74 return this; 75 } 76 if (value === undefined) { 77 return this[0] ? window.getComputedStyle(this[0])[prop] : undefined; 78 } 79 this.forEach(el => el.style[prop] = value); 80 return this; 81 }; 82 arr.addClass = function(className) { 83 this.forEach(el => el.classList.add(className)); 84 return this; 85 }; 86 arr.removeClass = function(className) { 87 this.forEach(el => el.classList.remove(className)); 88 return this; 89 }; 90 arr.is = function(selector) { 91 return this[0] ? this[0].matches(selector) : false; 92 }; 93 arr.val = function(value) { 94 if (value === undefined) { 95 return this[0] ? this[0].value : undefined; 96 } 97 this.forEach(el => el.value = value); 98 return this; 99 }; 100 return arr; 101 } 102 if (selector && selector.nodeType) return selector; 103 if (selector === document) return selector; 104 return selector; 105 } 106 107 // Extend element prototype with helper methods 108 Element.prototype.addClass = function(className) { 109 this.classList.add(className); 110 return this; 111 }; 112 113 Element.prototype.removeClass = function(className) { 114 this.classList.remove(className); 115 return this; 116 }; 117 118 Element.prototype.toggleClass = function(className) { 119 this.classList.toggle(className); 120 return this; 121 }; 122 123 Element.prototype.hasClass = function(className) { 124 return this.classList.contains(className); 125 }; 126 127 Element.prototype.on = function(event, handler) { 128 this.addEventListener(event, handler); 129 return this; 130 }; 131 132 Element.prototype.off = function(event, handler) { 133 this.removeEventListener(event, handler); 134 return this; 135 }; 136 137 Element.prototype.attr = function(name, value) { 138 if (value === undefined) { 139 return this.getAttribute(name); 140 } 141 this.setAttribute(name, value); 142 return this; 143 }; 144 145 Element.prototype.data = function(name, value) { 146 if (value === undefined) { 147 return this.dataset[name] || this.getAttribute('data-' + name); 148 } 149 this.dataset[name] = value; 150 return this; 151 }; 152 153 Element.prototype.prop = function(name, value) { 154 if (value === undefined) { 155 return this[name]; 156 } 157 this[name] = value; 158 return this; 159 }; 160 161 Element.prototype.val = function(value) { 162 if (value === undefined) { 163 return this.value; 164 } 165 this.value = value; 166 return this; 167 }; 168 169 Element.prototype.html = function(html) { 170 if (html === undefined) { 171 return this.innerHTML; 172 } 173 this.innerHTML = html; 174 return this; 175 }; 176 177 Element.prototype.text = function(text) { 178 if (text === undefined) { 179 return this.textContent; 180 } 181 this.textContent = text; 182 return this; 183 }; 184 185 Element.prototype.show = function() { 186 this.style.display = ''; 187 return this; 188 }; 189 190 Element.prototype.hide = function() { 191 this.style.display = 'none'; 192 return this; 193 }; 194 195 Element.prototype.css = function(prop, value) { 196 if (typeof prop === 'object') {
197 Object.keys(prop).forEach(key => { 198 this.style[key] = prop[key]; 199 }); 200 return this; 201 } 202 if (value === undefined) { 203 return window.getComputedStyle(this)[prop]; 204 } 205 this.style[prop] = value; 206 return this; 207 }; 208 209 Element.prototype.closest = function(selector) { 210 let el = this; 211 while (el && el.nodeType === 1) { 212 if (el.matches(selector)) { 213 return el; 214 } 215 el = el.parentElement; 216 } 217 return null; 218 }; 219 220 Element.prototype.parent = function(selector) { 221 const parent = this.parentElement; 222 if (!selector) return parent; 223 return parent && parent.matches(selector) ? parent : null; 224 }; 225 226 Element.prototype.siblings = function(selector) { 227 const siblings = []; 228 let sibling = this.parentElement.firstChild; 229 while (sibling) { 230 if (sibling.nodeType === 1 && sibling !== this) { 231 if (!selector || sibling.matches(selector)) { 232 siblings.push(sibling); 233 } 234 } 235 sibling = sibling.nextSibling; 236 } 237 return siblings; 238 }; 239 240 Element.prototype.find = function(selector) { 241 const elements = this.querySelectorAll(selector); 242 if (elements.length === 0) return null; 243 if (elements.length === 1) return elements[0]; 244 const arr = Array.from(elements); 245 arr.text = function(text) { 246 if (text === undefined) { 247 return this[0] ? this[0].textContent : undefined; 248 } 249 this.forEach(el => el.textContent = text); 250 return this; 251 }; 252 arr.removeClass = function(className) { 253 this.forEach(el => el.classList.remove(className)); 254 return this; 255 }; 256 arr.addClass = function(className) { 257 this.forEach(el => el.classList.add(className)); 258 return this; 259 }; 260 return arr; 261 }; 262 263 Element.prototype.is = function(selector) { 264 return this.matches(selector); 265 }; 266 267 // Array methods for NodeList/Array 268 Array.prototype.each = function(callback) { 269 this.forEach(callback); 270 return this; 271 }; 272 273 // Global helper functions 274 window.$ = $; 275 window.ready = ready; 276 window.$$ = function(selector, context) { 277 return Array.from((context || document).querySelectorAll(selector)); 278 }; 279 280 // jQuery-like document ready 281 window.$(document).ready = ready; 282 283 // Loading Overlay helper (replaces jQuery LoadingOverlay plugin) 284 window.LoadingOverlay = { 285 show: function(element) { 286 if (typeof element === 'string') { 287 element = $(element); 288 } 289 if (element) { 290 element.style.position = 'relative'; 291 const overlay = document.createElement('div'); 292 overlay.className = 'loading-overlay-backdrop'; 293 overlay.style.cssText = 'position:absolute;top:0;left:0;width:100%;height:100%;background:rgba(255,255,255,0.8);z-index:9999;display:flex;align-items:center;justify-content:center;'; 294 overlay.innerHTML = '<div style="text-align:center;"><div style="border:4px solid #f3f3f3;border-top:4px solid #3498db;border-radius:50%;width:40px;height:40px;animation:spin 1s linear infinite;margin:0 auto;"></div></div>'; 295 element.appendChild(overlay); 296 element._loadingOverlay = overlay; 297 } 298 }, 299 hide: function(element, remove) { 300 if (typeof element === 'string') { 301 element = $(element); 302 } 303 if (element && element._loadingOverlay) { 304 if (remove) { 305 element._loadingOverlay.remove(); 306 } else { 307 element._loadingOverlay.style.display = 'none'; 308 } 309 delete element._loadingOverlay; 310 } 311 }, 312 setup: function(options) { 313 // Store options for later use if needed 314 window._loadingOverlayOptions = options || {}; 315 } 316 }; 317 318 // Add spin animation if not exists 319 if (!document.querySelector('style[data-loading-overlay]')) { 320 const style = document.createElement('style'); 321 style.setAttribute('data-loading-overlay', 'true'); 322 style.textContent = '@keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }'; 323 document.head.appendChild(style); 324 } 325 326})(); 327
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.