dante-editor 0.0.13 → 0.0.14
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
|