mercury-rails 0.2.3 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/app/controllers/{images_controller.rb → mercury/images_controller.rb} +3 -3
- data/app/controllers/mercury_controller.rb +13 -3
- data/app/models/{image.rb → mercury/image.rb} +3 -1
- data/app/views/layouts/mercury.html.erb +14 -6
- data/app/views/mercury/lightviews/about.html +7 -3
- data/app/views/mercury/modals/character.html +2 -2
- data/app/views/mercury/modals/htmleditor.html +2 -2
- data/app/views/mercury/modals/link.html +3 -3
- data/app/views/mercury/modals/media.html +3 -3
- data/app/views/mercury/modals/table.html +3 -3
- data/app/views/mercury/panels/snippets.html +1 -1
- data/app/views/mercury/selects/formatblock.html +9 -9
- data/app/views/mercury/snippets/example/options.html.erb +27 -16
- data/config/engine.rb +35 -0
- data/db/migrate/{20110526035601_create_images.rb → 20110526035601_create_mercury_images.rb} +2 -2
- data/features/loading/loading.feature +1 -1
- data/features/loading/navigating.feature +1 -1
- data/features/loading/user_interface.feature +2 -2
- data/features/regions/editable/basic_editing.feature +8 -8
- data/features/regions/editable/inserting_snippets.feature +4 -5
- data/features/regions/editable/inserting_tables.feature +9 -9
- data/features/step_definitions/mercury_steps.rb +20 -23
- data/features/step_definitions/web_steps.rb +5 -5
- data/features/support/mercury_selectors.rb +1 -0
- data/lib/generators/mercury/install/install_generator.rb +24 -3
- data/lib/generators/mercury/install/templates/mongoid_paperclip_image.rb +17 -0
- data/lib/mercury-rails.rb +0 -1
- data/lib/mercury/authentication.rb +8 -0
- data/spec/javascripts/mercury/dialog_spec.js.coffee +28 -21
- data/spec/javascripts/mercury/dialogs/backcolor_spec.js.coffee +0 -2
- data/spec/javascripts/mercury/dialogs/forecolor_spec.js.coffee +0 -2
- data/spec/javascripts/mercury/dialogs/formatblock_spec.js.coffee +0 -2
- data/spec/javascripts/mercury/dialogs/snippetpanel_spec.js.coffee +0 -2
- data/spec/javascripts/mercury/dialogs/style_spec.js.coffee +0 -2
- data/spec/javascripts/mercury/history_buffer_spec.js.coffee +0 -2
- data/spec/javascripts/mercury/lightview_spec.js.coffee +42 -21
- data/spec/javascripts/mercury/mercury_spec.js.coffee +87 -7
- data/spec/javascripts/mercury/modal_spec.js.coffee +53 -23
- data/spec/javascripts/mercury/modals/htmleditor_spec.js.coffee +0 -2
- data/spec/javascripts/mercury/modals/insertcharacter_spec.js.coffee +2 -3
- data/spec/javascripts/mercury/modals/insertlink_spec.js.coffee +0 -2
- data/spec/javascripts/mercury/modals/insertmedia_spec.js.coffee +2 -2
- data/spec/javascripts/mercury/modals/insertsnippet_spec.js.coffee +0 -2
- data/spec/javascripts/mercury/modals/inserttable_spec.js.coffee +2 -4
- data/spec/javascripts/mercury/native_extensions_spec.js.coffee +20 -2
- data/spec/javascripts/mercury/page_editor_spec.js.coffee +130 -35
- data/spec/javascripts/mercury/palette_spec.js.coffee +4 -6
- data/spec/javascripts/mercury/panel_spec.js.coffee +44 -6
- data/spec/javascripts/mercury/region_spec.js.coffee +42 -8
- data/spec/javascripts/mercury/regions/editable_spec.js.coffee +0 -2
- data/spec/javascripts/mercury/regions/markupable_spec.js.coffee +0 -2
- data/spec/javascripts/mercury/regions/snippetable_spec.js.coffee +3 -5
- data/spec/javascripts/mercury/select_spec.js.coffee +4 -6
- data/spec/javascripts/mercury/snippet_spec.js.coffee +3 -4
- data/spec/javascripts/mercury/snippet_toolbar_spec.js.coffee +2 -4
- data/spec/javascripts/mercury/statusbar_spec.js.coffee +0 -2
- data/spec/javascripts/mercury/table_editor_spec.js.coffee +2 -4
- data/spec/javascripts/mercury/toolbar.button_group_spec.js.coffee +0 -2
- data/spec/javascripts/mercury/toolbar.button_spec.js.coffee +34 -15
- data/spec/javascripts/mercury/toolbar.expander_spec.js.coffee +0 -2
- data/spec/javascripts/mercury/toolbar_spec.js.coffee +41 -26
- data/spec/javascripts/mercury/tooltip_spec.js.coffee +3 -5
- data/spec/javascripts/mercury/uploader_spec.js.coffee +8 -14
- data/spec/javascripts/spec_helper.js +1 -0
- data/spec/javascripts/templates/mercury/page_editor.html +1 -0
- data/spec/javascripts/templates/mercury/region.html +2 -2
- data/vendor/assets/images/mercury/missing-image.png +0 -0
- data/vendor/assets/javascripts/mercury.js +218 -112
- data/vendor/assets/javascripts/mercury/dependencies/{jquery-1.6.js → jquery-1.7.js} +2030 -1595
- data/vendor/assets/javascripts/mercury/dependencies/jquery.additions.js +55 -0
- data/vendor/assets/javascripts/mercury/dialog.js.coffee +7 -5
- data/vendor/assets/javascripts/mercury/dialogs/backcolor.js.coffee +1 -1
- data/vendor/assets/javascripts/mercury/dialogs/forecolor.js.coffee +1 -1
- data/vendor/assets/javascripts/mercury/dialogs/formatblock.js.coffee +1 -1
- data/vendor/assets/javascripts/mercury/dialogs/{objectspanel.js.coffee → snippetpanel.js.coffee} +2 -2
- data/vendor/assets/javascripts/mercury/dialogs/style.js.coffee +1 -1
- data/vendor/assets/javascripts/mercury/finalize.js.coffee +3 -0
- data/vendor/assets/javascripts/mercury/lightview.js.coffee +76 -30
- data/vendor/assets/javascripts/mercury/locales/da.locale.js.coffee +211 -0
- data/vendor/assets/javascripts/mercury/locales/de.locale.js.coffee +206 -0
- data/vendor/assets/javascripts/mercury/locales/es.locale.js.coffee +211 -0
- data/vendor/assets/javascripts/mercury/locales/example.local.js.coffee +211 -0
- data/vendor/assets/javascripts/mercury/locales/fr.locale.js.coffee +211 -0
- data/vendor/assets/javascripts/mercury/locales/it.locale.js.coffee +208 -0
- data/vendor/assets/javascripts/mercury/locales/ko.local.js.coffee +206 -0
- data/vendor/assets/javascripts/mercury/locales/nl.locale.js.coffee +206 -0
- data/vendor/assets/javascripts/mercury/locales/pt.locale.js.coffee +211 -0
- data/vendor/assets/javascripts/mercury/locales/sv.local.js.coffee +209 -0
- data/vendor/assets/javascripts/mercury/locales/swedish_chef.locale.js.coffee +213 -0
- data/vendor/assets/javascripts/mercury/mercury.js.coffee +62 -17
- data/vendor/assets/javascripts/mercury/modal.js.coffee +34 -21
- data/vendor/assets/javascripts/mercury/modals/htmleditor.js.coffee +1 -2
- data/vendor/assets/javascripts/mercury/modals/insertcharacter.js.coffee +3 -3
- data/vendor/assets/javascripts/mercury/modals/insertlink.js.coffee +4 -4
- data/vendor/assets/javascripts/mercury/modals/insertmedia.js.coffee +10 -9
- data/vendor/assets/javascripts/mercury/modals/insertsnippet.js.coffee +1 -1
- data/vendor/assets/javascripts/mercury/modals/inserttable.js.coffee +8 -9
- data/vendor/assets/javascripts/mercury/native_extensions.js.coffee +26 -8
- data/vendor/assets/javascripts/mercury/page_editor.js.coffee +68 -46
- data/vendor/assets/javascripts/mercury/palette.js.coffee +1 -1
- data/vendor/assets/javascripts/mercury/panel.js.coffee +25 -7
- data/vendor/assets/javascripts/mercury/plugins/save_as_xml/mercury/page_editor.js.coffee +1 -0
- data/vendor/assets/javascripts/mercury/region.js.coffee +21 -17
- data/vendor/assets/javascripts/mercury/regions/editable.js.coffee +47 -35
- data/vendor/assets/javascripts/mercury/regions/markupable.js.coffee +43 -36
- data/vendor/assets/javascripts/mercury/regions/snippetable.js.coffee +22 -24
- data/vendor/assets/javascripts/mercury/select.js.coffee +3 -2
- data/vendor/assets/javascripts/mercury/snippet.js.coffee +2 -1
- data/vendor/assets/javascripts/mercury/snippet_toolbar.js.coffee +10 -7
- data/vendor/assets/javascripts/mercury/statusbar.js.coffee +4 -4
- data/vendor/assets/javascripts/mercury/table_editor.js.coffee +1 -3
- data/vendor/assets/javascripts/mercury/toolbar.button.js.coffee +42 -20
- data/vendor/assets/javascripts/mercury/toolbar.button_group.js.coffee +3 -3
- data/vendor/assets/javascripts/mercury/toolbar.expander.js.coffee +2 -2
- data/vendor/assets/javascripts/mercury/toolbar.js.coffee +8 -6
- data/vendor/assets/javascripts/mercury/tooltip.js.coffee +13 -9
- data/vendor/assets/javascripts/mercury/uploader.js.coffee +22 -16
- data/vendor/assets/javascripts/mercury_loader.js +2 -0
- data/vendor/assets/javascripts/mercury_overrides.js +6 -0
- data/vendor/assets/stylesheets/mercury/all_images.css.erb +89 -0
- data/vendor/assets/stylesheets/mercury/dialog.css +13 -4
- data/vendor/assets/stylesheets/mercury/lightview.css +66 -15
- data/vendor/assets/stylesheets/mercury/mercury.css +12 -7
- data/vendor/assets/stylesheets/mercury/modal.css +9 -5
- data/vendor/assets/stylesheets/mercury/toolbar.css +3 -29
- metadata +266 -144
- data/POST_INSTALL +0 -15
- data/README.md +0 -299
- data/VERSION +0 -1
- data/annotated_source.template +0 -57
- data/config/routes.rb +0 -15
- data/mercury-rails.gemspec +0 -288
- data/spec/javascripts/responses/blank.html +0 -1
- data/vendor/assets/javascripts/mercury/lightviews/imageprocessor.js.coffee +0 -2
@@ -6,11 +6,12 @@ class @Mercury.Region
|
|
6
6
|
Mercury.log("building #{@type}", @element, @options)
|
7
7
|
|
8
8
|
@document = @window.document
|
9
|
-
@name = @element.attr(
|
9
|
+
@name = @element.attr(Mercury.config.regions.identifier)
|
10
10
|
@history = new Mercury.HistoryBuffer()
|
11
11
|
@build()
|
12
12
|
@bindEvents()
|
13
13
|
@pushHistory()
|
14
|
+
@element.data('region', @)
|
14
15
|
|
15
16
|
|
16
17
|
build: ->
|
@@ -20,28 +21,24 @@ class @Mercury.Region
|
|
20
21
|
|
21
22
|
|
22
23
|
bindEvents: ->
|
23
|
-
Mercury.
|
24
|
-
@togglePreview() if options.mode == 'preview'
|
24
|
+
Mercury.on 'mode', (event, options) => @togglePreview() if options.mode == 'preview'
|
25
25
|
|
26
|
-
Mercury.
|
27
|
-
return if @previewing
|
28
|
-
return unless Mercury.region == @
|
26
|
+
Mercury.on 'focus:frame', =>
|
27
|
+
return if @previewing || Mercury.region != @
|
29
28
|
@focus()
|
30
29
|
|
31
|
-
Mercury.
|
32
|
-
return if @previewing
|
33
|
-
return unless Mercury.region == @
|
30
|
+
Mercury.on 'action', (event, options) =>
|
31
|
+
return if @previewing || Mercury.region != @
|
34
32
|
@execCommand(options.action, options) if options.action
|
35
33
|
|
36
|
-
@element.mousemove (event) =>
|
37
|
-
return if @previewing
|
38
|
-
return unless Mercury.region == @
|
34
|
+
@element.on 'mousemove', (event) =>
|
35
|
+
return if @previewing || Mercury.region != @
|
39
36
|
snippet = jQuery(event.target).closest('.mercury-snippet')
|
40
37
|
if snippet.length
|
41
38
|
@snippet = snippet
|
42
39
|
Mercury.trigger('show:toolbar', {type: 'snippet', snippet: @snippet})
|
43
40
|
|
44
|
-
@element.mouseout
|
41
|
+
@element.on 'mouseout', =>
|
45
42
|
return if @previewing
|
46
43
|
Mercury.trigger('hide:toolbar', {type: 'snippet', immediately: false})
|
47
44
|
|
@@ -55,7 +52,7 @@ class @Mercury.Region
|
|
55
52
|
container.html(@element.html().replace(/^\s+|\s+$/g, ''))
|
56
53
|
|
57
54
|
# replace snippet contents to be an identifier
|
58
|
-
if filterSnippets then for snippet
|
55
|
+
if filterSnippets then for snippet in container.find('.mercury-snippet')
|
59
56
|
snippet = jQuery(snippet)
|
60
57
|
snippet.attr({contenteditable: null, 'data-version': null})
|
61
58
|
snippet.html("[#{snippet.data('snippet')}]")
|
@@ -66,11 +63,11 @@ class @Mercury.Region
|
|
66
63
|
togglePreview: ->
|
67
64
|
if @previewing
|
68
65
|
@previewing = false
|
69
|
-
@element.addClass(Mercury.config.
|
66
|
+
@element.addClass(Mercury.config.regions.className).removeClass("#{Mercury.config.regions.className}-preview")
|
70
67
|
@focus() if Mercury.region == @
|
71
68
|
else
|
72
69
|
@previewing = true
|
73
|
-
@element.addClass("#{Mercury.config.
|
70
|
+
@element.addClass("#{Mercury.config.regions.className}-preview").removeClass(Mercury.config.regions.className)
|
74
71
|
Mercury.trigger('region:blurred', {region: @})
|
75
72
|
|
76
73
|
|
@@ -79,7 +76,7 @@ class @Mercury.Region
|
|
79
76
|
@pushHistory() unless action == 'redo'
|
80
77
|
|
81
78
|
Mercury.log('execCommand', action, options.value)
|
82
|
-
Mercury.changes = true
|
79
|
+
Mercury.changes = true unless options.already_handled
|
83
80
|
|
84
81
|
|
85
82
|
pushHistory: ->
|
@@ -95,9 +92,16 @@ class @Mercury.Region
|
|
95
92
|
return snippets
|
96
93
|
|
97
94
|
|
95
|
+
dataAttributes: ->
|
96
|
+
data = {}
|
97
|
+
data[attr] = @element.attr('data-' + attr) for attr in Mercury.config.regions.dataAttributes
|
98
|
+
return data
|
99
|
+
|
100
|
+
|
98
101
|
serialize: ->
|
99
102
|
return {
|
100
103
|
type: @type
|
104
|
+
data: @dataAttributes()
|
101
105
|
value: @content(null, true)
|
102
106
|
snippets: @snippets()
|
103
107
|
}
|
@@ -1,4 +1,8 @@
|
|
1
1
|
class @Mercury.Regions.Editable extends Mercury.Region
|
2
|
+
# No IE support yet because it doesn't follow the W3C standards for HTML5 contentEditable (aka designMode).
|
3
|
+
@supported: document.designMode && !jQuery.browser.konqueror && !jQuery.browser.msie
|
4
|
+
@supportedText: "Chrome 10+, Firefox 4+, Safari 5+"
|
5
|
+
|
2
6
|
type = 'editable'
|
3
7
|
|
4
8
|
constructor: (@element, @window, @options = {}) ->
|
@@ -41,15 +45,14 @@ class @Mercury.Regions.Editable extends Mercury.Region
|
|
41
45
|
bindEvents: ->
|
42
46
|
super
|
43
47
|
|
44
|
-
Mercury.
|
45
|
-
return if @previewing
|
46
|
-
|
47
|
-
setTimeout((=> @selection().forceSelection(@element.get(0))), 1)
|
48
|
+
Mercury.on 'region:update', =>
|
49
|
+
return if @previewing || Mercury.region != @
|
50
|
+
setTimeout(1, => @selection().forceSelection(@element.get(0)))
|
48
51
|
currentElement = @currentElement()
|
49
52
|
if currentElement.length
|
50
53
|
# setup the table editor if we're inside a table
|
51
54
|
table = currentElement.closest('table', @element)
|
52
|
-
Mercury.tableEditor(table, currentElement.closest('tr, td'), '
|
55
|
+
Mercury.tableEditor(table, currentElement.closest('tr, td'), '<br/>') if table.length
|
53
56
|
# display a tooltip if we're in an anchor
|
54
57
|
anchor = currentElement.closest('a', @element)
|
55
58
|
if anchor.length && anchor.attr('href')
|
@@ -57,25 +60,25 @@ class @Mercury.Regions.Editable extends Mercury.Region
|
|
57
60
|
else
|
58
61
|
Mercury.tooltip.hide()
|
59
62
|
|
60
|
-
@element.
|
63
|
+
@element.on 'dragenter', (event) =>
|
61
64
|
return if @previewing
|
62
65
|
event.preventDefault() unless Mercury.snippet
|
63
66
|
event.originalEvent.dataTransfer.dropEffect = 'copy'
|
64
67
|
|
65
|
-
@element.
|
68
|
+
@element.on 'dragover', (event) =>
|
66
69
|
return if @previewing
|
67
70
|
event.preventDefault() unless Mercury.snippet
|
68
71
|
event.originalEvent.dataTransfer.dropEffect = 'copy'
|
69
72
|
if jQuery.browser.webkit
|
70
73
|
clearTimeout(@dropTimeout)
|
71
|
-
@dropTimeout = setTimeout(
|
74
|
+
@dropTimeout = setTimeout(10, => @element.trigger('possible:drop'))
|
72
75
|
|
73
|
-
@element.
|
76
|
+
@element.on 'drop', (event) =>
|
74
77
|
return if @previewing
|
75
78
|
|
76
79
|
# handle dropping snippets
|
77
80
|
clearTimeout(@dropTimeout)
|
78
|
-
@dropTimeout = setTimeout(
|
81
|
+
@dropTimeout = setTimeout(1, => @element.trigger('possible:drop'))
|
79
82
|
|
80
83
|
# handle any files that were dropped
|
81
84
|
return unless event.originalEvent.dataTransfer.files.length
|
@@ -88,7 +91,7 @@ class @Mercury.Regions.Editable extends Mercury.Region
|
|
88
91
|
# isn't handled (eg, putting the image where it was dropped,) so to allow the browser to do it's thing, and also do
|
89
92
|
# our thing we have this little hack. *sigh*
|
90
93
|
# read: http://www.quirksmode.org/blog/archives/2009/09/the_html5_drag.html
|
91
|
-
@element.
|
94
|
+
@element.on 'possible:drop', =>
|
92
95
|
return if @previewing
|
93
96
|
if snippet = @element.find('img[data-snippet]').get(0)
|
94
97
|
@focus()
|
@@ -97,11 +100,11 @@ class @Mercury.Regions.Editable extends Mercury.Region
|
|
97
100
|
|
98
101
|
# custom paste handling: we have to do some hackery to get the pasted content since it's not exposed normally
|
99
102
|
# through a clipboard in firefox (heaven forbid), and to keep the behavior across all browsers, we manually detect
|
100
|
-
# what was pasted by
|
101
|
-
# content
|
102
|
-
|
103
|
-
|
104
|
-
return
|
103
|
+
# what was pasted by focusing a different (hidden) region, letting it paste there, making our adjustments, and then
|
104
|
+
# inserting the content where it was intended. This is possible, so it doesn't make sense why it wouldn't be
|
105
|
+
# exposed in a sensible way. *sigh*
|
106
|
+
@element.on 'paste', (event) =>
|
107
|
+
return if @previewing || Mercury.region != @
|
105
108
|
if @specialContainer
|
106
109
|
event.preventDefault()
|
107
110
|
return
|
@@ -109,35 +112,34 @@ class @Mercury.Regions.Editable extends Mercury.Region
|
|
109
112
|
Mercury.changes = true
|
110
113
|
@handlePaste(event.originalEvent)
|
111
114
|
|
112
|
-
@element.focus =>
|
115
|
+
@element.on 'focus', =>
|
113
116
|
return if @previewing
|
114
117
|
Mercury.region = @
|
115
|
-
setTimeout(
|
118
|
+
setTimeout(1, => @selection().forceSelection(@element.get(0)))
|
116
119
|
Mercury.trigger('region:focused', {region: @})
|
117
120
|
|
118
|
-
@element.blur =>
|
121
|
+
@element.on 'blur', =>
|
119
122
|
return if @previewing
|
120
123
|
Mercury.trigger('region:blurred', {region: @})
|
121
124
|
Mercury.tooltip.hide()
|
122
125
|
|
123
|
-
@element.click (event) =>
|
124
|
-
jQuery(event.target).closest('a').attr('target', '
|
126
|
+
@element.on 'click', (event) =>
|
127
|
+
jQuery(event.target).closest('a').attr('target', '_parent') if @previewing
|
125
128
|
|
126
|
-
@element.dblclick (event) =>
|
129
|
+
@element.on 'dblclick', (event) =>
|
127
130
|
return if @previewing
|
128
131
|
image = jQuery(event.target).closest('img', @element)
|
129
132
|
if image.length
|
130
133
|
@selection().selectNode(image.get(0), true)
|
131
134
|
Mercury.trigger('button', {action: 'insertMedia'})
|
132
135
|
|
133
|
-
@element.mouseup =>
|
136
|
+
@element.on 'mouseup', =>
|
134
137
|
return if @previewing
|
135
138
|
@pushHistory()
|
136
139
|
Mercury.trigger('region:update', {region: @})
|
137
140
|
|
138
|
-
@element.keydown (event) =>
|
141
|
+
@element.on 'keydown', (event) =>
|
139
142
|
return if @previewing
|
140
|
-
Mercury.changes = true
|
141
143
|
switch event.keyCode
|
142
144
|
when 90 # undo / redo
|
143
145
|
return unless event.metaKey
|
@@ -166,7 +168,7 @@ class @Mercury.Regions.Editable extends Mercury.Region
|
|
166
168
|
else if container.parents('ul, ol').length > 1
|
167
169
|
@execCommand('outdent')
|
168
170
|
else
|
169
|
-
@execCommand('insertHTML', {value: '
|
171
|
+
@execCommand('insertHTML', {value: ' '})
|
170
172
|
|
171
173
|
if event.metaKey
|
172
174
|
switch event.keyCode
|
@@ -184,15 +186,21 @@ class @Mercury.Regions.Editable extends Mercury.Region
|
|
184
186
|
|
185
187
|
@pushHistory(event.keyCode)
|
186
188
|
|
187
|
-
@element.keyup =>
|
189
|
+
@element.on 'keyup', =>
|
188
190
|
return if @previewing
|
189
191
|
Mercury.trigger('region:update', {region: @})
|
192
|
+
Mercury.changes = true
|
190
193
|
|
191
194
|
|
192
195
|
focus: ->
|
193
196
|
if Mercury.region != @
|
194
|
-
@element.focus()
|
195
|
-
|
197
|
+
setTimeout(10, => @element.focus())
|
198
|
+
try
|
199
|
+
@selection().selection.collapseToStart()
|
200
|
+
catch e
|
201
|
+
# intentially do nothing
|
202
|
+
else
|
203
|
+
setTimeout(10, => @element.focus())
|
196
204
|
|
197
205
|
Mercury.trigger('region:focused', {region: @})
|
198
206
|
Mercury.trigger('region:update', {region: @})
|
@@ -278,9 +286,12 @@ class @Mercury.Regions.Editable extends Mercury.Region
|
|
278
286
|
@document.execCommand(action, false, options.value)
|
279
287
|
catch error
|
280
288
|
# mozilla: indenting when there's no br tag handles strangely
|
281
|
-
#
|
289
|
+
# mozilla: trying to justify the first line of any contentEditable fails
|
282
290
|
@element.prev().remove() if action == 'indent' && @element.prev() != sibling
|
283
291
|
|
292
|
+
# handle any broken images by replacing the source with an alert image
|
293
|
+
@element.find('img').one 'error', -> jQuery(@).attr({src: '/assets/mercury/missing-image.png', title: 'Image not found'})
|
294
|
+
|
284
295
|
|
285
296
|
pushHistory: (keyCode) ->
|
286
297
|
# when pressing return, delete or backspace it should push to the history
|
@@ -297,7 +308,7 @@ class @Mercury.Regions.Editable extends Mercury.Region
|
|
297
308
|
@history.push(@content(null, false, true))
|
298
309
|
else if keyCode
|
299
310
|
# set a timeout for pushing to the history
|
300
|
-
@historyTimeout = setTimeout(
|
311
|
+
@historyTimeout = setTimeout(waitTime * 1000, => @history.push(@content(null, false, true)))
|
301
312
|
else
|
302
313
|
# push to the history immediately
|
303
314
|
@history.push(@content(null, false, true))
|
@@ -331,7 +342,6 @@ class @Mercury.Regions.Editable extends Mercury.Region
|
|
331
342
|
event.preventDefault()
|
332
343
|
return
|
333
344
|
else
|
334
|
-
console.debug('testing')
|
335
345
|
# get current selection & range
|
336
346
|
selection = @selection()
|
337
347
|
selection.placeMarker()
|
@@ -354,7 +364,7 @@ class @Mercury.Regions.Editable extends Mercury.Region
|
|
354
364
|
|
355
365
|
sanitize: (sanitizer) ->
|
356
366
|
# always remove nested regions
|
357
|
-
sanitizer.find(".#{Mercury.config.
|
367
|
+
sanitizer.find(".#{Mercury.config.regions.className}").remove()
|
358
368
|
|
359
369
|
if Mercury.config.pasting.sanitize
|
360
370
|
switch Mercury.config.pasting.sanitize
|
@@ -369,8 +379,8 @@ class @Mercury.Regions.Editable extends Mercury.Region
|
|
369
379
|
for allowedTag, allowedAttributes of Mercury.config.pasting.whitelist
|
370
380
|
if element.tagName.toLowerCase() == allowedTag.toLowerCase()
|
371
381
|
allowed = true
|
372
|
-
for attr
|
373
|
-
jQuery(element).
|
382
|
+
for attr in jQuery(element.attributes)
|
383
|
+
jQuery(element).removeAttr(attr.name) unless attr.name in allowedAttributes
|
374
384
|
break
|
375
385
|
jQuery(element).replaceWith(jQuery(element).contents()) unless allowed
|
376
386
|
content = sanitizer.html()
|
@@ -426,6 +436,8 @@ class @Mercury.Regions.Editable extends Mercury.Region
|
|
426
436
|
|
427
437
|
insertImage: (selection, options) -> @execCommand('insertHTML', {value: jQuery('<img/>', options.value)})
|
428
438
|
|
439
|
+
insertTable: (selection, options) -> @execCommand('insertHTML', {value: options.value})
|
440
|
+
|
429
441
|
insertLink: (selection, options) ->
|
430
442
|
anchor = jQuery("<#{options.value.tagName}>", @document).attr(options.value.attrs).html(options.value.content)
|
431
443
|
selection.insertNode(anchor)
|
@@ -4,6 +4,9 @@
|
|
4
4
|
# nice if we could activate the bold button for instance.
|
5
5
|
|
6
6
|
class @Mercury.Regions.Markupable extends Mercury.Region
|
7
|
+
@supported: document.getElementById
|
8
|
+
@supportedText: "IE 7+, Chrome 10+, Firefox 4+, Safari 5+, Opera 8+"
|
9
|
+
|
7
10
|
type = 'markupable'
|
8
11
|
|
9
12
|
constructor: (@element, @window, @options = {}) ->
|
@@ -17,54 +20,46 @@ class @Mercury.Regions.Markupable extends Mercury.Region
|
|
17
20
|
height = @element.height()
|
18
21
|
|
19
22
|
value = @element.html().replace(/^\s+|\s+$/g, '').replace('>', '>')
|
23
|
+
@element.removeClass(Mercury.config.regions.className)
|
20
24
|
@textarea = jQuery('<textarea>', @document).val(value)
|
21
25
|
@textarea.attr('class', @element.attr('class')).addClass('mercury-textarea')
|
22
|
-
@textarea.css({border: 0, background: 'transparent', display: 'block', width: width, height: height, fontFamily: '"Courier New", Courier, monospace'
|
26
|
+
@textarea.css({border: 0, background: 'transparent', display: 'block', 'overflow-y': 'hidden', width: width, height: height, fontFamily: '"Courier New", Courier, monospace'})
|
27
|
+
@element.addClass(Mercury.config.regions.className)
|
23
28
|
@element.empty().append(@textarea)
|
24
|
-
@element.removeClass(Mercury.config.regionClass)
|
25
29
|
|
26
30
|
@previewElement = jQuery('<div>', @document)
|
27
31
|
@element.append(@previewElement)
|
32
|
+
@container = @element
|
33
|
+
@container.data('region', @)
|
28
34
|
@element = @textarea
|
29
35
|
@resize()
|
30
36
|
|
31
37
|
|
32
|
-
focus: ->
|
33
|
-
@element.focus()
|
34
|
-
|
35
|
-
|
36
38
|
bindEvents: ->
|
37
|
-
Mercury.
|
38
|
-
|
39
|
+
Mercury.on 'mode', (event, options) => @togglePreview() if options.mode == 'preview'
|
40
|
+
Mercury.on 'focus:frame', => @focus() if !@previewing && Mercury.region == @
|
39
41
|
|
40
|
-
Mercury.
|
41
|
-
return if @previewing
|
42
|
-
return unless Mercury.region == @
|
43
|
-
@focus()
|
44
|
-
|
45
|
-
Mercury.bind 'action', (event, options) =>
|
46
|
-
return if @previewing
|
47
|
-
return unless Mercury.region == @
|
42
|
+
Mercury.on 'action', (event, options) =>
|
43
|
+
return if @previewing || Mercury.region != @
|
48
44
|
@execCommand(options.action, options) if options.action
|
49
45
|
|
50
|
-
Mercury.
|
51
|
-
return if @previewing
|
52
|
-
return unless Mercury.region == @
|
46
|
+
Mercury.on 'unfocus:regions', =>
|
47
|
+
return if @previewing || Mercury.region != @
|
53
48
|
@element.blur()
|
54
|
-
@
|
49
|
+
@container.removeClass('focus')
|
55
50
|
Mercury.trigger('region:blurred', {region: @})
|
56
51
|
|
57
|
-
@element.
|
52
|
+
@element.on 'dragenter', (event) =>
|
58
53
|
return if @previewing
|
59
54
|
event.preventDefault()
|
60
55
|
event.originalEvent.dataTransfer.dropEffect = 'copy'
|
61
56
|
|
62
|
-
@element.
|
57
|
+
@element.on 'dragover', (event) =>
|
63
58
|
return if @previewing
|
64
59
|
event.preventDefault()
|
65
60
|
event.originalEvent.dataTransfer.dropEffect = 'copy'
|
66
61
|
|
67
|
-
@element.
|
62
|
+
@element.on 'drop', (event) =>
|
68
63
|
return if @previewing
|
69
64
|
|
70
65
|
# handle dropping snippets
|
@@ -79,15 +74,14 @@ class @Mercury.Regions.Markupable extends Mercury.Region
|
|
79
74
|
@focus()
|
80
75
|
Mercury.uploader(event.originalEvent.dataTransfer.files[0])
|
81
76
|
|
82
|
-
@element.focus =>
|
77
|
+
@element.on 'focus', =>
|
83
78
|
return if @previewing
|
84
79
|
Mercury.region = @
|
85
|
-
@
|
80
|
+
@container.addClass('focus')
|
86
81
|
Mercury.trigger('region:focused', {region: @})
|
87
82
|
|
88
|
-
@element.keydown (event) =>
|
83
|
+
@element.on 'keydown', (event) =>
|
89
84
|
return if @previewing
|
90
|
-
Mercury.changes = true
|
91
85
|
@resize()
|
92
86
|
switch event.keyCode
|
93
87
|
when 90 # undo / redo
|
@@ -133,17 +127,23 @@ class @Mercury.Regions.Markupable extends Mercury.Region
|
|
133
127
|
|
134
128
|
@pushHistory(event.keyCode)
|
135
129
|
|
136
|
-
@element.keyup =>
|
130
|
+
@element.on 'keyup', =>
|
137
131
|
return if @previewing
|
132
|
+
Mercury.changes = true
|
133
|
+
@resize()
|
138
134
|
Mercury.trigger('region:update', {region: @})
|
139
135
|
|
140
|
-
@element.mouseup =>
|
136
|
+
@element.on 'mouseup', =>
|
141
137
|
return if @previewing
|
142
138
|
@focus()
|
143
139
|
Mercury.trigger('region:focused', {region: @})
|
144
140
|
|
145
|
-
@previewElement.click (event) =>
|
146
|
-
$(event.target).closest('a').attr('target', '
|
141
|
+
@previewElement.on 'click', (event) =>
|
142
|
+
$(event.target).closest('a').attr('target', '_parent') if @previewing
|
143
|
+
|
144
|
+
|
145
|
+
focus: ->
|
146
|
+
@element.focus()
|
147
147
|
|
148
148
|
|
149
149
|
content: (value = null, filterSnippets = true) ->
|
@@ -163,14 +163,19 @@ class @Mercury.Regions.Markupable extends Mercury.Region
|
|
163
163
|
|
164
164
|
togglePreview: ->
|
165
165
|
if @previewing
|
166
|
+
@previewing = false
|
167
|
+
@container.addClass(Mercury.config.regions.className).removeClass("#{Mercury.config.regions.className}-preview")
|
166
168
|
@previewElement.hide()
|
167
169
|
@element.show()
|
170
|
+
@focus() if Mercury.region == @
|
168
171
|
else
|
172
|
+
@previewing = true
|
173
|
+
@container.addClass("#{Mercury.config.regions.className}-preview").removeClass(Mercury.config.regions.className)
|
169
174
|
value = @converter.makeHtml(@element.val())
|
170
175
|
@previewElement.html(value)
|
171
176
|
@previewElement.show()
|
172
177
|
@element.hide()
|
173
|
-
|
178
|
+
Mercury.trigger('region:blurred', {region: @})
|
174
179
|
|
175
180
|
|
176
181
|
execCommand: (action, options = {}) ->
|
@@ -195,7 +200,7 @@ class @Mercury.Regions.Markupable extends Mercury.Region
|
|
195
200
|
@history.push(@contentAndSelection())
|
196
201
|
else if keyCode
|
197
202
|
# set a timeout for pushing to the history
|
198
|
-
@historyTimeout = setTimeout(
|
203
|
+
@historyTimeout = setTimeout(waitTime * 1000, => @history.push(@contentAndSelection()))
|
199
204
|
else
|
200
205
|
# push to the history immediately
|
201
206
|
@history.push(@contentAndSelection())
|
@@ -208,9 +213,8 @@ class @Mercury.Regions.Markupable extends Mercury.Region
|
|
208
213
|
|
209
214
|
|
210
215
|
resize: ->
|
211
|
-
|
212
|
-
|
213
|
-
# @textarea.height(adjustedHeight) if adjustedHeight >= @textarea.get(0).clientHeight
|
216
|
+
@element.css({height: @element.get(0).scrollHeight - 100})
|
217
|
+
@element.css({height: @element.get(0).scrollHeight});
|
214
218
|
|
215
219
|
|
216
220
|
snippets: ->
|
@@ -231,6 +235,9 @@ class @Mercury.Regions.Markupable extends Mercury.Region
|
|
231
235
|
insertImage: (selection, options) ->
|
232
236
|
selection.replace('![add alt text](' + encodeURI(options.value.src) + ')', true)
|
233
237
|
|
238
|
+
insertTable: (selection, options) ->
|
239
|
+
selection.replace(options.value.replace(/<br>|<br\/>/ig, ''), false, true)
|
240
|
+
|
234
241
|
insertLink: (selection, options) ->
|
235
242
|
selection.replace("[#{options.value.content}](#{options.value.attrs.href} 'optional title')", true)
|
236
243
|
|