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

:scope not working when the context has a class name that uses special characters #106

Open
jordimarimon opened this issue Mar 5, 2024 · 3 comments

Comments

@jordimarimon
Copy link

jordimarimon commented Mar 5, 2024

Minimal example that breaks in the latest nwsapi (I have downloaded the nwsapi.js file from github today):

<!DOCTYPE html>
<html lang="en">
	<head>
		<title>test nwsapi</title>
		<meta charset="UTF-8">
		<meta name="viewport" content="width=device-width, initial-scale=1">
		<style>
			@media (min-width: 768px) {
				.md\:p-4 {
					padding: 1rem;
				}
			}
		</style>
	</head>
	<body class="md:p-4">

		<div data-test="foo"></div>

		<script type="text/javascript" src="nwsapi.js" onload="NW.Dom.install()"></script>

		<script>
			console.log(document.body.querySelector(":scope > [data-test=\"foo\"]"));
		</script>>

	</body>
</html>

This throws Uncaught DOMException: unknown pseudo-class selector ':p-4>[data-test="foo"]' but if I try the query selector API provided by the browser it works.

I'm using tailwind which makes use of special characters in the class names and I was running tests with jest using jsdom as the environment and it's when I encounter the error.

Is this use case something that nwsapi would be open to support?

I will try to help by finding out how this could be fixed and in case that I do find it, I could open a PR if it's okay?

@jordimarimon
Copy link
Author

jordimarimon commented Mar 5, 2024

I think I have found where the error is thrown:

https://github.com/dperini/nwsapi/blob/master/src/nwsapi.js#L896-L1277

I think it's because :p-4 is not a valid pseudo class. If I were open to help, does nwsapi would want to support class names that use :?

@jordimarimon
Copy link
Author

After looking more into it, I have found one possible solution, although maybe it's not the way you want to approach this.

I have added in the makeref implementation to escape the class name:

// replace ':scope' pseudo-class with element references
  makeref =
    function(selectors, element) {
      // DOCUMENT_NODE (9)
      if (element.nodeType === 9) {
        element = element.documentElement;
      }

      return selectors.replace(/:scope/ig,
        element.localName +
        (element.id ? '#' + element.id : '') +
        (element.className ? '.' + escape(element.classList[0]) : ''));
    },

  // This is not the correct way to escape special characters in an identifier, it's just a proof of concept
  escape = function(string) {
    return string.replace(/[!"#$%&'()*+,./;<=>?@\[\\\]^`{|}~\t\n\v\f:]/, match => '\\' + match);
  },

Because when using :scope in the selector, the class name is being retrieved from the DOM, it's not properly escaped.

I think nwsapi should escape the class name when replacing :scope. Also, the id may need to be escaped as well.

@dperini
Copy link
Owner

dperini commented Mar 8, 2024

@jordimarimon
thank you so much for the contribution.
Like you did, I would have also escaped special characters

This fix will be in next revision. I will commit as soon as I am back to my desk.
By an unlucky accident nwsapi-2.2.8 should be postponed for almost two more weeks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants