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

querySelectorAll is not always returning elements in document order #928

Closed
alexgallardo opened this issue May 22, 2023 · 2 comments · Fixed by #931
Closed

querySelectorAll is not always returning elements in document order #928

alexgallardo opened this issue May 22, 2023 · 2 comments · Fixed by #931
Assignees
Labels
bug Something isn't working

Comments

@alexgallardo
Copy link

Describe the bug
Incorrect order of elements when using document.querySelectorAll under certain circumstances. See "Additional context" for a technical description.

To Reproduce

import { Window } from "happy-dom";

const window = new Window();
const document = window.document;

document.body.innerHTML = `
<div>0</div>
<button>1</button>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<button>8</button>
<button>9</button>
<button>10</button>
<button>11</button>
`;

document
  .querySelectorAll("button")
  .forEach((button) => console.log(button.textContent));

// Output:
// 1
// 10
// 11
// 8
// 9

Expected behavior
document.querySelectorAll should return the elements in document order.

Additional context
In the QuerySelector class, findAll method, when iterating through the elements, the position of every one is stored as a string using its index:

const position = (documentPosition ? documentPosition + '>' : '') + i;

Later, in the querySelectorAll method, that position is used to sort the results:

const keys = Object.keys(matchesMap).sort();

Given that individual characters are compared when sorting strings, items with an index of 10 to 19, 100 to 199 and so on will appear before items with index of 3, 4...

Something like adding leading zeroes to the position of the elements of every level up to the number of digits of children.length - 1 would fix the issue without changing the way they are sorted, but since performance is a selling point vs jsdom, maybe a more complex solution is preferable.

@alexgallardo alexgallardo added the bug Something isn't working label May 22, 2023
@capricorn86 capricorn86 self-assigned this May 22, 2023
capricorn86 added a commit that referenced this issue May 22, 2023
capricorn86 added a commit that referenced this issue May 22, 2023
…-not-always-returning-elements-in-document-order

#928@patch: Fixes problem with querySelectorAll() not always retirnin…
@capricorn86
Copy link
Owner

Thank you for reporting @alexgallardo! 🙂

I have fixed the problem now.

You can read more about the release here:
https://github.com/capricorn86/happy-dom/releases/tag/v9.20.1

@capricorn86
Copy link
Owner

The sorting mechanism was sorting incorrectly as it sorted by characters and numbers came in the wrong order (1, 10, 11, 2, 3, 4 etc.). The unit test did not cover this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants