diff --git a/package.json b/package.json index c625294..de0155c 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "babel-register": "^6.24.1", "chai": "^4.0.2", "cross-env": "^3.0.0", + "element-matches": "^0.1.2", "karma": "^1.7.0", "karma-mocha": "^1.3.0", "karma-phantomjs-launcher": "^1.0.4", diff --git a/src/index.js b/src/index.js index 1805a22..23f2ea1 100644 --- a/src/index.js +++ b/src/index.js @@ -1,3 +1,5 @@ +import 'element-matches'; + let ShortKey = {} let mapFunctions = {} let objAvoided = [] @@ -159,30 +161,10 @@ const mappingFunctions = ({b, push, once, focus, el}) => { const filteringElement = (pKey) => { const decodedKey = ShortKey.decodeKey(pKey) const objectAvoid = objAvoided.find(r => r === document.activeElement) - const elementSeparate = checkElementType() - const elementTypeAvoid = elementSeparate.avoidedTypes - const elementClassAvoid = elementSeparate.avoidedClasses - const filterTypeAvoid = elementTypeAvoid.find(r => document.activeElement && r === document.activeElement.tagName.toLowerCase()) - const filterClassAvoid = elementClassAvoid.find(r => document.activeElement && r === '.' + document.activeElement.className.toLowerCase()) - return !objectAvoid && mapFunctions[decodedKey] && !filterTypeAvoid && !filterClassAvoid -} - -const checkElementType = () => { - let elmTypeAvoid = [] - let elmClassAvoid = [] - elementAvoided.forEach(r => { - const dotPosition = r.indexOf('.') - if (dotPosition === 0) { - elmClassAvoid.push(r) - } else if (dotPosition > 0) { - elmTypeAvoid.push(r.split('.')[0]) - elmClassAvoid.push('.' + r.split('.')[1]) - } else { - elmTypeAvoid.push(r) - } - }) - return {avoidedTypes: elmTypeAvoid, avoidedClasses: elmClassAvoid} + // check if the element gets matched by at least one selector in the prevent list + const filterAvoid = elementAvoided.find(selector => document.activeElement && document.activeElement.matches(selector)) + return !objectAvoid && mapFunctions[decodedKey] && !filterAvoid } if (typeof module != 'undefined' && module.exports) { diff --git a/test/index.test.js b/test/index.test.js index dea3343..cc7d5fd 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -5,7 +5,7 @@ import Shortkey from '../src/index.js' find.shim() -Vue.use(Shortkey) +Vue.use(Shortkey, { prevent: ['.disableshortkey', '.disableshortkey textarea'] }) const VM = template => new Vue({ template, data() { @@ -172,6 +172,86 @@ describe('functionnal tests', () => { vm.$destroy() }) + it('does not trigger events when its class is in the prevent list', () => { + const vm = new VM('
') + vm.$mount(createDiv()) + + const textarea = vm.$el.querySelector('textarea') + textarea.focus() + expect(document.activeElement == textarea).to.be.true + + const keydown = createEvent('keydown') + keydown.key = 'b' + document.dispatchEvent(keydown) + + const keyup = createEvent('keyup') + keyup.key = 'b' + document.dispatchEvent(keyup) + + expect(vm.called).to.be.false + vm.$destroy() + }) + + it('does not trigger events when one of its classes is in the prevent list', () => { + const vm = new VM('
') + vm.$mount(createDiv()) + + const textarea = vm.$el.querySelector('textarea') + textarea.focus() + expect(document.activeElement == textarea).to.be.true + + const keydown = createEvent('keydown') + keydown.key = 'b' + document.dispatchEvent(keydown) + + const keyup = createEvent('keyup') + keyup.key = 'b' + document.dispatchEvent(keyup) + + expect(vm.called).to.be.false + vm.$destroy() + }) + + it('does not trigger events when it gets matched by one item in the prevent list', () => { + const vm = new VM('
') + vm.$mount(createDiv()) + + const textarea = vm.$el.querySelector('textarea') + textarea.focus() + expect(document.activeElement == textarea).to.be.true + + const keydown = createEvent('keydown') + keydown.key = 'b' + document.dispatchEvent(keydown) + + const keyup = createEvent('keyup') + keyup.key = 'b' + document.dispatchEvent(keyup) + + expect(vm.called).to.be.false + vm.$destroy() + }) + + it('does trigger events when only the parent element gets matched by one item in the prevent list', () => { + const vm = new VM('
') + vm.$mount(createDiv()) + + const input = vm.$el.querySelector('input') + input.focus() + expect(document.activeElement == input).to.be.true + + const keydown = createEvent('keydown') + keydown.key = 'b' + document.dispatchEvent(keydown) + + const keyup = createEvent('keyup') + keyup.key = 'b' + document.dispatchEvent(keyup) + + expect(vm.called).to.be.true + vm.$destroy() + }) + it('listen for keydown and dispatch event with object key', () => { const vm = new VM('
') vm.$mount(createDiv())