dante-editor 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/app/assets/javascripts/dante.js +1 -0
- data/app/assets/javascripts/dante/behaviors/image.js.coffee +235 -3
- data/app/assets/javascripts/dante/behaviors/paste.js.coffee +64 -0
- data/app/assets/javascripts/dante/editor.js.coffee +44 -191
- data/app/assets/javascripts/dante/popover.js.coffee +1 -1
- data/app/assets/javascripts/dante/tooltip_widgets/uploader.js.coffee +7 -2
- data/bower.json +1 -1
- data/dist/js/dante-editor.js +357 -199
- data/lib/dante-editor/version.rb +1 -1
- data/source/partials/_readme.markdown +15 -10
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b896bd119ce66604964b20e7e45e6d7547e26022
|
4
|
+
data.tar.gz: 4675935e48ee846eccbf5ba67f5c961d9343635b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 011a522973ef58cc5e486d70779f52dc876b65c3cb64478634e8b6fc6584a424dcab24b9c274390af0390e7f8c72cd72a3a99b9466c1eb5825b3c3653ad7918f
|
7
|
+
data.tar.gz: d994b05d927cb2059506b0d251252dc9dcf90b7413f6e677b1714697af3fecf8310ae9575403ae7e879ae120c2c9b4c0c42efdb5d8a8645a302e5a3501ef03b4
|
data/README.md
CHANGED
@@ -94,7 +94,7 @@ Until now I´ve been able to implement the following features:
|
|
94
94
|
#### Uploader:
|
95
95
|
+ **upload_url:** default: /uploads.json
|
96
96
|
+ **upload_callback** default: empty, allows optional way to handle the server response when image is uploaded This is useful when you don't have control on the backend response.
|
97
|
-
|
97
|
+
+ **image_delete_callback**: default: none, returns the image data before deletion. use this if you want to destroy image from the server.
|
98
98
|
#### Embed tool:
|
99
99
|
+ **oembed_url:** default: http://api.embed.ly/1/oembed?url="
|
100
100
|
+ **extract_url:** default: http://api.embed.ly/1/extract?url="
|
@@ -2,6 +2,16 @@ utils = Dante.utils
|
|
2
2
|
|
3
3
|
class Dante.View.Behavior.Image extends Dante.View.Behavior
|
4
4
|
|
5
|
+
# TODO. dry up this!, call constants from @editor
|
6
|
+
BACKSPACE = 8
|
7
|
+
TAB = 9
|
8
|
+
ENTER = 13
|
9
|
+
SPACEBAR = 32
|
10
|
+
LEFTARROW = 37
|
11
|
+
UPARROW = 38
|
12
|
+
RIGHTARROW = 39
|
13
|
+
DOWNARROW = 40
|
14
|
+
|
5
15
|
events:
|
6
16
|
"click .graf--figure .aspectRatioPlaceholder" : "handleGrafFigureSelectImg"
|
7
17
|
"click .graf--figure figcaption" : "handleGrafFigureSelectCaption"
|
@@ -27,17 +37,24 @@ class Dante.View.Behavior.Image extends Dante.View.Behavior
|
|
27
37
|
target = $(ev.currentTarget)
|
28
38
|
@editor.pop_over_align.positionPopOver(target)
|
29
39
|
|
40
|
+
placeHolderDiv: (target)->
|
41
|
+
target.find(".aspectRatioPlaceholder")
|
42
|
+
|
30
43
|
handleGrafFigureSelectCaption: (ev)->
|
31
44
|
utils.log "FIGCAPTION"
|
32
45
|
element = ev.currentTarget
|
33
46
|
$(element).parent(".graf--figure").removeClass("is-mediaFocused")
|
47
|
+
@editor.pop_over_align.hide()
|
34
48
|
|
35
49
|
handleGrafCaptionTyping: (ev)->
|
50
|
+
@editor.pop_over_align.hide()
|
51
|
+
|
52
|
+
node = $(@editor.getNode())
|
53
|
+
|
36
54
|
if _.isEmpty(utils.getNode().textContent.trim())
|
37
|
-
$(
|
55
|
+
$(node).addClass("is-defaultValue")
|
38
56
|
else
|
39
|
-
$(
|
40
|
-
|
57
|
+
$(node).removeClass("is-defaultValue")
|
41
58
|
|
42
59
|
#TODO: this is from embed! move this to embed behavior
|
43
60
|
handleGrafFigureSelectIframe: (ev)->
|
@@ -54,3 +71,218 @@ class Dante.View.Behavior.Image extends Dante.View.Behavior
|
|
54
71
|
@iframeSelected = null
|
55
72
|
$(element).removeClass("is-selected is-mediaFocused")
|
56
73
|
|
74
|
+
handleKeyDown: (e, parent)->
|
75
|
+
|
76
|
+
if _.contains([UPARROW, DOWNARROW], e.which)
|
77
|
+
utils.log e.which
|
78
|
+
@handleArrowForKeyDown(e)
|
79
|
+
|
80
|
+
if (e.which is BACKSPACE)
|
81
|
+
|
82
|
+
# without selection but with target active
|
83
|
+
if $(e.target).hasClass("graf--figure")
|
84
|
+
e.preventDefault()
|
85
|
+
|
86
|
+
# call callback for image delete
|
87
|
+
if @editor.image_delete_callback
|
88
|
+
@editor.image_delete_callback( $(".is-selected").find("img").data() )
|
89
|
+
|
90
|
+
utils.log("Replacing selected node")
|
91
|
+
@editor.replaceWith("p", $(".is-selected"))
|
92
|
+
@editor.setRangeAt($(".is-selected")[0])
|
93
|
+
@editor.pop_over_align.hide()
|
94
|
+
utils.log("Focus on the previous graf")
|
95
|
+
@editor.continue = false
|
96
|
+
return false
|
97
|
+
|
98
|
+
#select an image if backspacing into it from a paragraph
|
99
|
+
if(parent.hasClass("graf--p") && @editor.isFirstChar() )
|
100
|
+
if(parent.prev().hasClass("graf--figure") && @editor.getSelectedText().length == 0)
|
101
|
+
e.preventDefault()
|
102
|
+
parent.prev().find("img").click()
|
103
|
+
@editor.pop_over_align.positionPopOver(parent.prev())
|
104
|
+
utils.log("Focus on the previous image")
|
105
|
+
@editor.continue = false
|
106
|
+
return false
|
107
|
+
|
108
|
+
# supress del into & delete embed if empty content found on delete key
|
109
|
+
if parent.hasClass("graf--mixtapeEmbed") or parent.hasClass("graf--iframe")
|
110
|
+
if _.isEmpty parent.text().trim() or @isFirstChar()
|
111
|
+
utils.log("Check for inmediate deletion on empty embed text")
|
112
|
+
@editor.inmediateDeletion = @editor.isSelectingAll(anchor_node)
|
113
|
+
@editor.handleInmediateDeletion(parent) if @editor.inmediateDeletion
|
114
|
+
e.preventDefault()
|
115
|
+
@editor.continue = false
|
116
|
+
return false
|
117
|
+
|
118
|
+
# TODO: supress del when the prev el is embed and current_node is at first char
|
119
|
+
if parent.prev().hasClass("graf--mixtapeEmbed")
|
120
|
+
if @editor.isFirstChar() && !_.isEmpty( parent.text().trim() )
|
121
|
+
@editor.continue = false
|
122
|
+
return false
|
123
|
+
|
124
|
+
# when user types over a selected image (graf--figure)
|
125
|
+
# unselect image , and set range on caption
|
126
|
+
if _.isUndefined(parent) or parent.length is 0 && $(".is-selected").hasClass("is-mediaFocused")
|
127
|
+
# will remove default value on typing
|
128
|
+
node = $(".is-selected").find("figcaption")
|
129
|
+
node.find(".defaultValue").remove()
|
130
|
+
|
131
|
+
@editor.setRangeAt node[0]
|
132
|
+
$(".is-selected").removeClass("is-mediaFocused")
|
133
|
+
@editor.pop_over_align.hide()
|
134
|
+
#@editor.continue = false
|
135
|
+
return false
|
136
|
+
|
137
|
+
# handleKeyUp: (e, parent)->
|
138
|
+
|
139
|
+
#handle arrow direction from keyDown.
|
140
|
+
handleArrowForKeyDown: (ev)=>
|
141
|
+
caret_node = @editor.getNode()
|
142
|
+
current_node = $(caret_node)
|
143
|
+
utils.log(ev)
|
144
|
+
ev_type = ev.originalEvent.key || ev.originalEvent.keyIdentifier
|
145
|
+
|
146
|
+
utils.log("ENTER ARROW for key #{ev_type}")
|
147
|
+
|
148
|
+
|
149
|
+
#handle keys for image figure
|
150
|
+
|
151
|
+
switch ev_type
|
152
|
+
|
153
|
+
when "ArrowDown", "Down"
|
154
|
+
# when graff-image selected but none selection is found
|
155
|
+
if _.isUndefined(current_node) or !current_node.exists()
|
156
|
+
if $(".is-selected").exists()
|
157
|
+
current_node = $(".is-selected")
|
158
|
+
|
159
|
+
next_node = current_node.next()
|
160
|
+
|
161
|
+
utils.log "NEXT NODE IS #{next_node.attr('class')}"
|
162
|
+
utils.log "CURRENT NODE IS #{current_node.attr('class')}"
|
163
|
+
|
164
|
+
return unless $(current_node).hasClass("graf")
|
165
|
+
return unless current_node.hasClass("graf--figure") or $(current_node).editableCaretOnLastLine()
|
166
|
+
|
167
|
+
utils.log "ENTER ARROW PASSED RETURNS"
|
168
|
+
|
169
|
+
#if next element is embed select & focus it
|
170
|
+
if next_node.hasClass("graf--figure") && caret_node
|
171
|
+
n = next_node.find(".imageCaption")
|
172
|
+
@editor.scrollTo(n)
|
173
|
+
utils.log "1 down"
|
174
|
+
utils.log n[0]
|
175
|
+
@editor.skip_keyup = true
|
176
|
+
@editor.selection().removeAllRanges()
|
177
|
+
@editor.markAsSelected(next_node)
|
178
|
+
next_node.addClass("is-mediaFocused is-selected")
|
179
|
+
|
180
|
+
#@editor.setRangeAt $(".is-selected").find("figcaption")[0]
|
181
|
+
@editor.pop_over_align.positionPopOver(@placeHolderDiv(next_node))
|
182
|
+
@editor.continue = false
|
183
|
+
|
184
|
+
return false
|
185
|
+
|
186
|
+
else if next_node.prev().hasClass("graf--figure")
|
187
|
+
@editor.pop_over_align.hide()
|
188
|
+
|
189
|
+
#if current node is embed
|
190
|
+
else if next_node.hasClass("graf--mixtapeEmbed")
|
191
|
+
n = current_node.next(".graf--mixtapeEmbed")
|
192
|
+
num = n[0].childNodes.length
|
193
|
+
@editor.setRangeAt n[0], num
|
194
|
+
#@editor.scrollTo(n)
|
195
|
+
utils.log "2 down"
|
196
|
+
@editor.continue = false
|
197
|
+
return false
|
198
|
+
|
199
|
+
if current_node.hasClass("graf--figure") && next_node.hasClass("graf")
|
200
|
+
@editor.scrollTo(next_node)
|
201
|
+
utils.log "3 down, from figure to next graf"
|
202
|
+
@editor.skip_keyup = true
|
203
|
+
@editor.markAsSelected(next_node)
|
204
|
+
@editor.setRangeAt next_node[0]
|
205
|
+
@editor.continue = false
|
206
|
+
|
207
|
+
return false
|
208
|
+
|
209
|
+
when "ArrowUp", "Up"
|
210
|
+
prev_node = current_node.prev()
|
211
|
+
utils.log "PREV NODE IS #{prev_node.attr('class')} #{prev_node.attr('name')}"
|
212
|
+
utils.log "CURRENT NODE IS up #{current_node.attr('class')}"
|
213
|
+
|
214
|
+
# will handle up when figure is selected
|
215
|
+
if prev_node.length is 0 && $(ev.target).hasClass("graf--figure")
|
216
|
+
n = $(ev.target).prev(".graf")
|
217
|
+
#num = n[0].childNodes.length
|
218
|
+
#@editor.setRangeAt n[0], num
|
219
|
+
@editor.continue = false
|
220
|
+
@editor.markAsSelected(n[0])
|
221
|
+
@editor.pop_over_align.hide()
|
222
|
+
return false
|
223
|
+
|
224
|
+
else if prev_node.length > 0 && $(".graf--figure.is-mediaFocused").length > 0
|
225
|
+
# do our best to detect up arrow from selected
|
226
|
+
n = $(".graf--figure.is-mediaFocused").prev(".graf")
|
227
|
+
#num = n[0].childNodes.length
|
228
|
+
#@editor.setRangeAt n[0], num
|
229
|
+
@editor.continue = false
|
230
|
+
@editor.markAsSelected(n[0])
|
231
|
+
@editor.pop_over_align.hide()
|
232
|
+
return false
|
233
|
+
|
234
|
+
return unless $(current_node).hasClass("graf")
|
235
|
+
return unless $(current_node).editableCaretOnFirstLine()
|
236
|
+
|
237
|
+
utils.log "ENTER ARROW PASSED RETURNS"
|
238
|
+
|
239
|
+
if prev_node.hasClass("graf--figure")
|
240
|
+
utils.log "1 up"
|
241
|
+
n = prev_node.find(".imageCaption")
|
242
|
+
@editor.scrollTo(n)
|
243
|
+
@editor.skip_keyup = true
|
244
|
+
@editor.selection().removeAllRanges()
|
245
|
+
@editor.markAsSelected(prev_node)
|
246
|
+
|
247
|
+
#TODO: to function
|
248
|
+
# @editor.setRangeAt $(".is-selected").find("figcaption")[0]
|
249
|
+
prev_node.addClass("is-mediaFocused")
|
250
|
+
@editor.pop_over_align.positionPopOver(@placeHolderDiv(prev_node))
|
251
|
+
|
252
|
+
@editor.continue = false
|
253
|
+
|
254
|
+
return false
|
255
|
+
|
256
|
+
else if prev_node.hasClass("graf--mixtapeEmbed")
|
257
|
+
n = current_node.prev(".graf--mixtapeEmbed")
|
258
|
+
num = n[0].childNodes.length
|
259
|
+
@editor.setRangeAt n[0], num
|
260
|
+
#@editor.scrollTo(n)
|
261
|
+
utils.log "2 up"
|
262
|
+
@editor.continue = false
|
263
|
+
return false
|
264
|
+
|
265
|
+
if current_node.hasClass("graf--figure") && prev_node.hasClass("graf")
|
266
|
+
@editor.setRangeAt prev_node[0]
|
267
|
+
#@editor.scrollTo(prev_node)
|
268
|
+
utils.log "3 up"
|
269
|
+
@editor.continue = false
|
270
|
+
return false
|
271
|
+
|
272
|
+
else if prev_node.hasClass("graf")
|
273
|
+
n = current_node.prev(".graf")
|
274
|
+
num = n[0].childNodes.length
|
275
|
+
#@editor.scrollTo(n)
|
276
|
+
utils.log "4 up"
|
277
|
+
@editor.skip_keyup = true
|
278
|
+
@editor.markAsSelected(prev_node)
|
279
|
+
# @editor.continue = false
|
280
|
+
return false
|
281
|
+
|
282
|
+
|
283
|
+
#handle arrow direction from keyUp.
|
284
|
+
handleArrowForKeyUp: (ev)=>
|
285
|
+
current_node = $(@editor.editor.getNode())
|
286
|
+
if current_node.length > 0
|
287
|
+
@editor.markAsSelected( current_node )
|
288
|
+
@editor.displayTooltipAt( current_node )
|
@@ -0,0 +1,64 @@
|
|
1
|
+
utils = Dante.utils
|
2
|
+
|
3
|
+
class Dante.View.Behavior.Paste extends Dante.View.Behavior
|
4
|
+
|
5
|
+
#events:
|
6
|
+
# "paste" : "handlePaste"
|
7
|
+
|
8
|
+
initialize: (opts={})->
|
9
|
+
@editor = opts.current_editor
|
10
|
+
|
11
|
+
#detects html data , creates a hidden node to paste ,
|
12
|
+
#then clean up the content and copies to currentNode, very clever uh?
|
13
|
+
handlePaste: (ev, parent)=>
|
14
|
+
|
15
|
+
utils.log("pasted!")
|
16
|
+
|
17
|
+
pastedText = undefined
|
18
|
+
if (window.clipboardData && window.clipboardData.getData) #IE
|
19
|
+
pastedText = window.clipboardData.getData('Text')
|
20
|
+
else if (ev.originalEvent.clipboardData && ev.originalEvent.clipboardData.getData)
|
21
|
+
cbd = ev.originalEvent.clipboardData
|
22
|
+
pastedText = if _.isEmpty(cbd.getData('text/html')) then cbd.getData('text/plain') else cbd.getData('text/html')
|
23
|
+
|
24
|
+
utils.log("Process and handle text...")
|
25
|
+
#detect if is html
|
26
|
+
if pastedText.match(/<\/*[a-z][^>]+?>/gi)
|
27
|
+
utils.log("HTML DETECTED ON PASTE")
|
28
|
+
pastedText = pastedText.replace(/&.*;/g, "")
|
29
|
+
|
30
|
+
#convert pasted divs in p before copy contents into div
|
31
|
+
pastedText = pastedText.replace(/<div>([\w\W]*?)<\/div>/gi, '<p>$1</p>')
|
32
|
+
|
33
|
+
#create the placeholder element and assign pasted content
|
34
|
+
document.body.appendChild( $("<div id='#{@editor.paste_element_id.replace('#', '')}' class='dante-paste'></div>")[0] )
|
35
|
+
|
36
|
+
$(@editor.paste_element_id).html("<span>#{pastedText}</span>")
|
37
|
+
|
38
|
+
#clean pasted content
|
39
|
+
@editor.setupElementsClasses $(@editor.paste_element_id), (e)=>
|
40
|
+
# e is the target object which is cleaned
|
41
|
+
nodes = $(e.html()).insertAfter($(parent))
|
42
|
+
#remove paste div since we wont use it until the next paste
|
43
|
+
e.remove()
|
44
|
+
#set caret on newly created node
|
45
|
+
last_node = nodes.last()[0]
|
46
|
+
num = last_node.childNodes.length
|
47
|
+
@editor.setRangeAt(last_node, num)
|
48
|
+
|
49
|
+
#select new node
|
50
|
+
new_node = $(@editor.getNode())
|
51
|
+
@editor.markAsSelected(new_node)
|
52
|
+
@editor.displayTooltipAt($(@editor.el).find(".is-selected"))
|
53
|
+
|
54
|
+
# wrap new images
|
55
|
+
@editor.handleUnwrappedImages(nodes)
|
56
|
+
|
57
|
+
#scroll to element top
|
58
|
+
top = new_node.offset().top
|
59
|
+
$('html, body').animate
|
60
|
+
scrollTop: top
|
61
|
+
, 20
|
62
|
+
|
63
|
+
@editor.continue = false
|
64
|
+
return false # Prevent the default handler from running.
|
@@ -38,6 +38,8 @@ class Dante.Editor extends Dante.View
|
|
38
38
|
|
39
39
|
@upload_url = opts.upload_url || "/uploads.json"
|
40
40
|
@upload_callback = opts.upload_callback
|
41
|
+
@image_delete_callback = opts.image_delete_callback
|
42
|
+
|
41
43
|
@oembed_url = opts.oembed_url || "http://api.embed.ly/1/oembed?key=#{opts.api_key}&url="
|
42
44
|
@extract_url = opts.extract_url || "http://api.embed.ly/1/extract?key=#{opts.api_key}&url="
|
43
45
|
@default_loading_placeholder = opts.default_loading_placeholder || Dante.defaults.image_placeholder
|
@@ -60,7 +62,7 @@ class Dante.Editor extends Dante.View
|
|
60
62
|
@suggest_resource_handler = opts.suggest_resource_handler || null
|
61
63
|
|
62
64
|
opts.base_widgets ||= ["uploader", "embed", "embed_extract"]
|
63
|
-
opts.base_behaviors ||= ["save", "image","list", "suggest"]
|
65
|
+
opts.base_behaviors ||= ["save", "image", "paste", "list", "suggest"]
|
64
66
|
|
65
67
|
@widgets = []
|
66
68
|
@behaviors = []
|
@@ -94,13 +96,17 @@ class Dante.Editor extends Dante.View
|
|
94
96
|
@save_behavior = new Dante.View.Behavior.Save(current_editor: @, el: @el)
|
95
97
|
@behaviors.push @save_behavior
|
96
98
|
|
99
|
+
if base_behaviors.indexOf("paste") >= 0
|
100
|
+
@paste_behavior = new Dante.View.Behavior.Paste(current_editor: @, el: @el)
|
101
|
+
@behaviors.push @paste_behavior
|
102
|
+
|
97
103
|
if base_behaviors.indexOf("image") >= 0
|
98
|
-
@
|
99
|
-
@behaviors.push @
|
104
|
+
@image_behavior = new Dante.View.Behavior.Image(current_editor: @, el: @el)
|
105
|
+
@behaviors.push @image_behavior
|
100
106
|
|
101
107
|
if base_behaviors.indexOf("list") >= 0
|
102
|
-
@
|
103
|
-
@behaviors.push @
|
108
|
+
@list_behavior = new Dante.View.Behavior.List(current_editor: @, el: @el)
|
109
|
+
@behaviors.push @list_behavior
|
104
110
|
|
105
111
|
#add extra behaviors
|
106
112
|
if opts.extra_behaviors
|
@@ -217,6 +223,7 @@ class Dante.Editor extends Dante.View
|
|
217
223
|
|
218
224
|
getSelectionStart: ->
|
219
225
|
node = document.getSelection().anchorNode
|
226
|
+
return if node is null
|
220
227
|
if node.nodeType == 3 then node.parentNode else node
|
221
228
|
|
222
229
|
getRange: () ->
|
@@ -386,111 +393,12 @@ class Dante.Editor extends Dante.View
|
|
386
393
|
, 20
|
387
394
|
|
388
395
|
#handle arrow direction from keyUp.
|
389
|
-
|
396
|
+
handleArrowForKeyUp: (ev)=>
|
390
397
|
current_node = $(@getNode())
|
391
398
|
if current_node.length > 0
|
392
399
|
@markAsSelected( current_node )
|
393
400
|
@displayTooltipAt( current_node )
|
394
401
|
|
395
|
-
#handle arrow direction from keyDown.
|
396
|
-
handleArrowForKeyDown: (ev)=>
|
397
|
-
caret_node = @getNode()
|
398
|
-
current_node = $(caret_node)
|
399
|
-
utils.log(ev)
|
400
|
-
ev_type = ev.originalEvent.key || ev.originalEvent.keyIdentifier
|
401
|
-
|
402
|
-
utils.log("ENTER ARROW for key #{ev_type}")
|
403
|
-
|
404
|
-
#handle keys for image figure
|
405
|
-
switch ev_type
|
406
|
-
|
407
|
-
when "Down"
|
408
|
-
#when graff-image selected but none selection is found
|
409
|
-
if _.isUndefined(current_node) or !current_node.exists()
|
410
|
-
if $(".is-selected").exists()
|
411
|
-
current_node = $(".is-selected")
|
412
|
-
|
413
|
-
next_node = current_node.next()
|
414
|
-
|
415
|
-
utils.log "NEXT NODE IS #{next_node.attr('class')}"
|
416
|
-
utils.log "CURRENT NODE IS #{current_node.attr('class')}"
|
417
|
-
|
418
|
-
return unless $(current_node).hasClass("graf")
|
419
|
-
return unless current_node.hasClass("graf--figure") or $(current_node).editableCaretOnLastLine()
|
420
|
-
|
421
|
-
utils.log "ENTER ARROW PASSED RETURNS"
|
422
|
-
|
423
|
-
#if next element is embed select & focus it
|
424
|
-
if next_node.hasClass("graf--figure") && caret_node
|
425
|
-
n = next_node.find(".imageCaption")
|
426
|
-
@scrollTo(n)
|
427
|
-
utils.log "1 down"
|
428
|
-
utils.log n[0]
|
429
|
-
@skip_keyup = true
|
430
|
-
@selection().removeAllRanges()
|
431
|
-
@markAsSelected(next_node)
|
432
|
-
next_node.addClass("is-mediaFocused is-selected")
|
433
|
-
return false
|
434
|
-
#if current node is embed
|
435
|
-
else if next_node.hasClass("graf--mixtapeEmbed")
|
436
|
-
n = current_node.next(".graf--mixtapeEmbed")
|
437
|
-
num = n[0].childNodes.length
|
438
|
-
@setRangeAt n[0], num
|
439
|
-
@scrollTo(n)
|
440
|
-
utils.log "2 down"
|
441
|
-
return false
|
442
|
-
|
443
|
-
if current_node.hasClass("graf--figure") && next_node.hasClass("graf")
|
444
|
-
@scrollTo(next_node)
|
445
|
-
utils.log "3 down, from figure to next graf"
|
446
|
-
#@skip_keyup = true
|
447
|
-
@markAsSelected(next_node)
|
448
|
-
@setRangeAt next_node[0]
|
449
|
-
return false
|
450
|
-
|
451
|
-
when "Up"
|
452
|
-
prev_node = current_node.prev()
|
453
|
-
utils.log "PREV NODE IS #{prev_node.attr('class')} #{prev_node.attr('name')}"
|
454
|
-
utils.log "CURRENT NODE IS up #{current_node.attr('class')}"
|
455
|
-
|
456
|
-
return unless $(current_node).hasClass("graf")
|
457
|
-
return unless $(current_node).editableCaretOnFirstLine()
|
458
|
-
|
459
|
-
utils.log "ENTER ARROW PASSED RETURNS"
|
460
|
-
|
461
|
-
if prev_node.hasClass("graf--figure")
|
462
|
-
utils.log "1 up"
|
463
|
-
n = prev_node.find(".imageCaption")
|
464
|
-
@scrollTo(n)
|
465
|
-
@skip_keyup = true
|
466
|
-
@selection().removeAllRanges()
|
467
|
-
@markAsSelected(prev_node)
|
468
|
-
prev_node.addClass("is-mediaFocused")
|
469
|
-
return false
|
470
|
-
|
471
|
-
else if prev_node.hasClass("graf--mixtapeEmbed")
|
472
|
-
n = current_node.prev(".graf--mixtapeEmbed")
|
473
|
-
num = n[0].childNodes.length
|
474
|
-
@setRangeAt n[0], num
|
475
|
-
@scrollTo(n)
|
476
|
-
utils.log "2 up"
|
477
|
-
return false
|
478
|
-
|
479
|
-
if current_node.hasClass("graf--figure") && prev_node.hasClass("graf")
|
480
|
-
@setRangeAt prev_node[0]
|
481
|
-
@scrollTo(prev_node)
|
482
|
-
utils.log "3 up"
|
483
|
-
return false
|
484
|
-
|
485
|
-
else if prev_node.hasClass("graf")
|
486
|
-
n = current_node.prev(".graf")
|
487
|
-
num = n[0].childNodes.length
|
488
|
-
@scrollTo(n)
|
489
|
-
utils.log "4 up"
|
490
|
-
@skip_keyup = true
|
491
|
-
@markAsSelected(prev_node)
|
492
|
-
return false
|
493
|
-
|
494
402
|
#parse text for initial mess
|
495
403
|
parseInitialMess: ()->
|
496
404
|
@setupElementsClasses $(@el).find('.section-inner') , (e)=>
|
@@ -505,56 +413,17 @@ class Dante.Editor extends Dante.View
|
|
505
413
|
|
506
414
|
#detects html data , creates a hidden node to paste ,
|
507
415
|
#then clean up the content and copies to currentNode, very clever uh?
|
508
|
-
handlePaste: (
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
if (window.clipboardData && window.clipboardData.getData) #IE
|
514
|
-
pastedText = window.clipboardData.getData('Text')
|
515
|
-
else if (ev.originalEvent.clipboardData && ev.originalEvent.clipboardData.getData)
|
516
|
-
cbd = ev.originalEvent.clipboardData
|
517
|
-
pastedText = if _.isEmpty(cbd.getData('text/html')) then cbd.getData('text/plain') else cbd.getData('text/html')
|
518
|
-
|
519
|
-
utils.log("Process and handle text...")
|
520
|
-
#detect if is html
|
521
|
-
if pastedText.match(/<\/*[a-z][^>]+?>/gi)
|
522
|
-
utils.log("HTML DETECTED ON PASTE")
|
523
|
-
pastedText = pastedText.replace(/&.*;/g, "")
|
524
|
-
|
525
|
-
#convert pasted divs in p before copy contents into div
|
526
|
-
pastedText = pastedText.replace(/<div>([\w\W]*?)<\/div>/gi, '<p>$1</p>')
|
527
|
-
|
528
|
-
#create the placeholder element and assign pasted content
|
529
|
-
document.body.appendChild( $("<div id='#{@paste_element_id.replace('#', '')}' class='dante-paste'></div>")[0] )
|
530
|
-
$(@paste_element_id).html("<span>#{pastedText}</span>")
|
531
|
-
|
532
|
-
#clean pasted content
|
533
|
-
|
534
|
-
@setupElementsClasses $(@paste_element_id), (e)=>
|
535
|
-
# e is the target object which is cleaned
|
536
|
-
nodes = $(e.html()).insertAfter($(@aa))
|
537
|
-
#remove paste div since we wont use it until the next paste
|
538
|
-
e.remove()
|
539
|
-
#set caret on newly created node
|
540
|
-
last_node = nodes.last()[0]
|
541
|
-
num = last_node.childNodes.length
|
542
|
-
@setRangeAt(last_node, num)
|
543
|
-
#select new node
|
544
|
-
new_node = $(@getNode())
|
545
|
-
@markAsSelected(new_node)
|
546
|
-
@displayTooltipAt($(@el).find(".is-selected"))
|
547
|
-
|
548
|
-
@handleUnwrappedImages(nodes)
|
549
|
-
|
550
|
-
#scroll to element top
|
551
|
-
top = new_node.offset().top
|
552
|
-
$('html, body').animate
|
553
|
-
scrollTop: top
|
554
|
-
, 20
|
416
|
+
handlePaste: (e)=>
|
417
|
+
@continue = true
|
418
|
+
#handle paste for each widget
|
419
|
+
utils.log("HANDLING PASTE");
|
420
|
+
parent = @getNode()
|
555
421
|
|
422
|
+
_.each @behaviors, (b)=>
|
423
|
+
if b.handlePaste
|
424
|
+
b.handlePaste(e, parent);
|
556
425
|
|
557
|
-
|
426
|
+
return false unless @continue
|
558
427
|
|
559
428
|
handleUnwrappedImages: (elements)->
|
560
429
|
# http://stackoverflow.com/questions/4998908/convert-data-uri-to-file-then-append-to-formdata
|
@@ -658,6 +527,8 @@ class Dante.Editor extends Dante.View
|
|
658
527
|
handleKeyDown: (e)->
|
659
528
|
utils.log "KEYDOWN"
|
660
529
|
|
530
|
+
@continue = true
|
531
|
+
|
661
532
|
anchor_node = @getNode() #current node on which cursor is positioned
|
662
533
|
parent = $(anchor_node)
|
663
534
|
|
@@ -670,6 +541,8 @@ class Dante.Editor extends Dante.View
|
|
670
541
|
if b.handleKeyDown
|
671
542
|
b.handleKeyDown(e, parent);
|
672
543
|
|
544
|
+
return false unless @continue
|
545
|
+
|
673
546
|
if e.which is TAB
|
674
547
|
@handleTab(anchor_node)
|
675
548
|
return false
|
@@ -682,7 +555,7 @@ class Dante.Editor extends Dante.View
|
|
682
555
|
utils.log @isLastChar()
|
683
556
|
|
684
557
|
#handle keydowns for each widget
|
685
|
-
utils.log("HANDLING WIDGET
|
558
|
+
utils.log("HANDLING WIDGET ENTER");
|
686
559
|
_.each @widgets, (w)=>
|
687
560
|
if w.handleEnterKey
|
688
561
|
w.handleEnterKey(e, parent);
|
@@ -761,11 +634,11 @@ class Dante.Editor extends Dante.View
|
|
761
634
|
return false;
|
762
635
|
|
763
636
|
#select an image if backspacing into it from a paragraph
|
764
|
-
if($(anchor_node).hasClass("graf--p") && @isFirstChar() )
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
637
|
+
#if($(anchor_node).hasClass("graf--p") && @isFirstChar() )
|
638
|
+
# if($(anchor_node).prev().hasClass("graf--figure") && @getSelectedText().length == 0)
|
639
|
+
# e.preventDefault();
|
640
|
+
# $(anchor_node).prev().find("img").click();
|
641
|
+
# utils.log("Focus on the previous image");
|
769
642
|
|
770
643
|
if $(utils_anchor_node).hasClass("section-content") || $(utils_anchor_node).hasClass("graf--first")
|
771
644
|
utils.log "SECTION DETECTED FROM KEYDOWN #{_.isEmpty($(utils_anchor_node).text())}"
|
@@ -775,41 +648,17 @@ class Dante.Editor extends Dante.View
|
|
775
648
|
# @displayEmptyPlaceholder()
|
776
649
|
utils.log("TextNode detected from Down!")
|
777
650
|
#return false
|
778
|
-
|
779
|
-
# supress del into & delete embed if empty content found on delete key
|
780
|
-
if $(anchor_node).hasClass("graf--mixtapeEmbed") or $(anchor_node).hasClass("graf--iframe")
|
781
|
-
if _.isEmpty $(anchor_node).text().trim() or @isFirstChar()
|
782
|
-
utils.log("Check for inmediate deletion on empty embed text")
|
783
|
-
@inmediateDeletion = @isSelectingAll(anchor_node)
|
784
|
-
@handleInmediateDeletion($(anchor_node)) if @inmediateDeletion
|
785
|
-
return false
|
786
|
-
|
787
|
-
# TODO: supress del when the prev el is embed and current_node is at first char
|
788
|
-
if $(anchor_node).prev().hasClass("graf--mixtapeEmbed")
|
789
|
-
return false if @isFirstChar() && !_.isEmpty( $(anchor_node).text().trim() )
|
790
|
-
|
791
|
-
#arrows key
|
792
|
-
#up & down
|
793
|
-
if _.contains([UPARROW, DOWNARROW], e.which)
|
794
|
-
utils.log e.which
|
795
|
-
@handleArrowForKeyDown(e)
|
796
|
-
#return false
|
797
|
-
|
651
|
+
|
798
652
|
#hides tooltip if anchor_node text is empty
|
799
653
|
if anchor_node
|
800
654
|
unless _.isEmpty($(anchor_node).text())
|
801
655
|
@tooltip_view.hide()
|
802
656
|
$(anchor_node).removeClass("graf--empty")
|
803
657
|
|
804
|
-
#when user types over a selected image (graf--figure)
|
805
|
-
#unselect image , and set range on caption
|
806
|
-
if _.isUndefined(anchor_node) && $(".is-selected").hasClass("is-mediaFocused")
|
807
|
-
@setRangeAt $(".is-selected").find("figcaption")[0]
|
808
|
-
$(".is-selected").removeClass("is-mediaFocused")
|
809
|
-
return false
|
810
|
-
|
811
658
|
handleKeyUp: (e , node)->
|
812
659
|
|
660
|
+
@continue = true
|
661
|
+
|
813
662
|
if @skip_keyup
|
814
663
|
@skip_keyup = null
|
815
664
|
utils.log "SKIP KEYUP"
|
@@ -830,6 +679,8 @@ class Dante.Editor extends Dante.View
|
|
830
679
|
if b.handleKeyUp
|
831
680
|
b.handleKeyUp(e)
|
832
681
|
|
682
|
+
return false unless @continue
|
683
|
+
|
833
684
|
if (e.which == BACKSPACE)
|
834
685
|
|
835
686
|
#if detect all text deleted , re render
|
@@ -872,7 +723,7 @@ class Dante.Editor extends Dante.View
|
|
872
723
|
|
873
724
|
#arrows key
|
874
725
|
if _.contains([LEFTARROW, UPARROW, RIGHTARROW, DOWNARROW], e.which)
|
875
|
-
@
|
726
|
+
@handleArrowForKeyUp(e)
|
876
727
|
#return false
|
877
728
|
|
878
729
|
handleKeyPress: (e, node)->
|
@@ -915,13 +766,15 @@ class Dante.Editor extends Dante.View
|
|
915
766
|
|
916
767
|
#mark the current row as selected
|
917
768
|
markAsSelected: (element)->
|
918
|
-
utils.log
|
769
|
+
utils.log "MARK AS SELECTED"
|
770
|
+
|
919
771
|
return if _.isUndefined element
|
920
772
|
|
921
773
|
$(@el).find(".is-selected").removeClass("is-mediaFocused is-selected")
|
774
|
+
|
922
775
|
$(element).addClass("is-selected")
|
923
776
|
|
924
|
-
|
777
|
+
#$(element).find(".defaultValue").remove()
|
925
778
|
#set reached top if element is first!
|
926
779
|
if $(element).hasClass("graf--first")
|
927
780
|
@reachedTop = true
|
@@ -997,7 +850,7 @@ class Dante.Editor extends Dante.View
|
|
997
850
|
@cleanContents(element)
|
998
851
|
@wrapTextNodes(element)
|
999
852
|
#setup classes
|
1000
|
-
_.each
|
853
|
+
_.each element.children(), (n)=>
|
1001
854
|
name = $(n).prop("tagName").toLowerCase()
|
1002
855
|
n = @addClassesToElement(n)
|
1003
856
|
@setElementName(n)
|
@@ -1114,7 +967,7 @@ class Dante.Editor extends Dante.View
|
|
1114
967
|
|
1115
968
|
setupFirstAndLast: ()=>
|
1116
969
|
childs = $(@el).find(".section-inner").children()
|
1117
|
-
childs.removeClass("graf--last
|
970
|
+
childs.removeClass("graf--last, graf--first")
|
1118
971
|
childs.first().addClass("graf--first")
|
1119
972
|
childs.last().addClass("graf--last")
|
1120
973
|
|