@@ -64,40 +64,61 @@ class StimulusLazyControllerHandler {
6464 }
6565
6666 private lazyLoadExistingControllers ( element : Element ) {
67- this . queryControllerNamesWithin ( element ) . forEach ( ( controllerName ) => this . loadLazyController ( controllerName ) ) ;
67+ Array . from ( element . querySelectorAll ( `[${ controllerAttribute } ]` ) )
68+ . flatMap ( extractControllerNamesFrom )
69+ . forEach ( ( controllerName ) => this . loadLazyController ( controllerName ) ) ;
6870 }
6971
70- private async loadLazyController ( name : string ) {
71- if ( canRegisterController ( name , this . application ) ) {
72- if ( this . lazyControllers [ name ] === undefined ) {
73- return ;
74- }
72+ private loadLazyController ( name : string ) {
73+ if ( ! this . lazyControllers [ name ] ) {
74+ return ;
75+ }
7576
76- const controllerModule = await this . lazyControllers [ name ] ( ) ;
77+ // Delete the loader to avoid loading it twice
78+ const controllerLoader = this . lazyControllers [ name ] ;
79+ delete this . lazyControllers [ name ] ;
7780
78- registerController ( name , controllerModule . default , this . application ) ;
81+ if ( ! canRegisterController ( name , this . application ) ) {
82+ return ;
7983 }
84+
85+ this . application . logDebugActivity ( name , 'lazy:loading' ) ;
86+
87+ controllerLoader ( )
88+ . then ( ( controllerModule ) => {
89+ this . application . logDebugActivity ( name , 'lazy:loaded' ) ;
90+ registerController ( name , controllerModule . default , this . application ) ;
91+ } )
92+ . catch ( ( error ) => {
93+ console . error ( `Error loading controller "${ name } ":` , error ) ;
94+ } ) ;
8095 }
8196
8297 private lazyLoadNewControllers ( element : Element ) {
98+ if ( Object . keys ( this . lazyControllers ) . length === 0 ) {
99+ return ;
100+ }
83101 new MutationObserver ( ( mutationsList ) => {
84- for ( const { attributeName , target , type } of mutationsList ) {
85- switch ( type ) {
86- case 'attributes ' : {
87- if (
88- attributeName === controllerAttribute &&
89- ( target as Element ) . getAttribute ( controllerAttribute )
90- ) {
91- extractControllerNamesFrom ( target as Element ) . forEach ( ( controllerName ) =>
92- this . loadLazyController ( controllerName )
93- ) ;
102+ for ( const mutation of mutationsList ) {
103+ switch ( mutation . type ) {
104+ case 'childList ' : {
105+ // @ts -ignore
106+ for ( const node of mutation . addedNodes ) {
107+ if ( node instanceof Element ) {
108+ extractControllerNamesFrom ( node ) . forEach ( ( controllerName ) => {
109+ this . loadLazyController ( controllerName ) ;
110+ } ) ;
111+ }
94112 }
95-
96113 break ;
97114 }
98115
99- case 'childList' : {
100- this . lazyLoadExistingControllers ( target as Element ) ;
116+ case 'attributes' : {
117+ if ( mutation . attributeName === controllerAttribute ) {
118+ extractControllerNamesFrom ( mutation . target as Element ) . forEach ( ( controllerName ) =>
119+ this . loadLazyController ( controllerName )
120+ ) ;
121+ }
101122 }
102123 }
103124 }
@@ -107,10 +128,6 @@ class StimulusLazyControllerHandler {
107128 childList : true ,
108129 } ) ;
109130 }
110-
111- private queryControllerNamesWithin ( element : Element ) : string [ ] {
112- return Array . from ( element . querySelectorAll ( `[${ controllerAttribute } ]` ) ) . flatMap ( extractControllerNamesFrom ) ;
113- }
114131}
115132
116133function registerController ( name : string , controller : ControllerConstructor , application : Application ) {
0 commit comments