dante-editor 0.1.6 → 0.1.7
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 +6 -0
- data/app/assets/javascripts/dante.js +7 -6
- data/app/assets/javascripts/dante/article.js.coffee +56 -0
- data/app/assets/javascripts/dante/behaviors/image.js.coffee +9 -9
- data/app/assets/javascripts/dante/behaviors/list.js.coffee +2 -2
- data/app/assets/javascripts/dante/behaviors/paste.js.coffee +3 -0
- data/app/assets/javascripts/dante/dante.js.coffee.erb +2 -0
- data/app/assets/javascripts/dante/editor.js.coffee +71 -40
- data/app/assets/javascripts/dante/popovers/anchor.js.coffee +82 -0
- data/app/assets/javascripts/dante/popovers/card.js.coffee +103 -0
- data/app/assets/javascripts/dante/popovers/image.js.coffee +112 -0
- data/app/assets/javascripts/dante/popovers/typeahead.js.coffee +125 -0
- data/app/assets/javascripts/dante/tooltip_widgets/embed.js.coffee +3 -3
- data/app/assets/javascripts/dante/tooltip_widgets/extract.js.coffee +12 -3
- data/app/assets/javascripts/dante/tooltip_widgets/uploader.js.coffee +1 -1
- data/bower.json +1 -1
- data/dist/js/dante-editor.js +608 -455
- data/lib/dante-editor/version.rb +1 -1
- data/source/non_editable.erb +45 -0
- data/source/partials/_existing_content.erb +35 -0
- metadata +9 -3
- data/app/assets/javascripts/dante/popover.js.coffee +0 -424
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e5f8c0fc81095096da19c3e387d79bedab7a3ec3
|
4
|
+
data.tar.gz: f11b2bc0404231a18de30c42b59169ae674db5af
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 61923bfbcb46e98d3314997362b4f13a3041a60e34b8dc97b4ab4c91c8f436a7a7e1c76c751fa3d55148cfe30746c6fd4be68fa7d5479a73f89145ebe03169a4
|
7
|
+
data.tar.gz: 3bca3b2e85212118e3f6dcb114fa7ed75cca273cc58d75f9cdd1f7843837dd507a69446e679792d696340796071b022e82ba8bfeab6535813f824f473984bc56
|
data/README.md
CHANGED
@@ -92,13 +92,19 @@ Until now I´ve been able to implement the following features:
|
|
92
92
|
+ **store_interval:** default: 1500 (1.5 secs), used when store_url is present.
|
93
93
|
|
94
94
|
#### Uploader:
|
95
|
+
|
95
96
|
+ **upload_url:** default: /uploads.json
|
96
97
|
+ **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
98
|
+ **image_delete_callback**: default: none, returns the image data before deletion. use this if you want to destroy image from the server.
|
99
|
+
+ **image_caption_placeholder** default: "Type caption for image (optional)"
|
100
|
+
|
101
|
+
|
98
102
|
#### Embed tool:
|
103
|
+
|
99
104
|
+ **oembed_url:** default: http://api.embed.ly/1/oembed?url="
|
100
105
|
+ **extract_url:** default: http://api.embed.ly/1/extract?url="
|
101
106
|
+ **embed_placeholder** default: 'Paste a YouTube, Vine, Vimeo, or other video link, and press Enter'
|
107
|
+
+ **embed_caption_placeholder** default: "Type caption for embed (optional)"
|
102
108
|
+ **extract_placeholder** default: 'Paste a link to embed content from another site (e.g. Twitter) and press Enter'
|
103
109
|
|
104
110
|
#### Suggest Behavior (new!)
|
@@ -3,16 +3,17 @@
|
|
3
3
|
//= require dante/utils
|
4
4
|
//= require dante/view
|
5
5
|
//= require dante/editor
|
6
|
+
|
7
|
+
//= require dante/article
|
8
|
+
|
6
9
|
//= require dante/behavior
|
7
|
-
//=
|
8
|
-
|
9
|
-
//= require dante/behaviors/image
|
10
|
-
//= require dante/behaviors/list
|
11
|
-
//= require dante/behaviors/save
|
10
|
+
//= require_tree ./dante/behaviors
|
11
|
+
|
12
12
|
//= require dante/tooltip_widget
|
13
13
|
//= require dante/tooltip_widgets/uploader
|
14
14
|
//= require dante/tooltip_widgets/embed
|
15
15
|
//= require dante/tooltip_widgets/extract
|
16
16
|
//= require dante/tooltip
|
17
|
-
|
17
|
+
|
18
|
+
//= require_tree ./dante/popovers
|
18
19
|
//= require dante/menu
|
@@ -0,0 +1,56 @@
|
|
1
|
+
class Dante.Article extends Dante.View
|
2
|
+
|
3
|
+
el: "body"
|
4
|
+
|
5
|
+
events:
|
6
|
+
# TODO: this events should be in tooltip class
|
7
|
+
"mouseover .markup--anchor" : "displayPopOver"
|
8
|
+
"mouseout .markup--anchor" : "hidePopOver"
|
9
|
+
|
10
|
+
initialize: (opts={})->
|
11
|
+
@options = opts
|
12
|
+
@popovers = []
|
13
|
+
opts.base_popovers ||= ["anchor", "card"]
|
14
|
+
|
15
|
+
start: ()=>
|
16
|
+
@render()
|
17
|
+
@appendMenus()
|
18
|
+
|
19
|
+
appendMenus: ->
|
20
|
+
@intializePopOvers(@options)
|
21
|
+
@removeEditables()
|
22
|
+
|
23
|
+
render: ->
|
24
|
+
|
25
|
+
removeEditables: ->
|
26
|
+
$(@el).find("[contenteditable]").removeAttr("contenteditable")
|
27
|
+
|
28
|
+
intializePopOvers: (opts)->
|
29
|
+
|
30
|
+
base_popovers = opts.base_popovers
|
31
|
+
self = @
|
32
|
+
|
33
|
+
if base_popovers.indexOf("anchor") >= 0
|
34
|
+
@pop_over = new Dante.Editor.PopOver(editor: @)
|
35
|
+
@popovers.push @pop_over
|
36
|
+
|
37
|
+
if base_popovers.indexOf("card") >= 0
|
38
|
+
@pop_over_card = new Dante.Editor.PopOverCard(editor: @)
|
39
|
+
@popovers.push @pop_over_card
|
40
|
+
|
41
|
+
# add extra widgets
|
42
|
+
if opts.extra_popovers
|
43
|
+
_.each opts.extra_popovers, (w)=>
|
44
|
+
if !w.current_editor
|
45
|
+
w.current_editor = self
|
46
|
+
@popovers.push w
|
47
|
+
|
48
|
+
# render and hide
|
49
|
+
@popovers.forEach (p)->
|
50
|
+
p.render().hide()
|
51
|
+
|
52
|
+
displayPopOver: (ev)->
|
53
|
+
@pop_over.displayAt(ev)
|
54
|
+
|
55
|
+
hidePopOver: (ev)->
|
56
|
+
@pop_over.hide(ev)
|
@@ -85,11 +85,11 @@ class Dante.View.Behavior.Image extends Dante.View.Behavior
|
|
85
85
|
|
86
86
|
# call callback for image delete
|
87
87
|
if @editor.image_delete_callback
|
88
|
-
@editor.image_delete_callback(
|
88
|
+
@editor.image_delete_callback( @editor.findSelected().find("img").data() )
|
89
89
|
|
90
90
|
utils.log("Replacing selected node")
|
91
|
-
@editor.replaceWith("p",
|
92
|
-
@editor.setRangeAt(
|
91
|
+
@editor.replaceWith("p", @editor.findSelected())
|
92
|
+
@editor.setRangeAt(@editor.findSelected()[0])
|
93
93
|
@editor.pop_over_align.hide()
|
94
94
|
utils.log("Focus on the previous graf")
|
95
95
|
@editor.continue = false
|
@@ -123,13 +123,13 @@ class Dante.View.Behavior.Image extends Dante.View.Behavior
|
|
123
123
|
|
124
124
|
# when user types over a selected image (graf--figure)
|
125
125
|
# unselect image , and set range on caption
|
126
|
-
if _.isUndefined(parent) or parent.length is 0 &&
|
126
|
+
if _.isUndefined(parent) or parent.length is 0 && @editor.findSelected().hasClass("is-mediaFocused")
|
127
127
|
# will remove default value on typing
|
128
|
-
node =
|
128
|
+
node = @editor.findSelected().find("figcaption")
|
129
129
|
node.find(".defaultValue").remove()
|
130
130
|
|
131
131
|
@editor.setRangeAt node[0]
|
132
|
-
|
132
|
+
@editor.findSelected().removeClass("is-mediaFocused")
|
133
133
|
@editor.pop_over_align.hide()
|
134
134
|
#@editor.continue = false
|
135
135
|
return false
|
@@ -153,8 +153,8 @@ class Dante.View.Behavior.Image extends Dante.View.Behavior
|
|
153
153
|
when "ArrowDown", "Down"
|
154
154
|
# when graff-image selected but none selection is found
|
155
155
|
if _.isUndefined(current_node) or !current_node.exists()
|
156
|
-
if
|
157
|
-
current_node =
|
156
|
+
if @editor.findSelected().exists()
|
157
|
+
current_node = @editor.findSelected()
|
158
158
|
|
159
159
|
next_node = current_node.next()
|
160
160
|
|
@@ -274,7 +274,7 @@ class Dante.View.Behavior.Image extends Dante.View.Behavior
|
|
274
274
|
num = n[0].childNodes.length
|
275
275
|
#@editor.scrollTo(n)
|
276
276
|
utils.log "4 up"
|
277
|
-
@editor.skip_keyup = true
|
277
|
+
# @editor.skip_keyup = true
|
278
278
|
@editor.markAsSelected(prev_node)
|
279
279
|
# @editor.continue = false
|
280
280
|
return false
|
@@ -60,7 +60,7 @@ class Dante.View.Behavior.List extends Dante.View.Behavior
|
|
60
60
|
|
61
61
|
@editor.addClassesToElement($list[0])
|
62
62
|
@editor.replaceWith("li", $paragraph)
|
63
|
-
$li =
|
63
|
+
$li = @editor.findSelected()
|
64
64
|
|
65
65
|
@editor.setElementName($li[0])
|
66
66
|
|
@@ -141,7 +141,7 @@ class Dante.View.Behavior.List extends Dante.View.Behavior
|
|
141
141
|
$list.before($li)
|
142
142
|
content = $li.html()
|
143
143
|
@editor.replaceWith("p", $li)
|
144
|
-
$paragraph =
|
144
|
+
$paragraph = @editor.findSelected()
|
145
145
|
$paragraph.removeClass("graf--empty").html(content).attr("name", utils.generateUniqueName());
|
146
146
|
|
147
147
|
if($list.children().length is 0)
|
@@ -13,6 +13,9 @@ class Dante.View.Behavior.Paste extends Dante.View.Behavior
|
|
13
13
|
handlePaste: (ev, parent)=>
|
14
14
|
|
15
15
|
utils.log("pasted!")
|
16
|
+
|
17
|
+
# hide default value if it's any
|
18
|
+
@editor.hidePlaceholder($(parent))
|
16
19
|
|
17
20
|
pastedText = undefined
|
18
21
|
if (window.clipboardData && window.clipboardData.getData) #IE
|
@@ -39,11 +39,13 @@ class Dante.Editor extends Dante.View
|
|
39
39
|
@upload_url = opts.upload_url || "/uploads.json"
|
40
40
|
@upload_callback = opts.upload_callback
|
41
41
|
@image_delete_callback = opts.image_delete_callback
|
42
|
+
@image_caption_placeholder = opts.image_caption_placeholder || "Type caption for image (optional)"
|
42
43
|
|
43
44
|
@oembed_url = opts.oembed_url || "http://api.embed.ly/1/oembed?key=#{opts.api_key}&url="
|
44
45
|
@extract_url = opts.extract_url || "http://api.embed.ly/1/extract?key=#{opts.api_key}&url="
|
45
46
|
@default_loading_placeholder = opts.default_loading_placeholder || Dante.defaults.image_placeholder
|
46
|
-
|
47
|
+
@embed_caption_placeholder = opts.embed_caption_placeholder || "Type caption for embed (optional)"
|
48
|
+
|
47
49
|
@store_url = opts.store_url
|
48
50
|
@store_method = opts.store_method || "POST"
|
49
51
|
@store_success_handler = opts.store_success_handler
|
@@ -63,9 +65,11 @@ class Dante.Editor extends Dante.View
|
|
63
65
|
|
64
66
|
opts.base_widgets ||= ["uploader", "embed", "embed_extract"]
|
65
67
|
opts.base_behaviors ||= ["save", "image", "paste", "list", "suggest"]
|
68
|
+
opts.base_popovers ||= ["anchor", "typeahead", "card", "align"]
|
66
69
|
|
67
70
|
@widgets = []
|
68
71
|
@behaviors = []
|
72
|
+
@popovers = []
|
69
73
|
|
70
74
|
window.debugMode = opts.debug || false
|
71
75
|
|
@@ -73,8 +77,7 @@ class Dante.Editor extends Dante.View
|
|
73
77
|
|
74
78
|
titleplaceholder = opts.title_placeholder || 'Title'
|
75
79
|
@title_placeholder = "<span class='defaultValue defaultValue--root'>#{titleplaceholder}</span><br>"
|
76
|
-
title
|
77
|
-
@title = title
|
80
|
+
@title = opts.title || ''
|
78
81
|
bodyplaceholder = opts.body_placeholder || 'Tell your story…'
|
79
82
|
@body_placeholder = "<span class='defaultValue defaultValue--root'>#{bodyplaceholder}</span><br>"
|
80
83
|
embedplaceholder = opts.embed_placeholder || 'Paste a YouTube, Vine, Vimeo, or other video link, and press Enter'
|
@@ -108,7 +111,7 @@ class Dante.Editor extends Dante.View
|
|
108
111
|
@list_behavior = new Dante.View.Behavior.List(current_editor: @, el: @el)
|
109
112
|
@behaviors.push @list_behavior
|
110
113
|
|
111
|
-
#add extra behaviors
|
114
|
+
# add extra behaviors
|
112
115
|
if opts.extra_behaviors
|
113
116
|
_.each opts.extra_behaviors, (w)=>
|
114
117
|
if !w.current_editor
|
@@ -116,8 +119,8 @@ class Dante.Editor extends Dante.View
|
|
116
119
|
@behaviors.push w
|
117
120
|
|
118
121
|
initializeWidgets: (opts)->
|
119
|
-
#TODO: this could be a hash to access widgets without var
|
120
|
-
#Base widgets
|
122
|
+
# TODO: this could be a hash to access widgets without var
|
123
|
+
# Base widgets
|
121
124
|
base_widgets = opts.base_widgets
|
122
125
|
self = @
|
123
126
|
|
@@ -133,13 +136,45 @@ class Dante.Editor extends Dante.View
|
|
133
136
|
@embed_extract_widget = new Dante.View.TooltipWidget.EmbedExtract(current_editor: @)
|
134
137
|
@widgets.push @embed_extract_widget
|
135
138
|
|
136
|
-
#add extra widgets
|
139
|
+
# add extra widgets
|
137
140
|
if opts.extra_tooltip_widgets
|
138
141
|
_.each opts.extra_tooltip_widgets, (w)=>
|
139
142
|
if !w.current_editor
|
140
143
|
w.current_editor = self
|
141
144
|
@widgets.push w
|
142
145
|
|
146
|
+
intializePopOvers: (opts)->
|
147
|
+
|
148
|
+
base_popovers = opts.base_popovers
|
149
|
+
self = @
|
150
|
+
|
151
|
+
if base_popovers.indexOf("anchor") >= 0
|
152
|
+
@pop_over = new Dante.Editor.PopOver(editor: @)
|
153
|
+
@pop_over.render().hide()
|
154
|
+
|
155
|
+
if base_popovers.indexOf("typeahead") >= 0
|
156
|
+
@pop_over_typeahead = new Dante.Editor.PopOverTypeAhead(editor: @)
|
157
|
+
@popovers.push @pop_over_typeahead
|
158
|
+
|
159
|
+
if base_popovers.indexOf("card") >= 0
|
160
|
+
@pop_over_card = new Dante.Editor.PopOverCard(editor: @)
|
161
|
+
@popovers.push @pop_over_card
|
162
|
+
|
163
|
+
if base_popovers.indexOf("align") >= 0
|
164
|
+
@pop_over_align = new Dante.Editor.ImageTooltip(editor: @)
|
165
|
+
@popovers.push @pop_over_align
|
166
|
+
|
167
|
+
# add extra widgets
|
168
|
+
if opts.extra_popovers
|
169
|
+
_.each opts.extra_popovers, (w)=>
|
170
|
+
if !w.current_editor
|
171
|
+
w.current_editor = self
|
172
|
+
@popovers.push w
|
173
|
+
|
174
|
+
# render and hide
|
175
|
+
@popovers.forEach (p)->
|
176
|
+
p.render().hide()
|
177
|
+
|
143
178
|
getContent: ()->
|
144
179
|
$(@el).find(".section-inner").html()
|
145
180
|
|
@@ -170,18 +205,8 @@ class Dante.Editor extends Dante.View
|
|
170
205
|
$("<div class='inlineTooltip'></div>").insertAfter(@el)
|
171
206
|
@editor_menu = new Dante.Editor.Menu(editor: @)
|
172
207
|
@tooltip_view = new @tooltip_class(editor: @ , widgets: @widgets)
|
173
|
-
@pop_over = new Dante.Editor.PopOver(editor: @)
|
174
|
-
@pop_over.render().hide()
|
175
208
|
|
176
|
-
|
177
|
-
@pop_over_typeahead = new Dante.Editor.PopOverTypeAhead(editor: @)
|
178
|
-
@pop_over_typeahead.render().hide()
|
179
|
-
|
180
|
-
@pop_over_card = new Dante.Editor.PopOverCard(editor: @)
|
181
|
-
@pop_over_card.render().hide()
|
182
|
-
|
183
|
-
@pop_over_align = new Dante.Editor.ImageTooltip(editor: @)
|
184
|
-
@pop_over_align.render().hide()
|
209
|
+
@intializePopOvers(@editor_options)
|
185
210
|
|
186
211
|
@tooltip_view.render().hide()
|
187
212
|
|
@@ -488,7 +513,7 @@ class Dante.Editor extends Dante.View
|
|
488
513
|
else if !prev
|
489
514
|
@.setRangeAt(@.$el.find(".section-inner p")[0])
|
490
515
|
|
491
|
-
@displayTooltipAt(
|
516
|
+
@displayTooltipAt(@findSelected())
|
492
517
|
|
493
518
|
#used when all the content is removed, then it re render
|
494
519
|
handleCompleteDeletion: (element)->
|
@@ -525,6 +550,7 @@ class Dante.Editor extends Dante.View
|
|
525
550
|
@scrollTo $(next)
|
526
551
|
|
527
552
|
handleKeyDown: (e)->
|
553
|
+
|
528
554
|
utils.log "KEYDOWN"
|
529
555
|
|
530
556
|
@continue = true
|
@@ -536,12 +562,6 @@ class Dante.Editor extends Dante.View
|
|
536
562
|
|
537
563
|
#handle keyups for each widget
|
538
564
|
utils.log("HANDLING Behavior KEYDOWN");
|
539
|
-
|
540
|
-
_.each @behaviors, (b)=>
|
541
|
-
if b.handleKeyDown
|
542
|
-
b.handleKeyDown(e, parent);
|
543
|
-
|
544
|
-
return false unless @continue
|
545
565
|
|
546
566
|
if e.which is TAB
|
547
567
|
@handleTab(anchor_node)
|
@@ -550,7 +570,7 @@ class Dante.Editor extends Dante.View
|
|
550
570
|
if e.which is ENTER
|
551
571
|
|
552
572
|
#removes previous selected nodes
|
553
|
-
|
573
|
+
@findSelected().removeClass("is-selected")
|
554
574
|
|
555
575
|
utils.log @isLastChar()
|
556
576
|
|
@@ -569,9 +589,9 @@ class Dante.Editor extends Dante.View
|
|
569
589
|
if parent.hasClass("graf--iframe") or parent.hasClass("graf--figure")
|
570
590
|
if @isLastChar()
|
571
591
|
@handleLineBreakWith("p", parent)
|
572
|
-
@setRangeAtText(
|
592
|
+
@setRangeAtText(@findSelected()[0])
|
573
593
|
|
574
|
-
|
594
|
+
@findSelected().trigger("mouseup") #is not making any change
|
575
595
|
return false
|
576
596
|
else
|
577
597
|
return false
|
@@ -603,7 +623,7 @@ class Dante.Editor extends Dante.View
|
|
603
623
|
$(node).append("<br>")
|
604
624
|
|
605
625
|
# shows tooltip
|
606
|
-
@displayTooltipAt(
|
626
|
+
@displayTooltipAt(@findSelected())
|
607
627
|
, 2
|
608
628
|
|
609
629
|
# delete key
|
@@ -651,10 +671,16 @@ class Dante.Editor extends Dante.View
|
|
651
671
|
|
652
672
|
#hides tooltip if anchor_node text is empty
|
653
673
|
if anchor_node
|
654
|
-
|
674
|
+
if !_.isEmpty($(anchor_node).text())
|
655
675
|
@tooltip_view.hide()
|
656
676
|
$(anchor_node).removeClass("graf--empty")
|
657
677
|
|
678
|
+
_.each @behaviors, (b)=>
|
679
|
+
if b.handleKeyDown
|
680
|
+
b.handleKeyDown(e, parent);
|
681
|
+
|
682
|
+
return false unless @continue
|
683
|
+
|
658
684
|
handleKeyUp: (e , node)->
|
659
685
|
|
660
686
|
@continue = true
|
@@ -673,14 +699,6 @@ class Dante.Editor extends Dante.View
|
|
673
699
|
|
674
700
|
@handleTextSelection(anchor_node)
|
675
701
|
|
676
|
-
# handle keyups for each widget
|
677
|
-
utils.log("HANDLING Behavior KEYUPS");
|
678
|
-
_.each @behaviors, (b)=>
|
679
|
-
if b.handleKeyUp
|
680
|
-
b.handleKeyUp(e)
|
681
|
-
|
682
|
-
return false unless @continue
|
683
|
-
|
684
702
|
if (e.which == BACKSPACE)
|
685
703
|
|
686
704
|
#if detect all text deleted , re render
|
@@ -726,10 +744,21 @@ class Dante.Editor extends Dante.View
|
|
726
744
|
@handleArrowForKeyUp(e)
|
727
745
|
#return false
|
728
746
|
|
747
|
+
# handle keyups for each widget
|
748
|
+
utils.log("HANDLING Behavior KEYUPS");
|
749
|
+
_.each @behaviors, (b)=>
|
750
|
+
if b.handleKeyUp
|
751
|
+
b.handleKeyUp(e)
|
752
|
+
|
753
|
+
return false unless @continue
|
754
|
+
|
729
755
|
handleKeyPress: (e, node)->
|
730
756
|
anchor_node = @getNode()
|
731
757
|
parent = $(anchor_node)
|
732
|
-
|
758
|
+
|
759
|
+
@hidePlaceholder(parent)
|
760
|
+
|
761
|
+
# handle keyups for each widget
|
733
762
|
utils.log("HANDLING Behavior KEYPRESS");
|
734
763
|
_.each @behaviors, (b)=>
|
735
764
|
if b.handleKeyPress
|
@@ -770,7 +799,7 @@ class Dante.Editor extends Dante.View
|
|
770
799
|
|
771
800
|
return if _.isUndefined element
|
772
801
|
|
773
|
-
|
802
|
+
@findSelected().removeClass("is-mediaFocused is-selected")
|
774
803
|
|
775
804
|
$(element).addClass("is-selected")
|
776
805
|
|
@@ -990,3 +1019,5 @@ class Dante.Editor extends Dante.View
|
|
990
1019
|
$(span).replaceWith($(span).html()) for span in $spans when not $(span).hasClass("defaultValue")
|
991
1020
|
$item
|
992
1021
|
|
1022
|
+
findSelected: ->
|
1023
|
+
$(@el).find(".is-selected")
|