@@ -443,105 +443,118 @@ function* genChildElements(
443443/**
444444 * Get the parent elements.
445445 */
446- function * genParentElements (
446+ function genParentElements (
447447 elements : AST . VElement [ ] ,
448448) : IterableIterator < AST . VElement > {
449- const found = new Set < AST . VElement > ( )
450- for ( const element of elements ) {
451- const parent = getParentElement ( element )
452- if ( parent ) {
453- if ( ! found . has ( parent ) ) {
454- yield parent
455- found . add ( parent )
456- }
449+ return iterateUnique ( function * ( ) {
450+ for ( const element of elements ) {
451+ yield getParentElement ( element )
457452 }
458- }
453+ } )
459454}
460455
461456/**
462457 * Get the adjacent sibling elements.
463458 */
464- function * genAdjacentSiblingElements (
459+ function genAdjacentSiblingElements (
465460 elements : AST . VElement [ ] ,
466461) : IterableIterator < AST . VElement > {
467- for ( const element of elements ) {
468- const parent = getParentElement ( element )
469- if ( parent == null ) {
470- continue
471- }
472- const children = [ ...genChildElements ( [ parent ] ) ]
473- const index = children . indexOf ( element )
474- const e = children [ index + 1 ]
475- if ( e ) {
476- yield e
462+ return iterateUnique ( function * ( ) {
463+ for ( const element of elements ) {
464+ if ( hasVFor ( element ) ) {
465+ yield element
466+ }
467+ const vForTemplate = getVForTemplate ( element )
468+ if ( vForTemplate ) {
469+ const children = [ ...genChildElements ( [ vForTemplate ] ) ]
470+ const index = children . indexOf ( element )
471+ yield children [ index + 1 ] || children [ 0 ]
472+ }
473+ const parent = getParentElement ( element )
474+ if ( parent ) {
475+ const children = [ ...genChildElements ( [ parent ] ) ]
476+ const index = children . indexOf ( element )
477+ yield children [ index + 1 ]
478+ }
477479 }
478- }
480+ } )
479481}
480482
481483/**
482484 * Gets the previous adjacent sibling elements.
483485 */
484- function * genPrevAdjacentSiblingElements (
486+ function genPrevAdjacentSiblingElements (
485487 elements : AST . VElement [ ] ,
486488) : IterableIterator < AST . VElement > {
487- for ( const element of elements ) {
488- const parent = getParentElement ( element )
489- if ( parent == null ) {
490- continue
491- }
492- const children = [ ...genChildElements ( [ parent ] ) ]
493- const index = children . indexOf ( element )
494- const e = children [ index - 1 ]
495- if ( e ) {
496- yield e
489+ return iterateUnique ( function * ( ) {
490+ for ( const element of elements ) {
491+ if ( hasVFor ( element ) ) {
492+ yield element
493+ }
494+ const vForTemplate = getVForTemplate ( element )
495+ if ( vForTemplate ) {
496+ const children = [ ...genChildElements ( [ vForTemplate ] ) ]
497+ const index = children . indexOf ( element )
498+ yield children [ index - 1 ] || children [ children . length - 1 ]
499+ }
500+ const parent = getParentElement ( element )
501+ if ( parent ) {
502+ const children = [ ...genChildElements ( [ parent ] ) ]
503+ const index = children . indexOf ( element )
504+ yield children [ index - 1 ]
505+ }
497506 }
498- }
507+ } )
499508}
500509
501510/**
502511 * Gets the general sibling elements.
503512 */
504- function * genGeneralSiblingElements (
513+ function genGeneralSiblingElements (
505514 elements : AST . VElement [ ] ,
506515) : IterableIterator < AST . VElement > {
507- const found = new Set < AST . VElement > ( )
508- for ( const element of elements ) {
509- const parent = getParentElement ( element )
510- if ( parent == null ) {
511- continue
512- }
513- const children = [ ...genChildElements ( [ parent ] ) ]
514- const index = children . indexOf ( element )
515- for ( const n of children . slice ( index + 1 ) ) {
516- if ( ! found . has ( n ) ) {
517- yield n
518- found . add ( n )
516+ return iterateUnique ( function * ( ) {
517+ for ( const element of elements ) {
518+ if ( hasVFor ( element ) ) {
519+ yield element
520+ }
521+ const vForTemplate = getVForTemplate ( element )
522+ if ( vForTemplate ) {
523+ yield * genChildElements ( [ vForTemplate ] )
524+ }
525+ const parent = getParentElement ( element )
526+ if ( parent ) {
527+ const children = [ ...genChildElements ( [ parent ] ) ]
528+ const index = children . indexOf ( element )
529+ yield * children . slice ( index + 1 )
519530 }
520531 }
521- }
532+ } )
522533}
523534
524535/**
525536 * Gets the previous general sibling elements.
526537 */
527- function * genPrevGeneralSiblingElements (
538+ function genPrevGeneralSiblingElements (
528539 elements : AST . VElement [ ] ,
529540) : IterableIterator < AST . VElement > {
530- const found = new Set < AST . VElement > ( )
531- for ( const element of elements ) {
532- const parent = getParentElement ( element )
533- if ( parent == null ) {
534- continue
535- }
536- const children = [ ...genChildElements ( [ parent ] ) ]
537- const index = children . indexOf ( element )
538- for ( const p of children . slice ( 0 , index ) ) {
539- if ( ! found . has ( p ) ) {
540- yield p
541- found . add ( p )
541+ return iterateUnique ( function * ( ) {
542+ for ( const element of elements ) {
543+ if ( hasVFor ( element ) ) {
544+ yield element
545+ }
546+ const vForTemplate = getVForTemplate ( element )
547+ if ( vForTemplate ) {
548+ yield * genChildElements ( [ vForTemplate ] )
549+ }
550+ const parent = getParentElement ( element )
551+ if ( parent ) {
552+ const children = [ ...genChildElements ( [ parent ] ) ]
553+ const index = children . indexOf ( element )
554+ yield * children . slice ( 0 , index )
542555 }
543556 }
544- }
557+ } )
545558}
546559
547560/**
@@ -556,16 +569,11 @@ function* genVDeepElements(
556569 ) => AST . VElement [ ] ,
557570) : IterableIterator < AST . VElement > {
558571 if ( params . length ) {
559- const found = new Set < AST . VElement > ( )
560- for ( const node of params ) {
561- const els = query ( elements , node . nodes )
562- for ( const e of els ) {
563- if ( ! found . has ( e ) ) {
564- yield e
565- found . add ( e )
566- }
572+ yield * iterateUnique ( function * ( ) {
573+ for ( const node of params ) {
574+ yield * query ( elements , node . nodes )
567575 }
568- }
576+ } )
569577 } else {
570578 yield * elements
571579 }
@@ -574,33 +582,30 @@ function* genVDeepElements(
574582/**
575583 * Gets the v-slotted elements
576584 */
577- function * genVSlottedElements (
585+ function genVSlottedElements (
578586 elements : AST . VElement [ ] ,
579587 params : VCSSSelector [ ] ,
580588 query : (
581589 els : AST . VElement [ ] ,
582590 selList : VCSSSelectorValueNode [ ] ,
583591 ) => AST . VElement [ ] ,
584592) : IterableIterator < AST . VElement > {
585- const found = new Set < AST . VElement > ( )
586- for ( const element of elements ) {
587- if ( isSlotElement ( element ) ) {
588- if ( ! found . has ( element ) ) {
593+ return iterateUnique ( function * ( ) {
594+ for ( const element of elements ) {
595+ if ( isSlotElement ( element ) ) {
589596 yield element
590- found . add ( element )
591597 }
592598 }
593- }
594599
595- for ( const node of params ) {
596- const els = query ( elements , node . nodes )
597- for ( const e of els ) {
598- if ( ! found . has ( e ) && inSlot ( e ) ) {
599- yield e
600- found . add ( e )
600+ for ( const node of params ) {
601+ const els = query ( elements , node . nodes )
602+ for ( const e of els ) {
603+ if ( inSlot ( e ) ) {
604+ yield e
605+ }
601606 }
602607 }
603- }
608+ } )
604609
605610 /**
606611 * Checks if givin element within slot
@@ -616,7 +621,7 @@ function* genVSlottedElements(
616621/**
617622 * Gets the v-global elements
618623 */
619- function * genVGlobalElements (
624+ function genVGlobalElements (
620625 _elements : AST . VElement [ ] ,
621626 params : VCSSSelector [ ] ,
622627 document : VueDocumentQueryContext ,
@@ -625,16 +630,11 @@ function* genVGlobalElements(
625630 selList : VCSSSelectorValueNode [ ] ,
626631 ) => AST . VElement [ ] ,
627632) : IterableIterator < AST . VElement > {
628- const found = new Set < AST . VElement > ( )
629- for ( const node of params ) {
630- const els = query ( document . elements , node . nodes )
631- for ( const e of els ) {
632- if ( ! found . has ( e ) ) {
633- yield e
634- found . add ( e )
635- }
633+ return iterateUnique ( function * ( ) {
634+ for ( const node of params ) {
635+ yield * query ( document . elements , node . nodes )
636636 }
637- }
637+ } )
638638}
639639
640640/**
@@ -1035,3 +1035,44 @@ function withinTemplate(
10351035 templateRange [ 0 ] <= expr . range [ 0 ] && expr . range [ 1 ] <= templateRange [ 1 ]
10361036 )
10371037}
1038+
1039+ /**
1040+ * Iterate unique items
1041+ */
1042+ function * iterateUnique < T > (
1043+ gen : ( ) => IterableIterator < T | null > ,
1044+ ) : IterableIterator < T > {
1045+ const found = new Set < T > ( )
1046+ for ( const e of gen ( ) ) {
1047+ if ( e != null && ! found . has ( e ) ) {
1048+ yield e
1049+ found . add ( e )
1050+ }
1051+ }
1052+ }
1053+
1054+ /**
1055+ * Checks if givin element has v-for
1056+ */
1057+ function hasVFor ( element : AST . VElement ) {
1058+ return element . startTag . attributes . some (
1059+ ( attr ) => attr . directive && attr . key . name . name === "for" ,
1060+ )
1061+ }
1062+
1063+ /**
1064+ * Get the <template v-for> from givin element within
1065+ */
1066+ function getVForTemplate ( element : AST . VElement ) {
1067+ let parent = element . parent
1068+ while ( parent ) {
1069+ if ( parent . type !== "VElement" || parent . name !== "template" ) {
1070+ return null
1071+ }
1072+ if ( hasVFor ( parent ) ) {
1073+ return parent
1074+ }
1075+ parent = parent . parent
1076+ }
1077+ return null
1078+ }
0 commit comments