/** * AKSRT Rehydrate System * * Centralized component initialization and re-initialization system. * Components register their init functions, and rehydrate() is called * to initialize or re-initialize them on a given root element. * * Usage: * AksrtFrontend.register('name', initFn); // Register a component * AksrtFrontend.boot(document); // One-time initial page load * AksrtFrontend.rehydrate(root, 'ajax'); // Initialize dynamic content * * @package AKSRT * @since 5.0.0 */ (function () { 'use strict'; var _registry = []; var _booted = false; var _bootRoot = null; function invoke(entry, root, reason) { try { entry.initFn(root, reason); } catch (err) { console.error('[AKSRT Rehydrate] Error initializing "' + entry.name + '":', err); } } function dispatch(root, reason, eventName) { try { root.dispatchEvent(new CustomEvent(eventName, { bubbles: true, detail: { reason: reason } })); } catch (e) { /* IE fallback */ } } window.AksrtFrontend = { /** * Register a component's init function. * * @param {string} name Unique component name * @param {Function} initFn Function(root, reason) - root defaults to document */ register: function (name, initFn) { if (typeof name !== 'string' || typeof initFn !== 'function') return; // Prevent duplicate registrations for (var i = 0; i < _registry.length; i++) { if (_registry[i].name === name) { _registry[i].initFn = initFn; if (_booted) invoke(_registry[i], _bootRoot || document, 'init'); return; } } var entry = { name: name, initFn: initFn }; _registry.push(entry); if (_booted) invoke(entry, _bootRoot || document, 'init'); }, /** * Run the one-time initial page boot. * * @param {Element|Document} root The document root to initialize */ boot: function (root) { if (_booted) return; _booted = true; _bootRoot = root || document; this.rehydrate(_bootRoot, 'init'); dispatch(_bootRoot, 'init', 'aksrt:ready'); }, /** * Initialize or re-initialize all registered components on a root element. * * @param {Element|Document} root The root DOM element to search within * @param {string} reason Why rehydrate is called: * 'init' = initial page load * 'ajax' = after AJAX content injection * 'modal' = after modal content loads * Custom string for other triggers */ rehydrate: function (root, reason) { root = root || document; reason = reason || 'init'; for (var i = 0; i < _registry.length; i++) { invoke(_registry[i], root, reason); } dispatch(root, reason, 'aksrt:rehydrated'); }, /** * Get the list of registered component names (for debugging). */ getRegistered: function () { return _registry.map(function (r) { return r.name; }); }, isBooted: function () { return _booted; } }; })();