-
Notifications
You must be signed in to change notification settings - Fork 5.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
v1.14.1: regression in tabs with non-standard IDs #2344
Comments
Thanks for the report and easy to run test cases! This was caused by #2307. I'll have a look at it for |
I added decoding in #2307 as it's needed for some complex characters like emojis to work - it's interesting that the linked issue claims it's emoji handling that's now broken... 🤔 |
I wanted to see if we should or should not be decoding the anchor hash value in the end. I checked native browser behavior, without jQuery UI - one was testing whether anchor1.hash // '#%F0%9F%A4%97' for `<a href="#🤗">`
anchor2.hash // '#%F0%9F%98%85' for `<a href="#😅">` we have the following:
However, in the browser, clicking any of them will scroll to the proper div. 🤔 That got me curious so I looked into the specs. It starts with the "scrolling to a fragment" section of the HTML spec. That uses a concept of document's indicated part. Slightly below there's an algorithm to compute the indicated part. The interesting parts are steps 4 to 9:
First, in steps 4-5, the algorithm tries the hash as-is, without decoding. Then, if one is not found, the same is attempted with a decoded hash. Yes, it actually checks both! That complicates things as we cannot compute the id from the hash without running a query and checking if an element with a matching id is actually in the DOM. 🤕 As part of that, we should also perhaps revert 1e5662e (this part should also be tested). |
Prior to jQuery UI 1.14.1, hashes in anchor hrefs were used directly. In jquerygh-2307, that was changed - by decoding - to support more complex IDs, e.g. containing emojis which are automatically encoded in `anchor.hash`. Unfortunately, that broke cases where the panel ID is decoded as well. It turns out the spec mandates checking both. In the "scrolling to a fragment" section of the HTML spec[^1]. That uses a concept of document's indicated part[^2]. Slightly below there's an algorithm to compute the indicated part[^3]. The interesting parts are steps 4 to 9: 4. Let potentialIndicatedElement be the result of finding a potential indicated element given document and fragment. 5. If potentialIndicatedElement is not null, then return potentialIndicatedElement. 6. Let fragmentBytes be the result of percent-decoding fragment. 7. Let decodedFragment be the result of running UTF-8 decode without BOM on fragmentBytes. 8. Set potentialIndicatedElement to the result of finding a potential indicated element given document and decodedFragment. 9. If potentialIndicatedElement is not null, then return potentialIndicatedElement. First, in steps 4-5, the algorithm tries the hash as-is, without decoding. Then, if one is not found, the same is attempted with a decoded hash. This change replicates this logic by first trying the hash as-is and then decoding it. Fixes jquerygh-2344 Ref jquerygh-2307 [^1]: https://html.spec.whatwg.org/#scrolling-to-a-fragment [^2]: https://html.spec.whatwg.org/#the-indicated-part-of-the-document [^3]: https://html.spec.whatwg.org/#select-the-indicated-part
Prior to jQuery UI 1.14.1, hashes in anchor hrefs were used directly. In jquerygh-2307, that was changed - by decoding - to support more complex IDs, e.g. containing emojis which are automatically encoded in `anchor.hash`. Unfortunately, that broke cases where the panel ID is decoded as well. It turns out the spec mandates checking both. In the "scrolling to a fragment" section of the HTML spec[^1]. That uses a concept of document's indicated part[^2]. Slightly below there's an algorithm to compute the indicated part[^3]. The interesting parts are steps 4 to 9: 4. Let potentialIndicatedElement be the result of finding a potential indicated element given document and fragment. 5. If potentialIndicatedElement is not null, then return potentialIndicatedElement. 6. Let fragmentBytes be the result of percent-decoding fragment. 7. Let decodedFragment be the result of running UTF-8 decode without BOM on fragmentBytes. 8. Set potentialIndicatedElement to the result of finding a potential indicated element given document and decodedFragment. 9. If potentialIndicatedElement is not null, then return potentialIndicatedElement. First, in steps 4-5, the algorithm tries the hash as-is, without decoding. Then, if one is not found, the same is attempted with a decoded hash. This change replicates this logic by first trying the hash as-is and then decoding it. Fixes jquerygh-2344 Ref jquerygh-2307 [^1]: https://html.spec.whatwg.org/#scrolling-to-a-fragment [^2]: https://html.spec.whatwg.org/#the-indicated-part-of-the-document [^3]: https://html.spec.whatwg.org/#select-the-indicated-part
Prior to jQuery UI 1.14.1, hashes in anchor hrefs were used directly. In jquerygh-2307, that was changed - by decoding - to support more complex IDs, e.g. containing emojis which are automatically encoded in `anchor.hash`. Unfortunately, that broke cases where the panel ID is decoded as well. It turns out the spec mandates checking both. In the "scrolling to a fragment" section of the HTML spec[^1]. That uses a concept of document's indicated part[^2]. Slightly below there's an algorithm to compute the indicated part[^3]. The interesting parts are steps 4 to 9: 4. Let potentialIndicatedElement be the result of finding a potential indicated element given document and fragment. 5. If potentialIndicatedElement is not null, then return potentialIndicatedElement. 6. Let fragmentBytes be the result of percent-decoding fragment. 7. Let decodedFragment be the result of running UTF-8 decode without BOM on fragmentBytes. 8. Set potentialIndicatedElement to the result of finding a potential indicated element given document and decodedFragment. 9. If potentialIndicatedElement is not null, then return potentialIndicatedElement. First, in steps 4-5, the algorithm tries the hash as-is, without decoding. Then, if one is not found, the same is attempted with a decoded hash. This change replicates this logic by first trying the hash as-is and then decoding it. Fixes jquerygh-2344 Ref jquerygh-2307 [^1]: https://html.spec.whatwg.org/#scrolling-to-a-fragment [^2]: https://html.spec.whatwg.org/#the-indicated-part-of-the-document [^3]: https://html.spec.whatwg.org/#select-the-indicated-part
Prior to jQuery UI 1.14.1, hashes in anchor hrefs were used directly. In jquerygh-2307, that was changed - by decoding - to support more complex IDs, e.g. containing emojis which are automatically encoded in `anchor.hash`. Unfortunately, that broke cases where the panel ID is decoded as well. It turns out the spec mandates checking both. In the "scrolling to a fragment" section of the HTML spec[^1]. That uses a concept of document's indicated part[^2]. Slightly below there's an algorithm to compute the indicated part[^3]. The interesting parts are steps 4 to 9: 4. Let potentialIndicatedElement be the result of finding a potential indicated element given document and fragment. 5. If potentialIndicatedElement is not null, then return potentialIndicatedElement. 6. Let fragmentBytes be the result of percent-decoding fragment. 7. Let decodedFragment be the result of running UTF-8 decode without BOM on fragmentBytes. 8. Set potentialIndicatedElement to the result of finding a potential indicated element given document and decodedFragment. 9. If potentialIndicatedElement is not null, then return potentialIndicatedElement. First, in steps 4-5, the algorithm tries the hash as-is, without decoding. Then, if one is not found, the same is attempted with a decoded hash. This change replicates this logic by first trying the hash as-is and then decoding it. Fixes jquerygh-2344 Ref jquerygh-2307 [^1]: https://html.spec.whatwg.org/#scrolling-to-a-fragment [^2]: https://html.spec.whatwg.org/#the-indicated-part-of-the-document [^3]: https://html.spec.whatwg.org/#select-the-indicated-part
Prior to jQuery UI 1.14.1, hashes in anchor hrefs were used directly. In jquerygh-2307, that was changed - by decoding - to support more complex IDs, e.g. containing emojis which are automatically encoded in `anchor.hash`. Unfortunately, that broke cases where the panel ID is decoded as well. It turns out the spec mandates checking both. In the "scrolling to a fragment" section of the HTML spec[^1]. That uses a concept of document's indicated part[^2]. Slightly below there's an algorithm to compute the indicated part[^3]. The interesting parts are steps 4 to 9: 4. Let potentialIndicatedElement be the result of finding a potential indicated element given document and fragment. 5. If potentialIndicatedElement is not null, then return potentialIndicatedElement. 6. Let fragmentBytes be the result of percent-decoding fragment. 7. Let decodedFragment be the result of running UTF-8 decode without BOM on fragmentBytes. 8. Set potentialIndicatedElement to the result of finding a potential indicated element given document and decodedFragment. 9. If potentialIndicatedElement is not null, then return potentialIndicatedElement. First, in steps 4-5, the algorithm tries the hash as-is, without decoding. Then, if one is not found, the same is attempted with a decoded hash. This change replicates this logic by first trying the hash as-is and then decoding it. Fixes jquerygh-2344 Ref jquerygh-2307 [^1]: https://html.spec.whatwg.org/#scrolling-to-a-fragment [^2]: https://html.spec.whatwg.org/#the-indicated-part-of-the-document [^3]: https://html.spec.whatwg.org/#select-the-indicated-part
Prior to jQuery UI 1.14.1, hashes in anchor hrefs were used directly. In jquerygh-2307, that was changed - by decoding - to support more complex IDs, e.g. containing emojis which are automatically encoded in `anchor.hash`. Unfortunately, that broke cases where the panel ID is decoded as well. It turns out the spec mandates checking both. In the "scrolling to a fragment" section of the HTML spec[^1]. That uses a concept of document's indicated part[^2]. Slightly below there's an algorithm to compute the indicated part[^3]. The interesting parts are steps 4 to 9: 4. Let potentialIndicatedElement be the result of finding a potential indicated element given document and fragment. 5. If potentialIndicatedElement is not null, then return potentialIndicatedElement. 6. Let fragmentBytes be the result of percent-decoding fragment. 7. Let decodedFragment be the result of running UTF-8 decode without BOM on fragmentBytes. 8. Set potentialIndicatedElement to the result of finding a potential indicated element given document and decodedFragment. 9. If potentialIndicatedElement is not null, then return potentialIndicatedElement. First, in steps 4-5, the algorithm tries the hash as-is, without decoding. Then, if one is not found, the same is attempted with a decoded hash. This change replicates this logic by first trying the hash as-is and then decoding it. Fixes jquerygh-2344 Ref jquerygh-2307 [^1]: https://html.spec.whatwg.org/#scrolling-to-a-fragment [^2]: https://html.spec.whatwg.org/#the-indicated-part-of-the-document [^3]: https://html.spec.whatwg.org/#select-the-indicated-part
Hello, thanks for the fix and apologies for the late reply. I was monitoring this issue but I've somehow missed the notification. I confirm that #2345 fixes the issue we were having on ActiveAdmin. You can see the CI pass here: https://github.com/activeadmin/activeadmin/actions/runs/14146757191 Tested by replacing v1.14.1 with the dev file from the PR: activeadmin/activeadmin@7aa7778 Additionally, I've manually tested and the feature appears to correctly work Before (v1.14.1) ❌After (#2345) ✅![]() |
Thanks for confirming! |
Prior to jQuery UI 1.14.1, hashes in anchor hrefs were used directly. In jquerygh-2307, that was changed - by decoding - to support more complex IDs, e.g. containing emojis which are automatically encoded in `anchor.hash`. Unfortunately, that broke cases where the panel ID is decoded as well. It turns out the spec mandates checking both. In the "scrolling to a fragment" section of the HTML spec[^1]. That uses a concept of document's indicated part[^2]. Slightly below there's an algorithm to compute the indicated part[^3]. The interesting parts are steps 4 to 9: 4. Let potentialIndicatedElement be the result of finding a potential indicated element given document and fragment. 5. If potentialIndicatedElement is not null, then return potentialIndicatedElement. 6. Let fragmentBytes be the result of percent-decoding fragment. 7. Let decodedFragment be the result of running UTF-8 decode without BOM on fragmentBytes. 8. Set potentialIndicatedElement to the result of finding a potential indicated element given document and decodedFragment. 9. If potentialIndicatedElement is not null, then return potentialIndicatedElement. First, in steps 4-5, the algorithm tries the hash as-is, without decoding. Then, if one is not found, the same is attempted with a decoded hash. This change replicates this logic by first trying the hash as-is and then decoding it. Fixes jquerygh-2344 Closes jquerygh-2345 Ref jquerygh-2307 [^1]: https://html.spec.whatwg.org/#scrolling-to-a-fragment [^2]: https://html.spec.whatwg.org/#the-indicated-part-of-the-document [^3]: https://html.spec.whatwg.org/#select-the-indicated-part
Hello,
not sure that this is an issue with jQuery UI, but I think it is worth to report it
In Active Admin, we were trying to upgrade jQuery UI to 1.14.1 from 1.13.2, but one of our specs related to the tabs component was failing.
The failure is related to the way Active Admin creates the fragment name when it contains just an emoji, which is the same way GitHub creates fragments in markdown to HTML conversion
Example:
☺️
=>%EF%B8%8F
Reproducible test case:
Code taken from: https://jqueryui.com/tabs/
Expected
Actual
Refs:
The text was updated successfully, but these errors were encountered: