PluginProbe
Gutenberg / 23.7.2
Gutenberg v23.7.2
23.9.1 23.9.0 23.8.0 23.7.2 23.7.1 23.7.0 23.6.1 23.6.2 23.6.0 23.5.3 23.5.2 23.5.1 23.5.0 23.4.0 23.3.2 23.3.1 23.3.0 23.2.0 23.2.1 23.2.2 23.1.1 23.1.0 23.0.1 12.6.0 7.4.0 All 402 releases
gutenberg / build / pages / experiments / page-wp-admin.php

page-wp-admin.php in Gutenberg 23.7.2, at build/pages/experiments/page-wp-admin.php

325 lines 9.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Page: experiments (wp-admin integrated)
4 * Auto-generated by build process.
5 * Do not edit this file manually.
6 *
7 * This version integrates with the standard WordPress admin interface,
8 * keeping the wp-admin sidebar and scripts/styles intact.
9 *
10 * @package gutenberg
11 */
12
13 // Global storage for experiments routes and menu items
14 global $gutenberg_experiments_wp_admin_routes, $gutenberg_experiments_wp_admin_menu_items;
15 $gutenberg_experiments_wp_admin_routes = array();
16 $gutenberg_experiments_wp_admin_menu_items = array();
17
18 /**
19 * Register a route for the experiments-wp-admin page.
20 *
21 * @param string $path Route path (e.g., '/types/$type/edit/$id').
22 * @param string|null $content_module Script module ID for content (stage/inspector).
23 * @param string|null $route_module Script module ID for route lifecycle hooks.
24 */
25 function gutenberg_register_experiments_wp_admin_route( $path, $content_module = null, $route_module = null ) {
26 global $gutenberg_experiments_wp_admin_routes;
27
28 $route = array( 'path' => $path );
29 if ( ! empty( $content_module ) ) {
30 $route['content_module'] = $content_module;
31 }
32 if ( ! empty( $route_module ) ) {
33 $route['route_module'] = $route_module;
34 }
35
36 $gutenberg_experiments_wp_admin_routes[] = $route;
37 }
38
39 /**
40 * Register a menu item for the experiments-wp-admin page.
41 * Note: Menu items are registered but not displayed in single-page mode.
42 *
43 * @param string $id Menu item ID.
44 * @param string $label Display label.
45 * @param string $to Route path to navigate to.
46 * @param string $parent_id Optional. Parent menu item ID.
47 */
48 function gutenberg_register_experiments_wp_admin_menu_item( $id, $label, $to, $parent_id = '' ) {
49 global $gutenberg_experiments_wp_admin_menu_items;
50
51 $menu_item = array(
52 'id' => $id,
53 'label' => $label,
54 'to' => $to,
55 );
56
57 if ( ! empty( $parent_id ) ) {
58 $menu_item['parent'] = $parent_id;
59 }
60
61 $gutenberg_experiments_wp_admin_menu_items[] = $menu_item;
62 }
63
64 /**
65 * Get all registered routes for the experiments-wp-admin page.
66 *
67 * @return array Array of route objects.
68 */
69 function gutenberg_get_experiments_wp_admin_routes() {
70 global $gutenberg_experiments_wp_admin_routes;
71 return $gutenberg_experiments_wp_admin_routes ?? array();
72 }
73
74 /**
75 * Get all registered menu items for the experiments-wp-admin page.
76 *
77 * @return array Array of menu item objects.
78 */
79 function gutenberg_get_experiments_wp_admin_menu_items() {
80 global $gutenberg_experiments_wp_admin_menu_items;
81 return $gutenberg_experiments_wp_admin_menu_items ?? array();
82 }
83
84 /**
85 * Preload REST API data for the experiments-wp-admin page.
86 * Automatically called during page rendering.
87 */
88 function gutenberg_experiments_wp_admin_preload_data() {
89 // Define paths to preload - same for all pages
90 // This must exactly match the _fields list in packages/core-data/src/entities.js,
91 // same fields in the same order, or the preload is never consumed.
92 $preload_paths = array(
93 '/?_fields=description,gmt_offset,home,image_max_bit_depth,image_sizes,image_size_threshold,image_strip_meta,name,site_icon,site_icon_url,site_logo,timezone_string,url,page_for_posts,page_on_front,show_on_front',
94 array( '/wp/v2/settings', 'OPTIONS' ),
95 );
96
97 // Use rest_preload_api_request to gather the preloaded data
98 $preload_data = array_reduce(
99 $preload_paths,
100 'rest_preload_api_request',
101 array()
102 );
103
104 // Register the preloading middleware with wp-api-fetch
105 wp_add_inline_script(
106 'wp-api-fetch',
107 sprintf(
108 'wp.apiFetch.use( wp.apiFetch.createPreloadingMiddleware( %s ) );',
109 wp_json_encode( $preload_data )
110 ),
111 'after'
112 );
113 }
114
115 /**
116 * Enqueue scripts and styles for the experiments-wp-admin page.
117 * Hooked to admin_enqueue_scripts.
118 *
119 * @param string $hook_suffix The current admin page.
120 */
121 function gutenberg_experiments_wp_admin_enqueue_scripts( $hook_suffix ) {
122 // Check all possible ways this page can be accessed:
123 // 1. Menu page via admin.php?page=experiments-wp-admin (plugin)
124 // 2. Direct file via experiments.php (Core) - screen ID will be 'experiments'
125 $current_screen = get_current_screen();
126 $is_our_page = (
127 ( isset( $_GET['page'] ) && 'experiments-wp-admin' === $_GET['page'] ) || // phpcs:ignore WordPress.Security.NonceVerification.Recommended
128 ( $current_screen && 'experiments' === $current_screen->id )
129 );
130
131 if ( ! $is_our_page ) {
132 return;
133 }
134
135 // Load build constants
136 $build_constants = require __DIR__ . '/../../constants.php';
137
138 /**
139 * Fires when the experiments admin page is initialized so extensions can register routes and menu items.
140 */
141 do_action( 'experiments-wp-admin_init' );
142
143 // Preload REST API data
144 gutenberg_experiments_wp_admin_preload_data();
145
146 // Get all registered routes
147 $routes = gutenberg_get_experiments_wp_admin_routes();
148
149 // Get boot module asset file for dependencies
150 $asset_file = __DIR__ . '/../../modules/boot/index.min.asset.php';
151 if ( file_exists( $asset_file ) ) {
152 $asset = require $asset_file;
153
154 // This script serves two purposes:
155 // 1. It ensures all the globals that are made available to the modules are loaded.
156 // 2. It initializes the boot module as an inline script.
157 wp_register_script( 'experiments-wp-admin-prerequisites', '', $asset['dependencies'], $asset['version'], true );
158
159 $init_modules = [];
160
161 /*
162 * Add inline script to initialize the app using initSinglePage (no menuItems).
163 * The dynamic import is deferred until DOMContentLoaded so that all classic
164 * script dependencies of @wordpress/boot (wp-private-apis, wp-components,
165 * wp-theme, etc.) have finished parsing and executing before the boot module
166 * evaluates. Otherwise, a modulepreloaded @wordpress/boot can win the race
167 * against the classic-script-printing pass on fast CDN-fronted hosts in
168 * Chrome, evaluating before wp.theme.privateApis is defined and throwing
169 * "Cannot unlock an undefined object". See <https://core.trac.wordpress.org/ticket/65103>.
170 */
171 $init_js_function = <<<'JS'
172 ( mountId, routes, initModules ) => {
173 const run = async () => {
174 const mod = await import( "@wordpress/boot" );
175 mod.initSinglePage( { mountId, routes, initModules } );
176 };
177 if ( document.readyState === "loading" ) {
178 document.addEventListener( "DOMContentLoaded", run );
179 } else {
180 run();
181 }
182 }
183 JS;
184 wp_add_inline_script(
185 'experiments-wp-admin-prerequisites',
186 sprintf(
187 '( %s )( %s, %s, %s );',
188 $init_js_function,
189 wp_json_encode( 'experiments-wp-admin-app', JSON_HEX_TAG | JSON_UNESCAPED_SLASHES ),
190 wp_json_encode( $routes, JSON_HEX_TAG | JSON_UNESCAPED_SLASHES ),
191 wp_json_encode( $init_modules, JSON_HEX_TAG | JSON_UNESCAPED_SLASHES )
192 )
193 );
194
195 // Register prerequisites style by filtering script dependencies to find registered styles
196 $style_dependencies = array_filter(
197 $asset['dependencies'],
198 function ( $handle ) {
199 return wp_style_is( $handle, 'registered' );
200 }
201 );
202 wp_register_style( 'experiments-wp-admin-prerequisites', false, $style_dependencies, $asset['version'] );
203
204 // Build dependencies for experiments-wp-admin module
205 $boot_dependencies = array(
206 array(
207 'import' => 'static',
208 'id' => '@wordpress/boot',
209 ),
210 );
211
212 // Add init modules as static dependencies
213 // No init modules configured
214
215 // Add all registered routes as dependencies
216 foreach ( $routes as $route ) {
217 if ( isset( $route['route_module'] ) ) {
218 $boot_dependencies[] = array(
219 'import' => 'static',
220 'id' => $route['route_module'],
221 );
222 }
223 if ( isset( $route['content_module'] ) ) {
224 $boot_dependencies[] = array(
225 'import' => 'dynamic',
226 'id' => $route['content_module'],
227 );
228 }
229 }
230
231 /**
232 * Filters the boot script-module dependencies for the
233 * experiments-wp-admin page.
234 *
235 * Surfaces extending this page can append entries to the boot
236 * dependency list. Each entry is an array with 'import' (string
237 * 'static' or 'dynamic') and 'id' (script-module handle) keys.
238 *
239 * @param array $boot_dependencies Boot dependencies for the page.
240 */
241 $boot_dependencies = apply_filters(
242 'experiments-wp-admin_boot_dependencies',
243 $boot_dependencies
244 );
245
246 // Dummy script module to ensure dependencies are loaded
247 wp_register_script_module(
248 'experiments-wp-admin',
249 $build_constants['build_url'] . 'pages/experiments/loader.js',
250 $boot_dependencies
251 );
252
253 // Enqueue the boot scripts and styles
254 wp_enqueue_script( 'experiments-wp-admin-prerequisites' );
255 wp_enqueue_script_module( 'experiments-wp-admin' );
256 wp_enqueue_style( 'experiments-wp-admin-prerequisites' );
257 }
258 }
259
260 /**
261 * Render the experiments-wp-admin page.
262 * Call this function from add_menu_page or add_submenu_page.
263 * This renders within the normal WordPress admin interface.
264 */
265 function gutenberg_experiments_wp_admin_render_page() {
266 ?>
267 <style>
268 /* Critical styles to prevent layout shifts - inlined for immediate application */
269
270 #wpwrap {
271 overflow-y: auto;
272 }
273 body {
274 background: #fff;
275 }
276
277 /* Reset wp-admin padding */
278 #wpcontent {
279 padding-inline-start: 0;
280 }
281 #wpbody-content {
282 padding-bottom: 0;
283 }
284
285 /* Hide legacy admin elements */
286 #wpbody-content > div:not(.boot-layout-container):not(#screen-meta) {
287 display: none;
288 }
289 #wpfooter {
290 display: none;
291 }
292
293 /* Accessibility regions */
294 .a11y-speak-region {
295 inset-inline-start: -1px;
296 top: -1px;
297 }
298
299 /* Admin menu indicators */
300 ul#adminmenu a.wp-has-current-submenu::after,
301 ul#adminmenu > li.current > a.current::after {
302 border-inline-end-color: #fff;
303 }
304
305 /* Media frame fix */
306 .media-frame select.attachment-filters:last-of-type {
307 width: auto;
308 max-width: 100%;
309 }
310
311 /* Responsive overflow fix for #wpwrap */
312 @media (min-width: 782px) {
313 #wpwrap {
314 overflow-y: initial;
315 }
316 }
317 </style>
318 <div id="experiments-wp-admin-app" class="boot-layout-container"></div>
319 <?php
320 }
321
322 // Hook the enqueue function to admin_enqueue_scripts
323 add_action( 'admin_enqueue_scripts', 'gutenberg_experiments_wp_admin_enqueue_scripts' );
324
325