forked from slab/quill
-
Notifications
You must be signed in to change notification settings - Fork 0
/
document.coffee
107 lines (92 loc) · 2.94 KB
/
document.coffee
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
ScribeDOM = require('./dom')
ScribeFormatManager = require('./format-manager')
ScribeLine = require('./line')
ScribeNormalizer = require('./normalizer')
ScribeUtils = require('./utils')
Tandem = require('tandem-core')
class ScribeDocument
constructor: (@root, options = {}) ->
@formatManager = new ScribeFormatManager(@root, options)
@normalizer = new ScribeNormalizer(@root, @formatManager)
@root.innerHTML = ScribeNormalizer.normalizeHtml(@root.innerHTML)
@lines = new LinkedList()
@lineMap = {}
@normalizer.normalizeDoc()
_.each(@root.childNodes, (node) =>
this.appendLine(node)
)
appendLine: (lineNode) ->
return this.insertLineBefore(lineNode, null)
findLeaf: (node) ->
lineNode = node.parentNode
while lineNode? && !ScribeUtils.isLineNode(lineNode)
lineNode = lineNode.parentNode
return null if !lineNode?
line = this.findLine(lineNode)
return line.findLeaf(node)
findLine: (node) ->
node = this.findLineNode(node)
if node?
return @lineMap[node.id]
else
return null
findLineAtOffset: (offset) ->
retLine = @lines.first
_.all(@lines.toArray(), (line, index) =>
retLine = line
if offset < line.length
return false
else
offset -= line.length if index < @lines.length - 1
return true
)
return [retLine, offset]
findLineNode: (node) ->
while node? && !ScribeUtils.isLineNode(node)
node = node.parentNode
return node
insertLineBefore: (newLineNode, refLine) ->
line = new ScribeLine(this, newLineNode)
if refLine != null
@lines.insertAfter(refLine.prev, line)
else
@lines.append(line)
@lineMap[line.id] = line
return line
mergeLines: (line, lineToMerge) ->
return unless line? and lineToMerge?
_.each(_.clone(lineToMerge.node.childNodes), (child) ->
line.node.appendChild(child)
)
ScribeDOM.removeNode(lineToMerge.node)
this.removeLine(lineToMerge)
line.trailingNewline = lineToMerge.trailingNewline
line.rebuild()
removeLine: (line) ->
delete @lineMap[line.id]
@lines.remove(line)
splitLine: (line, offset) ->
if offset != line.length or line.trailingNewline
[lineNode1, lineNode2] = ScribeUtils.splitNode(line.node, offset, true)
line.node = lineNode1
trailingNewline = line.trailingNewline
line.trailingNewline = true
this.updateLine(line)
newLine = this.insertLineBefore(lineNode2, line.next)
newLine.trailingNewline = trailingNewline
newLine.resetContent()
return newLine
else
line.trailingNewline = true
line.resetContent()
return line
toDelta: ->
lines = @lines.toArray()
ops = _.flatten(_.map(lines, (line, index) ->
return line.delta.ops
), true)
delta = new Tandem.Delta(0, ops)
return delta
updateLine: (line) ->
return line.rebuild()
module.exports = ScribeDocument