dante-editor 0.0.7 → 0.0.8

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e2ec0071786217bc5d8d7e34c715187744439cae
4
- data.tar.gz: 164d2de65f75dfa632f86343558007ff8c20f38c
3
+ metadata.gz: eedf5900c356c7db2f6c2a506a3c36023327a52a
4
+ data.tar.gz: ece1127158d6ed6c86311f7ca034a81194618778
5
5
  SHA512:
6
- metadata.gz: eac586a212bb0abec442f55a200001a6c6dbbc05b9d2203eaee38926d2afa4992a98a48e9c74c3a3764c183aa9e9fdfe5a12ed3139163fd93e06658dea505fa9
7
- data.tar.gz: 74078718948964b7d15975034b4a089e40f1d7de5c6d801246a3e2f6418fdd00ab477717d3ce33be88650dae9a89b256cc8364c55cf00516b6f5bae923c9447a
6
+ metadata.gz: 41352cf754791ce8c712c582c8670a5d924c07d56b1313f2cab57e178bcfa36f0d5b59f32ff32605ba791b33ec6d61eb236e39795405b6d22b3be1edd3edd7d7
7
+ data.tar.gz: 4902b6a415b936025f9f7f26db7a4ff3cf5fc81b1c3fa97b5d6acd1d4fad43ecc7d0a9dfea44bcb5cb2455361ed0805f2a7ed46df1b91a42fbc713582215d5e2
data/README.md CHANGED
@@ -26,6 +26,7 @@ Until now I´ve been able to implement the following features:
26
26
  + Image Uploader with *preview* and caption option.
27
27
  + Embed data for pasted link through OEmbed services.
28
28
  + Embed media information for pasted links through OEmbed services.
29
+ + List creation with shorcuts ie:. 1. , - , 1) with spacebar or return key
29
30
  + CSS tries to use the same fonts used in Medium, (if you have already setup those fonts) or fallbacks to open fonts (by Google fonts) or system fonts.
30
31
  + serif: freight-text-pro fallbacks to Merriweather or Georgia,
31
32
  + sans: jaf-bernino-sans fallbacks to Open Sans or Lucida Grande
@@ -60,7 +61,7 @@ Until now I´ve been able to implement the following features:
60
61
  ### Configuration options:
61
62
 
62
63
  + **el:** default: #editor
63
- + **debugMode:** default: false
64
+ + **debug:** default: false
64
65
  + **upload_url:** default: /uploads.json
65
66
  + **oembed_url:** default: http://api.embed.ly/1/oembed?url="
66
67
  + **extract_url:** default: http://api.embed.ly/1/extract?url="
@@ -112,6 +113,7 @@ There is a web app for development to work with the source files and make the pr
112
113
 
113
114
  + install ruby
114
115
  + execute `bundle install`
116
+ + execute `bower install`
115
117
 
116
118
  ### Start app:
117
119
 
@@ -139,7 +141,13 @@ tests are located in source/tests and /source/assets/spec folder and accessible
139
141
  + [Miguel Michelson](http://github.com/michelson)
140
142
  + [Cristian Ferrari](http://github.com/cristianferrarig)
141
143
 
142
- ### Alternatives:
144
+ ### CONTRIBUTORS
145
+
146
+ Big kudos to our valued contributors. Check them all at:
147
+
148
+ https://github.com/michelson/dante/graphs/contributors
149
+
150
+ ### ALTERNATIVES
143
151
 
144
152
  + https://github.com/sofish/pen
145
153
  + https://github.com/orthes/medium-editor-insert-plugin
@@ -152,4 +160,4 @@ tests are located in source/tests and /source/assets/spec folder and accessible
152
160
 
153
161
  ### LICENSE
154
162
 
155
- [Licensed under MIT.](./license.md) 2014
163
+ [Licensed under MIT.](./license.md) 2014
@@ -13,6 +13,9 @@ class Dante.Editor extends Dante.View
13
13
  "drop" : "handleDrag"
14
14
  "click .graf--figure .aspectRatioPlaceholder" : "handleGrafFigureSelectImg"
15
15
  "click .graf--figure figcaption" : "handleGrafFigureSelectCaption"
16
+
17
+ "mouseover .graf--figure.graf--iframe" : "handleGrafFigureSelectIframe"
18
+ "mouseleave .graf--figure.graf--iframe" : "handleGrafFigureUnSelectIframe"
16
19
  "keyup .graf--figure figcaption" : "handleGrafCaptionTyping"
17
20
 
18
21
  "mouseover .markup--anchor" : "displayPopOver"
@@ -33,6 +36,7 @@ class Dante.Editor extends Dante.View
33
36
  @spell_check = opts.spellcheck || false
34
37
  @disable_title = opts.disable_title || false
35
38
  @store_interval = opts.store_interval || 15000
39
+ @paste_element_id = "#dante-paste-div"
36
40
  window.debugMode = opts.debug || false
37
41
  $(@el).addClass("debug") if window.debugMode
38
42
  if (localStorage.getItem('contenteditable'))
@@ -151,7 +155,7 @@ class Dante.Editor extends Dante.View
151
155
  range = range || this.current_range
152
156
  if !range
153
157
  range = this.getRange()
154
- range.collapse(false); # set to end
158
+ range.collapse(false) # set to end
155
159
 
156
160
  @selection().removeAllRanges()
157
161
  @selection().addRange(range)
@@ -233,8 +237,14 @@ class Dante.Editor extends Dante.View
233
237
  range = @selection().getRangeAt(0)
234
238
  node = range.commonAncestorContainer
235
239
  return null if not node or node is root
236
- node = node.parentNode while node and (node.nodeType isnt 1) and (node.parentNode isnt root)
237
- node = node.parentNode while node and (node.parentNode isnt root)
240
+
241
+ #node = node.parentNode while node and (node.nodeType isnt 1) and (node.parentNode isnt root)
242
+ #node = node.parentNode while node and (node.parentNode isnt root)
243
+
244
+ node = node.parentNode while node and (node.nodeType isnt 1 or not $(node).hasClass("graf")) and (node.parentNode isnt root)
245
+ if not $(node).hasClass("graf--li")
246
+ node = node.parentNode while node and (node.parentNode isnt root)
247
+
238
248
  (if root && root.contains(node) then node else null)
239
249
 
240
250
  displayMenu: (sel)->
@@ -290,6 +300,20 @@ class Dante.Editor extends Dante.View
290
300
  $(element).parent(".graf--figure").addClass("is-selected is-mediaFocused")
291
301
  @selection().removeAllRanges()
292
302
 
303
+ handleGrafFigureSelectIframe: (ev)->
304
+ utils.log "FIGURE IFRAME SELECT"
305
+ element = ev.currentTarget
306
+ @iframeSelected = element
307
+ @markAsSelected( element )
308
+ $(element).addClass("is-selected is-mediaFocused")
309
+ @selection().removeAllRanges()
310
+
311
+ handleGrafFigureUnSelectIframe: (ev)->
312
+ utils.log "FIGURE IFRAME UNSELECT"
313
+ element = ev.currentTarget
314
+ @iframeSelected = null
315
+ $(element).removeClass("is-selected is-mediaFocused")
316
+
293
317
  handleGrafFigureSelectCaption: (ev)->
294
318
  utils.log "FIGCAPTION"
295
319
  element = ev.currentTarget
@@ -448,17 +472,20 @@ class Dante.Editor extends Dante.View
448
472
  cbd = ev.originalEvent.clipboardData
449
473
  pastedText = if _.isEmpty(cbd.getData('text/html')) then cbd.getData('text/plain') else cbd.getData('text/html')
450
474
 
451
- utils.log(pastedText) # Process and handle text...
475
+ utils.log("Process and handle text...")
452
476
  #detect if is html
453
477
  if pastedText.match(/<\/*[a-z][^>]+?>/gi)
454
478
  utils.log("HTML DETECTED ON PASTE")
455
- $(pastedText)
479
+ pastedText = pastedText.replace(/&.*;/g, "")
480
+ #convert pasted divs in p before copy contents into div
481
+ pastedText = pastedText.replace(/<div>([\w\W]*?)<\/div>/gi, '<p>$1</p>')
456
482
 
457
- document.body.appendChild($("<div id='paste'></div>")[0])
458
- $("#paste").html(pastedText)
459
- @setupElementsClasses $("#paste"), ()=>
460
- nodes = $($("#paste").html()).insertAfter($(@aa))
461
- $("#paste").remove()
483
+ document.body.appendChild($("<div id='#{@paste_element_id.replace('#', '')}'></div>")[0])
484
+ $(@paste_element_id).html("<span>#{pastedText}</span>")
485
+
486
+ @setupElementsClasses $(@paste_element_id), ()=>
487
+ nodes = $($(@paste_element_id).html()).insertAfter($(@aa))
488
+ $(@paste_element_id).remove()
462
489
  #set caret on newly created node
463
490
  last_node = nodes.last()[0]
464
491
  num = last_node.childNodes.length
@@ -481,7 +508,6 @@ class Dante.Editor extends Dante.View
481
508
  utils.log ("process image here!")
482
509
  @tooltip_view.uploadExistentImage(image)
483
510
 
484
- #TODO: remove this, not used
485
511
  handleInmediateDeletion: (element)->
486
512
  @inmediateDeletion = false
487
513
  new_node = $( @baseParagraphTmpl() ).insertBefore( $(element) )
@@ -576,6 +602,7 @@ class Dante.Editor extends Dante.View
576
602
  utils.log "KEYDOWN"
577
603
 
578
604
  anchor_node = @getNode() #current node on which cursor is positioned
605
+ $node = $(anchor_node);
579
606
 
580
607
  @markAsSelected( anchor_node ) if anchor_node
581
608
 
@@ -593,6 +620,13 @@ class Dante.Editor extends Dante.View
593
620
 
594
621
  utils.log @isLastChar()
595
622
 
623
+ #smart list support
624
+ if $node.hasClass("graf--p")
625
+ li = @handleSmartList($node, e)
626
+ anchor_node = li if li
627
+ else if $node.hasClass("graf--li") and ($node.text() is "")
628
+ @handleListLineBreak($node, e)
629
+
596
630
  #embeds or extracts
597
631
  if parent.hasClass("is-embedable")
598
632
  @tooltip_view.getEmbedFromNode($(anchor_node))
@@ -617,7 +651,6 @@ class Dante.Editor extends Dante.View
617
651
 
618
652
  @tooltip_view.cleanOperationClasses($(anchor_node))
619
653
 
620
-
621
654
  if (anchor_node && @editor_menu.lineBreakReg.test(anchor_node.nodeName))
622
655
  #new paragraph if it the last character
623
656
  if @isLastChar()
@@ -627,6 +660,7 @@ class Dante.Editor extends Dante.View
627
660
 
628
661
  setTimeout ()=>
629
662
  node = @getNode()
663
+ return if _.isUndefined(node)
630
664
  #set name on new element
631
665
  @setElementName($(node))
632
666
 
@@ -656,6 +690,9 @@ class Dante.Editor extends Dante.View
656
690
  anchor_node = @getNode()
657
691
  utils_anchor_node = utils.getNode()
658
692
 
693
+ if($node.hasClass("graf--li") and @getCharacterPrecedingCaret().length is 0)
694
+ return this.handleListBackspace($node, e);
695
+
659
696
  if $(utils_anchor_node).hasClass("section-content") || $(utils_anchor_node).hasClass("graf--first")
660
697
  utils.log "SECTION DETECTED FROM KEYDOWN #{_.isEmpty($(utils_anchor_node).text())}"
661
698
  return false if _.isEmpty($(utils_anchor_node).text())
@@ -665,27 +702,29 @@ class Dante.Editor extends Dante.View
665
702
  utils.log("TextNode detected from Down!")
666
703
  #return false
667
704
 
668
- #supress del into embed if first char or delete if empty content
705
+ #supress del into & delete embed if empty content found on delete key
669
706
  if $(anchor_node).hasClass("graf--mixtapeEmbed") or $(anchor_node).hasClass("graf--iframe")
670
- if _.isEmpty $(anchor_node).text().trim()
671
- utils.log "EMPTY CHAR"
707
+ if _.isEmpty $(anchor_node).text().trim() or @isFirstChar()
708
+ utils.log("Check for inmediate deletion on empty embed text")
709
+ @inmediateDeletion = @isSelectingAll(anchor_node)
710
+ @handleInmediateDeletion($(anchor_node)) if @inmediateDeletion
672
711
  return false
673
- else
674
- if @isFirstChar()
675
- utils.log "FIRST CHAR"
676
- @inmediateDeletion = true if @isSelectingAll(anchor_node)
677
- return false
678
712
 
679
713
  #TODO: supress del when the prev el is embed and current_node is at first char
680
714
  if $(anchor_node).prev().hasClass("graf--mixtapeEmbed")
681
715
  return false if @isFirstChar() && !_.isEmpty( $(anchor_node).text().trim() )
682
716
 
683
- utils.log anchor_node
684
- if $(".is-selected").hasClass("graf--figure")
717
+ #remove graf figure is is selected but not in range (not focus on caption)
718
+ if $(".is-selected").hasClass("graf--figure") && !anchor_node?
685
719
  @replaceWith("p", $(".is-selected"))
686
720
  @setRangeAt($(".is-selected")[0])
687
721
  return false
688
722
 
723
+ #spacebar
724
+ if (e.which == 32)
725
+ utils.log("SPACEBAR")
726
+ if ($node.hasClass("graf--p"))
727
+ @handleSmartList($node, e)
689
728
  #arrows key
690
729
  #if _.contains([37,38,39,40], e.which)
691
730
  #up & down
@@ -790,10 +829,11 @@ class Dante.Editor extends Dante.View
790
829
  displayTooltipAt: (element)->
791
830
  utils.log ("POSITION FOR TOOLTIP")
792
831
  #utils.log $(element)
793
- return if !element
832
+ element = $(element)
833
+ return if !element || _.isEmpty(element) || element[0].tagName is "LI"
794
834
  @tooltip_view.hide()
795
- return unless _.isEmpty( $(element).text() )
796
- @positions = $(element).offset()
835
+ return unless _.isEmpty( element.text() )
836
+ @positions = element.offset()
797
837
  @tooltip_view.render()
798
838
  @tooltip_view.move(@positions)
799
839
 
@@ -816,7 +856,6 @@ class Dante.Editor extends Dante.View
816
856
  name = n.nodeName.toLowerCase()
817
857
  switch name
818
858
  when "p", "pre", "div"
819
- #utils.log n
820
859
  unless $(n).hasClass("graf--mixtapeEmbed")
821
860
  $(n).removeClass().addClass("graf graf--#{name}")
822
861
 
@@ -837,10 +876,10 @@ class Dante.Editor extends Dante.View
837
876
  n = $(n).parent()
838
877
 
839
878
  when "ol", "ul"
840
- #utils.log "lists"
879
+ utils.log "lists"
841
880
  $(n).removeClass().addClass("postList")
842
881
  _.each $(n).find("li"), (li)->
843
- $(n).removeClass().addClass("graf graf--li")
882
+ $(li).removeClass().addClass("graf graf--li")
844
883
  #postList , and li as graf
845
884
 
846
885
  when "img"
@@ -881,11 +920,11 @@ class Dante.Editor extends Dante.View
881
920
  #clean context and wrap text nodes
882
921
  @cleanContents(@element)
883
922
  @wrapTextNodes(@element)
923
+
884
924
  #setup classes
885
925
  _.each @element.children(), (n)=>
886
926
  name = $(n).prop("tagName").toLowerCase()
887
927
  n = @addClassesToElement(n)
888
-
889
928
  @setElementName(n)
890
929
 
891
930
  @setupLinks(@element.find("a"))
@@ -902,7 +941,7 @@ class Dante.Editor extends Dante.View
902
941
  @element = element
903
942
 
904
943
  s = new Sanitize
905
- elements: ['strong','img', 'em', 'br', 'a', 'blockquote', 'b', 'u', 'i', 'pre', 'p', 'h1', 'h2', 'h3', 'h4']
944
+ elements: ['strong','img', 'em', 'br', 'a', 'blockquote', 'b', 'u', 'i', 'pre', 'p', 'h1', 'h2', 'h3', 'h4', 'ul', 'ol', 'li']
906
945
 
907
946
  attributes:
908
947
  '__ALL__': ['class']
@@ -966,7 +1005,7 @@ class Dante.Editor extends Dante.View
966
1005
  ]
967
1006
 
968
1007
  if @element.exists()
969
- utils.log "CLEAN HTML"
1008
+ utils.log "CLEAN HTML #{@element[0].tagName}"
970
1009
  @element.html(s.clean_node( @element[0] ))
971
1010
 
972
1011
  setupLinks: (elems)->
@@ -981,7 +1020,7 @@ class Dante.Editor extends Dante.View
981
1020
 
982
1021
  preCleanNode: (element)->
983
1022
  s = new Sanitize
984
- elements: ['strong', 'em', 'br', 'a', 'b', 'u', 'i']
1023
+ elements: ['strong', 'em', 'br', 'a', 'b', 'u', 'i', 'ul', 'ol', 'li']
985
1024
 
986
1025
  attributes:
987
1026
  a: ['href', 'title', 'target']
@@ -1012,4 +1051,83 @@ class Dante.Editor extends Dante.View
1012
1051
  ).wrap "<p class='graf grap--p'></p>"
1013
1052
 
1014
1053
  setElementName: (element)->
1015
- $(element).attr("name", utils.generateUniqueName())
1054
+ $(element).attr("name", utils.generateUniqueName())
1055
+
1056
+ #LIST METHODS
1057
+
1058
+ listify: ($paragraph, listType, tagLength)->
1059
+ utils.log "LISTIFY PARAGRAPH"
1060
+ content = $paragraph.html().replace(/&nbsp;/g, " ")
1061
+ utils.log(tagLength)
1062
+
1063
+ content = content.slice(tagLength, content.length)
1064
+
1065
+ switch(listType)
1066
+ when "ul" then $list = $("<ul></ul>")
1067
+ when "ol" then $list = $("<ol></ol>")
1068
+ else return false
1069
+
1070
+ @addClassesToElement($list[0])
1071
+ @replaceWith("li", $paragraph)
1072
+ $li = $(".is-selected")
1073
+
1074
+ @setElementName($li[0])
1075
+
1076
+ $li.html(content).wrap($list)
1077
+
1078
+ if($li.find("br").length == 0)
1079
+ $li.append("<br/>")
1080
+ @setRangeAt($li[0])
1081
+
1082
+ $li[0]
1083
+
1084
+ handleSmartList: ($item, e)->
1085
+ utils.log("HANDLE A SMART LIST")
1086
+ match = $item.text().match(/^\s*(\-|\*)\s*/)
1087
+
1088
+ if match
1089
+ utils.log("CREATING UL LIST ITEM")
1090
+ e.preventDefault()
1091
+ $li = @listify($item, "ul", match[0].length)
1092
+ else if match = $item.text().match(/^\s*1(\.|\))\s*/)
1093
+ utils.log("CREATING OL LIST ITEM")
1094
+ e.preventDefault()
1095
+ $li = @listify($item, "ol", match[0].length)
1096
+
1097
+ $li
1098
+
1099
+ handleListLineBreak: ($li, e)->
1100
+ utils.log("LIST LINE BREAK")
1101
+ e.preventDefault()
1102
+ @tooltip_view.hide()
1103
+ $list = $li.parent("ol, ul")
1104
+ $paragraph = $("<p></p>")
1105
+ if($list.children().length == 1)
1106
+ @replaceWith("p", $list)
1107
+ else if ($li.next().length == 0 and $li.text() == "")
1108
+ $list.after($paragraph)
1109
+ $li.remove()
1110
+
1111
+ @addClassesToElement($paragraph[0])
1112
+ @setRangeAt($paragraph[0])
1113
+ @markAsSelected($paragraph[0])
1114
+ @scrollTo($paragraph)
1115
+
1116
+ handleListBackspace: ($li, e)->
1117
+
1118
+ $list = $li.parent("ol, ul")
1119
+ utils.log("LIST BACKSPACE")
1120
+
1121
+ if($li.prev().length is 0)
1122
+ e.preventDefault()
1123
+
1124
+ $list.before($li)
1125
+ content = $li.html()
1126
+ @replaceWith("p", $li)
1127
+ $paragraph = $(".is-selected")
1128
+ $paragraph.removeClass("graf--empty").html(content)
1129
+
1130
+ if($list.children().length is 0)
1131
+ $list.remove()
1132
+
1133
+ @setupFirstAndLast()
@@ -196,6 +196,9 @@ class Dante.Editor.Menu extends Dante.View
196
196
  if tag.match /(?:h[1-6])/i
197
197
  $(@el).find(".icon-bold, .icon-italic, .icon-blockquote")
198
198
  .parent("li").remove()
199
+ else if tag is "indent"
200
+ $(@el).find(".icon-h2, .icon-h3, .icon-h4, .icon-blockquote")
201
+ .parent("li").remove()
199
202
  #.parent("li").hide()
200
203
  #.addClass("hidden")
201
204
 
@@ -310,19 +310,23 @@ class Dante.Editor.Tooltip extends Dante.View
310
310
  false
311
311
 
312
312
  getEmbedFromNode: (node)=>
313
- @node_name = $(node).attr("name")
314
- $.getJSON("#{@current_editor.oembed_url}#{$(@node).text()}").success (data)=>
315
- @node = $("[name=#{@node_name}]")
316
- iframe_src = $(data.html).prop("src")
317
- tmpl = $(@embedTemplate())
318
- tmpl.attr("name", @node.attr("name"))
319
- $(@node).replaceWith(tmpl)
320
- replaced_node = $(".graf--iframe[name=#{@node.attr("name")}]")
321
- replaced_node.find("iframe").attr("src", iframe_src)
322
- url = data.url || data.author_url
323
- utils.log "URL IS #{url}"
324
- replaced_node.find(".markup--anchor").attr("href", url ).text(url)
325
- @hide()
313
+ @node = $(node)
314
+ @node_name = @node.attr("name")
315
+ @node.addClass("spinner")
316
+
317
+ $.getJSON("#{@current_editor.oembed_url}#{$(@node).text()}")
318
+ .success (data)=>
319
+ @node = $("[name=#{@node_name}]")
320
+ iframe_src = $(data.html).prop("src")
321
+ tmpl = $(@embedTemplate())
322
+ tmpl.attr("name", @node.attr("name"))
323
+ $(@node).replaceWith(tmpl)
324
+ replaced_node = $(".graf--iframe[name=#{@node.attr("name")}]")
325
+ replaced_node.find("iframe").attr("src", iframe_src)
326
+ url = data.url || data.author_url
327
+ utils.log "URL IS #{url}"
328
+ replaced_node.find(".markup--anchor").attr("href", url ).text(url)
329
+ @hide()
326
330
 
327
331
  ##EXTRACT
328
332
  displayExtractPlaceHolder: ()->
@@ -335,7 +339,10 @@ class Dante.Editor.Tooltip extends Dante.View
335
339
  false
336
340
 
337
341
  getExtractFromNode: (node)=>
338
- @node_name = $(node).attr("name")
342
+ @node = $(node)
343
+ @node_name = @node.attr("name")
344
+ @node.addClass("spinner")
345
+
339
346
  $.getJSON("#{@current_editor.extract_url}#{$(@node).text()}").success (data)=>
340
347
  @node = $("[name=#{@node_name}]")
341
348
  iframe_src = $(data.html).prop("src")