aboutsummaryrefslogtreecommitdiff
path: root/js/src
diff options
context:
space:
mode:
Diffstat (limited to 'js/src')
-rw-r--r--js/src/dom/selector-engine.js26
-rw-r--r--js/src/dom/selector-engine.spec.js115
2 files changed, 117 insertions, 24 deletions
diff --git a/js/src/dom/selector-engine.js b/js/src/dom/selector-engine.js
index eb6b680ac..d66d8acfc 100644
--- a/js/src/dom/selector-engine.js
+++ b/js/src/dom/selector-engine.js
@@ -22,37 +22,22 @@ const SelectorEngine = {
},
find(selector, element = document.documentElement) {
- if (typeof selector !== 'string') {
- return null
- }
-
return findFn.call(element, selector)
},
findOne(selector, element = document.documentElement) {
- if (typeof selector !== 'string') {
- return null
- }
-
return findOne.call(element, selector)
},
children(element, selector) {
- if (typeof selector !== 'string') {
- return null
- }
-
const children = makeArray(element.children)
return children.filter(child => this.matches(child, selector))
},
parents(element, selector) {
- if (typeof selector !== 'string') {
- return null
- }
-
const parents = []
+
let ancestor = element.parentNode
while (ancestor && ancestor.nodeType === Node.ELEMENT_NODE && ancestor.nodeType !== NODE_TEXT) {
@@ -67,19 +52,12 @@ const SelectorEngine = {
},
closest(element, selector) {
- if (typeof selector !== 'string') {
- return null
- }
-
return closest.call(element, selector)
},
prev(element, selector) {
- if (typeof selector !== 'string') {
- return null
- }
-
const siblings = []
+
let previous = element.previousSibling
while (previous && previous.nodeType === Node.ELEMENT_NODE && previous.nodeType !== NODE_TEXT) {
diff --git a/js/src/dom/selector-engine.spec.js b/js/src/dom/selector-engine.spec.js
new file mode 100644
index 000000000..28ccdf40b
--- /dev/null
+++ b/js/src/dom/selector-engine.spec.js
@@ -0,0 +1,115 @@
+import SelectorEngine from './selector-engine'
+import { makeArray } from '../util/index'
+
+/** Test helpers */
+import { getFixture, clearFixture } from '../../tests/helpers/fixture'
+
+describe('SelectorEngine', () => {
+ let fixtureEl
+
+ beforeAll(() => {
+ fixtureEl = getFixture()
+ })
+
+ afterEach(() => {
+ clearFixture()
+ })
+
+ describe('matches', () => {
+ it('should return matched elements', () => {
+ fixtureEl.innerHTML = '<div></div>'
+
+ expect(SelectorEngine.matches(fixtureEl, 'div')).toEqual(true)
+ })
+ })
+
+ describe('find', () => {
+ it('should find elements', () => {
+ fixtureEl.innerHTML = '<div></div>'
+
+ const div = fixtureEl.querySelector('div')
+
+ expect(makeArray(SelectorEngine.find('div', fixtureEl))).toEqual([div])
+ })
+
+ it('should find elements globaly', () => {
+ fixtureEl.innerHTML = '<div id="test"></div>'
+
+ const div = fixtureEl.querySelector('#test')
+
+ expect(makeArray(SelectorEngine.find('#test'))).toEqual([div])
+ })
+
+ it('should handle :scope selectors', () => {
+ fixtureEl.innerHTML = `<ul>
+ <li></li>
+ <li>
+ <a href="#" class="active">link</a>
+ </li>
+ <li></li>
+ </ul>`
+
+ const listEl = fixtureEl.querySelector('ul')
+ const aActive = fixtureEl.querySelector('.active')
+
+ expect(makeArray(SelectorEngine.find(':scope > li > .active', listEl))).toEqual([aActive])
+ })
+ })
+
+ describe('findOne', () => {
+ it('should return one element', () => {
+ fixtureEl.innerHTML = '<div id="test"></div>'
+
+ const div = fixtureEl.querySelector('#test')
+
+ expect(SelectorEngine.findOne('#test')).toEqual(div)
+ })
+ })
+
+ describe('children', () => {
+ it('should find children', () => {
+ fixtureEl.innerHTML = `<ul>
+ <li></li>
+ <li></li>
+ <li></li>
+ </ul>`
+
+ const list = fixtureEl.querySelector('ul')
+ const liList = makeArray(fixtureEl.querySelectorAll('li'))
+ const result = makeArray(SelectorEngine.children(list, 'li'))
+
+ expect(result).toEqual(liList)
+ })
+ })
+
+ describe('parents', () => {
+ it('should return parents', () => {
+ expect(SelectorEngine.parents(fixtureEl, 'body').length).toEqual(1)
+ })
+ })
+
+ describe('prev', () => {
+ it('should return previous element', () => {
+ fixtureEl.innerHTML = '<div class="test"></div><button class="btn"></button>'
+
+ const btn = fixtureEl.querySelector('.btn')
+ const divTest = fixtureEl.querySelector('.test')
+
+ expect(SelectorEngine.prev(btn, '.test')).toEqual([divTest])
+ })
+
+ it('should return previous element with an extra element between', () => {
+ fixtureEl.innerHTML = [
+ '<div class="test"></div>',
+ '<span></span>',
+ '<button class="btn"></button>'
+ ].join('')
+
+ const btn = fixtureEl.querySelector('.btn')
+ const divTest = fixtureEl.querySelector('.test')
+
+ expect(SelectorEngine.prev(btn, '.test')).toEqual([divTest])
+ })
+ })
+})
+