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
@@ -0,0 +1,82 @@
|
|
1
|
+
utils = Dante.utils
|
2
|
+
|
3
|
+
class Dante.Editor.PopOver extends Dante.View
|
4
|
+
el: "body"
|
5
|
+
|
6
|
+
events:
|
7
|
+
"mouseover .popover--tooltip": "cancelHide"
|
8
|
+
"mouseout .popover--tooltip": "hide"
|
9
|
+
|
10
|
+
initialize: (opts = {})->
|
11
|
+
utils.log("initialized popover")
|
12
|
+
@pop_over_element = ".popover--tooltip"
|
13
|
+
@editor = opts.editor
|
14
|
+
@hideTimeout
|
15
|
+
@settings = {timeout: 300}
|
16
|
+
|
17
|
+
template: ()->
|
18
|
+
"<div class='dante-popover popover--tooltip popover--Linktooltip popover--bottom is-active'>
|
19
|
+
<div class='popover-inner'>
|
20
|
+
<a href='#' target='_blank'> Link </a>
|
21
|
+
</div>
|
22
|
+
<div class='popover-arrow'>
|
23
|
+
</div>
|
24
|
+
</div>"
|
25
|
+
|
26
|
+
#display & copy original link
|
27
|
+
positionAt: (ev)->
|
28
|
+
target = $(ev.currentTarget)
|
29
|
+
wrapperOffset = target.closest('article.postArticle').offset()
|
30
|
+
target_positions = @resolveTargetPosition(target)
|
31
|
+
target_offset = target.offset()
|
32
|
+
target_width = target.outerWidth()
|
33
|
+
target_height = target.outerHeight()
|
34
|
+
popover_width = @findElement().outerWidth()
|
35
|
+
top_value = target_positions.top + target_height
|
36
|
+
left_value = target_offset.left + (target_width/2) - (popover_width/2) - wrapperOffset.left
|
37
|
+
|
38
|
+
@findElement()
|
39
|
+
.css("top", top_value)
|
40
|
+
.css("left", left_value )
|
41
|
+
.show()
|
42
|
+
|
43
|
+
@handleDirection(target)
|
44
|
+
|
45
|
+
displayAt: (ev)->
|
46
|
+
@cancelHide()
|
47
|
+
target = $(ev.currentTarget)
|
48
|
+
@findElement()
|
49
|
+
.find(".popover-inner a")
|
50
|
+
.text( target.attr('href') )
|
51
|
+
.attr('href', target.attr("href") )
|
52
|
+
@positionAt(ev)
|
53
|
+
@findElement().css("pointer-events", "auto")
|
54
|
+
$(@el).show()
|
55
|
+
|
56
|
+
cancelHide: ()->
|
57
|
+
utils.log "Cancel Hide"
|
58
|
+
clearTimeout @hideTimeout
|
59
|
+
|
60
|
+
hide: (ev)->
|
61
|
+
@cancelHide()
|
62
|
+
@hideTimeout = setTimeout ()=>
|
63
|
+
@findElement().hide()
|
64
|
+
, @settings.timeout
|
65
|
+
|
66
|
+
resolveTargetPosition: (target)->
|
67
|
+
if target.parents(".graf--mixtapeEmbed").exists()
|
68
|
+
target.parents(".graf--mixtapeEmbed").position()
|
69
|
+
else
|
70
|
+
target.position()
|
71
|
+
|
72
|
+
handleDirection: (target)->
|
73
|
+
if target.parents(".graf--mixtapeEmbed").exists()
|
74
|
+
@findElement().removeClass("popover--bottom").addClass("popover--top")
|
75
|
+
else
|
76
|
+
@findElement().removeClass("popover--top").addClass("popover--bottom")
|
77
|
+
|
78
|
+
findElement: ()->
|
79
|
+
$(@el).find(@pop_over_element)
|
80
|
+
|
81
|
+
render: ()->
|
82
|
+
$(@template()).insertAfter(@editor.$el)
|
@@ -0,0 +1,103 @@
|
|
1
|
+
utils = Dante.utils
|
2
|
+
|
3
|
+
class Dante.Editor.PopOverCard extends Dante.Editor.PopOver
|
4
|
+
|
5
|
+
el: "body"
|
6
|
+
|
7
|
+
events:
|
8
|
+
"mouseover .popover--card": "cancelHide"
|
9
|
+
"mouseout .popover--card": "hide"
|
10
|
+
"mouseover .markup--user" : "displayPopOver"
|
11
|
+
"mouseout .markup--user" : "hidePopOver"
|
12
|
+
|
13
|
+
initialize: (opts = {})->
|
14
|
+
@pop_over_element = ".popover--card"
|
15
|
+
utils.log("initialized popover")
|
16
|
+
@editor = opts.editor
|
17
|
+
@hideTimeout
|
18
|
+
@settings = {timeout: 300}
|
19
|
+
@card_data = {}
|
20
|
+
|
21
|
+
template: ()->
|
22
|
+
"<div class='dante-popover popover--card js-popover popover--animated popover--flexible popover--top is-active'>
|
23
|
+
<div class='popover-inner js-popover-inner'>
|
24
|
+
</div>
|
25
|
+
</div>"
|
26
|
+
|
27
|
+
cardTemplate: ->
|
28
|
+
"<div class='popoverCard'>
|
29
|
+
<div class='u-clearfix'>
|
30
|
+
|
31
|
+
<div class='u-floatLeft popoverCard-meta'>
|
32
|
+
<h4 class='popoverCard-title'>
|
33
|
+
<a class='link u-baseColor--link'
|
34
|
+
href='#{@card_data.href}'
|
35
|
+
title='#{@card_data.text}'
|
36
|
+
aria-label='#{@card_data.text}'
|
37
|
+
data-user-id='#{@card_data.id}'
|
38
|
+
dir='auto'>
|
39
|
+
#{@card_data.text}
|
40
|
+
</a>
|
41
|
+
</h4>
|
42
|
+
<div class='popoverCard-description'>
|
43
|
+
#{@card_data.description}
|
44
|
+
</div>
|
45
|
+
</div>
|
46
|
+
|
47
|
+
<div class='u-floatRight popoverCard-avatar'>
|
48
|
+
<a class='link dante-avatar u-baseColor--link'
|
49
|
+
href='#{@card_data.href}'
|
50
|
+
title='#{@card_data.text}'
|
51
|
+
aria-label='#{@card_data.text}'
|
52
|
+
data-user-id='#{@card_data.id}'
|
53
|
+
dir='auto'>
|
54
|
+
<img src='#{@card_data.avatar}'
|
55
|
+
class='avatar-image avatar-image--small'
|
56
|
+
alt='#{@card_data.text}'>
|
57
|
+
</a>
|
58
|
+
</div>
|
59
|
+
</div>
|
60
|
+
#{ @footerTemplate() }
|
61
|
+
<div class='popover-arrow'></div>
|
62
|
+
|
63
|
+
</div>"
|
64
|
+
|
65
|
+
# TODO: implement footer
|
66
|
+
footerTemplate: ->
|
67
|
+
""
|
68
|
+
###
|
69
|
+
"<div class='popoverCard-actions u-clearfix'>
|
70
|
+
<div class='u-floatLeft popoverCard-stats'>
|
71
|
+
<span class='popoverCard-stat'>
|
72
|
+
Following
|
73
|
+
<span class='popoverCard-count js-userFollowingCount'>124</span>
|
74
|
+
</span>
|
75
|
+
<span class='popoverCard-stat'>
|
76
|
+
Followers
|
77
|
+
<span class='popoverCard-count js-userFollowersCount'>79</span>
|
78
|
+
</span>
|
79
|
+
</div>
|
80
|
+
</div>"
|
81
|
+
###
|
82
|
+
|
83
|
+
displayPopOver: (ev)->
|
84
|
+
@.displayAt(ev)
|
85
|
+
|
86
|
+
displayAt: (ev)->
|
87
|
+
@cancelHide()
|
88
|
+
|
89
|
+
$.getJSON($(ev.currentTarget).data().href)
|
90
|
+
.success (data)=>
|
91
|
+
if @editor.suggest_resource_handler
|
92
|
+
@card_data = @editor.suggest_resource_handler(data)
|
93
|
+
else
|
94
|
+
@card_data = data
|
95
|
+
|
96
|
+
@refreshTemplate()
|
97
|
+
@positionAt(ev)
|
98
|
+
|
99
|
+
hidePopOver: (ev)->
|
100
|
+
@.hide(ev)
|
101
|
+
|
102
|
+
refreshTemplate: ->
|
103
|
+
$(".popover--card .popover-inner").html(@cardTemplate())
|
@@ -0,0 +1,112 @@
|
|
1
|
+
utils = Dante.utils
|
2
|
+
|
3
|
+
class Dante.Editor.ImageTooltip extends Dante.Editor.PopOver
|
4
|
+
|
5
|
+
el: "body"
|
6
|
+
|
7
|
+
events:
|
8
|
+
"click .graf" : "handleHide"
|
9
|
+
"click .dante-menu-button.align-left": "alignLeft"
|
10
|
+
"click .dante-menu-button.align-center": "alignCenter"
|
11
|
+
|
12
|
+
initialize: (opts = {})->
|
13
|
+
utils.log("initialized popover")
|
14
|
+
@pop_over_element = ".popover--Aligntooltip"
|
15
|
+
@editor = opts.editor
|
16
|
+
@hideTimeout
|
17
|
+
@settings = {timeout: 100}
|
18
|
+
|
19
|
+
alignLeft: (ev)->
|
20
|
+
@activateLink $(ev.currentTarget)
|
21
|
+
@findSelectedImage().addClass("graf--layoutOutsetLeft")
|
22
|
+
|
23
|
+
handleHide: (ev)->
|
24
|
+
target = $(ev.currentTarget)
|
25
|
+
@hide(ev) unless target.hasClass("graf--figure") and target.hasClass("is-mediaFocused")
|
26
|
+
|
27
|
+
alignCenter: (ev)->
|
28
|
+
@activateLink $(ev.currentTarget)
|
29
|
+
@findSelectedImage().removeClass("graf--layoutOutsetLeft")
|
30
|
+
@repositionWithActiveImage()
|
31
|
+
|
32
|
+
handleActiveClass: ->
|
33
|
+
@findElement().find(".dante-menu-button").removeClass("active")
|
34
|
+
if @findSelectedImage().hasClass("graf--layoutOutsetLeft")
|
35
|
+
@findElement().find(".icon-image-left").parent().addClass("active")
|
36
|
+
else
|
37
|
+
@findElement().find(".icon-image-center").parent().addClass("active")
|
38
|
+
|
39
|
+
activateLink: (element)->
|
40
|
+
setTimeout =>
|
41
|
+
@repositionWithActiveImage()
|
42
|
+
, 20
|
43
|
+
|
44
|
+
repositionWithActiveImage: ->
|
45
|
+
# pass the same element that is passed from click event
|
46
|
+
@positionPopOver(@findSelectedImage().find("div") )
|
47
|
+
|
48
|
+
template: ()->
|
49
|
+
"<div class='dante-popover popover--Aligntooltip popover--top'>
|
50
|
+
|
51
|
+
<div class='popover-inner'>
|
52
|
+
|
53
|
+
<ul class='dante-menu-buttons'>
|
54
|
+
|
55
|
+
<li class='dante-menu-button align-left'>
|
56
|
+
<span class='tooltip-icon icon-image-left'></span>
|
57
|
+
</li>
|
58
|
+
|
59
|
+
<li class='dante-menu-button align-wide hidden'>
|
60
|
+
<span class='tooltip-icon icon-image-wide'></span>
|
61
|
+
</li>
|
62
|
+
|
63
|
+
<li class='dante-menu-button align-fill hidden'>
|
64
|
+
<span class='tooltip-icon icon-image-fill'></span>
|
65
|
+
</li>
|
66
|
+
|
67
|
+
<li class='dante-menu-button align-center'>
|
68
|
+
<span class='tooltip-icon icon-image-center'></span>
|
69
|
+
</li>
|
70
|
+
|
71
|
+
</ul>
|
72
|
+
|
73
|
+
</div>
|
74
|
+
|
75
|
+
<div class='popover-arrow'>
|
76
|
+
</div>
|
77
|
+
</div>"
|
78
|
+
|
79
|
+
positionPopOver: (target)->
|
80
|
+
target_offset = target.offset()
|
81
|
+
target_position = target.parent().position()
|
82
|
+
target_width = target.outerWidth()
|
83
|
+
target_height = target.outerHeight()
|
84
|
+
popover_width = @findElement().outerWidth()
|
85
|
+
|
86
|
+
# hacky hack
|
87
|
+
pad_top = if @findSelectedImage().hasClass("graf--layoutOutsetLeft") then 72 else 74
|
88
|
+
|
89
|
+
top_value = target_position.top - pad_top # target_positions.top + target_height
|
90
|
+
left_value = target_offset.left + (target_width/2) - (popover_width/2)
|
91
|
+
|
92
|
+
@findElement()
|
93
|
+
.css("top", top_value)
|
94
|
+
.css("left", left_value )
|
95
|
+
.show()
|
96
|
+
.addClass("is-active")
|
97
|
+
|
98
|
+
@handleActiveClass()
|
99
|
+
|
100
|
+
hide: (ev)->
|
101
|
+
@cancelHide()
|
102
|
+
@hideTimeout = setTimeout ()=>
|
103
|
+
@findElement()
|
104
|
+
.hide()
|
105
|
+
.removeClass("is-active")
|
106
|
+
, @settings.timeout
|
107
|
+
|
108
|
+
findSelectedImage: ->
|
109
|
+
$(".graf--figure.is-mediaFocused")
|
110
|
+
|
111
|
+
render: ()->
|
112
|
+
$(@template()).insertAfter(@editor.$el)
|
@@ -0,0 +1,125 @@
|
|
1
|
+
utils = Dante.utils
|
2
|
+
|
3
|
+
class Dante.Editor.PopOverTypeAhead extends Dante.Editor.PopOver
|
4
|
+
el: "body"
|
5
|
+
|
6
|
+
events:
|
7
|
+
"mouseover .popover--typeahead": "cancelHide"
|
8
|
+
"mouseout .popover--typeahead": "hide"
|
9
|
+
|
10
|
+
"click .typeahead-item": "handleOptionSelection"
|
11
|
+
|
12
|
+
initialize: (opts = {})->
|
13
|
+
@pop_over_element = "popover--typeahead"
|
14
|
+
utils.log("initialized popover")
|
15
|
+
@editor = opts.editor
|
16
|
+
@hideTimeout
|
17
|
+
@settings = {timeout: 300}
|
18
|
+
@typeaheadStyles()
|
19
|
+
|
20
|
+
template: ()->
|
21
|
+
"<div class='dante-popover popover--typeahead js-popover typeahead typeahead--mention popover--maxWidth360 popover--bottom is-active'>
|
22
|
+
<div class='popover-inner js-popover-inner'>
|
23
|
+
<ul></ul>
|
24
|
+
</div>
|
25
|
+
<div class='popover-arrow' style='left: 297px;'></div>
|
26
|
+
</div>"
|
27
|
+
|
28
|
+
popoverItem: (item)->
|
29
|
+
"<li class='typeahead-item'
|
30
|
+
data-action-value='#{item.text}'
|
31
|
+
data-action='typeahead-populate' data-id='#{item.id}'
|
32
|
+
data-type='#{item.type}'
|
33
|
+
data-href='#{item.href}'>
|
34
|
+
|
35
|
+
<div class='dante-avatar'>
|
36
|
+
<img src='#{item.avatar}'
|
37
|
+
class='avatar-image avatar-image--icon'
|
38
|
+
alt='#{item.text}'>
|
39
|
+
|
40
|
+
<span class='avatar-text'>#{item.text}</span>
|
41
|
+
<em class='avatar-description'>#{item.description}</em>
|
42
|
+
|
43
|
+
</div>
|
44
|
+
|
45
|
+
</li>"
|
46
|
+
|
47
|
+
typeaheadStyles: ->
|
48
|
+
@classesForCurrent = "typeahead typeahead--mention popover--maxWidth360"
|
49
|
+
|
50
|
+
handleOptionSelection: (ev)->
|
51
|
+
ev.preventDefault
|
52
|
+
console.log "Select option here!"
|
53
|
+
data = $(ev.currentTarget).data()
|
54
|
+
$(".markup--query").replaceWith(@linkTemplate(data))
|
55
|
+
@hide(0)
|
56
|
+
#@setRangeAt(new_paragraph[0])
|
57
|
+
|
58
|
+
linkTemplate: (data)->
|
59
|
+
"<a href='#'
|
60
|
+
data-type='#{data.type}'
|
61
|
+
data-href='#{data.href}'
|
62
|
+
data-id='#{data.id}'
|
63
|
+
class='markup--user markup--p-user'>
|
64
|
+
#{data.actionValue}
|
65
|
+
</a>"
|
66
|
+
|
67
|
+
#display & copy original link
|
68
|
+
positionAt: (target)->
|
69
|
+
target = $(target)
|
70
|
+
wrapperOffset = target.closest('article.postArticle').offset()
|
71
|
+
target_positions = @resolveTargetPosition(target)
|
72
|
+
target_offset = target.offset()
|
73
|
+
target_width = target.outerWidth()
|
74
|
+
target_height = target.outerHeight()
|
75
|
+
popover_width = @findElement().outerWidth()
|
76
|
+
top_value = target_positions.top + target_height
|
77
|
+
left_value = target_offset.left + (target_width/2) - (popover_width/2) - wrapperOffset.left
|
78
|
+
|
79
|
+
@findElement()
|
80
|
+
.css("top", top_value)
|
81
|
+
.css("left", left_value )
|
82
|
+
.show()
|
83
|
+
|
84
|
+
@handleDirection(target)
|
85
|
+
|
86
|
+
displayAt: (ev)->
|
87
|
+
@cancelHide()
|
88
|
+
#target = $(ev.currentTarget)
|
89
|
+
#$(@el).find(".popover-inner a").text( target.attr('href') ).attr('href', target.attr("href") )
|
90
|
+
@positionAt(ev)
|
91
|
+
#$(@el).find(".popover--tooltip").css("pointer-events", "auto")
|
92
|
+
#$(@el).show()
|
93
|
+
|
94
|
+
cancelHide: ()->
|
95
|
+
utils.log "Cancel Hide"
|
96
|
+
clearTimeout @hideTimeout
|
97
|
+
|
98
|
+
findElement: ->
|
99
|
+
$(@el).find(".#{@pop_over_element}")
|
100
|
+
|
101
|
+
hide: (ev, timeout = @settings.timeout)->
|
102
|
+
@cancelHide()
|
103
|
+
@hideTimeout = setTimeout ()=>
|
104
|
+
@findElement().hide()
|
105
|
+
, timeout
|
106
|
+
|
107
|
+
appendData: (data)->
|
108
|
+
@findElement().find(".popover-inner ul").html("")
|
109
|
+
_.each data, (item)=>
|
110
|
+
@findElement().find(".popover-inner ul").append(@popoverItem(item))
|
111
|
+
|
112
|
+
resolveTargetPosition: (target)->
|
113
|
+
if target.parents(".graf--mixtapeEmbed").exists()
|
114
|
+
target.parents(".graf--mixtapeEmbed").position()
|
115
|
+
else
|
116
|
+
target.position()
|
117
|
+
|
118
|
+
handleDirection: (target)->
|
119
|
+
if target.parents(".graf--mixtapeEmbed").exists()
|
120
|
+
@findElement().removeClass("popover--bottom").addClass("popover--top")
|
121
|
+
else
|
122
|
+
@findElement().removeClass("popover--top").addClass("popover--bottom")
|
123
|
+
|
124
|
+
render: ()->
|
125
|
+
$(@template()).insertAfter(@editor.$el)
|
@@ -21,7 +21,7 @@ class Dante.View.TooltipWidget.Embed extends Dante.View.TooltipWidget
|
|
21
21
|
<iframe frameborder='0' width='700' height='393' data-media-id='' src='' data-height='480' data-width='854'>
|
22
22
|
</iframe>
|
23
23
|
</div>
|
24
|
-
<figcaption contenteditable='true' data-default-value='
|
24
|
+
<figcaption contenteditable='true' data-default-value='#{@current_editor.embed_caption_placeholder}' class='imageCaption'>
|
25
25
|
<a rel='nofollow' class='markup--anchor markup--figure-anchor' data-href='' href='' target='_blank'>
|
26
26
|
|
27
27
|
</a>
|
@@ -41,8 +41,8 @@ class Dante.View.TooltipWidget.Embed extends Dante.View.TooltipWidget
|
|
41
41
|
@node = $(node)
|
42
42
|
@node_name = @node.attr("name")
|
43
43
|
@node.addClass("spinner")
|
44
|
-
|
45
|
-
$.getJSON(
|
44
|
+
url = "#{@current_editor.oembed_url}#{$(@node).text()}&scheme=https"
|
45
|
+
$.getJSON(url)
|
46
46
|
.success (data)=>
|
47
47
|
@node = $("[name=#{@node_name}]")
|
48
48
|
iframe_src = $(data.html).prop("src")
|
@@ -19,9 +19,18 @@ class Dante.View.TooltipWidget.EmbedExtract extends Dante.View.TooltipWidget
|
|
19
19
|
"<div class='graf graf--mixtapeEmbed is-selected' name=''>
|
20
20
|
<a target='_blank' data-media-id='' class='js-mixtapeImage mixtapeImage mixtapeImage--empty u-ignoreBlock' href=''>
|
21
21
|
</a>
|
22
|
-
<a data-tooltip-type='link'
|
23
|
-
|
24
|
-
|
22
|
+
<a data-tooltip-type='link'
|
23
|
+
data-tooltip-position='bottom'
|
24
|
+
data-tooltip=''
|
25
|
+
title=''
|
26
|
+
class='markup--anchor markup--mixtapeEmbed-anchor'
|
27
|
+
data-href=''
|
28
|
+
href=''
|
29
|
+
target='_blank'>
|
30
|
+
<strong class='markup--strong markup--mixtapeEmbed-strong'>
|
31
|
+
</strong>
|
32
|
+
<em class='markup--em markup--mixtapeEmbed-em'>
|
33
|
+
</em>
|
25
34
|
</a>
|
26
35
|
</div>"
|
27
36
|
|