Skip to content

Commit e9db13d

Browse files
committed
feat: Add bold and italic event handling
1 parent aff1f0d commit e9db13d

File tree

6 files changed

+190
-1
lines changed

6 files changed

+190
-1
lines changed

spec/dispatcher.spec.js

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import * as content from '../src/content'
55
import Cursor from '../src/cursor'
66
import Keyboard from '../src/keyboard'
77
import Editable from '../src/core'
8+
import Selection from '../src/selection'
89
const {key} = Keyboard
910

1011
describe('Dispatcher', function () {
@@ -31,6 +32,18 @@ describe('Dispatcher', function () {
3132
return range
3233
}
3334

35+
function createSelection (range) {
36+
const selection = new Selection($elem[0], range)
37+
selection.setSelection()
38+
return selection
39+
}
40+
41+
function createFullRange (node) {
42+
const range = rangy.createRange()
43+
range.selectNodeContents(node)
44+
return range
45+
}
46+
3447
let onListener
3548
// register one listener per test
3649
function on (eventName, func) {
@@ -214,5 +227,47 @@ describe('Dispatcher', function () {
214227
$elem.trigger(event)
215228
})
216229
})
230+
231+
describe('on bold', function () {
232+
233+
beforeEach(function () {
234+
event = $.Event('keydown')
235+
event.ctrlKey = true
236+
event.keyCode = key.b
237+
})
238+
239+
it('fires toggleBold when ctrl + b is pressed', (done) => {
240+
$elem.html('foo')
241+
const elemSelection = createSelection(createFullRange($elem[0]))
242+
243+
on('toggleBold', (selection) => {
244+
expect(selection).toEqual(elemSelection)
245+
done()
246+
})
247+
248+
$elem.trigger(event)
249+
})
250+
})
251+
252+
describe('on italic', function () {
253+
254+
beforeEach(function () {
255+
event = $.Event('keydown')
256+
event.ctrlKey = true
257+
event.keyCode = key.i
258+
})
259+
260+
it('fires toggleEmphasis when ctrl + i is pressed', (done) => {
261+
$elem.html('foo')
262+
const elemSelection = createSelection(createFullRange($elem[0]))
263+
264+
on('toggleEmphasis', (selection) => {
265+
expect(selection).toEqual(elemSelection)
266+
done()
267+
})
268+
269+
$elem.trigger(event)
270+
})
271+
})
217272
})
218273
})

spec/keyboard.spec.js

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,80 @@ describe('Keyboard', function () {
5959
keyboard.dispatchKeyEvent(event, {}, false)
6060
expect(called).toEqual(0)
6161
})
62+
63+
it('does fire the event for a "b" key', function () {
64+
keyboard.on('character', () => called++)
65+
66+
event.keyCode = Keyboard.key.b
67+
keyboard.dispatchKeyEvent(event, {}, true)
68+
expect(called).toEqual(1)
69+
})
70+
71+
it('does fire the event for an "i" key', function () {
72+
keyboard.on('character', () => called++)
73+
74+
event.keyCode = Keyboard.key.i
75+
keyboard.dispatchKeyEvent(event, {}, true)
76+
expect(called).toEqual(1)
77+
})
78+
})
79+
80+
describe('notify "bold" event', function () {
81+
82+
it('does not fire the event for a "b" key without "ctrl" or "meta" key', function () {
83+
keyboard.on('bold', () => called++)
84+
85+
event.keyCode = Keyboard.key.b
86+
keyboard.dispatchKeyEvent(event, {}, true)
87+
expect(called).toEqual(0)
88+
})
89+
90+
it('does fire the event for a "b" key with "ctrl" key', function () {
91+
keyboard.on('bold', () => called++)
92+
93+
event.keyCode = Keyboard.key.b
94+
event.ctrlKey = true
95+
keyboard.dispatchKeyEvent(event, {}, true)
96+
expect(called).toEqual(1)
97+
})
98+
99+
it('does fire the event for a "b" key with "meta" key', function () {
100+
keyboard.on('bold', () => called++)
101+
102+
event.keyCode = Keyboard.key.b
103+
event.metaKey = true
104+
keyboard.dispatchKeyEvent(event, {}, true)
105+
expect(called).toEqual(1)
106+
})
107+
})
108+
109+
describe('notify "italic" event', function () {
110+
111+
it('does not fire the event for a "i" key without "ctrl" or "meta" key', function () {
112+
keyboard.on('italic', () => called++)
113+
114+
event.keyCode = Keyboard.key.i
115+
keyboard.dispatchKeyEvent(event, {}, true)
116+
expect(called).toEqual(0)
117+
})
118+
119+
it('does fire the event for a "i" key with "ctrl" key', function () {
120+
keyboard.on('italic', () => called++)
121+
122+
event.keyCode = Keyboard.key.i
123+
event.ctrlKey = true
124+
keyboard.dispatchKeyEvent(event, {}, true)
125+
expect(called).toEqual(1)
126+
})
127+
128+
it('does fire the event for a "i" key with "meta" key', function () {
129+
keyboard.on('italic', () => called++)
130+
131+
event.keyCode = Keyboard.key.i
132+
event.metaKey = true
133+
keyboard.dispatchKeyEvent(event, {}, true)
134+
expect(called).toEqual(1)
135+
})
62136
})
63137
})
64138

src/create-default-behavior.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,14 @@ export default function createDefaultBehavior (editable) {
173173

174174
clipboard (element, action, cursor) {
175175
log('Default clipboard behavior')
176+
},
177+
178+
toggleBold (selection) {
179+
selection.toggleBold()
180+
},
181+
182+
toggleEmphasis (selection) {
183+
selection.toggleEmphasis()
176184
}
177185
}
178186
}

src/create-default-events.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,26 @@ export default function createDefaultEvents (editable) {
185185
*/
186186
paste (element, blocks, cursor) {
187187
behavior.paste(element, blocks, cursor)
188+
},
189+
190+
/**
191+
* The toggleBold event is triggered when the bold keyboard shortcut is used
192+
*
193+
* @event toggleBold
194+
* @param {Selection} The selection object.
195+
*/
196+
toggleBold (selection) {
197+
behavior.toggleBold(selection)
198+
},
199+
200+
/**
201+
* The toggleEmphasis event is triggered when the italic keyboard shortcut is used
202+
*
203+
* @event toggleEmphasis
204+
* @param {Selection} The selection object.
205+
*/
206+
toggleEmphasis (selection) {
207+
behavior.toggleEmphasis(selection)
188208
}
189209
}
190210
}

src/dispatcher.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,24 @@ export default class Dispatcher {
261261
self.notify('newline', this, cursor)
262262
})
263263

264+
.on('bold', function (event) {
265+
event.preventDefault()
266+
event.stopPropagation()
267+
const selection = self.selectionWatcher.getFreshSelection()
268+
if (selection.isSelection) {
269+
self.notify('toggleBold', selection)
270+
}
271+
})
272+
273+
.on('italic', function (event) {
274+
event.preventDefault()
275+
event.stopPropagation()
276+
const selection = self.selectionWatcher.getFreshSelection()
277+
if (selection.isSelection) {
278+
self.notify('toggleEmphasis', selection)
279+
}
280+
})
281+
264282
.on('character', function (event) {
265283
self.notify('change', this)
266284
})

src/keyboard.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,17 +46,29 @@ export default class Keyboard {
4646
case this.key.enter:
4747
if (event.shiftKey) return this.notify(target, 'shiftEnter', event)
4848
return this.notify(target, 'enter', event)
49+
4950
case this.key.ctrl:
5051
case this.key.shift:
5152
case this.key.alt:
5253
return
54+
5355
// Metakey
5456
case 224: // Firefox: 224
5557
case 17: // Opera: 17
5658
case 91: // Chrome/Safari: 91 (Left)
5759
case 93: // Chrome/Safari: 93 (Right)
5860
return
61+
5962
default:
63+
// Added here to avoid using fallthrough in the switch
64+
// when b or i are pressed without ctrlKey or metaKey
65+
if (event.keyCode === this.key.b && (event.ctrlKey || event.metaKey)) {
66+
return this.notify(target, 'bold', event)
67+
}
68+
if (event.keyCode === this.key.i && (event.ctrlKey || event.metaKey)) {
69+
return this.notify(target, 'italic', event)
70+
}
71+
6072
this.preventContenteditableBug(target, event)
6173
if (!notifyCharacterEvent) return
6274
// Don't notify character events as long as either the ctrl or
@@ -179,5 +191,7 @@ Keyboard.key = Keyboard.prototype.key = {
179191
enter: 13,
180192
shift: 16,
181193
ctrl: 17,
182-
alt: 18
194+
alt: 18,
195+
b: 66,
196+
i: 73
183197
}

0 commit comments

Comments
 (0)