Skip to content

Scaffold View Transitions feature plugin #1998

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

Merged
merged 2 commits into from
Apr 30, 2025
Merged
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
3 changes: 3 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,6 @@

# Plugin: Speculative Loading
/plugins/speculation-rules @felixarntz

# Plugin: View Transitions
/plugins/view-transitions @felixarntz
2 changes: 2 additions & 0 deletions .github/workflows/php-test-plugins.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ jobs:
npm run test-php:image-prioritizer -- -- -- --coverage-clover=./single-site-reports/coverage-image-prioritizer.xml
npm run test-php:optimization-detective -- -- -- --coverage-clover=./single-site-reports/coverage-optimization-detective.xml
npm run test-php:speculation-rules -- -- -- --coverage-clover=./single-site-reports/coverage-speculation-rules.xml
npm run test-php:view-transitions -- -- -- --coverage-clover=./single-site-reports/coverage-view-transitions.xml
npm run test-php:web-worker-offloading -- -- -- --coverage-clover=./single-site-reports/coverage-web-worker-offloading.xml
npm run test-php:webp-uploads -- -- -- --coverage-clover=./single-site-reports/coverage-webp-uploads.xml
else
Expand All @@ -110,6 +111,7 @@ jobs:
npm run test-php-multisite:image-prioritizer -- -- -- --coverage-clover=./multisite-reports/coverage-multisite-image-prioritizer.xml
npm run test-php-multisite:optimization-detective -- -- -- --coverage-clover=./multisite-reports/coverage-multisite-optimization-detective.xml
npm run test-php-multisite:speculation-rules -- -- -- --coverage-clover=./multisite-reports/coverage-multisite-speculation-rules.xml
npm run test-php-multisite:view-transitions -- -- -- --coverage-clover=./multisite-reports/coverage-multisite-view-transitions.xml
npm run test-php-multisite:web-worker-offloading -- -- -- --coverage-clover=./multisite-reports/coverage-multisite-web-worker-offloading.xml
npm run test-php-multisite:webp-uploads -- -- -- --coverage-clover=./multisite-reports/coverage-multisite-webp-uploads.xml
else
Expand Down
1 change: 1 addition & 0 deletions .wp-env.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"./plugins/image-prioritizer",
"./plugins/performance-lab",
"./plugins/speculation-rules",
"./plugins/view-transitions",
"./plugins/web-worker-offloading",
"./plugins/webp-uploads"
],
Expand Down
8 changes: 8 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
"@format:optimization-detective",
"@format:performance-lab",
"@format:speculation-rules",
"@format:view-transitions",
"@format:web-worker-offloading",
"@format:webp-uploads"
],
Expand All @@ -65,6 +66,7 @@
"format:optimization-detective": "@format -- ./plugins/optimization-detective --standard=./plugins/optimization-detective/phpcs.xml.dist",
"format:performance-lab": "@format -- ./plugins/performance-lab --standard=./plugins/performance-lab/phpcs.xml.dist",
"format:speculation-rules": "@format -- ./plugins/speculation-rules --standard=./plugins/speculation-rules/phpcs.xml.dist",
"format:view-transitions": "@format -- ./plugins/view-transitions --standard=./plugins/view-transitions/phpcs.xml.dist",
"format:web-worker-offloading": "@format -- ./plugins/web-worker-offloading --standard=./plugins/web-worker-offloading/phpcs.xml.dist",
"format:webp-uploads": "@format -- ./plugins/webp-uploads --standard=./plugins/webp-uploads/phpcs.xml.dist",
"lint": "phpcs",
Expand All @@ -77,6 +79,7 @@
"@lint:optimization-detective",
"@lint:performance-lab",
"@lint:speculation-rules",
"@lint:view-transitions",
"@lint:web-worker-offloading",
"@lint:webp-uploads"
],
Expand All @@ -87,6 +90,7 @@
"lint:optimization-detective": "@lint -- ./plugins/optimization-detective --standard=./plugins/optimization-detective/phpcs.xml.dist",
"lint:performance-lab": "@lint -- ./plugins/performance-lab --standard=./plugins/performance-lab/phpcs.xml.dist",
"lint:speculation-rules": "@lint -- ./plugins/speculation-rules --standard=./plugins/speculation-rules/phpcs.xml.dist",
"lint:view-transitions": "@lint -- ./plugins/view-transitions --standard=./plugins/view-transitions/phpcs.xml.dist",
"lint:web-worker-offloading": "@lint -- ./plugins/web-worker-offloading --standard=./plugins/web-worker-offloading/phpcs.xml.dist",
"lint:webp-uploads": "@lint -- ./plugins/webp-uploads --standard=./plugins/webp-uploads/phpcs.xml.dist",
"phpstan": "phpstan analyse --memory-limit=2048M",
Expand All @@ -102,6 +106,7 @@
"@test-multisite:optimization-detective",
"@test-multisite:performance-lab",
"@test-multisite:speculation-rules",
"@test-multisite:view-transitions",
"@test-multisite:web-worker-offloading",
"@test-multisite:webp-uploads"
],
Expand All @@ -112,6 +117,7 @@
"test-multisite:optimization-detective": "@test-multisite --verbose --testsuite optimization-detective",
"test-multisite:performance-lab": "@test-multisite --verbose --testsuite performance-lab",
"test-multisite:speculation-rules": "@test-multisite --verbose --testsuite speculation-rules",
"test-multisite:view-transitions": "@test-multisite --verbose --testsuite view-transitions",
"test-multisite:web-worker-offloading": "@test-multisite --verbose --testsuite web-worker-offloading",
"test-multisite:webp-uploads": "@test-multisite --verbose --testsuite webp-uploads",
"test:plugins": [
Expand All @@ -122,6 +128,7 @@
"@test:optimization-detective",
"@test:performance-lab",
"@test:speculation-rules",
"@test:view-transitions",
"@test:web-worker-offloading",
"@test:webp-uploads"
],
Expand All @@ -132,6 +139,7 @@
"test:optimization-detective": "@test --verbose --testsuite optimization-detective",
"test:performance-lab": "@test --verbose --testsuite performance-lab",
"test:speculation-rules": "@test --verbose --testsuite speculation-rules",
"test:view-transitions": "@test --verbose --testsuite view-transitions",
"test:web-worker-offloading": "@test --verbose --testsuite web-worker-offloading",
"test:webp-uploads": "@test --verbose --testsuite webp-uploads"
}
Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
"build:plugin:image-prioritizer": "webpack --mode production --env plugin=image-prioritizer",
"build:plugin:optimization-detective": "webpack --mode production --env plugin=optimization-detective",
"build:plugin:speculation-rules": "webpack --mode production --env plugin=speculation-rules",
"build:plugin:view-transitions": "webpack --mode production --env plugin=view-transitions",
"build:plugin:web-worker-offloading": "webpack --mode production --env plugin=web-worker-offloading",
"build:plugin:webp-uploads": "webpack --mode production --env plugin=webp-uploads",
"generate-pending-release-diffs": "bin/generate-pending-release-diffs.sh",
Expand All @@ -62,6 +63,7 @@
"test-php:image-prioritizer": "wp-env run tests-cli --env-cwd=/var/www/html/wp-content/plugins/performance composer test:image-prioritizer",
"test-php:optimization-detective": "wp-env run tests-cli --env-cwd=/var/www/html/wp-content/plugins/performance composer test:optimization-detective",
"test-php:speculation-rules": "wp-env run tests-cli --env-cwd=/var/www/html/wp-content/plugins/performance composer test:speculation-rules",
"test-php:view-transitions": "wp-env run tests-cli --env-cwd=/var/www/html/wp-content/plugins/performance composer test:view-transitions",
"test-php:web-worker-offloading": "wp-env run tests-cli --env-cwd=/var/www/html/wp-content/plugins/performance composer test:web-worker-offloading",
"test-php:webp-uploads": "wp-env run tests-cli --env-cwd=/var/www/html/wp-content/plugins/performance composer test:webp-uploads",
"test-php-multisite:performance-lab": "wp-env run tests-cli --env-cwd=/var/www/html/wp-content/plugins/performance composer test-multisite:performance-lab",
Expand All @@ -71,6 +73,7 @@
"test-php-multisite:image-prioritizer": "wp-env run tests-cli --env-cwd=/var/www/html/wp-content/plugins/performance composer test-multisite:image-prioritizer",
"test-php-multisite:optimization-detective": "wp-env run tests-cli --env-cwd=/var/www/html/wp-content/plugins/performance composer test-multisite:optimization-detective",
"test-php-multisite:speculation-rules": "wp-env run tests-cli --env-cwd=/var/www/html/wp-content/plugins/performance composer test-multisite:speculation-rules",
"test-php-multisite:view-transitions": "wp-env run tests-cli --env-cwd=/var/www/html/wp-content/plugins/performance composer test-multisite:view-transitions",
"test-php-multisite:web-worker-offloading": "wp-env run tests-cli --env-cwd=/var/www/html/wp-content/plugins/performance composer test-multisite:web-worker-offloading",
"test-php-multisite:webp-uploads": "wp-env run tests-cli --env-cwd=/var/www/html/wp-content/plugins/performance composer test-multisite:webp-uploads",
"wp-env": "wp-env",
Expand Down
3 changes: 3 additions & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@
<testsuite name="speculation-rules">
<directory suffix=".php">plugins/speculation-rules/tests</directory>
</testsuite>
<testsuite name="view-transitions">
<directory suffix=".php">plugins/view-transitions/tests</directory>
</testsuite>
<testsuite name="web-worker-offloading">
<directory suffix=".php">plugins/web-worker-offloading/tests</directory>
</testsuite>
Expand Down
32 changes: 32 additions & 0 deletions plugins/view-transitions/hooks.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php
/**
* Hook callbacks used for View Transitions.
*
* @package view-transitions
* @since 1.0.0
*/

// @codeCoverageIgnoreStart
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
// @codeCoverageIgnoreEnd

/**
* Displays the HTML generator tag for the plugin.
*
* See {@see 'wp_head'}.
*
* @since 1.0.0
*/
function plvt_render_generator(): void {
// Use the plugin slug as it is immutable.
echo '<meta name="generator" content="view-transitions ' . esc_attr( VIEW_TRANSITIONS_VERSION ) . '">' . "\n";
}
add_action( 'wp_head', 'plvt_render_generator' );

Check warning on line 26 in plugins/view-transitions/hooks.php

View check run for this annotation

Codecov / codecov/patch

plugins/view-transitions/hooks.php#L26

Added line #L26 was not covered by tests

/**
* Filters related to the View Transitions functionality.
*/
add_action( 'after_setup_theme', 'plvt_polyfill_theme_support', PHP_INT_MAX );
add_action( 'wp_enqueue_scripts', 'plvt_load_view_transitions' );

Check warning on line 32 in plugins/view-transitions/hooks.php

View check run for this annotation

Codecov / codecov/patch

plugins/view-transitions/hooks.php#L31-L32

Added lines #L31 - L32 were not covered by tests
45 changes: 45 additions & 0 deletions plugins/view-transitions/includes/theme.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php
/**
* Theme related functions for View Transitions.
*
* @package view-transitions
* @since 1.0.0
*/

/**
* Polyfills theme support for 'view-transitions', regardless of the theme.
*
* In WordPress Core, the 'view-transitions' feature may end up as an optional feature, or it may be added by default.
* In any case, in the scope of the plugin it does not make sense to have the feature as opt-in, since it is the entire
* purpose of the plugin.
*
* Therefore, this function will unconditionally add support with the default configuration, unless the theme itself
* actually added support for it already.
*
* This function must run at the latest possible priority for `after_setup_theme`.
*
* @since 1.0.0
*/
function plvt_polyfill_theme_support(): void {
if ( current_theme_supports( 'view-transitions' ) ) {
return;
}
add_theme_support( 'view-transitions' );
}

/**
* Loads view transitions based on the current configuration.
*
* @since 1.0.0
*/
function plvt_load_view_transitions(): void {
if ( ! current_theme_supports( 'view-transitions' ) ) {
return;
}

// Use an inline style to avoid an extra request.
$stylesheet = '@view-transition { navigation: auto; }';
wp_register_style( 'wp-view-transitions', false, array(), null ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion
wp_add_inline_style( 'wp-view-transitions', $stylesheet );
wp_enqueue_style( 'wp-view-transitions' );
}
10 changes: 10 additions & 0 deletions plugins/view-transitions/phpcs.xml.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0"?>
<ruleset name="WPP-ViewTransitions">
<description>WordPress Coding Standards for View Transitions Plugin</description>

<rule ref="../../tools/phpcs/phpcs.ruleset.xml"/>

<config name="text_domain" value="view-transitions"/>

<file>.</file>
</ruleset>
56 changes: 56 additions & 0 deletions plugins/view-transitions/readme.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
=== View Transitions ===

Contributors: wordpressdotorg
Tested up to: 6.8
Stable tag: 1.4.0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be 1.0.0

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @mukeshpanchal27, I'll fix this as part of #1999.

License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Tags: performance, view transitions, smooth transitions, animations

Adds smooth transitions between navigations to your WordPress site.

== Description ==

This plugin implements support for [cross-document view transitions](https://developer.chrome.com/docs/web-platform/view-transitions/cross-document) in WordPress. This effectively replaces the hard transitions when navigating from one URL to the other with a smooth animation, by default using a fade effect.

= Browser support =

Cross-document view transitions are supported in a variety of browsers, including Chrome, Edge, and Safari. Users with browsers that currently do not support it should not see any adverse effects when the plugin is active. They will simply not benefit from the feature and continue to experience the traditional hard transitions between URLs.

[Please refer to "Can I use..." for a comprehensive overview of browser support for the feature.](https://caniuse.com/mdn-css_at-rules_view-transition)

== Installation ==

= Installation from within WordPress =

1. Visit **Plugins > Add New**.
2. Search for **View Transitions**.
3. Install and activate the **View Transitions** plugin.

= Manual installation =

1. Upload the entire plugin folder to the `/wp-content/plugins/` directory.
2. Visit **Plugins**.
3. Activate the **View Transitions** plugin.

== Frequently Asked Questions ==

= Where can I submit my plugin feedback? =

Feedback is encouraged and much appreciated, especially since this plugin may contain future WordPress core features. If you have suggestions or requests for new features, you can [submit them as an issue in the WordPress Performance Team's GitHub repository](https://github.com/WordPress/performance/issues/new/choose). If you need help with troubleshooting or have a question about the plugin, please [create a new topic on our support forum](https://wordpress.org/support/plugin/view-transitions/#new-topic-0).

= Where can I report security bugs? =

The Performance team and WordPress community take security bugs seriously. We appreciate your efforts to responsibly disclose your findings, and will make every effort to acknowledge your contributions.

To report a security issue, please visit the [WordPress HackerOne](https://hackerone.com/wordpress) program.

= How can I contribute to the plugin? =

Contributions are always welcome! Learn more about how to get involved in the [Core Performance Team Handbook](https://make.wordpress.org/performance/handbook/get-involved/).

== Changelog ==

= 1.0.0 =

* Initial release.
22 changes: 22 additions & 0 deletions plugins/view-transitions/tests/test-hooks.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php
/**
* Tests for the View Transitions plugin hooks.php file.
*
* @package view-transitions
* @group view-transitions
*/

class Test_ViewTransitions_Hooks extends WP_UnitTestCase {

public function test_hooks(): void {
$this->assertSame( 10, has_action( 'wp_head', 'plvt_render_generator' ) );
$this->assertSame( PHP_INT_MAX, has_action( 'after_setup_theme', 'plvt_polyfill_theme_support' ) );
$this->assertSame( 10, has_action( 'wp_enqueue_scripts', 'plvt_load_view_transitions' ) );
}

public function test_plvt_render_generator(): void {
$expected = '<meta name="generator" content="view-transitions ' . VIEW_TRANSITIONS_VERSION . '">' . "\n";
$output = get_echo( 'plvt_render_generator' );
$this->assertSame( $expected, $output );
}
}
43 changes: 43 additions & 0 deletions plugins/view-transitions/tests/test-theme.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php
/**
* Tests for the View Transitions plugin includes/theme.php file.
*
* @package view-transitions
* @group view-transitions
*/

class Test_ViewTransitions_Theme extends WP_UnitTestCase {

public function test_plvt_polyfill_theme_support(): void {
// Test polyfill without support registered.
remove_theme_support( 'view-transitions' );
plvt_polyfill_theme_support();
$this->assertTrue( current_theme_supports( 'view-transitions' ) );
$this->assertTrue( get_theme_support( 'view-transitions' ) );

// Test polyfill does not override theme support arguments if already provided by the actual theme.
add_theme_support( 'view-transitions', array( 'custom_key' => 'custom_value' ) );
plvt_polyfill_theme_support();
$this->assertTrue( current_theme_supports( 'view-transitions' ) );
$this->assertSame( array( array( 'custom_key' => 'custom_value' ) ), get_theme_support( 'view-transitions' ) );
}

public function test_plvt_load_view_transitions(): void {
// Clear up style if it is already registered.
if ( wp_style_is( 'wp-view-transitions', 'registered' ) ) {
unset( wp_styles()->registered['wp-view-transitions'] );
}

// Test that without theme support this does nothing.
remove_theme_support( 'view-transitions' );
plvt_load_view_transitions();
$this->assertFalse( wp_style_is( 'wp-view-transitions', 'registered' ) );
$this->assertFalse( wp_style_is( 'wp-view-transitions', 'enqueued' ) );

// Test that with theme support it registers and enqueues the style.
add_theme_support( 'view-transitions' );
plvt_load_view_transitions();
$this->assertTrue( wp_style_is( 'wp-view-transitions', 'registered' ) );
$this->assertTrue( wp_style_is( 'wp-view-transitions', 'enqueued' ) );
}
}
32 changes: 32 additions & 0 deletions plugins/view-transitions/view-transitions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php
/**
* Plugin Name: View Transitions
* Plugin URI: https://github.com/WordPress/performance/tree/trunk/plugins/view-transitions
* Description: Adds smooth transitions between navigations to your WordPress site.
* Requires at least: 6.6
* Requires PHP: 7.2
* Version: 1.0.0
* Author: WordPress Performance Team
* Author URI: https://make.wordpress.org/performance/
* License: GPLv2 or later
* License URI: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* Text Domain: view-transitions
*
* @package view-transitions
*/

// @codeCoverageIgnoreStart
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}

// Define the constant.
if ( defined( 'VIEW_TRANSITIONS_VERSION' ) ) {
return;
}

define( 'VIEW_TRANSITIONS_VERSION', '1.0.0' );

require_once __DIR__ . '/includes/theme.php';
require_once __DIR__ . '/hooks.php';
// @codeCoverageIgnoreEnd