Add explicit variables to fix use strict.#12371
Conversation
Each of the variables declared at the top are included either are already used in the global scope or are prefixed. Trac Ticket: https://core.trac.wordpress.org/ticket/65515 AI Disclosure: Debugged and initial patch including tests generated with Opencode and gpt-5.5. Manually checked and adjusted to reduce the number of variables in the global scope.
This comment was marked as outdated.
This comment was marked as outdated.
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. |
|
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. |
There was a problem hiding this comment.
Pull request overview
This PR updates the vendored Thickbox script to be safe when executed under strict mode (e.g., when concatenated after a "use strict" script) by making previously implicit globals explicit, and adds a QUnit regression test to ensure Thickbox initializes under strict mode.
Changes:
- Declare previously implicit Thickbox state variables (
imgLoader,TB_*) explicitly to avoid strict-modeReferenceErrors. - Convert a few other implicit/global assignments inside
tb_show()/tb_getPageSize()into properly scoped locals / direct returns. - Add a QUnit test that loads the Thickbox source and evaluates it under strict mode, asserting initialization does not throw.
Reviewed changes
Copilot reviewed 1 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| tests/qunit/wp-includes/js/thickbox.js | Adds a strict-mode initialization regression test for Thickbox. |
| src/js/_enqueues/vendor/thickbox/thickbox.js | Makes Thickbox variables explicitly declared/scoped to avoid strict-mode failures. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| (function (QUnit) { | ||
| QUnit.module('thickbox'); | ||
|
|
||
| QUnit.test( | ||
| 'initializes when concatenated after a strict-mode script', | ||
| function (assert) { |
|
With 0b5ea7e the file is now clean of JSHint errors (well, it is suppressing errors in what appear to be unrelated to strict mode or which are not actual issues). |
| @@ -1,14 +1,29 @@ | |||
| 'use strict'; | |||
There was a problem hiding this comment.
Adding this seems safer than just relying on loading it with QUnit as strict mode, because some strict mode semantics would only affect the behavior at runtime. And since QUnit isn't attempting to do full test coverage, there would be issues which possibly aren't detected. However, since now JSHint is checking the file for issues (b4ed2e7), and the only strict-mode specific error is W040 ("JSHint: If a strict mode function is executed using function invocation, its 'this' value will be undefined.") which I've confirmed to not be an issue in tb_click() since it is passed to jQuery as an event handler, I think it's better to include use strict so that any strict mode issues can be detected with static analysis.
There was a problem hiding this comment.
Looking at the big picture - isn't adding use strict at the top of the file just making the problem worse?
Now if thickbox.js is concatenated with other scripts, and thickbox.js happens to be the first script, it will put all scripts in the concatenation into strict mode. If some of the other scripts expect to be run in sloppy mode, that could cause issues with those scripts.
(As a compromise, you could put use strict into each of the individual outermost functions instead. There are 10 functions, so you would need to repeat it 10 times. But it should be safer than putting it at the top of the file.)
There was a problem hiding this comment.
That's a good point. I suppose it depends a bit on how many core scripts are currently in strict of sloppy mode. If thickbox is the outlier in being sloppy, then the way it is here seems fine. Otherwise, if there are many cases of sloppy mode scripts then your suggestion is probably the better way to go.
There was a problem hiding this comment.
I've switched to using the function form of use strict in aedfc3e
An added benefit is it eliminates the need to suppress the W097 warning (Use the function form of 'use strict') in JSHint.
Under `'use strict'`, function declarations nested inside `if` blocks are block-scoped (Annex B hoisting is disabled), so the keydown handler's `goNext()`/`goPrev()` calls threw `ReferenceError` when paging between images in a grouped Thickbox. Declare both as function expressions in the enclosing scope so the handler can reach them, keeping the `if` guards on the click bindings. This also makes the JSHint W082 suppression unnecessary. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
I had Claude Opus 4.8 (with 1M context) search Veloria for the variables newly removed from the global scope along with the ones which are now explicitly made global: The evidence is now conclusive. The Findings1. Variables now restricted to lexical scope (the breakage-risk set)
These four were always function-internal temporaries, never part of any documented or de-facto API. Scoping them lexically (or removing 2. Variables kept explicitly in global scope (the top-level
|
westonruter
left a comment
There was a problem hiding this comment.
I tried opening the plugin details lightbox in Playground with this PR, and it works. However, it works for me in 7.0 as well.
Move the strict-mode directive from file scope into each of the 10
outermost functions. A file-level 'use strict' would, if thickbox.js
were the first script in a concatenated bundle, force every other
script in that bundle into strict mode, potentially breaking scripts
that rely on sloppy-mode semantics. The function form scopes strict
mode to thickbox's own functions only.
The now-unnecessary JSHint W097 suppression ("Use the function form of
'use strict'") is removed since the function form no longer triggers it.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: siliconforks <siliconforks@git.wordpress.org>
westonruter
left a comment
There was a problem hiding this comment.
While making Thickbox strict-mode compatible is attractive, I think the better approach is WordPress/gutenberg#79792 since it is comprehensive, specifically targeting the original regression that caused the issue in the first place. It also avoids the need to patch vendor libraries like this (although surely such patching is not unique).
Each of the variables declared at the top are included either are already used in the global scope or are prefixed.
Trac Ticket: https://core.trac.wordpress.org/ticket/65515
Use of AI Tools
AI assistance: Yes
Debugged and initial patch including tests generated with Opencode and gpt-5.5. Manually checked and adjusted to reduce the number of variables in the global scope.
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.