Skip to content

Commit 5b881da

Browse files
Merge branch 'trunk' into trunk
2 parents bc48036 + 81885a9 commit 5b881da

58 files changed

Lines changed: 1903 additions & 406 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

package-lock.json

Lines changed: 22 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"url": "https://develop.svn.wordpress.org/trunk"
88
},
99
"gutenberg": {
10-
"ref": "7bf80ea84eb8b62eceb1bb3fe82e42163673ca79"
10+
"ref": "59a08c5496008ca88f4b6b86f38838c3612d88c8"
1111
},
1212
"engines": {
1313
"node": ">=20.10.0",
@@ -30,6 +30,7 @@
3030
"@lodder/grunt-postcss": "^3.1.1",
3131
"@playwright/test": "1.56.1",
3232
"@pmmmwh/react-refresh-webpack-plugin": "0.6.1",
33+
"@types/codemirror": "5.60.17",
3334
"@wordpress/e2e-test-utils-playwright": "1.33.2",
3435
"@wordpress/prettier-config": "4.33.1",
3536
"@wordpress/scripts": "30.26.2",
@@ -79,6 +80,7 @@
7980
"core-js-url-browser": "3.6.4",
8081
"csslint": "1.0.5",
8182
"element-closest": "3.0.2",
83+
"espree": "9.6.1",
8284
"esprima": "4.0.1",
8385
"formdata-polyfill": "4.0.10",
8486
"hoverintent": "2.2.1",
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
/**
2+
* CodeMirror JavaScript linter.
3+
*
4+
* @since 7.0.0
5+
*/
6+
7+
import CodeMirror from 'codemirror';
8+
9+
/**
10+
* CodeMirror Lint Error.
11+
*
12+
* @see https://codemirror.net/5/doc/manual.html#addon_lint
13+
*
14+
* @typedef {Object} CodeMirrorLintError
15+
* @property {string} message - Error message.
16+
* @property {'error'} severity - Severity.
17+
* @property {CodeMirror.Position} from - From position.
18+
* @property {CodeMirror.Position} to - To position.
19+
*/
20+
21+
/**
22+
* JSHint options supported by Espree.
23+
*
24+
* @see https://jshint.com/docs/options/
25+
* @see https://www.npmjs.com/package/espree#options
26+
*
27+
* @typedef {Object} SupportedJSHintOptions
28+
* @property {number} [esversion] - "This option is used to specify the ECMAScript version to which the code must adhere."
29+
* @property {boolean} [es5] - "This option enables syntax first defined in the ECMAScript 5.1 specification. This includes allowing reserved keywords as object properties."
30+
* @property {boolean} [es3] - "This option tells JSHint that your code needs to adhere to ECMAScript 3 specification. Use this option if you need your program to be executable in older browsers—such as Internet Explorer 6/7/8/9—and other legacy JavaScript environments."
31+
* @property {boolean} [module] - "This option informs JSHint that the input code describes an ECMAScript 6 module. All module code is interpreted as strict mode code."
32+
* @property {'implied'} [strict] - "This option requires the code to run in ECMAScript 5's strict mode."
33+
*/
34+
35+
/**
36+
* Validates JavaScript.
37+
*
38+
* @since 7.0.0
39+
*
40+
* @param {string} text - Source.
41+
* @param {SupportedJSHintOptions} options - Linting options.
42+
* @returns {Promise<CodeMirrorLintError[]>}
43+
*/
44+
async function validator( text, options ) {
45+
const errors = /** @type {CodeMirrorLintError[]} */ [];
46+
try {
47+
const espree = await import( /* webpackIgnore: true */ 'espree' );
48+
espree.parse( text, {
49+
...getEspreeOptions( options ),
50+
loc: true,
51+
} );
52+
} catch ( error ) {
53+
if (
54+
// This is an `EnhancedSyntaxError` in Espree: <https://github.com/brettz9/espree/blob/3c1120280b24f4a5e4c3125305b072fa0dfca22b/packages/espree/lib/espree.js#L48-L54>.
55+
error instanceof SyntaxError &&
56+
typeof error.lineNumber === 'number' &&
57+
typeof error.column === 'number'
58+
) {
59+
const line = error.lineNumber - 1;
60+
errors.push( {
61+
message: error.message,
62+
severity: 'error',
63+
from: CodeMirror.Pos( line, error.column - 1 ),
64+
to: CodeMirror.Pos( line, error.column ),
65+
} );
66+
} else {
67+
console.warn( '[CodeMirror] Unable to lint JavaScript:', error ); // jshint ignore:line
68+
}
69+
}
70+
71+
return errors;
72+
}
73+
74+
CodeMirror.registerHelper( 'lint', 'javascript', validator );
75+
76+
/**
77+
* Gets the options for Espree from the supported JSHint options.
78+
*
79+
* @since 7.0.0
80+
*
81+
* @param {SupportedJSHintOptions} options - Linting options for JSHint.
82+
* @return {{
83+
* ecmaVersion?: number|'latest',
84+
* ecmaFeatures?: {
85+
* impliedStrict?: true
86+
* }
87+
* }}
88+
*/
89+
function getEspreeOptions( options ) {
90+
const ecmaFeatures = {};
91+
if ( options.strict === 'implied' ) {
92+
ecmaFeatures.impliedStrict = true;
93+
}
94+
95+
return {
96+
ecmaVersion: getEcmaVersion( options ),
97+
sourceType: options.module ? 'module' : 'script',
98+
ecmaFeatures,
99+
};
100+
}
101+
102+
/**
103+
* Gets the ECMAScript version.
104+
*
105+
* @since 7.0.0
106+
*
107+
* @param {SupportedJSHintOptions} options - Options.
108+
* @return {number|'latest'} ECMAScript version.
109+
*/
110+
function getEcmaVersion( options ) {
111+
if ( typeof options.esversion === 'number' ) {
112+
return options.esversion;
113+
}
114+
if ( options.es5 ) {
115+
return 5;
116+
}
117+
if ( options.es3 ) {
118+
return 3;
119+
}
120+
return 'latest';
121+
}

src/wp-admin/includes/class-wp-debug-data.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -373,8 +373,8 @@ private static function get_wp_server(): array {
373373
);
374374
$fields['httpd_software'] = array(
375375
'label' => __( 'Web server' ),
376-
'value' => $_SERVER['SERVER_SOFTWARE'] ?? __( 'Unable to determine what web server software is used' ),
377-
'debug' => $_SERVER['SERVER_SOFTWARE'] ?? 'unknown',
376+
'value' => ! empty( $_SERVER['SERVER_SOFTWARE'] ) ? wp_unslash( $_SERVER['SERVER_SOFTWARE'] ) : __( 'Unable to determine what web server software is used' ),
377+
'debug' => ! empty( $_SERVER['SERVER_SOFTWARE'] ) ? wp_unslash( $_SERVER['SERVER_SOFTWARE'] ) : 'unknown',
378378
);
379379
$fields['php_version'] = array(
380380
'label' => __( 'PHP version' ),
@@ -545,7 +545,7 @@ private static function get_wp_server(): array {
545545
);
546546
$fields['server-time'] = array(
547547
'label' => __( 'Current Server time' ),
548-
'value' => wp_date( 'c', $_SERVER['REQUEST_TIME'] ),
548+
'value' => isset( $_SERVER['REQUEST_TIME'] ) ? wp_date( 'c', (int) $_SERVER['REQUEST_TIME'] ) : __( 'Unable to determine server time' ),
549549
);
550550

551551
return array(

src/wp-admin/includes/class-wp-filesystem-direct.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,22 @@ public function chmod( $file, $mode = false, $recursive = false ) {
170170
}
171171

172172
if ( ! $recursive || ! $this->is_dir( $file ) ) {
173+
$current_mode = fileperms( $file ) & 0777 | 0644;
174+
175+
/*
176+
* fileperms() populates the stat cache, so have to clear it
177+
* to maintain parity with the previous behavior.
178+
*/
179+
clearstatcache( true, $file );
180+
181+
/*
182+
* Avoid calling chmod() if the requested mode is already set,
183+
* to prevent throwing a warning when we aren't the owner.
184+
*/
185+
if ( $current_mode === $mode ) {
186+
return true;
187+
}
188+
173189
return chmod( $file, $mode );
174190
}
175191

src/wp-admin/includes/file.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ function wp_get_plugin_file_editable_extensions( $plugin ) {
202202
'inc',
203203
'include',
204204
'js',
205+
'mjs',
205206
'json',
206207
'jsx',
207208
'less',
@@ -261,6 +262,7 @@ function wp_get_theme_file_editable_extensions( $theme ) {
261262
'inc',
262263
'include',
263264
'js',
265+
'mjs',
264266
'json',
265267
'jsx',
266268
'less',

src/wp-admin/includes/update-core.php

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -840,10 +840,6 @@
840840
'wp-includes/js/dist/fields.min.js',
841841
'wp-includes/js/dist/fields.js',
842842
// 6.9
843-
'wp-includes/blocks/post-author/editor.css',
844-
'wp-includes/blocks/post-author/editor.min.css',
845-
'wp-includes/blocks/post-author/editor-rtl.css',
846-
'wp-includes/blocks/post-author/editor-rtl.min.css',
847843
'wp-includes/SimplePie/src/Decode',
848844
'wp-includes/SimplePie/src/Core.php',
849845
);

src/wp-content/themes/twentytwentyone/inc/block-patterns.php

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,9 @@ function twenty_twenty_one_register_block_pattern_category() {
2727
add_action( 'init', 'twenty_twenty_one_register_block_pattern_category' );
2828
}
2929

30-
/**
31-
* Register Block Patterns.
32-
*/
3330
if ( function_exists( 'register_block_pattern' ) ) {
3431
/**
35-
* Registers Block Pattern.
32+
* Registers Block Patterns.
3633
*
3734
* @since Twenty Twenty-One 1.0
3835
*

src/wp-includes/abilities-api.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,8 @@
132132
*
133133
* Ability names must follow these rules:
134134
*
135-
* - Include a namespace prefix (e.g., `my-plugin/my-ability`).
135+
* - Contain 2 to 4 segments separated by forward slashes
136+
* (e.g., `my-plugin/my-ability`, `my-plugin/resource/find`, `my-plugin/resource/sub/find`).
136137
* - Use only lowercase alphanumeric characters, dashes, and forward slashes.
137138
* - Use descriptive, action-oriented names (e.g., `process-payment`, `generate-report`).
138139
*
@@ -225,9 +226,8 @@
225226
* @see wp_register_ability_category()
226227
* @see wp_unregister_ability()
227228
*
228-
* @param string $name The name of the ability. Must be a namespaced string containing
229-
* a prefix, e.g., `my-plugin/my-ability`. Can only contain lowercase
230-
* alphanumeric characters, dashes, and forward slashes.
229+
* @param string $name The name of the ability. Must be the fully-namespaced
230+
* string identifier, e.g. `my-plugin/my-ability` or `my-plugin/resource/my-ability`.
231231
* @param array<string, mixed> $args {
232232
* An associative array of arguments for configuring the ability.
233233
*
@@ -318,7 +318,7 @@ function wp_register_ability( string $name, array $args ): ?WP_Ability {
318318
* @see wp_register_ability()
319319
*
320320
* @param string $name The name of the ability to unregister, including namespace prefix
321-
* (e.g., 'my-plugin/my-ability').
321+
* (e.g., 'my-plugin/my-ability' or 'my-plugin/resource/find').
322322
* @return WP_Ability|null The unregistered ability instance on success, `null` on failure.
323323
*/
324324
function wp_unregister_ability( string $name ): ?WP_Ability {
@@ -351,7 +351,7 @@ function wp_unregister_ability( string $name ): ?WP_Ability {
351351
* @see wp_get_ability()
352352
*
353353
* @param string $name The name of the ability to check, including namespace prefix
354-
* (e.g., 'my-plugin/my-ability').
354+
* (e.g., 'my-plugin/my-ability' or 'my-plugin/resource/find').
355355
* @return bool `true` if the ability is registered, `false` otherwise.
356356
*/
357357
function wp_has_ability( string $name ): bool {
@@ -383,7 +383,7 @@ function wp_has_ability( string $name ): bool {
383383
* @see wp_has_ability()
384384
*
385385
* @param string $name The name of the ability, including namespace prefix
386-
* (e.g., 'my-plugin/my-ability').
386+
* (e.g., 'my-plugin/my-ability' or 'my-plugin/resource/find').
387387
* @return WP_Ability|null The registered ability instance, or `null` if not registered.
388388
*/
389389
function wp_get_ability( string $name ): ?WP_Ability {

src/wp-includes/abilities-api/class-wp-abilities-registry.php

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,8 @@ final class WP_Abilities_Registry {
4343
*
4444
* @see wp_register_ability()
4545
*
46-
* @param string $name The name of the ability. The name must be a string containing a namespace
47-
* prefix, i.e. `my-plugin/my-ability`. It can only contain lowercase
48-
* alphanumeric characters, dashes and the forward slash.
46+
* @param string $name The name of the ability. Must be the fully-namespaced
47+
* string identifier, e.g. `my-plugin/my-ability` or `my-plugin/resource/my-ability`.
4948
* @param array<string, mixed> $args {
5049
* An associative array of arguments for the ability.
5150
*
@@ -78,11 +77,11 @@ final class WP_Abilities_Registry {
7877
* @return WP_Ability|null The registered ability instance on success, null on failure.
7978
*/
8079
public function register( string $name, array $args ): ?WP_Ability {
81-
if ( ! preg_match( '/^[a-z0-9-]+\/[a-z0-9-]+$/', $name ) ) {
80+
if ( ! preg_match( '/^[a-z0-9-]+(?:\/[a-z0-9-]+){1,3}$/', $name ) ) {
8281
_doing_it_wrong(
8382
__METHOD__,
8483
__(
85-
'Ability name must be a string containing a namespace prefix, i.e. "my-plugin/my-ability". It can only contain lowercase alphanumeric characters, dashes and the forward slash.'
84+
'Ability name must contain 2 to 4 segments separated by forward slashes, e.g. "my-plugin/my-ability" or "my-plugin/resource/my-ability". It can only contain lowercase alphanumeric characters, dashes, and forward slashes.'
8685
),
8786
'6.9.0'
8887
);

0 commit comments

Comments
 (0)