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

SyntaxError: Failed to execute 'querySelector' on 'Element': '#div-2.1' is not a valid selector #37858

Open
3 tasks done
larseggert opened this issue Jan 11, 2023 · 7 comments
Labels

Comments

@larseggert
Copy link

Prerequisites

Describe the issue

#35566 didn't fix things for all weird IDs. The test case addition below causes the error in the issue title.

Reduced test cases

diff --git a/js/tests/unit/scrollspy.spec.js b/js/tests/unit/scrollspy.spec.js
index c7951e6..704b52a 100644
--- a/js/tests/unit/scrollspy.spec.js
+++ b/js/tests/unit/scrollspy.spec.js
@@ -341,11 +341,13 @@ describe('ScrollSpy', () => {
           '  <ul class="nav">',
           '    <li class="nav-item"><a class="nav-link" id="a-1" href="#div-1">div 1</a></li>',
           '    <li class="nav-item"><a class="nav-link" id="a-2" href="#div-2">div 2</a></li>',
+          '    <li class="nav-item"><a class="nav-link" id="a-2.1" href="#div-2.1">div 2</a></li>',
           '  </ul>',
           '</nav>',
           '<div class="content" style="overflow: auto; height: 50px">',
           '  <div id="div-1" style="height: 100px; padding: 0; margin: 0">div 1</div>',
           '  <div id="div-2" style="height: 200px; padding: 0; margin: 0">div 2</div>',
+          '  <div id="div-2.1" style="height: 200px; padding: 0; margin: 0">div 2.1</div>',
           '</div>'
         ].join('')

What operating system(s) are you seeing the problem on?

macOS

What browser(s) are you seeing the problem on?

Firefox

What version of Bootstrap are you using?

v5.2.3

@pierresouchay
Copy link
Contributor

pierresouchay commented Jan 11, 2023

@larseggert this is weird...

did not take the time to look at, but If I copy-paste:

const parseSelector = selector => {
   if (selector && window.CSS && window.CSS.escape) {
     // document.querySelector needs escaping to handle IDs (html5+) containing for instance /
     selector = selector.replaceAll(/#([^\s"#']+)/g, (match, id) => '#' + CSS.escape(id))
   }

   return selector
 }

in my JS Console in Firefox, and then I type:

parseSelector("#div-2.1")
"#div-2\\.1" 

=> Looks like the correct result to me

@larseggert
Copy link
Author

Hm. Apply the patch and run the tests? That should recreate the issue. (Maybe that function isn't called?)

@larseggert
Copy link
Author

Here is the test failure I get with the patch above:

Chrome Headless 109.0.5414.87 (Mac OS 10.15.7) ScrollSpy constructor should add the active class to the correct element FAILED
	SyntaxError: Failed to execute 'querySelector' on 'Element': '#div-2.1' is not a valid selector.
	error properties: Object({ code: 12, INDEX_SIZE_ERR: 1, DOMSTRING_SIZE_ERR: 2, HIERARCHY_REQUEST_ERR: 3, WRONG_DOCUMENT_ERR: 4, INVALID_CHARACTER_ERR: 5, NO_DATA_ALLOWED_ERR: 6, NO_MODIFICATION_ALLOWED_ERR: 7, NOT_FOUND_ERR: 8, NOT_SUPPORTED_ERR: 9, INUSE_ATTRIBUTE_ERR: 10, INVALID_STATE_ERR: 11, SYNTAX_ERR: 12, INVALID_MODIFICATION_ERR: 13, NAMESPACE_ERR: 14, INVALID_ACCESS_ERR: 15, VALIDATION_ERR: 16, TYPE_MISMATCH_ERR: 17, SECURITY_ERR: 18, NETWORK_ERR: 19, ABORT_ERR: 20, URL_MISMATCH_ERR: 21, QUOTA_EXCEEDED_ERR: 22, TIMEOUT_ERR: 23, INVALID_NODE_TYPE_ERR: 24, DATA_CLONE_ERR: 25 })
	    at Object.findOne (js/src/dom/selector-engine.js:41:44 <- js/tests/unit/scrollspy.spec.js:9260:46)
	    at ScrollSpy._initializeTargetsAndObservables (js/src/scrollspy.js:211:48 <- js/tests/unit/scrollspy.spec.js:15411:76)
	    at ScrollSpy.refresh (js/src/scrollspy.js:91:10 <- js/tests/unit/scrollspy.spec.js:15227:12)
	    at new ScrollSpy (js/src/scrollspy.js:73:10 <- js/tests/unit/scrollspy.spec.js:15207:12)
	    at js/tests/unit/scrollspy.spec.js:355:27 <- js/tests/unit/scrollspy.spec.js:15743:29
	    at new Promise (<anonymous>)
	    at UserContext.<anonymous> (js/tests/unit/scrollspy.spec.js:338:14 <- js/tests/unit/scrollspy.spec.js:15740:16)
	    at <Jasmine>

@larseggert
Copy link
Author

OK, I'm not familiar with the bootstrap code, but to me it looks like scrollspy uses various SelectorEngine functions (find, etc.) that don't seem to call parseSelector at all?

@neurotools
Copy link

I have a similar problem but with a tab linking to an external PDF file, using the "file.pdf#page=10" format.

<a href="http://example.com/document.pdf#page=10" target="_blank" class="nav-link">External link</a>

I got JS errors:

Uncaught DOMException: Document.querySelector: '#page=10' is not a valid selector

@chrisyeh96
Copy link

chrisyeh96 commented Apr 17, 2023

+1. I am also seeing this issue on Bootstrap v5.2.3, running Microsoft Edge v112 on Windows 11.

<h2 id="2-partition-normalized-cut">2-partition: Normalized Cut</h2>

causes the error

Uncaught DOMException: Failed to execute 'querySelector' on 'Element': '#2-partition-normalized-cut' is not a valid selector.
    at Object.findOne (https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.min.js:6:10283)
    at Be._initializeTargetsAndObservables (https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.min.js:6:53059)
    at Be.refresh (https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.min.js:6:51311)
    at new Be (https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.min.js:6:51184)
    at Be.getOrCreateInstance (https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.min.js:6:8552)
    at https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.min.js:6:54113
    at i (https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.min.js:6:4608)

It seems like #34412 (which was supposed to be closed by #35566) is actually still not solved.

@InsanePrawn
Copy link

InsanePrawn commented Oct 14, 2023

Can confirm on 5.3.2.

Patching SelectorEngine.findOne() like so fixes (that part of...) scrollspy for me and my #2-foo-bar IDs. (not checked for side-effects!)

    findOne(selector, element = document.documentElement) {
-      return Element.prototype.querySelector.call(element, selector);
+      return Element.prototype.querySelector.call(element, parseSelector(selector));
    },

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

No branches or pull requests

6 participants