Skip to content
This repository has been archived by the owner on Jul 28, 2023. It is now read-only.

Experiment: Add view transitions API directive #241

2 changes: 1 addition & 1 deletion e2e/page-2/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ store({
state.newValue = !state.newValue;
},
replaceWithPage3: () => {
navigate('/csn-page-3.html', { replace: true });
navigate('/csn-page-3.html', true, { replace: true });
},
},
});
19 changes: 8 additions & 11 deletions src/runtime/directives.js
Original file line number Diff line number Diff line change
Expand Up @@ -161,19 +161,16 @@ export default () => {
if (clientSideNavigation && link !== false) {
element.props.onclick = async (event) => {
event.preventDefault();

// Fetch the page (or return it from cache).
await navigate(href);

// Update the scroll, depending on the option. True by default.
if (link?.scroll === 'smooth') {
window.scrollTo({
top: 0,
left: 0,
behavior: 'smooth',
if (
document.startViewTransition &&
link.viewTransitionsAPI
) {
document.startViewTransition(async () => {
await navigate(href, link?.scroll);
});
} else if (link?.scroll !== false) {
window.scrollTo(0, 0);
} else {
await navigate(href, link?.scroll);
}
};
}
Expand Down
11 changes: 10 additions & 1 deletion src/runtime/hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,14 @@ const RecursivePriorityLevel = ({
);

const props = { ...originalProps, children };
const directiveArgs = { directives, props, element, context, evaluate };
const directiveArgs = {
directives,
props,
element,
context,
evaluate,
store,
};

for (const d in directives) {
const wrapper = directiveMap[d]?.(directiveArgs);
Expand All @@ -123,6 +130,8 @@ const RecursivePriorityLevel = ({
const old = options.vnode;
options.vnode = (vnode) => {
if (vnode.props.__directives) {
if (vnode.props['data-wp-key'])
vnode.props.key = vnode.props['data-wp-key'];
const props = vnode.props;
const directives = props.__directives;
delete props.__directives;
Expand Down
2 changes: 2 additions & 0 deletions src/runtime/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import registerDirectives from './directives';
import { init } from './router';
export { store } from './store';
export { navigate } from './router';
export { directive } from './hooks';
export * from 'preact/hooks';

/**
* Initialize the Interactivity API.
Expand Down
17 changes: 16 additions & 1 deletion src/runtime/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,11 @@ export const prefetch = (url) => {
};

// Navigate to a new page.
export const navigate = async (href, { replace = false } = {}) => {
export const navigate = async (
href,
scroll = true,
{ replace = false } = {}
) => {
const url = cleanUrl(href);
prefetch(url);
const page = await pages.get(url);
Expand All @@ -127,6 +131,17 @@ export const navigate = async (href, { replace = false } = {}) => {
} else {
window.location.assign(href);
}

// Update the scroll, depending on the option. True by default.
if (scroll === 'smooth') {
window.scrollTo({
top: 0,
left: 0,
behavior: 'smooth',
});
} else if (scroll !== false) {
window.scrollTo(0, 0);
}
};

// Listen to the back and forward buttons and restore the page if it's in the
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export const deepMerge = (target, source) => {
const getSerializedState = () => {
// TODO: change the store tag ID for a better one.
const storeTag = document.querySelector(
`script[type="application/json"]#store`
`script[type="application/json"]#wp-interactivity-store-data`
);
if (!storeTag) return {};
try {
Expand Down
40 changes: 20 additions & 20 deletions wp-directives.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?php
/**
* Plugin Name: wp-directives
* Version: 0.1.26
* Version: 0.1.27
* Requires at least: 6.0
* Requires PHP: 5.6
* Author: Gutenberg Team
Expand Down Expand Up @@ -37,18 +37,18 @@ function () {
return;
}

require_once __DIR__ . '/src/directives/wp-html.php';
// require_once __DIR__ . '/src/directives/wp-html.php';

require_once __DIR__ . '/src/directives/class-wp-directive-context.php';
require_once __DIR__ . '/src/directives/class-wp-directive-store.php';
require_once __DIR__ . '/src/directives/wp-process-directives.php';
// require_once __DIR__ . '/src/directives/class-wp-directive-context.php';
// require_once __DIR__ . '/src/directives/class-wp-directive-store.php';
// require_once __DIR__ . '/src/directives/wp-process-directives.php';

require_once __DIR__ . '/src/directives/attributes/wp-bind.php';
require_once __DIR__ . '/src/directives/attributes/wp-context.php';
require_once __DIR__ . '/src/directives/attributes/wp-class.php';
require_once __DIR__ . '/src/directives/attributes/wp-html.php';
require_once __DIR__ . '/src/directives/attributes/wp-style.php';
require_once __DIR__ . '/src/directives/attributes/wp-text.php';
// require_once __DIR__ . '/src/directives/attributes/wp-bind.php';
// require_once __DIR__ . '/src/directives/attributes/wp-context.php';
// require_once __DIR__ . '/src/directives/attributes/wp-class.php';
// require_once __DIR__ . '/src/directives/attributes/wp-html.php';
// require_once __DIR__ . '/src/directives/attributes/wp-style.php';
// require_once __DIR__ . '/src/directives/attributes/wp-text.php';

/**
* Load includes.
Expand Down Expand Up @@ -128,10 +128,10 @@ function wp_directives_add_wp_link_attribute( $block_content ) {
) {
$w->set_attribute(
'data-wp-link',
'{ "prefetch": true, "scroll": false }'
'{ "prefetch": true, "viewTransitionsAPI": true, "scroll": false }'
);
} else {
$w->set_attribute( 'data-wp-link', '{ "prefetch": true }' );
$w->set_attribute( 'data-wp-link', '{ "prefetch": true, "viewTransitionsAPI": true }' );
}
}
}
Expand Down Expand Up @@ -269,13 +269,13 @@ function process_directives_in_block( $block_content ) {
$tags = wp_process_directives( $tags, 'data-wp-', $directives );
return $tags->get_updated_html();
}
add_filter(
'render_block',
'process_directives_in_block',
10,
1
);
// add_filter(
// 'render_block',
// 'process_directives_in_block',
// 10,
// 1
// );

// TODO: check if priority 9 is enough.
// TODO: check if `wp_footer` is the most appropriate hook.
add_action( 'wp_footer', array( 'WP_Directive_Store', 'render' ), 9 );
// add_action( 'wp_footer', array( 'WP_Directive_Store', 'render' ), 9 );
Loading