This repository has been archived by the owner on Feb 23, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 219
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Serialize the Interactivity API's store from PHP and hydrate it on th…
…e client (#8447) * Update Interactivity API * Change `wp` prefixes to `woo` * Use `woo` prefix for the directives runtime bundle * Update Interactivity API runtime * Hardcode php from interactivity API * Temporarily add gutenberg plugin as dependency * Exclude Interactivity API files from phpcs checks * Update Interactivity API js files * Update Interactivity API php files * Remove gutenberg from wp-env plugins * Fix registered runtime paths * Fix prefixes when getting attributes in directives * Fix directive prefix in constants * Avoid a Fatal error when importing `wp-html` * Remove TODO comments from Interactivity API files * Add missing prefix to some global functions * Use true as value for boolean attributes * Add `wp-html` file * Change requires in `wp-html` with includes
- Loading branch information
Showing
20 changed files
with
556 additions
and
73 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
export const cstMetaTagItemprop = 'woo-client-side-transitions'; | ||
export const csnMetaTagItemprop = 'woo-client-side-navigation'; | ||
export const componentPrefix = 'woo-'; | ||
export const directivePrefix = 'data-woo-'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import { deepSignal } from 'deepsignal'; | ||
|
||
const isObject = ( item ) => | ||
item && typeof item === 'object' && ! Array.isArray( item ); | ||
|
||
export const deepMerge = ( target, source ) => { | ||
if ( isObject( target ) && isObject( source ) ) { | ||
for ( const key in source ) { | ||
if ( isObject( source[ key ] ) ) { | ||
if ( ! target[ key ] ) Object.assign( target, { [ key ]: {} } ); | ||
deepMerge( target[ key ], source[ key ] ); | ||
} else { | ||
Object.assign( target, { [ key ]: source[ key ] } ); | ||
} | ||
} | ||
} | ||
}; | ||
|
||
const getSerializedState = () => { | ||
const storeTag = document.querySelector( | ||
`script[type="application/json"]#store` | ||
); | ||
if ( ! storeTag ) return {}; | ||
try { | ||
const { state } = JSON.parse( storeTag.textContent ); | ||
if ( isObject( state ) ) return state; | ||
throw Error( 'Parsed state is not an object' ); | ||
} catch ( e ) { | ||
console.log( e ); | ||
} | ||
return {}; | ||
}; | ||
|
||
const rawState = getSerializedState(); | ||
export const rawStore = { state: deepSignal( rawState ) }; | ||
|
||
if ( typeof window !== 'undefined' ) window.store = rawStore; | ||
|
||
export const store = ( { state, ...block } ) => { | ||
deepMerge( rawStore, block ); | ||
deepMerge( rawState, state ); | ||
}; |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<?php | ||
|
||
require_once __DIR__ . '/../utils.php'; | ||
|
||
function process_woo_bind( $tags, $context ) { | ||
if ( $tags->is_tag_closer() ) { | ||
return; | ||
} | ||
|
||
$prefixed_attributes = $tags->get_attribute_names_with_prefix( 'data-woo-bind:' ); | ||
|
||
foreach ( $prefixed_attributes as $attr ) { | ||
list( , $bound_attr ) = explode( ':', $attr ); | ||
if ( empty( $bound_attr ) ) { | ||
continue; | ||
} | ||
|
||
$expr = $tags->get_attribute( $attr ); | ||
$value = woo_directives_evaluate( $expr, $context->get_context() ); | ||
$tags->set_attribute( $bound_attr, $value ); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
<?php | ||
|
||
require_once __DIR__ . '/../utils.php'; | ||
|
||
function process_woo_class( $tags, $context ) { | ||
if ( $tags->is_tag_closer() ) { | ||
return; | ||
} | ||
|
||
$prefixed_attributes = $tags->get_attribute_names_with_prefix( 'data-woo-class:' ); | ||
|
||
foreach ( $prefixed_attributes as $attr ) { | ||
list( , $class_name ) = explode( ':', $attr ); | ||
if ( empty( $class_name ) ) { | ||
continue; | ||
} | ||
|
||
$expr = $tags->get_attribute( $attr ); | ||
$add_class = woo_directives_evaluate( $expr, $context->get_context() ); | ||
if ( $add_class ) { | ||
$tags->add_class( $class_name ); | ||
} else { | ||
$tags->remove_class( $class_name ); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<?php | ||
|
||
function process_woo_context_attribute( $tags, $context ) { | ||
if ( $tags->is_tag_closer() ) { | ||
$context->rewind_context(); | ||
return; | ||
} | ||
|
||
$value = $tags->get_attribute( 'data-woo-context' ); | ||
if ( null === $value ) { | ||
// No woo-context directive. | ||
return; | ||
} | ||
|
||
$new_context = json_decode( $value, true ); | ||
|
||
$context->set_context( $new_context ); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
<?php | ||
|
||
require_once __DIR__ . '/../utils.php'; | ||
|
||
function process_woo_style( $tags, $context ) { | ||
if ( $tags->is_tag_closer() ) { | ||
return; | ||
} | ||
|
||
$prefixed_attributes = $tags->get_attribute_names_with_prefix( 'data-woo-style:' ); | ||
|
||
foreach ( $prefixed_attributes as $attr ) { | ||
list( , $style_name ) = explode( ':', $attr ); | ||
if ( empty( $style_name ) ) { | ||
continue; | ||
} | ||
|
||
$expr = $tags->get_attribute( $attr ); | ||
$style_value = woo_directives_evaluate( $expr, $context->get_context() ); | ||
if ( $style_value ) { | ||
$style_attr = $tags->get_attribute( 'style' ); | ||
$style_attr = woo_directives_set_style( $style_attr, $style_name, $style_value ); | ||
$tags->set_attribute( 'style', $style_attr ); | ||
} else { | ||
// $tags->remove_class( $style_name ); | ||
} | ||
} | ||
} | ||
|
73 changes: 73 additions & 0 deletions
73
src/Interactivity/directives/class-woo-directive-context.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
<?php | ||
/** | ||
* Context data implementation. | ||
* | ||
* @package block-hydration-experiments | ||
*/ | ||
|
||
/** | ||
* This is a data structure to hold the current context. | ||
* | ||
* Whenever encountering a `woo-context` directive, we need to update | ||
* the context with the data found in that directive. Conversely, | ||
* when "leaving" that context (by encountering a closing tag), we | ||
* need to reset the context to its previous state. This means that | ||
* we actually need sort of a stack to keep track of all nested contexts. | ||
* | ||
* Example: | ||
* | ||
* <woo-context data='{ "foo": 123 }'> | ||
* <!-- foo should be 123 here. --> | ||
* <woo-context data='{ "foo": 456 }'> | ||
* <!-- foo should be 456 here. --> | ||
* </woo-context> | ||
* <!-- foo should be reset to 123 here. --> | ||
* </woo-context> | ||
*/ | ||
class Woo_Directive_Context { | ||
/** | ||
* The stack used to store contexts internally. | ||
* | ||
* @var array An array of contexts. | ||
*/ | ||
protected $stack = array( array() ); | ||
|
||
/** | ||
* Constructor. | ||
* | ||
* Accepts a context as an argument to initialize this with. | ||
* | ||
* @param array $context A context. | ||
*/ | ||
function __construct( $context = array() ) { | ||
$this->set_context( $context ); | ||
} | ||
|
||
/** | ||
* Return the current context. | ||
* | ||
* @return array The current context. | ||
*/ | ||
public function get_context() { | ||
return end( $this->stack ); | ||
} | ||
|
||
/** | ||
* Set the current context. | ||
* | ||
* @param array $context The context to be set. | ||
* @return void | ||
*/ | ||
public function set_context( $context ) { | ||
array_push( $this->stack, array_replace_recursive( $this->get_context(), $context ) ); | ||
} | ||
|
||
/** | ||
* Reset the context to its previous state. | ||
* | ||
* @return void | ||
*/ | ||
public function rewind_context() { | ||
array_pop( $this->stack ); | ||
} | ||
} |
Oops, something went wrong.