From 2d190c6503dc4083cd17775eaf0ac3cde2f641b1 Mon Sep 17 00:00:00 2001 From: Ruslan Hrabovyi Date: Thu, 26 Oct 2023 00:54:27 +0200 Subject: [PATCH] allow selectors concatenation --- addon/src/-private/query.js | 22 +++++++++++++++----- addon/src/-private/query/locator.js | 12 +++++++++++ addon/src/-private/query/selector.js | 9 ++++++++ addon/src/-private/query/selectors/jquery.js | 8 +++++++ 4 files changed, 46 insertions(+), 5 deletions(-) diff --git a/addon/src/-private/query.js b/addon/src/-private/query.js index 55494c06..0ba9a9ec 100644 --- a/addon/src/-private/query.js +++ b/addon/src/-private/query.js @@ -58,14 +58,26 @@ export class Query { ? fullPath.length - 1 : fullPath.findLastIndex((i) => typeof i.resetScope === 'boolean'); - const allLocators = ( + const locators = ( resetScopeIndex === -1 ? fullPath : fullPath.slice(resetScopeIndex) ) .map((p) => p.scope) - .filter(Boolean); - - this._locators = allLocators.length - ? allLocators + .filter(Boolean) + .reduce((acc, locator) => { + if (acc.length === 0) { + return [locator]; + } + + const lastLocator = acc[acc.length - 1]; + if (lastLocator.canConcat(locator)) { + return [...acc.slice(0, -1), lastLocator.concat(locator)]; + } + + return [...acc, locator]; + }, []); + + this._locators = locators.length + ? locators : [new Locator(':first-child', { at: 0 })]; } diff --git a/addon/src/-private/query/locator.js b/addon/src/-private/query/locator.js index 48bd6430..06deefc5 100644 --- a/addon/src/-private/query/locator.js +++ b/addon/src/-private/query/locator.js @@ -72,6 +72,18 @@ export default class Locator { return `${selector}:${modifiers.join(':')}`; } + + canConcat(locator) { + if (this.filters) { + return false; + } + + return this.selector.canConcat(locator.selector); + } + + concat(locator) { + return new Locator(this.selector.concat(locator.selector), locator.filters); + } } function getDefaultQuerySelectorClass() { diff --git a/addon/src/-private/query/selector.js b/addon/src/-private/query/selector.js index a4a51b11..a6388d86 100644 --- a/addon/src/-private/query/selector.js +++ b/addon/src/-private/query/selector.js @@ -10,6 +10,15 @@ export class QuerySelector { toString() { return this.selector.toString(); } + + // eslint-disable-next-line no-unused-vars + canConcat(/* selector */) { + return false; + } + + concat(/* selector */) { + throw new Error('`concat` method is not implemented'); + } } export function isQuerySelector(selector) { diff --git a/addon/src/-private/query/selectors/jquery.js b/addon/src/-private/query/selectors/jquery.js index 748a382f..cb31abb3 100644 --- a/addon/src/-private/query/selectors/jquery.js +++ b/addon/src/-private/query/selectors/jquery.js @@ -9,6 +9,14 @@ export default class JQueryQuerySelector extends QuerySelector { return $(selector, containerElement).toArray(); } + + canConcat(selector) { + return selector instanceof JQueryQuerySelector; + } + + concat(selector) { + return new JQueryQuerySelector(`${this.selector} ${selector.selector}`); + } } function validate(selector) {