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.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +49 -10
- data/app/assets/fonts/dante/dante.eot +0 -0
- data/app/assets/fonts/dante/dante.svg +9 -5
- data/app/assets/fonts/dante/dante.ttf +0 -0
- data/app/assets/fonts/dante/dante.woff +0 -0
- data/app/assets/javascripts/dante/behavior.js.coffee +2 -0
- data/app/assets/javascripts/dante/behaviors/image.js.coffee +56 -0
- data/app/assets/javascripts/dante/behaviors/list.js.coffee +150 -0
- data/app/assets/javascripts/dante/behaviors/save.js.coffee +40 -0
- data/app/assets/javascripts/dante/behaviors/suggest.js.coffee +118 -0
- data/app/assets/javascripts/dante/editor.js.coffee +110 -228
- data/app/assets/javascripts/dante/popover.js.coffee +350 -11
- data/app/assets/javascripts/dante/tooltip_widgets/uploader.js.coffee +2 -2
- data/app/assets/javascripts/dante.js +5 -0
- data/app/assets/stylesheets/dante/_blame.scss +209 -0
- data/app/assets/stylesheets/dante/_caption.scss +14 -0
- data/app/assets/stylesheets/dante/_icons.scss +10 -5
- data/app/assets/stylesheets/dante/_menu.scss +7 -7
- data/app/assets/stylesheets/dante/_popover.scss +122 -44
- data/app/assets/stylesheets/dante/_utilities.scss +5 -1
- data/app/assets/stylesheets/dante/_variables.scss +7 -3
- data/app/assets/stylesheets/dante.scss +2 -0
- data/config.rb +5 -4
- data/dist/css/dante-editor.css +246 -44
- data/dist/fonts/dante/dante.eot +0 -0
- data/dist/fonts/dante/dante.svg +9 -5
- data/dist/fonts/dante/dante.ttf +0 -0
- data/dist/fonts/dante/dante.woff +0 -0
- data/dist/js/dante-editor.js +1015 -283
- data/lib/dante-editor/version.rb +1 -1
- data/source/api/cristian.json.erb +8 -0
- data/source/api/miguel.json.erb +8 -0
- data/source/api/resource.json.erb +8 -0
- data/source/api/save.json.erb +1 -0
- data/source/api/suggest.json.erb +22 -0
- data/source/assets/images/dante-demo.png +0 -0
- data/source/icons/image-center.svg +12 -0
- data/source/icons/image-fill.svg +11 -0
- data/source/icons/image-left.svg +15 -0
- data/source/icons/image-wide.svg +12 -0
- data/source/index.html.erb +6 -0
- data/source/partials/_readme.markdown +2 -2
- metadata +18 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 73da3d8fd1e1f91d98447623572bc34f01875b6c
|
4
|
+
data.tar.gz: 119bfee12fff5d4ed905ff0bf3a2b96c32bc1eb4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5ee9aa76441e57c48f1076c7a15fe89b7fd487e556c4f468a566ca2ed4143274e2c1fc2a631aa6e270c6c5ea7b5c3692583123630b6ff2edfd5851521f22eaa3
|
7
|
+
data.tar.gz: 2fabadbecdae53b7fd83614bae1cd41cbe8fa39ee8d1abb8520521b7effb960e4234b614f2a93ea55243cac62b9cc72881698440937bc3335dcadac129b8a64a
|
data/Gemfile.lock
CHANGED
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
|
-
|
83
|
-
|
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" >
|
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=" "
|
10
|
-
<glyph unicode="" 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="" 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="" 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="" 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=" " horiz-adv-x="512" d="" />
|
10
|
+
<glyph unicode="" 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="" 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="" 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="" 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="" glyph-name="image-center" horiz-adv-x="1152" d="M128 128h896v-96h-896v96zM128 704h896v-480h-896v480zM128 896h896v-96h-896v96z" />
|
15
|
+
<glyph unicode="" glyph-name="image-fill" horiz-adv-x="1152" d="M128 128h896v-96h-896v96zM0 896h1152v-672h-1152v672z" />
|
16
|
+
<glyph unicode="" 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="" 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,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(/ /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
|