Repository: exadel-inc/esl
Pull request #83 (2021-03-09 21:21:51)

feat: filtration common pseudo-selectors


Patch:
diff --git a/src/modules/esl-traversing-query/core/esl-traversing-query.ts b/src/modules/esl-traversing-query/core/esl-traversing-query.ts
index d30dc96be..6cfcd411d 100644
--- a/src/modules/esl-traversing-query/core/esl-traversing-query.ts
+++ b/src/modules/esl-traversing-query/core/esl-traversing-query.ts
@@ -15,6 +15,7 @@ type CollectionProcessor = (els: Element[], sel: string) => Element[];
  * - ::parent and ::child pseudo-selectors
  * - ::find pseudo-selector
  * - ::first, ::last and :nth(#) limitation pseudo-selectors
+ * - ::filter, ::not filtration pseudo-selectors
  *
  * @example "#id .class [attr]" - find by CSS selector in a current document
  * @example "" - get current base element
@@ -24,6 +25,8 @@ type CollectionProcessor = (els: Element[], sel: string) => Element[];
  * @example "::parent(#id .class [attr])" - find the closest parent matching passed selector
  * @example "::child(#id .class [attr])" - find direct child element(s) that match passed selector
  * @example "::find(#id .class [attr])" - find child element(s) that match passed selector
+ * @example "::find(buttons, a)::not([hidden])" - find all buttons and anchors that are not have hidden attribute
+ * @example "::find(buttons, a)::filter(:first-child)" - find all buttons and anchors that are first child in container
  * @example "::parent::child(some-tag)" - find direct child element(s) that match tag 'some-tag' in the parent
  * @example "#id .class [attr]::parent" - find parent of element matching selector '#id .class [attr]' in document
  * @example "::find(.row)::last::parent" - find parent of the last element matching selector '.row' from the base element subtree
@@ -42,7 +45,9 @@ export class TraversingQuery {
     '::nth': (list: Element[], sel?: string) => {
       const index = sel ? +sel : NaN;
       return wrap(list[index - 1]);
-    }
+    },
+    '::not': (list: Element[], sel?: string) => list.filter((el) => !el.matches(sel || '')),
+    '::filter': (list: Element[], sel?: string) => list.filter((el) => el.matches(sel || ''))
   };
 
   /**


Test patch:
diff --git a/src/modules/esl-traversing-query/test/esl-traversing-query.test.ts b/src/modules/esl-traversing-query/test/esl-traversing-query.test.ts
index 808a07740..11665a915 100644
--- a/src/modules/esl-traversing-query/test/esl-traversing-query.test.ts
+++ b/src/modules/esl-traversing-query/test/esl-traversing-query.test.ts
@@ -95,6 +95,14 @@ describe('Traversing Query tests', () => {
     ['::find(.btn)::nth(8)', root, []],
     ['::find(.btn)::nth(bla bla)', root, []],
 
+    // Filters
+    ['::find(.btn)::filter(.un-existing)', root, []],
+    ['::find(.btn)::not(button)', root, []],
+    ['::find(.btn)::filter([data-test])', root, [btn2, btn5, btn6]],
+    ['::find(.btn)::not([data-test])', root, [btn1, btn3, btn4]],
+    ['::find(.btn)::filter(:first-child)', root, [btn1]],
+    ['::find(.btn)::not(:first-child)', root, [btn2, btn3, btn4, btn5, btn6]],
+
     // Complex query test
     ['::parent::child', root, [root]],
     ['::parent::find(.btn)', btn5, [btn1, btn2, btn3, btn4, btn5]],