dante-editor 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
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")