1// FIXME: es-module-shim won't shim the dynamic import without this explicit import 2import "@hotwired/stimulus" 3 4const controllerAttribute = "data-controller" 5const registeredControllers = {} 6 7// Eager load all controllers registered beneath the `under` path in the import map to the passed application instance. 8export function eagerLoadControllersFrom(under, application) { 9 const paths = Object.keys(parseImportmapJson()).filter(path => path.match(new RegExp(`^${under}/.*_controller$`))) 10 paths.forEach(path => registerControllerFromPath(path, under, application)) 11} 12 13function parseImportmapJson() { 14 return JSON.parse(document.querySelector("script[type=importmap]").text).imports 15} 16 17function registerControllerFromPath(path, under, application) { 18 const name = path 19 .replace(new RegExp(`^${under}/`), "") 20 .replace("_controller", "") 21 .replace(/\//g, "--") 22 .replace(/_/g, "-") 23 24 if (!(name in registeredControllers)) { 25 import(path) 26 .then(module => registerController(name, module, application)) 27 .catch(error => console.error(`Failed to register controller: ${name} (${path})`, error)) 28 } 29} 30 31 32// Lazy load controllers registered beneath the `under` path in the import map to the passed application instance. 33export function lazyLoadControllersFrom(under, application, element = document) { 34 lazyLoadExistingControllers(under, application, element) 35 lazyLoadNewControllers(under, application, element) 36} 37 38function lazyLoadExistingControllers(under, application, element) { 39 queryControllerNamesWithin(element).forEach(controllerName => loadController(controllerName, under, application)) 40} 41 42function lazyLoadNewControllers(under, application, element) { 43 new MutationObserver((mutationsList) => { 44 for (const { attributeName, target, type } of mutationsList) { 45 switch (type) { 46 case "attributes": { 47 if (attributeName == controllerAttribute && target.getAttribute(controllerAttribute)) { 48 extractControllerNamesFrom(target).forEach(controllerName => loadController(controllerName, under, application)) 49 } 50 } 51 52 case "childList": { 53 lazyLoadExistingControllers(under, application, target) 54 } 55 } 56 } 57 }).observe(element, { attributeFilter: [controllerAttribute], subtree: true, childList: true }) 58} 59 60function queryControllerNamesWithin(element) { 61 return Array.from(element.querySelectorAll(`[${controllerAttribute}]`)).map(extractControllerNamesFrom).flat() 62} 63 64function extractControllerNamesFrom(element) { 65 return element.getAttribute(controllerAttribute).split(/\s+/).filter(content => content.length) 66} 67 68function loadController(name, under, application) { 69 if (!(name in registeredControllers)) { 70 import(controllerFilename(name, under)) 71 .then(module => registerController(name, module, application)) 72 .catch(error => console.error(`Failed to autoload controller: ${name}`, error)) 73 } 74} 75 76function controllerFilename(name, under) { 77 return `${under}/${name.replace(/--/g, "/").replace(/-/g, "_")}_controller` 78} 79 80function registerController(name, module, application) { 81 if (!(name in registeredControllers)) { 82 application.register(name, module.default) 83 registeredControllers[name] = true 84 } 85} 86;
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.