Skip to content
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

[css-selectors][css-escape] Cannot select attributes with multiple escaped chars #4820

Closed
apollolux opened this issue Feb 29, 2020 · 7 comments
Labels
Closed as Question Answered Used when the issue is more of a question than a problem, and it's been answered.

Comments

@apollolux
Copy link

apollolux commented Feb 29, 2020

Hello! As someone who isn't part of the WG I wasn't sure where to report the issue so this looked like a reasonable place to do so.

I recently had occasion to want to select an HTML element with an attribute that has a Windows-formatted file path as its main content (i.e. backslash directory separators and a colon separating drive letter and the rest of the path). I asked on Stack Overflow if it was possible, as I was using JavaScript to querySelector it and all my attempts to escape the backslashes and colon, either using CSS.escape or manually, have failed beyond the first escaped char. Microsoft Visual Studio Code, when on Windows, is what formats paths Windows-style, while on macOS and *nix paths separate with / and targeting seems okay. Sample element and failed selector (actual HTML from VSCode in the Stack Overflow):

<li data-path="c:\WINDOWS\system32\mspaint.exe">mspaint.exe</li>
li[data-path="c\:\\WINDOW\\system32\\mspaint\.exe"]

Is there something I'm missing regarding how to escape the attribute, or is it a fruitless endeavor to try to target an attribute that has a Windows-style path in it?

@Loirooriol
Copy link
Contributor

Yes, you are missing something, you should escape the backslash in WINDOWS\system32.
And it's fine but unnecessary to escape : and . in a string.

var li = document.createElement("li");
li.dataset.path = String.raw`c:\WINDOWS\system32\mspaint.exe`;
li.matches(String.raw`li[data-path^="c:\\WINDOWS\\system32\\mspaint.exe"]`); // true
li.matches(String.raw`li[data-path^=c\:\\WINDOWS\\system32\\mspaint\.exe]`); // true

@Loirooriol Loirooriol added the Closed as Question Answered Used when the issue is more of a question than a problem, and it's been answered. label Mar 1, 2020
@apollolux
Copy link
Author

apollolux commented Mar 1, 2020

The missing backslash was a fault of retyping into the box and has been edited.

It seems that the thing I'm ACTUALLY missing which you seem to have ACCIDENTALLY gotten right in your attempt to point out a typo rather than give an actual explanation is the use of String.raw instead of a plain string. Also doesn't help non-JavaScript selection, but at least this is something.

@Loirooriol
Copy link
Contributor

Sure, if you are using JS, you have to escape a backslash twice (once for JS and once for CSS). Or use String.raw to get the raw specified string without processing escapes.

@tabatkins
Copy link
Member

It seems that the thing I'm ACTUALLY missing which you seem to have ACCIDENTALLY gotten right in your attempt to point out a typo rather than give an actual explanation

Snark is neither appreciated nor useful.

is the use of String.raw instead of a plain string. Also doesn't help non-JavaScript selection, but at least this is something.

Yeah, note that you need to escape the backslash both at the JS and the CSS level if you're putting this in querySelector(), because it gets parsed by both languages. Without String.raw, you thus have to double-escape, like querySelector('[data-path^="c:\\\\WINDOWS\\\\system32\\\\mspaint.exe"]'), which just gets a bit silly.

Inside of a stylesheet you only need to escape it once, since only CSS will be parsing it, so [data-path^="c:\\WINDOWS..."] is fine.

@apollolux
Copy link
Author

The snark was in response to what was essentially a one-line answer only pointing out a typo instead of focusing on the actual fix. I see those kind of no-substance one-liners on Stack Overflow and Quora too often and I'm not a fan of those either.

@tabatkins
Copy link
Member

  1. It doesn't matter the circumstance, snark isn't appreciated here. Don't do it again, please.

  2. It was a legitimate answer. Neither your post nor the SO you link to had an actual code example that was failing; Oriol gave you a working code example. They commenting on the code as they saw it at the time was also fine; it's not unusual for people to trip up on small errors like that, that their eyes keep skipping over accidentally.

@apollolux
Copy link
Author

  1. I acknowledge the snark was wrong and I apologize.

  2. The code on SO did not have the original typo of the first post of this issue, which was simply the result of typing the given escaped example by hand and a typo was never the actual problem, hence my original disappointment at the delivery of the reply focusing more on it than at pointing out that JavaScript would need double-escaping. I acknowledge that the SO code did not show the actual JavaScript I was attempting, but I did say that I had attempted to CSS.escape the query to run with the selector. The example given by Oriol did work, yes, that was never in dispute, and refactoring my code to account for that allowed it to work.

Given that the use case of a backslash in an attribute is indeed not common, the documentation (at least on MDN at the time) was lacking in that respect and would benefit from an update saying that double-escaping (or String.raw tagging an already escaped template literal) the query is potentially necessary if in JavaScript.

While I regret how I presented my text, I am glad I asked the question here and I do thank y'all for providing not just the answer to it specifically but the CSSWG in general for promoting the continuous useful progression of CSS.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Closed as Question Answered Used when the issue is more of a question than a problem, and it's been answered.
Projects
None yet
Development

No branches or pull requests

3 participants