Add Site Editor and PHP changes from Gutenberg 10.1 - 11.9

- First pass at adding the site editor from the Gutenberg plugin to
  wp-admin/site-editor.php.
- Adds miscellaneous PHP changes from Gutenberg 10.1 - 11.9.

Follows [52042].
See #54337.
Props youknowriad, aristath, hellofromtonya, gziolo.

Built from https://develop.svn.wordpress.org/trunk@52069


git-svn-id: http://core.svn.wordpress.org/trunk@51661 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
noisysocks 2021-11-09 02:17:17 +00:00
parent 84dae82fd3
commit c421e9b34a
88 changed files with 18748 additions and 158 deletions

View File

@ -202,8 +202,24 @@ if ( ! is_multisite() && current_user_can( 'update_themes' ) ) {
/* translators: %s: Number of available theme updates. */
$submenu['themes.php'][5] = array( sprintf( __( 'Themes %s' ), $count ), $appearance_cap, 'themes.php' );
if ( wp_is_block_template_theme() ) {
$submenu['themes.php'][6] = array(
sprintf(
/* translators: %s: "beta" label */
__( 'Editor %s' ),
'<span class="awaiting-mod">' . __( 'beta' ) . '</span>'
),
'edit_theme_options',
'site-editor.php',
);
}
// Hide Customize link on block themes unless a plugin or theme is using
// customize_register to add a setting.
if ( ! wp_is_block_template_theme() || has_action( 'customize_register' ) ) {
$customize_url = add_query_arg( 'return', urlencode( remove_query_arg( wp_removable_query_args(), wp_unslash( $_SERVER['REQUEST_URI'] ) ) ), 'customize.php' );
$submenu['themes.php'][6] = array( __( 'Customize' ), 'customize', esc_url( $customize_url ), '', 'hide-if-no-customize' );
$submenu['themes.php'][7] = array( __( 'Customize' ), 'customize', esc_url( $customize_url ), '', 'hide-if-no-customize' );
}
if ( current_theme_supports( 'menus' ) || current_theme_supports( 'widgets' ) ) {
$submenu['themes.php'][10] = array( __( 'Menus' ), 'edit_theme_options', 'nav-menus.php' );

115
wp-admin/site-editor.php Normal file
View File

@ -0,0 +1,115 @@
<?php
/**
* Site Editor administration screen.
*
* @package WordPress
* @subpackage Administration
*/
global $post, $editor_styles;
/** WordPress Administration Bootstrap */
require_once __DIR__ . '/admin.php';
if ( ! current_user_can( 'edit_theme_options' ) ) {
wp_die(
'<h1>' . __( 'You need a higher level of permission.' ) . '</h1>' .
'<p>' . __( 'Sorry, you are not allowed to edit theme options on this site.' ) . '</p>',
403
);
}
if ( ! wp_is_block_template_theme() ) {
wp_die( __( 'The theme you are currently using is not compatible with Full Site Editing.' ) );
}
// Used in the HTML title tag.
$title = __( 'Editor (beta)' );
$parent_file = 'themes.php';
// Flag that we're loading the block editor.
$current_screen = get_current_screen();
$current_screen->is_block_editor( true );
$block_editor_context = new WP_Block_Editor_Context();
$active_global_styles_id = WP_Theme_JSON_Resolver::get_user_custom_post_type_id();
$active_theme = wp_get_theme()->get_stylesheet();
$preload_paths = array(
array( '/wp/v2/media', 'OPTIONS' ),
'/',
'/wp/v2/types?context=edit',
'/wp/v2/taxonomies?context=edit',
'/wp/v2/pages?context=edit',
'/wp/v2/categories?context=edit',
'/wp/v2/posts?context=edit',
'/wp/v2/tags?context=edit',
'/wp/v2/templates?context=edit',
'/wp/v2/template-parts?context=edit',
'/wp/v2/settings',
'/wp/v2/themes?context=edit&status=active',
'/wp/v2/global-styles/' . $active_global_styles_id . '?context=edit',
'/wp/v2/global-styles/' . $active_global_styles_id,
'/wp/v2/themes/' . $active_theme . '/global-styles',
);
block_editor_rest_api_preload( $preload_paths, $block_editor_context );
$editor_settings = get_block_editor_settings(
array(
'siteUrl' => site_url(),
'postsPerPage' => get_option( 'posts_per_page' ),
'styles' => get_block_editor_theme_styles(),
'defaultTemplateTypes' => get_default_block_template_types(),
'defaultTemplatePartAreas' => get_allowed_block_template_part_areas(),
'__experimentalBlockPatterns' => WP_Block_Patterns_Registry::get_instance()->get_all_registered(),
'__experimentalBlockPatternCategories' => WP_Block_Pattern_Categories_Registry::get_instance()->get_all_registered(),
),
$block_editor_context
);
wp_add_inline_script(
'wp-edit-site',
sprintf(
'wp.domReady( function() {
wp.editSite.initialize( "site-editor", %s );
} );',
wp_json_encode( $editor_settings )
)
);
// Preload server-registered block schemas.
wp_add_inline_script(
'wp-blocks',
'wp.blocks.unstable__bootstrapServerSideBlockDefinitions(' . wp_json_encode( get_block_editor_server_block_settings() ) . ');'
);
wp_add_inline_script(
'wp-blocks',
sprintf( 'wp.blocks.setCategories( %s );', wp_json_encode( get_block_categories( $post ) ) ),
'after'
);
wp_enqueue_script( 'wp-edit-site' );
wp_enqueue_script( 'wp-format-library' );
wp_enqueue_style( 'wp-edit-site' );
wp_enqueue_style( 'wp-format-library' );
wp_enqueue_media();
if (
current_theme_supports( 'wp-block-styles' ) ||
( ! is_array( $editor_styles ) || count( $editor_styles ) === 0 )
) {
wp_enqueue_style( 'wp-block-library-theme' );
}
/** This action is documented in wp-admin/edit-form-blocks.php */
do_action( 'enqueue_block_editor_assets' );
require_once ABSPATH . 'wp-admin/admin-header.php';
?>
<div id="site-editor" class="edit-site"></div>
<?php
require_once ABSPATH . 'wp-admin/admin-footer.php';

File diff suppressed because one or more lines are too long

View File

@ -9,7 +9,7 @@ return array(
'title' => _x( 'Image at left', 'Block pattern title' ),
'blockTypes' => array( 'core/query' ),
'categories' => array( 'query' ),
'content' => '<!-- wp:query {"query":{"perPage":1,"pages":0,"offset":0,"postType":"post","categoryIds":[],"tagIds":[],"order":"desc","orderBy":"date","author":"","search":"","exclude":[],"sticky":"","inherit":false}} -->
'content' => '<!-- wp:query {"query":{"perPage":3,"pages":0,"offset":0,"postType":"post","categoryIds":[],"tagIds":[],"order":"desc","orderBy":"date","author":"","search":"","exclude":[],"sticky":"","inherit":false}} -->
<div class="wp-block-query">
<!-- wp:post-template -->
<!-- wp:columns {"align":"wide"} -->

View File

@ -9,7 +9,7 @@ return array(
'title' => _x( 'Small image and title', 'Block pattern title' ),
'blockTypes' => array( 'core/query' ),
'categories' => array( 'query' ),
'content' => '<!-- wp:query {"query":{"perPage":1,"pages":0,"offset":0,"postType":"post","categoryIds":[],"tagIds":[],"order":"desc","orderBy":"date","author":"","search":"","exclude":[],"sticky":"","inherit":false}} -->
'content' => '<!-- wp:query {"query":{"perPage":3,"pages":0,"offset":0,"postType":"post","categoryIds":[],"tagIds":[],"order":"desc","orderBy":"date","author":"","search":"","exclude":[],"sticky":"","inherit":false}} -->
<div class="wp-block-query">
<!-- wp:post-template -->
<!-- wp:columns {"verticalAlignment":"center"} -->

View File

@ -9,7 +9,7 @@ return array(
'title' => _x( 'Standard', 'Block pattern title' ),
'blockTypes' => array( 'core/query' ),
'categories' => array( 'query' ),
'content' => '<!-- wp:query {"query":{"perPage":1,"pages":0,"offset":0,"postType":"post","categoryIds":[],"tagIds":[],"order":"desc","orderBy":"date","author":"","search":"","exclude":[],"sticky":"","inherit":false}} -->
'content' => '<!-- wp:query {"query":{"perPage":3,"pages":0,"offset":0,"postType":"post","categoryIds":[],"tagIds":[],"order":"desc","orderBy":"date","author":"","search":"","exclude":[],"sticky":"","inherit":false}} -->
<div class="wp-block-query">
<!-- wp:post-template -->
<!-- wp:post-title {"isLink":true} /-->

View File

@ -63,8 +63,23 @@ function wp_apply_border_support( $block_type, $block_attributes ) {
wp_has_border_feature_support( $block_type, 'radius' ) &&
isset( $block_attributes['style']['border']['radius'] )
) {
$border_radius = (int) $block_attributes['style']['border']['radius'];
$styles[] = sprintf( 'border-radius: %dpx;', $border_radius );
$border_radius = $block_attributes['style']['border']['radius'];
if ( is_array( $border_radius ) ) {
// We have individual border radius corner values.
foreach ( $border_radius as $key => $radius ) {
// Convert CamelCase corner name to kebab-case.
$corner = strtolower( preg_replace( '/(?<!^)[A-Z]/', '-$0', $key ) );
$styles[] = sprintf( 'border-%s-radius: %s;', $corner, $radius );
}
} else {
// This check handles original unitless implementation.
if ( is_numeric( $border_radius ) ) {
$border_radius .= 'px';
}
$styles[] = sprintf( 'border-radius: %s;', $border_radius );
}
}
// Border style.
@ -81,8 +96,14 @@ function wp_apply_border_support( $block_type, $block_attributes ) {
wp_has_border_feature_support( $block_type, 'width' ) &&
isset( $block_attributes['style']['border']['width'] )
) {
$border_width = intval( $block_attributes['style']['border']['width'] );
$styles[] = sprintf( 'border-width: %dpx;', $border_width );
$border_width = $block_attributes['style']['border']['width'];
// This check handles original unitless implementation.
if ( is_numeric( $border_width ) ) {
$border_width .= 'px';
}
$styles[] = sprintf( 'border-width: %s;', $border_width );
}
// Border color.

View File

@ -99,7 +99,7 @@ function wp_apply_colors_support( $block_type, $block_attributes ) {
}
// Apply color class or inline style.
if ( $has_named_text_color ) {
$classes[] = sprintf( 'has-%s-color', $block_attributes['textColor'] );
$classes[] = sprintf( 'has-%s-color', _wp_to_kebab_case( $block_attributes['textColor'] ) );
} elseif ( $has_custom_text_color ) {
$styles[] = sprintf( 'color: %s;', $block_attributes['style']['color']['text'] );
}
@ -116,7 +116,7 @@ function wp_apply_colors_support( $block_type, $block_attributes ) {
}
// Apply background color classes or styles.
if ( $has_named_background_color ) {
$classes[] = sprintf( 'has-%s-background-color', $block_attributes['backgroundColor'] );
$classes[] = sprintf( 'has-%s-background-color', _wp_to_kebab_case( $block_attributes['backgroundColor'] ) );
} elseif ( $has_custom_background_color ) {
$styles[] = sprintf( 'background-color: %s;', $block_attributes['style']['color']['background'] );
}
@ -132,7 +132,7 @@ function wp_apply_colors_support( $block_type, $block_attributes ) {
}
// Apply required background class.
if ( $has_named_gradient ) {
$classes[] = sprintf( 'has-%s-gradient-background', $block_attributes['gradient'] );
$classes[] = sprintf( 'has-%s-gradient-background', _wp_to_kebab_case( $block_attributes['gradient'] ) );
} elseif ( $has_custom_gradient ) {
$styles[] = sprintf( 'background: %s;', $block_attributes['style']['color']['gradient'] );
}

View File

@ -0,0 +1,92 @@
<?php
/**
* Dimensions block support flag.
*
* This does not include the `spacing` block support even though that visually
* appears under the "Dimensions" panel in the editor. It remains in its
* original `spacing.php` file for backwards compatibility.
*
* @package WordPress
* @since 5.9.0
*/
/**
* Registers the style block attribute for block types that support it.
*
* @since 5.9.0
* @access private
*
* @param WP_Block_Type $block_type Block Type.
*/
function wp_register_dimensions_support( $block_type ) {
// Setup attributes and styles within that if needed.
if ( ! $block_type->attributes ) {
$block_type->attributes = array();
}
// Check for existing style attribute definition e.g. from block.json.
if ( array_key_exists( 'style', $block_type->attributes ) ) {
return;
}
$has_dimensions_support = block_has_support( $block_type, array( '__experimentalDimensions' ), false );
// Future block supports such as height & width will be added here.
if ( $has_dimensions_support ) {
$block_type->attributes['style'] = array(
'type' => 'object',
);
}
}
/**
* Add CSS classes for block dimensions to the incoming attributes array.
* This will be applied to the block markup in the front-end.
*
* @since 5.9.0
* @access private
*
* @param WP_Block_Type $block_type Block Type.
* @param array $block_attributes Block attributes.
*
* @return array Block dimensions CSS classes and inline styles.
*/
function wp_apply_dimensions_support( $block_type, $block_attributes ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
if ( wp_skip_dimensions_serialization( $block_type ) ) {
return array();
}
$styles = array();
// Height support to be added in near future.
// Width support to be added in near future.
return empty( $styles ) ? array() : array( 'style' => implode( ' ', $styles ) );
}
/**
* Checks whether serialization of the current block's dimensions properties
* should occur.
*
* @since 5.9.0
* @access private
*
* @param WP_Block_type $block_type Block type.
*
* @return boolean Whether to serialize spacing support styles & classes.
*/
function wp_skip_dimensions_serialization( $block_type ) {
$dimensions_support = _wp_array_get( $block_type->supports, array( '__experimentalDimensions' ), false );
return is_array( $dimensions_support ) &&
array_key_exists( '__experimentalSkipSerialization', $dimensions_support ) &&
$dimensions_support['__experimentalSkipSerialization'];
}
// Register the block support.
WP_Block_Supports::get_instance()->register(
'dimensions',
array(
'register_attribute' => 'wp_register_dimensions_support',
'apply' => 'wp_apply_dimensions_support',
)
);

View File

@ -266,7 +266,7 @@ function wp_tinycolor_string_to_rgb( $color_str ) {
$hsla_regexp = '/^hsla' . $permissive_match4 . '$/';
if ( preg_match( $hsla_regexp, $color_str, $match ) ) {
return wp_tinycolor_hsl_to_rgb(
$rgb = wp_tinycolor_hsl_to_rgb(
array(
'h' => $match[1],
's' => $match[2],
@ -384,13 +384,16 @@ function wp_register_duotone_support( $block_type ) {
}
}
}
/**
* Renders the duotone filter SVG and returns the CSS filter property to
* reference the rendered SVG.
*
* @since 5.9.0
*
* @access private
* @param array $preset Duotone preset value as seen in theme.json.
*
* @return string Duotone CSS filter property.
*/
function wp_render_duotone_filter_preset( $preset ) {
@ -460,13 +463,11 @@ function wp_render_duotone_filter_preset( $preset ) {
}
add_action(
/*
* Safari doesn't render SVG filters defined in data URIs,
* and SVG filters won't render in the head of a document,
* so the next best place to put the SVG is in the footer.
*/
// Safari doesn't render SVG filters defined in data URIs,
// and SVG filters won't render in the head of a document,
// so the next best place to put the SVG is in the footer.
is_admin() ? 'admin_footer' : 'wp_footer',
static function () use ( $svg ) {
function () use ( $svg ) {
echo $svg;
}
);
@ -502,84 +503,38 @@ function wp_render_duotone_support( $block_content, $block ) {
return $block_content;
}
$duotone_colors = $block['attrs']['style']['color']['duotone'];
$duotone_values = array(
'r' => array(),
'g' => array(),
'b' => array(),
$filter_preset = array(
'slug' => uniqid(),
'colors' => $block['attrs']['style']['color']['duotone'],
);
foreach ( $duotone_colors as $color_str ) {
$color = wp_tinycolor_string_to_rgb( $color_str );
$filter_property = wp_render_duotone_filter_preset( $filter_preset );
$filter_id = 'wp-duotone-' . $filter_preset['slug'];
$duotone_values['r'][] = $color['r'] / 255;
$duotone_values['g'][] = $color['g'] / 255;
$duotone_values['b'][] = $color['b'] / 255;
$scope = '.' . $filter_id;
$selectors = explode( ',', $duotone_support );
$scoped = array();
foreach ( $selectors as $sel ) {
$scoped[] = $scope . ' ' . trim( $sel );
}
$selector = implode( ', ', $scoped );
$duotone_id = 'wp-duotone-filter-' . uniqid();
// !important is needed because these styles render before global styles,
// and they should be overriding the duotone filters set by global styles.
$filter_style = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG
? $selector . " {\n\tfilter: " . $filter_property . " !important;\n}\n"
: $selector . '{filter:' . $filter_property . ' !important;}';
$selectors = explode( ',', $duotone_support );
$selectors_scoped = array_map(
static function ( $selector ) use ( $duotone_id ) {
return '.' . $duotone_id . ' ' . trim( $selector );
},
$selectors
);
$selectors_group = implode( ', ', $selectors_scoped );
ob_start();
?>
<style>
<?php echo $selectors_group; ?> {
filter: url( <?php echo esc_url( '#' . $duotone_id ); ?> );
}
</style>
<svg
xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 0 0"
width="0"
height="0"
focusable="false"
role="none"
style="visibility: hidden; position: absolute; left: -9999px; overflow: hidden;"
>
<defs>
<filter id="<?php echo esc_attr( $duotone_id ); ?>">
<feColorMatrix
type="matrix"
<?php // phpcs:disable Generic.WhiteSpace.DisallowSpaceIndent ?>
values=".299 .587 .114 0 0
.299 .587 .114 0 0
.299 .587 .114 0 0
0 0 0 1 0"
<?php // phpcs:enable Generic.WhiteSpace.DisallowSpaceIndent ?>
/>
<feComponentTransfer color-interpolation-filters="sRGB" >
<feFuncR type="table" tableValues="<?php echo esc_attr( implode( ' ', $duotone_values['r'] ) ); ?>" />
<feFuncG type="table" tableValues="<?php echo esc_attr( implode( ' ', $duotone_values['g'] ) ); ?>" />
<feFuncB type="table" tableValues="<?php echo esc_attr( implode( ' ', $duotone_values['b'] ) ); ?>" />
</feComponentTransfer>
</filter>
</defs>
</svg>
<?php
$duotone = ob_get_clean();
wp_register_style( $filter_id, false, array(), true, true );
wp_add_inline_style( $filter_id, $filter_style );
wp_enqueue_style( $filter_id );
// Like the layout hook, this assumes the hook only applies to blocks with a single wrapper.
$content = preg_replace(
return preg_replace(
'/' . preg_quote( 'class="', '/' ) . '/',
'class="' . $duotone_id . ' ',
'class="' . $filter_id . ' ',
$block_content,
1
);
return $content . $duotone;
}
// Register the block support.

View File

@ -17,6 +17,10 @@
* @return string Filtered block content.
*/
function wp_render_elements_support( $block_content, $block ) {
if ( ! $block_content ) {
return $block_content;
}
$link_color = null;
if ( ! empty( $block['attrs'] ) ) {
$link_color = _wp_array_get( $block['attrs'], array( 'style', 'elements', 'link', 'color', 'text' ), null );
@ -42,7 +46,7 @@ function wp_render_elements_support( $block_content, $block ) {
}
$link_color_declaration = esc_html( safecss_filter_attr( "color: $link_color" ) );
$style = "<style>.$class_name a{" . $link_color_declaration . " !important;}</style>\n";
$style = "<style>.$class_name a{" . $link_color_declaration . ";}</style>\n";
// Like the layout hook this assumes the hook only applies to blocks with a single wrapper.
// Retrieve the opening tag of the first HTML element.
@ -64,8 +68,19 @@ function wp_render_elements_support( $block_content, $block ) {
$content = substr_replace( $block_content, ' class="' . $class_name . '"', $first_element_offset + strlen( $first_element ) - 1, 0 );
}
return $content . $style;
/*
* Ideally styles should be loaded in the head, but blocks may be parsed
* after that, so loading in the footer for now.
* See https://core.trac.wordpress.org/ticket/53494.
*/
add_action(
'wp_footer',
static function () use ( $style ) {
echo $style;
}
);
return $content;
}
add_filter( 'render_block', 'wp_render_elements_support', 10, 2 );

View File

@ -29,6 +29,106 @@ function wp_register_layout_support( $block_type ) {
}
}
/**
* Generates the CSS corresponding to the provided layout.
*
* @since 5.9.0
* @access private
*
* @param string $selector CSS selector.
* @param array $layout Layout object. The one that is passed has already checked the existance of default block layout.
* @param boolean $has_block_gap_support Whether the theme has support for the block gap.
*
* @return string CSS style.
*/
function wp_get_layout_style( $selector, $layout, $has_block_gap_support = false ) {
$layout_type = isset( $layout['type'] ) ? $layout['type'] : 'default';
$style = '';
if ( 'default' === $layout_type ) {
$content_size = isset( $layout['contentSize'] ) ? $layout['contentSize'] : null;
$wide_size = isset( $layout['wideSize'] ) ? $layout['wideSize'] : null;
$all_max_width_value = $content_size ? $content_size : $wide_size;
$wide_max_width_value = $wide_size ? $wide_size : $content_size;
// Make sure there is a single CSS rule, and all tags are stripped for security.
// TODO: Use `safecss_filter_attr` instead - once https://core.trac.wordpress.org/ticket/46197 is patched.
$all_max_width_value = wp_strip_all_tags( explode( ';', $all_max_width_value )[0] );
$wide_max_width_value = wp_strip_all_tags( explode( ';', $wide_max_width_value )[0] );
$style = '';
if ( $content_size || $wide_size ) {
$style = "$selector > * {";
$style .= 'max-width: ' . esc_html( $all_max_width_value ) . ';';
$style .= 'margin-left: auto !important;';
$style .= 'margin-right: auto !important;';
$style .= '}';
$style .= "$selector > .alignwide { max-width: " . esc_html( $wide_max_width_value ) . ';}';
$style .= "$selector .alignfull { max-width: none; }";
}
$style .= "$selector .alignleft { float: left; margin-right: 2em; }";
$style .= "$selector .alignright { float: right; margin-left: 2em; }";
if ( $has_block_gap_support ) {
$style .= "$selector > * { margin-top: 0; margin-bottom: 0; }";
$style .= "$selector > * + * { margin-top: var( --wp--style--block-gap ); margin-bottom: 0; }";
}
} elseif ( 'flex' === $layout_type ) {
$layout_orientation = isset( $layout['orientation'] ) ? $layout['orientation'] : 'horizontal';
$justify_content_options = array(
'left' => 'flex-start',
'right' => 'flex-end',
'center' => 'center',
);
if ( 'horizontal' === $layout_orientation ) {
$justify_content_options += array( 'space-between' => 'space-between' );
}
$flex_wrap_options = array( 'wrap', 'nowrap' );
$flex_wrap = ! empty( $layout['flexWrap'] ) && in_array( $layout['flexWrap'], $flex_wrap_options, true ) ?
$layout['flexWrap'] :
'wrap';
$style = "$selector {";
$style .= 'display: flex;';
if ( $has_block_gap_support ) {
$style .= 'gap: var( --wp--style--block-gap, 0.5em );';
} else {
$style .= 'gap: 0.5em;';
}
$style .= "flex-wrap: $flex_wrap;";
$style .= 'align-items: center;';
if ( 'horizontal' === $layout_orientation ) {
$style .= 'align-items: center;';
/**
* Add this style only if is not empty for backwards compatibility,
* since we intend to convert blocks that had flex layout implemented
* by custom css.
*/
if ( ! empty( $layout['justifyContent'] ) && array_key_exists( $layout['justifyContent'], $justify_content_options ) ) {
$style .= "justify-content: {$justify_content_options[ $layout['justifyContent'] ]};";
// --justification-setting allows children to inherit the value regardless or row or column direction.
$style .= "--justification-setting: {$justify_content_options[ $layout['justifyContent'] ]};";
}
} else {
$style .= 'flex-direction: column;';
if ( ! empty( $layout['justifyContent'] ) && array_key_exists( $layout['justifyContent'], $justify_content_options ) ) {
$style .= "align-items: {$justify_content_options[ $layout['justifyContent'] ]};";
$style .= "--justification-setting: {$justify_content_options[ $layout['justifyContent'] ]};";
}
}
$style .= '}';
$style .= "$selector > * { margin: 0; }";
}
return $style;
}
/**
* Renders the layout config to the block wrapper.
*
@ -42,47 +142,25 @@ function wp_register_layout_support( $block_type ) {
function wp_render_layout_support_flag( $block_content, $block ) {
$block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] );
$support_layout = block_has_support( $block_type, array( '__experimentalLayout' ), false );
if ( ! $support_layout || ! isset( $block['attrs']['layout'] ) ) {
if ( ! $support_layout ) {
return $block_content;
}
$used_layout = $block['attrs']['layout'];
$block_gap = wp_get_global_settings( array( 'spacing', 'blockGap' ) );
$default_layout = wp_get_global_settings( array( 'layout' ) );
$has_block_gap_support = isset( $block_gap ) ? null !== $block_gap : false;
$default_block_layout = _wp_array_get( $block_type->supports, array( '__experimentalLayout', 'default' ), array() );
$used_layout = isset( $block['attrs']['layout'] ) ? $block['attrs']['layout'] : $default_block_layout;
if ( isset( $used_layout['inherit'] ) && $used_layout['inherit'] ) {
$tree = WP_Theme_JSON_Resolver::get_merged_data();
$default_layout = _wp_array_get( $tree->get_settings(), array( 'layout' ) );
if ( ! $default_layout ) {
return $block_content;
}
$used_layout = $default_layout;
}
$id = uniqid();
$content_size = isset( $used_layout['contentSize'] ) ? $used_layout['contentSize'] : null;
$wide_size = isset( $used_layout['wideSize'] ) ? $used_layout['wideSize'] : null;
$all_max_width_value = $content_size ? $content_size : $wide_size;
$wide_max_width_value = $wide_size ? $wide_size : $content_size;
// Make sure there is a single CSS rule, and all tags are stripped for security.
$all_max_width_value = safecss_filter_attr( explode( ';', $all_max_width_value )[0] );
$wide_max_width_value = safecss_filter_attr( explode( ';', $wide_max_width_value )[0] );
$style = '';
if ( $content_size || $wide_size ) {
$style = ".wp-container-$id > * {";
$style .= 'max-width: ' . esc_html( $all_max_width_value ) . ';';
$style .= 'margin-left: auto !important;';
$style .= 'margin-right: auto !important;';
$style .= '}';
$style .= ".wp-container-$id > .alignwide { max-width: " . esc_html( $wide_max_width_value ) . ';}';
$style .= ".wp-container-$id .alignfull { max-width: none; }";
}
$style .= ".wp-container-$id .alignleft { float: left; margin-right: 2em; }";
$style .= ".wp-container-$id .alignright { float: right; margin-left: 2em; }";
$id = uniqid();
$style = wp_get_layout_style( ".wp-container-$id", $used_layout, $has_block_gap_support );
// This assumes the hook only applies to blocks with a single wrapper.
// I think this is a reasonable limitation for that particular hook.
$content = preg_replace(
@ -92,7 +170,19 @@ function wp_render_layout_support_flag( $block_content, $block ) {
1
);
return $content . '<style>' . $style . '</style>';
/*
* Ideally styles should be loaded in the head, but blocks may be parsed
* after that, so loading in the footer for now.
* See https://core.trac.wordpress.org/ticket/53494.
*/
add_action(
'wp_footer',
static function () use ( $style ) {
echo '<style>' . $style . '</style>';
}
);
return $content;
}
// Register the block support.
@ -123,7 +213,8 @@ function wp_restore_group_inner_container( $block_content, $block ) {
if (
'core/group' !== $block['blockName'] ||
WP_Theme_JSON_Resolver::theme_has_support() ||
1 === preg_match( $group_with_inner_container_regex, $block_content )
1 === preg_match( $group_with_inner_container_regex, $block_content ) ||
( isset( $block['attrs']['layout']['type'] ) && 'default' !== $block['attrs']['layout']['type'] )
) {
return $block_content;
}

View File

@ -1,6 +1,9 @@
<?php
/**
* Spacing block support flag.
* For backwards compatibility, this remains separate to the dimensions.php
* block support despite both belonging under a single panel in the editor.
*
* @package WordPress
* @since 5.8.0
@ -42,25 +45,33 @@ function wp_register_spacing_support( $block_type ) {
* @return array Block spacing CSS classes and inline styles.
*/
function wp_apply_spacing_support( $block_type, $block_attributes ) {
$has_padding_support = wp_has_spacing_feature_support( $block_type, 'padding' );
$has_margin_support = wp_has_spacing_feature_support( $block_type, 'margin' );
if ( wp_skip_spacing_serialization( $block_type ) ) {
return array();
}
$has_padding_support = block_has_support( $block_type, array( 'spacing', 'padding' ), false );
$has_margin_support = block_has_support( $block_type, array( 'spacing', 'margin' ), false );
$styles = array();
if ( $has_padding_support ) {
$padding_value = _wp_array_get( $block_attributes, array( 'style', 'spacing', 'padding' ), null );
if ( null !== $padding_value ) {
if ( is_array( $padding_value ) ) {
foreach ( $padding_value as $key => $value ) {
$styles[] = sprintf( 'padding-%s: %s;', $key, $value );
}
} elseif ( null !== $padding_value ) {
$styles[] = sprintf( 'padding: %s;', $padding_value );
}
}
if ( $has_margin_support ) {
$margin_value = _wp_array_get( $block_attributes, array( 'style', 'spacing', 'margin' ), null );
if ( null !== $margin_value ) {
if ( is_array( $margin_value ) ) {
foreach ( $margin_value as $key => $value ) {
$styles[] = sprintf( 'margin-%s: %s;', $key, $value );
}
} elseif ( null !== $margin_value ) {
$styles[] = sprintf( 'margin: %s;', $margin_value );
}
}
@ -68,20 +79,75 @@ function wp_apply_spacing_support( $block_type, $block_attributes ) {
}
/**
* Checks whether the current block type supports the spacing feature requested.
* Checks whether serialization of the current block's spacing properties should
* occur.
*
* @since 5.8.0
* @since 5.9.0
* @access private
*
* @param WP_Block_Type $block_type Block type to check for support.
* @param string $feature Name of the feature to check support for.
* @param mixed $default Fallback value for feature support. Default false.
* @return bool Whether the feature is supported.
* @param WP_Block_Type $block_type Block type.
*
* @return boolean Whether to serialize spacing support styles & classes.
*/
function wp_has_spacing_feature_support( $block_type, $feature, $default = false ) {
// Check if the specific feature has been opted into individually
// via nested flag under `spacing`.
return block_has_support( $block_type, array( 'spacing', $feature ), $default );
function wp_skip_spacing_serialization( $block_type ) {
$spacing_support = _wp_array_get( $block_type->supports, array( 'spacing' ), false );
return is_array( $spacing_support ) &&
array_key_exists( '__experimentalSkipSerialization', $spacing_support ) &&
$spacing_support['__experimentalSkipSerialization'];
}
/**
* Renders the spacing gap support to the block wrapper, to ensure
* that the CSS variable is rendered in all environments.
*
* @since 5.9.0
* @access private
*
* @param string $block_content Rendered block content.
* @param array $block Block object.
* @return string Filtered block content.
*/
function wp_render_spacing_gap_support( $block_content, $block ) {
$block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] );
$has_gap_support = block_has_support( $block_type, array( 'spacing', 'blockGap' ), false );
if ( ! $has_gap_support || ! isset( $block['attrs']['style']['spacing']['blockGap'] ) ) {
return $block_content;
}
$gap_value = $block['attrs']['style']['spacing']['blockGap'];
// Skip if gap value contains unsupported characters.
// Regex for CSS value borrowed from `safecss_filter_attr`, and used here
// because we only want to match against the value, not the CSS attribute.
if ( preg_match( '%[\\\(&=}]|/\*%', $gap_value ) ) {
return $block_content;
}
$style = sprintf(
'--wp--style--block-gap: %s',
esc_attr( $gap_value )
);
// Attempt to update an existing style attribute on the wrapper element.
$injected_style = preg_replace(
'/^([^>.]+?)(' . preg_quote( 'style="', '/' ) . ')(?=.+?>)/',
'$1$2' . $style . '; ',
$block_content,
1
);
// If there is no existing style attribute, add one to the wrapper element.
if ( $injected_style === $block_content ) {
$injected_style = preg_replace(
'/<([a-zA-Z0-9]+)([ >])/',
'<$1 style="' . $style . '"$2',
$block_content,
1
);
};
return $injected_style;
}
// Register the block support.
@ -92,3 +158,5 @@ WP_Block_Supports::get_instance()->register(
'apply' => 'wp_apply_spacing_support',
)
);
add_filter( 'render_block', 'wp_render_spacing_gap_support', 10, 2 );

View File

@ -28,6 +28,7 @@ function wp_register_typography_support( $block_type ) {
$has_font_size_support = _wp_array_get( $typography_supports, array( 'fontSize' ), false );
$has_font_style_support = _wp_array_get( $typography_supports, array( '__experimentalFontStyle' ), false );
$has_font_weight_support = _wp_array_get( $typography_supports, array( '__experimentalFontWeight' ), false );
$has_letter_spacing_support = _wp_array_get( $typography_supports, array( '__experimentalLetterSpacing' ), false );
$has_line_height_support = _wp_array_get( $typography_supports, array( 'lineHeight' ), false );
$has_text_decoration_support = _wp_array_get( $typography_supports, array( '__experimentalTextDecoration' ), false );
$has_text_transform_support = _wp_array_get( $typography_supports, array( '__experimentalTextTransform' ), false );
@ -36,6 +37,7 @@ function wp_register_typography_support( $block_type ) {
|| $has_font_size_support
|| $has_font_style_support
|| $has_font_weight_support
|| $has_letter_spacing_support
|| $has_line_height_support
|| $has_text_decoration_support
|| $has_text_transform_support;
@ -93,6 +95,7 @@ function wp_apply_typography_support( $block_type, $block_attributes ) {
$has_font_size_support = _wp_array_get( $typography_supports, array( 'fontSize' ), false );
$has_font_style_support = _wp_array_get( $typography_supports, array( '__experimentalFontStyle' ), false );
$has_font_weight_support = _wp_array_get( $typography_supports, array( '__experimentalFontWeight' ), false );
$has_letter_spacing_support = _wp_array_get( $typography_supports, array( '__experimentalLetterSpacing' ), false );
$has_line_height_support = _wp_array_get( $typography_supports, array( 'lineHeight' ), false );
$has_text_decoration_support = _wp_array_get( $typography_supports, array( '__experimentalTextDecoration' ), false );
$has_text_transform_support = _wp_array_get( $typography_supports, array( '__experimentalTextTransform' ), false );
@ -102,24 +105,28 @@ function wp_apply_typography_support( $block_type, $block_attributes ) {
$has_custom_font_size = isset( $block_attributes['style']['typography']['fontSize'] );
if ( $has_named_font_size ) {
$classes[] = sprintf( 'has-%s-font-size', $block_attributes['fontSize'] );
$classes[] = sprintf( 'has-%s-font-size', _wp_to_kebab_case( $block_attributes['fontSize'] ) );
} elseif ( $has_custom_font_size ) {
$styles[] = sprintf( 'font-size: %s;', $block_attributes['style']['typography']['fontSize'] );
}
}
if ( $has_font_family_support ) {
$has_font_family = isset( $block_attributes['style']['typography']['fontFamily'] );
if ( $has_font_family ) {
$font_family = $block_attributes['style']['typography']['fontFamily'];
if ( strpos( $font_family, 'var:preset|font-family' ) !== false ) {
// Get the name from the string and add proper styles.
$index_to_splice = strrpos( $font_family, '|' ) + 1;
$font_family_name = substr( $font_family, $index_to_splice );
$styles[] = sprintf( 'font-family: var(--wp--preset--font-family--%s);', $font_family_name );
} else {
$styles[] = sprintf( 'font-family: %s;', $block_attributes['style']['typography']['fontFamily'] );
$has_named_font_family = array_key_exists( 'fontFamily', $block_attributes );
$has_custom_font_family = isset( $block_attributes['style']['typography']['fontFamily'] );
if ( $has_named_font_family ) {
$classes[] = sprintf( 'has-%s-font-family', _wp_to_kebab_case( $block_attributes['fontFamily'] ) );
} elseif ( $has_custom_font_family ) {
// Before using classes, the value was serialized as a CSS Custom Property.
// We don't need this code path when it lands in core.
$font_family_custom = $block_attributes['style']['typography']['fontFamily'];
if ( strpos( $font_family_custom, 'var:preset|font-family' ) !== false ) {
$index_to_splice = strrpos( $font_family_custom, '|' ) + 1;
$font_family_slug = _wp_to_kebab_case( substr( $font_family_custom, $index_to_splice ) );
$font_family_custom = sprintf( 'var(--wp--preset--font-family--%s)', $font_family_slug );
}
$styles[] = sprintf( 'font-family: %s;', $font_family_custom );
}
}
@ -158,6 +165,13 @@ function wp_apply_typography_support( $block_type, $block_attributes ) {
}
}
if ( $has_letter_spacing_support ) {
$letter_spacing_style = wp_typography_get_css_variable_inline_style( $block_attributes, 'letterSpacing', 'letter-spacing' );
if ( $letter_spacing_style ) {
$styles[] = $letter_spacing_style;
}
}
if ( ! empty( $classes ) ) {
$attributes['class'] = implode( ' ', $classes );
}

View File

@ -1182,3 +1182,117 @@ function get_query_pagination_arrow( $block, $is_next ) {
}
return null;
}
/**
* Enqueue a stylesheet for a specific block.
*
* If the theme has opted-in to separate-styles loading,
* then the stylesheet will be enqueued on-render,
* otherwise when the block inits.
*
* @param string $block_name The block-name, including namespace.
* @param array $args An array of arguments [handle,src,deps,ver,media].
*
* @return void
*/
function wp_enqueue_block_style( $block_name, $args ) {
$args = wp_parse_args(
$args,
array(
'handle' => '',
'src' => '',
'deps' => array(),
'ver' => false,
'media' => 'all',
)
);
/**
* Callback function to register and enqueue styles.
*
* @param string $content When the callback is used for the render_block filter,
* the content needs to be returned so the function parameter
* is to ensure the content exists.
*
* @return string
*/
$callback = static function( $content ) use ( $args ) {
// Register the stylesheet.
if ( ! empty( $args['src'] ) ) {
wp_register_style( $args['handle'], $args['src'], $args['deps'], $args['ver'], $args['media'] );
}
// Add `path` data if provided.
if ( isset( $args['path'] ) ) {
wp_style_add_data( $args['handle'], 'path', $args['path'] );
// Get the RTL file path.
$rtl_file_path = str_replace( '.css', '-rtl.css', $args['path'] );
// Add RTL stylesheet.
if ( file_exists( $rtl_file_path ) ) {
wp_style_add_data( $args['hanle'], 'rtl', 'replace' );
if ( is_rtl() ) {
wp_style_add_data( $args['handle'], 'path', $rtl_file_path );
}
}
}
// Enqueue the stylesheet.
wp_enqueue_style( $args['handle'] );
return $content;
};
$hook = did_action( 'wp_enqueue_scripts' ) ? 'wp_footer' : 'wp_enqueue_scripts';
if ( wp_should_load_separate_core_block_assets() ) {
$hook = "render_block_$block_name";
}
/*
* The filter's callback here is an anonymous function because
* using a named function in this case is not possible.
*
* The function cannot be unhooked, however, users are still able
* to dequeue the stylesheets registered/enqueued by the callback
* which is why in this case, using an anonymous function
* was deemed acceptable.
*/
add_filter( $hook, $callback );
// Enqueue assets in the editor.
add_action( 'enqueue_block_assets', $callback );
}
/**
* Allow multiple block styles.
*
* @param array $metadata Metadata for registering a block type.
*
* @return array
*/
function _wp_multiple_block_styles( $metadata ) {
foreach ( array( 'style', 'editorStyle' ) as $key ) {
if ( ! empty( $metadata[ $key ] ) && is_array( $metadata[ $key ] ) ) {
$default_style = array_shift( $metadata[ $key ] );
foreach ( $metadata[ $key ] as $handle ) {
$args = array( 'handle' => $handle );
if ( 0 === strpos( $handle, 'file:' ) && isset( $metadata['file'] ) ) {
$style_path = remove_block_asset_path_prefix( $handle );
$args = array(
'handle' => sanitize_key( "{$metadata['name']}-{$style_path}" ),
'src' => plugins_url( $style_path, $metadata['file'] ),
);
}
wp_enqueue_block_style( $metadata['name'], $args );
}
// Only return the 1st item in the array.
$metadata[ $key ] = $default_style;
}
}
return $metadata;
}
add_filter( 'block_type_metadata', '_wp_multiple_block_styles' );

View File

@ -15,29 +15,38 @@ require ABSPATH . WPINC . '/blocks/latest-comments.php';
require ABSPATH . WPINC . '/blocks/latest-posts.php';
require ABSPATH . WPINC . '/blocks/legacy-widget.php';
require ABSPATH . WPINC . '/blocks/loginout.php';
require ABSPATH . WPINC . '/blocks/navigation-area.php';
require ABSPATH . WPINC . '/blocks/navigation-link.php';
require ABSPATH . WPINC . '/blocks/navigation-submenu.php';
require ABSPATH . WPINC . '/blocks/navigation.php';
require ABSPATH . WPINC . '/blocks/page-list.php';
require ABSPATH . WPINC . '/blocks/pattern.php';
require ABSPATH . WPINC . '/blocks/post-author.php';
require ABSPATH . WPINC . '/blocks/post-comments.php';
require ABSPATH . WPINC . '/blocks/post-content.php';
require ABSPATH . WPINC . '/blocks/post-date.php';
require ABSPATH . WPINC . '/blocks/post-excerpt.php';
require ABSPATH . WPINC . '/blocks/post-featured-image.php';
require ABSPATH . WPINC . '/blocks/post-navigation-link.php';
require ABSPATH . WPINC . '/blocks/post-template.php';
require ABSPATH . WPINC . '/blocks/post-terms.php';
require ABSPATH . WPINC . '/blocks/post-title.php';
require ABSPATH . WPINC . '/blocks/post-template.php';
require ABSPATH . WPINC . '/blocks/query.php';
require ABSPATH . WPINC . '/blocks/query-pagination.php';
require ABSPATH . WPINC . '/blocks/query-pagination-next.php';
require ABSPATH . WPINC . '/blocks/query-pagination-numbers.php';
require ABSPATH . WPINC . '/blocks/query-pagination-previous.php';
require ABSPATH . WPINC . '/blocks/query-pagination.php';
require ABSPATH . WPINC . '/blocks/query-title.php';
require ABSPATH . WPINC . '/blocks/query.php';
require ABSPATH . WPINC . '/blocks/rss.php';
require ABSPATH . WPINC . '/blocks/search.php';
require ABSPATH . WPINC . '/blocks/shortcode.php';
require ABSPATH . WPINC . '/blocks/site-tagline.php';
require ABSPATH . WPINC . '/blocks/site-logo.php';
require ABSPATH . WPINC . '/blocks/site-tagline.php';
require ABSPATH . WPINC . '/blocks/site-title.php';
require ABSPATH . WPINC . '/blocks/social-link.php';
require ABSPATH . WPINC . '/blocks/tag-cloud.php';
require ABSPATH . WPINC . '/blocks/template-part.php';
require ABSPATH . WPINC . '/blocks/term-description.php';
/**
* Registers core block types using metadata files.

View File

@ -0,0 +1,21 @@
<?php
/**
* Server-side rendering of the `core/navigation-area` block.
*
* @package gutenberg
*/
/**
* Registers the `core/navigation-area` block on the server.
*/
function register_block_core_navigation_area() {
register_block_type_from_metadata(
__DIR__ . '/navigation-area',
array(
'provides_context' => array(
'navigationArea' => 'area',
),
)
);
}
add_action( 'init', 'register_block_core_navigation_area' );

View File

@ -0,0 +1,27 @@
{
"apiVersion": 2,
"name": "core/navigation-area",
"title": "Navigation Area",
"category": "theme",
"description": "Define a navigation area for your theme. The navigation block associated with this area will be automatically displayed.",
"keywords": [
"menu",
"navigation",
"links",
"location"
],
"textdomain": "default",
"attributes": {
"area": {
"type": "string",
"default": "primary"
}
},
"providesContext": {
"navigationArea": "area"
},
"supports": {
"html": false,
"inserter": true
}
}

View File

@ -0,0 +1,350 @@
<?php
/**
* Server-side rendering of the `core/navigation-link` block.
*
* @package gutenberg
*/
/**
* Build an array with CSS classes and inline styles defining the colors
* which will be applied to the navigation markup in the front-end.
*
* @param array $context Navigation block context.
* @param array $attributes Block attributes.
* @return array Colors CSS classes and inline styles.
*/
function block_core_navigation_link_build_css_colors( $context, $attributes ) {
$colors = array(
'css_classes' => array(),
'inline_styles' => '',
);
$is_sub_menu = isset( $attributes['isTopLevelLink'] ) ? ( ! $attributes['isTopLevelLink'] ) : false;
// Text color.
$named_text_color = null;
$custom_text_color = null;
if ( $is_sub_menu && array_key_exists( 'customOverlayTextColor', $context ) ) {
$custom_text_color = $context['customOverlayTextColor'];
} elseif ( $is_sub_menu && array_key_exists( 'overlayTextColor', $context ) ) {
$named_text_color = $context['overlayTextColor'];
} elseif ( array_key_exists( 'customTextColor', $context ) ) {
$custom_text_color = $context['customTextColor'];
} elseif ( array_key_exists( 'textColor', $context ) ) {
$named_text_color = $context['textColor'];
} elseif ( isset( $context['style']['color']['text'] ) ) {
$custom_text_color = $context['style']['color']['text'];
}
// If has text color.
if ( ! is_null( $named_text_color ) ) {
// Add the color class.
array_push( $colors['css_classes'], 'has-text-color', sprintf( 'has-%s-color', $named_text_color ) );
} elseif ( ! is_null( $custom_text_color ) ) {
// Add the custom color inline style.
$colors['css_classes'][] = 'has-text-color';
$colors['inline_styles'] .= sprintf( 'color: %s;', $custom_text_color );
}
// Background color.
$named_background_color = null;
$custom_background_color = null;
if ( $is_sub_menu && array_key_exists( 'customOverlayBackgroundColor', $context ) ) {
$custom_background_color = $context['customOverlayBackgroundColor'];
} elseif ( $is_sub_menu && array_key_exists( 'overlayBackgroundColor', $context ) ) {
$named_background_color = $context['overlayBackgroundColor'];
} elseif ( array_key_exists( 'customBackgroundColor', $context ) ) {
$custom_background_color = $context['customBackgroundColor'];
} elseif ( array_key_exists( 'backgroundColor', $context ) ) {
$named_background_color = $context['backgroundColor'];
} elseif ( isset( $context['style']['color']['background'] ) ) {
$custom_background_color = $context['style']['color']['background'];
}
// If has background color.
if ( ! is_null( $named_background_color ) ) {
// Add the background-color class.
array_push( $colors['css_classes'], 'has-background', sprintf( 'has-%s-background-color', $named_background_color ) );
} elseif ( ! is_null( $custom_background_color ) ) {
// Add the custom background-color inline style.
$colors['css_classes'][] = 'has-background';
$colors['inline_styles'] .= sprintf( 'background-color: %s;', $custom_background_color );
}
return $colors;
}
/**
* Build an array with CSS classes and inline styles defining the font sizes
* which will be applied to the navigation markup in the front-end.
*
* @param array $context Navigation block context.
* @return array Font size CSS classes and inline styles.
*/
function block_core_navigation_link_build_css_font_sizes( $context ) {
// CSS classes.
$font_sizes = array(
'css_classes' => array(),
'inline_styles' => '',
);
$has_named_font_size = array_key_exists( 'fontSize', $context );
$has_custom_font_size = isset( $context['style']['typography']['fontSize'] );
if ( $has_named_font_size ) {
// Add the font size class.
$font_sizes['css_classes'][] = sprintf( 'has-%s-font-size', $context['fontSize'] );
} elseif ( $has_custom_font_size ) {
// Add the custom font size inline style.
$font_sizes['inline_styles'] = sprintf( 'font-size: %spx;', $context['style']['typography']['fontSize'] );
}
return $font_sizes;
}
/**
* Returns the top-level submenu SVG chevron icon.
*
* @return string
*/
function block_core_navigation_link_render_submenu_icon() {
return '<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12" fill="none" role="img" aria-hidden="true" focusable="false"><path d="M1.50002 4L6.00002 8L10.5 4" stroke-width="1.5"></path></svg>';
}
/**
* Renders the `core/navigation-link` block.
*
* @param array $attributes The block attributes.
* @param array $content The saved content.
* @param array $block The parsed block.
*
* @return string Returns the post content with the legacy widget added.
*/
function render_block_core_navigation_link( $attributes, $content, $block ) {
$navigation_link_has_id = isset( $attributes['id'] ) && is_numeric( $attributes['id'] );
$is_post_type = isset( $attributes['kind'] ) && 'post-type' === $attributes['kind'];
$is_post_type = $is_post_type || isset( $attributes['type'] ) && ( 'post' === $attributes['type'] || 'page' === $attributes['type'] );
// Don't render the block's subtree if it is a draft or if the ID does not exist.
if ( $is_post_type && $navigation_link_has_id ) {
$post = get_post( $attributes['id'] );
if ( ! $post || 'publish' !== $post->post_status ) {
return '';
}
}
// Don't render the block's subtree if it has no label.
if ( empty( $attributes['label'] ) ) {
return '';
}
$colors = block_core_navigation_link_build_css_colors( $block->context, $attributes );
$font_sizes = block_core_navigation_link_build_css_font_sizes( $block->context );
$classes = array_merge(
$colors['css_classes'],
$font_sizes['css_classes']
);
$style_attribute = ( $colors['inline_styles'] . $font_sizes['inline_styles'] );
$css_classes = trim( implode( ' ', $classes ) );
$has_submenu = count( $block->inner_blocks ) > 0;
$is_active = ! empty( $attributes['id'] ) && ( get_the_ID() === $attributes['id'] );
$wrapper_attributes = get_block_wrapper_attributes(
array(
'class' => $css_classes . ' wp-block-navigation-item' . ( $has_submenu ? ' has-child' : '' ) .
( $is_active ? ' current-menu-item' : '' ),
'style' => $style_attribute,
)
);
$html = '<li ' . $wrapper_attributes . '>' .
'<a class="wp-block-navigation-item__content" ';
// Start appending HTML attributes to anchor tag.
if ( isset( $attributes['url'] ) ) {
$html .= ' href="' . esc_url( $attributes['url'] ) . '"';
}
if ( $is_active ) {
$html .= ' aria-current="page"';
}
if ( isset( $attributes['opensInNewTab'] ) && true === $attributes['opensInNewTab'] ) {
$html .= ' target="_blank" ';
}
if ( isset( $attributes['rel'] ) ) {
$html .= ' rel="' . esc_attr( $attributes['rel'] ) . '"';
} elseif ( isset( $attributes['nofollow'] ) && $attributes['nofollow'] ) {
$html .= ' rel="nofollow"';
}
if ( isset( $attributes['title'] ) ) {
$html .= ' title="' . esc_attr( $attributes['title'] ) . '"';
}
// End appending HTML attributes to anchor tag.
// Start anchor tag content.
$html .= '>' .
// Wrap title with span to isolate it from submenu icon.
'<span class="wp-block-navigation-item__label">';
if ( isset( $attributes['label'] ) ) {
$html .= wp_kses(
$attributes['label'],
array(
'code' => array(),
'em' => array(),
'img' => array(
'scale' => array(),
'class' => array(),
'style' => array(),
'src' => array(),
'alt' => array(),
),
's' => array(),
'span' => array(
'style' => array(),
),
'strong' => array(),
)
);
}
$html .= '</span>';
if ( isset( $block->context['showSubmenuIcon'] ) && $block->context['showSubmenuIcon'] && $has_submenu ) {
// The submenu icon can be hidden by a CSS rule on the Navigation Block.
$html .= '<span class="wp-block-navigation__submenu-icon">' . block_core_navigation_link_render_submenu_icon() . '</span>';
}
$html .= '</a>';
// End anchor tag content.
if ( $has_submenu ) {
$inner_blocks_html = '';
foreach ( $block->inner_blocks as $inner_block ) {
$inner_blocks_html .= $inner_block->render();
}
$html .= sprintf(
'<ul class="wp-block-navigation__submenu-container">%s</ul>',
$inner_blocks_html
);
}
$html .= '</li>';
return $html;
}
/**
* Returns a navigation link variation
*
* @param WP_Taxonomy|WP_Post_Type $entity post type or taxonomy entity.
* @param string $kind string of value 'taxonomy' or 'post-type'.
*
* @return array
*/
function build_variation_for_navigation_link( $entity, $kind ) {
$title = '';
$description = '';
if ( property_exists( $entity->labels, 'item_link' ) ) {
$title = $entity->labels->item_link;
}
if ( property_exists( $entity->labels, 'item_link_description' ) ) {
$description = $entity->labels->item_link_description;
}
$variation = array(
'name' => $entity->name,
'title' => $title,
'description' => $description,
'attributes' => array(
'type' => $entity->name,
'kind' => $kind,
),
);
// Tweak some value for the variations.
$variation_overrides = array(
'post_tag' => array(
'name' => 'tag',
'attributes' => array(
'type' => 'tag',
'kind' => $kind,
),
),
'post_format' => array(
// The item_link and item_link_description for post formats is the
// same as for tags, so need to be overridden.
'title' => __( 'Post Format Link' ),
'description' => __( 'A link to a post format' ),
'attributes' => array(
'type' => 'post_format',
'kind' => $kind,
),
),
);
if ( array_key_exists( $entity->name, $variation_overrides ) ) {
$variation = array_merge(
$variation,
$variation_overrides[ $entity->name ]
);
}
return $variation;
}
/**
* Register the navigation link block.
*
* @uses render_block_core_navigation()
* @throws WP_Error An WP_Error exception parsing the block definition.
*/
function register_block_core_navigation_link() {
$post_types = get_post_types( array( 'show_in_nav_menus' => true ), 'objects' );
$taxonomies = get_taxonomies( array( 'show_in_nav_menus' => true ), 'objects' );
// Use two separate arrays as a way to order the variations in the UI.
// Known variations (like Post Link and Page Link) are added to the
// `built_ins` array. Variations for custom post types and taxonomies are
// added to the `variations` array and will always appear after `built-ins.
$built_ins = array();
$variations = array();
if ( $post_types ) {
foreach ( $post_types as $post_type ) {
$variation = build_variation_for_navigation_link( $post_type, 'post-type' );
if ( $post_type->_builtin ) {
$built_ins[] = $variation;
} else {
$variations[] = $variation;
}
}
}
if ( $taxonomies ) {
foreach ( $taxonomies as $taxonomy ) {
$variation = build_variation_for_navigation_link( $taxonomy, 'taxonomy' );
if ( $taxonomy->_builtin ) {
$built_ins[] = $variation;
} else {
$variations[] = $variation;
}
}
}
register_block_type_from_metadata(
__DIR__ . '/navigation-link',
array(
'render_callback' => 'render_block_core_navigation_link',
'variations' => array_merge( $built_ins, $variations ),
)
);
}
add_action( 'init', 'register_block_core_navigation_link' );

View File

@ -0,0 +1,65 @@
{
"apiVersion": 2,
"name": "core/navigation-link",
"title": "Custom Link",
"category": "design",
"parent": [
"core/navigation"
],
"description": "Add a page, link, or another item to your navigation.",
"textdomain": "default",
"attributes": {
"label": {
"type": "string"
},
"type": {
"type": "string"
},
"description": {
"type": "string"
},
"rel": {
"type": "string"
},
"id": {
"type": "number"
},
"opensInNewTab": {
"type": "boolean",
"default": false
},
"url": {
"type": "string"
},
"title": {
"type": "string"
},
"kind": {
"type": "string"
},
"isTopLevelLink": {
"type": "boolean"
}
},
"usesContext": [
"textColor",
"customTextColor",
"backgroundColor",
"customBackgroundColor",
"overlayTextColor",
"customOverlayTextColor",
"overlayBackgroundColor",
"customOverlayBackgroundColor",
"fontSize",
"customFontSize",
"showSubmenuIcon",
"style"
],
"supports": {
"reusable": false,
"html": false,
"__experimentalSlashInserter": true
},
"editorStyle": "wp-block-navigation-link-editor",
"style": "wp-block-navigation-link"
}

View File

@ -0,0 +1,163 @@
/**
* Colors
*/
/**
* Breakpoints & Media Queries
*/
/**
* SCSS Variables.
*
* Please use variables from this sheet to ensure consistency across the UI.
* Don't add to this sheet unless you're pretty sure the value will be reused in many places.
* For example, don't add rules to this sheet that affect block visuals. It's purely for UI.
*/
/**
* Colors
*/
/**
* Fonts & basic variables.
*/
/**
* Grid System.
* https://make.wordpress.org/design/2019/10/31/proposal-a-consistent-spacing-system-for-wordpress/
*/
/**
* Dimensions.
*/
/**
* Shadows.
*/
/**
* Editor widths.
*/
/**
* Block & Editor UI.
*/
/**
* Block paddings.
*/
/**
* React Native specific.
* These variables do not appear to be used anywhere else.
*/
/**
* Converts a hex value into the rgb equivalent.
*
* @param {string} hex - the hexadecimal value to convert
* @return {string} comma separated rgb values
*/
/**
* Breakpoint mixins
*/
/**
* Long content fade mixin
*
* Creates a fading overlay to signify that the content is longer
* than the space allows.
*/
/**
* Focus styles.
*/
/**
* Applies editor left position to the selector passed as argument
*/
/**
* Styles that are reused verbatim in a few places
*/
/**
* Allows users to opt-out of animations via OS-level preferences.
*/
/**
* Reset default styles for JavaScript UI based pages.
* This is a WP-admin agnostic reset
*/
/**
* Reset the WP Admin page styles for Gutenberg-like pages.
*/
/**
* Submenus.
*/
.wp-block-navigation .has-child {
cursor: pointer;
}
.wp-block-navigation .has-child .wp-block-navigation__submenu-container {
z-index: 28;
}
.wp-block-navigation .has-child:hover .wp-block-navigation__submenu-container {
z-index: 29;
}
.wp-block-navigation .has-child.is-selected > .wp-block-navigation__submenu-container, .wp-block-navigation .has-child.has-child-selected > .wp-block-navigation__submenu-container {
visibility: visible !important;
opacity: 1 !important;
min-width: 200px !important;
height: auto !important;
width: auto !important;
}
/**
* Navigation Items.
*/
.wp-block-navigation-item .wp-block-navigation-item__content {
cursor: text;
}
.wp-block-navigation-item.is-editing, .wp-block-navigation-item.is-selected {
min-width: 20px;
}
.wp-block-navigation-item .block-list-appender {
margin-top: 16px;
margin-left: auto;
margin-bottom: 16px;
margin-right: 16px;
}
/**
* Menu item setup state. Is shown when a menu item has no URL configured.
*/
.wp-block-navigation-link__placeholder {
position: relative;
text-decoration: none !important;
box-shadow: none !important;
background-image: none !important;
}
.wp-block-navigation-link__placeholder .wp-block-navigation-link__placeholder-text span {
--wp-underline-color: var(--wp-admin-theme-color);
background-image: linear-gradient(-45deg, transparent 20%, var(--wp-underline-color) 30%, var(--wp-underline-color) 36%, transparent 46%), linear-gradient(-135deg, transparent 54%, var(--wp-underline-color) 64%, var(--wp-underline-color) 70%, transparent 80%);
background-position: 100% 100%;
background-size: 6px 3px;
background-repeat: repeat-x;
padding-bottom: 0.1em;
}
.is-dark-theme .wp-block-navigation-link__placeholder .wp-block-navigation-link__placeholder-text span {
--wp-underline-color: #fff;
}
.wp-block-navigation-link__placeholder.wp-block-navigation-item__content {
cursor: pointer;
}
/**
* Link Control Transforms
*/
.link-control-transform {
border-top: 1px solid #ccc;
padding: 0 16px 8px 16px;
}
.link-control-transform__subheading {
font-size: 11px;
text-transform: uppercase;
font-weight: 500;
color: #1e1e1e;
margin-bottom: 1.5em;
}
.link-control-transform__items {
display: flex;
justify-content: space-between;
}
.link-control-transform__item {
flex-basis: 33%;
flex-direction: column;
gap: 8px;
height: auto;
}

View File

@ -0,0 +1 @@
.wp-block-navigation .has-child{cursor:pointer}.wp-block-navigation .has-child .wp-block-navigation__submenu-container{z-index:28}.wp-block-navigation .has-child:hover .wp-block-navigation__submenu-container{z-index:29}.wp-block-navigation .has-child.has-child-selected>.wp-block-navigation__submenu-container,.wp-block-navigation .has-child.is-selected>.wp-block-navigation__submenu-container{visibility:visible!important;opacity:1!important;min-width:200px!important;height:auto!important;width:auto!important}.wp-block-navigation-item .wp-block-navigation-item__content{cursor:text}.wp-block-navigation-item.is-editing,.wp-block-navigation-item.is-selected{min-width:20px}.wp-block-navigation-item .block-list-appender{margin:16px 16px 16px auto}.wp-block-navigation-link__placeholder{position:relative;text-decoration:none!important;box-shadow:none!important;background-image:none!important}.wp-block-navigation-link__placeholder .wp-block-navigation-link__placeholder-text span{--wp-underline-color:var(--wp-admin-theme-color);background-image:linear-gradient(-45deg,transparent 20%,var(--wp-underline-color) 30%,var(--wp-underline-color) 36%,transparent 46%),linear-gradient(-135deg,transparent 54%,var(--wp-underline-color) 64%,var(--wp-underline-color) 70%,transparent 80%);background-position:100% 100%;background-size:6px 3px;background-repeat:repeat-x;padding-bottom:.1em}.is-dark-theme .wp-block-navigation-link__placeholder .wp-block-navigation-link__placeholder-text span{--wp-underline-color:#fff}.wp-block-navigation-link__placeholder.wp-block-navigation-item__content{cursor:pointer}.link-control-transform{border-top:1px solid #ccc;padding:0 16px 8px}.link-control-transform__subheading{font-size:11px;text-transform:uppercase;font-weight:500;color:#1e1e1e;margin-bottom:1.5em}.link-control-transform__items{display:flex;justify-content:space-between}.link-control-transform__item{flex-basis:33%;flex-direction:column;gap:8px;height:auto}

View File

@ -0,0 +1,163 @@
/**
* Colors
*/
/**
* Breakpoints & Media Queries
*/
/**
* SCSS Variables.
*
* Please use variables from this sheet to ensure consistency across the UI.
* Don't add to this sheet unless you're pretty sure the value will be reused in many places.
* For example, don't add rules to this sheet that affect block visuals. It's purely for UI.
*/
/**
* Colors
*/
/**
* Fonts & basic variables.
*/
/**
* Grid System.
* https://make.wordpress.org/design/2019/10/31/proposal-a-consistent-spacing-system-for-wordpress/
*/
/**
* Dimensions.
*/
/**
* Shadows.
*/
/**
* Editor widths.
*/
/**
* Block & Editor UI.
*/
/**
* Block paddings.
*/
/**
* React Native specific.
* These variables do not appear to be used anywhere else.
*/
/**
* Converts a hex value into the rgb equivalent.
*
* @param {string} hex - the hexadecimal value to convert
* @return {string} comma separated rgb values
*/
/**
* Breakpoint mixins
*/
/**
* Long content fade mixin
*
* Creates a fading overlay to signify that the content is longer
* than the space allows.
*/
/**
* Focus styles.
*/
/**
* Applies editor left position to the selector passed as argument
*/
/**
* Styles that are reused verbatim in a few places
*/
/**
* Allows users to opt-out of animations via OS-level preferences.
*/
/**
* Reset default styles for JavaScript UI based pages.
* This is a WP-admin agnostic reset
*/
/**
* Reset the WP Admin page styles for Gutenberg-like pages.
*/
/**
* Submenus.
*/
.wp-block-navigation .has-child {
cursor: pointer;
}
.wp-block-navigation .has-child .wp-block-navigation__submenu-container {
z-index: 28;
}
.wp-block-navigation .has-child:hover .wp-block-navigation__submenu-container {
z-index: 29;
}
.wp-block-navigation .has-child.is-selected > .wp-block-navigation__submenu-container, .wp-block-navigation .has-child.has-child-selected > .wp-block-navigation__submenu-container {
visibility: visible !important;
opacity: 1 !important;
min-width: 200px !important;
height: auto !important;
width: auto !important;
}
/**
* Navigation Items.
*/
.wp-block-navigation-item .wp-block-navigation-item__content {
cursor: text;
}
.wp-block-navigation-item.is-editing, .wp-block-navigation-item.is-selected {
min-width: 20px;
}
.wp-block-navigation-item .block-list-appender {
margin-top: 16px;
margin-right: auto;
margin-bottom: 16px;
margin-left: 16px;
}
/**
* Menu item setup state. Is shown when a menu item has no URL configured.
*/
.wp-block-navigation-link__placeholder {
position: relative;
text-decoration: none !important;
box-shadow: none !important;
background-image: none !important;
}
.wp-block-navigation-link__placeholder .wp-block-navigation-link__placeholder-text span {
--wp-underline-color: var(--wp-admin-theme-color);
background-image: linear-gradient(45deg, transparent 20%, var(--wp-underline-color) 30%, var(--wp-underline-color) 36%, transparent 46%), linear-gradient(135deg, transparent 54%, var(--wp-underline-color) 64%, var(--wp-underline-color) 70%, transparent 80%);
background-position: 0 100%;
background-size: 6px 3px;
background-repeat: repeat-x;
padding-bottom: 0.1em;
}
.is-dark-theme .wp-block-navigation-link__placeholder .wp-block-navigation-link__placeholder-text span {
--wp-underline-color: #fff;
}
.wp-block-navigation-link__placeholder.wp-block-navigation-item__content {
cursor: pointer;
}
/**
* Link Control Transforms
*/
.link-control-transform {
border-top: 1px solid #ccc;
padding: 0 16px 8px 16px;
}
.link-control-transform__subheading {
font-size: 11px;
text-transform: uppercase;
font-weight: 500;
color: #1e1e1e;
margin-bottom: 1.5em;
}
.link-control-transform__items {
display: flex;
justify-content: space-between;
}
.link-control-transform__item {
flex-basis: 33%;
flex-direction: column;
gap: 8px;
height: auto;
}

View File

@ -0,0 +1 @@
.wp-block-navigation .has-child{cursor:pointer}.wp-block-navigation .has-child .wp-block-navigation__submenu-container{z-index:28}.wp-block-navigation .has-child:hover .wp-block-navigation__submenu-container{z-index:29}.wp-block-navigation .has-child.has-child-selected>.wp-block-navigation__submenu-container,.wp-block-navigation .has-child.is-selected>.wp-block-navigation__submenu-container{visibility:visible!important;opacity:1!important;min-width:200px!important;height:auto!important;width:auto!important}.wp-block-navigation-item .wp-block-navigation-item__content{cursor:text}.wp-block-navigation-item.is-editing,.wp-block-navigation-item.is-selected{min-width:20px}.wp-block-navigation-item .block-list-appender{margin:16px auto 16px 16px}.wp-block-navigation-link__placeholder{position:relative;text-decoration:none!important;box-shadow:none!important;background-image:none!important}.wp-block-navigation-link__placeholder .wp-block-navigation-link__placeholder-text span{--wp-underline-color:var(--wp-admin-theme-color);background-image:linear-gradient(45deg,transparent 20%,var(--wp-underline-color) 30%,var(--wp-underline-color) 36%,transparent 46%),linear-gradient(135deg,transparent 54%,var(--wp-underline-color) 64%,var(--wp-underline-color) 70%,transparent 80%);background-position:0 100%;background-size:6px 3px;background-repeat:repeat-x;padding-bottom:.1em}.is-dark-theme .wp-block-navigation-link__placeholder .wp-block-navigation-link__placeholder-text span{--wp-underline-color:#fff}.wp-block-navigation-link__placeholder.wp-block-navigation-item__content{cursor:pointer}.link-control-transform{border-top:1px solid #ccc;padding:0 16px 8px}.link-control-transform__subheading{font-size:11px;text-transform:uppercase;font-weight:500;color:#1e1e1e;margin-bottom:1.5em}.link-control-transform__items{display:flex;justify-content:space-between}.link-control-transform__item{flex-basis:33%;flex-direction:column;gap:8px;height:auto}

View File

@ -0,0 +1,80 @@
/**
* Colors
*/
/**
* Breakpoints & Media Queries
*/
/**
* SCSS Variables.
*
* Please use variables from this sheet to ensure consistency across the UI.
* Don't add to this sheet unless you're pretty sure the value will be reused in many places.
* For example, don't add rules to this sheet that affect block visuals. It's purely for UI.
*/
/**
* Colors
*/
/**
* Fonts & basic variables.
*/
/**
* Grid System.
* https://make.wordpress.org/design/2019/10/31/proposal-a-consistent-spacing-system-for-wordpress/
*/
/**
* Dimensions.
*/
/**
* Shadows.
*/
/**
* Editor widths.
*/
/**
* Block & Editor UI.
*/
/**
* Block paddings.
*/
/**
* React Native specific.
* These variables do not appear to be used anywhere else.
*/
/**
* Converts a hex value into the rgb equivalent.
*
* @param {string} hex - the hexadecimal value to convert
* @return {string} comma separated rgb values
*/
/**
* Breakpoint mixins
*/
/**
* Long content fade mixin
*
* Creates a fading overlay to signify that the content is longer
* than the space allows.
*/
/**
* Focus styles.
*/
/**
* Applies editor left position to the selector passed as argument
*/
/**
* Styles that are reused verbatim in a few places
*/
/**
* Allows users to opt-out of animations via OS-level preferences.
*/
/**
* Reset default styles for JavaScript UI based pages.
* This is a WP-admin agnostic reset
*/
/**
* Reset the WP Admin page styles for Gutenberg-like pages.
*/
.wp-block-navigation .wp-block-navigation-item__label {
word-break: normal;
overflow-wrap: break-word;
}

View File

@ -0,0 +1 @@
.wp-block-navigation .wp-block-navigation-item__label{word-break:normal;overflow-wrap:break-word}

View File

@ -0,0 +1,80 @@
/**
* Colors
*/
/**
* Breakpoints & Media Queries
*/
/**
* SCSS Variables.
*
* Please use variables from this sheet to ensure consistency across the UI.
* Don't add to this sheet unless you're pretty sure the value will be reused in many places.
* For example, don't add rules to this sheet that affect block visuals. It's purely for UI.
*/
/**
* Colors
*/
/**
* Fonts & basic variables.
*/
/**
* Grid System.
* https://make.wordpress.org/design/2019/10/31/proposal-a-consistent-spacing-system-for-wordpress/
*/
/**
* Dimensions.
*/
/**
* Shadows.
*/
/**
* Editor widths.
*/
/**
* Block & Editor UI.
*/
/**
* Block paddings.
*/
/**
* React Native specific.
* These variables do not appear to be used anywhere else.
*/
/**
* Converts a hex value into the rgb equivalent.
*
* @param {string} hex - the hexadecimal value to convert
* @return {string} comma separated rgb values
*/
/**
* Breakpoint mixins
*/
/**
* Long content fade mixin
*
* Creates a fading overlay to signify that the content is longer
* than the space allows.
*/
/**
* Focus styles.
*/
/**
* Applies editor left position to the selector passed as argument
*/
/**
* Styles that are reused verbatim in a few places
*/
/**
* Allows users to opt-out of animations via OS-level preferences.
*/
/**
* Reset default styles for JavaScript UI based pages.
* This is a WP-admin agnostic reset
*/
/**
* Reset the WP Admin page styles for Gutenberg-like pages.
*/
.wp-block-navigation .wp-block-navigation-item__label {
word-break: normal;
overflow-wrap: break-word;
}

View File

@ -0,0 +1 @@
.wp-block-navigation .wp-block-navigation-item__label{word-break:normal;overflow-wrap:break-word}

View File

@ -0,0 +1,300 @@
<?php
/**
* Server-side rendering of the `core/navigation-submenu` block.
*
* @package gutenberg
*/
/**
* Build an array with CSS classes and inline styles defining the colors
* which will be applied to the navigation markup in the front-end.
*
* @param array $context Navigation block context.
* @param array $attributes Block attributes.
* @return array Colors CSS classes and inline styles.
*/
function block_core_navigation_submenu_build_css_colors( $context, $attributes ) {
$colors = array(
'css_classes' => array(),
'inline_styles' => '',
);
$is_sub_menu = isset( $attributes['isTopLevelLink'] ) ? ( ! $attributes['isTopLevelLink'] ) : false;
// Text color.
$named_text_color = null;
$custom_text_color = null;
if ( $is_sub_menu && array_key_exists( 'customOverlayTextColor', $context ) ) {
$custom_text_color = $context['customOverlayTextColor'];
} elseif ( $is_sub_menu && array_key_exists( 'overlayTextColor', $context ) ) {
$named_text_color = $context['overlayTextColor'];
} elseif ( array_key_exists( 'customTextColor', $context ) ) {
$custom_text_color = $context['customTextColor'];
} elseif ( array_key_exists( 'textColor', $context ) ) {
$named_text_color = $context['textColor'];
} elseif ( isset( $context['style']['color']['text'] ) ) {
$custom_text_color = $context['style']['color']['text'];
}
// If has text color.
if ( ! is_null( $named_text_color ) ) {
// Add the color class.
array_push( $colors['css_classes'], 'has-text-color', sprintf( 'has-%s-color', $named_text_color ) );
} elseif ( ! is_null( $custom_text_color ) ) {
// Add the custom color inline style.
$colors['css_classes'][] = 'has-text-color';
$colors['inline_styles'] .= sprintf( 'color: %s;', $custom_text_color );
}
// Background color.
$named_background_color = null;
$custom_background_color = null;
if ( $is_sub_menu && array_key_exists( 'customOverlayBackgroundColor', $context ) ) {
$custom_background_color = $context['customOverlayBackgroundColor'];
} elseif ( $is_sub_menu && array_key_exists( 'overlayBackgroundColor', $context ) ) {
$named_background_color = $context['overlayBackgroundColor'];
} elseif ( array_key_exists( 'customBackgroundColor', $context ) ) {
$custom_background_color = $context['customBackgroundColor'];
} elseif ( array_key_exists( 'backgroundColor', $context ) ) {
$named_background_color = $context['backgroundColor'];
} elseif ( isset( $context['style']['color']['background'] ) ) {
$custom_background_color = $context['style']['color']['background'];
}
// If has background color.
if ( ! is_null( $named_background_color ) ) {
// Add the background-color class.
array_push( $colors['css_classes'], 'has-background', sprintf( 'has-%s-background-color', $named_background_color ) );
} elseif ( ! is_null( $custom_background_color ) ) {
// Add the custom background-color inline style.
$colors['css_classes'][] = 'has-background';
$colors['inline_styles'] .= sprintf( 'background-color: %s;', $custom_background_color );
}
return $colors;
}
/**
* Build an array with CSS classes and inline styles defining the font sizes
* which will be applied to the navigation markup in the front-end.
*
* @param array $context Navigation block context.
* @return array Font size CSS classes and inline styles.
*/
function block_core_navigation_submenu_build_css_font_sizes( $context ) {
// CSS classes.
$font_sizes = array(
'css_classes' => array(),
'inline_styles' => '',
);
$has_named_font_size = array_key_exists( 'fontSize', $context );
$has_custom_font_size = isset( $context['style']['typography']['fontSize'] );
if ( $has_named_font_size ) {
// Add the font size class.
$font_sizes['css_classes'][] = sprintf( 'has-%s-font-size', $context['fontSize'] );
} elseif ( $has_custom_font_size ) {
// Add the custom font size inline style.
$font_sizes['inline_styles'] = sprintf( 'font-size: %spx;', $context['style']['typography']['fontSize'] );
}
return $font_sizes;
}
/**
* Returns the top-level submenu SVG chevron icon.
*
* @return string
*/
function block_core_navigation_submenu_render_submenu_icon() {
return '<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12" fill="none" role="img" aria-hidden="true" focusable="false"><path d="M1.50002 4L6.00002 8L10.5 4" stroke-width="1.5"></path></svg>';
}
/**
* Renders the `core/navigation-submenu` block.
*
* @param array $attributes The block attributes.
* @param string $content The saved content.
* @param object $block The parsed block.
*
* @return string Returns the post content with the legacy widget added.
*/
function render_block_core_navigation_submenu( $attributes, $content, $block ) {
$navigation_link_has_id = isset( $attributes['id'] ) && is_numeric( $attributes['id'] );
$is_post_type = isset( $attributes['kind'] ) && 'post-type' === $attributes['kind'];
$is_post_type = $is_post_type || isset( $attributes['type'] ) && ( 'post' === $attributes['type'] || 'page' === $attributes['type'] );
// Don't render the block's subtree if it is a draft.
if ( $is_post_type && $navigation_link_has_id && 'publish' !== get_post_status( $attributes['id'] ) ) {
return '';
}
// Don't render the block's subtree if it has no label.
if ( empty( $attributes['label'] ) ) {
return '';
}
$colors = block_core_navigation_submenu_build_css_colors( $block->context, $attributes );
$font_sizes = block_core_navigation_submenu_build_css_font_sizes( $block->context );
$classes = array_merge(
$colors['css_classes'],
$font_sizes['css_classes']
);
$style_attribute = ( $colors['inline_styles'] . $font_sizes['inline_styles'] );
$css_classes = trim( implode( ' ', $classes ) );
$has_submenu = count( $block->inner_blocks ) > 0;
$is_active = ! empty( $attributes['id'] ) && ( get_the_ID() === $attributes['id'] );
$class_name = ! empty( $attributes['className'] ) ? implode( ' ', (array) $attributes['className'] ) : false;
if ( false !== $class_name ) {
$css_classes .= ' ' . $class_name;
}
$show_submenu_indicators = isset( $block->context['showSubmenuIcon'] ) && $block->context['showSubmenuIcon'];
$open_on_click = isset( $block->context['openSubmenusOnClick'] ) && $block->context['openSubmenusOnClick'];
$open_on_hover_and_click = isset( $block->context['openSubmenusOnClick'] ) && ! $block->context['openSubmenusOnClick'] &&
$show_submenu_indicators;
$wrapper_attributes = get_block_wrapper_attributes(
array(
'class' => $css_classes . ' wp-block-navigation-item' . ( $has_submenu ? ' has-child' : '' ) .
( $open_on_click ? ' open-on-click' : '' ) . ( $open_on_hover_and_click ? ' open-on-hover-click' : '' ) .
( $is_active ? ' current-menu-item' : '' ),
'style' => $style_attribute,
)
);
$html = '<li ' . $wrapper_attributes . '>';
// If Submenus open on hover, we render an anchor tag with attributes.
// If submenu icons are set to show, we also render a submenu button, so the submenu can be opened on click.
if ( ! $open_on_click ) {
$item_url = isset( $attributes['url'] ) ? esc_url( $attributes['url'] ) : '';
// Start appending HTML attributes to anchor tag.
$html .= '<a class="wp-block-navigation-item__content" href="' . $item_url . '"';
if ( $is_active ) {
$html .= ' aria-current="page"';
}
if ( isset( $attributes['opensInNewTab'] ) && true === $attributes['opensInNewTab'] ) {
$html .= ' target="_blank" ';
}
if ( isset( $attributes['rel'] ) ) {
$html .= ' rel="' . esc_attr( $attributes['rel'] ) . '"';
} elseif ( isset( $attributes['nofollow'] ) && $attributes['nofollow'] ) {
$html .= ' rel="nofollow"';
}
if ( isset( $attributes['title'] ) ) {
$html .= ' title="' . esc_attr( $attributes['title'] ) . '"';
}
$html .= '>';
// End appending HTML attributes to anchor tag.
if ( isset( $attributes['label'] ) ) {
$html .= wp_kses(
$attributes['label'],
array(
'code' => array(),
'em' => array(),
'img' => array(
'scale' => array(),
'class' => array(),
'style' => array(),
'src' => array(),
'alt' => array(),
),
's' => array(),
'span' => array(
'style' => array(),
),
'strong' => array(),
)
);
}
$html .= '</a>';
// End anchor tag content.
if ( $show_submenu_indicators ) {
// The submenu icon is rendered in a button here
// so that there's a clickable elment to open the submenu.
$html .= '<button class="wp-block-navigation__submenu-icon wp-block-navigation-submenu__toggle" aria-expanded="false">' . block_core_navigation_submenu_render_submenu_icon() . '</button>';
}
} else {
// If menus open on click, we render the parent as a button.
$html .= '<button class="wp-block-navigation-item__content wp-block-navigation-submenu__toggle" aria-expanded="false">';
// Wrap title with span to isolate it from submenu icon.
$html .= '<span class="wp-block-navigation-item__label">';
if ( isset( $attributes['label'] ) ) {
$html .= wp_kses(
$attributes['label'],
array(
'code' => array(),
'em' => array(),
'img' => array(
'scale' => array(),
'class' => array(),
'style' => array(),
'src' => array(),
'alt' => array(),
),
's' => array(),
'span' => array(
'style' => array(),
),
'strong' => array(),
)
);
}
$html .= '</span>';
$html .= '<span class="wp-block-navigation__submenu-icon">' . block_core_navigation_submenu_render_submenu_icon() . '</span>';
$html .= '</button>';
}
if ( $has_submenu ) {
$inner_blocks_html = '';
foreach ( $block->inner_blocks as $inner_block ) {
$inner_blocks_html .= $inner_block->render();
}
$html .= sprintf(
'<ul class="wp-block-navigation__submenu-container">%s</ul>',
$inner_blocks_html
);
}
$html .= '</li>';
return $html;
}
/**
* Register the navigation submenu block.
*
* @uses render_block_core_navigation_submenu()
* @throws WP_Error An WP_Error exception parsing the block definition.
*/
function register_block_core_navigation_submenu() {
register_block_type_from_metadata(
__DIR__ . '/navigation-submenu',
array(
'render_callback' => 'render_block_core_navigation_submenu',
)
);
}
add_action( 'init', 'register_block_core_navigation_submenu' );

View File

@ -0,0 +1,65 @@
{
"apiVersion": 2,
"name": "core/navigation-submenu",
"title": "Submenu",
"category": "design",
"parent": [
"core/navigation"
],
"description": "Add a submenu to your navigation.",
"textdomain": "default",
"attributes": {
"label": {
"type": "string"
},
"type": {
"type": "string"
},
"description": {
"type": "string"
},
"rel": {
"type": "string"
},
"id": {
"type": "number"
},
"opensInNewTab": {
"type": "boolean",
"default": false
},
"url": {
"type": "string"
},
"title": {
"type": "string"
},
"kind": {
"type": "string"
},
"isTopLevelItem": {
"type": "boolean"
}
},
"usesContext": [
"textColor",
"customTextColor",
"backgroundColor",
"customBackgroundColor",
"overlayTextColor",
"customOverlayTextColor",
"overlayBackgroundColor",
"customOverlayBackgroundColor",
"fontSize",
"customFontSize",
"showSubmenuIcon",
"openSubmenusOnClick",
"style"
],
"supports": {
"reusable": false,
"html": false
},
"editorStyle": "wp-block-navigation-submenu-editor",
"style": "wp-block-navigation-submenu"
}

View File

@ -0,0 +1,107 @@
/**
* Colors
*/
/**
* Breakpoints & Media Queries
*/
/**
* SCSS Variables.
*
* Please use variables from this sheet to ensure consistency across the UI.
* Don't add to this sheet unless you're pretty sure the value will be reused in many places.
* For example, don't add rules to this sheet that affect block visuals. It's purely for UI.
*/
/**
* Colors
*/
/**
* Fonts & basic variables.
*/
/**
* Grid System.
* https://make.wordpress.org/design/2019/10/31/proposal-a-consistent-spacing-system-for-wordpress/
*/
/**
* Dimensions.
*/
/**
* Shadows.
*/
/**
* Editor widths.
*/
/**
* Block & Editor UI.
*/
/**
* Block paddings.
*/
/**
* React Native specific.
* These variables do not appear to be used anywhere else.
*/
/**
* Converts a hex value into the rgb equivalent.
*
* @param {string} hex - the hexadecimal value to convert
* @return {string} comma separated rgb values
*/
/**
* Breakpoint mixins
*/
/**
* Long content fade mixin
*
* Creates a fading overlay to signify that the content is longer
* than the space allows.
*/
/**
* Focus styles.
*/
/**
* Applies editor left position to the selector passed as argument
*/
/**
* Styles that are reused verbatim in a few places
*/
/**
* Allows users to opt-out of animations via OS-level preferences.
*/
/**
* Reset default styles for JavaScript UI based pages.
* This is a WP-admin agnostic reset
*/
/**
* Reset the WP Admin page styles for Gutenberg-like pages.
*/
.wp-block-navigation-submenu {
display: block;
}
.wp-block-navigation-submenu .wp-block-navigation__submenu-container {
z-index: 28;
}
.wp-block-navigation-submenu.is-selected > .wp-block-navigation__submenu-container, .wp-block-navigation-submenu.has-child-selected > .wp-block-navigation__submenu-container {
visibility: visible !important;
opacity: 1 !important;
min-width: 200px !important;
height: auto !important;
width: auto !important;
position: absolute;
right: -1px;
top: 100%;
}
@media (min-width: 782px) {
.wp-block-navigation-submenu.is-selected > .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container, .wp-block-navigation-submenu.has-child-selected > .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container {
right: 100%;
top: -1px;
}
.wp-block-navigation-submenu.is-selected > .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container::before, .wp-block-navigation-submenu.has-child-selected > .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container::before {
content: "";
position: absolute;
left: 100%;
height: 100%;
display: block;
width: 0.5em;
background: transparent;
}
}

View File

@ -0,0 +1 @@
.wp-block-navigation-submenu{display:block}.wp-block-navigation-submenu .wp-block-navigation__submenu-container{z-index:28}.wp-block-navigation-submenu.has-child-selected>.wp-block-navigation__submenu-container,.wp-block-navigation-submenu.is-selected>.wp-block-navigation__submenu-container{visibility:visible!important;opacity:1!important;min-width:200px!important;height:auto!important;width:auto!important;position:absolute;right:-1px;top:100%}@media (min-width:782px){.wp-block-navigation-submenu.has-child-selected>.wp-block-navigation__submenu-container .wp-block-navigation__submenu-container,.wp-block-navigation-submenu.is-selected>.wp-block-navigation__submenu-container .wp-block-navigation__submenu-container{right:100%;top:-1px}.wp-block-navigation-submenu.has-child-selected>.wp-block-navigation__submenu-container .wp-block-navigation__submenu-container:before,.wp-block-navigation-submenu.is-selected>.wp-block-navigation__submenu-container .wp-block-navigation__submenu-container:before{content:"";position:absolute;left:100%;height:100%;display:block;width:.5em;background:transparent}}

View File

@ -0,0 +1,107 @@
/**
* Colors
*/
/**
* Breakpoints & Media Queries
*/
/**
* SCSS Variables.
*
* Please use variables from this sheet to ensure consistency across the UI.
* Don't add to this sheet unless you're pretty sure the value will be reused in many places.
* For example, don't add rules to this sheet that affect block visuals. It's purely for UI.
*/
/**
* Colors
*/
/**
* Fonts & basic variables.
*/
/**
* Grid System.
* https://make.wordpress.org/design/2019/10/31/proposal-a-consistent-spacing-system-for-wordpress/
*/
/**
* Dimensions.
*/
/**
* Shadows.
*/
/**
* Editor widths.
*/
/**
* Block & Editor UI.
*/
/**
* Block paddings.
*/
/**
* React Native specific.
* These variables do not appear to be used anywhere else.
*/
/**
* Converts a hex value into the rgb equivalent.
*
* @param {string} hex - the hexadecimal value to convert
* @return {string} comma separated rgb values
*/
/**
* Breakpoint mixins
*/
/**
* Long content fade mixin
*
* Creates a fading overlay to signify that the content is longer
* than the space allows.
*/
/**
* Focus styles.
*/
/**
* Applies editor left position to the selector passed as argument
*/
/**
* Styles that are reused verbatim in a few places
*/
/**
* Allows users to opt-out of animations via OS-level preferences.
*/
/**
* Reset default styles for JavaScript UI based pages.
* This is a WP-admin agnostic reset
*/
/**
* Reset the WP Admin page styles for Gutenberg-like pages.
*/
.wp-block-navigation-submenu {
display: block;
}
.wp-block-navigation-submenu .wp-block-navigation__submenu-container {
z-index: 28;
}
.wp-block-navigation-submenu.is-selected > .wp-block-navigation__submenu-container, .wp-block-navigation-submenu.has-child-selected > .wp-block-navigation__submenu-container {
visibility: visible !important;
opacity: 1 !important;
min-width: 200px !important;
height: auto !important;
width: auto !important;
position: absolute;
left: -1px;
top: 100%;
}
@media (min-width: 782px) {
.wp-block-navigation-submenu.is-selected > .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container, .wp-block-navigation-submenu.has-child-selected > .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container {
left: 100%;
top: -1px;
}
.wp-block-navigation-submenu.is-selected > .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container::before, .wp-block-navigation-submenu.has-child-selected > .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container::before {
content: "";
position: absolute;
right: 100%;
height: 100%;
display: block;
width: 0.5em;
background: transparent;
}
}

View File

@ -0,0 +1 @@
.wp-block-navigation-submenu{display:block}.wp-block-navigation-submenu .wp-block-navigation__submenu-container{z-index:28}.wp-block-navigation-submenu.has-child-selected>.wp-block-navigation__submenu-container,.wp-block-navigation-submenu.is-selected>.wp-block-navigation__submenu-container{visibility:visible!important;opacity:1!important;min-width:200px!important;height:auto!important;width:auto!important;position:absolute;left:-1px;top:100%}@media (min-width:782px){.wp-block-navigation-submenu.has-child-selected>.wp-block-navigation__submenu-container .wp-block-navigation__submenu-container,.wp-block-navigation-submenu.is-selected>.wp-block-navigation__submenu-container .wp-block-navigation__submenu-container{left:100%;top:-1px}.wp-block-navigation-submenu.has-child-selected>.wp-block-navigation__submenu-container .wp-block-navigation__submenu-container:before,.wp-block-navigation-submenu.is-selected>.wp-block-navigation__submenu-container .wp-block-navigation__submenu-container:before{content:"";position:absolute;right:100%;height:100%;display:block;width:.5em;background:transparent}}

View File

@ -0,0 +1,95 @@
/**
* Colors
*/
/**
* Breakpoints & Media Queries
*/
/**
* SCSS Variables.
*
* Please use variables from this sheet to ensure consistency across the UI.
* Don't add to this sheet unless you're pretty sure the value will be reused in many places.
* For example, don't add rules to this sheet that affect block visuals. It's purely for UI.
*/
/**
* Colors
*/
/**
* Fonts & basic variables.
*/
/**
* Grid System.
* https://make.wordpress.org/design/2019/10/31/proposal-a-consistent-spacing-system-for-wordpress/
*/
/**
* Dimensions.
*/
/**
* Shadows.
*/
/**
* Editor widths.
*/
/**
* Block & Editor UI.
*/
/**
* Block paddings.
*/
/**
* React Native specific.
* These variables do not appear to be used anywhere else.
*/
/**
* Converts a hex value into the rgb equivalent.
*
* @param {string} hex - the hexadecimal value to convert
* @return {string} comma separated rgb values
*/
/**
* Breakpoint mixins
*/
/**
* Long content fade mixin
*
* Creates a fading overlay to signify that the content is longer
* than the space allows.
*/
/**
* Focus styles.
*/
/**
* Applies editor left position to the selector passed as argument
*/
/**
* Styles that are reused verbatim in a few places
*/
/**
* Allows users to opt-out of animations via OS-level preferences.
*/
/**
* Reset default styles for JavaScript UI based pages.
* This is a WP-admin agnostic reset
*/
/**
* Reset the WP Admin page styles for Gutenberg-like pages.
*/
.wp-block-navigation-submenu {
position: relative;
display: flex;
}
.wp-block-navigation-submenu .wp-block-navigation__submenu-icon svg {
stroke: currentColor;
}
button.wp-block-navigation-item__content {
background-color: transparent;
border: none;
color: currentColor;
font-size: inherit;
font-family: inherit;
}
.wp-block-navigation-submenu__toggle {
cursor: pointer;
}

View File

@ -0,0 +1 @@
.wp-block-navigation-submenu{position:relative;display:flex}.wp-block-navigation-submenu .wp-block-navigation__submenu-icon svg{stroke:currentColor}button.wp-block-navigation-item__content{background-color:initial;border:none;color:currentColor;font-size:inherit;font-family:inherit}.wp-block-navigation-submenu__toggle{cursor:pointer}

View File

@ -0,0 +1,95 @@
/**
* Colors
*/
/**
* Breakpoints & Media Queries
*/
/**
* SCSS Variables.
*
* Please use variables from this sheet to ensure consistency across the UI.
* Don't add to this sheet unless you're pretty sure the value will be reused in many places.
* For example, don't add rules to this sheet that affect block visuals. It's purely for UI.
*/
/**
* Colors
*/
/**
* Fonts & basic variables.
*/
/**
* Grid System.
* https://make.wordpress.org/design/2019/10/31/proposal-a-consistent-spacing-system-for-wordpress/
*/
/**
* Dimensions.
*/
/**
* Shadows.
*/
/**
* Editor widths.
*/
/**
* Block & Editor UI.
*/
/**
* Block paddings.
*/
/**
* React Native specific.
* These variables do not appear to be used anywhere else.
*/
/**
* Converts a hex value into the rgb equivalent.
*
* @param {string} hex - the hexadecimal value to convert
* @return {string} comma separated rgb values
*/
/**
* Breakpoint mixins
*/
/**
* Long content fade mixin
*
* Creates a fading overlay to signify that the content is longer
* than the space allows.
*/
/**
* Focus styles.
*/
/**
* Applies editor left position to the selector passed as argument
*/
/**
* Styles that are reused verbatim in a few places
*/
/**
* Allows users to opt-out of animations via OS-level preferences.
*/
/**
* Reset default styles for JavaScript UI based pages.
* This is a WP-admin agnostic reset
*/
/**
* Reset the WP Admin page styles for Gutenberg-like pages.
*/
.wp-block-navigation-submenu {
position: relative;
display: flex;
}
.wp-block-navigation-submenu .wp-block-navigation__submenu-icon svg {
stroke: currentColor;
}
button.wp-block-navigation-item__content {
background-color: transparent;
border: none;
color: currentColor;
font-size: inherit;
font-family: inherit;
}
.wp-block-navigation-submenu__toggle {
cursor: pointer;
}

View File

@ -0,0 +1 @@
.wp-block-navigation-submenu{position:relative;display:flex}.wp-block-navigation-submenu .wp-block-navigation__submenu-icon svg{stroke:currentColor}button.wp-block-navigation-item__content{background-color:initial;border:none;color:currentColor;font-size:inherit;font-family:inherit}.wp-block-navigation-submenu__toggle{cursor:pointer}

View File

@ -0,0 +1,429 @@
<?php
/**
* Server-side rendering of the `core/navigation` block.
*
* @package gutenberg
*/
/**
* Build an array with CSS classes and inline styles defining the colors
* which will be applied to the navigation markup in the front-end.
*
* @param array $attributes Navigation block attributes.
* @return array Colors CSS classes and inline styles.
*/
function block_core_navigation_build_css_colors( $attributes ) {
$colors = array(
'css_classes' => array(),
'inline_styles' => '',
);
// Text color.
$has_named_text_color = array_key_exists( 'textColor', $attributes );
$has_custom_text_color = array_key_exists( 'customTextColor', $attributes );
// If has text color.
if ( $has_custom_text_color || $has_named_text_color ) {
// Add has-text-color class.
$colors['css_classes'][] = 'has-text-color';
}
if ( $has_named_text_color ) {
// Add the color class.
$colors['css_classes'][] = sprintf( 'has-%s-color', $attributes['textColor'] );
} elseif ( $has_custom_text_color ) {
// Add the custom color inline style.
$colors['inline_styles'] .= sprintf( 'color: %s;', $attributes['customTextColor'] );
}
// Background color.
$has_named_background_color = array_key_exists( 'backgroundColor', $attributes );
$has_custom_background_color = array_key_exists( 'customBackgroundColor', $attributes );
// If has background color.
if ( $has_custom_background_color || $has_named_background_color ) {
// Add has-background class.
$colors['css_classes'][] = 'has-background';
}
if ( $has_named_background_color ) {
// Add the background-color class.
$colors['css_classes'][] = sprintf( 'has-%s-background-color', $attributes['backgroundColor'] );
} elseif ( $has_custom_background_color ) {
// Add the custom background-color inline style.
$colors['inline_styles'] .= sprintf( 'background-color: %s;', $attributes['customBackgroundColor'] );
}
return $colors;
}
/**
* Build an array with CSS classes and inline styles defining the font sizes
* which will be applied to the navigation markup in the front-end.
*
* @param array $attributes Navigation block attributes.
* @return array Font size CSS classes and inline styles.
*/
function block_core_navigation_build_css_font_sizes( $attributes ) {
// CSS classes.
$font_sizes = array(
'css_classes' => array(),
'inline_styles' => '',
);
$has_named_font_size = array_key_exists( 'fontSize', $attributes );
$has_custom_font_size = array_key_exists( 'customFontSize', $attributes );
if ( $has_named_font_size ) {
// Add the font size class.
$font_sizes['css_classes'][] = sprintf( 'has-%s-font-size', $attributes['fontSize'] );
} elseif ( $has_custom_font_size ) {
// Add the custom font size inline style.
$font_sizes['inline_styles'] = sprintf( 'font-size: %spx;', $attributes['customFontSize'] );
}
return $font_sizes;
}
/**
* Returns the menu items for a WordPress menu location.
*
* @param string $location The menu location.
* @return array Menu items for the location.
*/
function gutenberg_get_menu_items_at_location( $location ) {
if ( empty( $location ) ) {
return;
}
// Build menu data. The following approximates the code in
// `wp_nav_menu()` and `gutenberg_output_block_nav_menu`.
// Find the location in the list of locations, returning early if the
// location can't be found.
$locations = get_nav_menu_locations();
if ( ! isset( $locations[ $location ] ) ) {
return;
}
// Get the menu from the location, returning early if there is no
// menu or there was an error.
$menu = wp_get_nav_menu_object( $locations[ $location ] );
if ( ! $menu || is_wp_error( $menu ) ) {
return;
}
$menu_items = wp_get_nav_menu_items( $menu->term_id, array( 'update_post_term_cache' => false ) );
_wp_menu_item_classes_by_context( $menu_items );
return $menu_items;
}
/**
* Sorts a standard array of menu items into a nested structure keyed by the
* id of the parent menu.
*
* @param array $menu_items Menu items to sort.
* @return array An array keyed by the id of the parent menu where each element
* is an array of menu items that belong to that parent.
*/
function gutenberg_sort_menu_items_by_parent_id( $menu_items ) {
$sorted_menu_items = array();
foreach ( (array) $menu_items as $menu_item ) {
$sorted_menu_items[ $menu_item->menu_order ] = $menu_item;
}
unset( $menu_items, $menu_item );
$menu_items_by_parent_id = array();
foreach ( $sorted_menu_items as $menu_item ) {
$menu_items_by_parent_id[ $menu_item->menu_item_parent ][] = $menu_item;
}
return $menu_items_by_parent_id;
}
/**
* Turns menu item data into a nested array of parsed blocks
*
* @param array $menu_items An array of menu items that represent
* an individual level of a menu.
* @param array $menu_items_by_parent_id An array keyed by the id of the
* parent menu where each element is an
* array of menu items that belong to
* that parent.
* @return array An array of parsed block data.
*/
function gutenberg_parse_blocks_from_menu_items( $menu_items, $menu_items_by_parent_id ) {
if ( empty( $menu_items ) ) {
return array();
}
$blocks = array();
foreach ( $menu_items as $menu_item ) {
$class_name = ! empty( $menu_item->classes ) ? implode( ' ', (array) $menu_item->classes ) : null;
$id = ( null !== $menu_item->object_id && 'custom' !== $menu_item->object ) ? $menu_item->object_id : null;
$opens_in_new_tab = null !== $menu_item->target && '_blank' === $menu_item->target;
$rel = ( null !== $menu_item->xfn && '' !== $menu_item->xfn ) ? $menu_item->xfn : null;
$kind = null !== $menu_item->type ? str_replace( '_', '-', $menu_item->type ) : 'custom';
$block = array(
'blockName' => 'core/navigation-link',
'attrs' => array(
'className' => $class_name,
'description' => $menu_item->description,
'id' => $id,
'kind' => $kind,
'label' => $menu_item->title,
'opensInNewTab' => $opens_in_new_tab,
'rel' => $rel,
'title' => $menu_item->attr_title,
'type' => $menu_item->object,
'url' => $menu_item->url,
),
);
$block['innerBlocks'] = gutenberg_parse_blocks_from_menu_items(
isset( $menu_items_by_parent_id[ $menu_item->ID ] )
? $menu_items_by_parent_id[ $menu_item->ID ]
: array(),
$menu_items_by_parent_id
);
$blocks[] = $block;
}
return $blocks;
}
/**
* Returns the top-level submenu SVG chevron icon.
*
* @return string
*/
function block_core_navigation_render_submenu_icon() {
return '<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12" fill="none" role="img" aria-hidden="true" focusable="false"><path d="M1.50002 4L6.00002 8L10.5 4" stroke-width="1.5"></path></svg>';
}
/**
* Renders the `core/navigation` block on server.
*
* @param array $attributes The block attributes.
* @param array $content The saved content.
* @param array $block The parsed block.
*
* @return string Returns the post content with the legacy widget added.
*/
function render_block_core_navigation( $attributes, $content, $block ) {
/**
* Deprecated:
* The rgbTextColor and rgbBackgroundColor attributes
* have been deprecated in favor of
* customTextColor and customBackgroundColor ones.
* Move the values from old attrs to the new ones.
*/
if ( isset( $attributes['rgbTextColor'] ) && empty( $attributes['textColor'] ) ) {
$attributes['customTextColor'] = $attributes['rgbTextColor'];
}
if ( isset( $attributes['rgbBackgroundColor'] ) && empty( $attributes['backgroundColor'] ) ) {
$attributes['customBackgroundColor'] = $attributes['rgbBackgroundColor'];
}
unset( $attributes['rgbTextColor'], $attributes['rgbBackgroundColor'] );
/**
* This is for backwards compatibility after `isResponsive` attribute has been removed.
*/
$has_old_responsive_attribute = ! empty( $attributes['isResponsive'] ) && $attributes['isResponsive'];
$is_responsive_menu = isset( $attributes['overlayMenu'] ) && 'never' !== $attributes['overlayMenu'] || $has_old_responsive_attribute;
$should_load_view_script = ! wp_script_is( 'wp-block-navigation-view' ) && ( $is_responsive_menu || $attributes['openSubmenusOnClick'] || $attributes['showSubmenuIcon'] );
if ( $should_load_view_script ) {
wp_enqueue_script( 'wp-block-navigation-view' );
}
$inner_blocks = $block->inner_blocks;
// If `__unstableLocation` is defined, create inner blocks from the classic menu assigned to that location.
if ( empty( $inner_blocks ) && array_key_exists( '__unstableLocation', $attributes ) ) {
$menu_items = gutenberg_get_menu_items_at_location( $attributes['__unstableLocation'] );
if ( empty( $menu_items ) ) {
return '';
}
$menu_items_by_parent_id = gutenberg_sort_menu_items_by_parent_id( $menu_items );
$parsed_blocks = gutenberg_parse_blocks_from_menu_items( $menu_items_by_parent_id[0], $menu_items_by_parent_id );
$inner_blocks = new WP_Block_List( $parsed_blocks, $attributes );
}
if ( ! empty( $block->context['navigationArea'] ) ) {
$area = $block->context['navigationArea'];
$mapping = get_option( 'fse_navigation_areas', array() );
if ( ! empty( $mapping[ $area ] ) ) {
$attributes['navigationMenuId'] = $mapping[ $area ];
}
}
// Load inner blocks from the navigation post.
if ( array_key_exists( 'navigationMenuId', $attributes ) ) {
$navigation_post = get_post( $attributes['navigationMenuId'] );
if ( ! isset( $navigation_post ) ) {
return '';
}
$parsed_blocks = parse_blocks( $navigation_post->post_content );
// 'parse_blocks' includes a null block with '\n\n' as the content when
// it encounters whitespace. This code strips it.
$compacted_blocks = array_filter(
$parsed_blocks,
function( $block ) {
return isset( $block['blockName'] );
}
);
// TODO - this uses the full navigation block attributes for the
// context which could be refined.
$inner_blocks = new WP_Block_List( $compacted_blocks, $attributes );
}
if ( empty( $inner_blocks ) ) {
return '';
}
$colors = block_core_navigation_build_css_colors( $attributes );
$font_sizes = block_core_navigation_build_css_font_sizes( $attributes );
$classes = array_merge(
$colors['css_classes'],
$font_sizes['css_classes'],
$is_responsive_menu ? array( 'is-responsive' ) : array()
);
$inner_blocks_html = '';
$is_list_open = false;
foreach ( $inner_blocks as $inner_block ) {
if ( ( 'core/navigation-link' === $inner_block->name || 'core/home-link' === $inner_block->name || 'core/site-title' === $inner_block->name || 'core/site-logo' === $inner_block->name || 'core/navigation-submenu' === $inner_block->name ) && ! $is_list_open ) {
$is_list_open = true;
$inner_blocks_html .= '<ul class="wp-block-navigation__container">';
}
if ( 'core/navigation-link' !== $inner_block->name && 'core/home-link' !== $inner_block->name && 'core/site-title' !== $inner_block->name && 'core/site-logo' !== $inner_block->name && 'core/navigation-submenu' !== $inner_block->name && $is_list_open ) {
$is_list_open = false;
$inner_blocks_html .= '</ul>';
}
if ( 'core/site-title' === $inner_block->name || 'core/site-logo' === $inner_block->name ) {
$inner_blocks_html .= '<li class="wp-block-navigation-item">' . $inner_block->render() . '</li>';
} else {
$inner_blocks_html .= $inner_block->render();
}
}
if ( $is_list_open ) {
$inner_blocks_html .= '</ul>';
}
$block_styles = isset( $attributes['styles'] ) ? $attributes['styles'] : '';
$wrapper_attributes = get_block_wrapper_attributes(
array(
'class' => implode( ' ', $classes ),
'style' => $block_styles . $colors['inline_styles'] . $font_sizes['inline_styles'],
)
);
$modal_unique_id = uniqid();
// Determine whether or not navigation elements should be wrapped in the markup required to make it responsive,
// return early if they don't.
if ( ! $is_responsive_menu ) {
return sprintf(
'<nav %1$s>%2$s</nav>',
$wrapper_attributes,
$inner_blocks_html
);
}
$is_hidden_by_default = isset( $attributes['overlayMenu'] ) && 'always' === $attributes['overlayMenu'];
$responsive_container_classes = array(
'wp-block-navigation__responsive-container',
$is_hidden_by_default ? 'hidden-by-default' : '',
);
$open_button_classes = array(
'wp-block-navigation__responsive-container-open',
$is_hidden_by_default ? 'always-shown' : '',
);
$responsive_container_markup = sprintf(
'<button aria-expanded="false" aria-haspopup="true" aria-label="%3$s" class="%6$s" data-micromodal-trigger="modal-%1$s"><svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="img" aria-hidden="true" focusable="false"><rect x="4" y="7.5" width="16" height="1.5" /><rect x="4" y="15" width="16" height="1.5" /></svg></button>
<div class="%5$s" id="modal-%1$s" aria-hidden="true">
<div class="wp-block-navigation__responsive-close" tabindex="-1" data-micromodal-close>
<div class="wp-block-navigation__responsive-dialog" role="dialog" aria-modal="true" aria-labelledby="modal-%1$s-title" >
<button aria-label="%4$s" data-micromodal-close class="wp-block-navigation__responsive-container-close"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" role="img" aria-hidden="true" focusable="false"><path d="M13 11.8l6.1-6.3-1-1-6.1 6.2-6.1-6.2-1 1 6.1 6.3-6.5 6.7 1 1 6.5-6.6 6.5 6.6 1-1z"></path></svg></button>
<div class="wp-block-navigation__responsive-container-content" id="modal-%1$s-content">
%2$s
</div>
</div>
</div>
</div>',
$modal_unique_id,
$inner_blocks_html,
__( 'Open menu' ), // Open button label.
__( 'Close menu' ), // Close button label.
implode( ' ', $responsive_container_classes ),
implode( ' ', $open_button_classes )
);
return sprintf(
'<nav %1$s>%2$s</nav>',
$wrapper_attributes,
$responsive_container_markup
);
}
/**
* Register the navigation block.
*
* @uses render_block_core_navigation()
* @throws WP_Error An WP_Error exception parsing the block definition.
*/
function register_block_core_navigation() {
register_block_type_from_metadata(
__DIR__ . '/navigation',
array(
'render_callback' => 'render_block_core_navigation',
)
);
}
add_action( 'init', 'register_block_core_navigation' );
/**
* Filter that changes the parsed attribute values of navigation blocks contain typographic presets to contain the values directly.
*
* @param array $parsed_block The block being rendered.
* @return array The block being rendered without typographic presets.
*/
function block_core_navigation_typographic_presets_backcompatibility( $parsed_block ) {
if ( 'core/navigation' === $parsed_block['blockName'] ) {
$attribute_to_prefix_map = array(
'fontStyle' => 'var:preset|font-style|',
'fontWeight' => 'var:preset|font-weight|',
'textDecoration' => 'var:preset|text-decoration|',
'textTransform' => 'var:preset|text-transform|',
);
foreach ( $attribute_to_prefix_map as $style_attribute => $prefix ) {
if ( ! empty( $parsed_block['attrs']['style']['typography'][ $style_attribute ] ) ) {
$prefix_len = strlen( $prefix );
$attribute_value = &$parsed_block['attrs']['style']['typography'][ $style_attribute ];
if ( 0 === strncmp( $attribute_value, $prefix, $prefix_len ) ) {
$attribute_value = substr( $attribute_value, $prefix_len );
}
if ( 'textDecoration' === $style_attribute && 'strikethrough' === $attribute_value ) {
$attribute_value = 'line-through';
}
}
}
}
return $parsed_block;
}
add_filter( 'render_block_data', 'block_core_navigation_typographic_presets_backcompatibility' );

View File

@ -0,0 +1,124 @@
{
"apiVersion": 2,
"name": "core/navigation",
"title": "Navigation",
"category": "theme",
"description": "A collection of blocks that allow visitors to get around your site.",
"keywords": [
"menu",
"navigation",
"links"
],
"textdomain": "default",
"attributes": {
"navigationMenuId": {
"type": "number"
},
"textColor": {
"type": "string"
},
"customTextColor": {
"type": "string"
},
"rgbTextColor": {
"type": "string"
},
"backgroundColor": {
"type": "string"
},
"customBackgroundColor": {
"type": "string"
},
"rgbBackgroundColor": {
"type": "string"
},
"showSubmenuIcon": {
"type": "boolean",
"default": true
},
"openSubmenusOnClick": {
"type": "boolean",
"default": false
},
"overlayMenu": {
"type": "string",
"default": "mobile"
},
"__unstableLocation": {
"type": "string"
},
"overlayBackgroundColor": {
"type": "string"
},
"customOverlayBackgroundColor": {
"type": "string"
},
"overlayTextColor": {
"type": "string"
},
"customOverlayTextColor": {
"type": "string"
}
},
"usesContext": [ "navigationArea" ],
"providesContext": {
"textColor": "textColor",
"customTextColor": "customTextColor",
"backgroundColor": "backgroundColor",
"customBackgroundColor": "customBackgroundColor",
"overlayTextColor": "overlayTextColor",
"customOverlayTextColor": "customOverlayTextColor",
"overlayBackgroundColor": "overlayBackgroundColor",
"customOverlayBackgroundColor": "customOverlayBackgroundColor",
"fontSize": "fontSize",
"customFontSize": "customFontSize",
"showSubmenuIcon": "showSubmenuIcon",
"openSubmenusOnClick": "openSubmenusOnClick",
"style": "style",
"orientation": "orientation"
},
"supports": {
"align": [
"wide",
"full"
],
"anchor": true,
"html": false,
"inserter": true,
"typography": {
"fontSize": true,
"lineHeight": true,
"__experimentalFontStyle": true,
"__experimentalFontWeight": true,
"__experimentalTextTransform": true,
"__experimentalFontFamily": true,
"__experimentalTextDecoration": true,
"__experimentalDefaultControls": {
"fontSize": true
}
},
"spacing": {
"blockGap": true,
"units": [
"px",
"em",
"rem",
"vh",
"vw"
],
"__experimentalDefaultControls": {
"blockGap": true
}
},
"__experimentalLayout": {
"allowSwitching": false,
"allowInheriting": false,
"default": {
"type": "flex"
}
}
},
"viewScript": "file:./view.min.js",
"editorStyle": "wp-block-navigation-editor",
"style": "wp-block-navigation"
}

View File

@ -0,0 +1,491 @@
/**
* Colors
*/
/**
* Breakpoints & Media Queries
*/
/**
* SCSS Variables.
*
* Please use variables from this sheet to ensure consistency across the UI.
* Don't add to this sheet unless you're pretty sure the value will be reused in many places.
* For example, don't add rules to this sheet that affect block visuals. It's purely for UI.
*/
/**
* Colors
*/
/**
* Fonts & basic variables.
*/
/**
* Grid System.
* https://make.wordpress.org/design/2019/10/31/proposal-a-consistent-spacing-system-for-wordpress/
*/
/**
* Dimensions.
*/
/**
* Shadows.
*/
/**
* Editor widths.
*/
/**
* Block & Editor UI.
*/
/**
* Block paddings.
*/
/**
* React Native specific.
* These variables do not appear to be used anywhere else.
*/
/**
* Converts a hex value into the rgb equivalent.
*
* @param {string} hex - the hexadecimal value to convert
* @return {string} comma separated rgb values
*/
/**
* Breakpoint mixins
*/
/**
* Long content fade mixin
*
* Creates a fading overlay to signify that the content is longer
* than the space allows.
*/
/**
* Focus styles.
*/
/**
* Applies editor left position to the selector passed as argument
*/
/**
* Styles that are reused verbatim in a few places
*/
/**
* Allows users to opt-out of animations via OS-level preferences.
*/
/**
* Reset default styles for JavaScript UI based pages.
* This is a WP-admin agnostic reset
*/
/**
* Reset the WP Admin page styles for Gutenberg-like pages.
*/
/**
* Editor only CSS.
*/
.editor-styles-wrapper .wp-block-navigation ul {
margin-top: 0;
margin-bottom: 0;
margin-right: 0;
padding-right: 0;
}
.editor-styles-wrapper .wp-block-navigation .wp-block-navigation-item.wp-block {
margin-right: revert;
margin-left: revert;
}
.wp-block-navigation-item__label {
display: inline;
}
/**
* Submenus.
*/
.wp-block-navigation__container.is-parent-of-selected-block {
visibility: visible;
opacity: 1;
}
.wp-block-navigation__container,
.wp-block-navigation-item {
background-color: inherit;
}
.wp-block-navigation:not(.is-selected):not(.has-child-selected) .has-child:hover > .wp-block-navigation__submenu-container {
opacity: 0;
visibility: hidden;
}
.has-child.is-selected > .wp-block-navigation__submenu-container, .has-child.has-child-selected > .wp-block-navigation__submenu-container {
display: flex;
opacity: 1;
visibility: visible;
}
.is-dragging-components-draggable .has-child.is-dragging-within > .wp-block-navigation__submenu-container {
opacity: 1;
visibility: visible;
}
.is-editing > .wp-block-navigation__container {
visibility: visible;
opacity: 1;
display: flex;
flex-direction: column;
}
.is-dragging-components-draggable .wp-block-navigation-link > .wp-block-navigation__container {
opacity: 1;
visibility: hidden;
}
.is-dragging-components-draggable .wp-block-navigation-link > .wp-block-navigation__container .block-editor-block-draggable-chip-wrapper {
visibility: visible;
}
/**
* Colors Selector component
*/
.block-library-colors-selector {
width: auto;
}
.block-library-colors-selector .block-library-colors-selector__toggle {
display: block;
margin: 0 auto;
padding: 3px;
width: auto;
}
.block-library-colors-selector .block-library-colors-selector__icon-container {
height: 30px;
position: relative;
margin: 0 auto;
padding: 3px;
display: flex;
align-items: center;
border-radius: 4px;
}
.block-library-colors-selector .block-library-colors-selector__state-selection {
margin-right: auto;
margin-left: auto;
border-radius: 11px;
box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.2);
width: 22px;
min-width: 22px;
height: 22px;
min-height: 22px;
line-height: 20px;
padding: 2px;
}
.block-library-colors-selector .block-library-colors-selector__state-selection > svg {
min-width: auto !important;
}
.block-library-colors-selector .block-library-colors-selector__state-selection.has-text-color > svg,
.block-library-colors-selector .block-library-colors-selector__state-selection.has-text-color > svg path {
color: inherit;
}
.block-library-colors-selector__popover .color-palette-controller-container {
padding: 16px;
}
.block-library-colors-selector__popover .components-base-control__label {
height: 20px;
line-height: 20px;
}
.block-library-colors-selector__popover .component-color-indicator {
float: left;
margin-top: 2px;
}
.block-library-colors-selector__popover .components-panel__body-title {
display: none;
}
.wp-block-navigation .block-editor-button-block-appender {
justify-content: flex-start;
}
/**
* Setup state
*/
.components-placeholder.wp-block-navigation-placeholder {
outline: none;
padding: 0;
box-shadow: none;
background: none;
min-height: 0;
color: inherit;
}
.components-placeholder.wp-block-navigation-placeholder .components-placeholder__fieldset {
font-size: inherit;
}
.components-placeholder.wp-block-navigation-placeholder .components-placeholder__fieldset .components-button {
margin-bottom: 0;
}
.is-selected .components-placeholder.wp-block-navigation-placeholder {
color: #1e1e1e;
}
.wp-block-navigation-placeholder .components-spinner {
margin-top: -4px;
margin-right: 4px;
vertical-align: middle;
margin-left: 7px;
}
@keyframes loadingpulse {
0% {
opacity: 1;
}
50% {
opacity: 0.5;
}
100% {
opacity: 1;
}
}
.wp-block-navigation-placeholder__preview {
display: flex;
flex-direction: row;
align-items: center;
flex-wrap: nowrap;
width: 100%;
overflow: hidden;
}
.wp-block-navigation-placeholder__preview.is-loading {
animation: loadingpulse 1s linear infinite;
animation-delay: 0.5s;
}
.wp-block-navigation-placeholder__preview .wp-block-navigation-item.wp-block-navigation-item {
position: relative;
min-width: 72px;
}
.wp-block-navigation-placeholder__preview .wp-block-navigation-item.wp-block-navigation-item::before {
display: block;
content: "";
border-radius: 2px;
background: currentColor;
height: 16px;
width: 100%;
}
.wp-block-navigation-placeholder__preview .wp-block-navigation-placeholder__preview-search-icon {
height: 24px;
}
.wp-block-navigation-placeholder__preview .wp-block-navigation-placeholder__preview-search-icon svg {
fill: currentColor;
}
.wp-block-navigation-placeholder__preview .wp-block-navigation-item.wp-block-navigation-item,
.wp-block-navigation-placeholder__preview .wp-block-navigation-placeholder__preview-search-icon {
opacity: 0.3;
}
.wp-block-navigation.is-selected .wp-block-navigation-placeholder__preview:not(.is-loading) {
display: flex;
opacity: 0;
width: 0;
overflow: hidden;
flex-wrap: nowrap;
flex: 0;
}
.is-vertical.is-selected .wp-block-navigation-placeholder__preview:not(.is-loading), .wp-block-navigation.is-selected .is-small .wp-block-navigation-placeholder__preview:not(.is-loading), .wp-block-navigation.is-selected .is-medium .wp-block-navigation-placeholder__preview:not(.is-loading) {
display: none;
}
.wp-block-navigation-placeholder__controls {
padding: 8px;
border-radius: 2px;
background-color: #fff;
box-shadow: inset 0 0 0 1px #1e1e1e;
flex-direction: row;
align-items: center;
display: none;
position: relative;
z-index: 1;
float: right;
width: 100%;
}
.is-large .wp-block-navigation-placeholder__controls {
padding: 4px 8px;
}
.wp-block-navigation.is-selected .wp-block-navigation-placeholder__controls {
display: flex;
}
.is-small .wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__actions, .is-medium .wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__actions, .is-vertical .wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__actions {
flex-direction: column;
}
.is-selected.is-vertical .wp-block-navigation-placeholder__controls {
display: inline-flex;
padding: 12px;
}
.wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__icon {
margin-left: 12px;
height: 36px;
}
.wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__actions__indicator {
margin-left: 12px;
padding: 0;
align-items: center;
justify-content: flex-start;
line-height: 0;
margin-right: 5px;
display: none;
}
.wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__actions__indicator svg {
margin-left: 4px;
}
.is-vertical .wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__actions__indicator {
margin-bottom: 4px;
margin-right: 0;
}
.is-large .wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__actions__indicator {
display: inline-flex;
}
.is-vertical .wp-block-navigation-placeholder,
.is-vertical .wp-block-navigation-placeholder__preview,
.is-vertical .wp-block-navigation-placeholder__controls {
min-height: 156px;
}
.is-vertical .wp-block-navigation-placeholder__preview,
.is-vertical .wp-block-navigation-placeholder__controls {
flex-direction: column;
align-items: flex-start;
}
.wp-block-navigation-placeholder__actions {
display: flex;
font-size: 13px;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
}
.wp-block-navigation-placeholder__actions .components-button.components-dropdown-menu__toggle.has-icon {
padding: 6px 12px 6px 4px;
display: flex;
flex-direction: row-reverse;
}
.wp-block-navigation-placeholder__actions .components-dropdown,
.wp-block-navigation-placeholder__actions > .components-button {
margin-left: 12px;
}
/**
* Mobile menu.
*/
@media (min-width: 600px) {
.wp-block-navigation__responsive-container:not(.is-menu-open) .components-button.wp-block-navigation__responsive-container-close {
display: none;
}
}
.wp-block-navigation__responsive-container.is-menu-open {
position: fixed;
top: 155px;
}
@media (min-width: 782px) {
.wp-block-navigation__responsive-container.is-menu-open {
top: 93px;
}
}
@media (min-width: 782px) {
.wp-block-navigation__responsive-container.is-menu-open {
right: 36px;
}
}
@media (min-width: 960px) {
.wp-block-navigation__responsive-container.is-menu-open {
right: 160px;
}
}
@media (min-width: 782px) {
.has-fixed-toolbar .wp-block-navigation__responsive-container.is-menu-open {
top: 141px;
}
}
.is-mobile-preview .wp-block-navigation__responsive-container.is-menu-open,
.is-tablet-preview .wp-block-navigation__responsive-container.is-menu-open {
top: 141px;
}
.is-sidebar-opened .wp-block-navigation__responsive-container.is-menu-open {
left: 280px;
}
.is-fullscreen-mode .wp-block-navigation__responsive-container.is-menu-open {
right: 0;
top: 155px;
}
@media (min-width: 782px) {
.is-fullscreen-mode .wp-block-navigation__responsive-container.is-menu-open {
top: 61px;
}
}
@media (min-width: 782px) {
.is-fullscreen-mode .has-fixed-toolbar .wp-block-navigation__responsive-container.is-menu-open {
top: 109px;
}
}
.is-fullscreen-mode .is-mobile-preview .wp-block-navigation__responsive-container.is-menu-open,
.is-fullscreen-mode .is-tablet-preview .wp-block-navigation__responsive-container.is-menu-open {
top: 109px;
}
body.editor-styles-wrapper .wp-block-navigation__responsive-container.is-menu-open {
top: 0;
left: 0;
bottom: 0;
right: 0;
}
@media (min-width: 600px) {
.wp-block-navigation__responsive-close {
pointer-events: none;
}
.wp-block-navigation__responsive-close .wp-block-navigation__responsive-container-close,
.wp-block-navigation__responsive-close .block-editor-block-list__layout * {
pointer-events: all;
}
}
.wp-block-navigation__responsive-close .wp-block-pages-list__item__link {
pointer-events: none;
}
.components-button.wp-block-navigation__responsive-container-open.wp-block-navigation__responsive-container-open,
.components-button.wp-block-navigation__responsive-container-close.wp-block-navigation__responsive-container-close {
padding: 0;
height: auto;
color: inherit;
}
.is-menu-open .wp-block-navigation__responsive-container-content * .block-list-appender {
margin-top: 16px;
}
@keyframes fadein {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
.wp-block-navigation__unsaved-changes {
position: relative;
}
.wp-block-navigation__unsaved-changes .components-spinner {
position: absolute;
top: calc(50% - 18px / 2);
right: calc(50% - 18px / 2);
opacity: 0;
animation: 0.5s linear 2s normal forwards fadein;
}
@keyframes fadeouthalf {
0% {
opacity: 1;
}
100% {
opacity: 0.5;
}
}
.wp-block-navigation__unsaved-changes-overlay.is-saving {
opacity: 1;
animation: 0.5s linear 2s normal forwards fadeouthalf;
}
.wp-block-navigation-delete-menu-button {
width: 100%;
justify-content: center;
margin-bottom: 16px;
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,491 @@
/**
* Colors
*/
/**
* Breakpoints & Media Queries
*/
/**
* SCSS Variables.
*
* Please use variables from this sheet to ensure consistency across the UI.
* Don't add to this sheet unless you're pretty sure the value will be reused in many places.
* For example, don't add rules to this sheet that affect block visuals. It's purely for UI.
*/
/**
* Colors
*/
/**
* Fonts & basic variables.
*/
/**
* Grid System.
* https://make.wordpress.org/design/2019/10/31/proposal-a-consistent-spacing-system-for-wordpress/
*/
/**
* Dimensions.
*/
/**
* Shadows.
*/
/**
* Editor widths.
*/
/**
* Block & Editor UI.
*/
/**
* Block paddings.
*/
/**
* React Native specific.
* These variables do not appear to be used anywhere else.
*/
/**
* Converts a hex value into the rgb equivalent.
*
* @param {string} hex - the hexadecimal value to convert
* @return {string} comma separated rgb values
*/
/**
* Breakpoint mixins
*/
/**
* Long content fade mixin
*
* Creates a fading overlay to signify that the content is longer
* than the space allows.
*/
/**
* Focus styles.
*/
/**
* Applies editor left position to the selector passed as argument
*/
/**
* Styles that are reused verbatim in a few places
*/
/**
* Allows users to opt-out of animations via OS-level preferences.
*/
/**
* Reset default styles for JavaScript UI based pages.
* This is a WP-admin agnostic reset
*/
/**
* Reset the WP Admin page styles for Gutenberg-like pages.
*/
/**
* Editor only CSS.
*/
.editor-styles-wrapper .wp-block-navigation ul {
margin-top: 0;
margin-bottom: 0;
margin-left: 0;
padding-left: 0;
}
.editor-styles-wrapper .wp-block-navigation .wp-block-navigation-item.wp-block {
margin-left: revert;
margin-right: revert;
}
.wp-block-navigation-item__label {
display: inline;
}
/**
* Submenus.
*/
.wp-block-navigation__container.is-parent-of-selected-block {
visibility: visible;
opacity: 1;
}
.wp-block-navigation__container,
.wp-block-navigation-item {
background-color: inherit;
}
.wp-block-navigation:not(.is-selected):not(.has-child-selected) .has-child:hover > .wp-block-navigation__submenu-container {
opacity: 0;
visibility: hidden;
}
.has-child.is-selected > .wp-block-navigation__submenu-container, .has-child.has-child-selected > .wp-block-navigation__submenu-container {
display: flex;
opacity: 1;
visibility: visible;
}
.is-dragging-components-draggable .has-child.is-dragging-within > .wp-block-navigation__submenu-container {
opacity: 1;
visibility: visible;
}
.is-editing > .wp-block-navigation__container {
visibility: visible;
opacity: 1;
display: flex;
flex-direction: column;
}
.is-dragging-components-draggable .wp-block-navigation-link > .wp-block-navigation__container {
opacity: 1;
visibility: hidden;
}
.is-dragging-components-draggable .wp-block-navigation-link > .wp-block-navigation__container .block-editor-block-draggable-chip-wrapper {
visibility: visible;
}
/**
* Colors Selector component
*/
.block-library-colors-selector {
width: auto;
}
.block-library-colors-selector .block-library-colors-selector__toggle {
display: block;
margin: 0 auto;
padding: 3px;
width: auto;
}
.block-library-colors-selector .block-library-colors-selector__icon-container {
height: 30px;
position: relative;
margin: 0 auto;
padding: 3px;
display: flex;
align-items: center;
border-radius: 4px;
}
.block-library-colors-selector .block-library-colors-selector__state-selection {
margin-left: auto;
margin-right: auto;
border-radius: 11px;
box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.2);
width: 22px;
min-width: 22px;
height: 22px;
min-height: 22px;
line-height: 20px;
padding: 2px;
}
.block-library-colors-selector .block-library-colors-selector__state-selection > svg {
min-width: auto !important;
}
.block-library-colors-selector .block-library-colors-selector__state-selection.has-text-color > svg,
.block-library-colors-selector .block-library-colors-selector__state-selection.has-text-color > svg path {
color: inherit;
}
.block-library-colors-selector__popover .color-palette-controller-container {
padding: 16px;
}
.block-library-colors-selector__popover .components-base-control__label {
height: 20px;
line-height: 20px;
}
.block-library-colors-selector__popover .component-color-indicator {
float: right;
margin-top: 2px;
}
.block-library-colors-selector__popover .components-panel__body-title {
display: none;
}
.wp-block-navigation .block-editor-button-block-appender {
justify-content: flex-start;
}
/**
* Setup state
*/
.components-placeholder.wp-block-navigation-placeholder {
outline: none;
padding: 0;
box-shadow: none;
background: none;
min-height: 0;
color: inherit;
}
.components-placeholder.wp-block-navigation-placeholder .components-placeholder__fieldset {
font-size: inherit;
}
.components-placeholder.wp-block-navigation-placeholder .components-placeholder__fieldset .components-button {
margin-bottom: 0;
}
.is-selected .components-placeholder.wp-block-navigation-placeholder {
color: #1e1e1e;
}
.wp-block-navigation-placeholder .components-spinner {
margin-top: -4px;
margin-left: 4px;
vertical-align: middle;
margin-right: 7px;
}
@keyframes loadingpulse {
0% {
opacity: 1;
}
50% {
opacity: 0.5;
}
100% {
opacity: 1;
}
}
.wp-block-navigation-placeholder__preview {
display: flex;
flex-direction: row;
align-items: center;
flex-wrap: nowrap;
width: 100%;
overflow: hidden;
}
.wp-block-navigation-placeholder__preview.is-loading {
animation: loadingpulse 1s linear infinite;
animation-delay: 0.5s;
}
.wp-block-navigation-placeholder__preview .wp-block-navigation-item.wp-block-navigation-item {
position: relative;
min-width: 72px;
}
.wp-block-navigation-placeholder__preview .wp-block-navigation-item.wp-block-navigation-item::before {
display: block;
content: "";
border-radius: 2px;
background: currentColor;
height: 16px;
width: 100%;
}
.wp-block-navigation-placeholder__preview .wp-block-navigation-placeholder__preview-search-icon {
height: 24px;
}
.wp-block-navigation-placeholder__preview .wp-block-navigation-placeholder__preview-search-icon svg {
fill: currentColor;
}
.wp-block-navigation-placeholder__preview .wp-block-navigation-item.wp-block-navigation-item,
.wp-block-navigation-placeholder__preview .wp-block-navigation-placeholder__preview-search-icon {
opacity: 0.3;
}
.wp-block-navigation.is-selected .wp-block-navigation-placeholder__preview:not(.is-loading) {
display: flex;
opacity: 0;
width: 0;
overflow: hidden;
flex-wrap: nowrap;
flex: 0;
}
.is-vertical.is-selected .wp-block-navigation-placeholder__preview:not(.is-loading), .wp-block-navigation.is-selected .is-small .wp-block-navigation-placeholder__preview:not(.is-loading), .wp-block-navigation.is-selected .is-medium .wp-block-navigation-placeholder__preview:not(.is-loading) {
display: none;
}
.wp-block-navigation-placeholder__controls {
padding: 8px;
border-radius: 2px;
background-color: #fff;
box-shadow: inset 0 0 0 1px #1e1e1e;
flex-direction: row;
align-items: center;
display: none;
position: relative;
z-index: 1;
float: left;
width: 100%;
}
.is-large .wp-block-navigation-placeholder__controls {
padding: 4px 8px;
}
.wp-block-navigation.is-selected .wp-block-navigation-placeholder__controls {
display: flex;
}
.is-small .wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__actions, .is-medium .wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__actions, .is-vertical .wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__actions {
flex-direction: column;
}
.is-selected.is-vertical .wp-block-navigation-placeholder__controls {
display: inline-flex;
padding: 12px;
}
.wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__icon {
margin-right: 12px;
height: 36px;
}
.wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__actions__indicator {
margin-right: 12px;
padding: 0;
align-items: center;
justify-content: flex-start;
line-height: 0;
margin-left: 5px;
display: none;
}
.wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__actions__indicator svg {
margin-right: 4px;
}
.is-vertical .wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__actions__indicator {
margin-bottom: 4px;
margin-left: 0;
}
.is-large .wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__actions__indicator {
display: inline-flex;
}
.is-vertical .wp-block-navigation-placeholder,
.is-vertical .wp-block-navigation-placeholder__preview,
.is-vertical .wp-block-navigation-placeholder__controls {
min-height: 156px;
}
.is-vertical .wp-block-navigation-placeholder__preview,
.is-vertical .wp-block-navigation-placeholder__controls {
flex-direction: column;
align-items: flex-start;
}
.wp-block-navigation-placeholder__actions {
display: flex;
font-size: 13px;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
}
.wp-block-navigation-placeholder__actions .components-button.components-dropdown-menu__toggle.has-icon {
padding: 6px 4px 6px 12px;
display: flex;
flex-direction: row-reverse;
}
.wp-block-navigation-placeholder__actions .components-dropdown,
.wp-block-navigation-placeholder__actions > .components-button {
margin-right: 12px;
}
/**
* Mobile menu.
*/
@media (min-width: 600px) {
.wp-block-navigation__responsive-container:not(.is-menu-open) .components-button.wp-block-navigation__responsive-container-close {
display: none;
}
}
.wp-block-navigation__responsive-container.is-menu-open {
position: fixed;
top: 155px;
}
@media (min-width: 782px) {
.wp-block-navigation__responsive-container.is-menu-open {
top: 93px;
}
}
@media (min-width: 782px) {
.wp-block-navigation__responsive-container.is-menu-open {
left: 36px;
}
}
@media (min-width: 960px) {
.wp-block-navigation__responsive-container.is-menu-open {
left: 160px;
}
}
@media (min-width: 782px) {
.has-fixed-toolbar .wp-block-navigation__responsive-container.is-menu-open {
top: 141px;
}
}
.is-mobile-preview .wp-block-navigation__responsive-container.is-menu-open,
.is-tablet-preview .wp-block-navigation__responsive-container.is-menu-open {
top: 141px;
}
.is-sidebar-opened .wp-block-navigation__responsive-container.is-menu-open {
right: 280px;
}
.is-fullscreen-mode .wp-block-navigation__responsive-container.is-menu-open {
left: 0;
top: 155px;
}
@media (min-width: 782px) {
.is-fullscreen-mode .wp-block-navigation__responsive-container.is-menu-open {
top: 61px;
}
}
@media (min-width: 782px) {
.is-fullscreen-mode .has-fixed-toolbar .wp-block-navigation__responsive-container.is-menu-open {
top: 109px;
}
}
.is-fullscreen-mode .is-mobile-preview .wp-block-navigation__responsive-container.is-menu-open,
.is-fullscreen-mode .is-tablet-preview .wp-block-navigation__responsive-container.is-menu-open {
top: 109px;
}
body.editor-styles-wrapper .wp-block-navigation__responsive-container.is-menu-open {
top: 0;
right: 0;
bottom: 0;
left: 0;
}
@media (min-width: 600px) {
.wp-block-navigation__responsive-close {
pointer-events: none;
}
.wp-block-navigation__responsive-close .wp-block-navigation__responsive-container-close,
.wp-block-navigation__responsive-close .block-editor-block-list__layout * {
pointer-events: all;
}
}
.wp-block-navigation__responsive-close .wp-block-pages-list__item__link {
pointer-events: none;
}
.components-button.wp-block-navigation__responsive-container-open.wp-block-navigation__responsive-container-open,
.components-button.wp-block-navigation__responsive-container-close.wp-block-navigation__responsive-container-close {
padding: 0;
height: auto;
color: inherit;
}
.is-menu-open .wp-block-navigation__responsive-container-content * .block-list-appender {
margin-top: 16px;
}
@keyframes fadein {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
.wp-block-navigation__unsaved-changes {
position: relative;
}
.wp-block-navigation__unsaved-changes .components-spinner {
position: absolute;
top: calc(50% - 18px / 2);
left: calc(50% - 18px / 2);
opacity: 0;
animation: 0.5s linear 2s normal forwards fadein;
}
@keyframes fadeouthalf {
0% {
opacity: 1;
}
100% {
opacity: 0.5;
}
}
.wp-block-navigation__unsaved-changes-overlay.is-saving {
opacity: 1;
animation: 0.5s linear 2s normal forwards fadeouthalf;
}
.wp-block-navigation-delete-menu-button {
width: 100%;
justify-content: center;
margin-bottom: 16px;
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,430 @@
/**
* Colors
*/
/**
* Breakpoints & Media Queries
*/
/**
* SCSS Variables.
*
* Please use variables from this sheet to ensure consistency across the UI.
* Don't add to this sheet unless you're pretty sure the value will be reused in many places.
* For example, don't add rules to this sheet that affect block visuals. It's purely for UI.
*/
/**
* Colors
*/
/**
* Fonts & basic variables.
*/
/**
* Grid System.
* https://make.wordpress.org/design/2019/10/31/proposal-a-consistent-spacing-system-for-wordpress/
*/
/**
* Dimensions.
*/
/**
* Shadows.
*/
/**
* Editor widths.
*/
/**
* Block & Editor UI.
*/
/**
* Block paddings.
*/
/**
* React Native specific.
* These variables do not appear to be used anywhere else.
*/
/**
* Converts a hex value into the rgb equivalent.
*
* @param {string} hex - the hexadecimal value to convert
* @return {string} comma separated rgb values
*/
/**
* Breakpoint mixins
*/
/**
* Long content fade mixin
*
* Creates a fading overlay to signify that the content is longer
* than the space allows.
*/
/**
* Focus styles.
*/
/**
* Applies editor left position to the selector passed as argument
*/
/**
* Styles that are reused verbatim in a few places
*/
/**
* Allows users to opt-out of animations via OS-level preferences.
*/
/**
* Reset default styles for JavaScript UI based pages.
* This is a WP-admin agnostic reset
*/
/**
* Reset the WP Admin page styles for Gutenberg-like pages.
*/
.wp-block-navigation {
position: relative;
}
.wp-block-navigation ul {
margin-top: 0;
margin-bottom: 0;
margin-right: 0;
padding-right: 0;
}
.wp-block-navigation ul,
.wp-block-navigation ul li {
list-style: none;
padding: 0;
}
.wp-block-navigation .wp-block-navigation-item {
display: flex;
align-items: center;
position: relative;
}
.wp-block-navigation .wp-block-navigation-item .wp-block-navigation__submenu-container:empty {
display: none;
}
.wp-block-navigation .wp-block-navigation-item__content {
color: inherit;
display: block;
padding: 0;
}
.wp-block-navigation[style*=text-decoration] .wp-block-navigation-item,
.wp-block-navigation[style*=text-decoration] .wp-block-navigation__submenu-container {
text-decoration: inherit;
}
.wp-block-navigation[style*=text-decoration] a {
text-decoration: inherit;
}
.wp-block-navigation[style*=text-decoration] a:focus, .wp-block-navigation[style*=text-decoration] a:active {
text-decoration: inherit;
}
.wp-block-navigation:not([style*=text-decoration]) a {
text-decoration: none;
}
.wp-block-navigation:not([style*=text-decoration]) a:focus, .wp-block-navigation:not([style*=text-decoration]) a:active {
text-decoration: none;
}
.wp-block-navigation .wp-block-navigation__submenu-icon {
align-self: center;
height: inherit;
line-height: 0;
margin-right: 6px;
padding: 0;
background-color: inherit;
color: currentColor;
border: none;
}
.wp-block-navigation .wp-block-navigation__submenu-icon svg {
display: inline-block;
stroke: currentColor;
}
.wp-block-navigation .has-child :where(.wp-block-navigation__submenu-container) {
background-color: inherit;
color: inherit;
position: absolute;
z-index: 2;
display: flex;
flex-direction: column;
align-items: normal;
opacity: 0;
transition: opacity 0.1s linear;
visibility: hidden;
width: 0;
height: 0;
right: -1px;
top: 100%;
}
.wp-block-navigation .has-child :where(.wp-block-navigation__submenu-container) > .wp-block-navigation-item > .wp-block-navigation-item__content {
display: flex;
flex-grow: 1;
white-space: nowrap;
}
.wp-block-navigation .has-child :where(.wp-block-navigation__submenu-container) > .wp-block-navigation-item > .wp-block-navigation-item__content .wp-block-navigation__submenu-icon {
margin-left: 0;
margin-right: auto;
}
.wp-block-navigation .has-child :where(.wp-block-navigation__submenu-container) .wp-block-navigation-item__content {
margin: 0;
}
@media (min-width: 782px) {
.wp-block-navigation .has-child :where(.wp-block-navigation__submenu-container) .wp-block-navigation__submenu-container {
right: 100%;
top: -1px;
}
.wp-block-navigation .has-child :where(.wp-block-navigation__submenu-container) .wp-block-navigation__submenu-container::before {
content: "";
position: absolute;
left: 100%;
height: 100%;
display: block;
width: 0.5em;
background: transparent;
}
.wp-block-navigation .has-child :where(.wp-block-navigation__submenu-container) .wp-block-navigation__submenu-icon svg {
transform: rotate(90deg);
}
}
.wp-block-navigation .has-child:where(:not(.open-on-click)):hover > .wp-block-navigation__submenu-container {
visibility: visible;
opacity: 1;
width: auto;
height: auto;
min-width: 200px;
}
.wp-block-navigation .has-child:where(:not(.open-on-click):not(.open-on-hover-click)):focus-within > .wp-block-navigation__submenu-container {
visibility: visible;
opacity: 1;
width: auto;
height: auto;
min-width: 200px;
}
.wp-block-navigation .has-child .wp-block-navigation-submenu__toggle[aria-expanded=true] + .wp-block-navigation__submenu-container {
visibility: visible;
opacity: 1;
width: auto;
height: auto;
min-width: 200px;
}
.wp-block-navigation.has-background .has-child .wp-block-navigation__submenu-container {
right: 0;
top: 100%;
}
@media (min-width: 782px) {
.wp-block-navigation.has-background .has-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container {
right: 100%;
top: 0;
}
}
/**
* Margins
*/
.wp-block-navigation,
.wp-block-navigation .wp-block-page-list,
.wp-block-navigation__container,
.wp-block-navigation__responsive-container-content {
gap: var(--wp--style--block-gap, 2em);
}
.wp-block-navigation:where(.has-background),
.wp-block-navigation:where(.has-background) .wp-block-navigation .wp-block-page-list,
.wp-block-navigation:where(.has-background) .wp-block-navigation__container {
gap: var(--wp--style--block-gap, 0.5em);
}
/**
* Paddings
*/
.wp-block-navigation:where(.has-background) .wp-block-navigation-item__content {
padding: 0.5em 1em;
}
.wp-block-navigation :where(.wp-block-navigation__submenu-container) .wp-block-navigation-item__content {
padding: 0.5em 1em;
}
/**
* Justifications.
*/
@media (min-width: 782px) {
.wp-block-navigation.items-justified-space-between .wp-block-page-list > .has-child:last-child .wp-block-navigation__submenu-container,
.wp-block-navigation.items-justified-space-between > .wp-block-navigation__container > .has-child:last-child .wp-block-navigation__submenu-container,
.wp-block-navigation.items-justified-right .wp-block-page-list > .has-child .wp-block-navigation__submenu-container,
.wp-block-navigation.items-justified-right .wp-block-navigation__container .has-child .wp-block-navigation__submenu-container {
right: auto;
left: 0;
}
.wp-block-navigation.items-justified-space-between .wp-block-page-list > .has-child:last-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container,
.wp-block-navigation.items-justified-space-between > .wp-block-navigation__container > .has-child:last-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container,
.wp-block-navigation.items-justified-right .wp-block-page-list > .has-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container,
.wp-block-navigation.items-justified-right .wp-block-navigation__container .has-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container {
right: auto;
left: 100%;
}
}
.wp-block-navigation:not(.has-background) .wp-block-navigation__submenu-container {
background-color: #fff;
color: #000;
border: 1px solid rgba(0, 0, 0, 0.15);
}
.wp-block-navigation__container {
list-style: none;
margin: 0;
padding-right: 0;
}
.wp-block-navigation__container .is-responsive {
display: none;
}
/**
* Mobile menu.
*/
.wp-block-navigation__responsive-container {
display: none;
position: fixed;
top: 0;
right: 0;
left: 0;
bottom: 0;
}
.wp-block-navigation__responsive-container .wp-block-navigation__responsive-container-content {
display: contents;
}
.wp-block-navigation__responsive-container.is-menu-open {
display: flex;
flex-direction: column;
overflow: auto;
z-index: 100000;
padding: 72px 24px 24px 24px;
background-color: inherit;
align-items: inherit;
}
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content {
display: flex;
flex-direction: column;
align-items: var(--justification-setting, inherit);
overflow: auto;
padding: 0;
}
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation__submenu-icon {
display: none;
}
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .has-child .submenu-container,
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .has-child .wp-block-navigation__submenu-container {
opacity: 1;
visibility: visible;
height: auto;
width: auto;
overflow: initial;
min-width: 200px;
position: static;
border: none;
padding-right: 32px;
padding-left: 32px;
}
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation__submenu-container,
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation__container {
gap: var(--wp--style--block-gap, 2em);
}
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container,
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation__submenu-container .wp-block-navigation__container,
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation__container .wp-block-navigation__submenu-container,
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation__container .wp-block-navigation__container {
padding-top: var(--wp--style--block-gap, 2em);
}
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation-item__content {
padding: 0;
}
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation__container,
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation-item,
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-page-list {
display: flex;
flex-direction: column;
align-items: var(--justification-setting, inherit);
}
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item .wp-block-navigation__submenu-container,
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item {
color: inherit !important;
background: transparent !important;
}
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__submenu-container.wp-block-navigation__submenu-container.wp-block-navigation__submenu-container.wp-block-navigation__submenu-container {
left: auto;
right: auto;
}
@media (min-width: 600px) {
.wp-block-navigation__responsive-container:not(.hidden-by-default):not(.is-menu-open) {
display: contents;
width: 100%;
position: relative;
z-index: 2;
background-color: inherit;
}
.wp-block-navigation__responsive-container:not(.hidden-by-default):not(.is-menu-open) .wp-block-navigation__responsive-container-close {
display: none;
}
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__submenu-container.wp-block-navigation__submenu-container.wp-block-navigation__submenu-container.wp-block-navigation__submenu-container {
right: 0;
}
}
.wp-block-navigation:not(.has-background) .wp-block-navigation__responsive-container.is-menu-open {
background-color: #fff;
color: #000;
}
.wp-block-navigation__responsive-container-open,
.wp-block-navigation__responsive-container-close {
vertical-align: middle;
cursor: pointer;
color: currentColor;
background: transparent;
border: none;
margin: 0;
padding: 0;
}
.wp-block-navigation__responsive-container-open svg,
.wp-block-navigation__responsive-container-close svg {
fill: currentColor;
pointer-events: none;
display: block;
width: 24px;
height: 24px;
}
.wp-block-navigation__responsive-container-open {
display: flex;
}
@media (min-width: 600px) {
.wp-block-navigation__responsive-container-open:not(.always-shown) {
display: none;
}
}
.wp-block-navigation__responsive-container-close {
position: absolute;
top: 24px;
left: 24px;
z-index: 2;
}
.wp-block-navigation__responsive-close {
width: 100%;
}
.is-menu-open .wp-block-navigation__responsive-close,
.is-menu-open .wp-block-navigation__responsive-dialog,
.is-menu-open .wp-block-navigation__responsive-container-content {
width: 100%;
height: 100%;
}
html.has-modal-open {
overflow: hidden;
}
.wp-block-navigation__responsive-close,
.wp-block-navigation__responsive-dialog,
.wp-block-navigation__container {
display: contents;
}
.is-menu-open .wp-block-navigation__responsive-close,
.is-menu-open .wp-block-navigation__responsive-dialog,
.is-menu-open .wp-block-navigation__container {
align-items: inherit;
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,430 @@
/**
* Colors
*/
/**
* Breakpoints & Media Queries
*/
/**
* SCSS Variables.
*
* Please use variables from this sheet to ensure consistency across the UI.
* Don't add to this sheet unless you're pretty sure the value will be reused in many places.
* For example, don't add rules to this sheet that affect block visuals. It's purely for UI.
*/
/**
* Colors
*/
/**
* Fonts & basic variables.
*/
/**
* Grid System.
* https://make.wordpress.org/design/2019/10/31/proposal-a-consistent-spacing-system-for-wordpress/
*/
/**
* Dimensions.
*/
/**
* Shadows.
*/
/**
* Editor widths.
*/
/**
* Block & Editor UI.
*/
/**
* Block paddings.
*/
/**
* React Native specific.
* These variables do not appear to be used anywhere else.
*/
/**
* Converts a hex value into the rgb equivalent.
*
* @param {string} hex - the hexadecimal value to convert
* @return {string} comma separated rgb values
*/
/**
* Breakpoint mixins
*/
/**
* Long content fade mixin
*
* Creates a fading overlay to signify that the content is longer
* than the space allows.
*/
/**
* Focus styles.
*/
/**
* Applies editor left position to the selector passed as argument
*/
/**
* Styles that are reused verbatim in a few places
*/
/**
* Allows users to opt-out of animations via OS-level preferences.
*/
/**
* Reset default styles for JavaScript UI based pages.
* This is a WP-admin agnostic reset
*/
/**
* Reset the WP Admin page styles for Gutenberg-like pages.
*/
.wp-block-navigation {
position: relative;
}
.wp-block-navigation ul {
margin-top: 0;
margin-bottom: 0;
margin-left: 0;
padding-left: 0;
}
.wp-block-navigation ul,
.wp-block-navigation ul li {
list-style: none;
padding: 0;
}
.wp-block-navigation .wp-block-navigation-item {
display: flex;
align-items: center;
position: relative;
}
.wp-block-navigation .wp-block-navigation-item .wp-block-navigation__submenu-container:empty {
display: none;
}
.wp-block-navigation .wp-block-navigation-item__content {
color: inherit;
display: block;
padding: 0;
}
.wp-block-navigation[style*=text-decoration] .wp-block-navigation-item,
.wp-block-navigation[style*=text-decoration] .wp-block-navigation__submenu-container {
text-decoration: inherit;
}
.wp-block-navigation[style*=text-decoration] a {
text-decoration: inherit;
}
.wp-block-navigation[style*=text-decoration] a:focus, .wp-block-navigation[style*=text-decoration] a:active {
text-decoration: inherit;
}
.wp-block-navigation:not([style*=text-decoration]) a {
text-decoration: none;
}
.wp-block-navigation:not([style*=text-decoration]) a:focus, .wp-block-navigation:not([style*=text-decoration]) a:active {
text-decoration: none;
}
.wp-block-navigation .wp-block-navigation__submenu-icon {
align-self: center;
height: inherit;
line-height: 0;
margin-left: 6px;
padding: 0;
background-color: inherit;
color: currentColor;
border: none;
}
.wp-block-navigation .wp-block-navigation__submenu-icon svg {
display: inline-block;
stroke: currentColor;
}
.wp-block-navigation .has-child :where(.wp-block-navigation__submenu-container) {
background-color: inherit;
color: inherit;
position: absolute;
z-index: 2;
display: flex;
flex-direction: column;
align-items: normal;
opacity: 0;
transition: opacity 0.1s linear;
visibility: hidden;
width: 0;
height: 0;
left: -1px;
top: 100%;
}
.wp-block-navigation .has-child :where(.wp-block-navigation__submenu-container) > .wp-block-navigation-item > .wp-block-navigation-item__content {
display: flex;
flex-grow: 1;
white-space: nowrap;
}
.wp-block-navigation .has-child :where(.wp-block-navigation__submenu-container) > .wp-block-navigation-item > .wp-block-navigation-item__content .wp-block-navigation__submenu-icon {
margin-right: 0;
margin-left: auto;
}
.wp-block-navigation .has-child :where(.wp-block-navigation__submenu-container) .wp-block-navigation-item__content {
margin: 0;
}
@media (min-width: 782px) {
.wp-block-navigation .has-child :where(.wp-block-navigation__submenu-container) .wp-block-navigation__submenu-container {
left: 100%;
top: -1px;
}
.wp-block-navigation .has-child :where(.wp-block-navigation__submenu-container) .wp-block-navigation__submenu-container::before {
content: "";
position: absolute;
right: 100%;
height: 100%;
display: block;
width: 0.5em;
background: transparent;
}
.wp-block-navigation .has-child :where(.wp-block-navigation__submenu-container) .wp-block-navigation__submenu-icon svg {
transform: rotate(-90deg);
}
}
.wp-block-navigation .has-child:where(:not(.open-on-click)):hover > .wp-block-navigation__submenu-container {
visibility: visible;
opacity: 1;
width: auto;
height: auto;
min-width: 200px;
}
.wp-block-navigation .has-child:where(:not(.open-on-click):not(.open-on-hover-click)):focus-within > .wp-block-navigation__submenu-container {
visibility: visible;
opacity: 1;
width: auto;
height: auto;
min-width: 200px;
}
.wp-block-navigation .has-child .wp-block-navigation-submenu__toggle[aria-expanded=true] + .wp-block-navigation__submenu-container {
visibility: visible;
opacity: 1;
width: auto;
height: auto;
min-width: 200px;
}
.wp-block-navigation.has-background .has-child .wp-block-navigation__submenu-container {
left: 0;
top: 100%;
}
@media (min-width: 782px) {
.wp-block-navigation.has-background .has-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container {
left: 100%;
top: 0;
}
}
/**
* Margins
*/
.wp-block-navigation,
.wp-block-navigation .wp-block-page-list,
.wp-block-navigation__container,
.wp-block-navigation__responsive-container-content {
gap: var(--wp--style--block-gap, 2em);
}
.wp-block-navigation:where(.has-background),
.wp-block-navigation:where(.has-background) .wp-block-navigation .wp-block-page-list,
.wp-block-navigation:where(.has-background) .wp-block-navigation__container {
gap: var(--wp--style--block-gap, 0.5em);
}
/**
* Paddings
*/
.wp-block-navigation:where(.has-background) .wp-block-navigation-item__content {
padding: 0.5em 1em;
}
.wp-block-navigation :where(.wp-block-navigation__submenu-container) .wp-block-navigation-item__content {
padding: 0.5em 1em;
}
/**
* Justifications.
*/
@media (min-width: 782px) {
.wp-block-navigation.items-justified-space-between .wp-block-page-list > .has-child:last-child .wp-block-navigation__submenu-container,
.wp-block-navigation.items-justified-space-between > .wp-block-navigation__container > .has-child:last-child .wp-block-navigation__submenu-container,
.wp-block-navigation.items-justified-right .wp-block-page-list > .has-child .wp-block-navigation__submenu-container,
.wp-block-navigation.items-justified-right .wp-block-navigation__container .has-child .wp-block-navigation__submenu-container {
left: auto;
right: 0;
}
.wp-block-navigation.items-justified-space-between .wp-block-page-list > .has-child:last-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container,
.wp-block-navigation.items-justified-space-between > .wp-block-navigation__container > .has-child:last-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container,
.wp-block-navigation.items-justified-right .wp-block-page-list > .has-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container,
.wp-block-navigation.items-justified-right .wp-block-navigation__container .has-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container {
left: auto;
right: 100%;
}
}
.wp-block-navigation:not(.has-background) .wp-block-navigation__submenu-container {
background-color: #fff;
color: #000;
border: 1px solid rgba(0, 0, 0, 0.15);
}
.wp-block-navigation__container {
list-style: none;
margin: 0;
padding-left: 0;
}
.wp-block-navigation__container .is-responsive {
display: none;
}
/**
* Mobile menu.
*/
.wp-block-navigation__responsive-container {
display: none;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.wp-block-navigation__responsive-container .wp-block-navigation__responsive-container-content {
display: contents;
}
.wp-block-navigation__responsive-container.is-menu-open {
display: flex;
flex-direction: column;
overflow: auto;
z-index: 100000;
padding: 72px 24px 24px 24px;
background-color: inherit;
align-items: inherit;
}
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content {
display: flex;
flex-direction: column;
align-items: var(--justification-setting, inherit);
overflow: auto;
padding: 0;
}
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation__submenu-icon {
display: none;
}
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .has-child .submenu-container,
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .has-child .wp-block-navigation__submenu-container {
opacity: 1;
visibility: visible;
height: auto;
width: auto;
overflow: initial;
min-width: 200px;
position: static;
border: none;
padding-left: 32px;
padding-right: 32px;
}
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation__submenu-container,
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation__container {
gap: var(--wp--style--block-gap, 2em);
}
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container,
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation__submenu-container .wp-block-navigation__container,
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation__container .wp-block-navigation__submenu-container,
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation__container .wp-block-navigation__container {
padding-top: var(--wp--style--block-gap, 2em);
}
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation-item__content {
padding: 0;
}
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation__container,
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation-item,
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-page-list {
display: flex;
flex-direction: column;
align-items: var(--justification-setting, inherit);
}
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item .wp-block-navigation__submenu-container,
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item {
color: inherit !important;
background: transparent !important;
}
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__submenu-container.wp-block-navigation__submenu-container.wp-block-navigation__submenu-container.wp-block-navigation__submenu-container {
right: auto;
left: auto;
}
@media (min-width: 600px) {
.wp-block-navigation__responsive-container:not(.hidden-by-default):not(.is-menu-open) {
display: contents;
width: 100%;
position: relative;
z-index: 2;
background-color: inherit;
}
.wp-block-navigation__responsive-container:not(.hidden-by-default):not(.is-menu-open) .wp-block-navigation__responsive-container-close {
display: none;
}
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__submenu-container.wp-block-navigation__submenu-container.wp-block-navigation__submenu-container.wp-block-navigation__submenu-container {
left: 0;
}
}
.wp-block-navigation:not(.has-background) .wp-block-navigation__responsive-container.is-menu-open {
background-color: #fff;
color: #000;
}
.wp-block-navigation__responsive-container-open,
.wp-block-navigation__responsive-container-close {
vertical-align: middle;
cursor: pointer;
color: currentColor;
background: transparent;
border: none;
margin: 0;
padding: 0;
}
.wp-block-navigation__responsive-container-open svg,
.wp-block-navigation__responsive-container-close svg {
fill: currentColor;
pointer-events: none;
display: block;
width: 24px;
height: 24px;
}
.wp-block-navigation__responsive-container-open {
display: flex;
}
@media (min-width: 600px) {
.wp-block-navigation__responsive-container-open:not(.always-shown) {
display: none;
}
}
.wp-block-navigation__responsive-container-close {
position: absolute;
top: 24px;
right: 24px;
z-index: 2;
}
.wp-block-navigation__responsive-close {
width: 100%;
}
.is-menu-open .wp-block-navigation__responsive-close,
.is-menu-open .wp-block-navigation__responsive-dialog,
.is-menu-open .wp-block-navigation__responsive-container-content {
width: 100%;
height: 100%;
}
html.has-modal-open {
overflow: hidden;
}
.wp-block-navigation__responsive-close,
.wp-block-navigation__responsive-dialog,
.wp-block-navigation__container {
display: contents;
}
.is-menu-open .wp-block-navigation__responsive-close,
.is-menu-open .wp-block-navigation__responsive-dialog,
.is-menu-open .wp-block-navigation__container {
align-items: inherit;
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
<?php return array('dependencies' => array(), 'version' => 'f63141a5a5be0a629c2580a2c4b8e4f8');

View File

@ -0,0 +1,619 @@
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ }
/******/ };
/******/
/******/ // define __esModule on exports
/******/ __webpack_require__.r = function(exports) {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/
/******/ // create a fake namespace object
/******/ // mode & 1: value is a module id, require it
/******/ // mode & 2: merge all properties of value into the ns
/******/ // mode & 4: return value when already ns object
/******/ // mode & 8|1: behave like require
/******/ __webpack_require__.t = function(value, mode) {
/******/ if(mode & 1) value = __webpack_require__(value);
/******/ if(mode & 8) return value;
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ var ns = Object.create(null);
/******/ __webpack_require__.r(ns);
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ return ns;
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = "kVj6");
/******/ })
/************************************************************************/
/******/ ({
/***/ "kVj6":
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
// ESM COMPAT FLAG
__webpack_require__.r(__webpack_exports__);
// CONCATENATED MODULE: ./node_modules/micromodal/dist/micromodal.es.js
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
function _defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
function _toConsumableArray(arr) {
return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
}
function _arrayWithoutHoles(arr) {
if (Array.isArray(arr)) return _arrayLikeToArray(arr);
}
function _iterableToArray(iter) {
if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter);
}
function _unsupportedIterableToArray(o, minLen) {
if (!o) return;
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
var n = Object.prototype.toString.call(o).slice(8, -1);
if (n === "Object" && o.constructor) n = o.constructor.name;
if (n === "Map" || n === "Set") return Array.from(n);
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
}
function _arrayLikeToArray(arr, len) {
if (len == null || len > arr.length) len = arr.length;
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
return arr2;
}
function _nonIterableSpread() {
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
var MicroModal = function () {
var FOCUSABLE_ELEMENTS = ['a[href]', 'area[href]', 'input:not([disabled]):not([type="hidden"]):not([aria-hidden])', 'select:not([disabled]):not([aria-hidden])', 'textarea:not([disabled]):not([aria-hidden])', 'button:not([disabled]):not([aria-hidden])', 'iframe', 'object', 'embed', '[contenteditable]', '[tabindex]:not([tabindex^="-"])'];
var Modal = /*#__PURE__*/function () {
function Modal(_ref) {
var targetModal = _ref.targetModal,
_ref$triggers = _ref.triggers,
triggers = _ref$triggers === void 0 ? [] : _ref$triggers,
_ref$onShow = _ref.onShow,
onShow = _ref$onShow === void 0 ? function () {} : _ref$onShow,
_ref$onClose = _ref.onClose,
onClose = _ref$onClose === void 0 ? function () {} : _ref$onClose,
_ref$openTrigger = _ref.openTrigger,
openTrigger = _ref$openTrigger === void 0 ? 'data-micromodal-trigger' : _ref$openTrigger,
_ref$closeTrigger = _ref.closeTrigger,
closeTrigger = _ref$closeTrigger === void 0 ? 'data-micromodal-close' : _ref$closeTrigger,
_ref$openClass = _ref.openClass,
openClass = _ref$openClass === void 0 ? 'is-open' : _ref$openClass,
_ref$disableScroll = _ref.disableScroll,
disableScroll = _ref$disableScroll === void 0 ? false : _ref$disableScroll,
_ref$disableFocus = _ref.disableFocus,
disableFocus = _ref$disableFocus === void 0 ? false : _ref$disableFocus,
_ref$awaitCloseAnimat = _ref.awaitCloseAnimation,
awaitCloseAnimation = _ref$awaitCloseAnimat === void 0 ? false : _ref$awaitCloseAnimat,
_ref$awaitOpenAnimati = _ref.awaitOpenAnimation,
awaitOpenAnimation = _ref$awaitOpenAnimati === void 0 ? false : _ref$awaitOpenAnimati,
_ref$debugMode = _ref.debugMode,
debugMode = _ref$debugMode === void 0 ? false : _ref$debugMode;
_classCallCheck(this, Modal);
// Save a reference of the modal
this.modal = document.getElementById(targetModal); // Save a reference to the passed config
this.config = {
debugMode: debugMode,
disableScroll: disableScroll,
openTrigger: openTrigger,
closeTrigger: closeTrigger,
openClass: openClass,
onShow: onShow,
onClose: onClose,
awaitCloseAnimation: awaitCloseAnimation,
awaitOpenAnimation: awaitOpenAnimation,
disableFocus: disableFocus
}; // Register click events only if pre binding eventListeners
if (triggers.length > 0) this.registerTriggers.apply(this, _toConsumableArray(triggers)); // pre bind functions for event listeners
this.onClick = this.onClick.bind(this);
this.onKeydown = this.onKeydown.bind(this);
}
/**
* Loops through all openTriggers and binds click event
* @param {array} triggers [Array of node elements]
* @return {void}
*/
_createClass(Modal, [{
key: "registerTriggers",
value: function registerTriggers() {
var _this = this;
for (var _len = arguments.length, triggers = new Array(_len), _key = 0; _key < _len; _key++) {
triggers[_key] = arguments[_key];
}
triggers.filter(Boolean).forEach(function (trigger) {
trigger.addEventListener('click', function (event) {
return _this.showModal(event);
});
});
}
}, {
key: "showModal",
value: function showModal() {
var _this2 = this;
var event = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
this.activeElement = document.activeElement;
this.modal.setAttribute('aria-hidden', 'false');
this.modal.classList.add(this.config.openClass);
this.scrollBehaviour('disable');
this.addEventListeners();
if (this.config.awaitOpenAnimation) {
var handler = function handler() {
_this2.modal.removeEventListener('animationend', handler, false);
_this2.setFocusToFirstNode();
};
this.modal.addEventListener('animationend', handler, false);
} else {
this.setFocusToFirstNode();
}
this.config.onShow(this.modal, this.activeElement, event);
}
}, {
key: "closeModal",
value: function closeModal() {
var event = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
var modal = this.modal;
this.modal.setAttribute('aria-hidden', 'true');
this.removeEventListeners();
this.scrollBehaviour('enable');
if (this.activeElement && this.activeElement.focus) {
this.activeElement.focus();
}
this.config.onClose(this.modal, this.activeElement, event);
if (this.config.awaitCloseAnimation) {
var openClass = this.config.openClass; // <- old school ftw
this.modal.addEventListener('animationend', function handler() {
modal.classList.remove(openClass);
modal.removeEventListener('animationend', handler, false);
}, false);
} else {
modal.classList.remove(this.config.openClass);
}
}
}, {
key: "closeModalById",
value: function closeModalById(targetModal) {
this.modal = document.getElementById(targetModal);
if (this.modal) this.closeModal();
}
}, {
key: "scrollBehaviour",
value: function scrollBehaviour(toggle) {
if (!this.config.disableScroll) return;
var body = document.querySelector('body');
switch (toggle) {
case 'enable':
Object.assign(body.style, {
overflow: ''
});
break;
case 'disable':
Object.assign(body.style, {
overflow: 'hidden'
});
break;
}
}
}, {
key: "addEventListeners",
value: function addEventListeners() {
this.modal.addEventListener('touchstart', this.onClick);
this.modal.addEventListener('click', this.onClick);
document.addEventListener('keydown', this.onKeydown);
}
}, {
key: "removeEventListeners",
value: function removeEventListeners() {
this.modal.removeEventListener('touchstart', this.onClick);
this.modal.removeEventListener('click', this.onClick);
document.removeEventListener('keydown', this.onKeydown);
}
}, {
key: "onClick",
value: function onClick(event) {
if (event.target.hasAttribute(this.config.closeTrigger)) {
this.closeModal(event);
}
}
}, {
key: "onKeydown",
value: function onKeydown(event) {
if (event.keyCode === 27) this.closeModal(event); // esc
if (event.keyCode === 9) this.retainFocus(event); // tab
}
}, {
key: "getFocusableNodes",
value: function getFocusableNodes() {
var nodes = this.modal.querySelectorAll(FOCUSABLE_ELEMENTS);
return Array.apply(void 0, _toConsumableArray(nodes));
}
/**
* Tries to set focus on a node which is not a close trigger
* if no other nodes exist then focuses on first close trigger
*/
}, {
key: "setFocusToFirstNode",
value: function setFocusToFirstNode() {
var _this3 = this;
if (this.config.disableFocus) return;
var focusableNodes = this.getFocusableNodes(); // no focusable nodes
if (focusableNodes.length === 0) return; // remove nodes on whose click, the modal closes
// could not think of a better name :(
var nodesWhichAreNotCloseTargets = focusableNodes.filter(function (node) {
return !node.hasAttribute(_this3.config.closeTrigger);
});
if (nodesWhichAreNotCloseTargets.length > 0) nodesWhichAreNotCloseTargets[0].focus();
if (nodesWhichAreNotCloseTargets.length === 0) focusableNodes[0].focus();
}
}, {
key: "retainFocus",
value: function retainFocus(event) {
var focusableNodes = this.getFocusableNodes(); // no focusable nodes
if (focusableNodes.length === 0) return;
/**
* Filters nodes which are hidden to prevent
* focus leak outside modal
*/
focusableNodes = focusableNodes.filter(function (node) {
return node.offsetParent !== null;
}); // if disableFocus is true
if (!this.modal.contains(document.activeElement)) {
focusableNodes[0].focus();
} else {
var focusedItemIndex = focusableNodes.indexOf(document.activeElement);
if (event.shiftKey && focusedItemIndex === 0) {
focusableNodes[focusableNodes.length - 1].focus();
event.preventDefault();
}
if (!event.shiftKey && focusableNodes.length > 0 && focusedItemIndex === focusableNodes.length - 1) {
focusableNodes[0].focus();
event.preventDefault();
}
}
}
}]);
return Modal;
}();
/**
* Modal prototype ends.
* Here on code is responsible for detecting and
* auto binding event handlers on modal triggers
*/
// Keep a reference to the opened modal
var activeModal = null;
/**
* Generates an associative array of modals and it's
* respective triggers
* @param {array} triggers An array of all triggers
* @param {string} triggerAttr The data-attribute which triggers the module
* @return {array}
*/
var generateTriggerMap = function generateTriggerMap(triggers, triggerAttr) {
var triggerMap = [];
triggers.forEach(function (trigger) {
var targetModal = trigger.attributes[triggerAttr].value;
if (triggerMap[targetModal] === undefined) triggerMap[targetModal] = [];
triggerMap[targetModal].push(trigger);
});
return triggerMap;
};
/**
* Validates whether a modal of the given id exists
* in the DOM
* @param {number} id The id of the modal
* @return {boolean}
*/
var validateModalPresence = function validateModalPresence(id) {
if (!document.getElementById(id)) {
console.warn("MicroModal: \u2757Seems like you have missed %c'".concat(id, "'"), 'background-color: #f8f9fa;color: #50596c;font-weight: bold;', 'ID somewhere in your code. Refer example below to resolve it.');
console.warn("%cExample:", 'background-color: #f8f9fa;color: #50596c;font-weight: bold;', "<div class=\"modal\" id=\"".concat(id, "\"></div>"));
return false;
}
};
/**
* Validates if there are modal triggers present
* in the DOM
* @param {array} triggers An array of data-triggers
* @return {boolean}
*/
var validateTriggerPresence = function validateTriggerPresence(triggers) {
if (triggers.length <= 0) {
console.warn("MicroModal: \u2757Please specify at least one %c'micromodal-trigger'", 'background-color: #f8f9fa;color: #50596c;font-weight: bold;', 'data attribute.');
console.warn("%cExample:", 'background-color: #f8f9fa;color: #50596c;font-weight: bold;', "<a href=\"#\" data-micromodal-trigger=\"my-modal\"></a>");
return false;
}
};
/**
* Checks if triggers and their corresponding modals
* are present in the DOM
* @param {array} triggers Array of DOM nodes which have data-triggers
* @param {array} triggerMap Associative array of modals and their triggers
* @return {boolean}
*/
var validateArgs = function validateArgs(triggers, triggerMap) {
validateTriggerPresence(triggers);
if (!triggerMap) return true;
for (var id in triggerMap) {
validateModalPresence(id);
}
return true;
};
/**
* Binds click handlers to all modal triggers
* @param {object} config [description]
* @return void
*/
var init = function init(config) {
// Create an config object with default openTrigger
var options = Object.assign({}, {
openTrigger: 'data-micromodal-trigger'
}, config); // Collects all the nodes with the trigger
var triggers = _toConsumableArray(document.querySelectorAll("[".concat(options.openTrigger, "]"))); // Makes a mappings of modals with their trigger nodes
var triggerMap = generateTriggerMap(triggers, options.openTrigger); // Checks if modals and triggers exist in dom
if (options.debugMode === true && validateArgs(triggers, triggerMap) === false) return; // For every target modal creates a new instance
for (var key in triggerMap) {
var value = triggerMap[key];
options.targetModal = key;
options.triggers = _toConsumableArray(value);
activeModal = new Modal(options); // eslint-disable-line no-new
}
};
/**
* Shows a particular modal
* @param {string} targetModal [The id of the modal to display]
* @param {object} config [The configuration object to pass]
* @return {void}
*/
var show = function show(targetModal, config) {
var options = config || {};
options.targetModal = targetModal; // Checks if modals and triggers exist in dom
if (options.debugMode === true && validateModalPresence(targetModal) === false) return; // clear events in case previous modal wasn't close
if (activeModal) activeModal.removeEventListeners(); // stores reference to active modal
activeModal = new Modal(options); // eslint-disable-line no-new
activeModal.showModal();
};
/**
* Closes the active modal
* @param {string} targetModal [The id of the modal to close]
* @return {void}
*/
var close = function close(targetModal) {
targetModal ? activeModal.closeModalById(targetModal) : activeModal.closeModal();
};
return {
init: init,
show: show,
close: close
};
}();
window.MicroModal = MicroModal;
/* harmony default export */ var micromodal_es = (MicroModal);
// CONCATENATED MODULE: ./node_modules/@wordpress/block-library/build-module/navigation/view.js
/**
* External dependencies
*/
// Responsive navigation toggle.
function navigationToggleModal(modal) {
const triggerButton = document.querySelector(`button[data-micromodal-trigger="${modal.id}"]`);
const closeButton = modal.querySelector('button[data-micromodal-close]'); // Use aria-hidden to determine the status of the modal, as this attribute is
// managed by micromodal.
const isHidden = 'true' === modal.getAttribute('aria-hidden');
triggerButton.setAttribute('aria-expanded', !isHidden);
closeButton.setAttribute('aria-expanded', !isHidden);
modal.classList.toggle('has-modal-open', !isHidden); // Add a class to indicate the modal is open.
const htmlElement = document.documentElement;
htmlElement.classList.toggle('has-modal-open');
} // Open on click functionality.
function closeSubmenus(element) {
element.querySelectorAll('[aria-expanded="true"]').forEach(function (toggle) {
toggle.setAttribute('aria-expanded', 'false');
});
}
function toggleSubmenuOnClick(event) {
const buttonToggle = event.target.closest('[aria-expanded]');
const isSubmenuOpen = buttonToggle.getAttribute('aria-expanded');
if (isSubmenuOpen === 'true') {
closeSubmenus(buttonToggle.closest('.wp-block-navigation-item'));
} else {
// Close all sibling submenus.
const parentElement = buttonToggle.closest('.wp-block-navigation-item');
const navigationParent = buttonToggle.closest('.wp-block-navigation__submenu-container, .wp-block-navigation__container, .wp-block-page-list');
navigationParent.querySelectorAll('.wp-block-navigation-item').forEach(function (child) {
if (child !== parentElement) {
closeSubmenus(child);
}
}); // Open submenu.
buttonToggle.setAttribute('aria-expanded', 'true');
}
}
const submenuButtons = document.querySelectorAll('.wp-block-navigation-submenu__toggle');
submenuButtons.forEach(function (button) {
button.addEventListener('click', toggleSubmenuOnClick);
}); // Close on click outside.
document.addEventListener('click', function (event) {
const navigationBlocks = document.querySelectorAll('.wp-block-navigation');
navigationBlocks.forEach(function (block) {
if (!block.contains(event.target)) {
closeSubmenus(block);
}
});
}); // Close on focus outside.
document.addEventListener('keyup', function (event) {
const submenuBlocks = document.querySelectorAll('.wp-block-navigation-item.has-child');
submenuBlocks.forEach(function (block) {
if (!block.contains(event.target)) {
closeSubmenus(block);
}
});
}); // Necessary for some themes such as TT1 Blocks, where
// scripts could be loaded before the body.
window.onload = () => micromodal_es.init({
onShow: navigationToggleModal,
onClose: navigationToggleModal,
openClass: 'is-menu-open'
});
/***/ })
/******/ });

View File

@ -0,0 +1 @@
<?php return array('dependencies' => array(), 'version' => '7b2c5174a07c417dc3db6f1d9a9c3f78');

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,44 @@
<?php
/**
* Server-side rendering of the `core/pattern` block.
*
* @package WordPress
*/
/**
* Registers the `core/pattern` block on the server.
*
* @return void
*/
function register_block_core_pattern() {
register_block_type_from_metadata(
__DIR__ . '/pattern',
array(
'render_callback' => 'render_block_core_pattern',
)
);
}
/**
* Renders the `core/pattern` block on the server.
*
* @param array $attributes Block attributes.
*
* @return string Returns the output of the pattern.
*/
function render_block_core_pattern( $attributes ) {
if ( empty( $attributes['slug'] ) ) {
return '';
}
$slug = $attributes['slug'];
$registry = WP_Block_Patterns_Registry::get_instance();
if ( ! $registry->is_registered( $slug ) ) {
return '';
}
$pattern = $registry->get_registered( $slug );
return do_blocks( $pattern['content'] );
}
add_action( 'init', 'register_block_core_pattern' );

View File

@ -0,0 +1,17 @@
{
"apiVersion": 2,
"name": "core/pattern",
"title": "Pattern",
"category": "design",
"description": "Show a block pattern.",
"supports": {
"html": false,
"inserter": false
},
"textdomain": "default",
"attributes": {
"slug": {
"type": "string"
}
}
}

View File

@ -0,0 +1,61 @@
<?php
/**
* Server-side rendering of the `core/post-author` block.
*
* @package WordPress
*/
/**
* Renders the `core/post-author` block on the server.
*
* @param array $attributes Block attributes.
* @param string $content Block default content.
* @param WP_Block $block Block instance.
* @return string Returns the rendered author block.
*/
function render_block_core_post_author( $attributes, $content, $block ) {
if ( ! isset( $block->context['postId'] ) ) {
return '';
}
$author_id = get_post_field( 'post_author', $block->context['postId'] );
if ( empty( $author_id ) ) {
return '';
}
$avatar = ! empty( $attributes['avatarSize'] ) ? get_avatar(
$author_id,
$attributes['avatarSize']
) : null;
$byline = ! empty( $attributes['byline'] ) ? $attributes['byline'] : false;
$classes = array_merge(
isset( $attributes['className'] ) ? array( $attributes['className'] ) : array(),
isset( $attributes['itemsJustification'] ) ? array( 'items-justified-' . $attributes['itemsJustification'] ) : array(),
isset( $attributes['textAlign'] ) ? array( 'has-text-align-' . $attributes['textAlign'] ) : array()
);
$wrapper_attributes = get_block_wrapper_attributes( array( 'class' => implode( ' ', $classes ) ) );
return sprintf( '<div %1$s>', $wrapper_attributes ) .
( ! empty( $attributes['showAvatar'] ) ? '<div class="wp-block-post-author__avatar">' . $avatar . '</div>' : '' ) .
'<div class="wp-block-post-author__content">' .
( ! empty( $byline ) ? '<p class="wp-block-post-author__byline">' . $byline . '</p>' : '' ) .
'<p class="wp-block-post-author__name">' . get_the_author_meta( 'display_name', $author_id ) . '</p>' .
( ! empty( $attributes['showBio'] ) ? '<p class="wp-block-post-author__bio">' . get_the_author_meta( 'user_description', $author_id ) . '</p>' : '' ) .
'</div>' .
'</div>';
}
/**
* Registers the `core/post-author` block on the server.
*/
function register_block_core_post_author() {
register_block_type_from_metadata(
__DIR__ . '/post-author',
array(
'render_callback' => 'render_block_core_post_author',
)
);
}
add_action( 'init', 'register_block_core_post_author' );

View File

@ -0,0 +1,53 @@
{
"apiVersion": 2,
"name": "core/post-author",
"title": "Post Author",
"category": "theme",
"description": "Add the author of this post.",
"textdomain": "default",
"attributes": {
"textAlign": {
"type": "string"
},
"avatarSize": {
"type": "number",
"default": 48
},
"showAvatar": {
"type": "boolean",
"default": true
},
"showBio": {
"type": "boolean"
},
"byline": {
"type": "string"
}
},
"usesContext": [ "postType", "postId", "queryId" ],
"supports": {
"html": false,
"spacing": {
"margin": true,
"padding": true
},
"typography": {
"fontSize": true,
"lineHeight": true,
"__experimentalFontStyle": true,
"__experimentalFontWeight": true,
"__experimentalLetterSpacing": true,
"__experimentalTextTransform": true,
"__experimentalDefaultControls": {
"fontSize": true
}
},
"color": {
"gradients": true,
"link": true,
"__experimentalDuotone": ".wp-block-post-author__avatar img"
}
},
"editorStyle": "wp-block-post-author-editor",
"style": "wp-block-post-author"
}

View File

@ -0,0 +1,100 @@
/**
* Colors
*/
/**
* Breakpoints & Media Queries
*/
/**
* SCSS Variables.
*
* Please use variables from this sheet to ensure consistency across the UI.
* Don't add to this sheet unless you're pretty sure the value will be reused in many places.
* For example, don't add rules to this sheet that affect block visuals. It's purely for UI.
*/
/**
* Colors
*/
/**
* Fonts & basic variables.
*/
/**
* Grid System.
* https://make.wordpress.org/design/2019/10/31/proposal-a-consistent-spacing-system-for-wordpress/
*/
/**
* Dimensions.
*/
/**
* Shadows.
*/
/**
* Editor widths.
*/
/**
* Block & Editor UI.
*/
/**
* Block paddings.
*/
/**
* React Native specific.
* These variables do not appear to be used anywhere else.
*/
/**
* Converts a hex value into the rgb equivalent.
*
* @param {string} hex - the hexadecimal value to convert
* @return {string} comma separated rgb values
*/
/**
* Breakpoint mixins
*/
/**
* Long content fade mixin
*
* Creates a fading overlay to signify that the content is longer
* than the space allows.
*/
/**
* Focus styles.
*/
/**
* Applies editor left position to the selector passed as argument
*/
/**
* Styles that are reused verbatim in a few places
*/
/**
* Allows users to opt-out of animations via OS-level preferences.
*/
/**
* Reset default styles for JavaScript UI based pages.
* This is a WP-admin agnostic reset
*/
/**
* Reset the WP Admin page styles for Gutenberg-like pages.
*/
.wp-block-post-author {
display: flex;
flex-wrap: wrap;
}
.wp-block-post-author__byline {
width: 100%;
margin-top: 0;
margin-bottom: 0;
font-size: 0.5em;
}
.wp-block-post-author__avatar {
margin-left: 1em;
}
.wp-block-post-author__bio {
margin-bottom: 0.7em;
font-size: 0.7em;
}
.wp-block-post-author__content {
flex-grow: 1;
flex-basis: 0;
}
.wp-block-post-author__name {
margin: 0;
}

View File

@ -0,0 +1 @@
.wp-block-post-author{display:flex;flex-wrap:wrap}.wp-block-post-author__byline{width:100%;margin-top:0;margin-bottom:0;font-size:.5em}.wp-block-post-author__avatar{margin-left:1em}.wp-block-post-author__bio{margin-bottom:.7em;font-size:.7em}.wp-block-post-author__content{flex-grow:1;flex-basis:0}.wp-block-post-author__name{margin:0}

View File

@ -0,0 +1,100 @@
/**
* Colors
*/
/**
* Breakpoints & Media Queries
*/
/**
* SCSS Variables.
*
* Please use variables from this sheet to ensure consistency across the UI.
* Don't add to this sheet unless you're pretty sure the value will be reused in many places.
* For example, don't add rules to this sheet that affect block visuals. It's purely for UI.
*/
/**
* Colors
*/
/**
* Fonts & basic variables.
*/
/**
* Grid System.
* https://make.wordpress.org/design/2019/10/31/proposal-a-consistent-spacing-system-for-wordpress/
*/
/**
* Dimensions.
*/
/**
* Shadows.
*/
/**
* Editor widths.
*/
/**
* Block & Editor UI.
*/
/**
* Block paddings.
*/
/**
* React Native specific.
* These variables do not appear to be used anywhere else.
*/
/**
* Converts a hex value into the rgb equivalent.
*
* @param {string} hex - the hexadecimal value to convert
* @return {string} comma separated rgb values
*/
/**
* Breakpoint mixins
*/
/**
* Long content fade mixin
*
* Creates a fading overlay to signify that the content is longer
* than the space allows.
*/
/**
* Focus styles.
*/
/**
* Applies editor left position to the selector passed as argument
*/
/**
* Styles that are reused verbatim in a few places
*/
/**
* Allows users to opt-out of animations via OS-level preferences.
*/
/**
* Reset default styles for JavaScript UI based pages.
* This is a WP-admin agnostic reset
*/
/**
* Reset the WP Admin page styles for Gutenberg-like pages.
*/
.wp-block-post-author {
display: flex;
flex-wrap: wrap;
}
.wp-block-post-author__byline {
width: 100%;
margin-top: 0;
margin-bottom: 0;
font-size: 0.5em;
}
.wp-block-post-author__avatar {
margin-right: 1em;
}
.wp-block-post-author__bio {
margin-bottom: 0.7em;
font-size: 0.7em;
}
.wp-block-post-author__content {
flex-grow: 1;
flex-basis: 0;
}
.wp-block-post-author__name {
margin: 0;
}

View File

@ -0,0 +1 @@
.wp-block-post-author{display:flex;flex-wrap:wrap}.wp-block-post-author__byline{width:100%;margin-top:0;margin-bottom:0;font-size:.5em}.wp-block-post-author__avatar{margin-right:1em}.wp-block-post-author__bio{margin-bottom:.7em;font-size:.7em}.wp-block-post-author__content{flex-grow:1;flex-basis:0}.wp-block-post-author__name{margin:0}

View File

@ -0,0 +1,68 @@
<?php
/**
* Server-side rendering of the `core/post-comments` block.
*
* @package WordPress
*/
/**
* Renders the `core/post-comments` block on the server.
*
* @param array $attributes Block attributes.
* @param string $content Block default content.
* @param WP_Block $block Block instance.
* @return string Returns the filtered post comments for the current post wrapped inside "p" tags.
*/
function render_block_core_post_comments( $attributes, $content, $block ) {
global $post;
$post_id = $block->context['postId'];
if ( ! isset( $post_id ) ) {
return '';
}
$comment_args = array(
'post_id' => $post_id,
'count' => true,
);
// Return early if there are no comments and comments are closed.
if ( ! comments_open( $post_id ) && get_comments( $comment_args ) === 0 ) {
return '';
}
$post_before = $post;
$post = get_post( $post_id );
setup_postdata( $post );
ob_start();
// There's a deprecation warning generated by WP Core.
// Ideally this deprecation is removed from Core.
// In the meantime, this removes it from the output.
add_filter( 'deprecated_file_trigger_error', '__return_false' );
comments_template();
remove_filter( 'deprecated_file_trigger_error', '__return_false' );
$post = $post_before;
$classes = '';
if ( isset( $attributes['textAlign'] ) ) {
$classes .= 'has-text-align-' . $attributes['textAlign'];
}
$wrapper_attributes = get_block_wrapper_attributes( array( 'class' => $classes ) );
$output = ob_get_clean();
return sprintf( '<div %1$s>%2$s</div>', $wrapper_attributes, $output );
}
/**
* Registers the `core/post-comments` block on the server.
*/
function register_block_core_post_comments() {
register_block_type_from_metadata(
__DIR__ . '/post-comments',
array(
'render_callback' => 'render_block_core_post_comments',
)
);
}
add_action( 'init', 'register_block_core_post_comments' );

View File

@ -0,0 +1,34 @@
{
"apiVersion": 2,
"name": "core/post-comments",
"title": "Post Comments",
"category": "theme",
"description": "Display a post's comments.",
"textdomain": "default",
"attributes": {
"textAlign": {
"type": "string"
}
},
"usesContext": [ "postId", "postType" ],
"supports": {
"html": false,
"align": [ "wide", "full" ],
"typography": {
"fontSize": true,
"lineHeight": true,
"__experimentalFontStyle": true,
"__experimentalFontWeight": true,
"__experimentalLetterSpacing": true,
"__experimentalTextTransform": true,
"__experimentalDefaultControls": {
"fontSize": true
}
},
"color": {
"gradients": true,
"link": true
}
},
"style": "wp-block-post-comments"
}

View File

@ -0,0 +1,155 @@
/**
* Colors
*/
/**
* Breakpoints & Media Queries
*/
/**
* SCSS Variables.
*
* Please use variables from this sheet to ensure consistency across the UI.
* Don't add to this sheet unless you're pretty sure the value will be reused in many places.
* For example, don't add rules to this sheet that affect block visuals. It's purely for UI.
*/
/**
* Colors
*/
/**
* Fonts & basic variables.
*/
/**
* Grid System.
* https://make.wordpress.org/design/2019/10/31/proposal-a-consistent-spacing-system-for-wordpress/
*/
/**
* Dimensions.
*/
/**
* Shadows.
*/
/**
* Editor widths.
*/
/**
* Block & Editor UI.
*/
/**
* Block paddings.
*/
/**
* React Native specific.
* These variables do not appear to be used anywhere else.
*/
/**
* Converts a hex value into the rgb equivalent.
*
* @param {string} hex - the hexadecimal value to convert
* @return {string} comma separated rgb values
*/
/**
* Breakpoint mixins
*/
/**
* Long content fade mixin
*
* Creates a fading overlay to signify that the content is longer
* than the space allows.
*/
/**
* Focus styles.
*/
/**
* Applies editor left position to the selector passed as argument
*/
/**
* Styles that are reused verbatim in a few places
*/
/**
* Allows users to opt-out of animations via OS-level preferences.
*/
/**
* Reset default styles for JavaScript UI based pages.
* This is a WP-admin agnostic reset
*/
/**
* Reset the WP Admin page styles for Gutenberg-like pages.
*/
.wp-block-post-comments > h3:first-of-type {
margin-top: 0;
}
.wp-block-post-comments .commentlist {
list-style: none;
margin: 0;
padding: 0;
}
.wp-block-post-comments .commentlist .comment {
min-height: 2.25em;
padding-right: 3.25em;
}
.wp-block-post-comments .commentlist .comment p {
font-size: 0.875em;
line-height: 1.8;
margin: 0.36em 0 1.4em;
}
.wp-block-post-comments .commentlist .children {
list-style: none;
margin: 0;
padding: 0;
}
.wp-block-post-comments .comment-author {
line-height: 1.5;
margin-right: -3.25em;
}
.wp-block-post-comments .comment-author .avatar {
border-radius: 1.5em;
display: block;
float: right;
height: 2.5em;
margin-left: 0.75em;
width: 2.5em;
}
.wp-block-post-comments .comment-author cite {
font-style: normal;
}
.wp-block-post-comments .comment-meta {
line-height: 1.5;
margin-right: -3.25em;
}
.wp-block-post-comments .comment-body .commentmetadata {
font-size: 0.75em;
}
.wp-block-post-comments .comment-form-comment label,
.wp-block-post-comments .comment-form-author label,
.wp-block-post-comments .comment-form-email label,
.wp-block-post-comments .comment-form-url label {
display: block;
margin-bottom: 0.25em;
}
.wp-block-post-comments .comment-form-comment textarea {
box-sizing: border-box;
width: 100%;
}
.wp-block-post-comments .comment-form-cookies-consent {
display: flex;
gap: 0.25em;
}
.wp-block-post-comments .comment-form-cookies-consent #wp-comment-cookies-consent {
margin-top: 0.35em;
}
.wp-block-post-comments .reply {
font-size: 0.75em;
margin-bottom: 1.4em;
}
.wp-block-post-comments textarea,
.wp-block-post-comments input:not([type=submit]) {
border: 1px solid #949494;
font-size: 1em;
font-family: inherit;
}
.wp-block-post-comments textarea,
.wp-block-post-comments input:not([type=submit]):not([type=checkbox]) {
padding: calc(0.667em + 2px);
}
.wp-block-post-comments input[type=submit] {
border: none;
}

View File

@ -0,0 +1 @@
.wp-block-post-comments>h3:first-of-type{margin-top:0}.wp-block-post-comments .commentlist{list-style:none;margin:0;padding:0}.wp-block-post-comments .commentlist .comment{min-height:2.25em;padding-right:3.25em}.wp-block-post-comments .commentlist .comment p{font-size:.875em;line-height:1.8;margin:.36em 0 1.4em}.wp-block-post-comments .commentlist .children{list-style:none;margin:0;padding:0}.wp-block-post-comments .comment-author{line-height:1.5;margin-right:-3.25em}.wp-block-post-comments .comment-author .avatar{border-radius:1.5em;display:block;float:right;height:2.5em;margin-left:.75em;width:2.5em}.wp-block-post-comments .comment-author cite{font-style:normal}.wp-block-post-comments .comment-meta{line-height:1.5;margin-right:-3.25em}.wp-block-post-comments .comment-body .commentmetadata{font-size:.75em}.wp-block-post-comments .comment-form-author label,.wp-block-post-comments .comment-form-comment label,.wp-block-post-comments .comment-form-email label,.wp-block-post-comments .comment-form-url label{display:block;margin-bottom:.25em}.wp-block-post-comments .comment-form-comment textarea{box-sizing:border-box;width:100%}.wp-block-post-comments .comment-form-cookies-consent{display:flex;gap:.25em}.wp-block-post-comments .comment-form-cookies-consent #wp-comment-cookies-consent{margin-top:.35em}.wp-block-post-comments .reply{font-size:.75em;margin-bottom:1.4em}.wp-block-post-comments input:not([type=submit]),.wp-block-post-comments textarea{border:1px solid #949494;font-size:1em;font-family:inherit}.wp-block-post-comments input:not([type=submit]):not([type=checkbox]),.wp-block-post-comments textarea{padding:calc(.667em + 2px)}.wp-block-post-comments input[type=submit]{border:none}

View File

@ -0,0 +1,155 @@
/**
* Colors
*/
/**
* Breakpoints & Media Queries
*/
/**
* SCSS Variables.
*
* Please use variables from this sheet to ensure consistency across the UI.
* Don't add to this sheet unless you're pretty sure the value will be reused in many places.
* For example, don't add rules to this sheet that affect block visuals. It's purely for UI.
*/
/**
* Colors
*/
/**
* Fonts & basic variables.
*/
/**
* Grid System.
* https://make.wordpress.org/design/2019/10/31/proposal-a-consistent-spacing-system-for-wordpress/
*/
/**
* Dimensions.
*/
/**
* Shadows.
*/
/**
* Editor widths.
*/
/**
* Block & Editor UI.
*/
/**
* Block paddings.
*/
/**
* React Native specific.
* These variables do not appear to be used anywhere else.
*/
/**
* Converts a hex value into the rgb equivalent.
*
* @param {string} hex - the hexadecimal value to convert
* @return {string} comma separated rgb values
*/
/**
* Breakpoint mixins
*/
/**
* Long content fade mixin
*
* Creates a fading overlay to signify that the content is longer
* than the space allows.
*/
/**
* Focus styles.
*/
/**
* Applies editor left position to the selector passed as argument
*/
/**
* Styles that are reused verbatim in a few places
*/
/**
* Allows users to opt-out of animations via OS-level preferences.
*/
/**
* Reset default styles for JavaScript UI based pages.
* This is a WP-admin agnostic reset
*/
/**
* Reset the WP Admin page styles for Gutenberg-like pages.
*/
.wp-block-post-comments > h3:first-of-type {
margin-top: 0;
}
.wp-block-post-comments .commentlist {
list-style: none;
margin: 0;
padding: 0;
}
.wp-block-post-comments .commentlist .comment {
min-height: 2.25em;
padding-left: 3.25em;
}
.wp-block-post-comments .commentlist .comment p {
font-size: 0.875em;
line-height: 1.8;
margin: 0.36em 0 1.4em;
}
.wp-block-post-comments .commentlist .children {
list-style: none;
margin: 0;
padding: 0;
}
.wp-block-post-comments .comment-author {
line-height: 1.5;
margin-left: -3.25em;
}
.wp-block-post-comments .comment-author .avatar {
border-radius: 1.5em;
display: block;
float: left;
height: 2.5em;
margin-right: 0.75em;
width: 2.5em;
}
.wp-block-post-comments .comment-author cite {
font-style: normal;
}
.wp-block-post-comments .comment-meta {
line-height: 1.5;
margin-left: -3.25em;
}
.wp-block-post-comments .comment-body .commentmetadata {
font-size: 0.75em;
}
.wp-block-post-comments .comment-form-comment label,
.wp-block-post-comments .comment-form-author label,
.wp-block-post-comments .comment-form-email label,
.wp-block-post-comments .comment-form-url label {
display: block;
margin-bottom: 0.25em;
}
.wp-block-post-comments .comment-form-comment textarea {
box-sizing: border-box;
width: 100%;
}
.wp-block-post-comments .comment-form-cookies-consent {
display: flex;
gap: 0.25em;
}
.wp-block-post-comments .comment-form-cookies-consent #wp-comment-cookies-consent {
margin-top: 0.35em;
}
.wp-block-post-comments .reply {
font-size: 0.75em;
margin-bottom: 1.4em;
}
.wp-block-post-comments textarea,
.wp-block-post-comments input:not([type=submit]) {
border: 1px solid #949494;
font-size: 1em;
font-family: inherit;
}
.wp-block-post-comments textarea,
.wp-block-post-comments input:not([type=submit]):not([type=checkbox]) {
padding: calc(0.667em + 2px);
}
.wp-block-post-comments input[type=submit] {
border: none;
}

View File

@ -0,0 +1 @@
.wp-block-post-comments>h3:first-of-type{margin-top:0}.wp-block-post-comments .commentlist{list-style:none;margin:0;padding:0}.wp-block-post-comments .commentlist .comment{min-height:2.25em;padding-left:3.25em}.wp-block-post-comments .commentlist .comment p{font-size:.875em;line-height:1.8;margin:.36em 0 1.4em}.wp-block-post-comments .commentlist .children{list-style:none;margin:0;padding:0}.wp-block-post-comments .comment-author{line-height:1.5;margin-left:-3.25em}.wp-block-post-comments .comment-author .avatar{border-radius:1.5em;display:block;float:left;height:2.5em;margin-right:.75em;width:2.5em}.wp-block-post-comments .comment-author cite{font-style:normal}.wp-block-post-comments .comment-meta{line-height:1.5;margin-left:-3.25em}.wp-block-post-comments .comment-body .commentmetadata{font-size:.75em}.wp-block-post-comments .comment-form-author label,.wp-block-post-comments .comment-form-comment label,.wp-block-post-comments .comment-form-email label,.wp-block-post-comments .comment-form-url label{display:block;margin-bottom:.25em}.wp-block-post-comments .comment-form-comment textarea{box-sizing:border-box;width:100%}.wp-block-post-comments .comment-form-cookies-consent{display:flex;gap:.25em}.wp-block-post-comments .comment-form-cookies-consent #wp-comment-cookies-consent{margin-top:.35em}.wp-block-post-comments .reply{font-size:.75em;margin-bottom:1.4em}.wp-block-post-comments input:not([type=submit]),.wp-block-post-comments textarea{border:1px solid #949494;font-size:1em;font-family:inherit}.wp-block-post-comments input:not([type=submit]):not([type=checkbox]),.wp-block-post-comments textarea{padding:calc(.667em + 2px)}.wp-block-post-comments input[type=submit]{border:none}

View File

@ -0,0 +1,96 @@
<?php
/**
* Server-side rendering of the `core/post-navigation-link` block.
*
* @package WordPress
*/
/**
* Renders the `core/post-navigation-link` block on the server.
*
* @param array $attributes Block attributes.
* @param string $content Block default content.
*
* @return string Returns the next or previous post link that is adjacent to the current post.
*/
function render_block_core_post_navigation_link( $attributes, $content ) {
if ( ! is_singular() ) {
return '';
}
// Get the nagigation type to show the proper link. Available options are `next|previous`.
$navigation_type = isset( $attributes['type'] ) ? $attributes['type'] : 'next';
// Allow only `next` and `previous` in `$navigation_type`.
if ( ! in_array( $navigation_type, array( 'next', 'previous' ), true ) ) {
return '';
}
$classes = "post-navigation-link-$navigation_type";
if ( isset( $attributes['textAlign'] ) ) {
$classes .= " has-text-align-{$attributes['textAlign']}";
}
$wrapper_attributes = get_block_wrapper_attributes( array( 'class' => $classes ) );
// Set default values.
$format = '%link';
$link = 'next' === $navigation_type ? _x( 'Next', 'label for next post link' ) : _x( 'Previous', 'label for previous post link' );
$label = '';
// If a custom label is provided, make this a link.
// `$label` is used to prepend the provided label, if we want to show the page title as well.
if ( isset( $attributes['label'] ) && ! empty( $attributes['label'] ) ) {
$label = "{$attributes['label']}";
$link = $label;
}
// If we want to also show the page title, make the page title a link and prepend the label.
if ( isset( $attributes['showTitle'] ) && $attributes['showTitle'] ) {
/*
* If the label link option is not enabled but there is a custom label,
* display the custom label as text before the linked title.
*/
if ( ! $attributes['linkLabel'] ) {
if ( $label ) {
$format = '<span class="post-navigation-link__label">' . $label . '</span> %link';
}
$link = '%title';
} elseif ( isset( $attributes['linkLabel'] ) && $attributes['linkLabel'] ) {
// If the label link option is enabled and there is a custom label, display it before the title.
if ( $label ) {
$link = '<span class="post-navigation-link__label">' . $label . '</span> <span class="post-navigation-link__title">%title</title>';
} else {
/*
* If the label link option is enabled and there is no custom label,
* add a colon between the label and the post title.
*/
$label = 'next' === $navigation_type ? _x( 'Next:', 'label before the title of the next post' ) : _x( 'Previous:', 'label before the title of the previous post' );
$link = sprintf(
'<span class="post-navigation-link__label">%1$s</span> <span class="post-navigation-link__title">%2$s</span>',
$label,
'%title'
);
}
}
}
// The dynamic portion of the function name, `$navigation_type`,
// refers to the type of adjacency, 'next' or 'previous'.
$get_link_function = "get_{$navigation_type}_post_link";
$content = $get_link_function( $format, $link );
return sprintf(
'<div %1$s>%2$s</div>',
$wrapper_attributes,
$content
);
}
/**
* Registers the `core/post-navigation-link` block on the server.
*/
function register_block_core_post_navigation_link() {
register_block_type_from_metadata(
__DIR__ . '/post-navigation-link',
array(
'render_callback' => 'render_block_core_post_navigation_link',
)
);
}
add_action( 'init', 'register_block_core_post_navigation_link' );

View File

@ -0,0 +1,43 @@
{
"apiVersion": 2,
"name": "core/post-navigation-link",
"title": "Post Navigation Link",
"category": "theme",
"description": "Displays the next or previous post link that is adjacent to the current post.",
"textdomain": "default",
"attributes": {
"textAlign": {
"type": "string"
},
"type": {
"type": "string",
"default": "next"
},
"label": {
"type": "string"
},
"showTitle": {
"type": "boolean",
"default": false
},
"linkLabel": {
"type": "boolean",
"default": false
}
},
"supports": {
"reusable": false,
"html": false,
"typography": {
"fontSize": true,
"lineHeight": true,
"__experimentalFontStyle": true,
"__experimentalFontWeight": true,
"__experimentalLetterSpacing": true,
"__experimentalTextTransform": true,
"__experimentalDefaultControls": {
"fontSize": true
}
}
}
}

View File

@ -0,0 +1,45 @@
<?php
/**
* Server-side rendering of the `core/term-description` block.
*
* @package WordPress
*/
/**
* Renders the `core/term-description` block on the server.
*
* @param array $attributes Block attributes.
*
* @return string Returns the description of the current taxonomy term, if available
*/
function render_block_core_term_description( $attributes ) {
$term_description = '';
if ( is_category() || is_tag() || is_tax() ) {
$term_description = term_description();
}
if ( empty( $term_description ) ) {
return '';
}
$extra_attributes = ( isset( $attributes['textAlign'] ) )
? array( 'class' => 'has-text-align-' . $attributes['textAlign'] )
: array();
$wrapper_attributes = get_block_wrapper_attributes( $extra_attributes );
return '<div ' . $wrapper_attributes . '>' . $term_description . '</div>';
}
/**
* Registers the `core/term-description` block on the server.
*/
function register_block_core_term_description() {
register_block_type_from_metadata(
__DIR__ . '/term-description',
array(
'render_callback' => 'render_block_core_term_description',
)
);
}
add_action( 'init', 'register_block_core_term_description' );

View File

@ -0,0 +1,28 @@
{
"apiVersion": 2,
"name": "core/term-description",
"title": "Term Description",
"category": "theme",
"description": "Display the description of categories, tags and custom taxonomies when viewing an archive.",
"textdomain": "default",
"attributes": {
"textAlign": {
"type": "string"
}
},
"supports": {
"align": [ "wide", "full" ],
"html": false,
"color": {
"link": true
},
"typography": {
"fontSize": true,
"lineHeight": true,
"__experimentalDefaultControls": {
"fontSize": true
}
}
},
"editorStyle": "wp-block-term-description-editor"
}

View File

@ -0,0 +1,78 @@
<?php
/**
* Server-side rendering of the `core/widget-group` block.
*
* @package WordPress
*/
/**
* Renders the 'core/widget-group' block.
*
* @param array $attributes The block attributes.
* @param string $content The block content.
* @param WP_Block $block The block.
*
* @return string Rendered block.
*/
function render_block_core_widget_group( $attributes, $content, $block ) {
global $wp_registered_sidebars, $_sidebar_being_rendered;
if ( isset( $wp_registered_sidebars[ $_sidebar_being_rendered ] ) ) {
$before_title = $wp_registered_sidebars[ $_sidebar_being_rendered ]['before_title'];
$after_title = $wp_registered_sidebars[ $_sidebar_being_rendered ]['after_title'];
} else {
$before_title = '<h2 class="widget-title">';
$after_title = '</h2>';
}
$html = '';
if ( ! empty( $attributes['title'] ) ) {
$html .= $before_title . $attributes['title'] . $after_title;
}
$html .= '<div class="wp-widget-group__inner-blocks">';
foreach ( $block->inner_blocks as $inner_block ) {
$html .= $inner_block->render();
}
$html .= '</div>';
return $html;
}
/**
* Registers the 'core/widget-group' block.
*/
function register_block_core_widget_group() {
register_block_type_from_metadata(
__DIR__ . '/widget-group',
array(
'render_callback' => 'render_block_core_widget_group',
)
);
}
add_action( 'init', 'register_block_core_widget_group' );
/**
* Make a note of the sidebar being rendered before WordPress starts rendering
* it. This lets us get to the current sidebar in
* render_block_core_widget_group().
*
* @param int|string $index Index, name, or ID of the dynamic sidebar.
*/
function note_sidebar_being_rendered( $index ) {
global $_sidebar_being_rendered;
$_sidebar_being_rendered = $index;
}
add_action( 'dynamic_sidebar_before', 'note_sidebar_being_rendered' );
/**
* Clear whatever we set in note_sidebar_being_rendered() after WordPress
* finishes rendering a sidebar.
*/
function discard_sidebar_being_rendered() {
global $_sidebar_being_rendered;
unset( $_sidebar_being_rendered );
}
add_action( 'dynamic_sidebar_after', 'discard_sidebar_being_rendered' );

View File

@ -0,0 +1,18 @@
{
"apiVersion": 2,
"name": "core/widget-group",
"category": "widgets",
"attributes": {
"title": {
"type": "string"
}
},
"supports": {
"html": false,
"inserter": true,
"customClassName": true,
"reusable": false
},
"editorStyle": "wp-block-widget-group-editor",
"style": "wp-block-widget-group"
}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

1523
wp-includes/css/dist/edit-site/style.css vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -581,6 +581,7 @@ add_action( 'wp_footer', 'wp_maybe_inline_styles', 1 ); // Run for late-loaded s
add_action( 'admin_footer-post.php', 'wp_add_iframed_editor_assets_html' );
add_action( 'admin_footer-post-new.php', 'wp_add_iframed_editor_assets_html' );
add_action( 'admin_footer-widgets.php', 'wp_add_iframed_editor_assets_html' );
// Taxonomy.
add_action( 'init', 'create_initial_taxonomies', 0 ); // Highest priority.

8982
wp-includes/js/dist/edit-site.js vendored Normal file

File diff suppressed because it is too large Load Diff

7
wp-includes/js/dist/edit-site.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -2287,6 +2287,8 @@ function safecss_filter_attr( $css, $deprecated = '' ) {
'border-right-width',
'border-bottom',
'border-bottom-color',
'border-bottom-left-radius',
'border-bottom-right-radius',
'border-bottom-style',
'border-bottom-width',
'border-bottom-right-radius',
@ -2297,6 +2299,8 @@ function safecss_filter_attr( $css, $deprecated = '' ) {
'border-left-width',
'border-top',
'border-top-color',
'border-top-left-radius',
'border-top-right-radius',
'border-top-style',
'border-top-width',
'border-top-left-radius',

View File

@ -450,6 +450,51 @@ function create_initial_post_types() {
)
);
register_post_type(
'wp_navigation',
array(
'labels' => array(
'name' => __( 'Navigation Menus', 'gutenberg' ),
'singular_name' => __( 'Navigation Menu', 'gutenberg' ),
'menu_name' => _x( 'Navigation Menus', 'Admin Menu text', 'gutenberg' ),
'add_new' => _x( 'Add New', 'Navigation Menu', 'gutenberg' ),
'add_new_item' => __( 'Add New Navigation Menu', 'gutenberg' ),
'new_item' => __( 'New Navigation Menu', 'gutenberg' ),
'edit_item' => __( 'Edit Navigation Menu', 'gutenberg' ),
'view_item' => __( 'View Navigation Menu', 'gutenberg' ),
'all_items' => __( 'All Navigation Menus', 'gutenberg' ),
'search_items' => __( 'Search Navigation Menus', 'gutenberg' ),
'parent_item_colon' => __( 'Parent Navigation Menu:', 'gutenberg' ),
'not_found' => __( 'No Navigation Menu found.', 'gutenberg' ),
'not_found_in_trash' => __( 'No Navigation Menu found in Trash.', 'gutenberg' ),
'archives' => __( 'Navigation Menu archives', 'gutenberg' ),
'insert_into_item' => __( 'Insert into Navigation Menu', 'gutenberg' ),
'uploaded_to_this_item' => __( 'Uploaded to this Navigation Menu', 'gutenberg' ),
// Some of these are a bit weird, what are they for?
'filter_items_list' => __( 'Filter Navigation Menu list', 'gutenberg' ),
'items_list_navigation' => __( 'Navigation Menus list navigation', 'gutenberg' ),
'items_list' => __( 'Navigation Menus list', 'gutenberg' ),
),
'description' => __( 'Navigation menus.', 'gutenberg' ),
'public' => false,
'_builtin' => true, /* internal use only. don't use this when registering your own post type. */
'has_archive' => false,
'show_ui' => false,
'show_in_menu' => 'themes.php',
'show_in_admin_bar' => false,
'show_in_rest' => true,
'rewrite' => false,
'map_meta_cap' => true,
'rest_base' => 'navigation',
'rest_controller_class' => 'WP_REST_Posts_Controller',
'supports' => array(
'title',
'editor',
'revisions',
),
)
);
register_post_status(
'publish',
array(

View File

@ -311,6 +311,12 @@ class WP_REST_Users_Controller extends WP_REST_Controller {
$prepared_args['has_published_posts'] = get_post_types( array( 'show_in_rest' => true ), 'names' );
}
if ( ! empty( $request['has_published_posts'] ) ) {
$prepared_args['has_published_posts'] = ( true === $request['has_published_posts'] )
? get_post_types( array( 'show_in_rest' => true ), 'names' )
: (array) $request['has_published_posts'];
}
if ( ! empty( $prepared_args['search'] ) ) {
$prepared_args['search'] = '*' . $prepared_args['search'] . '*';
}
@ -1580,6 +1586,15 @@ class WP_REST_Users_Controller extends WP_REST_Controller {
),
);
$query_params['has_published_posts'] = array(
'description' => __( 'Limit result set to users who have published posts.' ),
'type' => array( 'boolean', 'array' ),
'items' => array(
'type' => 'string',
'enum' => get_post_types( array( 'show_in_rest' => true ), 'names' ),
),
);
/**
* Filters REST API collection parameters for the users controller.
*

View File

@ -99,6 +99,29 @@ class WP_REST_Widget_Types_Controller extends WP_REST_Controller {
),
)
);
register_rest_route(
$this->namespace,
'/' . $this->rest_base . '/(?P<id>[a-zA-Z0-9_-]+)/render',
array(
array(
'methods' => WP_REST_Server::CREATABLE,
'permission_callback' => array( $this, 'get_item_permissions_check' ),
'callback' => array( $this, 'render' ),
'args' => array(
'id' => array(
'description' => __( 'The widget type id.', 'default' ),
'type' => 'string',
'required' => true,
),
'instance' => array(
'description' => __( 'Current instance settings of the widget.', 'default' ),
'type' => 'object',
),
),
),
)
);
}
/**
@ -559,6 +582,78 @@ class WP_REST_Widget_Types_Controller extends WP_REST_Controller {
return ob_get_clean();
}
/**
* Renders a single Legacy Widget and wraps it in a JSON-encodable array.
*
* @since 5.9.0
*
* @param WP_REST_Request $request Full details about the request.
*
* @return array An array with rendered Legacy Widget HTML.
*/
public function render( $request ) {
return array(
'preview' => $this->render_legacy_widget_preview_iframe(
$request['id'],
isset( $request['instance'] ) ? $request['instance'] : null
),
);
}
/**
* Renders a page containing a preview of the requested Legacy Widget block.
*
* @since 5.9.0
*
* @param string $id_base The id base of the requested widget.
* @param array $instance The widget instance attributes.
*
* @return string Rendered Legacy Widget block preview.
*/
private function render_legacy_widget_preview_iframe( $id_base, $instance ) {
if ( ! defined( 'IFRAME_REQUEST' ) ) {
define( 'IFRAME_REQUEST', true );
}
ob_start();
?>
<!doctype html>
<html <?php language_attributes(); ?>>
<head>
<meta charset="<?php bloginfo( 'charset' ); ?>" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="profile" href="https://gmpg.org/xfn/11" />
<?php wp_head(); ?>
<style>
/* Reset theme styles */
html, body, #page, #content {
padding: 0 !important;
margin: 0 !important;
}
</style>
</head>
<body <?php body_class(); ?>>
<div id="page" class="site">
<div id="content" class="site-content">
<?php
$registry = WP_Block_Type_Registry::get_instance();
$block = $registry->get_registered( 'core/legacy-widget' );
echo $block->render(
array(
'idBase' => $id_base,
'instance' => $instance,
)
);
?>
</div><!-- #content -->
</div><!-- #page -->
<?php wp_footer(); ?>
</body>
</html>
<?php
return ob_get_clean();
}
/**
* Retrieves the query params for collections.
*

View File

@ -103,8 +103,8 @@ function wp_default_packages_vendor( $scripts ) {
);
$vendor_scripts_versions = array(
'react' => '16.13.1',
'react-dom' => '16.13.1',
'react' => '17.0.1',
'react-dom' => '17.0.1',
'regenerator-runtime' => '0.13.7',
'moment' => '2.29.1',
'lodash' => '4.17.19',
@ -1598,6 +1598,11 @@ function wp_default_styles( $styles ) {
'wp-block-library',
'wp-reusable-blocks',
),
'edit-site' => array(
'wp-components',
'wp-block-editor',
'wp-edit-blocks',
),
);
foreach ( $package_styles as $package => $dependencies ) {
@ -1655,6 +1660,7 @@ function wp_default_styles( $styles ) {
'wp-components',
'wp-customize-widgets',
'wp-edit-post',
'wp-edit-site',
'wp-edit-widgets',
'wp-editor',
'wp-format-library',
@ -2265,7 +2271,19 @@ function wp_common_block_scripts_and_styles() {
wp_enqueue_style( 'wp-block-library' );
if ( current_theme_supports( 'wp-block-styles' ) ) {
wp_enqueue_style( 'wp-block-library-theme' );
if ( wp_should_load_separate_core_block_assets() ) {
$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? 'css' : 'min.css';
$files = glob( __DIR__ . "/blocks/**/theme.$suffix" );
foreach ( $files as $path ) {
$block_name = basename( dirname( $path ) );
if ( is_rtl() && file_exists( __DIR__ . "/blocks/$block_name/theme-rtl.$suffix" ) ) {
$path = __DIR__ . "/blocks/$block_name/theme-rtl.$suffix";
}
wp_add_inline_style( "wp-block-{$block_name}", file_get_contents( $path ) );
}
} else {
wp_enqueue_style( 'wp-block-library-theme' );
}
}
/**
@ -2773,6 +2791,8 @@ function _wp_normalize_relative_css_links( $css, $stylesheet_url ) {
* @since 5.8.0
*/
function wp_add_iframed_editor_assets_html() {
global $pagenow;
if ( ! wp_should_load_block_editor_scripts_and_styles() ) {
return;
}
@ -2785,6 +2805,11 @@ function wp_add_iframed_editor_assets_html() {
'wp-edit-blocks',
);
if ( 'widgets.php' === $pagenow || 'customize.php' === $pagenow ) {
$style_handles[] = 'wp-widgets';
$style_handles[] = 'wp-edit-widgets';
}
$block_registry = WP_Block_Type_Registry::get_instance();
foreach ( $block_registry->get_all_registered() as $block_type ) {
@ -2806,7 +2831,8 @@ function wp_add_iframed_editor_assets_html() {
ob_start();
wp_styles()->done = array();
// We do not need reset styles for the iframed editor.
wp_styles()->done = array( 'wp-reset-editor-styles' );
wp_styles()->do_items( $style_handles );
wp_styles()->done = $done;

View File

@ -10,8 +10,7 @@
* This needs to run before <head> so that blocks can add scripts and styles in wp_head().
*/
$template_html = get_the_block_template_html();
?>
<!DOCTYPE html>
?><!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>
<meta charset="<?php bloginfo( 'charset' ); ?>" />

View File

@ -4075,3 +4075,14 @@ function create_initial_theme_features() {
)
);
}
/**
* Returns whether the current theme is a block-based theme or not.
*
* @since 5.9.0
*
* @return boolean Whether the current theme is a block-based theme or not.
*/
function wp_is_block_template_theme() {
return is_readable( get_theme_file_path( '/block-templates/index.html' ) );
}

View File

@ -16,7 +16,7 @@
*
* @global string $wp_version
*/
$wp_version = '5.9-alpha-52068';
$wp_version = '5.9-alpha-52069';
/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.

View File

@ -317,6 +317,7 @@ require ABSPATH . WPINC . '/block-supports/align.php';
require ABSPATH . WPINC . '/block-supports/border.php';
require ABSPATH . WPINC . '/block-supports/colors.php';
require ABSPATH . WPINC . '/block-supports/custom-classname.php';
require ABSPATH . WPINC . '/block-supports/dimensions.php';
require ABSPATH . WPINC . '/block-supports/duotone.php';
require ABSPATH . WPINC . '/block-supports/elements.php';
require ABSPATH . WPINC . '/block-supports/generated-classname.php';