@wordpress/e2e-tests 9.5.1-next.v.202602271551.0 → 9.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/e2e-tests",
3
- "version": "9.5.1-next.v.202602271551.0+464abe399",
3
+ "version": "9.5.1",
4
4
  "description": "Test plugins and mu-plugins for E2E tests in WordPress.",
5
5
  "author": "The WordPress Contributors",
6
6
  "license": "GPL-2.0-or-later",
@@ -24,8 +24,8 @@
24
24
  "npm": ">=8.19.2"
25
25
  },
26
26
  "dependencies": {
27
- "@wordpress/interactivity": "^6.40.1-next.v.202602271551.0+464abe399",
28
- "@wordpress/interactivity-router": "^2.40.1-next.v.202602271551.0+464abe399"
27
+ "@wordpress/interactivity": "^6.40.1",
28
+ "@wordpress/interactivity-router": "^2.40.1"
29
29
  },
30
30
  "peerDependencies": {
31
31
  "jest": ">=29",
@@ -36,5 +36,5 @@
36
36
  "publishConfig": {
37
37
  "access": "public"
38
38
  },
39
- "gitHead": "95aa7055a5757219e2d96a91efc69f7dd1b2d4c3"
39
+ "gitHead": "adb6623c9f32490cfc73c7ac7f122578c1f10c65"
40
40
  }
@@ -172,7 +172,7 @@ function gutenberg_test_block_bindings_registration() {
172
172
  'type' => 'number',
173
173
  'show_in_rest' => true,
174
174
  'single' => true,
175
- 'default' => 5.5,
175
+ 'default' => 0.5,
176
176
  )
177
177
  );
178
178
  register_meta(
@@ -183,7 +183,7 @@ function gutenberg_test_block_bindings_registration() {
183
183
  'type' => 'integer',
184
184
  'show_in_rest' => true,
185
185
  'single' => true,
186
- 'default' => 5,
186
+ 'default' => 3,
187
187
  )
188
188
  );
189
189
  register_meta(
@@ -0,0 +1,112 @@
1
+ <?php
2
+ /**
3
+ * Plugin Name: Gutenberg Test Connectors Capability Restriction
4
+ * Plugin URI: https://github.com/WordPress/gutenberg
5
+ * Author: Gutenberg Team
6
+ *
7
+ * @package gutenberg-test-connectors-capability-restriction
8
+ */
9
+
10
+ add_action(
11
+ 'init',
12
+ static function () {
13
+ register_setting(
14
+ 'general',
15
+ 'gutenberg_test_cap_restriction',
16
+ array(
17
+ 'type' => 'string',
18
+ 'default' => '',
19
+ 'show_in_rest' => true,
20
+ )
21
+ );
22
+ }
23
+ );
24
+
25
+ register_activation_hook(
26
+ __FILE__,
27
+ static function () {
28
+ delete_option( 'gutenberg_test_cap_restriction' );
29
+ }
30
+ );
31
+
32
+ register_deactivation_hook(
33
+ __FILE__,
34
+ static function () {
35
+ delete_option( 'gutenberg_test_cap_restriction' );
36
+ }
37
+ );
38
+
39
+ add_action(
40
+ 'wp_connectors_init',
41
+ static function ( WP_Connector_Registry $registry ) {
42
+ $registry->register(
43
+ 'test_install_required_connector',
44
+ array(
45
+ 'name' => 'Test Install Required Connector',
46
+ 'description' => 'A connector backed by a plugin that is not installed.',
47
+ 'type' => 'ai_provider',
48
+ 'plugin' => array(
49
+ 'file' => 'gutenberg-test-connectors-never-installed/plugin.php',
50
+ 'is_active' => '__return_false',
51
+ ),
52
+ 'authentication' => array(
53
+ 'method' => 'api_key',
54
+ 'setting_name' => 'gutenberg_test_install_required_connector_api_key',
55
+ ),
56
+ )
57
+ );
58
+
59
+ $registry->register(
60
+ 'test_activate_required_connector',
61
+ array(
62
+ 'name' => 'Test Activate Required Connector',
63
+ 'description' => 'A connector backed by an installed inactive plugin.',
64
+ 'type' => 'ai_provider',
65
+ 'plugin' => array(
66
+ 'file' => 'hello/hello.php',
67
+ 'is_active' => '__return_false',
68
+ ),
69
+ 'authentication' => array(
70
+ 'method' => 'api_key',
71
+ 'setting_name' => 'gutenberg_test_activate_required_connector_api_key',
72
+ ),
73
+ )
74
+ );
75
+ }
76
+ );
77
+
78
+ add_filter(
79
+ 'map_meta_cap',
80
+ static function ( $caps, $cap ) {
81
+ $restriction = get_option( 'gutenberg_test_cap_restriction', '' );
82
+
83
+ if ( empty( $restriction ) ) {
84
+ return $caps;
85
+ }
86
+
87
+ $blocked_caps = array();
88
+
89
+ switch ( $restriction ) {
90
+ case 'no_install':
91
+ $blocked_caps = array( 'install_plugins', 'upload_plugins' );
92
+ break;
93
+ case 'no_activate':
94
+ $blocked_caps = array( 'activate_plugins' );
95
+ break;
96
+ case 'no_install_activate':
97
+ $blocked_caps = array( 'install_plugins', 'upload_plugins', 'activate_plugins' );
98
+ break;
99
+ case 'disallow_file_mods':
100
+ $blocked_caps = array( 'install_plugins', 'upload_plugins', 'delete_plugins', 'update_plugins' );
101
+ break;
102
+ }
103
+
104
+ if ( in_array( $cap, $blocked_caps, true ) ) {
105
+ return array( 'do_not_allow' );
106
+ }
107
+
108
+ return $caps;
109
+ },
110
+ 10,
111
+ 2
112
+ );
@@ -0,0 +1,19 @@
1
+ <?php
2
+ /**
3
+ * Plugin Name: Gutenberg Test Connectors Empty State
4
+ * Plugin URI: https://github.com/WordPress/gutenberg
5
+ * Author: Gutenberg Team
6
+ *
7
+ * Removes the default connector data so the Connectors page renders its empty state.
8
+ *
9
+ * @package gutenberg-test-connectors-empty-state
10
+ */
11
+
12
+ // Remove the Gutenberg filter that provides default connector data.
13
+ add_action(
14
+ 'init',
15
+ static function () {
16
+ remove_filter( 'script_module_data_options-connectors-wp-admin', '_gutenberg_get_connector_script_module_data' );
17
+ },
18
+ PHP_INT_MAX
19
+ );
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Script module that demonstrates client-side connector registration.
3
+ *
4
+ * The server registers test_custom_service with its name and description.
5
+ * This module calls registerConnector() with the same slug to add a render
6
+ * function. The store merges both registrations, so the final connector
7
+ * combines the render function from JS with the metadata from PHP.
8
+ */
9
+
10
+ // eslint-disable-next-line import/no-extraneous-dependencies
11
+ import {
12
+ __experimentalRegisterConnector as registerConnector,
13
+ __experimentalConnectorItem as ConnectorItem,
14
+ } from '@wordpress/connectors';
15
+
16
+ const h = window.React.createElement;
17
+
18
+ // Register the render function for the connector.
19
+ registerConnector( 'test_custom_service', {
20
+ render: ( props ) =>
21
+ h(
22
+ ConnectorItem,
23
+ {
24
+ className: 'connector-item--test_custom_service',
25
+ name: props.name,
26
+ description: props.description,
27
+ logo: props.logo,
28
+ },
29
+ h(
30
+ 'p',
31
+ { className: 'test-custom-service-content' },
32
+ 'Custom rendered content for testing.'
33
+ )
34
+ ),
35
+ } );
36
+
37
+ // Registers a custom render for an api_key connector to verify that a
38
+ // subsequent default registration for the same slug does not replace it.
39
+ registerConnector( 'test_api_key_with_custom_render', {
40
+ render: ( props ) =>
41
+ h(
42
+ ConnectorItem,
43
+ {
44
+ className: 'connector-item--test_api_key_with_custom_render',
45
+ name: props.name,
46
+ description: props.description,
47
+ logo: props.logo,
48
+ },
49
+ h(
50
+ 'p',
51
+ { className: 'test-api-key-with-custom-render-content' },
52
+ 'Custom render survived registerDefaultConnectors().'
53
+ )
54
+ ),
55
+ } );
@@ -0,0 +1,84 @@
1
+ <?php
2
+ /**
3
+ * Plugin Name: Gutenberg Test Connectors JS Extensibility
4
+ * Plugin URI: https://github.com/WordPress/gutenberg
5
+ * Author: Gutenberg Team
6
+ *
7
+ * Registers three connectors on the server:
8
+ *
9
+ * 1. test_custom_service — also registered client-side via a script module using
10
+ * the merging strategy (two registerConnector calls with the same slug: one
11
+ * providing the render function, the other metadata).
12
+ * 2. test_server_only_service — server-only, with no client-side render function,
13
+ * so it should not display a card in the UI.
14
+ * 3. test_api_key_with_custom_render — an api_key connector whose JS render
15
+ * is registered before the default registrations run, used to verify that
16
+ * a subsequent default registration does not replace an existing render.
17
+ *
18
+ * @package gutenberg-test-connectors-js-extensibility
19
+ */
20
+
21
+ // Register two custom-type connectors for E2E testing.
22
+ add_action(
23
+ 'wp_connectors_init',
24
+ static function ( WP_Connector_Registry $registry ) {
25
+ $registry->register(
26
+ 'test_custom_service',
27
+ array(
28
+ 'name' => 'Test Custom Service',
29
+ 'description' => 'A custom service for E2E testing.',
30
+ 'type' => 'custom_service',
31
+ 'authentication' => array(
32
+ 'method' => 'none',
33
+ ),
34
+ )
35
+ );
36
+
37
+ $registry->register(
38
+ 'test_server_only_service',
39
+ array(
40
+ 'name' => 'Test Server Only Service',
41
+ 'description' => 'A server-only service with no JS render.',
42
+ 'type' => 'custom_service',
43
+ 'authentication' => array(
44
+ 'method' => 'none',
45
+ ),
46
+ )
47
+ );
48
+
49
+ $registry->register(
50
+ 'test_api_key_with_custom_render',
51
+ array(
52
+ 'name' => 'Test API Key With Custom Render',
53
+ 'description' => 'An api_key connector with a JS-registered custom render.',
54
+ 'type' => 'ai_provider',
55
+ 'authentication' => array(
56
+ 'method' => 'api_key',
57
+ 'settingName' => 'test_api_key_with_custom_render_key',
58
+ ),
59
+ )
60
+ );
61
+ }
62
+ );
63
+
64
+ // Enqueue the script module on the connectors page.
65
+ add_action(
66
+ 'admin_enqueue_scripts',
67
+ static function () {
68
+ if ( ! isset( $_GET['page'] ) || 'options-connectors-wp-admin' !== $_GET['page'] ) {
69
+ return;
70
+ }
71
+
72
+ wp_register_script_module(
73
+ 'gutenberg-test-connectors-js-extensibility',
74
+ plugins_url( 'connectors-js-extensibility/index.mjs', __FILE__ ),
75
+ array(
76
+ array(
77
+ 'id' => '@wordpress/connectors',
78
+ 'import' => 'static',
79
+ ),
80
+ )
81
+ );
82
+ wp_enqueue_script_module( 'gutenberg-test-connectors-js-extensibility' );
83
+ }
84
+ );
@@ -0,0 +1,126 @@
1
+ <?php
2
+ /**
3
+ * Plugin Name: Gutenberg Test Connectors Provider
4
+ * Plugin URI: https://github.com/WordPress/gutenberg
5
+ * Author: Gutenberg Team
6
+ *
7
+ * Registers a naive AI provider with hardcoded API key validation
8
+ * for E2E testing of the Connectors page setup flow.
9
+ *
10
+ * The valid API key is: test-api-key-123
11
+ *
12
+ * @package gutenberg-test-connectors-provider
13
+ */
14
+
15
+ // phpcs:disable Generic.Files.OneObjectStructurePerFile.MultipleFound
16
+ // phpcs:disable WordPress.Files.FileName
17
+ // phpcs:disable WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
18
+ // phpcs:disable VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
19
+
20
+ use WordPress\AiClient\AiClient;
21
+ use WordPress\AiClient\Providers\AbstractProvider;
22
+ use WordPress\AiClient\Providers\Contracts\ModelMetadataDirectoryInterface;
23
+ use WordPress\AiClient\Providers\Contracts\ProviderAvailabilityInterface;
24
+ use WordPress\AiClient\Providers\DTO\ProviderMetadata;
25
+ use WordPress\AiClient\Providers\Enums\ProviderTypeEnum;
26
+ use WordPress\AiClient\Providers\Http\Contracts\RequestAuthenticationInterface;
27
+ use WordPress\AiClient\Providers\Http\Contracts\WithRequestAuthenticationInterface;
28
+ use WordPress\AiClient\Providers\Http\DTO\ApiKeyRequestAuthentication;
29
+ use WordPress\AiClient\Providers\Http\Enums\RequestAuthenticationMethod;
30
+ use WordPress\AiClient\Providers\Models\Contracts\ModelInterface;
31
+ use WordPress\AiClient\Providers\Models\DTO\ModelMetadata;
32
+
33
+ /**
34
+ * Availability checker that validates against a hardcoded API key.
35
+ */
36
+ class Gutenberg_Test_Provider_Availability implements ProviderAvailabilityInterface, WithRequestAuthenticationInterface {
37
+
38
+ const VALID_API_KEY = 'test-api-key-123';
39
+
40
+ /**
41
+ * @var RequestAuthenticationInterface|null
42
+ */
43
+ private $authentication = null;
44
+
45
+ public function isConfigured(): bool {
46
+ if ( ! $this->authentication instanceof ApiKeyRequestAuthentication ) {
47
+ return false;
48
+ }
49
+ return $this->authentication->getApiKey() === self::VALID_API_KEY;
50
+ }
51
+
52
+ public function setRequestAuthentication( RequestAuthenticationInterface $authentication ): void {
53
+ $this->authentication = $authentication;
54
+ }
55
+
56
+ public function getRequestAuthentication(): RequestAuthenticationInterface {
57
+ return $this->authentication;
58
+ }
59
+ }
60
+
61
+ /**
62
+ * Empty model metadata directory (no models needed for testing).
63
+ */
64
+ class Gutenberg_Test_Provider_Model_Directory implements ModelMetadataDirectoryInterface {
65
+
66
+ public function listModelMetadata(): array {
67
+ return array();
68
+ }
69
+
70
+ public function hasModelMetadata( string $modelId ): bool {
71
+ return false;
72
+ }
73
+
74
+ public function getModelMetadata( string $modelId ): ModelMetadata {
75
+ throw new \WordPress\AiClient\Common\Exception\InvalidArgumentException(
76
+ sprintf( 'Model not found: %s', $modelId )
77
+ );
78
+ }
79
+ }
80
+
81
+ /**
82
+ * Minimal AI provider for E2E testing.
83
+ */
84
+ class Gutenberg_Test_Provider extends AbstractProvider {
85
+
86
+ protected static function createProviderMetadata(): ProviderMetadata {
87
+ return new ProviderMetadata(
88
+ 'test_provider',
89
+ 'Test Provider',
90
+ ProviderTypeEnum::from( ProviderTypeEnum::CLOUD ),
91
+ null,
92
+ RequestAuthenticationMethod::from( RequestAuthenticationMethod::API_KEY ),
93
+ 'A test AI provider for E2E testing.'
94
+ );
95
+ }
96
+
97
+ protected static function createProviderAvailability(): ProviderAvailabilityInterface {
98
+ return new Gutenberg_Test_Provider_Availability();
99
+ }
100
+
101
+ protected static function createModelMetadataDirectory(): ModelMetadataDirectoryInterface {
102
+ return new Gutenberg_Test_Provider_Model_Directory();
103
+ }
104
+
105
+ protected static function createModel( ModelMetadata $modelMetadata, ProviderMetadata $providerMetadata ): ModelInterface {
106
+ throw new \WordPress\AiClient\Common\Exception\InvalidArgumentException( 'Test provider does not support models.' );
107
+ }
108
+ }
109
+
110
+ // Register the provider in the AiClient registry so it is auto-discovered by the WP_Connector_Registry.
111
+ add_action(
112
+ 'init',
113
+ static function () {
114
+ if ( ! class_exists( '\WordPress\AiClient\AiClient' ) ) {
115
+ return;
116
+ }
117
+ AiClient::defaultRegistry()->registerProvider( Gutenberg_Test_Provider::class );
118
+ }
119
+ );
120
+
121
+ register_deactivation_hook(
122
+ __FILE__,
123
+ static function () {
124
+ delete_option( 'connectors_ai_test_provider_api_key' );
125
+ }
126
+ );
@@ -66,6 +66,9 @@
66
66
  'emptyString' => '{ "value": "" }',
67
67
  'anyString' => '{ "value": "any" }',
68
68
  'number' => '{ "value": 10 }',
69
+ 'auto' => '{ "value": "auto" }',
70
+ 'manual' => '{ "value": "manual" }',
71
+ 'hint' => '{ "value": "hint" }',
69
72
  );
70
73
  ?>
71
74
 
@@ -90,6 +93,10 @@
90
93
  data-wp-bind--disabled="context.value"
91
94
  data-wp-bind--aria-disabled="context.value"
92
95
  >
96
+ <div
97
+ data-testid="popover"
98
+ data-wp-bind--popover="context.value"
99
+ ></div>
93
100
  <button
94
101
  data-testid="toggle value"
95
102
  data-wp-on--click="actions.toggleValue"
@@ -0,0 +1,15 @@
1
+ {
2
+ "$schema": "https://schemas.wp.org/trunk/block.json",
3
+ "apiVersion": 3,
4
+ "name": "test/router-race-condition",
5
+ "title": "E2E Interactivity tests - router race condition",
6
+ "category": "text",
7
+ "icon": "heart",
8
+ "description": "",
9
+ "supports": {
10
+ "interactivity": true
11
+ },
12
+ "textdomain": "e2e-interactivity",
13
+ "viewScriptModule": "file:./view.js",
14
+ "render": "file:./render.php"
15
+ }
@@ -0,0 +1,26 @@
1
+ <?php
2
+ /**
3
+ * HTML for testing the router hydration race condition.
4
+ *
5
+ * @package gutenberg-test-interactive-blocks
6
+ *
7
+ * @phpcs:disable VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable
8
+ */
9
+ ?>
10
+ <div
11
+ data-wp-interactive="router-race-condition"
12
+ data-wp-router-region="router-race-condition/buttons"
13
+ data-wp-context='{ "counter": 0 }'
14
+ >
15
+ <button
16
+ data-testid="context-counter"
17
+ data-wp-text="context.counter"
18
+ data-wp-on--click="actions.increment"
19
+ >0</button>
20
+
21
+ <button
22
+ data-testid="global-counter"
23
+ data-wp-text="state.counter"
24
+ data-wp-on--click="actions.incrementGlobal"
25
+ >0</button>
26
+ </div>
@@ -0,0 +1,9 @@
1
+ <?php return array(
2
+ 'dependencies' => array(
3
+ '@wordpress/interactivity',
4
+ array(
5
+ 'id' => '@wordpress/interactivity-router',
6
+ 'import' => 'static',
7
+ ),
8
+ ),
9
+ );
@@ -0,0 +1,20 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { store, getContext } from '@wordpress/interactivity';
5
+ import '@wordpress/interactivity-router';
6
+
7
+ const { state } = store( 'router-race-condition', {
8
+ state: {
9
+ counter: 0,
10
+ },
11
+ actions: {
12
+ increment() {
13
+ const context = getContext();
14
+ context.counter += 1;
15
+ },
16
+ incrementGlobal() {
17
+ state.counter += 1;
18
+ },
19
+ },
20
+ } );
@@ -164,6 +164,9 @@
164
164
  </p>
165
165
  </div>
166
166
 
167
+ <a data-testid="hash-link" href="#hash-link-target">Go to anchor</a>
168
+ <div id="hash-link-target" data-testid="hash-link-target"></div>
169
+
167
170
  <div id="regions-with-attach-to" data-testid="regions-with-attach-to">
168
171
  <?php
169
172
  /*
@@ -0,0 +1,31 @@
1
+ <?php
2
+ /**
3
+ * Plugin Name: Gutenberg Test Plugin, RTC Compatible Meta Box
4
+ * Plugin URI: https://github.com/WordPress/gutenberg
5
+ * Author: Gutenberg Team
6
+ *
7
+ * @package gutenberg-test-rtc-compatible-meta-box
8
+ */
9
+
10
+ /**
11
+ * Renders the RTC-compatible test meta box.
12
+ */
13
+ function gutenberg_test_rtc_compatible_meta_box_render() {
14
+ echo 'RTC Compatible Meta Box';
15
+ }
16
+
17
+ /**
18
+ * Registers a meta box marked as compatible with real-time collaboration.
19
+ */
20
+ function gutenberg_test_rtc_compatible_meta_box_add() {
21
+ add_meta_box(
22
+ 'gutenberg-test-rtc-compatible-meta-box',
23
+ 'RTC Compatible Test Meta Box',
24
+ 'gutenberg_test_rtc_compatible_meta_box_render',
25
+ 'post',
26
+ 'normal',
27
+ 'high',
28
+ array( '__rtc_compatible_meta_box' => true )
29
+ );
30
+ }
31
+ add_action( 'add_meta_boxes', 'gutenberg_test_rtc_compatible_meta_box_add' );
@@ -87,6 +87,14 @@ add_action(
87
87
  )
88
88
  );
89
89
 
90
+ // Add binding support for the auto-register-with-controls block.
91
+ add_filter(
92
+ 'block_bindings_supported_attributes_test/auto-register-with-controls',
93
+ static function () {
94
+ return array( 'title', 'count', 'spacing', 'showEmojis', 'emoji' );
95
+ }
96
+ );
97
+
90
98
  // PHP-only block with auto-generated controls from various attribute types
91
99
  register_block_type(
92
100
  'test/auto-register-with-controls',
@@ -0,0 +1,83 @@
1
+ ( function () {
2
+ const { createElement: el } = wp.element;
3
+ const { useSelect } = wp.data;
4
+ const {
5
+ Modal,
6
+ Button,
7
+ __experimentalVStack: VStack,
8
+ __experimentalHStack: HStack,
9
+ } = wp.components;
10
+ const { __ } = wp.i18n;
11
+ const { registerPlugin } = wp.plugins;
12
+
13
+ const { unlock } =
14
+ wp.privateApis.__dangerousOptInToUnstableAPIsOnlyForCoreModules(
15
+ 'I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.',
16
+ '@wordpress/core-data'
17
+ );
18
+
19
+ function CustomConnectionLimitModal() {
20
+ const connectionStatus = useSelect( function ( select ) {
21
+ return unlock( select( 'core' ) ).getSyncConnectionStatus() || null;
22
+ }, [] );
23
+
24
+ const error =
25
+ connectionStatus &&
26
+ connectionStatus.status === 'disconnected' &&
27
+ connectionStatus.error
28
+ ? connectionStatus.error
29
+ : null;
30
+
31
+ if ( ! error || error.code !== 'connection-limit-exceeded' ) {
32
+ return null;
33
+ }
34
+
35
+ return el(
36
+ Modal,
37
+ {
38
+ title: __( 'Collaboration limit reached' ),
39
+ isDismissible: false,
40
+ onRequestClose() {},
41
+ shouldCloseOnClickOutside: false,
42
+ shouldCloseOnEsc: false,
43
+ size: 'medium',
44
+ },
45
+ el(
46
+ VStack,
47
+ { spacing: 6 },
48
+ el(
49
+ 'p',
50
+ null,
51
+ 'Consider upgrading your hosting plan to increase the collaboration limits.'
52
+ ),
53
+ el(
54
+ HStack,
55
+ { justify: 'right' },
56
+ el(
57
+ Button,
58
+ {
59
+ variant: 'tertiary',
60
+ isDestructive: true,
61
+ href: 'edit.php',
62
+ __next40pxDefaultSize: true,
63
+ },
64
+ __( 'Back to Posts' )
65
+ ),
66
+ el(
67
+ Button,
68
+ {
69
+ variant: 'primary',
70
+ href: 'https://example.com/upgrade',
71
+ __next40pxDefaultSize: true,
72
+ },
73
+ __( 'Upgrade Plan' )
74
+ )
75
+ )
76
+ )
77
+ );
78
+ }
79
+
80
+ registerPlugin( 'custom-sync-connection-error', {
81
+ render: CustomConnectionLimitModal,
82
+ } );
83
+ } )();
@@ -0,0 +1,48 @@
1
+ <?php
2
+ /**
3
+ * Plugin Name: Gutenberg Test Plugin, Sync Connection Error Filter
4
+ * Plugin URI: https://github.com/WordPress/gutenberg
5
+ * Author: Gutenberg Team
6
+ *
7
+ * @package gutenberg-test-sync-connection-error-filter
8
+ */
9
+
10
+ /**
11
+ * Registers the editor.isSyncConnectionErrorHandled filter and custom modal.
12
+ */
13
+ function enqueue_sync_connection_error_filter_scripts() {
14
+ // Register the filter early on wp-hooks so it's available before the
15
+ // editor modal renders. Plugins return true for error codes they handle.
16
+ wp_add_inline_script(
17
+ 'wp-hooks',
18
+ "wp.hooks.addFilter(
19
+ 'editor.isSyncConnectionErrorHandled',
20
+ 'gutenberg-test/custom-sync-error',
21
+ function( isHandled, errorCode ) {
22
+ if ( errorCode === 'connection-limit-exceeded' ) {
23
+ return true;
24
+ }
25
+ return isHandled;
26
+ }
27
+ );"
28
+ );
29
+
30
+ // Enqueue the custom modal component that replaces the default UI
31
+ // for connection-limit-exceeded errors.
32
+ wp_enqueue_script(
33
+ 'gutenberg-test-sync-connection-error-filter',
34
+ plugins_url( 'sync-connection-error-filter/index.js', __FILE__ ),
35
+ array(
36
+ 'wp-components',
37
+ 'wp-data',
38
+ 'wp-element',
39
+ 'wp-i18n',
40
+ 'wp-plugins',
41
+ 'wp-private-apis',
42
+ ),
43
+ filemtime( plugin_dir_path( __FILE__ ) . 'sync-connection-error-filter/index.js' ),
44
+ true
45
+ );
46
+ }
47
+
48
+ add_action( 'enqueue_block_editor_assets', 'enqueue_sync_connection_error_filter_scripts' );