Same-page anchor: Account for <a> nested in <svg>#1495
Same-page anchor: Account for <a> nested in <svg>#1495seanpdoyle wants to merge 1 commit intohotwired:mainfrom
<a> nested in <svg>#1495Conversation
|
Related: Astro's ClientRouter approach: https://github.com/withastro/astro/blob/dbf71c021e3adf060c34e6f268cf1b5cd480233d/packages/astro/components/ClientRouter.astro#L82-L83 |
a4625fa to
d25a5c7
Compare
|
@domchristie interesting! Thanks for sharing that context. I'll copy-paste it here to keep those details as part of this conversation: if (
!(link instanceof HTMLAnchorElement) &&
!(link instanceof SVGAElement) &&
!(link instanceof HTMLAreaElement)
)
return
// …
const linkTarget = link instanceof HTMLElement ? link.target : link.target.baseVal;
const href = link instanceof HTMLElement ? link.href : link.href.baseVal;I like that approach in that there are some class-level checks. However, I worry about a future need of adding additional supported classes (in case we miss one now, or in case the "link" is an For now, I think I prefer the Am I missing out on something about the alternative? |
No I don't think so. The use of |
packagethief
left a comment
There was a problem hiding this comment.
Thanks for looking into this @seanpdoyle 🙏
src/util.js
Outdated
| const linkTarget = link.getAttribute("target") | ||
| if (linkTarget && linkTarget !== "_self") return null | ||
|
|
||
| if (/\A#/.test(link.getAttribute("href"))) return null |
There was a problem hiding this comment.
@seanpdoyle I tried to test this, but it seems JS regexp does not support \A as a start of string anchor, that's a ruby thing. (I think tests are failing because of this too).
/\A#/.test("#foo") // false
/\A#/.test("A#") // true
I went back and tested this, and the claim that this broke links in SVGs was wrong, I'm sorry about that. In fact, the links still behave as intended, there's just noise from the errors in the browser console. So I think (at least in my case) it is indeed 1. |
f4419bb to
54de754
Compare
Follow-up to [hotwired#1285][] While an `<a>` element is typically represented by an [HTMLAnchorElement][], an `<a>` nested inside an `<svg>` element is instead an [SVGAElement][]. Similarly, while [HTMLAnchorElement.href][] returns a `String`, the [SVGAElement.href][] returns an instance of [SVGAnimatedString][], which cannot be supported by neither calls to [String.startsWith][] nor [RegExp.test][]. This commit adds explicit test coverage for a same-page navigation from an `<a>` nested within an `<svg>`. To ensure that the value is a `String`, replace `.href` with `getAttribute("href")`. This restores the implementation to be closer to what was defined in [e591ea9][]. [hotwired#1285]: hotwired#1285 [HTMLAnchorElement]: https://developer.mozilla.org/en-US/docs/Web/API/HTMLAnchorElement [SVGAElement]: https://developer.mozilla.org/en-US/docs/Web/API/SVGAElement [HTMLAnchorElement.href]: https://developer.mozilla.org/en-US/docs/Web/API/HTMLAnchorElement/href [SVGAElement.href]: https://developer.mozilla.org/en-US/docs/Web/API/SVGAElement/href [SVGAnimatedString]: https://developer.mozilla.org/en-US/docs/Web/API/SVGAnimatedString [String.startsWith]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith [RegExp.test]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test [e591ea9]: hotwired@e591ea9#diff-9c0ec1b0a889e599f3ff81590864dd9dc65684a86b41f1da75acc53fafed12e3R251-R256
54de754 to
9951bff
Compare
Follow-up to #1285
While an
<a>element is typically represented by an HTMLAnchorElement, an<a>nested inside an<svg>element is instead an SVGAElement.Similarly, while HTMLAnchorElement.href returns a
String, the SVGAElement.href returns an instance of SVGAnimatedString, which cannot be supported by neither calls to String.startsWith nor RegExp.test.This commit adds explicit test coverage for a same-page navigation from an
<a>nested within an<svg>. To ensure that the value is aString, replace.hrefwithgetAttribute("href"). This restores the implementation to be closer to what was defined in e591ea9e.Note
It's worth mentioning that both of these new tests pass without the
page.on("pageerror")parts are omitted from the coverage. That signals to me that either:I'm hopeful that it's 1., and that the test coverage with the explicit JavaScript error tracking sufficiently guards against both 1. and 2. being true.