dante-editor 0.0.3 → 0.0.4

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.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/README.md +45 -24
  4. data/ROADMAP.md +12 -0
  5. data/TODO.md +1 -17
  6. data/app/assets/javascripts/dante/editor.js.coffee +149 -45
  7. data/app/assets/javascripts/dante/menu.js.coffee +13 -2
  8. data/app/assets/javascripts/dante/tooltip.js.coffee +87 -32
  9. data/app/assets/stylesheets/dante.css.scss +1 -2
  10. data/app/assets/stylesheets/dante/_debug.scss +2 -2
  11. data/app/assets/stylesheets/dante/_graf.scss +141 -68
  12. data/app/assets/stylesheets/dante/_icons.scss +22 -23
  13. data/app/assets/stylesheets/dante/_menu.scss +112 -110
  14. data/app/assets/stylesheets/dante/_needsorder.scss +7 -1
  15. data/app/assets/stylesheets/dante/_post.scss +7 -9
  16. data/app/assets/stylesheets/dante/_scaffold.scss +16 -21
  17. data/app/assets/stylesheets/dante/_tooltip.scss +103 -104
  18. data/app/assets/stylesheets/dante/_utilities.scss +2 -3
  19. data/app/assets/stylesheets/{old → temp}/fonts.css.scss +0 -26
  20. data/app/assets/stylesheets/temp/medium.css +12404 -0
  21. data/app/assets/stylesheets/temp/review.scss +21 -0
  22. data/app/assets/stylesheets/temp/structure.haml +22 -0
  23. data/lib/dante-editor/version.rb +1 -1
  24. data/source/assets/images/dante-logo.png +0 -0
  25. data/source/assets/stylesheets/_scaffold.scss +12 -0
  26. data/source/assets/stylesheets/_tooltips.scss +216 -0
  27. data/source/assets/stylesheets/all.css.scss +51 -26
  28. data/source/embeds.html.erb +13 -15
  29. data/source/index.html.erb +7 -24
  30. data/source/layouts/layout.erb +7 -3
  31. data/source/partials/_content.erb +6 -3
  32. data/source/partials/_example_1.erb +15 -0
  33. data/source/partials/_example_2.erb +1 -2
  34. data/source/partials/_example_3.erb +1 -14
  35. data/source/partials/_readme.markdown +13 -67
  36. data/source/partials/test/_example_1.erb +22 -1
  37. metadata +10 -6
  38. data/app/assets/stylesheets/old/base.css.scss +0 -57
  39. data/app/assets/stylesheets/old/editor.css.scss +0 -662
  40. data/source/readme.html.erb +0 -28
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9d4df3156378b59b7396a2b87162436cb60557e3
4
- data.tar.gz: 517e2d07d9f36c86a648e07123e534a97c57e025
3
+ metadata.gz: 64b4e8827f1fd8a73d53ea8a3d2096428c512777
4
+ data.tar.gz: bfcca07541a5c1b66e5fb750fdb0eb0d9fc3cdd5
5
5
  SHA512:
6
- metadata.gz: 67f9b45f3efd4dd05d92c9adf4eb0cf97d36996be5eb623cc47981d495be4b1546ea080aa948d366d0eaf356f574cc112ccc949b686e65afe7f117b8dc125f7e
7
- data.tar.gz: da1cd87246a7167a9fa0c493ac4da218800b1bd89d58c54c74f4a0749d97bb55ed6ecc216ddd16209d676687b0e085e3af4cb1f1e0cff4621516cd6ec45d5d3e
6
+ metadata.gz: 9e18ede5c0fcb9553798120b174c3cd05f17d8f785870b03c60e78d0e569783123cfcc3504af2b8dcb5a3d05fe5097aaa5d2dca06280e441b3df5304cbab9939
7
+ data.tar.gz: 890dfde37222b9741982b8c31f2b91b137a47bd1c6dea6902e4004c853d2916cd984bd893f109c118d401b46ecee365271058f18f19deab5378ecdb88aeaa234
data/Gemfile CHANGED
@@ -2,7 +2,7 @@
2
2
  # the following line to use "https"
3
3
  source 'http://rubygems.org'
4
4
 
5
- gem "therubyracer"
5
+ #gem "therubyracer"
6
6
  gem "middleman", "~>3.1.4"
7
7
 
8
8
  # Live-reloading plugin
data/README.md CHANGED
@@ -4,28 +4,30 @@
4
4
 
5
5
  ##Motivation:
6
6
 
7
- I´ve tried all the medium clones out there, they are really great and all have it´s pros & cons, but none of them have all the features that medium wysywig provides, so I wonder, how difficult could be build my own Medium clone?
7
+ So far I have tried all the Medium.com wysiwyg clones out there, these are really great, and each have their pros and cons. [But none of them has all the features that the real medium editor provides.](http://howtox.com/medium-editor-clones-in-js/)
8
+ so I wonder, How complicated could be write my own Medium wysiwyg clone?
9
+
10
+ ## Demo:
11
+
12
+ [http://michelson.github.io/Dante/](http://michelson.github.io/Dante/)
8
13
 
9
14
  Until now I´ve been able to implement the following features:
10
15
 
11
16
  ## Features:
12
17
 
13
- + HTML sanitizer when paste text or initial load.
14
- + Image formatting/upload for paste events.
15
- + Add an unique name to elements on page.
16
- + Implementation of the famous tooltip on each paragraph when selected
18
+ + HTML sanitizer for pasted or loaded text.
19
+ + Image upload for paste events.
20
+ + Image upload for legacy images on existent texts.
21
+ + The medium (+) Tooltip to embed or upload media.
17
22
  + Tab navigation.
18
23
  + Embeds:
19
24
  + Image Uploader with *preview* and caption option.
20
25
  + Embed data for pasted link through OEmbed services.
21
26
  + Embed media information for pasted links through OEmbed services.
22
- + CSS tries to use the same fonts used in Medium, if you have setup those fonts, or fallbacks to open fonts (by Google fonts) or system fonts.
27
+ + 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.
23
28
  + serif: freight-text-pro fallbacks to Merriweather or Georgia,
24
29
  + sans: jaf-bernino-sans fallbacks to Open Sans or Lucida Grande
25
30
 
26
- ## Demo:
27
-
28
- [http://michelson.github.io/Dante/](http://michelson.github.io/Dante/)
29
31
 
30
32
  ## Usage:
31
33
 
@@ -55,14 +57,16 @@ Until now I´ve been able to implement the following features:
55
57
 
56
58
  ### Configuration options:
57
59
 
58
- el: default: #editor
59
- debugMode: default: false
60
- upload_url: default: /uploads.json
61
- oembed_url: default: http://api.embed.ly/1/oembed?url="
62
- extract_url: default: http://api.embed.ly/1/extract?url="
63
- store_url: url to store data with interval , defaults to none
64
- store_interval: default: 15000 (15 secs)
65
- default_loading_placeholder: image placeholder to show when uploaded/pasted images are loading , defaults to a grey background
60
+ + **el:** default: #editor
61
+ + **debugMode:** default: false
62
+ + **upload_url:** default: /uploads.json
63
+ + **oembed_url:** default: http://api.embed.ly/1/oembed?url="
64
+ + **extract_url:** default: http://api.embed.ly/1/extract?url="
65
+ + **store_url:** default: to none , url to store data with interval
66
+ + **store_interval:** default: 15000 (15 secs)
67
+ + **spellcheck:** default: false
68
+ + **default_loading_placeholder:** image placeholder to show when uploaded/pasted images are loading , defaults to a grey background
69
+ + **disable_title** default: false , will hide the initial heading placeholder for initial text
66
70
 
67
71
  ### Rails / AssetPippeline
68
72
 
@@ -80,25 +84,27 @@ in Gemfile
80
84
 
81
85
  ## Disclaimer:
82
86
 
83
- This Library will work on early versions of Chrome/Safari/FF/IE.
84
- I don't have any intentions to target all browsers versions, really... if you like this library and need backwards support for an specific version you can submit a patch to help with the development or just upgrade your shitty browser :D
87
+ This Library will work fine on latest versions of Chrome/Safari/FF/IE.
88
+ We don't have any intention to target all browsers versions, really... if you like this library and you need backward compatibility with an specific version you can submit a patch to help with the development or just upgrade your shitty browser :D
89
+
90
+ **BTW , this library is an official beta release, so there are known bugs that we are currently working on.
91
+ see TODO list below.**
85
92
 
86
93
  ## Dependencies:
87
94
 
88
- Some dependencies are required in order to Dante editor to work propperly:
95
+ Some dependencies are required in order to Dante editor works properly:
89
96
 
90
97
  + Jquery
91
98
  + [Underscore](https://github.com/documentcloud/underscore)
92
99
  + [Sanitize.js](https://github.com/gbirke/sanitize.js)
93
100
 
94
101
 
95
- drop underscore and jquery dependencies is on the roadmap.
102
+ **Drop underscore and jquery dependencies are on our roadmap.**
96
103
 
97
104
 
98
105
  ## Development:
99
106
 
100
- There is a development web app middleman/sinatra to work with the source files and make the proper tests.
101
- To use application:
107
+ There is a web app for development to work with the source files and make the proper tests. To use application:
102
108
 
103
109
  ### Installation:
104
110
 
@@ -126,7 +132,22 @@ tests are located in source/tests and /source/assets/spec folder and accessible
126
132
 
127
133
  [read todo](./TODO.md)
128
134
 
135
+ ## MAINTAINERS:
136
+
137
+ + [Miguel Michelson](http://github.com/michelson)
138
+ + [Cristian Ferrari](http://github.com/cristianferrarig)
139
+
140
+ ### Alternatives:
141
+
142
+ + https://github.com/sofish/pen
143
+ + https://github.com/orthes/medium-editor-insert-plugin
144
+
145
+ ### ACKNOWLEDGMENTS:
146
+
147
+ + Inline menu features was written taking some ideas and code from [pen.js](https://github.com/sofish/pen)
148
+ + [Sanitize.js](https://github.com/gbirke/sanitize.js) allows us to clean HTML like pros.
149
+ + No animals were harmed in the making of this ~~film~~ wysiwyg
129
150
 
130
151
  ### LICENSE
131
152
 
132
- Miguel Michelson Martinez [Licensed under MIT.](./license.md) 2014
153
+ [Licensed under MIT.](./license.md) 2014
@@ -0,0 +1,12 @@
1
+ ## ROADMAP
2
+
3
+ + 0.0.5
4
+ + TODO LIST COMPLETE!
5
+ + 0.0.7
6
+ + implement Keyboard Shortcuts / word count / typing tricks
7
+ + 0.1.0
8
+ + implement layout changes on embeds & uploads.
9
+ + 0.2.0
10
+ + implement creation of new sections
11
+ + 1.0.0
12
+ + use Rangy for better selection & range support.
data/TODO.md CHANGED
@@ -3,14 +3,12 @@
3
3
 
4
4
  + GENERALS
5
5
  + FF in case markup breaks (like linebreak with br or unwraped text when typing) just rewrap from current range.
6
- + Check double clicks on first p
7
6
 
8
7
  + SANITIZE PROCESS
9
8
 
10
9
  + MENU
11
10
  + Filter inner tags (except a, b, i ... ) when convert to blockquote
12
- + Reposicionar menu cuando se cambia el tamaño del elemento
13
- + Quitar las opciones B/i cuando el elemento seleccionado es un header
11
+ + blockquote works like crap
14
12
 
15
13
  + DELETE
16
14
  + handle remove from PRE tag, it set rare span, just remove it
@@ -18,7 +16,6 @@
18
16
 
19
17
  + IMAGES:
20
18
  + upload, show progress, complete
21
- + mantain image ratio
22
19
  + handle enter (linebreak) when selected in caption (build new P)
23
20
  + Fix problem in FF when linebreak or arrow down to new P , is typing backwards!! (could be a range 1 char problem ?)
24
21
 
@@ -29,16 +26,3 @@
29
26
  + SUBMIT:
30
27
  get clean version of content
31
28
 
32
-
33
- ## ROADMAP
34
-
35
- + 0.0.5
36
- + TODO LIST COMPLETE!
37
- + 0.1.0
38
- + implement layout changes on embeds & uploads.
39
- + 0.2.0
40
- + implement creation of new sections
41
- + 1.0.0
42
- + use Rangy for better selection & range support.
43
-
44
-
@@ -10,23 +10,29 @@ class Dante.Editor extends Dante.View
10
10
  "keydown" : "handleKeyDown"
11
11
  "keyup" : "handleKeyUp"
12
12
  "paste" : "handlePaste"
13
- "click .graf--figure" : "handleGrafFigureSelect"
13
+ "dblclick" : "handleDblclick"
14
+ "dragstart": "handleDrag"
15
+ "drop" : "handleDrag"
16
+ "click .graf--figure .aspectRatioPlaceholder" : "handleGrafFigureSelectImg"
17
+ "click .graf--figure figcaption" : "handleGrafFigureSelectCaption"
14
18
 
15
19
  initialize: (opts = {})=>
16
20
  @editor_options = opts
17
21
  #globals for selected text and node
18
- @initial_html = $(@el).html()
19
- @current_range = null
20
- @current_node = null
22
+ @initial_html = $(@el).html()
23
+ @current_range = null
24
+ @current_node = null
21
25
  @el = opts.el || "#editor"
26
+ @upload_url = opts.upload_url || "/uploads.json"
27
+ @oembed_url = opts.oembed_url || "http://api.embed.ly/1/oembed?url="
28
+ @extract_url = opts.extract_url || "http://api.embed.ly/1/extract?key=86c28a410a104c8bb58848733c82f840&url="
29
+ @default_loading_placeholder = opts.default_loading_placeholder || Dante.defaults.image_placeholder
30
+ @store_url = opts.store_url
31
+ @spell_check = opts.spellcheck || false
32
+ @disable_title = opts.disable_title || false
33
+ @store_interval = opts.store_interval || 15000
22
34
  window.debugMode = opts.debug || false
23
35
  $(@el).addClass("debug") if window.debugMode
24
- @upload_url = opts.upload_url || "/uploads.json"
25
- @oembed_url = opts.oembed_url || "http://api.embed.ly/1/oembed?url="
26
- @extract_url = opts.extract_url || "http://api.embed.ly/1/extract?key=86c28a410a104c8bb58848733c82f840&url="
27
- @default_loading_placeholder = opts.default_loading_placeholder || Dante.defaults.image_placeholder
28
- @store_url = opts.store_url
29
- @store_interval = opts.store_interval || 15000
30
36
  if (localStorage.getItem('contenteditable'))
31
37
  $(@el).html localStorage.getItem('contenteditable')
32
38
 
@@ -64,6 +70,9 @@ class Dante.Editor extends Dante.View
64
70
  getContent: ()->
65
71
  $(@el).find(".section-inner").html()
66
72
 
73
+ renderTitle: ()->
74
+ "<h3 class='graf graf--h3'>#{@title_placeholder} </h3>"
75
+
67
76
  template: ()=>
68
77
  "<section class='section--first section--last'>
69
78
 
@@ -73,7 +82,7 @@ class Dante.Editor extends Dante.View
73
82
 
74
83
  <div class='section-content'>
75
84
  <div class='section-inner'>
76
- <h3 class='graf graf--h3'>#{@title_placeholder}</h3>
85
+ #{if @disable_title then '' else @renderTitle()}
77
86
  <p class='graf graf--p'>#{@body_placeholder}<p>
78
87
  </div>
79
88
  </div>
@@ -92,15 +101,17 @@ class Dante.Editor extends Dante.View
92
101
 
93
102
  appendInitialContent: ()=>
94
103
  $(@el).find(".section-inner").html(@initial_html)
104
+ $(@el).attr("spellcheck", @spell_check)
95
105
 
96
106
  start: ()=>
97
107
  @render()
98
108
  $(@el).attr("contenteditable", "true")
99
- $(@el).addClass("postField--body")
100
- $(@el).wrap("<div class='notesSource'></div>")
109
+ $(@el).addClass("postField postField--body editable smart-media-plugin")
110
+ $(@el).wrap("<div class='postContent'><div class='notesSource'></div></div>")
101
111
  @appendMenus()
102
112
  @appendInitialContent() unless _.isEmpty @initial_html.trim()
103
- @setupElementsClasses()
113
+ @parseInitialMess()
114
+
104
115
 
105
116
  restart: ()=>
106
117
  @render()
@@ -226,6 +237,7 @@ class Dante.Editor extends Dante.View
226
237
  (if root && root.contains(node) then node else null)
227
238
 
228
239
  displayMenu: (sel)->
240
+ #return if _.isUndefined sel
229
241
  setTimeout ()=>
230
242
  @editor_menu.render()
231
243
  pos = utils.getSelectionDimensions()
@@ -233,14 +245,16 @@ class Dante.Editor extends Dante.View
233
245
  @editor_menu.show()
234
246
  , 10
235
247
 
248
+ handleDrag: ()->
249
+ return false
250
+
236
251
  #get text of selected and displays menu
237
252
  handleTextSelection: (anchor_node)->
238
253
  @editor_menu.hide()
239
254
  text = @getSelectedText()
240
- unless _.isEmpty text.trim()
241
- #@current_range = @getRange()
242
- @current_node = anchor_node
243
- @.displayMenu()
255
+ if !$(anchor_node).is(".graf--mixtapeEmbed, .graf--figure") && !_.isEmpty text.trim()
256
+ @current_node = anchor_node
257
+ @.displayMenu()
244
258
 
245
259
  relocateMenu: (position)->
246
260
  height = @editor_menu.$el.outerHeight()
@@ -256,10 +270,19 @@ class Dante.Editor extends Dante.View
256
270
  $(".graf--first").html(@title_placeholder)
257
271
  $(".graf--last").html(@body_placeholder)
258
272
 
259
- handleGrafFigureSelect: (ev)->
273
+ handleGrafFigureSelectImg: (ev)->
274
+ utils.log "FIGURE SELECT"
260
275
  element = ev.currentTarget
261
276
  @markAsSelected( element )
262
- @setRangeAt( $(element).find('.imageCaption')[0] )
277
+ $(element).parent(".graf--figure").addClass("is-selected is-mediaFocused")
278
+ @selection().removeAllRanges()
279
+
280
+ handleGrafFigureSelectCaption: (ev)->
281
+ utils.log "FIGCAPTION"
282
+ element = ev.currentTarget
283
+ $(element).parent(".graf--figure").removeClass("is-mediaFocused")
284
+ #return false
285
+ #@setRangeAt( $(element).find('.imageCaption')[0] )
263
286
 
264
287
  handleBlur: (ev)=>
265
288
  #hide menu only if is not in use
@@ -272,9 +295,13 @@ class Dante.Editor extends Dante.View
272
295
  handleMouseUp: (ev)=>
273
296
  utils.log "MOUSE UP"
274
297
  anchor_node = @getNode()
275
- utils.log anchor_node
276
- utils.log ev.currentTarget
298
+ #utils.log anchor_node
299
+ #utils.log ev.currentTarget
300
+
277
301
  return if _.isNull(anchor_node)
302
+
303
+ @prev_current_node = anchor_node
304
+
278
305
  @handleTextSelection(anchor_node)
279
306
  @hidePlaceholder(anchor_node)
280
307
  @markAsSelected( anchor_node )
@@ -292,13 +319,14 @@ class Dante.Editor extends Dante.View
292
319
  #handle arrow direction from keyUp.
293
320
  handleArrow: (ev)=>
294
321
  current_node = $(@getNode())
295
- if current_node
322
+ if current_node.length > 0
296
323
  @markAsSelected( current_node )
297
324
  @displayTooltipAt( current_node )
298
325
 
299
326
  #handle arrow direction from keyDown.
300
327
  handleArrowForKeyDown: (ev)=>
301
- current_node = $(@getNode())
328
+ caret_node = @getNode()
329
+ current_node = $(caret_node)
302
330
  utils.log(ev)
303
331
  ev_type = ev.originalEvent.key || ev.originalEvent.keyIdentifier
304
332
 
@@ -308,22 +336,32 @@ class Dante.Editor extends Dante.View
308
336
  switch ev_type
309
337
 
310
338
  when "Down"
339
+ #when graff-image selected but none selection is found
340
+ #debugger
341
+ if _.isUndefined(current_node) or !current_node.exists()
342
+ if $(".is-selected").exists()
343
+ current_node = $(".is-selected")
344
+
311
345
  next_node = current_node.next()
346
+
312
347
  utils.log "NEXT NODE IS #{next_node.attr('class')}"
313
348
  utils.log "CURRENT NODE IS #{current_node.attr('class')}"
314
349
 
315
350
  return unless $(current_node).hasClass("graf")
316
- return unless $(current_node).editableCaretOnLastLine()
351
+ return unless current_node.hasClass("graf--figure") or $(current_node).editableCaretOnLastLine()
317
352
 
318
353
  utils.log "ENTER ARROW PASSED RETURNS"
319
354
 
320
355
  #if next element is embed select & focus it
321
- if next_node.hasClass("graf--figure")
356
+ if next_node.hasClass("graf--figure") && caret_node
322
357
  n = next_node.find(".imageCaption")
323
358
  @setRangeAt n[0]
324
359
  @scrollTo(n)
325
360
  utils.log "1 down"
326
361
  utils.log n[0]
362
+ @skip_keyup = true
363
+ @selection().removeAllRanges()
364
+ #@markAsSelected(next_node)
327
365
  next_node.addClass("is-mediaFocused is-selected")
328
366
  return false
329
367
  #if current node is embed
@@ -336,19 +374,13 @@ class Dante.Editor extends Dante.View
336
374
  return false
337
375
 
338
376
  if current_node.hasClass("graf--figure") && next_node.hasClass("graf")
339
- @setRangeAt next_node[0]
340
377
  @scrollTo(next_node)
341
- utils.log "3 down"
378
+ utils.log "3 down, from figure to next graf"
379
+ #@skip_keyup = true
380
+ @markAsSelected(next_node)
381
+ @setRangeAt next_node[0]
342
382
  return false
343
383
 
344
- ###
345
- else if next_node.hasClass("graf")
346
- n = current_node.next(".graf")
347
- @setRangeAt n[0]
348
- @scrollTo(n)
349
- false
350
- ###
351
-
352
384
  when "Up"
353
385
  prev_node = current_node.prev()
354
386
  utils.log "PREV NODE IS #{prev_node.attr('class')}"
@@ -362,8 +394,10 @@ class Dante.Editor extends Dante.View
362
394
  if prev_node.hasClass("graf--figure")
363
395
  utils.log "1 up"
364
396
  n = prev_node.find(".imageCaption")
365
- @setRangeAt n[0]
397
+ #@setRangeAt n[0]
366
398
  @scrollTo(n)
399
+ @skip_keyup = true
400
+ @selection().removeAllRanges()
367
401
  prev_node.addClass("is-mediaFocused is-selected")
368
402
  return false
369
403
 
@@ -384,13 +418,27 @@ class Dante.Editor extends Dante.View
384
418
  else if prev_node.hasClass("graf")
385
419
  n = current_node.prev(".graf")
386
420
  num = n[0].childNodes.length
387
- @setRangeAt n[0], num
421
+ #@setRangeAt n[0], num
388
422
  @scrollTo(n)
389
423
  utils.log "4 up"
424
+ @skip_keyup = true
425
+ #debugger
390
426
  return false
391
427
 
392
428
  utils.log "noting"
393
429
 
430
+ #parse text for initial mess
431
+ parseInitialMess: ()->
432
+ @setupElementsClasses $(@el).find('.section-inner') , ()=>
433
+ @handleUnwrappedImages($(@el).find('.section-inner'))
434
+
435
+ handleDblclick: ()->
436
+ utils.log "handleDblclick"
437
+ node = @getNode()
438
+ if _.isNull node
439
+ @setRangeAt(@prev_current_node)
440
+ return false
441
+
394
442
  #detects html data , creates a hidden node to paste ,
395
443
  #then clean up the content and copies to currentNode, very clever uh?
396
444
  handlePaste: (ev)=>
@@ -634,6 +682,15 @@ class Dante.Editor extends Dante.View
634
682
  if $(anchor_node).prev().hasClass("graf--mixtapeEmbed")
635
683
  return false if @isFirstChar() && !_.isEmpty( $(anchor_node).text().trim() )
636
684
 
685
+ utils.log "sss"
686
+ utils.log anchor_node
687
+ if $(".is-selected").hasClass("graf--figure")
688
+ @replaceWith("p", $(".is-selected"))
689
+ @setRangeAt($(".is-selected")[0])
690
+ return false
691
+
692
+
693
+
637
694
  #arrows key
638
695
  #if _.contains([37,38,39,40], e.which)
639
696
  #up & down
@@ -644,9 +701,24 @@ class Dante.Editor extends Dante.View
644
701
 
645
702
  #hides tooltip if anchor_node text is empty
646
703
  if anchor_node
647
- @tooltip_view.hide() unless _.isEmpty($(anchor_node).text())
704
+ unless _.isEmpty($(anchor_node).text())
705
+ @tooltip_view.hide()
706
+ $(anchor_node).removeClass("graf--empty")
707
+
708
+ #when user types over a selected image (graf--figure)
709
+ #unselect image , and set range on caption
710
+ if _.isUndefined(anchor_node) && $(".is-selected").hasClass("is-mediaFocused")
711
+ @setRangeAt $(".is-selected").find("figcaption")[0]
712
+ $(".is-selected").removeClass("is-mediaFocused")
713
+ return false
648
714
 
649
715
  handleKeyUp: (e , node)->
716
+
717
+ if @skip_keyup
718
+ @skip_keyup = null
719
+ utils.log "SKIP KEYUP"
720
+ return
721
+
650
722
  utils.log "KEYUP"
651
723
 
652
724
  @editor_menu.hide() #hides menu just in case
@@ -701,6 +773,12 @@ class Dante.Editor extends Dante.View
701
773
  @setRangeAt(new_paragraph[0])
702
774
  @scrollTo new_paragraph
703
775
 
776
+ replaceWith: (element_type, from_element)->
777
+ new_paragraph = $("<#{element_type} class='graf graf--#{element_type} graf--empty is-selected'><br/></#{element_type}>")
778
+ from_element.replaceWith(new_paragraph)
779
+ @setRangeAt(new_paragraph[0])
780
+ @scrollTo new_paragraph
781
+
704
782
  #shows the (+) tooltip at current element
705
783
  displayTooltipAt: (element)->
706
784
  utils.log ("POSITION FOR TOOLTIP")
@@ -720,8 +798,19 @@ class Dante.Editor extends Dante.View
720
798
  $(@el).find(".is-selected").removeClass("is-mediaFocused is-selected")
721
799
  $(element).addClass("is-selected")
722
800
 
801
+ ###
723
802
  if $(element).prop("tagName").toLowerCase() is "figure"
724
803
  $(element).addClass("is-mediaFocused")
804
+ n = utils.getNode()
805
+ utils.log n
806
+
807
+ n = utils.getNode()
808
+ utils.log n
809
+ if _.isUndefined n
810
+ $(element).addClass("is-mediaFocused")
811
+ else if $(n).prop("tagName").toLowerCase() is "figcaption"
812
+ $(element).removeClass("is-mediaFocused")
813
+ ###
725
814
 
726
815
  $(element).find(".defaultValue").remove()
727
816
  #set reached top if element is first!
@@ -733,7 +822,7 @@ class Dante.Editor extends Dante.View
733
822
  n = element
734
823
  name = n.nodeName.toLowerCase()
735
824
  switch name
736
- when "p", "h1", "h2", "h3", "h4", "h5", "h6", "pre", "div"
825
+ when "p", "pre", "div"
737
826
  #utils.log n
738
827
  unless $(n).hasClass("graf--mixtapeEmbed")
739
828
  $(n).removeClass().addClass("graf graf--#{name}")
@@ -741,6 +830,14 @@ class Dante.Editor extends Dante.View
741
830
  if name is "p" and $(n).find("br").length is 0
742
831
  $(n).append("<br>")
743
832
 
833
+ when "h1", "h2", "h3", "h4", "h5", "h6"
834
+ if name is "h1"
835
+ new_el = $("<h2 class='graf graf--h2'>#{$(n).text()}</h2>")
836
+ $(n).replaceWith(new_el)
837
+ @setElementName(n)
838
+ else
839
+ $(n).removeClass().addClass("graf graf--#{name}")
840
+
744
841
  when "code"
745
842
  #utils.log n
746
843
  $(n).unwrap().wrap("<p class='graf graf--pre'></p>")
@@ -755,14 +852,12 @@ class Dante.Editor extends Dante.View
755
852
 
756
853
  when "img"
757
854
  utils.log "images"
758
- #@handleUnwrappedImages(n)
759
- #@handleUnwrappedImages(nodes)
760
855
  @tooltip_view.uploadExistentImage(n)
761
856
  #set figure non editable
762
857
 
763
858
  when "a", 'strong', 'em', 'br', 'b', 'u', 'i'
764
859
  utils.log "links"
765
- $(n).wrap("<p class='graf graf--#{name}'></p>")
860
+ $(n).wrap("<p class='graf graf--p'></p>")
766
861
  n = $(n).parent()
767
862
  #dont know
768
863
 
@@ -771,6 +866,9 @@ class Dante.Editor extends Dante.View
771
866
  #$(n).find("p").unwrap()
772
867
  n = $(n).removeClass().addClass("graf graf--#{name}")
773
868
 
869
+ when "figure"
870
+ if $(n).hasClass(".graf--figure")
871
+ n = $(n)
774
872
  else
775
873
  #TODO: for now leave this relaxed, because this is
776
874
  #overwriting embeds
@@ -811,7 +909,7 @@ class Dante.Editor extends Dante.View
811
909
  @element = element
812
910
 
813
911
  s = new Sanitize
814
- elements: ['strong','img', 'em', 'br', 'a', 'blockquote', 'b', 'u', 'i', 'pre', 'p', 'h2', 'h3']
912
+ elements: ['strong','img', 'em', 'br', 'a', 'blockquote', 'b', 'u', 'i', 'pre', 'p', 'h1', 'h2', 'h3', 'h4']
815
913
 
816
914
  attributes:
817
915
  '__ALL__': ['class']
@@ -853,7 +951,10 @@ class Dante.Editor extends Dante.View
853
951
  if(input.node_name == 'figure' && $(input.node).hasClass("graf--figure") )
854
952
  return whitelist_nodes: [input.node]
855
953
 
856
- else if(input.node_name == 'div' && ($(input.node).hasClass("aspect-ratio-fill") || $(input.node).hasClass("aspectRatioPlaceholder")) && $(input.node).parent(".graf--figure").exists() )
954
+ else if(input.node_name == 'div' && ( $(input.node).hasClass("aspectRatioPlaceholder") && $(input.node).parent(".graf--figure").exists() ))
955
+ return whitelist_nodes: [input.node]
956
+
957
+ else if(input.node_name == 'div' && ( $(input.node).hasClass("aspect-ratio-fill") && $(input.node).parent(".aspectRatioPlaceholder").exists() ))
857
958
  return whitelist_nodes: [input.node]
858
959
 
859
960
  else if(input.node_name == 'img' && $(input.node).parent(".graf--figure").exists() )
@@ -862,6 +963,9 @@ class Dante.Editor extends Dante.View
862
963
  else if(input.node_name == 'a' && $(input.node).parent(".graf--mixtapeEmbed").exists() )
863
964
  return attr_whitelist: ["style"]
864
965
 
966
+ else if(input.node_name == 'figcaption' && $(input.node).parent(".graf--figure").exists())
967
+ return whitelist_nodes: [input.node]
968
+
865
969
  else if(input.node_name == 'span' && $(input.node).parent(".imageCaption").exists())
866
970
  return whitelist_nodes: [input.node]
867
971
  else