Skip to content

Commit 94cdfaf

Browse files
committed
Add support for returning the first element matching a selector
And a minor refactoring of matchElementAgainstSelectors().
1 parent d53277a commit 94cdfaf

2 files changed

Lines changed: 10 additions & 5 deletions

File tree

lib/match/selector.js

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1449,11 +1449,12 @@ function matchComplexSelector(element, selector, options) {
14491449
* @param {Element} element
14501450
* @param {*[]} selector
14511451
* @param {object} [options]
1452+
* @param {boolean} [all]
14521453
* @returns {object[]|null}
14531454
* @see {@link https://drafts.csswg.org/selectors-4/#match-a-selector-against-an-element}
14541455
*/
1455-
function matchElementAgainstSelectors(element, selector, options) {
1456-
if (options.all) {
1456+
function matchElementAgainstSelectors(element, selector, options, all) {
1457+
if (all) {
14571458
return selector.filter(selector => matchComplexSelector(element, selector, options))
14581459
}
14591460
return selector.some(selector => matchComplexSelector(element, selector, options))
@@ -1472,10 +1473,11 @@ function matchPseudoElementAgainstSelectors(pseudo, selector, options) { }
14721473
* @param {Element[]} trees
14731474
* @param {*[]} selector
14741475
* @param {object} [options]
1475-
* @returns {Element[]}
1476+
* @param {boolean} [first]
1477+
* @returns {Element|Element[]}
14761478
* @see {@link https://drafts.csswg.org/selectors-4/#match-a-selector-against-a-tree}
14771479
*/
1478-
function matchTreesAgainstSelectors(trees, selector, options = {}) {
1480+
function matchTreesAgainstSelectors(trees, selector, options = {}, first) {
14791481

14801482
// Assert: all trees share the same root
14811483

@@ -1491,6 +1493,9 @@ function matchTreesAgainstSelectors(trees, selector, options = {}) {
14911493
options = roots ? { ...options, scope: tree, tree } : { ...options, tree }
14921494
for (const element of traverse(tree, options)) {
14931495
if (matchElementAgainstSelectors(element, selector, options)) {
1496+
if (first) {
1497+
return selected
1498+
}
14941499
selected.push(element)
14951500
}
14961501
pseudos?.forEach(type => {

lib/resolve.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ function getSelectorSpecificity(selector) {
399399
*/
400400
function getDeclarationSpecificity({ context }, element) {
401401
const [...selectors] = context.selectors
402-
const matches = matchElementAgainstSelectors(element, selectors.pop(), { ...context, all: true })
402+
const matches = matchElementAgainstSelectors(element, selectors.pop(), context, true)
403403
return mergeSpecificities(
404404
// Highest specificity among complex selectors matching `element` in the innermost most style rule
405405
getHighestSpecificity(matches.map(getSelectorSpecificity)),

0 commit comments

Comments
 (0)