-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Upgrade CodeMirror to latest v5 #10778
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Upgrade CodeMirror to latest v5 #10778
Conversation
Adds codemirror, csslint, htmlhint, jsonlint, and esprima to package.json dependencies to manage them via npm. This aligns with the strategy for other vendor libraries in Core. Command: npm install [email protected] [email protected] [email protected] [email protected] [email protected] --save-prod --save-exact Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Removes manually bundled codemirror.min.js/css and standalone linters (csslint, esprima, htmlhint, jsonlint) from src/js/_enqueues/vendor/codemirror/. These will be replaced by artifacts generated from npm dependencies via the build process. Core-specific wrappers (fakejshint.js, htmlhint-kses.js) are preserved. Command: rm src/js/_enqueues/vendor/codemirror/codemirror.min.js src/js/_enqueues/vendor/codemirror/codemirror.min.css src/js/_enqueues/vendor/codemirror/csslint.js src/js/_enqueues/vendor/codemirror/esprima.js src/js/_enqueues/vendor/codemirror/htmlhint.js src/js/_enqueues/vendor/codemirror/jsonlint.js Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Creates tools/vendors/codemirror-entry.js, which replicates the logic of the original codemirror.manifest.js. This file aggregates the core library, modes, keymaps, and addons into a single entry point for the build process and exposes the global window.wp.CodeMirror object. Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Adds tools/webpack/codemirror.config.js to handle the bundling of the CodeMirror entry point into src/wp-includes/js/codemirror/codemirror.min.js. Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Updates Gruntfile.js to include tasks for building CodeMirror: - Registers a 'codemirror' target for webpack to bundle the JS. - Registers a 'codemirror' target for concat to bundle the CSS. - Registers a 'codemirror' target for cssmin to minify the CSS. - Registers a 'codemirror' target for copy to move linters and wrappers. - Creates a combined 'build:codemirror' task. - Adds 'build:codemirror' to the main 'build' task workflow. Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Updates the version strings for CodeMirror and its related linters (csslint, esprima, jsonlint, htmlhint) to reflect the upgrade to v5.65.18. Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Adds the required license header to the minified CodeMirror bundles during the build process. - Updates tools/webpack/codemirror.config.js to include the license header using BannerPlugin and ensures Terser preserves important comments. - Adds a usebanner:codemirror task to Gruntfile.js to append the license header to the minified CSS. - Dynamically retrieves the CodeMirror version from package.json for inclusion in the header. - Reformats the license headers to use multi-line backtick string literals for better maintainability. Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Ensures the CodeMirror license banner is applied to the unminified `codemirror.css` file in addition to the minified version. Also enables the `linebreak` option for the CodeMirror banner to ensure a newline separates the header from the content. Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Refactors the CodeMirror CSS build process to add the license banner to the unminified `codemirror.css` file first. The `cssmin` task then generates `codemirror.min.css` from this file, preserving the license header while stripping unnecessary whitespace. - Updates `usebanner:codemirror` to target only the unminified file. - Reorders the `build:codemirror` task sequence to run `usebanner:codemirror` before `cssmin:codemirror`. Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Test using WordPress PlaygroundThe changes in this pull request can previewed and tested using a WordPress Playground instance. WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser. Some things to be aware of
For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation. |
Updates the CodeMirror CSS build process to perform concatenation and minification in a single `cssmin` task. This eliminates the need for an intermediate unminified file and ensures the license banner is applied correctly to the final minified bundle without an extra newline. Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Adds `codemirror`, `csslint`, `esprima`, `htmlhint`, and `jsonlint` to the manually registered vendor scripts data provider in `Tests_Dependencies_Scripts::data_vendor_script_versions_registered_manually`. This ensures that `test_vendor_script_data_provider_includes_all_packages` passes by accounting for these dependencies which are present in `package.json`. Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Upgrades `htmlhint` to v1.8.0 and configures it as an external in the CodeMirror Webpack bundle to avoid duplicate code and ensure compatibility with Core wrappers. - Handles the change in HTMLHint's UMD export structure (where the instance is nested under `HTMLHint.HTMLHint`) by applying a build-time patch to `htmlhint.js` during the copy task. This patch unwraps the instance into the global scope, ensuring compatibility with CodeMirror's `html-lint` addon and WordPress's `htmlhint-kses` wrapper. - Configures `tools/webpack/codemirror.config.js` to use `window.*` for linter externals (`htmlhint`, `csslint`, `jshint`, `jsonlint`), preventing `ReferenceError` when these optional libraries are not loaded. - Updates `package.json` and `script-loader.php` to reflect the HTMLHint v1.8.0 upgrade. Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Updates the `copy:codemirror` task in `Gruntfile.js` to correctly identify and patch `htmlhint.min.js`. This ensures that the `HTMLHint` global is correctly unwrapped (fixing the namespace issue) when using the minified distribution of HTMLHint v1.8.0. Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Upgrades `codemirror` from 5.65.18 to 5.65.20 in `package.json` and `script-loader.php`. This ensures WordPress is using the absolute latest maintenance release of the CodeMirror v5 series. Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the Core Committers: Use this line as a base for the props when committing in SVN: To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
Aligns the JSHint settings used in the code editor with the project's `.jshintrc` file. This includes updating to ES10, removing deprecated options like `es3`, `onevar`, and `trailing`, and adding missing globals. Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR upgrades WordPress Core’s CodeMirror v5 integration to a newer upstream release by sourcing CodeMirror (and related linters) from npm and generating the runtime assets via the build tooling, then updating registered script/style versions accordingly.
Changes:
- Add npm dependencies for
codemirrorand linters (csslint,htmlhint,jsonlint,esprima), and update vendor version assertions in PHPUnit. - Introduce a dedicated Webpack entry/config to bundle CodeMirror + addons/modes, and wire a new
build:codemirrortask into the main Grunt build. - Update
wp_default_scripts()/wp_default_styles()registrations to the new package versions.
Reviewed changes
Copilot reviewed 6 out of 13 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
tools/webpack/codemirror.config.js |
New Webpack config for building codemirror.min.js with a license banner and externals for linters. |
tools/vendors/codemirror-entry.js |
New Webpack entry that imports CodeMirror core + required addons/modes and exposes it on window.wp. |
Gruntfile.js |
Adds webpack:codemirror, cssmin:codemirror, copy:codemirror, banner handling, and integrates build:codemirror into build. |
src/wp-includes/script-loader.php |
Updates registered versions for wp-codemirror and linter handles to match npm package versions. |
tests/phpunit/tests/dependencies/scripts.php |
Extends vendor-version test coverage to include CodeMirror and linter handles. |
package.json / package-lock.json |
Adds/locks new npm dependencies required for the CodeMirror + linter build pipeline. |
src/js/_enqueues/vendor/codemirror/* |
Removes previously bundled vendor artifacts now sourced from npm/build (leaving core wrappers). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Updates `tools/webpack/codemirror.config.js` to export a function that accepts a `buildTarget` parameter, ensuring the bundled CodeMirror script is written to the correct directory (`src/` for dev builds, `build/` for production). Also updates `Gruntfile.js` to pass the `WORKING_DIR` to this configuration function. Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Co-authored-by: Copilot <[email protected]>
Updates the comments in `codemirror-entry.js` to correctly describe the CodeMirror import and explain the distinction between `window.wp.CodeMirror` and the minimal version set by the `runmode-standalone` addon. Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Resets the global `usebanner.options.linebreak` to `true` to prevent affecting other build outputs, while maintaining `linebreak: false` specifically for the CodeMirror CSS bundle. Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Co-authored-by: Copilot <[email protected]>
src/wp-includes/general-template.php
Outdated
| 'curly' => true, | ||
| 'eqeqeq' => true, | ||
| 'eqnull' => true, | ||
| 'esversion' => 10, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that esprima doesn't support this, apparently, so ES6 syntax still is reported as a syntax error 😦
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See https://esprima.org/doc/es6.html
Given that Esprima hasn't been updated in 8 years, we might want to consider turning JS linting off by default the same as we did for CSS.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See Core-44471 for why CSS linting was disabled for a similar reason.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like we could replace Esprima with Espree which is actively maintained: https://www.npmjs.com/package/espree
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hah. So easy: ee2b6bd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We might want to revert this commit for another ticket, but it's closely related and I think makes sense to go out together.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've decided to undo the upgrade from Esprima to Espree (f108a38). This seems like it would warrant loading Espree as a script module and I don't want this to get bogged down.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I drafted #10806 to pick this back up.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 9 out of 17 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Unprops Copilot for 7db8792 Co-authored-by: Copilot <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 9 out of 17 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…into trac-48456-codemirror-v5-upgrade
Remove extraneous new to fix JSHint: Weird construction. Is 'new' necessary? (W057)
Updates the `fakejshint.js` vendor shim to correctly store the provided options in `currentOptions` during parsing. Previously, `fakeJSHINT.data().options` would always return the initial empty object, failing to reflect the actual configuration used. This commit also: - Simplifies control flow in `getEcmaVersion()` by removing unnecessary `else` blocks. - Corrects a spelling error in the file header. - Updates JSDoc to correctly mark the `options` parameter as optional. Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
…into trac-48456-codemirror-v5-upgrade
sirreal
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left one minor suggestion.
Most of this is updating the build system to use the external package. The removed files all seem to be built in the same locations.
In my testing, Codemirror seems to work like it did before the update.
Co-authored-by: Jon Surrell <[email protected]>
Trac ticket: https://core.trac.wordpress.org/ticket/48456
For Gemini CLI, I provided the following spec:
I also provided https://github.com/WordPress/better-code-editing as context for where the CodeMirror integration originally came from.
I then iterated on the plan with Gemini for awhile, and came up with the following:
I then told Gemini to execute the plan, creating commits for each logical step. I reviewed each carefully and made amendments as needed.
Initial Gemini Review
Addressed in 2fb47e4, 3fb2281, 79295b3
Removed in 0dcbf28.
Yes, they match the original manifest: https://github.com/WordPress/better-code-editing/blob/master/wp-includes/js/codemirror/codemirror.manifest.js
Gemini also pointed out an issue where the core library was being included twice before. Now it is included once. This doesn't appear to have any impact on the resulting bundle size, however.
The new
codemirror.min.jsis 620,848 bytes. The old one was 585,414 bytes. So the newer version of CodeMirror is a bit larger.Yes. That is correct.
Since
fakehshint.jsis unchanged, it doesn't seem like it should have its version updated, even though it was swapped out originally in 5bb7fc1 without having its version changed (which it should have to bust caches).Second Gemini Review
The file was actually minified: https://github.com/WordPress/wordpress-develop/blob/trunk/src/js/_enqueues/vendor/codemirror/htmlhint.js
So this is consistent.
Keeping only the minified versions preserves the status quo, and keeps the ZIP from growing.
Demos
PHP file in Plugin Editor
Screen.Recording.2026-01-22.at.21.57.10.mov
JS file in Theme Editor
Screen.Recording.2026-01-22.at.22.09.17.mov
CSS file in Theme Editor
Screen.Recording.2026-01-22.at.22.10.33.mov
Additional CSS in Customizer
Screen.Recording.2026-01-22.at.22.11.47.mov
Custom HTML Widget with disallowed
unfiltered_htmlScreen.Recording.2026-01-22.at.22.14.07.mov
This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.