-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
74 lines (67 loc) · 2.41 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
const m = require('mithril/render/hyperscript')
const util = require('./src/util')
const fragmentHandler = require('./src/fragments')
const render = require('./src/render')
module.exports = {
oninit: function (v) {
const textFragments = v.state.textFragments = fragmentHandler()
v.state.doc = util.parse(v.attrs.content)
v.state.makeBold = addFormatting('bold')
v.state.makeItalic = addFormatting('italic')
var currentSelection
var previousSelection
function cleanup (selection) {
selection.selectedFragments.map(function (fragment) {
if (!document.body.contains(fragment.el)) {
fragment.removed = true
}
})
}
function addFormatting (type) {
return function (event) {
const selection = document.getSelection()
const fragment = textFragments.byEl(selection.focusNode)
fragment.type = 'array'
delete fragment.el
const start = Math.min(selection.anchorOffset, selection.focusOffset)
const end = Math.max(selection.anchorOffset, selection.focusOffset)
const formatedFragment = {
type: type,
content: { type: 'string', content: fragment.content.substring(start, end) }
}
fragment.content = [
{ type: 'string', content: fragment.content.substring(0, start) },
formatedFragment,
{ type: 'string', content: fragment.content.substring(end) }
]
currentSelection.fragment = formatedFragment
currentSelection.start = 0
currentSelection.end = end - start
}
}
v.state.onInput = function (event) {
currentSelection.selectedFragments.map(function (fragment) {
fragment.content = fragment.el.textContent
})
cleanup(previousSelection)
}
v.state.updateSelection = function (event) {
previousSelection = currentSelection
currentSelection = textFragments.selection(document.getSelection())
}
return v.state
},
view: function (v) {
v.state.textFragments.reset()
return m('.editor', [
m('button', { onclick: v.state.makeBold }, 'bold'),
m('button', { onclick: v.state.makeItalic }, 'italic'),
m('#editor[contenteditable]', {
onkeydown: v.state.updateSelection,
onmousedown: v.state.updateSelection,
oninput: v.state.onInput
}, render(v.state)(v.state.doc)),
m('#view', render.readOnly(v.state.doc))
])
}
}