dante-editor 0.0.15 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +1 -1
  3. data/README.md +49 -10
  4. data/app/assets/fonts/dante/dante.eot +0 -0
  5. data/app/assets/fonts/dante/dante.svg +9 -5
  6. data/app/assets/fonts/dante/dante.ttf +0 -0
  7. data/app/assets/fonts/dante/dante.woff +0 -0
  8. data/app/assets/javascripts/dante/behavior.js.coffee +2 -0
  9. data/app/assets/javascripts/dante/behaviors/image.js.coffee +56 -0
  10. data/app/assets/javascripts/dante/behaviors/list.js.coffee +150 -0
  11. data/app/assets/javascripts/dante/behaviors/save.js.coffee +40 -0
  12. data/app/assets/javascripts/dante/behaviors/suggest.js.coffee +118 -0
  13. data/app/assets/javascripts/dante/editor.js.coffee +110 -228
  14. data/app/assets/javascripts/dante/popover.js.coffee +350 -11
  15. data/app/assets/javascripts/dante/tooltip_widgets/uploader.js.coffee +2 -2
  16. data/app/assets/javascripts/dante.js +5 -0
  17. data/app/assets/stylesheets/dante/_blame.scss +209 -0
  18. data/app/assets/stylesheets/dante/_caption.scss +14 -0
  19. data/app/assets/stylesheets/dante/_icons.scss +10 -5
  20. data/app/assets/stylesheets/dante/_menu.scss +7 -7
  21. data/app/assets/stylesheets/dante/_popover.scss +122 -44
  22. data/app/assets/stylesheets/dante/_utilities.scss +5 -1
  23. data/app/assets/stylesheets/dante/_variables.scss +7 -3
  24. data/app/assets/stylesheets/dante.scss +2 -0
  25. data/config.rb +5 -4
  26. data/dist/css/dante-editor.css +246 -44
  27. data/dist/fonts/dante/dante.eot +0 -0
  28. data/dist/fonts/dante/dante.svg +9 -5
  29. data/dist/fonts/dante/dante.ttf +0 -0
  30. data/dist/fonts/dante/dante.woff +0 -0
  31. data/dist/js/dante-editor.js +1015 -283
  32. data/lib/dante-editor/version.rb +1 -1
  33. data/source/api/cristian.json.erb +8 -0
  34. data/source/api/miguel.json.erb +8 -0
  35. data/source/api/resource.json.erb +8 -0
  36. data/source/api/save.json.erb +1 -0
  37. data/source/api/suggest.json.erb +22 -0
  38. data/source/assets/images/dante-demo.png +0 -0
  39. data/source/icons/image-center.svg +12 -0
  40. data/source/icons/image-fill.svg +11 -0
  41. data/source/icons/image-left.svg +15 -0
  42. data/source/icons/image-wide.svg +12 -0
  43. data/source/index.html.erb +6 -0
  44. data/source/partials/_readme.markdown +2 -2
  45. metadata +18 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 036b0962f6c62dfbb8adfaa70226e82e00704d72
4
- data.tar.gz: 4627b7d2aeed8182c06623ecf06201b7bb4e0fee
3
+ metadata.gz: 73da3d8fd1e1f91d98447623572bc34f01875b6c
4
+ data.tar.gz: 119bfee12fff5d4ed905ff0bf3a2b96c32bc1eb4
5
5
  SHA512:
6
- metadata.gz: 2523312b683c0522a5700112f0b76511ecfdcd1c5008fb15fe246239b84077dd9719b1e435d949f73f1afd6d0472f5f5a492072b7161cbba602e24be2d450a56
7
- data.tar.gz: 5673e8fc5e58d7686e09f5400ae137b08beaa3328ecbbb88a28c2cb45168819dca89e8a0dec707a61ce06677827c1dede5619e9aed31ce19f15905b7ae1e1b39
6
+ metadata.gz: 5ee9aa76441e57c48f1076c7a15fe89b7fd487e556c4f468a566ca2ed4143274e2c1fc2a631aa6e270c6c5ea7b5c3692583123630b6ff2edfd5851521f22eaa3
7
+ data.tar.gz: 2fabadbecdae53b7fd83614bae1cd41cbe8fa39ee8d1abb8520521b7effb960e4234b614f2a93ea55243cac62b9cc72881698440937bc3335dcadac129b8a64a
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- dante-editor (0.0.15)
4
+ dante-editor (0.1.0)
5
5
 
6
6
  GEM
7
7
  remote: http://rubygems.org/
data/README.md CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  [![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/michelson/Dante?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
4
4
 
5
+ (This library is free and will stay free, but needs your support to sustain its development. There are lots of desirable new features and maintenance to do. If you work for a company using Dante or have the means to do so, please consider financial support)
6
+
7
+ [![PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=QVH5DXB326YQG)
8
+
5
9
  ####Just another Medium editor clone.
6
10
 
7
11
  ##Motivation:
@@ -27,6 +31,7 @@ Until now I´ve been able to implement the following features:
27
31
  + Embed data for pasted link through OEmbed services.
28
32
  + Embed media information for pasted links through OEmbed services.
29
33
  + Add or remove tooltip buttons with ease with plugin system.
34
+ + Suggest data when type @
30
35
  + List creation with shorcuts ie:. 1. , - , 1) with spacebar or return key
31
36
  + Custom tooltip bottons support
32
37
  + 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.
@@ -62,25 +67,47 @@ Until now I´ve been able to implement the following features:
62
67
 
63
68
  ### Configuration options:
64
69
 
70
+ #### Basic:
65
71
  + **el:** default: #editor
66
72
  + **debug:** default: false
67
- + **upload_url:** default: /uploads.json
68
- + **upload_callback** default: empty, allows optional way to handle the server response when image is uploaded This is useful when you don't have control on the backend response.
69
- + **oembed_url:** default: http://api.embed.ly/1/oembed?url="
70
- + **extract_url:** default: http://api.embed.ly/1/extract?url="
71
- + **store_url:** default: to none , url to store data with interval
72
- + **store_method** default: to POST , http verb to use when store_url is present.
73
- + **store_interval:** default: 15000 (15 secs), used when store_url is present.
74
73
  + **spellcheck:** default: false
75
74
  + **default_loading_placeholder:** image placeholder to show when uploaded/pasted images are loading , defaults to a grey background
76
75
  + **disable_title** default: false, will hide the initial heading placeholder for initial text
77
76
  + **title_placeholder** default: 'Title'
78
77
  + **title** default: none, pass a pre-existing title to the editor here
79
78
  + **body_placeholder** default: 'Tell your story…'
79
+
80
+ #### Widgets & Tooltips
81
+ + **base_widgets:** default: ["uploader", "embed", "embed-extract"],
82
+ + **extra_tooltip_widgets:** an array of new Dante.TooltipWidget instances.
83
+
84
+ #### Behaviors
85
+ + **base_behaviors:** default: ["save", "image","list", "suggest"]
86
+ + **extra_behaviors:** an array of new Dante.Behavior instances.
87
+
88
+ #### Store Behavior:
89
+ + **store_url:** default: to none , url to store data with interval
90
+ + **store_method** default: to POST , http verb to use when store_url is present.
91
+ + **store_success_handler** default: to none. Option to set a function to handle success response for save operation, works only if store_url is present.
92
+ + **store_interval:** default: 1500 (1.5 secs), used when store_url is present.
93
+
94
+ #### Uploader:
95
+ + **upload_url:** default: /uploads.json
96
+ + **upload_callback** default: empty, allows optional way to handle the server response when image is uploaded This is useful when you don't have control on the backend response.
97
+
98
+ #### Embed tool:
99
+ + **oembed_url:** default: http://api.embed.ly/1/oembed?url="
100
+ + **extract_url:** default: http://api.embed.ly/1/extract?url="
80
101
  + **embed_placeholder** default: 'Paste a YouTube, Vine, Vimeo, or other video link, and press Enter'
81
102
  + **extract_placeholder** default: 'Paste a link to embed content from another site (e.g. Twitter) and press Enter'
82
- + **base_widgets:** default: ["uploader", "embed", "embed-extract"],
83
- + **extra_tooltip_widgets:** and array of new Dante.TooltipWidget instances.
103
+
104
+ #### Suggest Behavior (new!)
105
+ + **suggest_url**: default: "/api/suggest.json"
106
+ + **suggest_query_param:** default: "q"
107
+ + **suggest_query_timeout:** default: 300
108
+ + **suggest_handler:** default: none. Handler function to handle response of suggest request
109
+ + **suggest_resource_handler:** default: null. Handler function to handle the selected resource (when hover a link)
110
+
84
111
 
85
112
  ### Initialization
86
113
 
@@ -91,7 +118,9 @@ Until now I´ve been able to implement the following features:
91
118
  Use the following code to get your text into the Dante editor's body:
92
119
  ```html
93
120
 
94
- <div id="editor editable" > <%= clean_dante_post( @post.excerpt ).try(:html_safe) %> </div>
121
+ <div id="editor editable" >
122
+ <%= @post.excerpt %>
123
+ </div>
95
124
 
96
125
  ```
97
126
 
@@ -109,6 +138,16 @@ in Gemfile
109
138
 
110
139
  ```//= require 'dante'```
111
140
 
141
+
142
+ ## Donate
143
+
144
+ **Can I donate to support the development of Dante Editor?**
145
+
146
+ [![PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=QVH5DXB326YQG)
147
+
148
+ if you want to donate you will enable us to spend more time improving the library and we will be greatly thankful with you. If your company uses Dante please consider making a contribution. We are available for hire to work on or with Dante. Thanks!
149
+
150
+
112
151
  ## Disclaimer:
113
152
 
114
153
  This Library will work fine on latest versions of Chrome/Safari/FF/IE.
Binary file
@@ -6,9 +6,13 @@
6
6
  <font id="icomoon" horiz-adv-x="1024">
7
7
  <font-face units-per-em="1024" ascent="960" descent="-64" />
8
8
  <missing-glyph horiz-adv-x="1024" />
9
- <glyph unicode="&#x20;" d="" horiz-adv-x="512" />
10
- <glyph unicode="&#xe600;" d="M256 759.559v-623.174c0-70.118 47.316-95.291 105.683-55.222l428.634 294.258c58.622 40.244 58.367 105.034 0 145.103l-428.634 294.258c-58.622 40.244-105.683 15.345-105.683-55.222zM320 766.664l426.195-293.488c30.527-20.25 29.832-31 0-51.070l-426.195-295.039v639.598z" />
11
- <glyph unicode="&#xe601;" d="M294.4 768l0.489 2.446c13.868 69.342 82.599 125.554 152.977 125.554h128.267c70.619 0 139.014-55.74 152.977-125.554l0.489-2.446h166.78c70.483 0 127.62-57.611 127.62-127.489v-449.022c0-70.41-57.249-127.489-127.62-127.489h-768.76c-70.483 0-127.62 57.611-127.62 127.489v449.022c0 70.41 57.249 127.489 127.62 127.489h166.78zM347.123 704h-218.685c-35.641 0-64.438-28.583-64.438-63.843v-448.314c0-35.279 28.85-63.843 64.438-63.843h767.124c35.641 0 64.438 28.583 64.438 63.843v448.314c0 35.279-28.85 63.843-64.438 63.843h-218.816l-13.864 65.375c-7.263 34.25-41.874 62.625-77.145 62.625h-147.627c-35.433 0-69.805-28.038-77.134-62.625l-13.853-65.375zM320 448c0-105.823 85.961-192 192-192 105.823 0 192 85.961 192 192 0 105.823-85.961 192-192 192-105.823 0-192-85.961-192-192zM384 448c0 70.692 56.815 128 128 128 70.692 0 128-56.815 128-128 0-70.692-56.815-128-128-128-70.692 0-128 56.815-128 128z" />
12
- <glyph unicode="&#xe602;" d="M544 416v-375.294c0-17.673-14.327-32-32-32s-32 14.327-32 32v375.294h-375.294c-17.673 0-32 14.327-32 32s14.327 32 32 32h375.294v375.294c0 17.673 14.327 32 32 32s32-14.327 32-32v-375.294h375.294c17.673 0 32-14.327 32-32s-14.327-32-32-32h-375.294z" />
13
- <glyph unicode="&#xe603;" d="M882.24 449.498l-235.855 234.241c-12.497 12.411-12.497 32.534 0 44.945s32.758 12.411 45.255 0l253.704-251.968c1.872-1.201 3.645-2.616 5.284-4.244 12.497-12.411 12.497-32.534 0-44.945l-257.992-256.226c-12.497-12.411-32.758-12.411-45.255 0s-12.497 32.534 0 44.945l234.859 233.252zM67.842 461.229c-6.562-12.128-4.719-27.599 5.53-37.848 2.863-2.863 6.133-5.070 9.624-6.621l249.364-249.364c12.497-12.497 32.758-12.497 45.255 0s12.497 32.758 0 45.255l-234.859 234.859 233.863 233.863c12.497 12.497 12.497 32.758 0 45.255s-32.758 12.497-45.255 0l-251.712-251.712c-1.872-1.209-3.645-2.634-5.284-4.273-2.805-2.805-4.981-6.002-6.527-9.414v0 0z" />
9
+ <glyph unicode="&#x20;" horiz-adv-x="512" d="" />
10
+ <glyph unicode="&#xe600;" glyph-name="video" d="M256 759.559v-623.174c0-70.118 47.316-95.291 105.683-55.222l428.634 294.258c58.622 40.244 58.367 105.034 0 145.103l-428.634 294.258c-58.622 40.244-105.683 15.345-105.683-55.222zM320 766.664l426.195-293.488c30.527-20.25 29.832-31 0-51.070l-426.195-295.039v639.598z" />
11
+ <glyph unicode="&#xe601;" glyph-name="image" d="M294.4 768l0.489 2.446c13.868 69.342 82.599 125.554 152.977 125.554h128.267c70.619 0 139.014-55.74 152.977-125.554l0.489-2.446h166.78c70.483 0 127.62-57.611 127.62-127.489v-449.022c0-70.41-57.249-127.489-127.62-127.489h-768.76c-70.483 0-127.62 57.611-127.62 127.489v449.022c0 70.41 57.249 127.489 127.62 127.489h166.78zM347.123 704h-218.685c-35.641 0-64.438-28.583-64.438-63.843v-448.314c0-35.279 28.85-63.843 64.438-63.843h767.124c35.641 0 64.438 28.583 64.438 63.843v448.314c0 35.279-28.85 63.843-64.438 63.843h-218.816l-13.864 65.375c-7.263 34.25-41.874 62.625-77.145 62.625h-147.627c-35.433 0-69.805-28.038-77.134-62.625l-13.853-65.375zM320 448c0-105.823 85.961-192 192-192 105.823 0 192 85.961 192 192 0 105.823-85.961 192-192 192-105.823 0-192-85.961-192-192zM384 448c0 70.692 56.815 128 128 128 70.692 0 128-56.815 128-128 0-70.692-56.815-128-128-128-70.692 0-128 56.815-128 128z" />
12
+ <glyph unicode="&#xe602;" glyph-name="plus" d="M544 416v-375.294c0-17.673-14.327-32-32-32s-32 14.327-32 32v375.294h-375.294c-17.673 0-32 14.327-32 32s14.327 32 32 32h375.294v375.294c0 17.673 14.327 32 32 32s32-14.327 32-32v-375.294h375.294c17.673 0 32-14.327 32-32s-14.327-32-32-32h-375.294z" />
13
+ <glyph unicode="&#xe603;" glyph-name="embed" d="M882.24 449.498l-235.855 234.241c-12.497 12.411-12.497 32.534 0 44.945s32.758 12.411 45.255 0l253.704-251.968c1.872-1.201 3.645-2.616 5.284-4.244 12.497-12.411 12.497-32.534 0-44.945l-257.992-256.226c-12.497-12.411-32.758-12.411-45.255 0s-12.497 32.534 0 44.945l234.859 233.252zM67.842 461.229c-6.562-12.128-4.719-27.599 5.53-37.848 2.863-2.863 6.133-5.070 9.624-6.621l249.364-249.364c12.497-12.497 32.758-12.497 45.255 0s12.497 32.758 0 45.255l-234.859 234.859 233.863 233.863c12.497 12.497 12.497 32.758 0 45.255s-32.758 12.497-45.255 0l-251.712-251.712c-1.872-1.209-3.645-2.634-5.284-4.273-2.805-2.805-4.981-6.002-6.527-9.414v0 0z" />
14
+ <glyph unicode="&#xe900;" glyph-name="image-center" horiz-adv-x="1152" d="M128 128h896v-96h-896v96zM128 704h896v-480h-896v480zM128 896h896v-96h-896v96z" />
15
+ <glyph unicode="&#xe901;" glyph-name="image-fill" horiz-adv-x="1152" d="M128 128h896v-96h-896v96zM0 896h1152v-672h-1152v672z" />
16
+ <glyph unicode="&#xe902;" glyph-name="image-left" horiz-adv-x="1152" d="M256 128h896v-96h-896v96zM768 320h384v-96h-384v96zM0 704h672v-480h-672v480zM768 512h384v-96h-384v96zM768 704h384v-96h-384v96zM256 896h896v-96h-896v96z" />
17
+ <glyph unicode="&#xe903;" glyph-name="image-wide" horiz-adv-x="1152" d="M128 128h896v-96h-896v96zM0 704h1152v-480h-1152v480zM128 896h896v-96h-896v96z" />
14
18
  </font></defs></svg>
Binary file
Binary file
@@ -0,0 +1,2 @@
1
+ class Dante.View.Behavior extends Dante.View
2
+ # nothing here
@@ -0,0 +1,56 @@
1
+ utils = Dante.utils
2
+
3
+ class Dante.View.Behavior.Image extends Dante.View.Behavior
4
+
5
+ events:
6
+ "click .graf--figure .aspectRatioPlaceholder" : "handleGrafFigureSelectImg"
7
+ "click .graf--figure figcaption" : "handleGrafFigureSelectCaption"
8
+ "keyup .graf--figure figcaption" : "handleGrafCaptionTyping"
9
+
10
+ # TODO: this is from embed! move this to embed behavior
11
+ "mouseover .graf--figure.graf--iframe" : "handleGrafFigureSelectIframe"
12
+ "mouseleave .graf--figure.graf--iframe" : "handleGrafFigureUnSelectIframe"
13
+
14
+ initialize: (opts={})->
15
+ @editor = opts.current_editor
16
+
17
+ handleGrafFigureSelectImg: (ev)->
18
+ utils.log "FIGURE SELECT"
19
+ element = ev.currentTarget
20
+ @editor.markAsSelected( element )
21
+ $(element).parent(".graf--figure").addClass("is-selected is-mediaFocused")
22
+ @editor.selection().removeAllRanges()
23
+
24
+ @showAlignPopover(ev)
25
+
26
+ showAlignPopover: (ev)->
27
+ target = $(ev.currentTarget)
28
+ @editor.pop_over_align.positionPopOver(target) unless $(".popover--Aligntooltip").hasClass('is-active')
29
+
30
+ handleGrafFigureSelectCaption: (ev)->
31
+ utils.log "FIGCAPTION"
32
+ element = ev.currentTarget
33
+ $(element).parent(".graf--figure").removeClass("is-mediaFocused")
34
+
35
+ handleGrafCaptionTyping: (ev)->
36
+ if _.isEmpty(utils.getNode().textContent.trim())
37
+ $(@editor.getNode()).addClass("is-defaultValue")
38
+ else
39
+ $(@editor.getNode()).removeClass("is-defaultValue")
40
+
41
+
42
+ #TODO: this is from embed! move this to embed behavior
43
+ handleGrafFigureSelectIframe: (ev)->
44
+ utils.log "FIGURE IFRAME SELECT"
45
+ element = ev.currentTarget
46
+ @iframeSelected = element
47
+ @editor.markAsSelected( element )
48
+ $(element).addClass("is-selected is-mediaFocused")
49
+ @editor.selection().removeAllRanges()
50
+
51
+ handleGrafFigureUnSelectIframe: (ev)->
52
+ utils.log "FIGURE IFRAME UNSELECT"
53
+ element = ev.currentTarget
54
+ @iframeSelected = null
55
+ $(element).removeClass("is-selected is-mediaFocused")
56
+
@@ -0,0 +1,150 @@
1
+ utils = Dante.utils
2
+
3
+ class Dante.View.Behavior.List extends Dante.View.Behavior
4
+
5
+ # TODO. dry up this!, call constants from @editor
6
+ BACKSPACE = 8
7
+ TAB = 9
8
+ ENTER = 13
9
+ SPACEBAR = 32
10
+ LEFTARROW = 37
11
+ UPARROW = 38
12
+ RIGHTARROW = 39
13
+ DOWNARROW = 40
14
+
15
+ #events:
16
+
17
+ initialize: (opts={})->
18
+ @editor = opts.current_editor
19
+
20
+ # LIST METHODS
21
+
22
+ handleKeyDown: (e, parent)->
23
+ if e.which is ENTER
24
+ #smart list support
25
+ if parent.hasClass("graf--p")
26
+ li = @handleSmartList(parent, e)
27
+ anchor_node = li if li
28
+ else if parent.hasClass("graf--li")
29
+ @handleListLineBreak(parent, e)
30
+
31
+ # spacebar
32
+ if (e.which is SPACEBAR)
33
+ utils.log("SPACEBAR")
34
+ if (parent.hasClass("graf--p"))
35
+ @handleSmartList(parent, e)
36
+
37
+ if e.which is BACKSPACE
38
+ if(parent.hasClass("graf--li") and @editor.getCharacterPrecedingCaret().length is 0)
39
+ return @.handleListBackspace(parent, e)
40
+
41
+ handleKeyUp: (e)->
42
+ anchor_node = @editor.getNode()
43
+
44
+ if (_.contains([BACKSPACE, SPACEBAR, ENTER], e.which))
45
+ if $(anchor_node).hasClass("graf--li")
46
+ @editor.removeSpanTag($(anchor_node));
47
+
48
+ buildList: ($paragraph, listType, regex)->
49
+
50
+ utils.log "LISTIFY PARAGRAPH"
51
+
52
+ @editor.removeSpanTag($paragraph);
53
+
54
+ content = $paragraph.html().replace(/&nbsp;/g, " ").replace(regex, "")
55
+
56
+ switch(listType)
57
+ when "ul" then $list = $("<ul></ul>")
58
+ when "ol" then $list = $("<ol></ol>")
59
+ else return false
60
+
61
+ @editor.addClassesToElement($list[0])
62
+ @editor.replaceWith("li", $paragraph)
63
+ $li = $(".is-selected")
64
+
65
+ @editor.setElementName($li[0])
66
+
67
+ $li.html(content).wrap($list)
68
+
69
+ if($li.find("br").length == 0)
70
+ $li.append("<br/>")
71
+
72
+ @editor.setRangeAt($li[0])
73
+
74
+ $li[0]
75
+
76
+ handleSmartList: ($item, e)->
77
+ utils.log("HANDLE A SMART LIST")
78
+ chars = @editor.getCharacterPrecedingCaret()
79
+ match = chars.match(/^\s*(\-|\*)\s*$/)
80
+ if(match)
81
+ utils.log("CREATING LIST ITEM")
82
+ e.preventDefault()
83
+ regex = new RegExp(/\s*(\-|\*)\s*/)
84
+ $li = @buildList($item, "ul", regex)
85
+ else
86
+ match = chars.match(/^\s*1(\.|\))\s*$/)
87
+ if(match)
88
+ utils.log("CREATING LIST ITEM")
89
+ e.preventDefault()
90
+
91
+ regex = new RegExp(/\s*1(\.|\))\s*/)
92
+ $li = @buildList($item, "ol", regex)
93
+ $li
94
+
95
+ handleListLineBreak: ($li, e)->
96
+ utils.log("LIST LINE BREAK")
97
+ @editor.tooltip_view.hide()
98
+ $list = $li.parent("ol, ul")
99
+ $paragraph = $("<p></p>")
100
+ utils.log($li.prev());
101
+ if($list.children().length is 1 and $li.text() is "")
102
+ @editor.replaceWith("p", $list)
103
+
104
+ else if $li.text() is "" and ($li.next().length isnt 0)
105
+ e.preventDefault()
106
+
107
+ else if ($li.next().length is 0)
108
+ if($li.text() is "")
109
+ e.preventDefault()
110
+ utils.log("BREAK FROM LIST")
111
+ $list.after($paragraph)
112
+ $li.addClass("graf--removed").remove()
113
+
114
+ else if ($li.prev().length isnt 0 and $li.prev().text() is "" and @getCharacterPrecedingCaret() is "")
115
+ e.preventDefault()
116
+ utils.log("PREV IS EMPTY")
117
+ content = $li.html()
118
+ $list.after($paragraph)
119
+ $li.prev().remove()
120
+ $li.addClass("graf--removed").remove()
121
+ $paragraph.html(content)
122
+
123
+ if $list and $list.children().length is 0 then $list.remove()
124
+
125
+ utils.log($li);
126
+ if ($li.hasClass("graf--removed"))
127
+ utils.log("ELEMENT REMOVED")
128
+ @editor.addClassesToElement($paragraph[0])
129
+ @editor.setRangeAt($paragraph[0])
130
+ @editor.markAsSelected($paragraph[0])
131
+ @editor.scrollTo($paragraph)
132
+
133
+ handleListBackspace: ($li, e)->
134
+
135
+ $list = $li.parent("ol, ul")
136
+ utils.log("LIST BACKSPACE")
137
+
138
+ if($li.prev().length is 0)
139
+ e.preventDefault()
140
+
141
+ $list.before($li)
142
+ content = $li.html()
143
+ @editor.replaceWith("p", $li)
144
+ $paragraph = $(".is-selected")
145
+ $paragraph.removeClass("graf--empty").html(content).attr("name", utils.generateUniqueName());
146
+
147
+ if($list.children().length is 0)
148
+ $list.remove()
149
+
150
+ @editor.setupFirstAndLast()
@@ -0,0 +1,40 @@
1
+ utils = Dante.utils
2
+
3
+ class Dante.View.Behavior.Save extends Dante.View.Behavior
4
+
5
+ events:
6
+ "input" : "handleStore"
7
+
8
+ initialize: (opts={})->
9
+ @actionEvent = opts.title
10
+ @editor = opts.current_editor
11
+ @content = @editor.getContent()
12
+
13
+ handleStore: (ev)->
14
+ @store()
15
+
16
+ store: ()->
17
+ return unless @editor.store_url
18
+ utils.log "HANDLE DATA STORE"
19
+ clearTimeout(@timeout)
20
+ @timeout = setTimeout =>
21
+ @checkforStore()
22
+ , @editor.store_interval
23
+
24
+ checkforStore: ()->
25
+ utils.log "ENTER DATA STORE"
26
+ if @content is @editor.getContent()
27
+ utils.log "content not changed skip store"
28
+ @store()
29
+ else
30
+ utils.log "content changed! update"
31
+ @content = @editor.getContent()
32
+ $.ajax
33
+ url: @editor.store_url
34
+ method: @editor.store_method
35
+ dataType: "json"
36
+ data:
37
+ body: @editor.getContent()
38
+ success: (res)=>
39
+ utils.log "STORING CONTENT"
40
+ @editor.store_success_handler(res) if @editor.store_success_handler
@@ -0,0 +1,118 @@
1
+ utils = Dante.utils
2
+
3
+ class Dante.View.Behavior.Suggest extends Dante.View.Behavior
4
+
5
+ initialize: (opts={})->
6
+ @actionEvent = opts.title
7
+ @editor = opts.current_editor
8
+ @_name = null
9
+ @fetch_results = []
10
+
11
+ # TODO: this has to be pluggable too!
12
+ #@pop_over_typeahead = new Dante.Editor.PopOverTypeAhead(editor: @)
13
+ #@pop_over_typeahead.render().hide()
14
+
15
+ displayPopOver: (ev)->
16
+ @editor.pop_over_typeahead.displayAt(@editor.getSelectionStart())
17
+
18
+ hidePopOver: (ev)->
19
+ console.log "display popover from typeahead"
20
+ @editor.pop_over_typeahead.displayAt(ev)
21
+
22
+ desintegratePopOver: (e)->
23
+ $(@.editor.getSelectionStart()).remove()
24
+ @pasteHtmlAtCaret(@.editor.getSelectionStart().textContent, false)
25
+
26
+ handleKeyPress: (e)->
27
+ if !@insideQuery()
28
+ if e.keyCode is 64
29
+ e.preventDefault()
30
+ @pasteHtmlAtCaret(@wrapperTemplate("@"), false)
31
+ else
32
+ console.log "ok let's search"
33
+ @getResults (e)=>
34
+ @fetchResults(e)
35
+
36
+ handleKeyUp: (e)->
37
+ if @insideQuery()
38
+ @fetchResults(e)
39
+
40
+ fetchResults: (e)->
41
+ @desintegratePopOver(e) if @getResults.length < 1
42
+
43
+ @json_request.abort() if @json_request
44
+
45
+ @getResults (e)=>
46
+ @displayPopOver(e)
47
+ @editor.pop_over_typeahead.appendData(@fetch_results)
48
+
49
+ getResults: (cb, e)->
50
+ q = @editor.getSelectionStart().textContent.replace("@", "")
51
+
52
+ clearTimeout(@timeout)
53
+
54
+ @timeout = setTimeout =>
55
+ @json_request = $.ajax
56
+ url: "#{@editor.suggest_url}?#{@editor.suggest_query_param}=#{q}"
57
+ method: "get"
58
+ dataType: "json"
59
+ #data: { "#{@editor.suggest_query_param}": q }
60
+ .success (data)=>
61
+ if @editor.suggest_handler
62
+ @fetch_results = @editor.suggest_handler(data)
63
+ else
64
+ @fetch_results = data
65
+ cb(e) if cb
66
+ .error (data, err)=>
67
+ console.log "error fetching results"
68
+ , @editor.suggest_query_timeout
69
+
70
+ insideQuery: ()->
71
+ $(@editor.getSelectionStart()).hasClass("markup--query")
72
+
73
+ wrapperTemplate: (name)->
74
+ "<span class='markup--query'>#{name}</span>"
75
+
76
+ # http://stackoverflow.com/questions/6690752/insert-html-at-caret-in-a-contenteditable-div
77
+ pasteHtmlAtCaret: (html, selectPastedContent) ->
78
+ sel = undefined
79
+ range = undefined
80
+ if window.getSelection
81
+ # IE9 and non-IE
82
+ sel = window.getSelection()
83
+ if sel.getRangeAt and sel.rangeCount
84
+ range = sel.getRangeAt(0)
85
+ range.deleteContents()
86
+ # Range.createContextualFragment() would be useful here but is
87
+ # only relatively recently standardized and is not supported in
88
+ # some browsers (IE9, for one)
89
+ el = document.createElement('div')
90
+ el.innerHTML = html
91
+ frag = document.createDocumentFragment()
92
+ node = undefined
93
+ lastNode = undefined
94
+ while node = el.firstChild
95
+ lastNode = frag.appendChild(node)
96
+ firstNode = frag.firstChild
97
+ range.insertNode frag
98
+
99
+ # Preserve the selection
100
+ if lastNode
101
+ range = range.cloneRange()
102
+ range.setStartAfter lastNode
103
+ if selectPastedContent
104
+ range.setStartBefore firstNode
105
+ else
106
+ range.collapse true
107
+ sel.removeAllRanges()
108
+ sel.addRange range
109
+ else if (sel = document.selection) and sel.type != 'Control'
110
+ # IE < 9
111
+ originalRange = sel.createRange()
112
+ originalRange.collapse true
113
+ sel.createRange().pasteHTML html
114
+ if selectPastedContent
115
+ range = sel.createRange()
116
+ range.setEndPoint 'StartToStart', originalRange
117
+ range.select()
118
+ return