WordPress.org

Make WordPress Core

Opened 3 years ago

Last modified 5 weeks ago

#28536 reviewing enhancement

Add browser history and deep linking for navigation in Customizer preview

Reported by: westonruter Owned by:
Milestone: 4.8 Priority: normal
Severity: normal Version: 3.4
Component: Customize Keywords: has-patch
Focuses: ui, javascript Cc:

Description

The Theme Customizer allows you to click links within the preview to navigate to other URLs to customize. Navigation within the preview is especially important now with the Widget Customizer, since many templates display render widget areas, and you may have to navigate to another URL in the preview to edit that template's widget areas.

When you navigate, however, the URL in the parent window does not update to reflect the URL inside of the preview. If the Customizer was first invoked from http://example.org/test-page/ then the URL in the Customizer will remain http://example.org/wp-admin/customize.php?url=http%3A%2F%2Fexample.org%2Ftest-page%2F no matter how much navigation is done in the preview. This makes it difficult to deep-link in the Customizer preview.

Additionally, you cannot currently use the browser's back button to return to the previously URL previewed in the Customizer.

To address the above usability problems, the Customizer should implement history.pushState and the popstate event. Some support for these were added when invoking the Customizer from for a theme preview, but it was only implemented to add support for exiting out of the Customizer via the back button. See [20488] for #20337.

Attachments (5)

28536.diff (2.2 KB) - added by westonruter 3 years ago.
Add browser history and deep-linking for navigation in Customizer preview. Sync link for Customizer close button with preview URL. Commits also pushed to GitHub: https://github.com/x-team/wordpress-develop/pull/16
28536.1.diff (8.2 KB) - added by westonruter 3 years ago.
When doing live preview, let default return be themes.php not url query param. pushState and popState on parent frame for Live Preview; update back link only outside Live Preview. Handle hitting back to themes page after having reloaded on a page in the Customizer. Close Live Preview customizer if no state or state w/o preview URL. When canceling Live Preview, pop history all the way to themes.php. Fix apparent race conditions where Window objects go away. Prevent clicking on illegal URLs from adding history. Ensure that popping to intial state restores original URL in preview. Additional commits: https://github.com/x-team/wordpress-develop/compare/e62df5e...def209e Pull request: https://github.com/x-team/wordpress-develop/pull/16
28536.2.diff (12.4 KB) - added by westonruter 3 years ago.
Fix Uncaught TypeError when accessing window. Use message passing instead of directly accessing parent window. Use message passing instead of directly accessing parent window. Commit: https://github.com/x-team/wordpress-develop/commit/0464541f300ea3889503abc2da8b08db45d17ffc PR: https://github.com/x-team/wordpress-develop/pull/16
28536.3.diff (11.7 KB) - added by westonruter 3 years ago.
Fix merge conflicts. PR: https://github.com/x-team/wordpress-develop/pull/16
28536.4.diff (11.4 KB) - added by westonruter 3 years ago.
Fix issue with messenger variable. https://github.com/x-team/wordpress-develop/commit/15bee01361ed3ab54e9f4ca8eaeaef68688fa50f https://github.com/x-team/wordpress-develop/pull/16

Download all attachments as: .zip

Change History (55)

@westonruter
3 years ago

Add browser history and deep-linking for navigation in Customizer preview. Sync link for Customizer close button with preview URL. Commits also pushed to GitHub: https://github.com/x-team/wordpress-develop/pull/16

#1 @westonruter
3 years ago

  • Keywords has-patch added

#2 follow-up: @westonruter
3 years ago

For some reason, the pushState URL rewriting is not working when opening the Customizer for a Live Preview of a theme-switch. Nevertheless, the states are getting pushed onto the history, and so navigation via the browser history is working (i.e. via the back/forward buttons). It's just that the URL is not getting rewritten.

#3 follow-up: @celloexpressions
3 years ago

This is a good idea; could almost consider it a bug. Related to this and #28542, it would be nice if users could see the URL being previewed in a readable manner. And it would be cool if the url was more contextual to the page being customized. What about implementing support for http://example.com/sample-page/customize-like URLs, similar to what the front-end editor does?

It would be a big improvement if both the document title and url were contextually updated. Of course, this ticket is a necessary first step to something like that.

@westonruter
3 years ago

When doing live preview, let default return be themes.php not url query param. pushState and popState on parent frame for Live Preview; update back link only outside Live Preview. Handle hitting back to themes page after having reloaded on a page in the Customizer. Close Live Preview customizer if no state or state w/o preview URL. When canceling Live Preview, pop history all the way to themes.php. Fix apparent race conditions where Window objects go away. Prevent clicking on illegal URLs from adding history. Ensure that popping to intial state restores original URL in preview. Additional commits: https://github.com/x-team/wordpress-develop/compare/e62df5e...def209e Pull request: https://github.com/x-team/wordpress-develop/pull/16

#4 in reply to: ↑ 2 @westonruter
3 years ago

  • Owner set to ocean90
  • Status changed from new to reviewing

Replying to westonruter:

For some reason, the pushState URL rewriting is not working when opening the Customizer for a Live Preview of a theme-switch. Nevertheless, the states are getting pushed onto the history, and so navigation via the browser history is working (i.e. via the back/forward buttons). It's just that the URL is not getting rewritten.

In 28536.1.diff this has been fixed, among other improvements as can seen in the commit log.

#5 follow-up: @westonruter
3 years ago

Humm, one more bug I'm noticing when using this in theme-switch Live Preview. The windowis unavailable inside of the popstate event for some reason, which previously committed workarounds. The issue is happening right here:

queryVars = self.parseQueryVars( location.search.substr( 1 ) );

I'm getting an exception:

Uncaught TypeError: Cannot read property 'substr' of undefined

If I change location to window.parent.location then the error is:

Uncaught TypeError: Cannot read property 'parent' of null

So again, the window becomes unavailable for some reason which I've not figured out yet.

#6 @westonruter
3 years ago

  • Milestone changed from Awaiting Review to Future Release

#7 @westonruter
3 years ago

#26464 was marked as a duplicate.

#8 in reply to: ↑ 3 @westonruter
3 years ago

Replying to celloexpressions:

This is a good idea; could almost consider it a bug. Related to this and #28542, it would be nice if users could see the URL being previewed in a readable manner. And it would be cool if the url was more contextual to the page being customized. What about implementing support for http://example.com/sample-page/customize-like URLs, similar to what the front-end editor does?

I've submitted this enhancement as #28570.

This ticket was mentioned in IRC in #wordpress-dev by westonruter. View the logs.


3 years ago

@westonruter
3 years ago

Fix Uncaught TypeError when accessing window. Use message passing instead of directly accessing parent window. Use message passing instead of directly accessing parent window. Commit: https://github.com/x-team/wordpress-develop/commit/0464541f300ea3889503abc2da8b08db45d17ffc PR: https://github.com/x-team/wordpress-develop/pull/16

#10 in reply to: ↑ 5 @westonruter
3 years ago

Replying to westonruter:

Humm, one more bug I'm noticing when using this in theme-switch Live Preview. The windowis unavailable inside of the popstate event for some reason, which previously committed workarounds.

Fixed in 28536.2.diff

This ticket was mentioned in IRC in #wordpress-dev by nacin. View the logs.


3 years ago

This ticket was mentioned in IRC in #wordpress-dev by celloexpressions. View the logs.


3 years ago

#13 @celloexpressions
3 years ago

  • Milestone changed from Future Release to 4.1

#14 @celloexpressions
3 years ago

@westonruter, what's the current status here? This is way beyond my abilities to review.

#15 @westonruter
3 years ago

  • Keywords needs-refresh added

There are conflicts between this patch and trunk now. Refresh is needed.

#16 @westonruter
3 years ago

  • Keywords needs-testing added; needs-refresh removed

OK, I did a quick job at fixing the merge conflicts in 28536.3.diff. I haven't had time to test with the refreshed patch yet.

#17 @westonruter
3 years ago

  • Milestone changed from 4.1 to Future Release

This ticket was mentioned in IRC in #wordpress-dev by westonruter. View the logs.


3 years ago

#19 @celloexpressions
2 years ago

  • Keywords needs-refresh added

I'm guessing the proposed Customizer transaction stuff would affect this. But, this is still a big paint point for front-end-contextual usability, so would love to see a solution here for 4.2.

This ticket was mentioned in Slack in #core-customize by westonruter. View the logs.


2 years ago

#21 @westonruter
17 months ago

  • Owner changed from ocean90 to westonruter

This ticket was mentioned in Slack in #core-customize by westonruter. View the logs.


17 months ago

#23 @westonruter
10 months ago

I'm happy to share a new feature plugin that implements the key parts of this ticket: Customizer Browser History.

This plugin keeps the Customizer URL in the browser updated with current previewed URL as the url query param and current expanded panel/section/control as autofocus params. This allows for bookmarking and also the ability to reload and return go the same view (which is great for developers). This works best with the Customize Snapshots plugin, which allows allows you to save your Customizer state in a shapshot/changeset with an associated UUID that also gets added to the browser URL in the Customizer.

It doesn't currently implement back/forward history (history.pushState and popstate), but it does implement the key feature of updating the browser's URL to reflect the current panel/section/control and URL being previewed. This allows you to reload the Customizer after navigating around and you'll be taken back to where you were before reloading. As I mentioned in the readme, this is extremely helpful for development.

See also the project repo on GitHub: https://github.com/xwp/wp-customizer-browser-history

#24 @westonruter
9 months ago

New release of feature plugin (0.2.0) includes persistence of the current previewed device upon reloads via a new customize_previewed_device query param.

#25 @westonruter
9 months ago

And here's a PR for that plugin which adds back/forward browser history for navigation in the Customizer preview: https://github.com/xwp/wp-customizer-browser-history/pull/8

#26 @westonruter
9 months ago

  • Milestone changed from Future Release to 4.7

Suggesting we might consider this for 4.7.

#27 @celloexpressions
9 months ago

It seems like the plugin is fairly stable and this is a relatively easy win in terms of UX. Shouldn't run into too many issues for this for 4.7.

#28 @westonruter
9 months ago

Versions 0.3.0 and 0.4.0 have been released: https://wordpress.org/plugins/customizer-browser-history/changelog/

Plugin includes back/forward browser navigation for the preview (as noted in comment 25) as well as remembering the scroll position for each URL being previewed, behaving the same way that the browser retains the scroll position when navigating through history _outside_ the customizer preview. The scroll position is also retained when reloading the page, making it very useful for development.

#29 @celloexpressions
8 months ago

I've noticed some major performance issues when using the plugin in conjunction with the patch on #37661 (haven't tested without) and autofocusing to the new themes panel. Let's make sure there are no impacts on initial page load time, especially where controls are loaded dynamically via ajax.

#30 @westonruter
8 months ago

@celloexpressions I'm not seeing a performance impact without the patch for #37661. It could potentially be due to something with customize-loader and the changes in your patch. What specifically is showing poor performance?

BTW, the URL rewriting is not currently working when customize-loader is used. I just filed an issue for that: https://github.com/xwp/wp-customizer-browser-history/issues/13

#31 @celloexpressions
8 months ago

My guess is that it's related to the way theme controls will be lazy-loaded via ajax, but not sure exactly where the hangup is. We can investigate further once both projects are bit further along and verify if there's an issue. For the themes panel, we'll actually need to make sure that the autofocus is removed entirely, though, as the new pageload when loading a theme needs to open back to the top level. We'll need a strategy for updating the preview URL on the theme controls dynamically as well, although it might be acceptable to continue grabbing that from PHP since history, etc. is reset with the pageload anyway for now. Or, grab it directly in JS and do add_query_args there.

This ticket was mentioned in Slack in #core-customize by celloexpressions. View the logs.


8 months ago

This ticket was mentioned in Slack in #core-customize by celloexpressions. View the logs.


8 months ago

This ticket was mentioned in Slack in #core-customize by celloexpressions. View the logs.


7 months ago

This ticket was mentioned in Slack in #core-customize by celloexpressions. View the logs.


7 months ago

#36 @celloexpressions
7 months ago

This came up in the customizer themes user testing as something that users expect to work: https://make.wordpress.org/design/2016/09/23/user-testing-the-new-customizer-themes-experience/.

#37 @westonruter
7 months ago

  • Keywords needs-patch added; has-patch needs-testing needs-refresh removed

Blocked by transactions (#30937) because when the natural URL is used in the preview and navigation within the preview is done normally without the url being sent via postMessage to the parent frame, browser navigation then “just works” for the window in the iframe, and it will then be the task of browser history to do a history.replaceState() on the top window to keep it synced with whatever URL is being viewed in the preview at that time.

This ticket was mentioned in Slack in #core-customize by celloexpressions. View the logs.


7 months ago

This ticket was mentioned in Slack in #core-customize by celloexpressions. View the logs.


7 months ago

This ticket was mentioned in Slack in #core by jeffpaul. View the logs.


7 months ago

This ticket was mentioned in Slack in #core-customize by celloexpressions. View the logs.


6 months ago

This ticket was mentioned in Slack in #core-customize by westonruter. View the logs.


6 months ago

#43 @westonruter
6 months ago

Related defect: #38377

#44 @westonruter
6 months ago

  • Keywords has-patch added; needs-patch removed

The Customizer Browser History plugin code has been refactored into a patch and improved to work with customize-loader. Patch is available for review and testing at https://github.com/xwp/wordpress-develop/pull/181

The most brittle part of this code I'd say would be the use of back/forward navigation when using customize loader. If you are on the themes page, click to preview a theme, make some changes, and then switch to another theme in the customizer: if you then start going back, it feels the browser history can get confused.

To apply the patch, run grunt patch:https://github.com/xwp/wordpress-develop/pull/181

I'm currently 50/50 on whether to push for this or punt it, letting it remain as feature plugin.

This ticket was mentioned in Slack in #core-customize by celloexpressions. View the logs.


6 months ago

#46 @westonruter
6 months ago

  • Milestone changed from 4.7 to Future Release
  • Owner westonruter deleted

Punting. Will live in feature plugin for now.

This ticket was mentioned in Slack in #core-customize by melchoyce. View the logs.


2 months ago

#48 @westonruter
2 months ago

  • Milestone changed from Future Release to 4.8

#49 @westonruter
2 months ago

Tentatively we're thinking to use the functionality as it exists in the feature plugin which only applies when customize-loader is not used, and also to remove customize-loader from being used in core. Currently the customize-loader is used on the themes admin screen and for the Customize button on the admin dashboard, but it is not technically needed and it adds a lot of complexity which makes browser history in the customizer challenging. The primary gain in using customize-loader is that exiting the customizer is very fast because it just means an iframe is removed from the document. On the themes admin screen, which uses JS for theme search, also manipulates the browser history so returning to the themes admin will already restore the previous search. We'll have to evaluate the pros and cons.

#50 @westonruter
5 weeks ago

I've opened #40254 to eliminate core use of customize-loader.

Note: See TracTickets for help on using tickets.