@@ -126,24 +126,29 @@ export default function({ directive, magic, reactive }) {
126126 }
127127
128128 function process_link ( ) {
129- const is_blank = ( el . getAttribute ( "target" ) ?? "" ) . indexOf ( "_blank" ) >= 0 ;
130- const unsubscribe = listen ( el , "click" , e => {
131- if ( e . metaKey
132- || e . altKey
133- || e . ctrlKey
134- || e . shiftKey
135- || e . defaultPrevented
136- || e . button > 0
137- || is_blank ) {
138- return ;
139- }
129+ let link = get_anchor_element ( el ) ;
130+ if ( link ) {
131+ el . _r_routerlink = link ;
132+
133+ const is_blank = ( link . getAttribute ( "target" ) ?? "" ) . indexOf ( "_blank" ) >= 0 ;
134+ const unsubscribe = listen ( link , "click" , e => {
135+ if ( e . metaKey
136+ || e . altKey
137+ || e . ctrlKey
138+ || e . shiftKey
139+ || e . defaultPrevented
140+ || e . button > 0
141+ || is_blank ) {
142+ return ;
143+ }
140144
141- e . preventDefault ( ) ;
145+ e . preventDefault ( ) ;
142146
143- router . navigate ( `${ el . pathname } ${ el . search } ${ el . hash } ` ) ;
144- } ) ;
147+ router . navigate ( `${ link . pathname } ${ link . search } ${ link . hash } ` ) ;
148+ } ) ;
145149
146- cleanup ( unsubscribe ) ;
150+ cleanup ( unsubscribe ) ;
151+ }
147152 }
148153
149154 function process_outlet ( ) {
@@ -161,11 +166,59 @@ export default function({ directive, magic, reactive }) {
161166
162167 magic ( "active" , el => {
163168 const router = closest ( el , node => node . _r_router ) ?. _r_router ;
169+ if ( is_nullish ( router ) ) {
170+ warn ( "No x-router directive found" ) ;
171+ return false ;
172+ }
164173
165- if ( ! is_nullish ( router ) ) {
166- return router . history . resolve ( el . href ) === router . values . path ;
174+ //
175+ // Create a dependency on router.values
176+ //
177+ JSON . stringify ( router . values ) ;
178+
179+ const link = is_anchor_element ( el ) ? el : closest ( el , node => node . _r_routerlink ) ?. _r_routerlink ;
180+
181+ //
182+ // The issue is that the router:link directive is processed later than x-bind,
183+ // and if $active is used in x-bind, we won’t find node._r_routerlink.
184+ // Therefore, we delay execution and try again.
185+ //
186+ // <div x-router:link :class="{ active: $active }">
187+ // ...
188+ // </div>
189+ //
190+
191+ if ( link ) {
192+ return router . history . resolve ( link . href ) === router . values . path ;
167193 }
168194
169- warn ( "No x-router directive found" ) ;
195+ if ( el . _r_routerlink_init ) {
196+ warn ( `x-router:link directive not found` , el ) ;
197+ }
198+ else {
199+ queueMicrotask ( ( ) => {
200+ el . _r_routerlink_init = true ;
201+ //
202+ // Force an upate
203+ //
204+ router . values . path = router . values . path ;
205+ } ) ;
206+ }
207+
208+ return false ;
170209 } ) ;
171210}
211+
212+ function is_anchor_element ( el ) {
213+ return el . tagName . toUpperCase ( ) === "A" ;
214+ }
215+
216+ function get_anchor_element ( el ) {
217+ if ( is_anchor_element ( el ) ) {
218+ return el ;
219+ }
220+
221+ const links = el . querySelectorAll ( "a" ) ;
222+ links . length !== 1 && warn ( `Expected exactly one link, but found ${ links . length } ` ) ;
223+ return links [ 0 ] ;
224+ }
0 commit comments