-
Notifications
You must be signed in to change notification settings - Fork 143
Add support for chronological and pagination transitions #2336
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: trunk
Are you sure you want to change the base?
Changes from all commits
08e7cae
f518306
e1d07ae
0bcdbc1
431e777
d3b4785
f2ce961
5c43cc2
b6dfded
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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; | ||
| } | ||
|
|
@@ -124,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'] ); | ||
| }; | ||
|
|
||
| /* | ||
|
|
@@ -293,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; | ||
| } | ||
|
|
@@ -324,7 +345,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 ) && | ||
| 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; | ||
| } | ||
|
|
@@ -336,11 +361,40 @@ function plvt_load_view_transitions(): void { | |
| ), | ||
| ); | ||
|
|
||
| $additional_transition_types = array( | ||
| 'chronological-forwards', | ||
| 'chronological-backwards', | ||
| 'pagination-forwards', | ||
| 'pagination-backwards', | ||
| ); | ||
|
|
||
|
Comment on lines
+364
to
+370
|
||
| 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', | ||
| '@media (prefers-reduced-motion: no-preference) {' . plvt_scope_animation_stylesheet_to_transition_type( $additional_animation_stylesheet, $transition_type ) . '}' | ||
| ); | ||
|
Comment on lines
+373
to
+379
|
||
| } | ||
|
|
||
| $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' => $additional_animation_args['target-name'] ?? '*', // Special argument. | ||
| ); | ||
| } else { | ||
| $animations_js_config[ $transition_type ] = false; | ||
| } | ||
| } | ||
|
Comment on lines
+371
to
+390
|
||
|
|
||
| $config = array( | ||
| 'postSelector' => $theme_support['post-selector'], | ||
| '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 | ||
|
|
@@ -389,3 +443,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 | ||
westonruter marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| * @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; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,12 +8,17 @@ export type ViewTransitionsConfig = { | |
| globalTransitionNames?: Record< string, string >; | ||
| postTransitionNames?: Record< string, string >; | ||
| animations?: Record< string, ViewTransitionAnimationConfig >; | ||
| paginationBase: string; | ||
| }; | ||
|
|
||
| export type InitViewTransitionsFunction = ( | ||
| config: ViewTransitionsConfig | ||
| ) => void; | ||
|
|
||
| export type NavigationHistoryEntry = { | ||
| url: string; | ||
| }; | ||
|
Comment on lines
+18
to
+20
|
||
|
|
||
| declare global { | ||
| interface Window { | ||
| plvtInitViewTransitions?: InitViewTransitionsFunction; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When the special
*-chronological-paginationoption is selected,$args['default-animation']remains set to that value, but it is not a registered animation slug/alias in the animation registry. As a result, the default transition falls back to the browser default (fade) instead of the intended slide/swipe/wipe. Map$args['default-animation']to a real registry alias/slug (e.g. the base animation or a concrete direction) when enabling these special options.