11import type { Options as SwupOptions , Handler } from 'swup' ;
2- import { nextTick } from 'swup' ;
2+ import { forceReflow } from 'swup' ;
33import Plugin from '@swup/plugin' ;
44
55declare module 'swup' {
6- export interface AnimationContext {
6+ export interface VisitAnimation {
77 /** Parallel visit: run in and out animation at the same time */
88 parallel ?: boolean ;
99 }
@@ -44,55 +44,46 @@ export default class SwupParallelPlugin extends Plugin {
4444 }
4545
4646 // On visit: check for containers and mark as parallel visit
47- this . swup . hooks . on ( 'visit:start' , this . startVisit , { priority : 1 } ) ;
48- // When awaiting animation: skip if not in animation phase
49- this . swup . hooks . replace ( 'animation:await' , this . maybeSkipAnimation ) ;
47+ // Run after user hooks to allow disabling parallel animations beforehand
48+ this . on ( 'visit:start' , this . startVisit , { priority : 1 } ) ;
49+ // Before awaiting out animation: skip
50+ this . before ( 'animation:out:await' , this . skipOutAnimation , { priority : 1 } ) ;
5051 // Before content replace: insert new containers
51- this . swup . hooks . before ( 'content:replace' , this . insertContainers ) ;
52- // After content replace: reset containers in context object
53- this . swup . hooks . on ( 'content:replace' , this . resetContainers ) ;
52+ this . before ( 'content:replace' , this . insertContainers , { priority : 1 } ) ;
53+ // After content replace: reset containers
54+ this . on ( 'content:replace' , this . resetContainers ) ;
5455 // After visit: remove old containers
55- this . swup . hooks . on ( 'visit:end' , this . cleanupContainers ) ;
56+ this . on ( 'visit:end' , this . cleanupContainers ) ;
5657 }
5758
58- unmount ( ) {
59- this . swup . hooks . off ( 'visit:start' , this . startVisit ) ;
60- this . swup . hooks . off ( 'animation:await' , this . maybeSkipAnimation ) ;
61- this . swup . hooks . off ( 'content:replace' , this . insertContainers ) ;
62- this . swup . hooks . off ( 'content:replace' , this . resetContainers ) ;
63- this . swup . hooks . off ( 'visit:end' , this . cleanupContainers ) ;
64- }
65-
66- startVisit : Handler < 'visit:start' > = ( context ) => {
67- const { animate, parallel } = context . animation ;
59+ startVisit : Handler < 'visit:start' > = ( visit ) => {
60+ const { animate, parallel } = visit . animation ;
6861 const { containers } = this . options ;
6962 if ( ! animate || parallel === false ) {
70- console . log ( 'Not animated or parallel disabled' ) ;
7163 return ;
7264 }
73-
7465 // Only mark as parallel visit if containers found
75- const hasContainers = containers . some ( ( selector ) => document . querySelector ( selector ) ) ;
76- console . log ( 'Checking for parallel containers' , hasContainers , containers ) ;
66+ const hasContainers = containers . some ( ( selector ) => {
67+ const el = document . querySelector ( selector )
68+ if ( ! el ) return false ;
69+ return visit . containers . some ( s => el . matches ( s ) ) ;
70+ } ) ;
7771 if ( hasContainers ) {
78- context . animation . wait = true ;
79- context . animation . parallel = true ;
72+ visit . animation . wait = true ;
73+ visit . animation . parallel = true ;
8074 }
8175 } ;
8276
83- maybeSkipAnimation : Handler < 'animation:await' > = ( context , args , defaultHandler ) => {
84- const { animate, parallel } = context . animation ;
85- const { direction } = args ;
86- const isAnimationPhase = 'in' === direction ;
87- if ( animate && parallel && ! isAnimationPhase ) {
88- return Promise . resolve ( ) ;
77+ skipOutAnimation : Handler < 'animation:out:await' > = ( visit , args ) => {
78+ const { animate, parallel } = visit . animation ;
79+ if ( animate && parallel ) {
80+ args . skip = true ;
8981 }
90- return defaultHandler ?.( context , args ) ;
9182 } ;
9283
93- insertContainers : Handler < 'content:replace' > = ( context , args ) => {
94- const { animate, parallel } = context . animation ;
95- const { containers } = context ;
84+ insertContainers : Handler < 'content:replace' > = ( visit , args ) => {
85+ const { animate, parallel } = visit . animation ;
86+ const { containers } = visit ;
9687 const { page } = args ;
9788
9889 if ( ! animate || ! parallel ) {
@@ -125,26 +116,22 @@ export default class SwupParallelPlugin extends Plugin {
125116 previous . before ( next ) ;
126117
127118 next . classList . add ( 'is-next-container' ) ;
128- this . forceReflow ( next ) ;
119+ forceReflow ( next ) ;
129120 next . classList . remove ( 'is-next-container' ) ;
130121 previous . classList . add ( 'is-previous-container' ) ;
131122 } ) ;
132123
133- console . log ( 'containersInParallel' , containersInParallel ) ;
134- console . log ( 'containersInSeries' , containersInSeries ) ;
135- console . log ( 'parallelContainers' , parallelContainers ) ;
136-
137124 this . originalContainers = defaultContainers ;
138- context . containers = containersInSeries ;
125+ visit . containers = containersInSeries ;
139126 } ;
140127
141- resetContainers : Handler < 'content:replace' > = ( context ) => {
142- const { animate, parallel } = context . animation ;
128+ resetContainers : Handler < 'content:replace' > = ( visit ) => {
129+ const { animate, parallel } = visit . animation ;
143130 if ( ! animate || ! parallel ) {
144131 return ;
145132 }
146133
147- context . containers = this . originalContainers ;
134+ visit . containers = this . originalContainers ;
148135 } ;
149136
150137 cleanupContainers = ( ) => {
@@ -156,16 +143,10 @@ export default class SwupParallelPlugin extends Plugin {
156143
157144 parseContainers ( { html } : { html : string } ) : ContainerSet [ ] {
158145 const incomingDocument = new DOMParser ( ) . parseFromString ( html , 'text/html' ) ;
159- return this . options . containers
160- . reduce ( ( containers , selector : string ) => {
161- const previous = document . querySelector < HTMLElement > ( selector ) ;
162- const next = incomingDocument . querySelector < HTMLElement > ( selector ) ;
163- return previous && next ? [ ...containers , { previous, next } ] : containers ;
164- } , [ ] as ContainerSet [ ] ) ;
165- }
166-
167- forceReflow ( element ?: HTMLElement ) {
168- element = element || document . body ;
169- return element ?. offsetHeight ;
146+ return this . options . containers . reduce ( ( containers , selector : string ) => {
147+ const previous = document . querySelector < HTMLElement > ( selector ) ;
148+ const next = incomingDocument . querySelector < HTMLElement > ( selector ) ;
149+ return previous && next ? [ ...containers , { previous, next } ] : containers ;
150+ } , [ ] as ContainerSet [ ] ) ;
170151 }
171152}
0 commit comments