diff options
Diffstat (limited to 'js/src')
| -rw-r--r-- | js/src/dom/selector-engine.js | 26 | ||||
| -rw-r--r-- | js/src/dom/selector-engine.spec.js | 115 |
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]) + }) + }) +}) + |
