1import { Application } from "@hotwired/stimulus"; 2import { eagerControllers, isApplicationDebug, lazyControllers } from "./controllers.js"; 3const controllerAttribute = "data-controller"; 4const loadControllers = (application, eagerControllers, lazyControllers) => { 5 for (const name in eagerControllers) registerController(name, eagerControllers[name], application); 6 new StimulusLazyControllerHandler(application, lazyControllers).start(); 7}; 8const startStimulusApp = () => { 9 const application = Application.start(); 10 application.debug = isApplicationDebug; 11 loadControllers(application, eagerControllers, lazyControllers); 12 return application; 13}; 14var StimulusLazyControllerHandler = class { 15 application; 16 lazyControllers; 17 constructor(application, lazyControllers) { 18 this.application = application; 19 this.lazyControllers = lazyControllers; 20 } 21 start() { 22 this.lazyLoadExistingControllers(document.documentElement); 23 this.lazyLoadNewControllers(document.documentElement); 24 } 25 lazyLoadExistingControllers(element) { 26 Array.from(element.querySelectorAll(`[${controllerAttribute}]`)).flatMap(extractControllerNamesFrom).forEach((controllerName) => { 27 this.loadLazyController(controllerName); 28 }); 29 } 30 loadLazyController(name) { 31 if (!this.lazyControllers[name]) return; 32 const controllerLoader = this.lazyControllers[name]; 33 delete this.lazyControllers[name]; 34 if (!canRegisterController(name, this.application)) return; 35 this.application.logDebugActivity(name, "lazy:loading");
36 controllerLoader().then((controllerModule) => { 37 this.application.logDebugActivity(name, "lazy:loaded"); 38 registerController(name, controllerModule.default, this.application); 39 }).catch((error) => { 40 console.error(`Error loading controller "${name}":`, error); 41 }); 42 } 43 lazyLoadNewControllers(element) { 44 if (Object.keys(this.lazyControllers).length === 0) return; 45 const observer = new MutationObserver((mutationsList) => { 46 for (const { attributeName, target, type } of mutationsList) switch (type) { 47 case "attributes": 48 if (attributeName === controllerAttribute && target.getAttribute(controllerAttribute)) extractControllerNamesFrom(target).forEach((controllerName) => { 49 this.loadLazyController(controllerName); 50 }); 51 break; 52 case "childList": this.lazyLoadExistingControllers(target); 53 } 54 if (Object.keys(this.lazyControllers).length === 0) observer.disconnect(); 55 }); 56 observer.observe(element, { 57 attributeFilter: [controllerAttribute], 58 subtree: true, 59 childList: true 60 }); 61 } 62}; 63function registerController(name, controller, application) { 64 if (canRegisterController(name, application)) application.register(name, controller); 65} 66function extractControllerNamesFrom(element) { 67 const controllerNameValue = element.getAttribute(controllerAttribute); 68 if (!controllerNameValue) return []; 69 return controllerNameValue.split(/\s+/).filter((content) => content.length); 70} 71function canRegisterController(name, application) { 72 return !application.router.modulesByIdentifier.has(name); 73} 74export { loadControllers, startStimulusApp };
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.