@@ -16,6 +16,20 @@ parser.addArgument("transition", "none", ["none", "css", "fade", "slide"]);
1616parser . addArgument ( "effect-duration" , "fast" ) ;
1717parser . addArgument ( "effect-easing" , "swing" ) ;
1818
19+
20+ // A custom input event which differs from the one in `core/events` in that it
21+ // accepts a `detail` object to pass arbitrary information around.
22+ // TODO: The events in `core/events` should be refactored to accept a `detail`
23+ // object.
24+ const input_event = ( detail = { } ) => {
25+ return new CustomEvent ( "input" , {
26+ bubbles : true ,
27+ cancelable : false ,
28+ detail : detail ,
29+ } ) ;
30+ } ;
31+
32+
1933class Pattern extends BasePattern {
2034 static name = "depends" ;
2135 static trigger = ".pat-depends" ;
@@ -44,7 +58,14 @@ class Pattern extends BasePattern {
4458 input ,
4559 "input" ,
4660 `pat-depends--input--${ this . uuid } ` ,
47- this . set_state . bind ( this )
61+ ( e ) => {
62+ if ( e ?. detail ?. pattern_uuid === this . uuid ) {
63+ // Ignore input events invoked from this pattern
64+ // instance to avoid infinite loops.
65+ return ;
66+ }
67+ this . set_state ( ) ;
68+ }
4869 ) ;
4970
5071 if ( input . form ) {
@@ -74,15 +95,40 @@ class Pattern extends BasePattern {
7495 enable ( ) {
7596 const inputs = dom . find_inputs ( this . el ) ;
7697 for ( const input of inputs ) {
98+ if ( input . disabled === false ) {
99+ // Do not re-enable an already enabled input.
100+ continue ;
101+ }
102+
103+ // Now, enable the input element.
77104 input . disabled = false ;
78- // Trigger the input after disabling so that any other bound
105+
106+ if ( input === this . el ) {
107+ // Do not re-trigger this pattern on it's own element to avoid
108+ // infinite loops.
109+ continue ;
110+ }
111+
112+ if ( dom . is_button ( input ) ) {
113+ // Do not trigger the input event on buttons as they do not
114+ // support it.
115+ continue ;
116+ }
117+
118+ // Trigger the input after enabling so that any other bound
79119 // actions can react on that.
80- input . dispatchEvent ( events . input_event ( ) ) ;
120+ input . dispatchEvent ( input_event ( { pattern_uuid : this . uuid } ) ) ;
81121 }
122+
123+ // Restore the original click behavior for anchor elements.
82124 if ( this . el . tagName === "A" ) {
83125 events . remove_event_listener ( this . el , "pat-depends--click" ) ;
84126 }
127+
128+ // Remove the disabled class from the element.
85129 this . el . classList . remove ( "disabled" ) ;
130+
131+ // Trigger the pat-update event to notify other patterns about enabling.
86132 this . $el . trigger ( "pat-update" , {
87133 pattern : "depends" ,
88134 action : "attribute-changed" ,
@@ -94,17 +140,42 @@ class Pattern extends BasePattern {
94140 disable ( ) {
95141 const inputs = dom . find_inputs ( this . el ) ;
96142 for ( const input of inputs ) {
143+ if ( input . disabled === true ) {
144+ // Do not re-disable an already disabled input.
145+ continue ;
146+ }
147+
148+ // Now, disable the input element.
97149 input . disabled = true ;
150+
151+ if ( input === this . el ) {
152+ // Do not re-trigger this pattern on it's own element to avoid
153+ // infinite loops.
154+ continue ;
155+ }
156+
157+ if ( dom . is_button ( input ) ) {
158+ // Do not trigger the input event on buttons as they do not
159+ // support it.
160+ continue ;
161+ }
162+
98163 // Trigger the input after disabling so that any other bound
99164 // actions can react on that.
100- input . dispatchEvent ( events . input_event ( ) ) ;
165+ input . dispatchEvent ( input_event ( { pattern_uuid : this . uuid } ) ) ;
101166 }
167+
168+ // Prevent the default click behavior for anchor elements.
102169 if ( this . el . tagName === "A" ) {
103170 events . add_event_listener ( this . el , "click" , "pat-depends--click" , ( e ) =>
104171 e . preventDefault ( )
105172 ) ;
106173 }
174+
175+ // Add the disabled class to the element.
107176 this . el . classList . add ( "disabled" ) ;
177+
178+ // Trigger the pat-update event to notify other patterns about disabling.
108179 this . $el . trigger ( "pat-update" , {
109180 pattern : "depends" ,
110181 action : "attribute-changed" ,
0 commit comments