nwsapi
nwsapi copied to clipboard
:scope not working when the context has a class name that uses special characters
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?
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 :
?
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.
@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.