Reset the plugin-update notifiers live after updates run - #408
Merged
Conversation
Core's shiny updater applies plugin/theme updates over AJAX, so the chromeless bridge's load-time payload emit never re-fired and both the admin-bar circle-arrows count and the dock Plugins badge kept their boot-time numbers until a hard refresh. The bridge now watches updates.js completion events and nudges the shell (desktop-mode-updates-changed), posts payload/signature to the top window so the bulk updater's nested update.php iframe reaches the shell, and the payload carries aggregate updateCounts that the shell mirrors onto #wp-admin-bar-updates via one debounced refreshMenu() probe.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #296
What it does
After updating plugins (or themes) inside the desktop shell, the two update notifiers now reset live, with no hard refresh:
#wp-admin-bar-updates) — the element reported in Plugin update notifier does not reset #296,Both flows are covered: per-plugin "update now" links on
plugins.php(Core's shiny AJAX updater) and the bulk "Update Plugins" run on the Updates screen. When the count reaches zero the admin-bar node disappears, exactly as a fresh server render would; if updates appear later on a shell that booted clean, the node is re-created in Core's slot order.Rationale
Two gaps compounded:
plugins.php/themes.php/ etc. Shiny updates run over AJAX with no navigation, so the shell never learned the counts changed — the dock badge went stale.#wp-admin-bar-updates: it is static server HTML rendered at shell boot, so even a fresh payload could not fix it.A third, related gap: the bulk updater nests a progress iframe (
update-core.php→update.php?action=update-selected) whoseiframe_footer()firesadmin_footerafter the upgrades ran — a perfectly fresh payload — but posted it towindow.parent, i.e. the intermediateupdate-core.phppage, which has no listener.Implementation
Follows the existing live-refresh pattern (payload key + shell applier), no new mechanism:
includes/render/chromeless-bridge.php— a shiny-update watcher binds the jQuery eventsupdates.jstriggers ondocument(wp-plugin-update-success/-error,wp-plugin-delete-success, theme counterparts) and posts a payload-lessdesktop-mode-updates-changednudge oncewp.updates.queueis drained. Error events are included deliberately:wp_ajax_update_plugincallswp_update_plugins()up front, which can mutate the transient even when the upgrade fails. The payload/signature emit now targets the top window instead of the immediate parent — identical for normal window iframes, and it lets the nested bulk-updater payload reach the shell.includes/core/payload.php— the menu payload gainsupdateCounts(total, locale-formatted count, translated screen-reader text,update-core.phpURL) from capability-awarewp_get_update_data(), prebuilt server-side so the client repaint stays locale-correct.src/boot/menu-refresh.ts— handles the nudge with a 600 ms trailing debounce plus in-flight coalescing (a nudge landing mid-probe queues exactly one follow-up probe), then spends one existingrefreshMenu()probe.src/admin-bar-updates.ts(new, wired fromsrc/menu-refresh-apply.ts) — mirrorsupdateCountsonto the admin-bar node: label + screen-reader text, hidden at zero, re-created mirroring Core'swp_admin_bar_updates_menu()markup when absent. Missing key (older payload) means "no change". The dock badge needs no new code — the probe's payload already recomputes it.Docs updated in the same change:
docs/javascript-reference.md(payload shape + new message),docs/api-index.md, and the payload key listing inAGENTS.md.Testing instructions
npm run test:js # includes 8 new cases for the admin-bar repaint + 2 payload-contract cases npm run test:php -- --filter test_payload_carries_update_countsManual repro (mirrors the issue):
wp plugin install classic-editor --version=1.6.5andwp plugin install akismet --version=5.3, thenwp eval 'wp_update_plugins();'.Verified end-to-end on wp-env: counter stepped 3→2→1→hidden with per-plugin updates, and the bulk run cleared both notifiers the moment "All updates have been completed" appeared. Full suites green: 2178 vitest tests, 1333 PHPUnit tests, typecheck, ESLint, PHPCS (no new violations).