Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 32 additions & 14 deletions plugins/view-transitions/includes/settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -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' ),
);
}

Expand Down Expand Up @@ -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',
Expand Down
123 changes: 116 additions & 7 deletions plugins/view-transitions/includes/theme.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand All @@ -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'],
Expand Down Expand Up @@ -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;
}
4 changes: 4 additions & 0 deletions plugins/view-transitions/js/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ export type InitViewTransitionsFunction = (
config: ViewTransitionsConfig
) => void;

export type NavigationHistoryEntry = {
url: string;
};

declare global {
interface Window {
plvtInitViewTransitions?: InitViewTransitionsFunction;
Expand Down
Loading
Loading