written 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/written/app/assets/javascripts/written/core/content.coffee +41 -10
- data/lib/written/app/assets/javascripts/written/core/cursor.coffee +5 -5
- data/lib/written/app/assets/javascripts/written/core/document.coffee +2 -1
- data/lib/written/app/assets/javascripts/written/core/history.coffee +23 -10
- data/lib/written/app/assets/javascripts/written/parsers/block/code.coffee +3 -2
- data/lib/written/app/assets/javascripts/written/parsers/parsers.coffee +15 -0
- data/lib/written/app/assets/javascripts/written.coffee +0 -2
- data/lib/written/version.rb +1 -1
- data/test/server/app/assets/javascripts/application.coffee +4 -0
- data/test/server/app/assets/javascripts/prism.js +26 -0
- data/test/server/app/assets/stylesheets/application.scss +1 -0
- data/test/server/app/assets/stylesheets/prism.css +179 -0
- data/test/server/app/views/posts/show.html.erb +4 -1
- metadata +3 -4
- data/lib/written/app/assets/javascripts/vendors/prism.js +0 -1411
- data/lib/written/app/assets/javascripts/written/extensions/clipboard.coffee +0 -114
- data/lib/written/app/assets/javascripts/written/extensions/image.coffee +0 -91
@@ -1,114 +0,0 @@
|
|
1
|
-
class ClipBoard
|
2
|
-
constructor: (editor, hooks) ->
|
3
|
-
@editor = editor
|
4
|
-
@editor.element().addEventListener 'paste', @paste
|
5
|
-
|
6
|
-
paste: (e) =>
|
7
|
-
e.preventDefault()
|
8
|
-
e.stopPropagation()
|
9
|
-
|
10
|
-
data = e.clipboardData.getData('text/plain')
|
11
|
-
|
12
|
-
texts = data.split('\n').map (text) ->
|
13
|
-
document.createTextNode(text)
|
14
|
-
return unless texts.length > 0
|
15
|
-
|
16
|
-
_sel = window.getSelection()
|
17
|
-
sel = {
|
18
|
-
type: _sel.type
|
19
|
-
}
|
20
|
-
position = _sel.anchorNode.compareDocumentPosition(_sel.extentNode)
|
21
|
-
if _sel.anchorOffset <= _sel.extentOffset || position == document.DOCUMENT_POSITION_PRECEDING
|
22
|
-
sel.anchorNode = _sel.anchorNode
|
23
|
-
sel.anchorOffset = _sel.anchorOffset
|
24
|
-
sel.extentNode = _sel.extentNode
|
25
|
-
sel.extentOffset = _sel.extentOffset
|
26
|
-
else
|
27
|
-
sel.anchorNode = _sel.extentNode
|
28
|
-
sel.anchorOffset = _sel.extentOffset
|
29
|
-
sel.extentNode = _sel.anchorNode
|
30
|
-
sel.extentOffset = _sel.anchorOffset
|
31
|
-
|
32
|
-
if sel.anchorNode == @editor.element()
|
33
|
-
line = @editor.line()
|
34
|
-
@editor.element().appendChild(line)
|
35
|
-
sel.anchorNode = sel.extentNode = line
|
36
|
-
|
37
|
-
@editor.observer.hold =>
|
38
|
-
if sel.type == 'Range'
|
39
|
-
@replace(texts, sel)
|
40
|
-
else
|
41
|
-
@insert(texts, sel)
|
42
|
-
|
43
|
-
|
44
|
-
replace: (texts, sel) =>
|
45
|
-
|
46
|
-
node = sel.extentNode
|
47
|
-
line = node
|
48
|
-
nodes = [node]
|
49
|
-
|
50
|
-
while line.parentElement != @editor.element()
|
51
|
-
line = line.parentElement
|
52
|
-
|
53
|
-
offsets = {
|
54
|
-
start: sel.anchorOffset
|
55
|
-
end: sel.extentOffset
|
56
|
-
}
|
57
|
-
|
58
|
-
offsets.start = @editor.lineOffset(line, sel.anchorNode, offsets.start)
|
59
|
-
offsets.end = @editor.lineOffset(line, sel.extentNode, offsets.end)
|
60
|
-
|
61
|
-
text = texts.map((t) ->
|
62
|
-
t.textContent
|
63
|
-
).join()
|
64
|
-
|
65
|
-
|
66
|
-
line.textContent = line.textContent.substr(0, offsets.start) + text + line.textContent.substr(offsets.end)
|
67
|
-
|
68
|
-
fragment = @editor.parse(@editor.cloneNodesFrom(line))
|
69
|
-
|
70
|
-
@editor.updateDOM(line, fragment)
|
71
|
-
|
72
|
-
cursor = new Written.Cursor(offsets.start + text.length)
|
73
|
-
cursor.update(@editor.walker(cursor.focus(line)), true)
|
74
|
-
|
75
|
-
|
76
|
-
insert: (texts, sel) =>
|
77
|
-
node = sel.anchorNode
|
78
|
-
str = node.textContent
|
79
|
-
text = texts.map((t) ->
|
80
|
-
t.textContent
|
81
|
-
).join("\n")
|
82
|
-
|
83
|
-
node.textContent = str.substr(0, sel.anchorOffset)
|
84
|
-
node.textContent += text
|
85
|
-
node.textContent += str.substr(sel.anchorOffset)
|
86
|
-
|
87
|
-
line = node
|
88
|
-
while line.parentElement != @editor.element()
|
89
|
-
line = line.parentElement
|
90
|
-
|
91
|
-
offset = sel.anchorOffset + text.length
|
92
|
-
if node != line
|
93
|
-
offset += @nodeOffset(node, line)
|
94
|
-
|
95
|
-
fragment = @editor.parse(@editor.cloneNodesFrom(line))
|
96
|
-
|
97
|
-
lines = @editor.updateDOM(line, fragment)
|
98
|
-
|
99
|
-
cursor = new Written.Cursor(offset)
|
100
|
-
cursor.update(@editor.walker(cursor.focus(lines[0])), true)
|
101
|
-
|
102
|
-
nodeOffset: (node, line) ->
|
103
|
-
offset = 0
|
104
|
-
|
105
|
-
for n in line.childNodes
|
106
|
-
if n == node
|
107
|
-
break
|
108
|
-
else if n.contains(node)
|
109
|
-
offset += @nodeOffset(node, n)
|
110
|
-
break
|
111
|
-
else
|
112
|
-
offset += n.textContent.length
|
113
|
-
|
114
|
-
offset
|
@@ -1,91 +0,0 @@
|
|
1
|
-
class
|
2
|
-
loaded: =>
|
3
|
-
@element().addEventListener 'dragover', @over
|
4
|
-
@element().addEventListener 'dragleave', @cancel
|
5
|
-
@element().addEventListener 'drop', @drop
|
6
|
-
@on 'click', @container(), @open
|
7
|
-
@on 'change', @element().querySelector('input'), @upload
|
8
|
-
if @element().querySelector('figcaption').hasAttribute('name')
|
9
|
-
@show()
|
10
|
-
else
|
11
|
-
@placehold()
|
12
|
-
|
13
|
-
over: (e) =>
|
14
|
-
e.preventDefault()
|
15
|
-
@element().classList.add 'dropping'
|
16
|
-
|
17
|
-
cancel: (e) =>
|
18
|
-
e.preventDefault()
|
19
|
-
@element().classList.remove 'dropping'
|
20
|
-
|
21
|
-
drop: (e) =>
|
22
|
-
e.preventDefault()
|
23
|
-
@element().classList.remove 'dropping'
|
24
|
-
e.file = e.dataTransfer.files[0]
|
25
|
-
@upload(e)
|
26
|
-
|
27
|
-
show: =>
|
28
|
-
img = @retrieve('img')
|
29
|
-
img.src = @element().querySelector('figcaption').getAttribute('name')
|
30
|
-
@container().appendChild(img)
|
31
|
-
|
32
|
-
placehold: =>
|
33
|
-
placeholder = @retrieve('.placeholder')
|
34
|
-
@container().appendChild(placeholder)
|
35
|
-
|
36
|
-
container: =>
|
37
|
-
@container.element ||= @element().querySelector('div[contenteditable=false]')
|
38
|
-
|
39
|
-
open: =>
|
40
|
-
@container().querySelector('input').click()
|
41
|
-
|
42
|
-
uploaded: (e) =>
|
43
|
-
xml = new DOMParser().parseFromString(e.target.response, 'text/xml')
|
44
|
-
url = xml.querySelector('Location').textContent
|
45
|
-
img = @retrieve('img')
|
46
|
-
img.src = url
|
47
|
-
progressBar = @retrieve('.progressbar')
|
48
|
-
@container().insertBefore(img, progressBar)
|
49
|
-
progressBar.remove()
|
50
|
-
@retrieve('.placeholder').remove()
|
51
|
-
@element().querySelector('figcaption').lastChild.textContent = "(#{url})"
|
52
|
-
|
53
|
-
upload: (e) =>
|
54
|
-
@container().appendChild(@retrieve('.progressbar'))
|
55
|
-
unless e.file?
|
56
|
-
e.file = e.target.files[0]
|
57
|
-
id = PostBody.getAttribute('postid')
|
58
|
-
policy = PostBody.getAttribute('policy')
|
59
|
-
signature = PostBody.getAttribute('signature')
|
60
|
-
bucket = PostBody.getAttribute('bucket')
|
61
|
-
namespace = PostBody.getAttribute('namespace')
|
62
|
-
access_key = PostBody.getAttribute('access_key')
|
63
|
-
|
64
|
-
url = "https://s3.amazonaws.com/#{bucket}/"
|
65
|
-
dir = [id]
|
66
|
-
if namespace?
|
67
|
-
dir.splice(0,0, namespace)
|
68
|
-
|
69
|
-
dir = dir.join '/'
|
70
|
-
|
71
|
-
data = new FormData()
|
72
|
-
data.append 'AWSAccessKeyId', access_key
|
73
|
-
data.append 'success_action_status', 201
|
74
|
-
data.append 'acl', 'private'
|
75
|
-
data.append 'policy', policy
|
76
|
-
data.append 'signature', signature
|
77
|
-
data.append 'key', "#{dir}/#{e.file.name}"
|
78
|
-
data.append 'Content-Type', e.file.type
|
79
|
-
data.append 'file', e.file
|
80
|
-
|
81
|
-
xhr = new XMLHttpRequest()
|
82
|
-
xhr.open('POST', url, true)
|
83
|
-
xhr.onload = @uploaded
|
84
|
-
xhr.onprogress = @progress
|
85
|
-
xhr.send(data)
|
86
|
-
|
87
|
-
progress: (e) =>
|
88
|
-
return unless e.lengthComputable
|
89
|
-
percentComplete = e.loaded / e.total * 100.0;
|
90
|
-
progressBar = @retrieve('.progressbar')
|
91
|
-
progressBar.firstElementChild.style.width = "#{percentComplete}%";
|