|
1 |
| -/** |
2 |
| - * Starts the Stimulus application and reads a map dump in the DOM to load controllers. |
3 |
| - * |
4 |
| - * Inspired by stimulus-loading.js from stimulus-rails. |
5 |
| - */ |
6 | 1 | import { Application } from '@hotwired/stimulus';
|
7 |
| -import { eagerControllers, lazyControllers, isApplicationDebug } from './controllers.js'; |
| 2 | +import { eagerControllers, isApplicationDebug, lazyControllers } from './controllers.js'; |
8 | 3 |
|
9 | 4 | const controllerAttribute = 'data-controller';
|
10 |
| - |
11 |
| -export const loadControllers = (application) => { |
12 |
| - // loop over the controllers map and require each controller |
| 5 | +const loadControllers = (application) => { |
13 | 6 | for (const name in eagerControllers) {
|
14 | 7 | registerController(name, eagerControllers[name], application);
|
15 | 8 | }
|
16 |
| - |
17 | 9 | loadLazyControllers(application);
|
18 | 10 | };
|
19 |
| - |
20 |
| -export const startStimulusApp = () => { |
| 11 | +const startStimulusApp = () => { |
21 | 12 | const application = Application.start();
|
22 | 13 | application.debug = isApplicationDebug;
|
23 |
| - |
24 | 14 | loadControllers(application);
|
25 |
| - |
26 | 15 | return application;
|
27 | 16 | };
|
28 |
| - |
29 | 17 | function registerController(name, controller, application) {
|
30 | 18 | if (canRegisterController(name, application)) {
|
31 |
| - application.register(name, controller) |
| 19 | + application.register(name, controller); |
32 | 20 | }
|
33 | 21 | }
|
34 |
| - |
35 | 22 | function loadLazyControllers(application) {
|
36 |
| - lazyLoadExistingControllers(application, document); |
37 |
| - lazyLoadNewControllers(application, document) |
| 23 | + lazyLoadExistingControllers(application, document.documentElement); |
| 24 | + lazyLoadNewControllers(application, document.documentElement); |
38 | 25 | }
|
39 |
| - |
40 | 26 | function lazyLoadExistingControllers(application, element) {
|
41 |
| - queryControllerNamesWithin(element).forEach(controllerName => loadController(controllerName, application)) |
| 27 | + queryControllerNamesWithin(element).forEach(controllerName => loadController(controllerName, application)); |
42 | 28 | }
|
43 | 29 | function queryControllerNamesWithin(element) {
|
44 |
| - return Array.from(element.querySelectorAll(`[${controllerAttribute}]`)).map(extractControllerNamesFrom).flat() |
| 30 | + return Array.from(element.querySelectorAll(`[${controllerAttribute}]`)).map(extractControllerNamesFrom).flat(); |
45 | 31 | }
|
46 | 32 | function extractControllerNamesFrom(element) {
|
47 |
| - return element.getAttribute(controllerAttribute).split(/\s+/).filter(content => content.length) |
| 33 | + const controllerNameValue = element.getAttribute(controllerAttribute); |
| 34 | + if (!controllerNameValue) { |
| 35 | + return []; |
| 36 | + } |
| 37 | + return controllerNameValue.split(/\s+/).filter(content => content.length); |
48 | 38 | }
|
49 | 39 | function lazyLoadNewControllers(application, element) {
|
50 |
| - new MutationObserver((mutationsList) => { |
51 |
| - for (const { attributeName, target, type } of mutationsList) { |
52 |
| - switch (type) { |
53 |
| - case 'attributes': { |
54 |
| - if (attributeName === controllerAttribute && target.getAttribute(controllerAttribute)) { |
55 |
| - extractControllerNamesFrom(target).forEach(controllerName => loadController(controllerName, application)) |
56 |
| - } |
57 |
| - } |
58 |
| - |
59 |
| - case 'childList': { |
60 |
| - lazyLoadExistingControllers(application, target) |
| 40 | + new MutationObserver((mutationsList) => { |
| 41 | + for (const { attributeName, target, type } of mutationsList) { |
| 42 | + switch (type) { |
| 43 | + case 'attributes': { |
| 44 | + if (attributeName === controllerAttribute && target.getAttribute(controllerAttribute)) { |
| 45 | + extractControllerNamesFrom(target).forEach(controllerName => loadController(controllerName, application)); |
| 46 | + } |
| 47 | + break; |
| 48 | + } |
| 49 | + case 'childList': { |
| 50 | + lazyLoadExistingControllers(application, target); |
| 51 | + } |
| 52 | + } |
61 | 53 | }
|
62 |
| - } |
63 |
| - } |
64 |
| - }).observe(element, { attributeFilter: [controllerAttribute], subtree: true, childList: true }) |
| 54 | + }).observe(element, { |
| 55 | + attributeFilter: [controllerAttribute], |
| 56 | + subtree: true, |
| 57 | + childList: true, |
| 58 | + }); |
65 | 59 | }
|
66 |
| -function canRegisterController(name, application){ |
67 |
| - return !application.router.modulesByIdentifier.has(name) |
| 60 | +function canRegisterController(name, application) { |
| 61 | + return !application.router.modulesByIdentifier.has(name); |
68 | 62 | }
|
69 |
| - |
70 | 63 | async function loadController(name, application) {
|
71 | 64 | if (canRegisterController(name, application)) {
|
72 | 65 | if (lazyControllers[name] === undefined) {
|
73 | 66 | console.error(`Failed to autoload controller: ${name}`);
|
74 | 67 | }
|
75 |
| - |
76 | 68 | const controllerModule = await (lazyControllers[name]());
|
77 |
| - |
78 | 69 | registerController(name, controllerModule.default, application);
|
79 | 70 | }
|
80 | 71 | }
|
| 72 | + |
| 73 | +export { loadControllers, startStimulusApp }; |
0 commit comments