Opened 12 years ago
Closed 8 years ago
#23225 closed defect (bug) (fixed)
Customizer is Incompatible with jQuery UI Tabs.
Reported by: | mfields | Owned by: | westonruter |
---|---|---|---|
Milestone: | 4.7 | Priority: | normal |
Severity: | normal | Version: | 3.4 |
Component: | Customize | Keywords: | has-patch needs-testing |
Focuses: | Cc: |
Description
Steps to reproduce:
- Install the attached mfields-test-jquery-ui-tabs.php plugin.
- Open the Chrome console.
- Open the customizer and watch the console.
At this point you should see that a slew of XHR requests are triggered. If you reach a certain type of javascript error then the XHR requests will stop and the preview frame in the customizer will go blank.
It seems like jQuery UI Tabs and the customizer are currently incompatible. This will affect any theme or plugin that is using this library including the popular Genesis Tabs plugin.
Attachments (3)
Change History (48)
#11
@
11 years ago
This is related to a hotly debated jQuery "bug" related to the use of the <base>
tag, which done by the Customizer. See their ticket here: http://bugs.jqueryui.com/ticket/7822
Specifically, the result of jQuery UI Tab's isLocal()
on hash-only urls (e.g. href="#my-tab-1"
) unexpectedly returns false. This triggers an ajax call to pull in the tab's content. In the Customizer's case, that's the Customizer page itself (not pretty.)
Possible fixes:
The jQuery dev team recommends the use of absolute URLs.
I will suggest a simple check to see if URL to the left of the hash is an empty string which should be "local" by definition, though I forsee poor reception.
One commenter on the ticket has detailed the problem and a few suggestions here http://tjvantoll.com/2013/02/17/using-jquery-ui-tabs-with-the-base-tag/. His third suggestion is a hacky work-around but may be the most universal fix for the Customizer barring a solution by jQuery.
#13
@
11 years ago
The preceding patch makes two changes:
- It adds an ID to the
<base>
tag injected by the Customizer. It's a shortcut for the rest of the code but future customizer enhancements may find it useful as well.
- Injects an inline script in the footer that prepends all links that begin with # with the absolute URL of the Customizer.
This has the benefit of restoring expected behavior of hash-links which had been broken in any way while the Customizer was in use.
I'd prefer to avoid script injection but I think it was the easiest method to ensure remapping before jQuery's ready event fired. The mfields plugin test case showed proper behavior but I'm looking for more feedback about the approach and cross-browser testing.
#16
@
11 years ago
The patch provided by @deltafactory appears to resolve the issue with jQuery UI Tabs.
#17
@
11 years ago
Just reading the patch - will this approach work for any other page beyond the site home, since the base URL is home_url
?
#19
@
11 years ago
@helen, the patch works by tricking jQuery UI's isLocal() function into thinking that a # link is local by matching the domain of the hash URL to the page's. So it should work anywhere that the domain for the Customizer (derived from admin_url()
?) is the same as home_url()
.
I believe it will break regular hash URLs, though no more than the initial use of the <base>
tag.
I don't recall the exact code, but if there's another way to determine the interior page's URL then I'd be happy to use that. Between the method used by the Customizer to inject the HTML into the iframe, and cross-frame security, there may be limitations though I'd have to take a closer look.
#20
@
10 years ago
Not sure if this is still relevant given ongoing improvements to Customizer, but would be interested in feedback/inclusion in 4.1.
#21
@
10 years ago
- Milestone changed from Awaiting Review to 4.1
In class-wp-customize-manager.php.patch, I'm seeing that document.location.href
is not returning the URL of the Customizer preview even though a base[href]
is being set (e.g. I'm seeing http://src.wordpress-develop.dev/wp-admin/customize.php
instead of http://src.wordpress-develop.dev/
). This is probably due to the fact that the preview iframe
is getting populated dynamically via adocument.write()
call and not by actually being navigated to, so the preview window is inheriting the parent window's document.location.href
.
So It seems way for preview to determine its own URL is to instead look at the base
DOM element's href
property. In 23225.2.patch I've made this change. It's also now using jQuery to update the link href
attributes, and it is outputting a base[href]
containing the REQUEST_URI
not just the home
, to address your concern @helen.
Nevertheless, the Customizer hasn't been taking into account that a theme may be outputting a base
element of its own. Also, if the Customizer preview dynamically adds new #
links they're not going to be rewritten to have the right base
.
Patches for this ticket are added to a PR on GitHub: https://github.com/xwpco/wordpress-develop/pull/30
As an aside, all of this leads me to think that the current method for populating the Customizer preview iframe
introduces fundamental limitations, and some things that just aren't going to work in the way it is currently designed. It would be better if we could use the iframe
in a more traditional way, setting the src
attribute to the URL being previewed (doing a GET request) and not doing document.write()
on an about:blank
iframe (writing the response to an Ajax POST
); this would require an alternative back-channel for passing the settings data to the preview.
#22
follow-up:
↓ 23
@
10 years ago
The behavior you were seeing from document.location.href is "correct" (the source of the entire bug/dispute with jQuery UI) and directly related to the issue my patch resolved.
I agree with your concerns about the use of base
, document.write()
etc. though I intentionally avoided using jQuery as a dependency for the same reason.
#23
in reply to:
↑ 22
@
10 years ago
Replying to deltafactory:
The behavior you were seeing from document.location.href is "correct" (the source of the entire bug/dispute with jQuery UI) and directly related to the issue my patch resolved.
I'm not sure I understand. So it was intended that document.location.href
should be …/wp-admin/customize.php
and not the actual base URL for the URL being previewed?
#24
@
10 years ago
Based on jQuery UI's isLocal()
declaration, now refactored to _isLocal()
here: https://github.com/jquery/jquery-ui/blob/master/ui/tabs.js#L45 ... they define a local URL as one that is the same as location.href, up to the hash.
It's this definition of local that is the root of the jQuery UI tab incompatibility and the resulting remote request causes the recursive glitches.
To actually answer your question: yes. :)
#25
@
10 years ago
Humm, then I'm not sure patching Core to supply a wp-admin
URL as the base URL for links inside the preview is desirable. It seems like this hack to fix one script's problem could cause unintended side-effects elsewhere in other scripts.
#26
@
10 years ago
It's not the most elegant solution but I think it fixes more than it breaks. To your point, as I said once upon a time in comment 19.
I believe it will break regular hash URLs, though no more than the initial use of the
<base>
tag.
Until such time as the Customizer iframe
implementation is replaced, it seems like there are a number of issues that can't be fixed.
Since the ticket was marked has-patch
, needs-testing
with some positive feedback, I'd be happy to receive feedback on failed tests in lieu of a reimplementation.
This ticket was mentioned in IRC in #wordpress-dev by celloexpressions. View the logs.
10 years ago
#28
@
10 years ago
I've opened #30028 to investigate the alternative strategy for managing the Customizer iframe
.
This ticket was mentioned in Slack in #core by ocean90. View the logs.
10 years ago
#30
@
10 years ago
- Milestone changed from 4.1 to Future Release
The latest patch doesn't fix the issue. Punt.
#31
@
10 years ago
... The latest patch didn't fix the issue, but the next-to-last patch did. Is #30028 the future of the Customizer? Did my patch break anything? I'm still not sure why it was superseded by a patch that didn't quite fix the problem.
To westonruter's main concern that it will break non-jQuery tabs, I believe the behavior intended by use "#idref" urls in other situations is retained or improved by the technique implemented here.
While it's definitely too late for inclusion into 4.1, I would still like feedback. In the event that a reimplementation of the Customizer previous mechanism is in the works, I would like to be part of that discussion as well.
#32
@
10 years ago
deltafactory is right. The penultimate patch is the one that would have fixed the problem, although it was a workaround for a more fundamental issue which #30028 would address. Nothing has been done on that front yet, however, though I'll be sure to post any updates to the ticket when I get a chance to work on a proof of concept. I probably won't be able to until Christmas break, however.
This ticket was mentioned in Slack in #core-customize by westonruter. View the logs.
10 years ago
This ticket was mentioned in Slack in #core-customize by westonruter. View the logs.
10 years ago
#36
@
9 years ago
Using WP 4.3...
I have a shortcode that implements http://www.getmdl.io/components/index.html#layout-section/tabs (does not use jQuery).
Even when I make the HREFs absolute to the current page's permalink (e.g. #panel-7 --> http://my.dev?page_id=741#panel-7), the WP Customizer preview gets reloaded instead of switching to the tab I clicked within the current page view.
Yeah, at least the tab link stays on the current page instead of #panel-7 going to http://my.dev#panel-7, but the user's click to switch tabs inside the WP Customizer preview still does not work as expected.
This ticket was mentioned in Slack in #core-customize by westonruter. View the logs.
8 years ago
#38
@
8 years ago
- Milestone changed from Future Release to 4.6
- Owner set to westonruter
- Status changed from new to accepted
#39
@
8 years ago
- Milestone changed from 4.6 to Future Release
Punting due to transactions being too large to finish patch and test in time for 4.6.
#40
@
8 years ago
Similar problem, but when with a newer version of jquery.ui.tabs it works fine https://github.com/ThemeFuse/Unyson/issues/1794#issuecomment-233609296
This ticket was mentioned in Slack in #core-customize by celloexpressions. View the logs.
8 years ago
#42
@
8 years ago
- Keywords needs-patch added; needs-testing has-patch removed
This is still pending transactions and #30028.
#43
@
8 years ago
- Keywords has-patch needs-testing added; needs-patch removed
- Milestone changed from Future Release to 4.7
This has been implemented in the patch for #30937.
Please test: grunt patch:https://github.com/xwp/wordpress-develop/pull/161
Related: #24032