Opened 3 years ago
Last modified 5 months ago
#54568 new defect (bug)
WordPress admin overwrite JS history.state
Reported by: | maximeschoeni | Owned by: | |
---|---|---|---|
Milestone: | Awaiting Review | Priority: | normal |
Severity: | normal | Version: | |
Component: | General | Keywords: | has-patch |
Focuses: | javascript | Cc: |
Description
WordPress admin is injecting a piece of javascript at runtime (https://developer.wordpress.org/reference/functions/wp_admin_canonical_url/) that prevent accessing history.state. This is annoying because you cannot use history.pushState()
and history.replaceState()
functions properly in javascript.
Reproduce the bug:
- Navigate to any wp admin page and open the browser developer console
- Enter
window.history.replaceState({name: "hello"}, null)
in console - Navigate to any other page
- Go back and enter
history.state // result -> null
Problem:
The code overwrites any history.state with null
value:
window.history.replaceState( null, null, document.getElementById( 'wp-admin-canonical' ).href + window.location.hash );
Solution:
Replace null
value by window.history.state
(which also default to null):
window.history.replaceState( window.history.state, null, document.getElementById( 'wp-admin-canonical' ).href + window.location.hash );
The fix is very easy and has no side effect.
Attachments (1)
Change History (7)
#2
@
3 years ago
@maximeschoeni Thanks for the bug report.
Can you describe the use case for why you want to access history.state in wp-admin?
The original code here was introduced for https://core.trac.wordpress.org/ticket/23367
#3
@
3 years ago
Quite a specific thing, I needed a modal to open in a popup and the modal have different states and I thought it was nice if you can navigate between states using browser history... Actually there are different ways (probably betters) to do than storing things in history.state, but I was curious why it didn't work. I understand the purpose of this piece of javascript but I see no reason why it has to overwrite the history.state, and it rather sounds like a bug.
#4
@
3 years ago
- Version trunk deleted
Hello, thanks for reporting this ticket. It appears this issue wasn't introduced in WP 5.9, so I'm removing the trunk
version from the ticket.
#5
@
6 months ago
Hi, this affects us as well. Findkit Search provides a plugin for WordPress which can inject our search interface to the wp-admin as well. It uses history.state to preserve scroll position when user navigates back to it from a search result. Since the history.state is forced to be null on wp-admin, this feature is broken and there's really no reasonable workarounds.
The proposed patch seems reasonable to me.
--
Esa-Matti Suuronen
#6
@
5 months ago
Found a workaround with a monkey patch. Inject this JS early in the admin_head action:
const original = history.replaceState; history.replaceState = function findkitReplaceStatePatch(state, unused, url) { const canonical = document.getElementById('wp-admin-canonical').href + window.location.hash; if (state === null && url === canonical) { original.call(history, history.state, unused, url); history.replaceState = original; } else { original.call(history, state, unused, url); } }
it overrides the existing replaceState function and detects the invalid call and recalls it the original function with history.state as the first param. Afterwards it restores the original function.
Our full implementation is here:
https://github.com/findkit/wp-findkit/blob/b6b2bead0a29664fefb14a6088eab197be73aa06/src/BugFixWpAdminHistoryState.php
--
Esa-Matti Suuronen
The change makes sense to me!