From 3a7b4fd0070484598ee0328b5e34be0975cced5f Mon Sep 17 00:00:00 2001 From: Blake Thomson Date: Thu, 13 Aug 2015 14:04:03 -0400 Subject: [PATCH 1/2] Add removeHotkey to keyboard module, closes #110 Takes a string, number, or hotkey object. --- src/modules/keyboard.coffee | 7 +++++++ test/unit/modules/keyboard.coffee | 15 +++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/modules/keyboard.coffee b/src/modules/keyboard.coffee index 568b3b9371..0beb684428 100644 --- a/src/modules/keyboard.coffee +++ b/src/modules/keyboard.coffee @@ -30,6 +30,13 @@ class Keyboard @hotkeys[which].push(hotkey) ) + removeHotkey: (hotkey) -> + hotkey = if Keyboard.hotkeys[hotkey] then Keyboard.hotkeys[hotkey] else hotkey + hotkey = if _.isObject(hotkey) then hotkey else { key: hotkey } + which = if _.isNumber(hotkey.key) then hotkey.key else hotkey.key.toUpperCase().charCodeAt(0) + for handler in @hotkeys[which] || [] + return handler.callback if _.isEqual(hotkey, _.omit(handler, 'callback')) + toggleFormat: (range, format) -> if range.isCollapsed() delta = @quill.getContents(Math.max(0, range.start-1), range.end) diff --git a/test/unit/modules/keyboard.coffee b/test/unit/modules/keyboard.coffee index 460d361533..66c0cb2e38 100644 --- a/test/unit/modules/keyboard.coffee +++ b/test/unit/modules/keyboard.coffee @@ -80,5 +80,20 @@ describe('Keyboard', -> expect(dom($('.ql-bold').get(0)).hasClass('ql-active')).toBe(true) expect(dom($('.ql-size').get(0)).value()).toBe(size) ) + + it('removeHotkey by name', -> + fn = @quill.getModule('keyboard').removeHotkey('BOLD') + expect(typeof fn).toBe('function'); + ) + + it('removeHotkey by number', -> + fn = @quill.getModule('keyboard').removeHotkey(13) + expect(typeof fn).toBe('function'); + ) + + it('removeHotkey by object', -> + fn = @quill.getModule('keyboard').removeHotkey({ key: 'B', metaKey: true }) + expect(typeof fn).toBe('function'); + ) ) ) From 79eb7f9f5290f97f05ec17ed5e338f0bef6f80c5 Mon Sep 17 00:00:00 2001 From: Blake Thomson Date: Thu, 13 Aug 2015 18:34:55 -0400 Subject: [PATCH 2/2] Rename to removeHotkeys to indicate that an array is returned, and actually do what it says on the tin --- config/grunt/dist.coffee | 2 +- src/modules/keyboard.coffee | 14 ++++++++--- test/unit/modules/keyboard.coffee | 41 ++++++++++++++++++++++++------- 3 files changed, 43 insertions(+), 14 deletions(-) diff --git a/config/grunt/dist.coffee b/config/grunt/dist.coffee index ef9014415f..2c4c091b2d 100644 --- a/config/grunt/dist.coffee +++ b/config/grunt/dist.coffee @@ -67,7 +67,7 @@ module.exports = (grunt) -> modifier: 'modern' include: [ 'difference', 'intersection', 'last' - 'all', 'each', 'find', 'invoke', 'map', 'reduce' + 'all', 'each', 'find', 'invoke', 'map', 'reduce', 'partition', 'bind', 'defer', 'partial' 'clone', 'extend', 'defaults', 'omit', 'values' 'isElement', 'isEqual', 'isFunction', 'isNumber', 'isObject', 'isString' diff --git a/src/modules/keyboard.coffee b/src/modules/keyboard.coffee index 0beb684428..dd7b589068 100644 --- a/src/modules/keyboard.coffee +++ b/src/modules/keyboard.coffee @@ -30,12 +30,18 @@ class Keyboard @hotkeys[which].push(hotkey) ) - removeHotkey: (hotkey) -> + removeHotkeys: (hotkey, callback) -> + hotkey = if _.isString(hotkey) then hotkey.toUpperCase() else hotkey hotkey = if Keyboard.hotkeys[hotkey] then Keyboard.hotkeys[hotkey] else hotkey hotkey = if _.isObject(hotkey) then hotkey else { key: hotkey } - which = if _.isNumber(hotkey.key) then hotkey.key else hotkey.key.toUpperCase().charCodeAt(0) - for handler in @hotkeys[which] || [] - return handler.callback if _.isEqual(hotkey, _.omit(handler, 'callback')) + which = if _.isNumber(hotkey.key) then hotkey.key else hotkey.key.charCodeAt(0) + @hotkeys[which] ?= [] + [removed, kept] = _.partition(@hotkeys[which], (handler) -> + _.isEqual(hotkey, _.omit(handler, 'callback')) and + (!callback or callback == handler.callback) + ) + @hotkeys[which] = kept + return _.map(removed, 'callback') toggleFormat: (range, format) -> if range.isCollapsed() diff --git a/test/unit/modules/keyboard.coffee b/test/unit/modules/keyboard.coffee index 66c0cb2e38..d688b7f58e 100644 --- a/test/unit/modules/keyboard.coffee +++ b/test/unit/modules/keyboard.coffee @@ -81,19 +81,42 @@ describe('Keyboard', -> expect(dom($('.ql-size').get(0)).value()).toBe(size) ) - it('removeHotkey by name', -> - fn = @quill.getModule('keyboard').removeHotkey('BOLD') - expect(typeof fn).toBe('function'); + it('removeHotkeys by name', -> + counter = 0 + fn = -> counter += 1 + keyboard = @quill.getModule('keyboard') + keyboard.addHotkey('S', fn) + dom(@quill.root).trigger('keydown', { key: 'S' }) + expect(counter).toBe(1) + result = keyboard.removeHotkeys('S', fn) + expect(result.length).toBe(1) + expect(result[0]).toBe(fn); + dom(@quill.root).trigger('keydown', { key: 'S' }) + expect(counter).toBe(1) ) - it('removeHotkey by number', -> - fn = @quill.getModule('keyboard').removeHotkey(13) - expect(typeof fn).toBe('function'); + it('removeHotkeys by object', -> + counter = 0 + fn = -> counter += 1 + keyboard = @quill.getModule('keyboard') + keyboard.addHotkey({ key: 'S', metaKey: true }, fn) + dom(@quill.root).trigger('keydown', { key: 'S', metaKey: true }) + result = keyboard.removeHotkeys({ key: 'S', metaKey: true }) + expect(result.length).toBe(1) + expect(result[0]).toBe(fn) + dom(@quill.root).trigger('keydown', { key: 'S', metaKey: true }) + expect(counter).toBe(1) ) - it('removeHotkey by object', -> - fn = @quill.getModule('keyboard').removeHotkey({ key: 'B', metaKey: true }) - expect(typeof fn).toBe('function'); + it('removeHotKeys only the specified callback', -> + fn = -> + anotherFn = -> + keyboard = @quill.getModule('keyboard') + keyboard.addHotkey({ key: 'S', metaKey: true }, fn) + keyboard.addHotkey({ key: 'S', metaKey: true }, anotherFn) + result = keyboard.removeHotkeys({ key: 'S', metaKey: true }, fn) + expect(result.length).toBe(1) + expect(result[0]).toBe(fn) ) ) )