From 08e7cae7911352aa47cf90d43921eafe90858002 Mon Sep 17 00:00:00 2001 From: Aditya Dhade Date: Fri, 9 Jan 2026 02:03:44 +0530 Subject: [PATCH 1/5] Add support for chronological and pagination transitions Co-authored-by: Felix Arntz --- plugins/view-transitions/includes/theme.php | 123 ++++++++++++- plugins/view-transitions/js/types.ts | 4 + .../view-transitions/js/view-transitions.js | 162 +++++++++++++++++- 3 files changed, 279 insertions(+), 10 deletions(-) diff --git a/plugins/view-transitions/includes/theme.php b/plugins/view-transitions/includes/theme.php index fb2ad15ada..f1d7dae417 100644 --- a/plugins/view-transitions/includes/theme.php +++ b/plugins/view-transitions/includes/theme.php @@ -66,18 +66,22 @@ function plvt_sanitize_view_transitions_theme_support(): void { $args = $_wp_theme_features['view-transitions']; $defaults = array( - 'post-selector' => '.wp-block-post.post, article.post, body.single main', - 'global-transition-names' => array( + 'post-selector' => '.wp-block-post.post, article.post, body.single main', + 'global-transition-names' => array( 'header' => 'header', 'main' => 'main', ), - 'post-transition-names' => array( + 'post-transition-names' => array( '.wp-block-post-title, .entry-title' => 'post-title', '.wp-post-image' => 'post-thumbnail', '.wp-block-post-content, .entry-content' => 'post-content', ), - 'default-animation' => 'fade', - 'default-animation-duration' => 400, + 'default-animation' => 'fade', + 'default-animation-duration' => 400, + 'chronological-forwards-animation' => false, + 'chronological-backwards-animation' => false, + 'pagination-forwards-animation' => false, + 'pagination-backwards-animation' => false, ); // If no specific `$args` were provided, simply use the defaults. @@ -102,8 +106,21 @@ function plvt_sanitize_view_transitions_theme_support(): void { if ( ! is_array( $args['post-transition-names'] ) ) { $args['post-transition-names'] = array(); } - } + // If specific transition animations match the default animations, they are irrelevant. + if ( $args['chronological-forwards-animation'] === $args['default-animation'] ) { + $args['chronological-forwards-animation'] = false; + } + if ( $args['chronological-backwards-animation'] === $args['default-animation'] ) { + $args['chronological-backwards-animation'] = false; + } + if ( $args['pagination-forwards-animation'] === $args['default-animation'] ) { + $args['pagination-forwards-animation'] = false; + } + if ( $args['pagination-backwards-animation'] === $args['default-animation'] ) { + $args['pagination-backwards-animation'] = false; + } + } // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited $_wp_theme_features['view-transitions'] = $args; } @@ -324,7 +341,11 @@ function plvt_load_view_transitions(): void { */ if ( ( ! is_array( $theme_support['global-transition-names'] ) || count( $theme_support['global-transition-names'] ) === 0 ) && - ( ! is_array( $theme_support['post-transition-names'] ) || count( $theme_support['post-transition-names'] ) === 0 ) + ( ! is_array( $theme_support['post-transition-names'] ) || count( $theme_support['post-transition-names'] ) === 0 ) && + ! (bool) $theme_support['chronological-forwards-animation'] && + ! (bool) $theme_support['chronological-backwards-animation'] && + ! (bool) $theme_support['pagination-forwards-animation'] && + ! (bool) $theme_support['pagination-backwards-animation'] ) { return; } @@ -336,6 +357,34 @@ function plvt_load_view_transitions(): void { ), ); + $additional_transition_types = array( + 'chronological-forwards', + 'chronological-backwards', + 'pagination-forwards', + 'pagination-backwards', + ); + + foreach ( $additional_transition_types as $transition_type ) { + if ( isset( $theme_support[ $transition_type . '-animation' ] ) ) { + $additional_animation_args = isset( $theme_support[ $transition_type . '-animation-args' ] ) ? (array) $theme_support[ $transition_type . '-animation-args' ] : array(); + $additional_animation_stylesheet = $animation_registry->get_animation_stylesheet( $theme_support[ $transition_type . '-animation' ], $additional_animation_args ); + if ( '' !== $additional_animation_stylesheet ) { + wp_add_inline_style( + 'plvt-view-transitions', + plvt_scope_animation_stylesheet_to_transition_type( $additional_animation_stylesheet, $transition_type ) + ); + } + + $animations_js_config[ $transition_type ] = array( + 'useGlobalTransitionNames' => $animation_registry->use_animation_global_transition_names( $theme_support[ $transition_type . '-animation' ], $additional_animation_args ), + 'usePostTransitionNames' => $animation_registry->use_animation_post_transition_names( $theme_support[ $transition_type . '-animation' ], $additional_animation_args ), + 'targetName' => isset( $additional_animation_args['target-name'] ) ? $additional_animation_args['target-name'] : '*', // Special argument. + ); + } else { + $animations_js_config[ $transition_type ] = false; + } + } + $config = array( 'postSelector' => $theme_support['post-selector'], 'globalTransitionNames' => $theme_support['global-transition-names'], @@ -389,3 +438,63 @@ function plvt_inject_animation_duration( string $css, int $animation_duration ): return $css; } + +/** + * Scopes the given view transition animation CSS to apply only to a specific transition type. + * + * @since n.e.x.t + * @access private + * + * @param string $css Animation stylesheet as inline CSS. + * @param string $transition_type Transition type to scope the CSS to. + * @return string Scoped animation stylesheet. + */ +function plvt_scope_animation_stylesheet_to_transition_type( string $css, string $transition_type ): string { + $indent = static function ( string $input, $indent_tabs = 1 ): string { + return implode( + "\n", + array_map( + static function ( string $line ) use ( $indent_tabs ): string { + return str_repeat( "\t", $indent_tabs ) . $line; + }, + explode( "\n", $input ) + ) + ); + }; + + // This is very fragile, but it works well enough for now. TODO: Find a better solution to scope the CSS selectors. + if ( (bool) preg_match_all( '/(\s*)([^{}]+)\{[^{}]*?\}/m', $css, $matches ) ) { + // Wrap all `::view-transition-*` selectors to scope them to the transition type. + $view_transition_rule_pattern = '/::view-transition-/'; + + foreach ( $matches[0] as $index => $match ) { + $rule = $match; + $rule_name = $matches[2][ $index ]; + if ( (bool) preg_match( $view_transition_rule_pattern, $rule_name ) ) { + $rule_whitespace = $matches[1][ $index ]; + $prefixed_rule_name = preg_replace( $view_transition_rule_pattern, '&\0', $rule_name ); + if ( null === $prefixed_rule_name ) { + continue; + } + + $rule = str_replace( $rule_name, $prefixed_rule_name, $rule ); + + if ( str_contains( $rule, "\n" ) ) { // Non-minified. + $rule = $rule_whitespace . + "html:active-view-transition-type({$transition_type}) {\n" . + $indent( substr( $rule, strlen( $rule_whitespace ) ), 1 ) . + "\n}"; + } else { // Minified. + $rule = $rule_whitespace . + "html:active-view-transition-type({$transition_type}){" . + substr( $rule, strlen( $rule_whitespace ) ) . + '}'; + } + + // Replace the original rule with the wrapped/scoped one. + $css = str_replace( $match, $rule, $css ); + } + } + } + return $css; +} diff --git a/plugins/view-transitions/js/types.ts b/plugins/view-transitions/js/types.ts index c1509d37d4..1653b841c2 100644 --- a/plugins/view-transitions/js/types.ts +++ b/plugins/view-transitions/js/types.ts @@ -14,6 +14,10 @@ export type InitViewTransitionsFunction = ( config: ViewTransitionsConfig ) => void; +export type NavigationHistoryEntry = { + url: string; +}; + declare global { interface Window { plvtInitViewTransitions?: InitViewTransitionsFunction; diff --git a/plugins/view-transitions/js/view-transitions.js b/plugins/view-transitions/js/view-transitions.js index 485e7bba10..fe98730486 100644 --- a/plugins/view-transitions/js/view-transitions.js +++ b/plugins/view-transitions/js/view-transitions.js @@ -3,6 +3,7 @@ * @typedef {import("./types.ts").InitViewTransitionsFunction} InitViewTransitionsFunction * @typedef {import("./types.ts").PageSwapListenerFunction} PageSwapListenerFunction * @typedef {import("./types.ts").PageRevealListenerFunction} PageRevealListenerFunction + * @typedef {import("./types.ts").NavigationHistoryEntry} NavigationHistoryEntry */ /** @@ -133,6 +134,156 @@ window.plvtInitViewTransitions = ( config ) => { return articleLink.closest( config.postSelector ); }; + /** + * Determines the view transition type to use, given an old and new navigation history entry. + * + * @param {NavigationHistoryEntry|null} oldEntry Navigation history entry for the URL navigated from. + * @param {NavigationHistoryEntry} newEntry Navigation history entry for the URL navigated to. + * @return {string} View transition type (e.g. 'default', 'chronological-forwards', 'chronological-backwards'). + */ + const determineTransitionType = ( oldEntry, newEntry ) => { + if ( ! oldEntry || ! newEntry ) { + return 'default'; + } + + // Use 'default' transition type if all other transition types are disabled. + if ( + ! config.animations[ 'chronological-forwards' ] && + ! config.animations[ 'chronological-backwards' ] && + ! config.animations[ 'pagination-forwards' ] && + ! config.animations[ 'pagination-backwards' ] + ) { + return 'default'; + } + + const oldURL = new URL( oldEntry.url ); + const newURL = new URL( newEntry.url ); + + const oldPathname = oldURL.pathname; + const newPathname = newURL.pathname; + + if ( oldPathname === newPathname ) { + return 'default'; + } + + let oldPageMatches = null; + let newPageMatches = null; + let prefix = ''; + + // If enabled, check if the URLs are for a chronologically paginated archive. + if ( + config.animations[ 'chronological-forwards' ] || + config.animations[ 'chronological-backwards' ] + ) { + oldPageMatches = oldPathname.match( /\/page\/(\d+)\/?$/ ); + newPageMatches = newPathname.match( /\/page\/(\d+)\/?$/ ); + prefix = 'chronological-'; + } + + // If not, check if the URLs are for a multi-page post. + if ( + ! oldPageMatches && + ! newPageMatches && + ( config.animations[ 'pagination-forwards' ] || + config.animations[ 'pagination-backwards' ] ) + ) { + oldPageMatches = oldPathname.match( /\/(\d+)\/?$/ ); + newPageMatches = newPathname.match( /\/(\d+)\/?$/ ); + prefix = 'pagination-'; + } + // If there is a match on at least one of the URLs, compare whether their roots before the page segment match. + if ( oldPageMatches || newPageMatches ) { + const oldPageBase = oldPageMatches + ? oldPathname.substring( + 0, + oldPathname.length - oldPageMatches[ 0 ].length + ) + : oldPathname.replace( /\/$/, '' ); + const newPageBase = newPageMatches + ? newPathname.substring( + 0, + newPathname.length - newPageMatches[ 0 ].length + ) + : newPathname.replace( /\/$/, '' ); + + if ( oldPageBase === newPageBase ) { + // They belong to the same archive or post. + // Return the appropriate transition type, or 'default' if no particular animation is specified. + if ( oldPageMatches && newPageMatches ) { + if ( + Number( oldPageMatches[ 1 ] ) < + Number( newPageMatches[ 1 ] ) + ) { + return config.animations[ `${ prefix }forwards` ] + ? `${ prefix }forwards` + : 'default'; + } + return config.animations[ `${ prefix }backwards` ] + ? `${ prefix }backwards` + : 'default'; + } + if ( newPageMatches && Number( newPageMatches[ 1 ] ) > 1 ) { + return config.animations[ `${ prefix }forwards` ] + ? `${ prefix }forwards` + : 'default'; + } + if ( oldPageMatches && Number( oldPageMatches[ 1 ] ) > 1 ) { + return config.animations[ `${ prefix }backwards` ] + ? `${ prefix }backwards` + : 'default'; + } + } + } + + // If enabled, check if the URLs are for content labelled by date (e.g. navigation to previous/next post). + if ( + config.animations[ 'chronological-forwards' ] || + config.animations[ 'chronological-backwards' ] + ) { + const oldDateMatches = oldPathname.match( + /\/(\d{4})\/(\d{2})\/(\d{2})\/[^\/]+\/?$/ + ); + const newDateMatches = newPathname.match( + /\/(\d{4})\/(\d{2})\/(\d{2})\/[^\/]+\/?$/ + ); + if ( oldDateMatches && newDateMatches ) { + const oldPageBase = oldPathname.substring( + 0, + oldPathname.length - oldDateMatches[ 0 ].length + ); + const newPageBase = newPathname.substring( + 0, + newPathname.length - newDateMatches[ 0 ].length + ); + if ( oldPageBase === newPageBase ) { + // They belong to the same hierarchy. + const oldDate = new Date( + parseInt( oldDateMatches[ 1 ] ), + parseInt( oldDateMatches[ 2 ] ) - 1, + parseInt( oldDateMatches[ 3 ] ) + ); + const newDate = new Date( + parseInt( newDateMatches[ 1 ] ), + parseInt( newDateMatches[ 2 ] ) - 1, + parseInt( newDateMatches[ 3 ] ) + ); + if ( oldDate < newDate ) { + return config.animations[ 'chronological-forwards' ] + ? 'chronological-forwards' + : 'default'; + } + if ( oldDate > newDate ) { + return config.animations[ 'chronological-backwards' ] + ? 'chronological-backwards' + : 'default'; + } + } + } + } + + return 'default'; + }; + /** * Customizes view transition behavior on the URL that is being navigated from. * @@ -143,9 +294,11 @@ window.plvtInitViewTransitions = ( config ) => { 'pageswap', ( /** @type {PageSwapEvent} */ event ) => { if ( event.viewTransition ) { - const transitionType = 'default'; // Only 'default' is supported so far, but more to be added. + const transitionType = determineTransitionType( + event.activation.from, + event.activation.entry + ); event.viewTransition.types.add( transitionType ); - let viewTransitionEntries; if ( document.body.classList.contains( 'single' ) ) { viewTransitionEntries = getViewTransitionEntries( @@ -184,7 +337,10 @@ window.plvtInitViewTransitions = ( config ) => { 'pagereveal', ( /** @type {PageRevealEvent} */ event ) => { if ( event.viewTransition ) { - const transitionType = 'default'; // Only 'default' is supported so far, but more to be added. + const transitionType = determineTransitionType( + window.navigation.activation.from, + window.navigation.activation.entry + ); event.viewTransition.types.add( transitionType ); let viewTransitionEntries; From f51830674a55dd2b08fd358afbfd873c22d1b241 Mon Sep 17 00:00:00 2001 From: Aditya Dhade Date: Fri, 9 Jan 2026 02:42:05 +0530 Subject: [PATCH 2/5] Add options to settings for chronological and pagination transitions --- .../view-transitions/includes/settings.php | 46 +++++++++++++------ 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/plugins/view-transitions/includes/settings.php b/plugins/view-transitions/includes/settings.php index 4242dfc6de..f4d0df4d50 100644 --- a/plugins/view-transitions/includes/settings.php +++ b/plugins/view-transitions/includes/settings.php @@ -21,19 +21,22 @@ */ function plvt_get_view_transition_animation_labels(): array { return array( - 'fade' => _x( 'Fade (default)', 'animation label', 'view-transitions' ), - 'slide-from-right' => _x( 'Slide (from right)', 'animation label', 'view-transitions' ), - 'slide-from-left' => _x( 'Slide (from left)', 'animation label', 'view-transitions' ), - 'slide-from-bottom' => _x( 'Slide (from bottom)', 'animation label', 'view-transitions' ), - 'slide-from-top' => _x( 'Slide (from top)', 'animation label', 'view-transitions' ), - 'swipe-from-right' => _x( 'Swipe (from right)', 'animation label', 'view-transitions' ), - 'swipe-from-left' => _x( 'Swipe (from left)', 'animation label', 'view-transitions' ), - 'swipe-from-bottom' => _x( 'Swipe (from bottom)', 'animation label', 'view-transitions' ), - 'swipe-from-top' => _x( 'Swipe (from top)', 'animation label', 'view-transitions' ), - 'wipe-from-right' => _x( 'Wipe (from right)', 'animation label', 'view-transitions' ), - 'wipe-from-left' => _x( 'Wipe (from left)', 'animation label', 'view-transitions' ), - 'wipe-from-bottom' => _x( 'Wipe (from bottom)', 'animation label', 'view-transitions' ), - 'wipe-from-top' => _x( 'Wipe (from top)', 'animation label', 'view-transitions' ), + 'fade' => _x( 'Fade (default)', 'animation label', 'view-transitions' ), + 'slide-from-right' => _x( 'Slide (from right)', 'animation label', 'view-transitions' ), + 'slide-from-left' => _x( 'Slide (from left)', 'animation label', 'view-transitions' ), + 'slide-from-bottom' => _x( 'Slide (from bottom)', 'animation label', 'view-transitions' ), + 'slide-from-top' => _x( 'Slide (from top)', 'animation label', 'view-transitions' ), + 'slide-chronological-pagination' => _x( 'Slide (Chronological and Pagination)', 'animation label', 'view-transitions' ), + 'swipe-from-right' => _x( 'Swipe (from right)', 'animation label', 'view-transitions' ), + 'swipe-from-left' => _x( 'Swipe (from left)', 'animation label', 'view-transitions' ), + 'swipe-from-bottom' => _x( 'Swipe (from bottom)', 'animation label', 'view-transitions' ), + 'swipe-from-top' => _x( 'Swipe (from top)', 'animation label', 'view-transitions' ), + 'swipe-chronological-pagination' => _x( 'Swipe (Chronological and Pagination)', 'animation label', 'view-transitions' ), + 'wipe-from-right' => _x( 'Wipe (from right)', 'animation label', 'view-transitions' ), + 'wipe-from-left' => _x( 'Wipe (from left)', 'animation label', 'view-transitions' ), + 'wipe-from-bottom' => _x( 'Wipe (from bottom)', 'animation label', 'view-transitions' ), + 'wipe-from-top' => _x( 'Wipe (from top)', 'animation label', 'view-transitions' ), + 'wipe-chronological-pagination' => _x( 'Wipe (Chronological and Pagination)', 'animation label', 'view-transitions' ), ); } @@ -231,7 +234,22 @@ function plvt_apply_settings_to_theme_support(): void { // Apply the settings. $args['default-animation'] = $options['default_transition_animation']; $args['default-animation-duration'] = absint( $options['default_transition_animation_duration'] ); - $selector_options = array( + + // Automatically enable chronological and pagination animations for special animation options. + $chronological_pagination_animations = array( + 'slide-chronological-pagination' => 'slide', + 'swipe-chronological-pagination' => 'swipe', + 'wipe-chronological-pagination' => 'wipe', + ); + if ( isset( $chronological_pagination_animations[ $args['default-animation'] ] ) ) { + $base_animation = $chronological_pagination_animations[ $args['default-animation'] ]; + $args['chronological-forwards-animation'] = $base_animation . '-from-right'; + $args['chronological-backwards-animation'] = $base_animation . '-from-left'; + $args['pagination-forwards-animation'] = $base_animation . '-from-right'; + $args['pagination-backwards-animation'] = $base_animation . '-from-left'; + } + + $selector_options = array( 'global' => array( 'header_selector' => 'header', 'main_selector' => 'main', From d3b4785a98666a402be07d42b1b569536b982e99 Mon Sep 17 00:00:00 2001 From: Aditya Dhade Date: Thu, 26 Feb 2026 00:12:19 +0530 Subject: [PATCH 3/5] Wrap animation stylesheet in media query for reduced motion preference --- plugins/view-transitions/includes/theme.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/view-transitions/includes/theme.php b/plugins/view-transitions/includes/theme.php index f1d7dae417..a68b99d10b 100644 --- a/plugins/view-transitions/includes/theme.php +++ b/plugins/view-transitions/includes/theme.php @@ -371,7 +371,7 @@ function plvt_load_view_transitions(): void { if ( '' !== $additional_animation_stylesheet ) { wp_add_inline_style( 'plvt-view-transitions', - plvt_scope_animation_stylesheet_to_transition_type( $additional_animation_stylesheet, $transition_type ) + '@media (prefers-reduced-motion: no-preference) {' . plvt_scope_animation_stylesheet_to_transition_type( $additional_animation_stylesheet, $transition_type ) . '}' ); } From 5c43cc22420c90f56fab36db90b9fe1dee439d39 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Thu, 26 Feb 2026 22:08:40 -0800 Subject: [PATCH 4/5] Apply some static analysis improvements --- plugins/view-transitions/includes/theme.php | 16 ++++++++-------- plugins/view-transitions/js/view-transitions.js | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/plugins/view-transitions/includes/theme.php b/plugins/view-transitions/includes/theme.php index a68b99d10b..4b884353e6 100644 --- a/plugins/view-transitions/includes/theme.php +++ b/plugins/view-transitions/includes/theme.php @@ -141,7 +141,7 @@ function plvt_register_view_transition_animations( PLVT_View_Transition_Animatio * animation. */ $is_specific_target_name = static function ( string $alias, array $args ): bool { - return '*' === $args['target-name'] ? false : true; + return ! ( '*' === $args['target-name'] ); }; /* @@ -342,10 +342,10 @@ function plvt_load_view_transitions(): void { if ( ( ! is_array( $theme_support['global-transition-names'] ) || count( $theme_support['global-transition-names'] ) === 0 ) && ( ! is_array( $theme_support['post-transition-names'] ) || count( $theme_support['post-transition-names'] ) === 0 ) && - ! (bool) $theme_support['chronological-forwards-animation'] && - ! (bool) $theme_support['chronological-backwards-animation'] && - ! (bool) $theme_support['pagination-forwards-animation'] && - ! (bool) $theme_support['pagination-backwards-animation'] + false === $theme_support['chronological-forwards-animation'] && + false === $theme_support['chronological-backwards-animation'] && + false === $theme_support['pagination-forwards-animation'] && + false === $theme_support['pagination-backwards-animation'] ) { return; } @@ -378,7 +378,7 @@ function plvt_load_view_transitions(): void { $animations_js_config[ $transition_type ] = array( 'useGlobalTransitionNames' => $animation_registry->use_animation_global_transition_names( $theme_support[ $transition_type . '-animation' ], $additional_animation_args ), 'usePostTransitionNames' => $animation_registry->use_animation_post_transition_names( $theme_support[ $transition_type . '-animation' ], $additional_animation_args ), - 'targetName' => isset( $additional_animation_args['target-name'] ) ? $additional_animation_args['target-name'] : '*', // Special argument. + 'targetName' => $additional_animation_args['target-name'] ?? '*', // Special argument. ); } else { $animations_js_config[ $transition_type ] = false; @@ -481,12 +481,12 @@ static function ( string $line ) use ( $indent_tabs ): string { if ( str_contains( $rule, "\n" ) ) { // Non-minified. $rule = $rule_whitespace . - "html:active-view-transition-type({$transition_type}) {\n" . + "html:active-view-transition-type($transition_type) {\n" . $indent( substr( $rule, strlen( $rule_whitespace ) ), 1 ) . "\n}"; } else { // Minified. $rule = $rule_whitespace . - "html:active-view-transition-type({$transition_type}){" . + "html:active-view-transition-type($transition_type){" . substr( $rule, strlen( $rule_whitespace ) ) . '}'; } diff --git a/plugins/view-transitions/js/view-transitions.js b/plugins/view-transitions/js/view-transitions.js index fe98730486..2f60283404 100644 --- a/plugins/view-transitions/js/view-transitions.js +++ b/plugins/view-transitions/js/view-transitions.js @@ -180,7 +180,7 @@ window.plvtInitViewTransitions = ( config ) => { prefix = 'chronological-'; } - // If not, check if the URLs are for a multi-page post. + // If not, check if the URLs are for a multipage post. if ( ! oldPageMatches && ! newPageMatches && @@ -235,7 +235,7 @@ window.plvtInitViewTransitions = ( config ) => { } } - // If enabled, check if the URLs are for content labelled by date (e.g. navigation to previous/next post). + // If enabled, check if the URLs are for content labeled by date (e.g. navigation to previous/next post). if ( config.animations[ 'chronological-forwards' ] || config.animations[ 'chronological-backwards' ] From b6dfded7f1bd9306b8ba71969af173c6e1ab8de2 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Thu, 26 Feb 2026 22:27:17 -0800 Subject: [PATCH 5/5] Export pagination_base from PHP --- plugins/view-transitions/includes/theme.php | 5 +++++ plugins/view-transitions/js/types.ts | 1 + plugins/view-transitions/js/view-transitions.js | 11 +++++++++-- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/plugins/view-transitions/includes/theme.php b/plugins/view-transitions/includes/theme.php index 4b884353e6..23d6aaa938 100644 --- a/plugins/view-transitions/includes/theme.php +++ b/plugins/view-transitions/includes/theme.php @@ -310,8 +310,12 @@ function plvt_register_view_transition_animations( PLVT_View_Transition_Animatio * Loads view transitions based on the current configuration. * * @since 1.0.0 + * + * @global WP_Rewrite $wp_rewrite */ function plvt_load_view_transitions(): void { + global $wp_rewrite; + if ( ! current_theme_supports( 'view-transitions' ) ) { return; } @@ -390,6 +394,7 @@ function plvt_load_view_transitions(): void { 'globalTransitionNames' => $theme_support['global-transition-names'], 'postTransitionNames' => $theme_support['post-transition-names'], 'animations' => $animations_js_config, + 'paginationBase' => $wp_rewrite->pagination_base, ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents diff --git a/plugins/view-transitions/js/types.ts b/plugins/view-transitions/js/types.ts index 1653b841c2..7d53eb1cbb 100644 --- a/plugins/view-transitions/js/types.ts +++ b/plugins/view-transitions/js/types.ts @@ -8,6 +8,7 @@ export type ViewTransitionsConfig = { globalTransitionNames?: Record< string, string >; postTransitionNames?: Record< string, string >; animations?: Record< string, ViewTransitionAnimationConfig >; + paginationBase: string; }; export type InitViewTransitionsFunction = ( diff --git a/plugins/view-transitions/js/view-transitions.js b/plugins/view-transitions/js/view-transitions.js index 2f60283404..a3daf9cbe9 100644 --- a/plugins/view-transitions/js/view-transitions.js +++ b/plugins/view-transitions/js/view-transitions.js @@ -159,6 +159,7 @@ window.plvtInitViewTransitions = ( config ) => { const oldURL = new URL( oldEntry.url ); const newURL = new URL( newEntry.url ); + // TODO: Handle non-pretty permalinks. const oldPathname = oldURL.pathname; const newPathname = newURL.pathname; @@ -175,8 +176,12 @@ window.plvtInitViewTransitions = ( config ) => { config.animations[ 'chronological-forwards' ] || config.animations[ 'chronological-backwards' ] ) { - oldPageMatches = oldPathname.match( /\/page\/(\d+)\/?$/ ); - newPageMatches = newPathname.match( /\/page\/(\d+)\/?$/ ); + const pagedRegEx = new RegExp( + '/' + config.paginationBase + '/(\\d+)/?$' // TODO: Escape. + ); + // TODO: Handle non-pretty permalinks. + oldPageMatches = oldPathname.match( pagedRegEx ); + newPageMatches = newPathname.match( pagedRegEx ); prefix = 'chronological-'; } @@ -187,6 +192,7 @@ window.plvtInitViewTransitions = ( config ) => { ( config.animations[ 'pagination-forwards' ] || config.animations[ 'pagination-backwards' ] ) ) { + // TODO: Handle non-pretty permalinks. oldPageMatches = oldPathname.match( /\/(\d+)\/?$/ ); newPageMatches = newPathname.match( /\/(\d+)\/?$/ ); prefix = 'pagination-'; @@ -240,6 +246,7 @@ window.plvtInitViewTransitions = ( config ) => { config.animations[ 'chronological-forwards' ] || config.animations[ 'chronological-backwards' ] ) { + // TODO: Handle non-pretty permalinks. const oldDateMatches = oldPathname.match( /\/(\d{4})\/(\d{2})\/(\d{2})\/[^\/]+\/?$/ );