Skip to content

Commit

Permalink
prep build 01/12
Browse files Browse the repository at this point in the history
  • Loading branch information
bph committed Jan 12, 2024
2 parents 3d37003 + 7fce392 commit cc7807b
Show file tree
Hide file tree
Showing 112 changed files with 3,460 additions and 1,521 deletions.
40 changes: 39 additions & 1 deletion bin/api-docs/gen-theme-reference.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,42 @@ const keys = ( maybeObject ) => {
return Object.keys( maybeObject );
};

/**
* Get definition from ref.
*
* @param {string} ref
* @return {Object} definition
* @throws {Error} If the referenced definition is not found in 'themejson.definitions'.
*
* @example
* getDefinition( '#/definitions/typographyProperties/properties/fontFamily' )
* // returns themejson.definitions.typographyProperties.properties.fontFamily
*/
const resolveDefinitionRef = ( ref ) => {
const refParts = ref.split( '/' );
const definition = refParts[ refParts.length - 1 ];
if ( ! themejson.definitions[ definition ] ) {
throw new Error( `Can't resolve '${ ref }'. Definition not found` );
}
return themejson.definitions[ definition ];
};

/**
* Get properties from an array.
*
* @param {Object} items
* @return {Object} properties
*/
const getPropertiesFromArray = ( items ) => {
// if its a $ref resolve it
if ( items.$ref ) {
return resolveDefinitionRef( items.$ref ).properties;
}

// otherwise just return the properties
return items.properties;
};

/**
* Convert settings properties to markup.
*
Expand All @@ -96,7 +132,9 @@ const getSettingsPropertiesMarkup = ( struct ) => {
const def = 'default' in props[ key ] ? props[ key ].default : '';
const ps =
props[ key ].type === 'array'
? keys( props[ key ].items.properties ).sort().join( ', ' )
? keys( getPropertiesFromArray( props[ key ].items ) )
.sort()
.join( ', ' )
: '';
markup += `| ${ key } | ${ props[ key ].type } | ${ def } | ${ ps } |\n`;
} );
Expand Down
2 changes: 1 addition & 1 deletion bin/list-experimental-api-matches.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ namespace() {
awk -F: '
{ print module($1), $2 }
function module(path) {
n = split(path, parts, "/")
split(path, parts, "/")
if (parts[1] == "lib") return "lib"
return parts[1] "/" parts[2]
}'
Expand Down
256 changes: 256 additions & 0 deletions changelog.txt

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ Settings related to typography.

| Property | Type | Default | Props |
| --- | --- | --- |--- |
| defaultFontSizes | boolean | true | |
| customFontSize | boolean | true | |
| fontStyle | boolean | true | |
| fontWeight | boolean | true | |
Expand Down
2 changes: 1 addition & 1 deletion lib/block-supports/pattern.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
* @param WP_Block_Type $block_type Block Type.
*/
function gutenberg_register_pattern_support( $block_type ) {
$pattern_support = property_exists( $block_type, 'supports' ) ? _wp_array_get( $block_type->supports, array( '__experimentalConnections' ), false ) : false;
$pattern_support = 'core/paragraph' === $block_type->name ? true : false;

if ( $pattern_support ) {
if ( ! $block_type->uses_context ) {
Expand Down
29 changes: 15 additions & 14 deletions lib/class-wp-theme-json-gutenberg.php
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ class WP_Theme_JSON_Gutenberg {
),
array(
'path' => array( 'typography', 'fontSizes' ),
'prevent_override' => false,
'prevent_override' => array( 'typography', 'defaultFontSizes' ),
'use_default_names' => true,
'value_func' => 'gutenberg_get_typography_font_size_value',
'css_vars' => '--wp--preset--font-size--$slug',
Expand Down Expand Up @@ -411,19 +411,20 @@ class WP_Theme_JSON_Gutenberg {
'defaultPresets' => null,
),
'typography' => array(
'fluid' => null,
'customFontSize' => null,
'dropCap' => null,
'fontFamilies' => null,
'fontSizes' => null,
'fontStyle' => null,
'fontWeight' => null,
'letterSpacing' => null,
'lineHeight' => null,
'textColumns' => null,
'textDecoration' => null,
'textTransform' => null,
'writingMode' => null,
'fluid' => null,
'customFontSize' => null,
'defaultFontSizes' => null,
'dropCap' => null,
'fontFamilies' => null,
'fontSizes' => null,
'fontStyle' => null,
'fontWeight' => null,
'letterSpacing' => null,
'lineHeight' => null,
'textColumns' => null,
'textDecoration' => null,
'textTransform' => null,
'writingMode' => null,
),
);

Expand Down
110 changes: 110 additions & 0 deletions lib/experimental/block-bindings/html-processing.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
<?php
/**
* Define the mechanism to replace the HTML depending on the block attributes.
*
* @package gutenberg
*/

if ( ! function_exists( 'block_bindings_replace_html' ) ) {
/**
* Depending on the block attributes, replace the proper HTML based on the value returned by the source.
*
* @param string $block_content Block Content.
* @param string $block_name The name of the block to process.
* @param string $block_attr The attribute of the block we want to process.
* @param string $source_value The value used to replace the HTML.
*/
function block_bindings_replace_html( $block_content, $block_name, $block_attr, $source_value ) {
$block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block_name );
if ( null === $block_type ) {
return;
}

// Depending on the attribute source, the processing will be different.
switch ( $block_type->attributes[ $block_attr ]['source'] ) {
case 'html':
case 'rich-text':
$block_reader = new WP_HTML_Tag_Processor( $block_content );

// TODO: Support for CSS selectors whenever they are ready in the HTML API.
// In the meantime, support comma-separated selectors by exploding them into an array.
$selectors = explode( ',', $block_type->attributes[ $block_attr ]['selector'] );
// Add a bookmark to the first tag to be able to iterate over the selectors.
$block_reader->next_tag();
$block_reader->set_bookmark( 'iterate-selectors' );

// TODO: This shouldn't be needed when the `set_inner_html` function is ready.
// Store the parent tag and its attributes to be able to restore them later in the button.
// The button block has a wrapper while the paragraph and heading blocks don't.
if ( 'core/button' === $block_name ) {
$button_wrapper = $block_reader->get_tag();
$button_wrapper_attribute_names = $block_reader->get_attribute_names_with_prefix( '' );
$button_wrapper_attrs = array();
foreach ( $button_wrapper_attribute_names as $name ) {
$button_wrapper_attrs[ $name ] = $block_reader->get_attribute( $name );
}
}

foreach ( $selectors as $selector ) {
// If the parent tag, or any of its children, matches the selector, replace the HTML.
if ( strcasecmp( $block_reader->get_tag( $selector ), $selector ) === 0 || $block_reader->next_tag(
array(
'tag_name' => $selector,
)
) ) {
$block_reader->release_bookmark( 'iterate-selectors' );

// TODO: Use `set_inner_html` method whenever it's ready in the HTML API.
// Until then, it is hardcoded for the paragraph, heading, and button blocks.
// Store the tag and its attributes to be able to restore them later.
$selector_attribute_names = $block_reader->get_attribute_names_with_prefix( '' );
$selector_attrs = array();
foreach ( $selector_attribute_names as $name ) {
$selector_attrs[ $name ] = $block_reader->get_attribute( $name );
}
$selector_markup = "<$selector>" . esc_html( $source_value ) . "</$selector>";
$amended_content = new WP_HTML_Tag_Processor( $selector_markup );
$amended_content->next_tag();
foreach ( $selector_attrs as $attribute_key => $attribute_value ) {
$amended_content->set_attribute( $attribute_key, $attribute_value );
}
if ( 'core/paragraph' === $block_name || 'core/heading' === $block_name ) {
return $amended_content->get_updated_html();
}
if ( 'core/button' === $block_name ) {
$button_markup = "<$button_wrapper>{$amended_content->get_updated_html()}</$button_wrapper>";
$amended_button = new WP_HTML_Tag_Processor( $button_markup );
$amended_button->next_tag();
foreach ( $button_wrapper_attrs as $attribute_key => $attribute_value ) {
$amended_button->set_attribute( $attribute_key, $attribute_value );
}
return $amended_button->get_updated_html();
}
} else {
$block_reader->seek( 'iterate-selectors' );
}
}
$block_reader->release_bookmark( 'iterate-selectors' );
return $block_content;

case 'attribute':
$amended_content = new WP_HTML_Tag_Processor( $block_content );
if ( ! $amended_content->next_tag(
array(
// TODO: build the query from CSS selector.
'tag_name' => $block_type->attributes[ $block_attr ]['selector'],
)
) ) {
return $block_content;
}
$amended_content->set_attribute( $block_type->attributes[ $block_attr ]['attribute'], esc_attr( $source_value ) );
return $amended_content->get_updated_html();
break;

default:
return $block_content;
break;
}
return;
}
}
20 changes: 20 additions & 0 deletions lib/experimental/block-bindings/index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php
/**
* Require the necessary files.
*
* @package gutenberg
*/

require_once __DIR__ . '/sources/index.php';
require_once __DIR__ . '/html-processing.php';

// Register the sources.
$gutenberg_experiments = get_option( 'gutenberg-experiments' );
if ( $gutenberg_experiments ) {
if ( array_key_exists( 'gutenberg-pattern-partial-syncing', $gutenberg_experiments ) ) {
require_once __DIR__ . '/sources/pattern.php';
}
if ( array_key_exists( 'gutenberg-block-bindings', $gutenberg_experiments ) ) {
require_once __DIR__ . '/sources/post-meta.php';
}
}
32 changes: 32 additions & 0 deletions lib/experimental/block-bindings/sources/index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php
/**
* Define the mechanism to add new sources available in the block bindings API.
*
* @package gutenberg
*/

global $block_bindings_sources;
$block_bindings_sources = array();
if ( ! function_exists( 'register_block_bindings_source' ) ) {
/**
* Function to register a new source.
*
* @param string $source_name The name of the source.
* @param string $label The label of the source.
* @param callable(object, object, string): string $apply - The callback executed when the source is processed during block rendering.
* - object $source_attrs: Object containing source ID used to look up the override value, i.e. {"value": "{ID}"}.
* - object $block_instance: The block instance.
* - string $attribute_name: The name of an attribute used to retrieve an override value from the block context.
* The callable should return a string that will be used to override the block's original value.
*
*
* @return void
*/
function register_block_bindings_source( $source_name, $label, $apply ) {
global $block_bindings_sources;
$block_bindings_sources[ $source_name ] = array(
'label' => $label,
'apply' => $apply,
);
}
}
21 changes: 21 additions & 0 deletions lib/experimental/block-bindings/sources/pattern.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php
/**
* Add the metadata source to the block bindings API.
*
* @package gutenberg
*/

if ( function_exists( 'register_block_bindings_source' ) ) {
$pattern_source_callback = function ( $source_attrs, $block_instance, $attribute_name ) {
if ( ! _wp_array_get( $block_instance->attributes, array( 'metadata', 'id' ), false ) ) {
return null;
}
$block_id = $block_instance->attributes['metadata']['id'];
return _wp_array_get( $block_instance->context, array( 'pattern/overrides', $block_id, $attribute_name ), null );
};
register_block_bindings_source(
'pattern_attributes',
__( 'Pattern Attributes', 'gutenberg' ),
$pattern_source_callback
);
}
25 changes: 25 additions & 0 deletions lib/experimental/block-bindings/sources/post-meta.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php
/**
* Add the post_meta source to the block bindings API.
*
* @package gutenberg
*/

if ( function_exists( 'register_block_bindings_source' ) ) {
$post_meta_source_callback = function ( $source_attrs ) {
// Use the postId attribute if available
if ( isset( $source_attrs['postId'] ) ) {
$post_id = $source_attrs['postId'];
} else {
// I tried using $block_instance->context['postId'] but it wasn't available in the image block.
$post_id = get_the_ID();
}

return get_post_meta( $post_id, $source_attrs['value'], true );
};
register_block_bindings_source(
'post_meta',
__( 'Post Meta', 'gutenberg' ),
$post_meta_source_callback
);
}
Loading

0 comments on commit cc7807b

Please sign in to comment.