dante-editor 0.0.13 → 0.0.14
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/Gemfile.lock +4 -1
- data/app/assets/javascripts/dante/editor.js.coffee +71 -56
- data/app/assets/javascripts/dante/tooltip_widgets/uploader.js.coffee +22 -15
- data/app/assets/stylesheets/dante/_scaffold.scss +4 -0
- data/bower.json +1 -1
- data/dist/css/dante-editor.css +156 -152
- data/dist/js/dante-editor.js +76 -56
- data/lib/dante-editor/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 64f6f786c61ccbf8426121e68b54530c5fcf0427
|
4
|
+
data.tar.gz: 73f9b8c0bbb9e8ff59ce223ba455fd0c72d4f065
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f8f8c7511abc490294fcbf3e6a41dab1271f7ca5cef6046f6eb77a147895bae60926535c6a0fdd1c70c570977c92f1ae06728ed1d5c2f1b3506fbfdeebacefa6
|
7
|
+
data.tar.gz: 175e321a6d64c3c9dc3c6c33a0accee13edf352b08d7c42e7100278e321db2c6a5cb3fbcaa883941fb5431b7e3ea26840efb09dc76493cca45beb9b7cd63dc0d
|
data/Gemfile.lock
CHANGED
@@ -77,7 +77,6 @@ class Dante.Editor extends Dante.View
|
|
77
77
|
|
78
78
|
@initializeWidgets(opts)
|
79
79
|
|
80
|
-
|
81
80
|
initializeWidgets: (opts)->
|
82
81
|
#TODO: this could be a hash to access widgets without var
|
83
82
|
#Base widgets
|
@@ -248,11 +247,11 @@ class Dante.Editor extends Dante.View
|
|
248
247
|
a is b
|
249
248
|
|
250
249
|
#set focus and caret position on element
|
251
|
-
setRangeAt: (element,
|
250
|
+
setRangeAt: (element, pos=0)->
|
252
251
|
range = document.createRange()
|
253
252
|
sel = window.getSelection()
|
254
253
|
#node = element.firstChild;
|
255
|
-
range.setStart(element,
|
254
|
+
range.setStart(element, pos); #DANGER this is supported by IE 9
|
256
255
|
#range.setStartAfter(element)
|
257
256
|
#range.setEnd(element, int);
|
258
257
|
range.collapse(true)
|
@@ -261,7 +260,7 @@ class Dante.Editor extends Dante.View
|
|
261
260
|
element.focus()
|
262
261
|
|
263
262
|
#set focus and caret position on element
|
264
|
-
setRangeAtText: (element,
|
263
|
+
setRangeAtText: (element, pos=0)->
|
265
264
|
range = document.createRange()
|
266
265
|
sel = window.getSelection()
|
267
266
|
node = element.firstChild;
|
@@ -460,7 +459,7 @@ class Dante.Editor extends Dante.View
|
|
460
459
|
|
461
460
|
when "Up"
|
462
461
|
prev_node = current_node.prev()
|
463
|
-
utils.log "PREV NODE IS #{prev_node.attr('class')}"
|
462
|
+
utils.log "PREV NODE IS #{prev_node.attr('class')} #{prev_node.attr('name')}"
|
464
463
|
utils.log "CURRENT NODE IS up #{current_node.attr('class')}"
|
465
464
|
|
466
465
|
return unless $(current_node).hasClass("graf")
|
@@ -503,8 +502,8 @@ class Dante.Editor extends Dante.View
|
|
503
502
|
|
504
503
|
#parse text for initial mess
|
505
504
|
parseInitialMess: ()->
|
506
|
-
@setupElementsClasses $(@el).find('.section-inner') , ()=>
|
507
|
-
@handleUnwrappedImages(
|
505
|
+
@setupElementsClasses $(@el).find('.section-inner') , (e)=>
|
506
|
+
@handleUnwrappedImages(e)
|
508
507
|
|
509
508
|
handleDblclick: ()->
|
510
509
|
utils.log "handleDblclick"
|
@@ -517,7 +516,7 @@ class Dante.Editor extends Dante.View
|
|
517
516
|
#then clean up the content and copies to currentNode, very clever uh?
|
518
517
|
handlePaste: (ev)=>
|
519
518
|
utils.log("pasted!")
|
520
|
-
@aa =
|
519
|
+
@aa = @getNode()
|
521
520
|
|
522
521
|
pastedText = undefined
|
523
522
|
if (window.clipboardData && window.clipboardData.getData) #IE
|
@@ -531,28 +530,38 @@ class Dante.Editor extends Dante.View
|
|
531
530
|
if pastedText.match(/<\/*[a-z][^>]+?>/gi)
|
532
531
|
utils.log("HTML DETECTED ON PASTE")
|
533
532
|
pastedText = pastedText.replace(/&.*;/g, "")
|
533
|
+
|
534
534
|
#convert pasted divs in p before copy contents into div
|
535
535
|
pastedText = pastedText.replace(/<div>([\w\W]*?)<\/div>/gi, '<p>$1</p>')
|
536
536
|
|
537
|
-
|
537
|
+
#create the placeholder element and assign pasted content
|
538
|
+
document.body.appendChild( $("<div id='#{@paste_element_id.replace('#', '')}' class='dante-paste'></div>")[0] )
|
538
539
|
$(@paste_element_id).html("<span>#{pastedText}</span>")
|
539
540
|
|
540
|
-
|
541
|
-
|
542
|
-
|
541
|
+
#clean pasted content
|
542
|
+
|
543
|
+
@setupElementsClasses $(@paste_element_id), (e)=>
|
544
|
+
# e is the target object which is cleaned
|
545
|
+
nodes = $(e.html()).insertAfter($(@aa))
|
546
|
+
#remove paste div since we wont use it until the next paste
|
547
|
+
e.remove()
|
543
548
|
#set caret on newly created node
|
544
549
|
last_node = nodes.last()[0]
|
545
550
|
num = last_node.childNodes.length
|
546
551
|
@setRangeAt(last_node, num)
|
552
|
+
#select new node
|
547
553
|
new_node = $(@getNode())
|
548
|
-
top = new_node.offset().top
|
549
554
|
@markAsSelected(new_node)
|
550
555
|
@displayTooltipAt($(@el).find(".is-selected"))
|
551
|
-
|
556
|
+
|
552
557
|
@handleUnwrappedImages(nodes)
|
558
|
+
|
559
|
+
#scroll to element top
|
560
|
+
top = new_node.offset().top
|
553
561
|
$('html, body').animate
|
554
562
|
scrollTop: top
|
555
|
-
,
|
563
|
+
, 20
|
564
|
+
|
556
565
|
|
557
566
|
return false # Prevent the default handler from running.
|
558
567
|
|
@@ -604,6 +613,7 @@ class Dante.Editor extends Dante.View
|
|
604
613
|
node = $(range.commonAncestorContainer)
|
605
614
|
prev = node.prev()
|
606
615
|
num = prev[0].childNodes.length
|
616
|
+
utils.log "PREV NODE"
|
607
617
|
utils.log prev
|
608
618
|
if prev.hasClass("graf")
|
609
619
|
@setRangeAt(prev[0], num)
|
@@ -613,6 +623,8 @@ class Dante.Editor extends Dante.View
|
|
613
623
|
@setRangeAt(prev[0], num)
|
614
624
|
node.remove()
|
615
625
|
@markAsSelected(@getNode())
|
626
|
+
else if prev.hasClass("postList")
|
627
|
+
@.setRangeAt(prev.find("li").last()[0])
|
616
628
|
else if !prev
|
617
629
|
@.setRangeAt(@.$el.find(".section-inner p")[0])
|
618
630
|
|
@@ -658,15 +670,13 @@ class Dante.Editor extends Dante.View
|
|
658
670
|
anchor_node = @getNode() #current node on which cursor is positioned
|
659
671
|
parent = $(anchor_node)
|
660
672
|
|
661
|
-
|
662
673
|
@markAsSelected( anchor_node ) if anchor_node
|
663
674
|
|
664
675
|
if e.which is TAB
|
665
|
-
|
666
676
|
@handleTab(anchor_node)
|
667
677
|
return false
|
668
678
|
|
669
|
-
if e.which
|
679
|
+
if e.which is ENTER
|
670
680
|
|
671
681
|
#removes previous selected nodes
|
672
682
|
$(@el).find(".is-selected").removeClass("is-selected")
|
@@ -733,7 +743,7 @@ class Dante.Editor extends Dante.View
|
|
733
743
|
, 2
|
734
744
|
|
735
745
|
#delete key
|
736
|
-
if (e.which
|
746
|
+
if (e.which is BACKSPACE)
|
737
747
|
eventHandled = false;
|
738
748
|
@tooltip_view.hide()
|
739
749
|
utils.log("removing from down")
|
@@ -748,24 +758,26 @@ class Dante.Editor extends Dante.View
|
|
748
758
|
utils.log(utils_anchor_node);
|
749
759
|
|
750
760
|
#check if any of the widgets can handle a backspace keydown
|
751
|
-
utils.log("HANDLING WIDGET BACKSPACES")
|
761
|
+
utils.log("HANDLING WIDGET BACKSPACES")
|
752
762
|
_.each @widgets, (w)=>
|
753
|
-
if w.handleBackspaceKey && !
|
754
|
-
|
763
|
+
if _.isFunction(w.handleBackspaceKey) && !eventHandled
|
764
|
+
eventHandled = w.handleBackspaceKey(e, anchor_node)
|
765
|
+
utils.log(eventHandled)
|
755
766
|
|
756
767
|
if (eventHandled)
|
757
|
-
e.preventDefault()
|
768
|
+
e.preventDefault()
|
769
|
+
utils.log("SCAPE FROM BACKSPACE HANDLER")
|
758
770
|
return false;
|
759
771
|
|
760
772
|
if(parent.hasClass("graf--li") and @getCharacterPrecedingCaret().length is 0)
|
761
|
-
|
773
|
+
return this.handleListBackspace(parent, e);
|
762
774
|
|
763
775
|
#select an image if backspacing into it from a paragraph
|
764
|
-
if($(anchor_node).hasClass("graf--p") && @isFirstChar)
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
776
|
+
if($(anchor_node).hasClass("graf--p") && @isFirstChar() )
|
777
|
+
if($(anchor_node).prev().hasClass("graf--figure") && @getSelectedText().length == 0)
|
778
|
+
e.preventDefault();
|
779
|
+
$(anchor_node).prev().find("img").click();
|
780
|
+
utils.log("Focus on the previous image");
|
769
781
|
|
770
782
|
if $(utils_anchor_node).hasClass("section-content") || $(utils_anchor_node).hasClass("graf--first")
|
771
783
|
utils.log "SECTION DETECTED FROM KEYDOWN #{_.isEmpty($(utils_anchor_node).text())}"
|
@@ -789,12 +801,12 @@ class Dante.Editor extends Dante.View
|
|
789
801
|
return false if @isFirstChar() && !_.isEmpty( $(anchor_node).text().trim() )
|
790
802
|
|
791
803
|
#spacebar
|
792
|
-
if (e.which
|
804
|
+
if (e.which is SPACEBAR)
|
793
805
|
utils.log("SPACEBAR")
|
794
806
|
if (parent.hasClass("graf--p"))
|
795
807
|
@handleSmartList(parent, e)
|
808
|
+
|
796
809
|
#arrows key
|
797
|
-
#if _.contains([37,38,39,40], e.which)
|
798
810
|
#up & down
|
799
811
|
if _.contains([UPARROW, DOWNARROW], e.which)
|
800
812
|
utils.log e.which
|
@@ -912,7 +924,7 @@ class Dante.Editor extends Dante.View
|
|
912
924
|
|
913
925
|
#mark the current row as selected
|
914
926
|
markAsSelected: (element)->
|
915
|
-
|
927
|
+
utils.log element
|
916
928
|
return if _.isUndefined element
|
917
929
|
|
918
930
|
$(@el).find(".is-selected").removeClass("is-mediaFocused is-selected")
|
@@ -985,34 +997,35 @@ class Dante.Editor extends Dante.View
|
|
985
997
|
|
986
998
|
setupElementsClasses: (element, cb)->
|
987
999
|
if _.isUndefined(element)
|
988
|
-
|
1000
|
+
element = $(@el).find('.section-inner')
|
989
1001
|
else
|
990
|
-
|
991
|
-
|
992
|
-
setTimeout ()=>
|
993
|
-
#clean context and wrap text nodes
|
994
|
-
@cleanContents(@element)
|
995
|
-
@wrapTextNodes(@element)
|
996
|
-
|
997
|
-
#setup classes
|
998
|
-
_.each @element.children(), (n)=>
|
999
|
-
name = $(n).prop("tagName").toLowerCase()
|
1000
|
-
n = @addClassesToElement(n)
|
1001
|
-
@setElementName(n)
|
1002
|
-
|
1003
|
-
@setupLinks(@element.find("a"))
|
1004
|
-
@setupFirstAndLast()
|
1002
|
+
element = element
|
1005
1003
|
|
1006
|
-
|
1007
|
-
|
1004
|
+
#setTimeout ()=>
|
1005
|
+
#clean context and wrap text nodes
|
1006
|
+
@cleanContents(element)
|
1007
|
+
@wrapTextNodes(element)
|
1008
|
+
#setup classes
|
1009
|
+
_.each element.children(), (n)=>
|
1010
|
+
name = $(n).prop("tagName").toLowerCase()
|
1011
|
+
n = @addClassesToElement(n)
|
1012
|
+
@setElementName(n)
|
1013
|
+
|
1014
|
+
@setupLinks(element.find("a"))
|
1015
|
+
@setupFirstAndLast()
|
1016
|
+
cb(element) if _.isFunction(cb)
|
1017
|
+
#, 20
|
1008
1018
|
|
1009
1019
|
cleanContents: (element)->
|
1010
1020
|
#TODO: should config tags
|
1021
|
+
utils.log "ti"
|
1022
|
+
utils.log element
|
1011
1023
|
if _.isUndefined(element)
|
1012
|
-
|
1024
|
+
element = $(@el).find('.section-inner')
|
1013
1025
|
else
|
1014
|
-
|
1026
|
+
element = element
|
1015
1027
|
|
1028
|
+
paste_div = @paste_element_id
|
1016
1029
|
s = new Sanitize
|
1017
1030
|
elements: ['strong','img', 'em', 'br', 'a', 'blockquote', 'b', 'u', 'i', 'pre', 'p', 'h1', 'h2', 'h3', 'h4', 'ul', 'ol', 'li']
|
1018
1031
|
|
@@ -1027,6 +1040,8 @@ class Dante.Editor extends Dante.View
|
|
1027
1040
|
transformers: [(input)->
|
1028
1041
|
if (input.node_name == "span" && $(input.node).hasClass("defaultValue") )
|
1029
1042
|
return whitelist_nodes: [input.node]
|
1043
|
+
if( $(input.node).hasClass("dante-paste") )
|
1044
|
+
return whitelist_nodes: [input.node]
|
1030
1045
|
else
|
1031
1046
|
return null
|
1032
1047
|
(input)->
|
@@ -1077,9 +1092,9 @@ class Dante.Editor extends Dante.View
|
|
1077
1092
|
return null
|
1078
1093
|
]
|
1079
1094
|
|
1080
|
-
if
|
1081
|
-
utils.log "CLEAN HTML #{
|
1082
|
-
|
1095
|
+
if element.exists()
|
1096
|
+
utils.log "CLEAN HTML #{element[0].tagName}"
|
1097
|
+
element.html(s.clean_node( element[0] ))
|
1083
1098
|
|
1084
1099
|
setupLinks: (elems)->
|
1085
1100
|
_.each elems, (n)=>
|
@@ -1226,7 +1241,7 @@ class Dante.Editor extends Dante.View
|
|
1226
1241
|
content = $li.html()
|
1227
1242
|
@replaceWith("p", $li)
|
1228
1243
|
$paragraph = $(".is-selected")
|
1229
|
-
$paragraph.removeClass("graf--empty").html(content)
|
1244
|
+
$paragraph.removeClass("graf--empty").html(content).attr("name", utils.generateUniqueName());
|
1230
1245
|
|
1231
1246
|
if($list.children().length is 0)
|
1232
1247
|
$list.remove()
|
@@ -29,26 +29,26 @@ class Dante.View.TooltipWidget.Uploader extends Dante.View.TooltipWidget
|
|
29
29
|
#replace existing img tag , and wrap it in insertTamplate
|
30
30
|
#TODO: take the url and upload it
|
31
31
|
uploadExistentImage: (image_element, opts = {})->
|
32
|
-
|
33
32
|
utils.log ("process image here!")
|
34
33
|
tmpl = $(@insertTemplate())
|
35
34
|
tmpl.find("img").attr('src', @current_editor.default_loading_placeholder )
|
36
35
|
#is a child element or a first level element ?
|
37
36
|
|
38
37
|
if $(image_element).parents(".graf").length > 0
|
39
|
-
#return if
|
38
|
+
#return if it's already wrapped in graf--figure
|
40
39
|
if $(image_element).parents(".graf").hasClass("graf--figure")
|
41
40
|
return
|
41
|
+
|
42
42
|
utils.log "UNO"
|
43
43
|
tmpl.insertBefore( $(image_element).parents(".graf") )
|
44
44
|
node = @current_editor.getNode()
|
45
|
+
#wtf?
|
45
46
|
if node
|
46
47
|
@current_editor.preCleanNode($(node))
|
47
48
|
@current_editor.addClassesToElement(node)
|
48
49
|
else
|
49
50
|
utils.log "DOS"
|
50
|
-
|
51
|
-
$(img).replaceWith(tmpl)
|
51
|
+
$(image_element).replaceWith(tmpl)
|
52
52
|
|
53
53
|
utils.log $("[name='#{tmpl.attr('name')}']").attr("name")
|
54
54
|
@replaceImg(image_element, $("[name='#{tmpl.attr('name')}']"))
|
@@ -59,7 +59,6 @@ class Dante.View.TooltipWidget.Uploader extends Dante.View.TooltipWidget
|
|
59
59
|
for i in [0..n-1] by 1
|
60
60
|
$("[name='#{tmpl.attr('name')}']").unwrap()
|
61
61
|
|
62
|
-
utils.log "FIG"
|
63
62
|
#utils.log $("[name='#{tmpl.attr('name')}']").attr("name")
|
64
63
|
|
65
64
|
replaceImg: (image_element, figure)->
|
@@ -229,19 +228,27 @@ class Dante.View.TooltipWidget.Uploader extends Dante.View.TooltipWidget
|
|
229
228
|
# @param {Event} e - The backspace event that is being handled
|
230
229
|
# @param {Node} node - The node the backspace was used in, assumed to be from te editor's getNode() function
|
231
230
|
#
|
232
|
-
# @return {Boolean} true if this function
|
231
|
+
# @return {Boolean} true if this function should scape the default behavior
|
233
232
|
###
|
234
233
|
handleBackspaceKey: (e, node) =>
|
235
|
-
|
236
|
-
|
237
|
-
if
|
234
|
+
utils.log "handleBackspaceKey on uploader widget"
|
235
|
+
|
236
|
+
# remove graf figure if is selected but not in range (not focus on caption)
|
237
|
+
if $(node).hasClass("is-selected") && $(node).hasClass("graf--figure")
|
238
|
+
# exit if selection is on caption
|
239
|
+
anchor_node = @current_editor.selection().anchorNode
|
240
|
+
|
241
|
+
# return false unless backspace is in the first char
|
242
|
+
if ( anchor_node? && $(anchor_node.parentNode).hasClass("imageCaption"))
|
243
|
+
if @current_editor.isFirstChar()
|
244
|
+
return true
|
245
|
+
else
|
246
|
+
return false
|
247
|
+
|
248
|
+
else if $(".is-selected").hasClass("is-mediaFocused")
|
249
|
+
# assume that select node is the current media element
|
250
|
+
# if it's focused when backspace it means that it should be removed
|
238
251
|
utils.log("Replacing selected node")
|
239
252
|
@current_editor.replaceWith("p", $(".is-selected"))
|
240
|
-
|
241
|
-
e.preventDefault() #without this line, the browser may interpret the backspace as a "go pack a page" command
|
242
|
-
|
243
253
|
@current_editor.setRangeAt($(".is-selected")[0])
|
244
254
|
return true
|
245
|
-
|
246
|
-
return false
|
247
|
-
|