From afa455373957e555bbe038add9336d150e9535e2 Mon Sep 17 00:00:00 2001 From: Kevin Zoschke Date: Tue, 6 Jun 2023 13:49:52 -0400 Subject: [PATCH 1/7] [not verified] Extensions: build individual blocks --- .../jetpack/class.jetpack-gutenberg.php | 41 ++++++++++- .../tools/webpack.config.extensions.js | 71 +++---------------- 2 files changed, 50 insertions(+), 62 deletions(-) diff --git a/projects/plugins/jetpack/class.jetpack-gutenberg.php b/projects/plugins/jetpack/class.jetpack-gutenberg.php index 7c9b391fb903..7dac5b2de3e5 100644 --- a/projects/plugins/jetpack/class.jetpack-gutenberg.php +++ b/projects/plugins/jetpack/class.jetpack-gutenberg.php @@ -620,7 +620,7 @@ public static function enqueue_block_editor_assets() { Assets::register_script( 'jetpack-blocks-editor', - "{$blocks_dir}editor{$blocks_env}.js", + "{$blocks_dir}editor.js", JETPACK__PLUGIN_FILE, array( 'textdomain' => 'jetpack' ) ); @@ -641,6 +641,35 @@ public static function enqueue_block_editor_assets() { ) ); + $dir = dirname( JETPACK__PLUGIN_FILE ); + $blocks_json = file_get_contents( $dir . '/' . $blocks_dir . 'index.json' ); + $index = $blocks_env ? $blocks_env : 'production'; + $block_map = json_decode( $blocks_json, false ); + $blocks = $block_map->$index; + + foreach ( $blocks as $block ) { + $handle = "jetpack-$block-editor"; + + if ( file_exists( $dir . '/' . "{$blocks_dir}${block}/editor.js" ) ) { + Assets::register_script( + $handle, + "{$blocks_dir}${block}/editor.js", + JETPACK__PLUGIN_FILE, + array( 'textdomain' => 'jetpack' ) + ); + + Assets::enqueue_script( $handle ); + + wp_localize_script( + $handle, + 'Jetpack_Block_Assets_Base_Url', + array( + 'url' => plugins_url( $blocks_dir . '/', JETPACK__PLUGIN_FILE ), + ) + ); + } + } + if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) { $user = wp_get_current_user(); $user_data = array( @@ -740,6 +769,16 @@ public static function enqueue_block_editor_assets() { $initial_state ); + foreach ( $blocks as $block ) { + $handle = "jetpack-$block-editor"; + + wp_localize_script( + $handle, + 'Jetpack_Editor_Initial_State', + $initial_state + ); + } + // Adds Connection package initial state. wp_add_inline_script( 'jetpack-blocks-editor', Connection_Initial_State::render(), 'before' ); } diff --git a/projects/plugins/jetpack/tools/webpack.config.extensions.js b/projects/plugins/jetpack/tools/webpack.config.extensions.js index 127621bbd07b..db956d3e5a31 100644 --- a/projects/plugins/jetpack/tools/webpack.config.extensions.js +++ b/projects/plugins/jetpack/tools/webpack.config.extensions.js @@ -17,29 +17,11 @@ const StaticSiteGeneratorPlugin = require( './static-site-generator-webpack-plug */ const editorSetup = path.join( __dirname, '../extensions', 'editor' ); const viewSetup = path.join( __dirname, '../extensions', 'view' ); -const blockEditorDirectories = [ 'plugins', 'blocks' ]; const noop = function () {}; -/** - * Filters block editor scripts - * - * @param {string} type - script type - * @param {string} inputDir - input directory - * @param {Array} presetBlocks - preset blocks - * @returns {Array} list of block scripts - */ -function presetProductionExtensions( type, inputDir, presetBlocks ) { - return presetBlocks - .flatMap( block => - blockEditorDirectories.map( dir => path.join( inputDir, dir, block, `${ type }.js` ) ) - ) - .filter( fs.existsSync ); -} - const presetPath = path.join( __dirname, '../extensions', 'index.json' ); const presetIndex = require( presetPath ); const presetProductionBlocks = presetIndex.production || []; -const presetNoPostEditorBlocks = presetIndex[ 'no-post-editor' ] || []; const presetExperimentalBlocks = [ ...presetProductionBlocks, @@ -48,6 +30,14 @@ const presetExperimentalBlocks = [ // Beta Blocks include all blocks: beta, experimental, and production blocks. const presetBetaBlocks = [ ...presetExperimentalBlocks, ...( presetIndex.beta || [] ) ]; +const editorBlocksScripts = presetBetaBlocks.reduce( ( editorBlocks, block ) => { + const editorScriptPath = path.join( __dirname, '../extensions/blocks', block, 'editor.js' ); + if ( fs.existsSync( editorScriptPath ) ) { + editorBlocks[ block + '/editor' ] = [ editorScriptPath ]; + } + return editorBlocks; +}, {} ); + // Helps split up each block into its own folder view script const viewBlocksScripts = presetBetaBlocks.reduce( ( viewBlocks, block ) => { const viewScriptPath = path.join( __dirname, '../extensions/blocks', block, 'view.js' ); @@ -57,45 +47,6 @@ const viewBlocksScripts = presetBetaBlocks.reduce( ( viewBlocks, block ) => { return viewBlocks; }, {} ); -// Combines all the different production blocks into one editor.js script -const editorScript = [ - editorSetup, - ...presetProductionExtensions( - 'editor', - path.join( __dirname, '../extensions' ), - presetProductionBlocks - ), -]; - -// Combines all the different Experimental blocks into one editor.js script -const editorExperimentalScript = [ - editorSetup, - ...presetProductionExtensions( - 'editor', - path.join( __dirname, '../extensions' ), - presetExperimentalBlocks - ), -]; - -// Combines all the different blocks into one editor-beta.js script -const editorBetaScript = [ - editorSetup, - ...presetProductionExtensions( - 'editor', - path.join( __dirname, '../extensions' ), - presetBetaBlocks - ), -]; - -const editorNoPostEditorScript = [ - editorSetup, - ...presetProductionExtensions( - 'editor', - path.join( __dirname, '../extensions' ), - presetNoPostEditorBlocks - ), -]; - const sharedWebpackConfig = { mode: jetpackWebpackConfig.mode, devtool: jetpackWebpackConfig.devtool, @@ -176,10 +127,8 @@ module.exports = [ { ...sharedWebpackConfig, entry: { - editor: editorScript, - 'editor-experimental': editorExperimentalScript, - 'editor-beta': editorBetaScript, - 'editor-no-post-editor': editorNoPostEditorScript, + editor: editorSetup, + ...editorBlocksScripts, ...viewBlocksScripts, }, plugins: [ From 86c6d53a4ffba1633f26eb84b184becdc9622a71 Mon Sep 17 00:00:00 2001 From: Kevin Zoschke Date: Fri, 9 Jun 2023 08:57:59 -0400 Subject: [PATCH 2/7] [not verified] Set single build blocks in config --- pnpm-lock.yaml | 14 ++ .../jetpack/class.jetpack-gutenberg.php | 46 +--- .../blocks/business-hours-single/block.json | 29 +++ .../business-hours-single.php | 174 +++++++++++++++ .../components/day-edit.js | 198 ++++++++++++++++++ .../components/day-preview.js | 54 +++++ .../blocks/business-hours-single/edit.js | 91 ++++++++ .../blocks/business-hours-single/editor.js | 5 + .../blocks/business-hours-single/editor.scss | 170 +++++++++++++++ .../blocks/business-hours-single/index.js | 87 ++++++++ .../blocks/business-hours-single/style.scss | 26 +++ .../plugins/jetpack/extensions/index.json | 3 +- projects/plugins/jetpack/package.json | 1 + .../tools/webpack.config.extensions.js | 143 ++++++++++++- 14 files changed, 995 insertions(+), 46 deletions(-) create mode 100644 projects/plugins/jetpack/extensions/blocks/business-hours-single/block.json create mode 100644 projects/plugins/jetpack/extensions/blocks/business-hours-single/business-hours-single.php create mode 100644 projects/plugins/jetpack/extensions/blocks/business-hours-single/components/day-edit.js create mode 100644 projects/plugins/jetpack/extensions/blocks/business-hours-single/components/day-preview.js create mode 100644 projects/plugins/jetpack/extensions/blocks/business-hours-single/edit.js create mode 100644 projects/plugins/jetpack/extensions/blocks/business-hours-single/editor.js create mode 100644 projects/plugins/jetpack/extensions/blocks/business-hours-single/editor.scss create mode 100644 projects/plugins/jetpack/extensions/blocks/business-hours-single/index.js create mode 100644 projects/plugins/jetpack/extensions/blocks/business-hours-single/style.scss diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a846c6055825..f0572c50ed69 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2828,6 +2828,9 @@ importers: events: specifier: 3.3.0 version: 3.3.0 + file-loader: + specifier: 6.2.0 + version: 6.2.0(webpack@5.76.0) filesize: specifier: 8.0.6 version: 8.0.6 @@ -15413,6 +15416,17 @@ packages: flat-cache: 3.0.4 dev: true + /file-loader@6.2.0(webpack@5.76.0): + resolution: {integrity: sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==} + engines: {node: '>= 10.13.0'} + peerDependencies: + webpack: ^4.0.0 || ^5.0.0 + dependencies: + loader-utils: 2.0.4 + schema-utils: 3.1.2 + webpack: 5.76.0(webpack-cli@4.9.1) + dev: false + /file-system-cache@2.1.1: resolution: {integrity: sha512-vgZ1uDsK29DM4pptUOv47zdJO2tYM5M/ERyAE9Jk0QBN6e64Md+a+xJSOp68dCCDH4niFMVD8nC8n8A5ic0bmg==} dependencies: diff --git a/projects/plugins/jetpack/class.jetpack-gutenberg.php b/projects/plugins/jetpack/class.jetpack-gutenberg.php index 7dac5b2de3e5..4bdae9a319e6 100644 --- a/projects/plugins/jetpack/class.jetpack-gutenberg.php +++ b/projects/plugins/jetpack/class.jetpack-gutenberg.php @@ -620,7 +620,7 @@ public static function enqueue_block_editor_assets() { Assets::register_script( 'jetpack-blocks-editor', - "{$blocks_dir}editor.js", + "{$blocks_dir}editor{$blocks_env}.js", JETPACK__PLUGIN_FILE, array( 'textdomain' => 'jetpack' ) ); @@ -641,35 +641,6 @@ public static function enqueue_block_editor_assets() { ) ); - $dir = dirname( JETPACK__PLUGIN_FILE ); - $blocks_json = file_get_contents( $dir . '/' . $blocks_dir . 'index.json' ); - $index = $blocks_env ? $blocks_env : 'production'; - $block_map = json_decode( $blocks_json, false ); - $blocks = $block_map->$index; - - foreach ( $blocks as $block ) { - $handle = "jetpack-$block-editor"; - - if ( file_exists( $dir . '/' . "{$blocks_dir}${block}/editor.js" ) ) { - Assets::register_script( - $handle, - "{$blocks_dir}${block}/editor.js", - JETPACK__PLUGIN_FILE, - array( 'textdomain' => 'jetpack' ) - ); - - Assets::enqueue_script( $handle ); - - wp_localize_script( - $handle, - 'Jetpack_Block_Assets_Base_Url', - array( - 'url' => plugins_url( $blocks_dir . '/', JETPACK__PLUGIN_FILE ), - ) - ); - } - } - if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) { $user = wp_get_current_user(); $user_data = array( @@ -769,16 +740,6 @@ public static function enqueue_block_editor_assets() { $initial_state ); - foreach ( $blocks as $block ) { - $handle = "jetpack-$block-editor"; - - wp_localize_script( - $handle, - 'Jetpack_Editor_Initial_State', - $initial_state - ); - } - // Adds Connection package initial state. wp_add_inline_script( 'jetpack-blocks-editor', Connection_Initial_State::render(), 'before' ); } @@ -1056,6 +1017,11 @@ public static function get_extensions_preset_for_variation( $preset_extensions_m $preset_extensions = array_unique( array_merge( $preset_extensions, $production_extensions ) ); } + $single_extensions = isset( $preset_extensions_manifest->single ) + ? (array) $preset_extensions_manifest->single + : array(); + $preset_extensions = array_unique( array_merge( $preset_extensions, $single_extensions ) ); + return $preset_extensions; } diff --git a/projects/plugins/jetpack/extensions/blocks/business-hours-single/block.json b/projects/plugins/jetpack/extensions/blocks/business-hours-single/block.json new file mode 100644 index 000000000000..69afd76ac58f --- /dev/null +++ b/projects/plugins/jetpack/extensions/blocks/business-hours-single/block.json @@ -0,0 +1,29 @@ +{ + "$schema": "https://schemas.wp.org/trunk/block.json", + "apiVersion": 3, + "name": "jetpack/business-hours-single", + "title": "Business Hours Single", + "description": "Display opening hours for your business.", + "keywords": [ "opening hours", "closing time", "schedule", "working day" ], + "version": "1.0.0", + "textdomain": "jetpack", + "category": "grow", + "supports": { + "html": true, + "color": { + "gradients": true + }, + "spacing": { + "margin": true, + "padding": true + }, + "typography": { + "fontSize": true, + "lineHeight": true + }, + "align": [ "wide", "full" ] + }, + "editorScript": "file:./editor.js", + "editorStyle": "file:./_editor.css", + "style": "file:./_style.css" +} diff --git a/projects/plugins/jetpack/extensions/blocks/business-hours-single/business-hours-single.php b/projects/plugins/jetpack/extensions/blocks/business-hours-single/business-hours-single.php new file mode 100644 index 000000000000..ab890cf43bc6 --- /dev/null +++ b/projects/plugins/jetpack/extensions/blocks/business-hours-single/business-hours-single.php @@ -0,0 +1,174 @@ + __NAMESPACE__ . '\render', + ) + ); +} +add_action( 'init', __NAMESPACE__ . '\register_block' ); + +/** + * Get's default days / hours to render a business hour block with no data provided. + * + * @return array + */ +function get_default_days() { + return array( + array( + 'name' => 'Sun', + 'hours' => array(), + ), + array( + 'name' => 'Mon', + 'hours' => array( + array( + 'opening' => '09:00', + 'closing' => '17:00', + ), + ), + ), + array( + 'name' => 'Tue', + 'hours' => array( + array( + 'opening' => '09:00', + 'closing' => '17:00', + ), + ), + ), + array( + 'name' => 'Wed', + 'hours' => array( + array( + 'opening' => '09:00', + 'closing' => '17:00', + ), + ), + ), + array( + 'name' => 'Thu', + 'hours' => array( + array( + 'opening' => '09:00', + 'closing' => '17:00', + ), + ), + ), + array( + 'name' => 'Fri', + 'hours' => array( + array( + 'opening' => '09:00', + 'closing' => '17:00', + ), + ), + ), + array( + 'name' => 'Sat', + 'hours' => array(), + ), + ); +} + +/** + * Dynamic rendering of the block. + * + * @param array $attributes Array containing the business hours block attributes. + * + * @return string + */ +function render( $attributes ) { + global $wp_locale; + + if ( empty( $attributes['days'] ) || ! is_array( $attributes['days'] ) ) { + $attributes['days'] = get_default_days(); + } + + $wrapper_attributes = \WP_Block_Supports::get_instance()->apply_block_supports(); + + $start_of_week = (int) get_option( 'start_of_week', 0 ); + $time_format = get_option( 'time_format' ); + $content = sprintf( + '
', + ! empty( $attributes['className'] ) ? ' ' . esc_attr( $attributes['className'] ) : '', + ! empty( $wrapper_attributes['class'] ) ? ' ' . esc_attr( $wrapper_attributes['class'] ) : '', + ! empty( $wrapper_attributes['style'] ) ? ' style="' . esc_attr( $wrapper_attributes['style'] ) . '"' : '' + ); + + $days = array( 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' ); + + if ( $start_of_week ) { + $chunk1 = array_slice( $attributes['days'], 0, $start_of_week ); + $chunk2 = array_slice( $attributes['days'], $start_of_week ); + $attributes['days'] = array_merge( $chunk2, $chunk1 ); + } + + foreach ( $attributes['days'] as $day ) { + $content .= '
' . + ucfirst( $wp_locale->get_weekday( array_search( $day['name'], $days, true ) ) ) . + '
'; + $content .= '
'; + $days_hours = ''; + + foreach ( $day['hours'] as $key => $hour ) { + $opening = strtotime( $hour['opening'] ); + $closing = strtotime( $hour['closing'] ); + if ( ! $opening || ! $closing ) { + continue; + } + $days_hours .= sprintf( + '%1$s - %2$s', + gmdate( $time_format, $opening ), + gmdate( $time_format, $closing ) + ); + if ( $key + 1 < count( $day['hours'] ) ) { + $days_hours .= ', '; + } + } + + if ( empty( $days_hours ) ) { + $days_hours = esc_html__( 'Closed', 'jetpack' ); + } + $content .= $days_hours; + $content .= '
'; + } + + $content .= '
'; + + Jetpack_Gutenberg::load_assets_as_required( FEATURE_NAME ); + + /** + * Allows folks to filter the HTML content for the Business Hours block + * + * @since 7.1.0 + * + * @param string $content The default HTML content set by `jetpack_business_hours_render` + * @param array $attributes Attributes generated in the block editor for the Business Hours block + */ + return apply_filters( 'jetpack_business_hours_content', $content, $attributes ); +} diff --git a/projects/plugins/jetpack/extensions/blocks/business-hours-single/components/day-edit.js b/projects/plugins/jetpack/extensions/blocks/business-hours-single/components/day-edit.js new file mode 100644 index 000000000000..3bbe9eae1f13 --- /dev/null +++ b/projects/plugins/jetpack/extensions/blocks/business-hours-single/components/day-edit.js @@ -0,0 +1,198 @@ +import { Button, TextControl, ToggleControl } from '@wordpress/components'; +import { Component, Fragment } from '@wordpress/element'; +import { __ } from '@wordpress/i18n'; +import classNames from 'classnames'; +import { isEmpty } from 'lodash'; + +const defaultOpen = '09:00'; +const defaultClose = '17:00'; + +class DayEdit extends Component { + renderInterval = ( interval, intervalIndex ) => { + const { day } = this.props; + const { opening, closing } = interval; + return ( + +
+
+ { intervalIndex === 0 && this.renderDayToggle() } +
+
+ { + this.setHour( value, 'opening', intervalIndex ); + } } + /> + { + this.setHour( value, 'closing', intervalIndex ); + } } + /> +
+
+ { day.hours.length > 1 && ( +
+
+ { intervalIndex === day.hours.length - 1 && ( +
+
 
+
+ +
+
 
+
+ ) } +
+ ); + }; + + setHour = ( hourValue, hourType, hourIndex ) => { + const { day, attributes, setAttributes } = this.props; + const { days } = attributes; + setAttributes( { + days: days.map( value => { + if ( value.name === day.name ) { + return { + ...value, + hours: value.hours.map( ( hour, index ) => { + if ( index === hourIndex ) { + return { + ...hour, + [ hourType ]: hourValue, + }; + } + return hour; + } ), + }; + } + return value; + } ), + } ); + }; + + toggleClosed = nextValue => { + const { day, attributes, setAttributes } = this.props; + const { days } = attributes; + + setAttributes( { + days: days.map( value => { + if ( value.name === day.name ) { + const hours = nextValue + ? [ + { + opening: defaultOpen, + closing: defaultClose, + }, + ] + : []; + return { + ...value, + hours, + }; + } + return value; + } ), + } ); + }; + + addInterval = () => { + const { day, attributes, setAttributes } = this.props; + const { days } = attributes; + day.hours.push( { opening: '', closing: '' } ); + setAttributes( { + days: days.map( value => { + if ( value.name === day.name ) { + return { + ...value, + hours: day.hours, + }; + } + return value; + } ), + } ); + }; + + removeInterval = hourIndex => { + const { day, attributes, setAttributes } = this.props; + const { days } = attributes; + + setAttributes( { + days: days.map( value => { + if ( day.name === value.name ) { + return { + ...value, + hours: value.hours.filter( ( hour, index ) => { + return hourIndex !== index; + } ), + }; + } + return value; + } ), + } ); + }; + + isClosed() { + const { day } = this.props; + return isEmpty( day.hours ); + } + + renderDayToggle() { + const { day, localization } = this.props; + return ( + + { localization.days[ day.name ] } + + + ); + } + + renderClosed() { + const { day } = this.props; + return ( +
+
+ { this.renderDayToggle() } +
+
 
+
 
+
+ ); + } + + render() { + const { day } = this.props; + return this.isClosed() ? this.renderClosed() : day.hours.map( this.renderInterval ); + } +} + +export default DayEdit; diff --git a/projects/plugins/jetpack/extensions/blocks/business-hours-single/components/day-preview.js b/projects/plugins/jetpack/extensions/blocks/business-hours-single/components/day-preview.js new file mode 100644 index 000000000000..4c0c9c69ad9f --- /dev/null +++ b/projects/plugins/jetpack/extensions/blocks/business-hours-single/components/day-preview.js @@ -0,0 +1,54 @@ +import { date } from '@wordpress/date'; +import { Component } from '@wordpress/element'; +import { _x, sprintf } from '@wordpress/i18n'; +import { isEmpty } from 'lodash'; + +class DayPreview extends Component { + formatTime( time ) { + const { timeFormat } = this.props; + const [ hours, minutes ] = time.split( ':' ); + const _date = new Date(); + if ( ! hours || ! minutes ) { + return false; + } + _date.setHours( hours ); + _date.setMinutes( minutes ); + return date( timeFormat, _date ); + } + + renderInterval = ( interval, key ) => { + const { day } = this.props; + const hours = day.hours; + return ( + + { sprintf( + '%1$s - %2$s', + this.formatTime( interval.opening ), + this.formatTime( interval.closing ) + ) } + { hours.length > 1 + key && , } + + ); + }; + + render() { + const { day, localization } = this.props; + const hours = day.hours.filter( + // remove any malformed or empty intervals + interval => this.formatTime( interval.opening ) && this.formatTime( interval.closing ) + ); + return ( +
+
{ localization.days[ day.name ] }
+
+ { isEmpty( hours ) + ? _x( 'Closed', 'business is closed on a full day', 'jetpack' ) + : hours.map( this.renderInterval ) } +
+
+
+ ); + } +} + +export default DayPreview; diff --git a/projects/plugins/jetpack/extensions/blocks/business-hours-single/edit.js b/projects/plugins/jetpack/extensions/blocks/business-hours-single/edit.js new file mode 100644 index 000000000000..0c35aa992037 --- /dev/null +++ b/projects/plugins/jetpack/extensions/blocks/business-hours-single/edit.js @@ -0,0 +1,91 @@ +import apiFetch from '@wordpress/api-fetch'; +import { Placeholder } from '@wordpress/components'; +import { getSettings } from '@wordpress/date'; +import { Component } from '@wordpress/element'; +import { __ } from '@wordpress/i18n'; +import classNames from 'classnames'; +import DayEdit from './components/day-edit'; +import DayPreview from './components/day-preview'; +import { icon } from '.'; + +export const defaultLocalization = { + days: { + Sun: __( 'Sunday', 'jetpack' ), + Mon: __( 'Monday', 'jetpack' ), + Tue: __( 'Tuesday', 'jetpack' ), + Wed: __( 'Wednesday', 'jetpack' ), + Thu: __( 'Thursday', 'jetpack' ), + Fri: __( 'Friday', 'jetpack' ), + Sat: __( 'Saturday', 'jetpack' ), + }, + startOfWeek: 0, +}; + +class BusinessHours extends Component { + state = { + localization: defaultLocalization, + hasFetched: false, + }; + + componentDidMount() { + this.apiFetch(); + } + + apiFetch() { + this.setState( { data: defaultLocalization }, () => { + apiFetch( { path: '/wpcom/v2/business-hours/localized-week' } ).then( + data => { + this.setState( { localization: data, hasFetched: true } ); + }, + () => { + this.setState( { localization: defaultLocalization, hasFetched: true } ); + } + ); + } ); + } + + render() { + const { attributes, className, isSelected } = this.props; + const { days } = attributes; + const { localization, hasFetched } = this.state; + const { startOfWeek } = localization; + const localizedWeek = days.concat( days.slice( 0, startOfWeek ) ).slice( startOfWeek ); + + if ( ! hasFetched ) { + return ; + } + + if ( ! isSelected ) { + const settings = getSettings(); + const { + formats: { time }, + } = settings; + return ( +
+ { localizedWeek.map( ( day, key ) => { + return ( + + ); + } ) } +
+ ); + } + + return ( +
+ { localizedWeek.map( ( day, key ) => { + return ( + + ); + } ) } +
+ ); + } +} + +export default BusinessHours; diff --git a/projects/plugins/jetpack/extensions/blocks/business-hours-single/editor.js b/projects/plugins/jetpack/extensions/blocks/business-hours-single/editor.js new file mode 100644 index 000000000000..bde09cdd7529 --- /dev/null +++ b/projects/plugins/jetpack/extensions/blocks/business-hours-single/editor.js @@ -0,0 +1,5 @@ +import { registerBlockType } from '@wordpress/blocks'; +import metadata from './block.json'; +import { settings } from '.'; + +registerBlockType( metadata, settings ); diff --git a/projects/plugins/jetpack/extensions/blocks/business-hours-single/editor.scss b/projects/plugins/jetpack/extensions/blocks/business-hours-single/editor.scss new file mode 100644 index 000000000000..d596766155cf --- /dev/null +++ b/projects/plugins/jetpack/extensions/blocks/business-hours-single/editor.scss @@ -0,0 +1,170 @@ +@import '@automattic/jetpack-base-styles/gutenberg-base-styles'; + +.wp-block-jetpack-business-hours { + overflow: hidden; + + dd, dt { + @media (min-width: 480px ) { + display: inline-block; + } + } + + dt { + min-width: 30%; + vertical-align: top; + } + + dd { + margin: 0; + @media (min-width: 480px ) { + max-width: calc( 70% - 0.5em ); + } + } + + .components-toggle-control__label, + .components-base-control__label { + // Sets labels to 13px for consistency in the Site Editor. + // The Site Editor iframe doesn't include common styles, + // from which the font size of the labels are inherited. + // https://github.com/WordPress/gutenberg/blob/3da717b8d0ac7d7821fc6d0475695ccf3ae2829f/packages/base-styles/_variables.scss#L16 + font-size: $default-font-size; + } + + .components-base-control__field { + margin-bottom: 0; + } + + .jetpack-business-hours__item { + margin-bottom: 0.5em; + } + + .business-hours__row { + display: flex; + line-height: normal; + margin-bottom: 4px; + + &.business-hours-row__add, + &.business-hours-row__closed { + margin-bottom: 20px; + } + + .business-hours__day { + width: 44%; + display: flex; + align-items: flex-start; + + .business-hours__day-name { + width: 60%; + font-weight: bold; + overflow-x: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + .components-form-toggle { + margin-right: 4px; + margin-top: 4px; + } + } + + .business-hours__hours { + width: 44%; + margin: 0; + display: flex; + align-items: center; + flex-wrap: wrap; + + .components-button { + padding: 0; + } + + .components-base-control { + display: inline-block; + margin-bottom: 0; + width: 48%; + + &.business-hours__open { + margin-right: 4%; + } + + .components-base-control__label { + margin-bottom: 0; + } + } + } + } + + .business-hours__remove { + align-self: flex-end; + margin-bottom: 8px; + text-align: center; + width: 10%; + } + + .business-hours-row__add button:hover { + box-shadow: none !important; + } + + .business-hours__remove button { + display: block; + margin: 0 auto; + } + + .business-hours-row__add .components-button.is-default:hover, + .business-hours__remove .components-button.is-default:hover, + .business-hours-row__add .components-button.is-default:focus, + .business-hours__remove .components-button.is-default:focus, + .business-hours-row__add .components-button.is-default:active, + .business-hours__remove .components-button.is-default:active { + background: none; + box-shadow: none; + } +} + +/** + * We consider the editor area to be small when the business hours block is: + * - within a column block + * - in a screen < xlarge size with the sidebar open + * - in a screen < small size + * In these cases we'll apply small screen styles. + */ +@mixin editor-area-is-small { + @media ( max-width: $break-xlarge ) { + .is-sidebar-opened { + @content; + } + } + @media ( max-width: $break-small ) { + @content; + } + + .wp-block-columns { + @content; + } +} + +@include editor-area-is-small() { + .wp-block-jetpack-business-hours { + .business-hours__row { + flex-wrap: wrap; + + &.business-hours-row__add { + .business-hours__day, + .business-hours__remove { + display: none; + } + } + + .business-hours__day { + width: 100%; + } + + .business-hours__hours { + width: 78%; + } + .business-hours__remove { + width: 18%; + } + } + } +} diff --git a/projects/plugins/jetpack/extensions/blocks/business-hours-single/index.js b/projects/plugins/jetpack/extensions/blocks/business-hours-single/index.js new file mode 100644 index 000000000000..1076c617d3da --- /dev/null +++ b/projects/plugins/jetpack/extensions/blocks/business-hours-single/index.js @@ -0,0 +1,87 @@ +import { Path } from '@wordpress/components'; +import { getIconColor } from '../../shared/block-icons'; +import renderMaterialIcon from '../../shared/render-material-icon'; +import BusinessHours from './edit'; + +/** + * Block Registrations: + */ + +const defaultDays = [ + { + name: 'Sun', + hours: [], // Closed by default + }, + { + name: 'Mon', + hours: [ + { + opening: '09:00', + closing: '17:00', + }, + ], + }, + { + name: 'Tue', + hours: [ + { + opening: '09:00', + closing: '17:00', + }, + ], + }, + { + name: 'Wed', + hours: [ + { + opening: '09:00', + closing: '17:00', + }, + ], + }, + { + name: 'Thu', + hours: [ + { + opening: '09:00', + closing: '17:00', + }, + ], + }, + { + name: 'Fri', + hours: [ + { + opening: '09:00', + closing: '17:00', + }, + ], + }, + { + name: 'Sat', + hours: [], // Closed by default + }, +]; +export const icon = renderMaterialIcon( + +); + +export const settings = { + icon: { + src: icon, + foreground: getIconColor(), + }, + attributes: { + days: { + type: 'array', + default: defaultDays, + }, + }, + example: { + attributes: { + days: defaultDays, + }, + }, + edit: props => , + save: () => null, +}; diff --git a/projects/plugins/jetpack/extensions/blocks/business-hours-single/style.scss b/projects/plugins/jetpack/extensions/blocks/business-hours-single/style.scss new file mode 100644 index 000000000000..1fc272a79e0d --- /dev/null +++ b/projects/plugins/jetpack/extensions/blocks/business-hours-single/style.scss @@ -0,0 +1,26 @@ +.jetpack-business-hours { + dt, + dd { + @media (min-width: 480px ) { + display: inline-block; + } + } + + dt { + font-weight: bold; + margin-right: 0.5em; + min-width: 30%; + vertical-align: top; + } + + dd { + margin: 0; + @media (min-width: 480px ) { + max-width: calc( 70% - 0.5em ); + } + } +} + +.jetpack-business-hours__item { + margin-bottom: 0.5em; +} diff --git a/projects/plugins/jetpack/extensions/index.json b/projects/plugins/jetpack/extensions/index.json index 8ed40b295ce2..6c00daa2daae 100644 --- a/projects/plugins/jetpack/extensions/index.json +++ b/projects/plugins/jetpack/extensions/index.json @@ -90,5 +90,6 @@ "tiled-gallery", "videopress", "wordads" - ] + ], + "single": [ "business-hours-single" ] } diff --git a/projects/plugins/jetpack/package.json b/projects/plugins/jetpack/package.json index 041f2d551269..7de80e2fae30 100644 --- a/projects/plugins/jetpack/package.json +++ b/projects/plugins/jetpack/package.json @@ -86,6 +86,7 @@ "debug": "4.3.4", "email-validator": "2.0.4", "events": "3.3.0", + "file-loader": "6.2.0", "filesize": "8.0.6", "focus-trap": "6.3.0", "gridicons": "3.4.1", diff --git a/projects/plugins/jetpack/tools/webpack.config.extensions.js b/projects/plugins/jetpack/tools/webpack.config.extensions.js index db956d3e5a31..a88661b328a4 100644 --- a/projects/plugins/jetpack/tools/webpack.config.extensions.js +++ b/projects/plugins/jetpack/tools/webpack.config.extensions.js @@ -17,11 +17,30 @@ const StaticSiteGeneratorPlugin = require( './static-site-generator-webpack-plug */ const editorSetup = path.join( __dirname, '../extensions', 'editor' ); const viewSetup = path.join( __dirname, '../extensions', 'view' ); +const blockEditorDirectories = [ 'plugins', 'blocks' ]; const noop = function () {}; +/** + * Filters block editor scripts + * + * @param {string} type - script type + * @param {string} inputDir - input directory + * @param {Array} presetBlocks - preset blocks + * @returns {Array} list of block scripts + */ +function presetProductionExtensions( type, inputDir, presetBlocks ) { + return presetBlocks + .flatMap( block => + blockEditorDirectories.map( dir => path.join( inputDir, dir, block, `${ type }.js` ) ) + ) + .filter( fs.existsSync ); +} + const presetPath = path.join( __dirname, '../extensions', 'index.json' ); const presetIndex = require( presetPath ); const presetProductionBlocks = presetIndex.production || []; +const presetNoPostEditorBlocks = presetIndex[ 'no-post-editor' ] || []; +const presetSingleBlocks = presetIndex.single || []; const presetExperimentalBlocks = [ ...presetProductionBlocks, @@ -30,7 +49,55 @@ const presetExperimentalBlocks = [ // Beta Blocks include all blocks: beta, experimental, and production blocks. const presetBetaBlocks = [ ...presetExperimentalBlocks, ...( presetIndex.beta || [] ) ]; -const editorBlocksScripts = presetBetaBlocks.reduce( ( editorBlocks, block ) => { +// Helps split up each block into its own folder view script +const viewBlocksScripts = presetBetaBlocks.reduce( ( viewBlocks, block ) => { + const viewScriptPath = path.join( __dirname, '../extensions/blocks', block, 'view.js' ); + if ( fs.existsSync( viewScriptPath ) ) { + viewBlocks[ block + '/view' ] = [ viewSetup, ...[ viewScriptPath ] ]; + } + return viewBlocks; +}, {} ); + +// Combines all the different production blocks into one editor.js script +const editorScript = [ + editorSetup, + ...presetProductionExtensions( + 'editor', + path.join( __dirname, '../extensions' ), + presetProductionBlocks + ), +]; + +// Combines all the different Experimental blocks into one editor.js script +const editorExperimentalScript = [ + editorSetup, + ...presetProductionExtensions( + 'editor', + path.join( __dirname, '../extensions' ), + presetExperimentalBlocks + ), +]; + +// Combines all the different blocks into one editor-beta.js script +const editorBetaScript = [ + editorSetup, + ...presetProductionExtensions( + 'editor', + path.join( __dirname, '../extensions' ), + presetBetaBlocks + ), +]; + +const editorNoPostEditorScript = [ + editorSetup, + ...presetProductionExtensions( + 'editor', + path.join( __dirname, '../extensions' ), + presetNoPostEditorBlocks + ), +]; + +const editorSingleBlocksScripts = presetSingleBlocks.reduce( ( editorBlocks, block ) => { const editorScriptPath = path.join( __dirname, '../extensions/blocks', block, 'editor.js' ); if ( fs.existsSync( editorScriptPath ) ) { editorBlocks[ block + '/editor' ] = [ editorScriptPath ]; @@ -38,8 +105,7 @@ const editorBlocksScripts = presetBetaBlocks.reduce( ( editorBlocks, block ) => return editorBlocks; }, {} ); -// Helps split up each block into its own folder view script -const viewBlocksScripts = presetBetaBlocks.reduce( ( viewBlocks, block ) => { +const viewSingleBlocksScripts = presetSingleBlocks.reduce( ( viewBlocks, block ) => { const viewScriptPath = path.join( __dirname, '../extensions/blocks', block, 'view.js' ); if ( fs.existsSync( viewScriptPath ) ) { viewBlocks[ block + '/view' ] = [ viewSetup, ...[ viewScriptPath ] ]; @@ -47,6 +113,22 @@ const viewBlocksScripts = presetBetaBlocks.reduce( ( viewBlocks, block ) => { return viewBlocks; }, {} ); +const editorSingleBlocksStyles = presetSingleBlocks.reduce( ( editorBlocks, block ) => { + const editorStylePath = path.join( __dirname, '../extensions/blocks', block, 'editor.scss' ); + if ( fs.existsSync( editorStylePath ) ) { + editorBlocks[ block + '/editor' ] = [ editorStylePath ]; + } + return editorBlocks; +}, {} ); + +const viewSingleBlocksStyles = presetSingleBlocks.reduce( ( viewBlocks, block ) => { + const viewStylePath = path.join( __dirname, '../extensions/blocks', block, 'style.scss' ); + if ( fs.existsSync( viewStylePath ) ) { + viewBlocks[ block + '/view' ] = [ viewSetup, ...[ viewStylePath ] ]; + } + return viewBlocks; +}, {} ); + const sharedWebpackConfig = { mode: jetpackWebpackConfig.mode, devtool: jetpackWebpackConfig.devtool, @@ -127,8 +209,10 @@ module.exports = [ { ...sharedWebpackConfig, entry: { - editor: editorSetup, - ...editorBlocksScripts, + editor: editorScript, + 'editor-experimental': editorExperimentalScript, + 'editor-beta': editorBetaScript, + 'editor-no-post-editor': editorNoPostEditorScript, ...viewBlocksScripts, }, plugins: [ @@ -217,4 +301,53 @@ module.exports = [ } ), ], }, + { + ...sharedWebpackConfig, + entry: { + ...editorSingleBlocksScripts, + ...viewSingleBlocksScripts, + }, + plugins: [ + ...sharedWebpackConfig.plugins, + new CopyWebpackPlugin( { + patterns: [ + { + from: '**/block.json', + to: '[path][name][ext]', + context: path.join( __dirname, '../extensions/blocks' ), + }, + ], + } ), + ], + }, + { + ...sharedWebpackConfig, + entry: { + ...editorSingleBlocksStyles, + ...viewSingleBlocksStyles, + }, + module: { + rules: [ + { + test: /\.scss$/, + use: [ + { + loader: 'file-loader', + options: { + name: '[path]_[name].css', + context: path.join( __dirname, '../extensions/blocks' ), + }, + }, + { + loader: 'postcss-loader', + options: { + postcssOptions: { config: path.join( __dirname, 'postcss.config.js' ) }, + }, + }, + 'sass-loader', + ], + }, + ], + }, + }, ]; From 5d1835fb2a729880ed261ea385d6b930b4073704 Mon Sep 17 00:00:00 2001 From: Kevin Zoschke Date: Fri, 9 Jun 2023 09:01:20 -0400 Subject: [PATCH 3/7] changelog --- projects/plugins/jetpack/changelog/update-extensions-build | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 projects/plugins/jetpack/changelog/update-extensions-build diff --git a/projects/plugins/jetpack/changelog/update-extensions-build b/projects/plugins/jetpack/changelog/update-extensions-build new file mode 100644 index 000000000000..05b55adf2a46 --- /dev/null +++ b/projects/plugins/jetpack/changelog/update-extensions-build @@ -0,0 +1,4 @@ +Significance: minor +Type: enhancement + +Build individual blocks From db8277abea33ad193d5a7c3a2af84141357980df Mon Sep 17 00:00:00 2001 From: Kevin Zoschke Date: Tue, 20 Jun 2023 16:17:58 -0400 Subject: [PATCH 4/7] Fix single block implementation --- pnpm-lock.yaml | 17 +-- projects/packages/blocks/src/class-blocks.php | 6 +- .../jetpack/class.jetpack-gutenberg.php | 130 +++++++++++++----- .../blocks/business-hours-single/block.json | 4 +- .../business-hours-single.php | 8 +- .../blocks/business-hours-single/editor.js | 7 +- .../blocks/business-hours-single/view.js | 1 + projects/plugins/jetpack/package.json | 2 +- .../tools/webpack.config.extensions.js | 57 ++------ 9 files changed, 133 insertions(+), 99 deletions(-) create mode 100644 projects/plugins/jetpack/extensions/blocks/business-hours-single/view.js diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f0572c50ed69..2a69c07b4af1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2774,6 +2774,9 @@ importers: '@wordpress/date': specifier: 4.34.0 version: 4.34.0 + '@wordpress/dependency-extraction-webpack-plugin': + specifier: 4.17.0 + version: 4.17.0(webpack@5.76.0) '@wordpress/edit-post': specifier: 7.11.0 version: 7.11.0(@types/react@18.0.27)(react-dom@18.2.0)(react@18.2.0) @@ -2828,9 +2831,6 @@ importers: events: specifier: 3.3.0 version: 3.3.0 - file-loader: - specifier: 6.2.0 - version: 6.2.0(webpack@5.76.0) filesize: specifier: 8.0.6 version: 8.0.6 @@ -15416,17 +15416,6 @@ packages: flat-cache: 3.0.4 dev: true - /file-loader@6.2.0(webpack@5.76.0): - resolution: {integrity: sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==} - engines: {node: '>= 10.13.0'} - peerDependencies: - webpack: ^4.0.0 || ^5.0.0 - dependencies: - loader-utils: 2.0.4 - schema-utils: 3.1.2 - webpack: 5.76.0(webpack-cli@4.9.1) - dev: false - /file-system-cache@2.1.1: resolution: {integrity: sha512-vgZ1uDsK29DM4pptUOv47zdJO2tYM5M/ERyAE9Jk0QBN6e64Md+a+xJSOp68dCCDH4niFMVD8nC8n8A5ic0bmg==} dependencies: diff --git a/projects/packages/blocks/src/class-blocks.php b/projects/packages/blocks/src/class-blocks.php index 9286bd4ebc36..9b6696974029 100644 --- a/projects/packages/blocks/src/class-blocks.php +++ b/projects/packages/blocks/src/class-blocks.php @@ -39,7 +39,7 @@ class Blocks { * * @return WP_Block_Type|false The registered block type on success, or false on failure. */ - public static function jetpack_register_block( $slug, $args = array() ) { + public static function jetpack_register_block( $slug, $args = array(), $metadata_dir = '' ) { if ( 0 !== strpos( $slug, 'jetpack/' ) && ! strpos( $slug, '/' ) ) { _doing_it_wrong( 'jetpack_register_block', 'Prefix the block with jetpack/ ', 'Jetpack 9.0.0' ); $slug = 'jetpack/' . $slug; @@ -94,12 +94,12 @@ function () use ( $feature_name, $method_name ) { // Ensure editor styles are registered so that the site editor knows about the // editor style dependency when copying styles to the editor iframe. - if ( ! isset( $args['editor_style'] ) ) { + if ( ! isset( $args['editor_style'] ) && ! $metadata_dir ) { $args['editor_style'] = 'jetpack-blocks-editor'; } } - return register_block_type( $slug, $args ); + return register_block_type( $metadata_dir ? $metadata_dir : $slug, $args ); } /** diff --git a/projects/plugins/jetpack/class.jetpack-gutenberg.php b/projects/plugins/jetpack/class.jetpack-gutenberg.php index 4bdae9a319e6..fe3715d3f5a0 100644 --- a/projects/plugins/jetpack/class.jetpack-gutenberg.php +++ b/projects/plugins/jetpack/class.jetpack-gutenberg.php @@ -266,10 +266,11 @@ public static function preset_exists( $preset ) { * * @return mixed Returns an object if the file is present, or false if a valid .json file is not present. */ - public static function get_preset( $preset ) { + public static function get_preset( $preset, $associative = null ) { return json_decode( // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents - file_get_contents( JETPACK__PLUGIN_DIR . self::get_blocks_directory() . $preset . '.json' ) + file_get_contents( JETPACK__PLUGIN_DIR . self::get_blocks_directory() . $preset . '.json' ), + $associative ); } @@ -287,6 +288,37 @@ public static function get_jetpack_gutenberg_extensions_allowed_list() { return self::get_extensions_preset_for_variation( $preset_extensions_manifest, $blocks_variation ); } + public static function get_jetpack_gutenberg_single_extensions() { + $preset_extensions_manifest = self::preset_exists( 'index' ) + ? self::get_preset( 'index' ) + : (object) array(); + + return isset( $preset_extensions_manifest->single ) + ? (array) $preset_extensions_manifest->single + : array(); + } + + public static function has_bundled_extension() { + $preset_extensions_manifest = self::preset_exists( 'index' ) + ? self::get_preset( 'index', true ) + : array(); + + $production = isset( $preset_extensions_manifest['production'] ) + ? $preset_extensions_manifest['production'] + : array(); + $beta = isset( $preset_extensions_manifest['beta'] ) + ? $preset_extensions_manifest['beta'] + : array(); + $experimental = isset( $preset_extensions_manifest['experimental'] ) + ? $preset_extensions_manifest['experimental'] + : array(); + $no_post = isset( $preset_extensions_manifest['no-post-editor'] ) + ? $preset_extensions_manifest['no-post-editor'] + : array(); + + return count( $production ) > 0 || count( $beta ) > 0 || count( $experimental ) > 0 || count( $no_post ) > 0; + } + /** * Returns a diff from a combined list of allowed extensions and extensions determined to be excluded * @@ -611,6 +643,9 @@ public static function enqueue_block_editor_assets() { $blocks_dir = self::get_blocks_directory(); $blocks_variation = self::blocks_variation(); + $has_bundle = self::has_bundled_extension(); + $single_blocks = self::get_jetpack_gutenberg_single_extensions(); + $has_single = count( $single_blocks ) > 0; if ( 'production' !== $blocks_variation ) { $blocks_env = '-' . esc_attr( $blocks_variation ); @@ -618,28 +653,49 @@ public static function enqueue_block_editor_assets() { $blocks_env = ''; } - Assets::register_script( - 'jetpack-blocks-editor', - "{$blocks_dir}editor{$blocks_env}.js", - JETPACK__PLUGIN_FILE, - array( 'textdomain' => 'jetpack' ) - ); + if ( $has_single ) { + Assets::register_script( + 'editor-core', + "{$blocks_dir}editor-core.js", + JETPACK__PLUGIN_FILE, + array( 'textdomain' => 'jetpack' ) + ); - // Hack around #20357 (specifically, that the editor bundle depends on - // wp-edit-post but wp-edit-post's styles break the Widget Editor and - // Site Editor) until a real fix gets unblocked. - // @todo Remove this once #20357 is properly fixed. - wp_styles()->query( 'jetpack-blocks-editor', 'registered' )->deps = array(); + wp_enqueue_style( 'editor-core' ); - Assets::enqueue_script( 'jetpack-blocks-editor' ); + wp_localize_script( + 'editor-core', + 'Jetpack_Block_Assets_Base_Url', + array( + 'url' => plugins_url( $blocks_dir . '/', JETPACK__PLUGIN_FILE ), + ) + ); + } - wp_localize_script( - 'jetpack-blocks-editor', - 'Jetpack_Block_Assets_Base_Url', - array( - 'url' => plugins_url( $blocks_dir . '/', JETPACK__PLUGIN_FILE ), - ) - ); + if ( $has_bundle ) { + Assets::register_script( + 'jetpack-blocks-editor', + "{$blocks_dir}editor{$blocks_env}.js", + JETPACK__PLUGIN_FILE, + array( 'textdomain' => 'jetpack' ) + ); + + // Hack around #20357 (specifically, that the editor bundle depends on + // wp-edit-post but wp-edit-post's styles break the Widget Editor and + // Site Editor) until a real fix gets unblocked. + // @todo Remove this once #20357 is properly fixed. + wp_styles()->query( 'jetpack-blocks-editor', 'registered' )->deps = array(); + + Assets::enqueue_script( 'jetpack-blocks-editor' ); + + wp_localize_script( + 'jetpack-blocks-editor', + 'Jetpack_Block_Assets_Base_Url', + array( + 'url' => plugins_url( $blocks_dir . '/', JETPACK__PLUGIN_FILE ), + ) + ); + } if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) { $user = wp_get_current_user(); @@ -734,14 +790,27 @@ public static function enqueue_block_editor_assets() { ); } - wp_localize_script( - 'jetpack-blocks-editor', - 'Jetpack_Editor_Initial_State', - $initial_state - ); + if ( $has_bundle ) { + wp_localize_script( + 'jetpack-blocks-editor', + 'Jetpack_Editor_Initial_State', + $initial_state + ); + + // Adds Connection package initial state. + wp_add_inline_script( 'jetpack-blocks-editor', Connection_Initial_State::render(), 'before' ); + } - // Adds Connection package initial state. - wp_add_inline_script( 'jetpack-blocks-editor', Connection_Initial_State::render(), 'before' ); + if ( $has_single && ! $has_bundle ) { + wp_localize_script( + 'editor-core', + 'Jetpack_Editor_Initial_State', + $initial_state + ); + + // Adds Connection package initial state. + wp_add_inline_script( 'editor-core', Connection_Initial_State::render(), 'before' ); + } } /** @@ -1017,10 +1086,7 @@ public static function get_extensions_preset_for_variation( $preset_extensions_m $preset_extensions = array_unique( array_merge( $preset_extensions, $production_extensions ) ); } - $single_extensions = isset( $preset_extensions_manifest->single ) - ? (array) $preset_extensions_manifest->single - : array(); - $preset_extensions = array_unique( array_merge( $preset_extensions, $single_extensions ) ); + $preset_extensions = array_unique( array_merge( $preset_extensions, self::get_jetpack_gutenberg_single_extensions() ) ); return $preset_extensions; } diff --git a/projects/plugins/jetpack/extensions/blocks/business-hours-single/block.json b/projects/plugins/jetpack/extensions/blocks/business-hours-single/block.json index 69afd76ac58f..b8dfdf29c67c 100644 --- a/projects/plugins/jetpack/extensions/blocks/business-hours-single/block.json +++ b/projects/plugins/jetpack/extensions/blocks/business-hours-single/block.json @@ -24,6 +24,6 @@ "align": [ "wide", "full" ] }, "editorScript": "file:./editor.js", - "editorStyle": "file:./_editor.css", - "style": "file:./_style.css" + "editorStyle": "file:./editor.css", + "style": "file:./view.css" } diff --git a/projects/plugins/jetpack/extensions/blocks/business-hours-single/business-hours-single.php b/projects/plugins/jetpack/extensions/blocks/business-hours-single/business-hours-single.php index ab890cf43bc6..71037a29978d 100644 --- a/projects/plugins/jetpack/extensions/blocks/business-hours-single/business-hours-single.php +++ b/projects/plugins/jetpack/extensions/blocks/business-hours-single/business-hours-single.php @@ -9,6 +9,7 @@ namespace Automattic\Jetpack\Extensions\Business_Hours_Single; +use Automattic\Jetpack\Blocks; use Jetpack_Gutenberg; const FEATURE_NAME = 'business-hours-single'; @@ -23,11 +24,12 @@ function register_block() { $dir = dirname( JETPACK__PLUGIN_FILE ); $json_dir = $dir . '/_inc/blocks/' . FEATURE_NAME; - register_block_type( - $json_dir, + Blocks::jetpack_register_block( + BLOCK_NAME, array( 'render_callback' => __NAMESPACE__ . '\render', - ) + ), + $json_dir, ); } add_action( 'init', __NAMESPACE__ . '\register_block' ); diff --git a/projects/plugins/jetpack/extensions/blocks/business-hours-single/editor.js b/projects/plugins/jetpack/extensions/blocks/business-hours-single/editor.js index bde09cdd7529..03fa36550695 100644 --- a/projects/plugins/jetpack/extensions/blocks/business-hours-single/editor.js +++ b/projects/plugins/jetpack/extensions/blocks/business-hours-single/editor.js @@ -1,5 +1,8 @@ -import { registerBlockType } from '@wordpress/blocks'; +import 'editor-core'; // editor-core is an external dependency +import registerJetpackBlock from '../../shared/register-jetpack-block'; import metadata from './block.json'; import { settings } from '.'; -registerBlockType( metadata, settings ); +import './editor.scss'; + +registerJetpackBlock( metadata.name.replace( 'jetpack/', '' ), settings ); diff --git a/projects/plugins/jetpack/extensions/blocks/business-hours-single/view.js b/projects/plugins/jetpack/extensions/blocks/business-hours-single/view.js new file mode 100644 index 000000000000..423b033ce717 --- /dev/null +++ b/projects/plugins/jetpack/extensions/blocks/business-hours-single/view.js @@ -0,0 +1 @@ +import './style.scss'; diff --git a/projects/plugins/jetpack/package.json b/projects/plugins/jetpack/package.json index 7de80e2fae30..1453a5dc2d47 100644 --- a/projects/plugins/jetpack/package.json +++ b/projects/plugins/jetpack/package.json @@ -68,6 +68,7 @@ "@wordpress/compose": "6.11.0", "@wordpress/data": "9.4.0", "@wordpress/date": "4.34.0", + "@wordpress/dependency-extraction-webpack-plugin": "4.17.0", "@wordpress/edit-post": "7.11.0", "@wordpress/element": "5.11.0", "@wordpress/hooks": "3.34.0", @@ -86,7 +87,6 @@ "debug": "4.3.4", "email-validator": "2.0.4", "events": "3.3.0", - "file-loader": "6.2.0", "filesize": "8.0.6", "focus-trap": "6.3.0", "gridicons": "3.4.1", diff --git a/projects/plugins/jetpack/tools/webpack.config.extensions.js b/projects/plugins/jetpack/tools/webpack.config.extensions.js index a88661b328a4..66719c0604be 100644 --- a/projects/plugins/jetpack/tools/webpack.config.extensions.js +++ b/projects/plugins/jetpack/tools/webpack.config.extensions.js @@ -7,6 +7,9 @@ const path = require( 'path' ); const jetpackWebpackConfig = require( '@automattic/jetpack-webpack-config/webpack' ); const webpack = jetpackWebpackConfig.webpack; const RemoveAssetWebpackPlugin = require( '@automattic/remove-asset-webpack-plugin' ); +const { + defaultRequestToExternal, +} = require( '@wordpress/dependency-extraction-webpack-plugin/lib/util' ); const CopyWebpackPlugin = require( 'copy-webpack-plugin' ); const jsdom = require( 'jsdom' ); const CopyBlockEditorAssetsPlugin = require( './copy-block-editor-assets' ); @@ -113,22 +116,6 @@ const viewSingleBlocksScripts = presetSingleBlocks.reduce( ( viewBlocks, block ) return viewBlocks; }, {} ); -const editorSingleBlocksStyles = presetSingleBlocks.reduce( ( editorBlocks, block ) => { - const editorStylePath = path.join( __dirname, '../extensions/blocks', block, 'editor.scss' ); - if ( fs.existsSync( editorStylePath ) ) { - editorBlocks[ block + '/editor' ] = [ editorStylePath ]; - } - return editorBlocks; -}, {} ); - -const viewSingleBlocksStyles = presetSingleBlocks.reduce( ( viewBlocks, block ) => { - const viewStylePath = path.join( __dirname, '../extensions/blocks', block, 'style.scss' ); - if ( fs.existsSync( viewStylePath ) ) { - viewBlocks[ block + '/view' ] = [ viewSetup, ...[ viewStylePath ] ]; - } - return viewBlocks; -}, {} ); - const sharedWebpackConfig = { mode: jetpackWebpackConfig.mode, devtool: jetpackWebpackConfig.devtool, @@ -308,7 +295,6 @@ module.exports = [ ...viewSingleBlocksScripts, }, plugins: [ - ...sharedWebpackConfig.plugins, new CopyWebpackPlugin( { patterns: [ { @@ -318,36 +304,23 @@ module.exports = [ }, ], } ), + ...jetpackWebpackConfig.StandardPlugins( { + DependencyExtractionPlugin: { + injectPolyfill: true, + requestToExternal( request ) { + if ( request === 'editor-core' ) { + return 'editor-core'; + } + return defaultRequestToExternal( request ); + }, + }, + } ), ], }, { ...sharedWebpackConfig, entry: { - ...editorSingleBlocksStyles, - ...viewSingleBlocksStyles, - }, - module: { - rules: [ - { - test: /\.scss$/, - use: [ - { - loader: 'file-loader', - options: { - name: '[path]_[name].css', - context: path.join( __dirname, '../extensions/blocks' ), - }, - }, - { - loader: 'postcss-loader', - options: { - postcssOptions: { config: path.join( __dirname, 'postcss.config.js' ) }, - }, - }, - 'sass-loader', - ], - }, - ], + 'editor-core': path.join( __dirname, '../extensions/editor.js' ), }, }, ]; From b4e9876af0538a1772eebc2acf0f44e5ca86fcb2 Mon Sep 17 00:00:00 2001 From: Kevin Zoschke Date: Tue, 20 Jun 2023 16:19:13 -0400 Subject: [PATCH 5/7] changelog --- projects/packages/blocks/changelog/update-extensions-build | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 projects/packages/blocks/changelog/update-extensions-build diff --git a/projects/packages/blocks/changelog/update-extensions-build b/projects/packages/blocks/changelog/update-extensions-build new file mode 100644 index 000000000000..fa33a5d0df45 --- /dev/null +++ b/projects/packages/blocks/changelog/update-extensions-build @@ -0,0 +1,4 @@ +Significance: patch +Type: added + +Build individual blocks From b7134a58605f9b4479173cfcda4af4fabddcc230 Mon Sep 17 00:00:00 2001 From: Andrii Lysenko Date: Tue, 25 Jul 2023 11:49:52 -0700 Subject: [PATCH 6/7] small updates --- pnpm-lock.yaml | 11 +++++++++++ projects/packages/blocks/src/class-blocks.php | 2 +- .../jetpack/tools/webpack.config.extensions.js | 7 +------ tools/docker/jetpack-docker-config-default.yml | 1 + 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c5413a5c4e4f..207f8cd5085a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11492,6 +11492,17 @@ packages: moment: 2.29.4 moment-timezone: 0.5.43 + /@wordpress/dependency-extraction-webpack-plugin@4.17.0(webpack@5.76.0): + resolution: {integrity: sha512-vSWYcjHwdQrnvw6XeYfxRFLGZBEKR3IU82ahfiUEb0doomlR/ulZbnIZdC22Xo0KuQkvTSHEx71yhnvyKYolBg==} + engines: {node: '>=14'} + peerDependencies: + webpack: ^4.8.3 || ^5.0.0 + dependencies: + json2php: 0.0.7 + webpack: 5.76.0(webpack-cli@4.9.1) + webpack-sources: 3.2.3 + dev: false + /@wordpress/dependency-extraction-webpack-plugin@4.20.0(webpack@5.76.0): resolution: {integrity: sha512-YeQZGRHN7VFQWWzqznsackW3OC3SVEcRU03Ore9RWA58d4QuYCsnLq2YLrZDqEgJDnh9mO7b7Ac4SrZADkmhnA==} engines: {node: '>=14'} diff --git a/projects/packages/blocks/src/class-blocks.php b/projects/packages/blocks/src/class-blocks.php index 369e018404f0..046f80c17d4b 100644 --- a/projects/packages/blocks/src/class-blocks.php +++ b/projects/packages/blocks/src/class-blocks.php @@ -36,7 +36,7 @@ class Blocks { * @type array $version_requirements Array containing required Gutenberg version and, if known, the WordPress version that was released with this minimum version. * @type bool $plan_check Should we check for a specific plan before registering the block. * } - * @param string $metadata_dir TODO: define. + * @param string $metadata_dir Directory holding the block.json metadata file. * * @return WP_Block_Type|false The registered block type on success, or false on failure. */ diff --git a/projects/plugins/jetpack/tools/webpack.config.extensions.js b/projects/plugins/jetpack/tools/webpack.config.extensions.js index 66719c0604be..7c68f86ef3ea 100644 --- a/projects/plugins/jetpack/tools/webpack.config.extensions.js +++ b/projects/plugins/jetpack/tools/webpack.config.extensions.js @@ -293,6 +293,7 @@ module.exports = [ entry: { ...editorSingleBlocksScripts, ...viewSingleBlocksScripts, + 'editor-core': path.join( __dirname, '../extensions/editor.js' ), }, plugins: [ new CopyWebpackPlugin( { @@ -317,10 +318,4 @@ module.exports = [ } ), ], }, - { - ...sharedWebpackConfig, - entry: { - 'editor-core': path.join( __dirname, '../extensions/editor.js' ), - }, - }, ]; diff --git a/tools/docker/jetpack-docker-config-default.yml b/tools/docker/jetpack-docker-config-default.yml index 63ac16823faa..10ef36b238d4 100644 --- a/tools/docker/jetpack-docker-config-default.yml +++ b/tools/docker/jetpack-docker-config-default.yml @@ -7,6 +7,7 @@ default: tools/docker/wordpress: /var/www/html .: /usr/local/src/jetpack-monorepo tools/docker/mu-plugins: /var/www/html/wp-content/mu-plugins + /Users/andrewlysenko/Automattic/gutenberg: /var/www/html/wp-content/plugins/gutenberg # Extra configuration (none by default). Anything set under this key will be written out as # an extra docker-compose configuration file. From 21d2a83f6892798cb29cf69eb79aac8d5837bcd3 Mon Sep 17 00:00:00 2001 From: Andrii Lysenko Date: Tue, 25 Jul 2023 12:08:50 -0700 Subject: [PATCH 7/7] update: remove this for now. We can add it back if necessary --- .../jetpack/extensions/blocks/business-hours-single/block.json | 3 +-- .../jetpack/extensions/blocks/business-hours-single/view.js | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) delete mode 100644 projects/plugins/jetpack/extensions/blocks/business-hours-single/view.js diff --git a/projects/plugins/jetpack/extensions/blocks/business-hours-single/block.json b/projects/plugins/jetpack/extensions/blocks/business-hours-single/block.json index b8dfdf29c67c..2363268afaf4 100644 --- a/projects/plugins/jetpack/extensions/blocks/business-hours-single/block.json +++ b/projects/plugins/jetpack/extensions/blocks/business-hours-single/block.json @@ -24,6 +24,5 @@ "align": [ "wide", "full" ] }, "editorScript": "file:./editor.js", - "editorStyle": "file:./editor.css", - "style": "file:./view.css" + "editorStyle": "file:./editor.css" } diff --git a/projects/plugins/jetpack/extensions/blocks/business-hours-single/view.js b/projects/plugins/jetpack/extensions/blocks/business-hours-single/view.js deleted file mode 100644 index 423b033ce717..000000000000 --- a/projects/plugins/jetpack/extensions/blocks/business-hours-single/view.js +++ /dev/null @@ -1 +0,0 @@ -import './style.scss';