From e42f6f62484a1e2f2281fa2904f137614caad08b Mon Sep 17 00:00:00 2001 From: Alec Geatches Date: Tue, 20 Sep 2022 17:03:40 +0800 Subject: [PATCH 01/16] Add blockEditor.useSetting.before hook to useSetting --- .../src/components/use-setting/index.js | 63 ++++++++++++------- 1 file changed, 39 insertions(+), 24 deletions(-) diff --git a/packages/block-editor/src/components/use-setting/index.js b/packages/block-editor/src/components/use-setting/index.js index 3d37a85de16934..2a419a297f4e99 100644 --- a/packages/block-editor/src/components/use-setting/index.js +++ b/packages/block-editor/src/components/use-setting/index.js @@ -11,6 +11,7 @@ import { __EXPERIMENTAL_PATHS_WITH_MERGE as PATHS_WITH_MERGE, hasBlockSupport, } from '@wordpress/blocks'; +import { applyFilters } from '@wordpress/hooks'; /** * Internal dependencies @@ -127,33 +128,47 @@ export default function useSetting( path ) { ...select( blockEditorStore ).getBlockParents( clientId ), clientId, // The current block is added last, so it overwrites any ancestor. ]; - candidates.forEach( ( candidateClientId ) => { - const candidateBlockName = - select( blockEditorStore ).getBlockName( - candidateClientId - ); - if ( - hasBlockSupport( - candidateBlockName, - '__experimentalSettings', - false - ) - ) { - const candidateAtts = - select( blockEditorStore ).getBlockAttributes( + + result = applyFilters( + 'blockEditor.useSetting.before', + result, + blockName, + normalizedPath, + candidates + ); + + if ( result !== undefined ) { + candidates.forEach( ( candidateClientId ) => { + const candidateBlockName = + select( blockEditorStore ).getBlockName( candidateClientId ); - const candidateResult = - get( - candidateAtts, - `settings.blocks.${ blockName }.${ normalizedPath }` - ) ?? - get( candidateAtts, `settings.${ normalizedPath }` ); - if ( candidateResult !== undefined ) { - result = candidateResult; + if ( + hasBlockSupport( + candidateBlockName, + '__experimentalSettings', + false + ) + ) { + const candidateAtts = + select( blockEditorStore ).getBlockAttributes( + candidateClientId + ); + const candidateResult = + get( + candidateAtts, + `settings.blocks.${ blockName }.${ normalizedPath }` + ) ?? + get( + candidateAtts, + `settings.${ normalizedPath }` + ); + if ( candidateResult !== undefined ) { + result = candidateResult; + } } - } - } ); + } ); + } // 2. Fall back to the settings from the block editor store (__experimentalFeatures). const settings = select( blockEditorStore ).getSettings(); From e4d7ed0f4c865402726641d806ba6b84dbced454 Mon Sep 17 00:00:00 2001 From: ingeniumed Date: Tue, 27 Sep 2022 17:19:04 +1000 Subject: [PATCH 02/16] Add a new filter for sanitizing on the php side --- .../wordpress-6.1/class-wp-theme-json-6-1.php | 3 +- package-lock.json | 95 +++++++++++-------- 2 files changed, 55 insertions(+), 43 deletions(-) diff --git a/lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php b/lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php index b7c40a4c40cdd2..56175af3ffa118 100644 --- a/lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php +++ b/lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php @@ -233,7 +233,8 @@ protected static function sanitize( $input, $valid_block_names, $valid_element_n } } - return $output; + // This filter allows us to modify the settings that have been understood from the theme, in order to bake in support for features like nested block settings. + return apply_filters( 'gutenberg_theme_json_sanitize', $output, $schema, $valid_block_names, $input ); } /** diff --git a/package-lock.json b/package-lock.json index 69f456723c5f08..cd9d600f0a1f5f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18701,7 +18701,7 @@ "app-root-dir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/app-root-dir/-/app-root-dir-1.0.2.tgz", - "integrity": "sha1-OBh+wt6nV3//Az/8sSFyaS/24Rg=", + "integrity": "sha512-jlpIfsOoNoafl92Sz//64uQHGSyMrD2vYG5d8o2a4qGvyNCvXur7bzIsWtAC/6flI2RYAp3kv8rsfBtaLm7w0g==", "dev": true }, "app-root-path": { @@ -22209,6 +22209,12 @@ "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==", "dev": true }, + "follow-redirects": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz", + "integrity": "sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg==", + "dev": true + }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -22542,7 +22548,8 @@ "immediate": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", - "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=" + "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=", + "dev": true }, "inflight": { "version": "1.0.6", @@ -22794,6 +22801,35 @@ "verror": "1.10.0" } }, + "jszip": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.6.0.tgz", + "integrity": "sha512-jgnQoG9LKnWO3mnVNBnfhkh0QknICd1FGSrXcgrl67zioyJ4wgx25o9ZqwNtrROSflGBCGYnJfjrIyRIby1OoQ==", + "dev": true, + "requires": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "set-immediate-shim": "~1.0.1" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + } + } + }, "keypather": { "version": "1.10.2", "resolved": "https://registry.npmjs.org/keypather/-/keypather-1.10.2.tgz", @@ -22866,6 +22902,7 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "dev": true, "requires": { "immediate": "~3.0.5" } @@ -24216,7 +24253,8 @@ "set-immediate-shim": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", - "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=" + "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", + "dev": true }, "setprototypeof": { "version": "1.1.1", @@ -26842,7 +26880,7 @@ "babel-plugin-add-react-displayname": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/babel-plugin-add-react-displayname/-/babel-plugin-add-react-displayname-0.0.5.tgz", - "integrity": "sha1-M51M3be2X9YtHfnbn+BN4TQSK9U=", + "integrity": "sha512-LY3+Y0XVDYcShHHorshrDbt4KFWL4bSeniCtl4SYZbask+Syngk1uMPCeN9+nSiZo6zX5s0RTq/J9Pnaaf/KHw==", "dev": true }, "babel-plugin-apply-mdx-type-prop": { @@ -27265,7 +27303,7 @@ "batch-processor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/batch-processor/-/batch-processor-1.0.0.tgz", - "integrity": "sha1-dclcMrdI4IUNEMKxaPa9vpiRrOg=", + "integrity": "sha512-xoLQD8gmmR32MeuBHgH0Tzd5PuSZx71ZsbhVxOCRbgktZEPe4SQy7s9Z50uPp0F/f7iw2XmkHN2xkgbMfckMDA==", "dev": true }, "bcrypt-pbkdf": { @@ -30547,7 +30585,7 @@ "css.escape": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", - "integrity": "sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s=", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", "dev": true }, "cssesc": { @@ -36671,7 +36709,7 @@ "has-glob": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-glob/-/has-glob-1.0.0.tgz", - "integrity": "sha1-mqqe7b/7G6OZCnsAEPtnjuAIEgc=", + "integrity": "sha512-D+8A457fBShSEI3tFCj65PAbT++5sKiFtdCdOam0gnfBgw9D277OERk+HM9qYJXmdVLZ/znez10SqHN0BBQ50g==", "dev": true, "requires": { "is-glob": "^3.0.0" @@ -36680,7 +36718,7 @@ "is-glob": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", "dev": true, "requires": { "is-extglob": "^2.1.0" @@ -37546,12 +37584,6 @@ "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.6.3.tgz", "integrity": "sha512-47xSUiQioGaB96nqtp5/q55m0aBQSQdyIloMOc/x+QVTDZLNmXE892IIDrJ0hM1A5vcNUDD5tDffkSP5lCaIIA==" }, - "immediate": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", - "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", - "dev": true - }, "import-fresh": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.1.0.tgz", @@ -38500,7 +38532,7 @@ "is-window": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-window/-/is-window-1.0.2.tgz", - "integrity": "sha1-LIlspT25feRdPDMTOmXYyfVjSA0=", + "integrity": "sha512-uj00kdXyZb9t9RcAUAwMZAnkBUwdYGhYlt7djMXhfyhUCzwNba50tIiBKR7q0l7tdoBtFVw/3JmLY6fI3rmZmg==", "dev": true }, "is-windows": { @@ -41877,7 +41909,7 @@ "js-string-escape": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz", - "integrity": "sha1-4mJbrbwNZ8dTPp7cEGjFh65BN+8=", + "integrity": "sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg==", "dev": true }, "js-tokens": { @@ -42356,18 +42388,6 @@ } } }, - "jszip": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", - "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", - "dev": true, - "requires": { - "lie": "~3.3.0", - "pako": "~1.0.2", - "readable-stream": "~2.3.6", - "setimmediate": "^1.0.5" - } - }, "junk": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/junk/-/junk-3.1.0.tgz", @@ -42506,15 +42526,6 @@ "type-check": "~0.3.2" } }, - "lie": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", - "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", - "dev": true, - "requires": { - "immediate": "~3.0.5" - } - }, "lilconfig": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.3.tgz", @@ -43426,7 +43437,7 @@ "lz-string": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz", - "integrity": "sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY=", + "integrity": "sha512-0ckx7ZHRPqb0oUm8zNr+90mtf9DQB60H1wMCjBtfi62Kl3a7JbHob6gA2bC+xRvZoOL+1hzUK8jeuEIQE8svEQ==", "dev": true }, "macos-release": { @@ -46762,7 +46773,7 @@ "num2fraction": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", - "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=", + "integrity": "sha512-Y1wZESM7VUThYY+4W+X4ySH2maqcA+p7UR+w8VWNWVAd6lwuXXWz/w/Cz43J/dI2I+PS6wD5N+bJUF+gjWvIqg==", "dev": true }, "number-is-nan": { @@ -47841,7 +47852,7 @@ "p-defer": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", - "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", + "integrity": "sha512-wB3wfAxZpk2AzOfUMJNL+d36xothRSyj8EXOa4f6GMqYDN9BJaaSISbsk+wS9abmnebVw95C2Kb5t85UmpCxuw==", "dev": true }, "p-event": { @@ -49180,7 +49191,7 @@ "pretty-hrtime": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", - "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=", + "integrity": "sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A==", "dev": true }, "prismjs": { @@ -51397,7 +51408,7 @@ "relateurl": { "version": "0.2.7", "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=", + "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", "dev": true }, "remark": { From c5a4c1a55fa51099ec1b6b3750ab7fa51417983d Mon Sep 17 00:00:00 2001 From: ingeniumed Date: Wed, 28 Sep 2022 14:12:28 +1000 Subject: [PATCH 03/16] Add in a filter for the get_Settings_nodes for CSS override --- .../wordpress-6.1/class-wp-theme-json-6-1.php | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php b/lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php index 56175af3ffa118..519218ef105a92 100644 --- a/lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php +++ b/lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php @@ -144,6 +144,61 @@ public static function get_element_class_name( $element ) { return array_key_exists( $element, static::__EXPERIMENTAL_ELEMENT_CLASS_NAMES ) ? static::__EXPERIMENTAL_ELEMENT_CLASS_NAMES[ $element ] : ''; } + /** + * Builds metadata for the setting nodes, which returns in the form of: + * + * [ + * [ + * 'path' => ['path', 'to', 'some', 'node' ], + * 'selector' => 'CSS selector for some node' + * ], + * [ + * 'path' => [ 'path', 'to', 'other', 'node' ], + * 'selector' => 'CSS selector for other node' + * ], + * ] + * + * @since 5.8.0 + * + * @param array $theme_json The tree to extract setting nodes from. + * @param array $selectors List of selectors per block. + * @return array + */ + protected static function get_setting_nodes( $theme_json, $selectors = array() ) { + $nodes = array(); + if ( ! isset( $theme_json['settings'] ) ) { + return $nodes; + } + + // Top-level. + $nodes[] = array( + 'path' => array( 'settings' ), + 'selector' => static::ROOT_BLOCK_SELECTOR, + ); + + // Calculate paths for blocks. + if ( ! isset( $theme_json['settings']['blocks'] ) ) { + return $nodes; + } + + $valid_block_names = array_keys( static::get_blocks_metadata() ); + + foreach ( $theme_json['settings']['blocks'] as $name => $node ) { + $selector = null; + if ( isset( $selectors[ $name ]['selector'] ) ) { + $selector = $selectors[ $name ]['selector']; + } + + $nodes[] = array( + 'path' => array( 'settings', 'blocks', $name ), + 'selector' => $selector, + ); + } + + // This filter allows us to modify the settings for each node that have been understood from the theme, in order to bake in support for features like nested block settings. + return apply_filters( 'gutenberg_theme_json_get_settings_nodes', $nodes, $theme_json, $selectors, $valid_block_names ); + } + /** * Sanitizes the input according to the schemas. * From 36e7d371d9ee602a69bf7e969d4c7df902ba7480 Mon Sep 17 00:00:00 2001 From: ingeniumed Date: Wed, 28 Sep 2022 14:20:06 +1000 Subject: [PATCH 04/16] Add newline back for package-lock --- package-lock.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index 86e1a937184c0a..1d189002ecf0c5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -61380,4 +61380,4 @@ "dev": true } } -} \ No newline at end of file +} From b6dc84fe1a9f655466eb18d2d3dce179e9048ee0 Mon Sep 17 00:00:00 2001 From: Alec Geatches Date: Tue, 20 Sep 2022 17:03:40 +0800 Subject: [PATCH 05/16] Add blockEditor.useSetting.before hook to useSetting --- .../block-editor/src/components/use-setting/index.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/packages/block-editor/src/components/use-setting/index.js b/packages/block-editor/src/components/use-setting/index.js index 93932be57c4791..7449d75025daca 100644 --- a/packages/block-editor/src/components/use-setting/index.js +++ b/packages/block-editor/src/components/use-setting/index.js @@ -139,7 +139,7 @@ export default function useSetting( path ) { candidates ); - if ( result != undefined ) { + if ( result !== undefined ) { for ( const candidateClientId of candidates ) { const candidateBlockName = select( blockEditorStore ).getBlockName( @@ -156,12 +156,10 @@ export default function useSetting( path ) { select( blockEditorStore ).getBlockAttributes( candidateClientId ); - result = - get( - candidateAtts, - `settings.blocks.${ blockName }.${ normalizedPath }` - ) ?? - get( candidateAtts, `settings.${ normalizedPath }` ); + result = get( + candidateAtts, + `settings.${ normalizedPath }` + ); if ( result !== undefined ) { // Stop the search for more distant ancestors and move on. break; From f9e0eae0240d3bf77f4b40c492d59aba51108806 Mon Sep 17 00:00:00 2001 From: Alec Geatches Date: Thu, 29 Sep 2022 10:04:09 +0800 Subject: [PATCH 06/16] Fix useSetting merge mistake --- .../src/components/use-setting/index.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/block-editor/src/components/use-setting/index.js b/packages/block-editor/src/components/use-setting/index.js index 7449d75025daca..6d188517d9e8c4 100644 --- a/packages/block-editor/src/components/use-setting/index.js +++ b/packages/block-editor/src/components/use-setting/index.js @@ -156,10 +156,15 @@ export default function useSetting( path ) { select( blockEditorStore ).getBlockAttributes( candidateClientId ); - result = get( - candidateAtts, - `settings.${ normalizedPath }` - ); + result = + get( + candidateAtts, + `settings.blocks.${ blockName }.${ normalizedPath }` + ) ?? + get( + candidateAtts, + `settings.${ normalizedPath }` + ); if ( result !== undefined ) { // Stop the search for more distant ancestors and move on. break; From 6313e6501c16d6cb07e701f2ca4a6ebeec503457 Mon Sep 17 00:00:00 2001 From: Alec Geatches Date: Fri, 30 Sep 2022 10:48:43 +0800 Subject: [PATCH 07/16] Make get_blocks_metadata public for selector access --- lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php b/lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php index 519218ef105a92..bcc274f007a2b2 100644 --- a/lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php +++ b/lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php @@ -468,7 +468,7 @@ protected static function append_to_selector( $selector, $to_append, $position = * * @return array Block metadata. */ - protected static function get_blocks_metadata() { + public static function get_blocks_metadata() { if ( null !== static::$blocks_metadata ) { return static::$blocks_metadata; } From ca77c4644b56f5760a6e480f6bc786d674c18efe Mon Sep 17 00:00:00 2001 From: ingeniumed Date: Tue, 4 Oct 2022 14:13:07 +1100 Subject: [PATCH 08/16] Remove the previous way of doing the nesting via filters in sanitize and settings --- .../wordpress-6.1/class-wp-theme-json-6-1.php | 58 +------------------ 1 file changed, 1 insertion(+), 57 deletions(-) diff --git a/lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php b/lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php index 880aea756d3e30..67ec1b7195f87e 100644 --- a/lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php +++ b/lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php @@ -144,61 +144,6 @@ public static function get_element_class_name( $element ) { return array_key_exists( $element, static::__EXPERIMENTAL_ELEMENT_CLASS_NAMES ) ? static::__EXPERIMENTAL_ELEMENT_CLASS_NAMES[ $element ] : ''; } - /** - * Builds metadata for the setting nodes, which returns in the form of: - * - * [ - * [ - * 'path' => ['path', 'to', 'some', 'node' ], - * 'selector' => 'CSS selector for some node' - * ], - * [ - * 'path' => [ 'path', 'to', 'other', 'node' ], - * 'selector' => 'CSS selector for other node' - * ], - * ] - * - * @since 5.8.0 - * - * @param array $theme_json The tree to extract setting nodes from. - * @param array $selectors List of selectors per block. - * @return array - */ - protected static function get_setting_nodes( $theme_json, $selectors = array() ) { - $nodes = array(); - if ( ! isset( $theme_json['settings'] ) ) { - return $nodes; - } - - // Top-level. - $nodes[] = array( - 'path' => array( 'settings' ), - 'selector' => static::ROOT_BLOCK_SELECTOR, - ); - - // Calculate paths for blocks. - if ( ! isset( $theme_json['settings']['blocks'] ) ) { - return $nodes; - } - - $valid_block_names = array_keys( static::get_blocks_metadata() ); - - foreach ( $theme_json['settings']['blocks'] as $name => $node ) { - $selector = null; - if ( isset( $selectors[ $name ]['selector'] ) ) { - $selector = $selectors[ $name ]['selector']; - } - - $nodes[] = array( - 'path' => array( 'settings', 'blocks', $name ), - 'selector' => $selector, - ); - } - - // This filter allows us to modify the settings for each node that have been understood from the theme, in order to bake in support for features like nested block settings. - return apply_filters( 'gutenberg_theme_json_get_settings_nodes', $nodes, $theme_json, $selectors, $valid_block_names ); - } - /** * Sanitizes the input according to the schemas. * @@ -288,8 +233,7 @@ protected static function sanitize( $input, $valid_block_names, $valid_element_n } } - // This filter allows us to modify the settings that have been understood from the theme, in order to bake in support for features like nested block settings. - return apply_filters( 'gutenberg_theme_json_sanitize', $output, $schema, $valid_block_names, $input ); + return $output; } /** From 08e6ca4234d759fdfbfb4041fda9939176caa039 Mon Sep 17 00:00:00 2001 From: Alec Geatches Date: Tue, 18 Oct 2022 11:24:58 +0800 Subject: [PATCH 09/16] Add useSetting tests for hook override --- .../src/components/use-setting/test/index.js | 111 ++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 packages/block-editor/src/components/use-setting/test/index.js diff --git a/packages/block-editor/src/components/use-setting/test/index.js b/packages/block-editor/src/components/use-setting/test/index.js new file mode 100644 index 00000000000000..9a61f7c26b51d9 --- /dev/null +++ b/packages/block-editor/src/components/use-setting/test/index.js @@ -0,0 +1,111 @@ +/** + * WordPress dependencies + */ +import { addFilter, removeFilter } from '@wordpress/hooks'; +import { useSelect } from '@wordpress/data'; + +/** + * Internal dependencies + */ +import useSetting from '..'; +import * as BlockEditContext from '../../block-edit/context'; + +// Mock useSelect() functions used by useSetting() +jest.mock( '@wordpress/data/src/components/use-select' ); + +let selectMock = {}; +const setupSelectMock = () => { + selectMock = { + getSettings: () => ( {} ), + getBlockParents: () => [], + getBlockName: () => '', + }; +}; + +useSelect.mockImplementation( ( callback ) => callback( () => selectMock ) ); + +const mockSettings = ( settings ) => { + selectMock.getSettings = () => ( { + __experimentalFeatures: settings, + } ); +}; + +const mockBlockName = ( blockClientId, blockName ) => { + selectMock.getBlockName = ( clientId ) => { + if ( clientId === blockClientId ) { + return blockName; + } + }; +}; + +const mockCurrentBlockContext = ( + blockContext = { name: '', isSelected: false } +) => { + if ( blockContext.name !== '' && blockContext.clientID !== undefined ) { + mockBlockName( blockContext.clientID, blockContext.name ); + } + + jest.spyOn( BlockEditContext, 'useBlockEditContext' ).mockReturnValue( + blockContext + ); +}; + +describe( 'useSetting', () => { + beforeEach( () => { + setupSelectMock(); + mockCurrentBlockContext( {} ); + } ); + + it( 'uses block setting', () => { + mockSettings( { + blocks: { + 'core/test-block': { + layout: { + contentSize: '840px', + }, + }, + }, + } ); + + mockCurrentBlockContext( { + name: 'core/test-block', + } ); + + expect( useSetting( 'layout.contentSize' ) ).toBe( '840px' ); + } ); + + it( 'uses hook override', () => { + mockSettings( { + blocks: { + 'core/test-block': { + layout: { + contentSize: '840px', + }, + }, + }, + } ); + + mockCurrentBlockContext( { + name: 'core/test-block', + } ); + + addFilter( + 'blockEditor.useSetting.before', + 'test/useSetting.before', + ( result, blockName ) => { + if ( blockName === 'core/test-block' ) { + return '960px'; + } + + return result; + } + ); + + expect( useSetting( 'layout.contentSize' ) ).toBe( '960px' ); + + removeFilter( + 'blockEditor.useSetting.before', + 'test/useSetting.before' + ); + } ); +} ); From a345c49c4eaaa8ae800724492a9d5c0643ea7fe9 Mon Sep 17 00:00:00 2001 From: Alec Geatches Date: Tue, 18 Oct 2022 11:29:59 +0800 Subject: [PATCH 10/16] Simplify block context mocking --- .../src/components/use-setting/test/index.js | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/packages/block-editor/src/components/use-setting/test/index.js b/packages/block-editor/src/components/use-setting/test/index.js index 9a61f7c26b51d9..f27d9447b96765 100644 --- a/packages/block-editor/src/components/use-setting/test/index.js +++ b/packages/block-editor/src/components/use-setting/test/index.js @@ -17,7 +17,7 @@ let selectMock = {}; const setupSelectMock = () => { selectMock = { getSettings: () => ( {} ), - getBlockParents: () => [], + // getBlockParents: () => [], getBlockName: () => '', }; }; @@ -30,21 +30,9 @@ const mockSettings = ( settings ) => { } ); }; -const mockBlockName = ( blockClientId, blockName ) => { - selectMock.getBlockName = ( clientId ) => { - if ( clientId === blockClientId ) { - return blockName; - } - }; -}; - const mockCurrentBlockContext = ( blockContext = { name: '', isSelected: false } ) => { - if ( blockContext.name !== '' && blockContext.clientID !== undefined ) { - mockBlockName( blockContext.clientID, blockContext.name ); - } - jest.spyOn( BlockEditContext, 'useBlockEditContext' ).mockReturnValue( blockContext ); @@ -53,7 +41,7 @@ const mockCurrentBlockContext = ( describe( 'useSetting', () => { beforeEach( () => { setupSelectMock(); - mockCurrentBlockContext( {} ); + mockCurrentBlockContext(); } ); it( 'uses block setting', () => { From e736f6ed1eeb1d0d28102cacff82425e93819b52 Mon Sep 17 00:00:00 2001 From: Alec Geatches Date: Tue, 18 Oct 2022 11:33:14 +0800 Subject: [PATCH 11/16] Remove debug code, add test description --- .../block-editor/src/components/use-setting/test/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/block-editor/src/components/use-setting/test/index.js b/packages/block-editor/src/components/use-setting/test/index.js index f27d9447b96765..e175db98c361bc 100644 --- a/packages/block-editor/src/components/use-setting/test/index.js +++ b/packages/block-editor/src/components/use-setting/test/index.js @@ -17,7 +17,7 @@ let selectMock = {}; const setupSelectMock = () => { selectMock = { getSettings: () => ( {} ), - // getBlockParents: () => [], + getBlockParents: () => [], getBlockName: () => '', }; }; @@ -62,7 +62,7 @@ describe( 'useSetting', () => { expect( useSetting( 'layout.contentSize' ) ).toBe( '840px' ); } ); - it( 'uses hook override', () => { + it( 'uses blockEditor.useSetting.before hook override', () => { mockSettings( { blocks: { 'core/test-block': { From d76d2968bf18a3dd48d3ac09a611e861c1fed497 Mon Sep 17 00:00:00 2001 From: ingeniumed Date: Thu, 3 Nov 2022 18:42:18 +1100 Subject: [PATCH 12/16] Remove the previously exposed method for metadata of a block, do an early return from the filter and simplify down the arguments in the filter --- .../wordpress-6.1/class-wp-theme-json-6-1.php | 2 +- .../src/components/use-setting/index.js | 65 +++++++++---------- 2 files changed, 33 insertions(+), 34 deletions(-) diff --git a/lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php b/lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php index 4ab4a7ae38a4c7..8e12d99a074905 100644 --- a/lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php +++ b/lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php @@ -449,7 +449,7 @@ protected static function append_to_selector( $selector, $to_append, $position = * * @return array Block metadata. */ - public static function get_blocks_metadata() { + protected static function get_blocks_metadata() { if ( null !== static::$blocks_metadata ) { return static::$blocks_metadata; } diff --git a/packages/block-editor/src/components/use-setting/index.js b/packages/block-editor/src/components/use-setting/index.js index 6d188517d9e8c4..a7ae3ae4a5c7d8 100644 --- a/packages/block-editor/src/components/use-setting/index.js +++ b/packages/block-editor/src/components/use-setting/index.js @@ -119,8 +119,6 @@ export default function useSetting( path ) { let result; - const normalizedPath = removeCustomPrefixes( path ); - // 1. Take settings from the block instance or its ancestors. // Start from the current block and work our way up the ancestors. const candidates = [ @@ -134,41 +132,42 @@ export default function useSetting( path ) { result = applyFilters( 'blockEditor.useSetting.before', result, - blockName, - normalizedPath, - candidates + path, + clientId, + blockName ); - if ( result !== undefined ) { - for ( const candidateClientId of candidates ) { - const candidateBlockName = - select( blockEditorStore ).getBlockName( + if ( undefined !== result ) { + return result; + } + + const normalizedPath = removeCustomPrefixes( path ); + + for ( const candidateClientId of candidates ) { + const candidateBlockName = + select( blockEditorStore ).getBlockName( + candidateClientId + ); + if ( + hasBlockSupport( + candidateBlockName, + '__experimentalSettings', + false + ) + ) { + const candidateAtts = + select( blockEditorStore ).getBlockAttributes( candidateClientId ); - if ( - hasBlockSupport( - candidateBlockName, - '__experimentalSettings', - false - ) - ) { - const candidateAtts = - select( blockEditorStore ).getBlockAttributes( - candidateClientId - ); - result = - get( - candidateAtts, - `settings.blocks.${ blockName }.${ normalizedPath }` - ) ?? - get( - candidateAtts, - `settings.${ normalizedPath }` - ); - if ( result !== undefined ) { - // Stop the search for more distant ancestors and move on. - break; - } + result = + get( + candidateAtts, + `settings.blocks.${ blockName }.${ normalizedPath }` + ) ?? + get( candidateAtts, `settings.${ normalizedPath }` ); + if ( result !== undefined ) { + // Stop the search for more distant ancestors and move on. + break; } } } From 6c7858dbfe0393fe5ab1ddccef2cc419316999c3 Mon Sep 17 00:00:00 2001 From: ingeniumed Date: Thu, 3 Nov 2022 18:56:35 +1100 Subject: [PATCH 13/16] Fix the failing test by adding in all the parameters expected --- packages/block-editor/src/components/use-setting/test/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-editor/src/components/use-setting/test/index.js b/packages/block-editor/src/components/use-setting/test/index.js index e175db98c361bc..1c625c8a1969c4 100644 --- a/packages/block-editor/src/components/use-setting/test/index.js +++ b/packages/block-editor/src/components/use-setting/test/index.js @@ -80,7 +80,7 @@ describe( 'useSetting', () => { addFilter( 'blockEditor.useSetting.before', 'test/useSetting.before', - ( result, blockName ) => { + ( result, path, clientId, blockName ) => { if ( blockName === 'core/test-block' ) { return '960px'; } From d00aab819702c6c45e959886f6c9d1e4e37da090 Mon Sep 17 00:00:00 2001 From: Alec Geatches Date: Thu, 24 Nov 2022 14:19:19 +0800 Subject: [PATCH 14/16] Rerun tests From 8cc0e27c64a0909147f11d77b3d387a5fbc1e91b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Fri, 2 Dec 2022 15:27:41 +0100 Subject: [PATCH 15/16] Reorder so it returns early if it found a match --- .../src/components/use-setting/index.js | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/packages/block-editor/src/components/use-setting/index.js b/packages/block-editor/src/components/use-setting/index.js index e0af78d60c6327..42316d3151f4b4 100644 --- a/packages/block-editor/src/components/use-setting/index.js +++ b/packages/block-editor/src/components/use-setting/index.js @@ -123,21 +123,10 @@ export default function useSetting( path ) { return undefined; } - let result; - - // 1. Take settings from the block instance or its ancestors. - // Start from the current block and work our way up the ancestors. - const candidates = [ - clientId, - ...select( blockEditorStore ).getBlockParents( - clientId, - /* ascending */ true - ), - ]; - - result = applyFilters( + // 0. Allow third-parties to filter into the block's settings at runtime. + let result = applyFilters( 'blockEditor.useSetting.before', - result, + undefined, path, clientId, blockName @@ -149,6 +138,16 @@ export default function useSetting( path ) { const normalizedPath = removeCustomPrefixes( path ); + // 1. Take settings from the block instance or its ancestors. + // Start from the current block and work our way up the ancestors. + const candidates = [ + clientId, + ...select( blockEditorStore ).getBlockParents( + clientId, + /* ascending */ true + ), + ]; + for ( const candidateClientId of candidates ) { const candidateBlockName = select( blockEditorStore ).getBlockName( From dc80804d4ae7f6dca494dd7b1a59aef5a13db58b Mon Sep 17 00:00:00 2001 From: Gopal Krishnan Date: Mon, 5 Dec 2022 15:58:59 +1100 Subject: [PATCH 16/16] Change the wording for what the filter allows in the comment Co-authored-by: Aaron Robertshaw <60436221+aaronrobertshaw@users.noreply.github.com> --- packages/block-editor/src/components/use-setting/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-editor/src/components/use-setting/index.js b/packages/block-editor/src/components/use-setting/index.js index 42316d3151f4b4..add0b7ff6e08db 100644 --- a/packages/block-editor/src/components/use-setting/index.js +++ b/packages/block-editor/src/components/use-setting/index.js @@ -123,7 +123,7 @@ export default function useSetting( path ) { return undefined; } - // 0. Allow third-parties to filter into the block's settings at runtime. + // 0. Allow third parties to filter the block's settings at runtime. let result = applyFilters( 'blockEditor.useSetting.before', undefined,