Skip to content

Style: Replace Grunt with @wordpress/scripts and modernize the build - #734

Draft
obenland wants to merge 8 commits into
WordPress:trunkfrom
obenland:style/modernize-build-tooling
Draft

Style: Replace Grunt with @wordpress/scripts and modernize the build#734
obenland wants to merge 8 commits into
WordPress:trunkfrom
obenland:style/modernize-build-tooling

Conversation

@obenland

Copy link
Copy Markdown
Member

Modernizes the build tooling and code style for wordpress.org/public_html/style/, and adds CI coverage for it.

Tooling

  • Replaces Grunt/JSHint with @wordpress/scripts 33: npm run build / build:css / build:js / format / lint:js.
  • js/navigation.min.js is built in place by webpack (webpack.config.js); wp4-rtl.css by a small bin/build-rtl.js, preserving the Dashicons arrow-swap and @import renaming that RTLCSS can't infer and that wp-scripts' built-in RTL support can't express.
  • Browser targets now extend the official @wordpress/browserslist-config, matching the wporg-*-2024 themes, replacing the 2013-era list (IE 7+, Android 2.1+). Autoprefixer and the self-referential wp4.css.map are dropped: under current targets the stylesheet needs no generated prefixes (the few remaining -webkit-/-moz- occurrences are intentional non-standard properties).

Code style

  • All JS in style/ (including trac/) now passes the stock @wordpress/scripts ESLint ruleset with zero errors, and is Prettier-formatted with a single local override (printWidth: 120).
  • HTML-building string concatenation is converted to template literals; query-string building on the GitHub-PRs endpoint uses URLSearchParams (which also percent-encodes values that previously went onto the wire raw).
  • Removes trac/trac-search.js, dead since its include was removed in r7275 (2018) — its API endpoint no longer exists.

CI

  • New style-lint.yml workflow runs on changes to JS/CSS under style/: ESLint, prettier --check, and a build-drift check that fails when committed build output (wp4-rtl.css, js/navigation.min.js) is out of sync with its source.

Docs

  • Adds README.md, trac/README.md, and AGENTS.md (with a CLAUDE.md wrapper): file inventory, development flow, testing Trac changes via DevTools local overrides, and the deploy flow (commit + sandbox deploy, then the follow-up scripts_version bump in both Trac templates).

Verification

  • wp4.css builds byte-identical under the new pipeline before the browserslist change; the RTL diff beyond that consists of drift the old pipeline had accumulated plus the prefix removal.
  • All converted string sites verified output-equivalent (modulo whitespace between block-level tags) across every conditional branch.
  • npm run lint:js, npx prettier --check ., node --check on all sources, and a full npm run build idempotency check all pass.

Note for deployment: the changes to trac/*.js will need the usual scripts_version bump in site_head.html/site_footer.html as a follow-up commit once the assets are deployed.

🤖 Generated with Claude Code

obenland and others added 4 commits July 24, 2026 09:48
- Swap Grunt/JSHint for @wordpress/scripts (build, lint-js, format), with a
  webpack config that builds js/navigation.min.js in place and a small
  bin/build-rtl.js for the RTL stylesheet, keeping the Dashicons arrow swap
  RTLCSS cannot infer.
- Adopt the default WordPress code style (Prettier at a 120 line length) and
  fix all ESLint errors; convert HTML-building string concatenation to
  template literals and query building to URLSearchParams.
- Update browser targets to @wordpress/browserslist-config, matching the rest
  of WordPress.org, and drop the vendor prefixes nothing supported needs
  anymore, along with the Autoprefixer pass and the self-referential
  wp4.css.map.
- Remove trac/trac-search.js, unused since its include was removed in r7275.
- Document the directory in README.md, trac/README.md, and AGENTS.md (with a
  CLAUDE.md wrapper): file inventory, development flow, testing Trac changes
  via DevTools overrides, and the deploy + scripts_version bump process.
Runs on changes to JS or CSS under wordpress.org/public_html/style/ and
fails when the tooling wasn't run: ESLint errors, unformatted files, or
committed build output (wp4-rtl.css, js/navigation.min.js) that is out of
sync with its source.
Folds wp-trac-jinja-compat.js/.css — the client-side port of the DOM
rewrites the old Genshi site.html applied server-side with py:match —
into the main files, after verifying every TODO(verify) against the
live Trac 1.6 installs.

The rewrites are integrated following the file's structure: distinct
features become named methods (updateAuthLinks, addContributorAvatars,
requestReporterFeedback, addNewTicketGuidance,
requireContributionLicense, markUgcLinks), run first from init() so
everything else sees the rewritten DOM; non-gardener restrictions
(forced preview, attachment replacement) join nonGardeners(); page
tweaks join hacks(); the report-list pre-collapse runs at script load
as preCollapseReportList().

Notable changes over the compat files:

* Query results: Trac 1.6 renders no h2.report-result heading on
  single-page queries, and the compat guard/count selectors matched
  nothing (visible today as a duplicate, wrong-count "Results (100)"
  heading on paginated queries). Guard on Trac's own heading and count
  the actual result rows.
* Report views: hide the "arguments are missing" warning only on
  /report/<n> and only for users without the "Edit report" button,
  restoring the original REPORT_MODIFY condition.
* Report list: pre-collapse the groups at script-load time, replacing
  the compat CSS rule that depended on a html.with-js class nothing
  sets ('/report' still flashes expanded groups today).
* Project name: derive from the page title ("<name> Trac") instead of
  the #headline, which produced "Make WordPress Core" on core and fell
  back to "Bbpress" on bbPress ("reporting bugs in Bbpress", live).
* Attachment replacement: remove the "Replace existing attachment"
  option for non-gardeners in JS instead of hiding it with a
  gardener-dependent body class.
* Dropped as dead on Trac 1.6: the residual s.w.org cache-buster
  (wpTracScriptsVersion is never defined; all assets ship versioned)
  and the #tab_keybindings rule (the pane no longer exists).

Until the follow-up commit removes the compat includes and bumps
scripts_version, cold caches that pick up the new file will briefly
apply the rewrites twice; that duplication is cosmetic and temporary.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015Nm6k2sd9zv3aRZZZt6XCp
Their behavior now lives in wp-trac.js and wp-trac.css; remove the
files, their template includes, and their README entries.

scripts_version is deliberately untouched: per the documented deploy
flow it gets bumped in a follow-up commit once the merged assets are
deployed, so the CDN never caches a stale file under the new version.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015Nm6k2sd9zv3aRZZZt6XCp
@obenland
obenland force-pushed the style/modernize-build-tooling branch from d1d8266 to 6b014cc Compare July 25, 2026 00:25
obenland and others added 4 commits July 24, 2026 19:33
jqXHR.success() was removed in jQuery 3.0, and Trac 1.6 ships jQuery
3.6, so wp_trac_auth_check() has thrown a TypeError on every five-
minute poll and the "Session expired" overlay could never appear.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015Nm6k2sd9zv3aRZZZt6XCp
* Re-seed the dynamic-asset cache buster from wp-trac.js's own URL;
  its old seed looked for a ?v= script tag that only the Genshi
  templates produced, leaving it a silent no-op since the 1.6 upgrade.
* Replace the deprecated jQuery event shorthands and $.trim() with
  .on()/.trigger() and String.prototype.trim(), ahead of jQuery 4
  removing $.trim.
* Drop the String.prototype.replaceAll() polyfill; every supported
  browser ships it natively.
* Drop isNewTicket()'s form-action fallback; no Trac 1.6 page besides
  /newticket contains a form posting there.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015Nm6k2sd9zv3aRZZZt6XCp
Adds wp-scripts lint-style (the stock @wordpress/stylelint-config) as
npm run lint:css, wired into the CI workflow, and conforms wp4.css and
trac/wp-trac.css to it. Prettier ignores *.css, so stylelint owns CSS
formatting outright.

The fixes are rendering-identical: formatting, notation (::before,
bold=700, named colors to hex, quote style), dropped declarations that
a later duplicate in the same block already overrode, and generic
font-family fallbacks — including 'Open Sans', "sans serif", which
quoted the generic keyword into a nonexistent font name.

Cascade-affecting rules (selector reordering/merging, renaming the
Trac and WP.org markup's own ids and classes, unit conversions) are
disabled in .stylelintrc.js. Vendored, generated, and frozen legacy
stylesheets are excluded via .stylelintignore; wp4-rtl.css is rebuilt
from the conformed wp4.css.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015Nm6k2sd9zv3aRZZZt6XCp
Chrome stores DevTools local overrides with the query string in the
file name and only matches that exact name; hand-placed files without
it are silently ignored, as are tabs without an open DevTools window.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015Nm6k2sd9zv3aRZZZt6XCp
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant