mercury-rails 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. data/README.rdoc +81 -50
  2. data/VERSION +1 -1
  3. data/app/assets/javascripts/mercury/dialog.js.coffee +4 -4
  4. data/app/assets/javascripts/mercury/dialogs/backcolor.js.coffee +3 -3
  5. data/app/assets/javascripts/mercury/dialogs/forecolor.js.coffee +3 -3
  6. data/app/assets/javascripts/mercury/dialogs/formatblock.js.coffee +1 -1
  7. data/app/assets/javascripts/mercury/dialogs/objectspanel.js.coffee +3 -3
  8. data/app/assets/javascripts/mercury/dialogs/style.js.coffee +1 -1
  9. data/app/assets/javascripts/mercury/history_buffer.js.coffee +2 -2
  10. data/app/assets/javascripts/mercury/mercury.js.coffee +47 -54
  11. data/app/assets/javascripts/mercury/modal.js.coffee +13 -13
  12. data/app/assets/javascripts/mercury/modals/htmleditor.js.coffee +2 -2
  13. data/app/assets/javascripts/mercury/modals/insertcharacter.js.coffee +2 -2
  14. data/app/assets/javascripts/mercury/modals/insertlink.js.coffee +7 -7
  15. data/app/assets/javascripts/mercury/modals/insertmedia.js.coffee +5 -5
  16. data/app/assets/javascripts/mercury/modals/insertsnippet.js.coffee +2 -2
  17. data/app/assets/javascripts/mercury/modals/inserttable.js.coffee +14 -15
  18. data/app/assets/javascripts/mercury/native_extensions.js.coffee +2 -1
  19. data/app/assets/javascripts/mercury/page_editor.js.coffee +27 -27
  20. data/app/assets/javascripts/mercury/palette.js.coffee +6 -6
  21. data/app/assets/javascripts/mercury/panel.js.coffee +4 -4
  22. data/app/assets/javascripts/mercury/region.js.coffee +9 -9
  23. data/app/assets/javascripts/mercury/regions/editable.js.coffee +71 -71
  24. data/app/assets/javascripts/mercury/regions/markupable.js.coffee +51 -42
  25. data/app/assets/javascripts/mercury/regions/snippetable.js.coffee +7 -8
  26. data/app/assets/javascripts/mercury/select.js.coffee +8 -8
  27. data/app/assets/javascripts/mercury/snippet.js.coffee +6 -6
  28. data/app/assets/javascripts/mercury/snippet_toolbar.js.coffee +7 -7
  29. data/app/assets/javascripts/mercury/statusbar.js.coffee +7 -3
  30. data/app/assets/javascripts/mercury/table_editor.js.coffee +24 -24
  31. data/app/assets/javascripts/mercury/toolbar.button.js.coffee +20 -21
  32. data/app/assets/javascripts/mercury/toolbar.button_group.js.coffee +2 -2
  33. data/app/assets/javascripts/mercury/toolbar.expander.js.coffee +9 -9
  34. data/app/assets/javascripts/mercury/toolbar.js.coffee +12 -13
  35. data/app/assets/javascripts/mercury/tooltip.js.coffee +7 -7
  36. data/app/assets/javascripts/mercury/uploader.js.coffee +12 -13
  37. data/app/assets/javascripts/mercury_loader.js +98 -0
  38. data/app/assets/stylesheets/mercury/modal.scss +5 -5
  39. data/app/assets/stylesheets/mercury/toolbar.scss +62 -64
  40. data/app/views/layouts/mercury.html.haml +0 -4
  41. data/app/views/mercury/modals/character.html.haml +1 -1
  42. data/app/views/mercury/modals/htmleditor.html.haml +1 -1
  43. data/app/views/mercury/modals/table.html.haml +10 -10
  44. data/config/routes.rb +2 -2
  45. data/mercury-rails.gemspec +17 -20
  46. data/spec/javascripts/mercury/dialogs/backcolor_spec.js.coffee +3 -3
  47. data/spec/javascripts/mercury/dialogs/forecolor_spec.js.coffee +3 -3
  48. data/spec/javascripts/mercury/dialogs/objectspanel_spec.js.coffee +3 -3
  49. data/spec/javascripts/mercury/modals/htmleditor_spec.js.coffee +4 -4
  50. data/spec/javascripts/mercury/modals/insertcharacter_spec.js.coffee +2 -2
  51. data/spec/javascripts/mercury/modals/insertlink_spec.js.coffee +10 -10
  52. data/spec/javascripts/mercury/modals/insertmedia_spec.js.coffee +7 -7
  53. data/spec/javascripts/mercury/modals/insertsnippet_spec.js.coffee +4 -4
  54. data/spec/javascripts/mercury/modals/inserttable_spec.js.coffee +17 -17
  55. data/spec/javascripts/mercury/page_editor_spec.js.coffee +5 -6
  56. data/spec/javascripts/mercury/region_spec.js.coffee +5 -5
  57. data/spec/javascripts/mercury/regions/editable_spec.js.coffee +398 -0
  58. data/spec/javascripts/mercury/regions/snippetable_spec.js.coffee +18 -14
  59. data/spec/javascripts/mercury/snippet_spec.js.coffee +1 -1
  60. data/spec/javascripts/mercury/toolbar.button_spec.js.coffee +16 -16
  61. data/spec/javascripts/templates/mercury/modals/inserttable.html +11 -11
  62. data/spec/javascripts/templates/mercury/regions/editable.html +3 -0
  63. data/spec/javascripts/templates/mercury/toolbar.button.html +8 -8
  64. data/vendor/assets/javascripts/{jquery-ui-1.8.13.sortable.custom.js → jquery-ui-1.8.13.custom.js} +250 -0
  65. data/vendor/assets/javascripts/jquery.additions.js +151 -0
  66. data/vendor/assets/javascripts/showdown.js +1254 -1276
  67. metadata +26 -29
  68. data/app/assets/javascripts/mercury/websocket.js.coffee +0 -34
  69. data/spec/javascripts/mercury/regions/_editable_.js.coffee +0 -0
  70. data/vendor/assets/javascripts/jquery-ui-1.8.13.custom.min.js +0 -249
  71. data/vendor/assets/javascripts/jquery.easing.js +0 -173
  72. data/vendor/assets/javascripts/jquery.json2.js +0 -178
  73. data/vendor/assets/javascripts/jquery.serialize_object.js +0 -16
  74. data/vendor/assets/javascripts/jquery.ujs.js +0 -289
@@ -8,14 +8,14 @@ class @Mercury.Regions.Editable extends Mercury.Region
8
8
 
9
9
  build: ->
10
10
  # mozilla: set some initial content so everything works correctly
11
- @html(' ') if $.browser.mozilla && @html() == ''
11
+ @content(' ') if jQuery.browser.mozilla && @content() == ''
12
12
 
13
13
  # set overflow just in case
14
14
  @element.data({originalOverflow: @element.css('overflow')})
15
15
  @element.css({overflow: 'auto'})
16
16
 
17
17
  # mozilla: there's some weird behavior when the element isn't a div
18
- @specialContainer = $.browser.mozilla && @element.get(0).tagName != 'DIV'
18
+ @specialContainer = jQuery.browser.mozilla && @element.get(0).tagName != 'DIV'
19
19
 
20
20
  # make it editable
21
21
  # gecko: in this makes double clicking in textareas fail: https://bugzilla.mozilla.org/show_bug.cgi?id=490367
@@ -24,7 +24,7 @@ class @Mercury.Regions.Editable extends Mercury.Region
24
24
  # make all snippets not editable, and set their versions to 1
25
25
  for element in @element.find('.mercury-snippet')
26
26
  element.contentEditable = false
27
- $(element).attr('data-version', '1')
27
+ jQuery(element).attr('data-version', '1')
28
28
 
29
29
  # add the basic editor settings to the document (only once)
30
30
  unless @document.mercuryEditing
@@ -46,7 +46,7 @@ class @Mercury.Regions.Editable extends Mercury.Region
46
46
  if currentElement.length
47
47
  # setup the table editor if we're inside a table
48
48
  table = currentElement.closest('table', @element)
49
- Mercury.tableEditor(table, currentElement) if table.length
49
+ Mercury.tableEditor(table, currentElement.closest('tr, td')) if table.length
50
50
  # display a tooltip if we're in an anchor
51
51
  anchor = currentElement.closest('a', @element)
52
52
  if anchor.length && anchor.attr('href')
@@ -63,7 +63,7 @@ class @Mercury.Regions.Editable extends Mercury.Region
63
63
  return if @previewing
64
64
  event.preventDefault() if event.shiftKey
65
65
  event.originalEvent.dataTransfer.dropEffect = 'copy'
66
- if $.browser.webkit
66
+ if jQuery.browser.webkit
67
67
  clearTimeout(@dropTimeout)
68
68
  @dropTimeout = setTimeout((=> @element.trigger('possible:drop')), 10)
69
69
 
@@ -89,7 +89,7 @@ class @Mercury.Regions.Editable extends Mercury.Region
89
89
  return if @previewing
90
90
  if snippet = @element.find('img[data-snippet]').get(0)
91
91
  @focus()
92
- Mercury.Snippet.displayOptionsFor($(snippet).data('snippet'))
92
+ Mercury.Snippet.displayOptionsFor(jQuery(snippet).data('snippet'))
93
93
  @document.execCommand('undo', false, null)
94
94
 
95
95
  # custom paste handling: we have to do some hackery to get the pasted content since it's not exposed normally
@@ -100,9 +100,9 @@ class @Mercury.Regions.Editable extends Mercury.Region
100
100
  return if @previewing
101
101
  return unless Mercury.region == @
102
102
  Mercury.changes = true
103
- html = @html()
103
+ content = @content()
104
104
  event.preventDefault() if @specialContainer
105
- setTimeout((=> @handlePaste(html)), 1)
105
+ setTimeout((=> @handlePaste(content)), 1)
106
106
 
107
107
  @element.focus =>
108
108
  return if @previewing
@@ -116,14 +116,14 @@ class @Mercury.Regions.Editable extends Mercury.Region
116
116
  Mercury.tooltip.hide()
117
117
 
118
118
  @element.click (event) =>
119
- $(event.target).closest('a').attr('target', '_top') if @previewing
119
+ jQuery(event.target).closest('a').attr('target', '_top') if @previewing
120
120
 
121
121
  @element.dblclick (event) =>
122
122
  return if @previewing
123
- image = $(event.target).closest('img', @element)
123
+ image = jQuery(event.target).closest('img', @element)
124
124
  if image.length
125
125
  @selection().selectNode(image.get(0), true)
126
- Mercury.trigger('button', {action: 'insertmedia'})
126
+ Mercury.trigger('button', {action: 'insertMedia'})
127
127
 
128
128
  @element.mouseup =>
129
129
  return if @previewing
@@ -134,7 +134,6 @@ class @Mercury.Regions.Editable extends Mercury.Region
134
134
  return if @previewing
135
135
  Mercury.changes = true
136
136
  switch event.keyCode
137
-
138
137
  when 90 # undo / redo
139
138
  return unless event.metaKey
140
139
  event.preventDefault()
@@ -142,9 +141,9 @@ class @Mercury.Regions.Editable extends Mercury.Region
142
141
  return
143
142
 
144
143
  when 13 # enter
145
- if $.browser.webkit && @selection().commonAncestor().closest('li, ul', @element).length == 0
144
+ if jQuery.browser.webkit && @selection().commonAncestor().closest('li, ul', @element).length == 0
146
145
  event.preventDefault()
147
- @document.execCommand('insertlinebreak', false, null)
146
+ @document.execCommand('insertLineBreak', false, null)
148
147
  else if @specialContainer
149
148
  # mozilla: pressing enter in any elemeny besides a div handles strangely
150
149
  event.preventDefault()
@@ -164,7 +163,6 @@ class @Mercury.Regions.Editable extends Mercury.Region
164
163
 
165
164
  if event.metaKey
166
165
  switch event.keyCode
167
-
168
166
  when 66 # b
169
167
  @execCommand('bold')
170
168
  event.preventDefault()
@@ -190,16 +188,16 @@ class @Mercury.Regions.Editable extends Mercury.Region
190
188
  Mercury.trigger('region:update', {region: @})
191
189
 
192
190
 
193
- html: (value = null, filterSnippets = true, includeMarker = false) ->
191
+ content: (value = null, filterSnippets = true, includeMarker = false) ->
194
192
  if value != null
195
193
  # sanitize the html before we insert it
196
- container = $('<div>').appendTo(@document.createDocumentFragment())
194
+ container = jQuery('<div>').appendTo(@document.createDocumentFragment())
197
195
  container.html(value)
198
196
 
199
197
  # fill in the snippet contents
200
198
  for element in container.find('[data-snippet]')
201
199
  element.contentEditable = false
202
- element = $(element)
200
+ element = jQuery(element)
203
201
  if snippet = Mercury.Snippet.find(element.data('snippet'))
204
202
  unless element.data('version')
205
203
  try
@@ -225,24 +223,24 @@ class @Mercury.Regions.Editable extends Mercury.Region
225
223
  selection.placeMarker()
226
224
 
227
225
  # sanitize the html before we return it
228
- container = $('<div>').appendTo(@document.createDocumentFragment())
226
+ container = jQuery('<div>').appendTo(@document.createDocumentFragment())
229
227
  container.html(@element.html().replace(/^\s+|\s+$/g, ''))
230
228
 
231
229
  # replace snippet contents to be an identifier
232
230
  if filterSnippets then for element, index in container.find('[data-snippet]')
233
- element = $(element)
231
+ element = jQuery(element)
234
232
  if snippet = Mercury.Snippet.find(element.data("snippet"))
235
233
  snippet.data = element.html()
236
234
  element.html("[#{element.data("snippet")}/#{element.data("version")}]")
237
235
  element.attr({contenteditable: null, 'data-version': null})
238
236
 
239
237
  # get the html before removing the markers
240
- html = container.html()
238
+ content = container.html()
241
239
 
242
240
  # remove the markers from the dom
243
241
  selection.removeMarker() if includeMarker
244
242
 
245
- return html
243
+ return content
246
244
 
247
245
 
248
246
  togglePreview: ->
@@ -250,7 +248,7 @@ class @Mercury.Regions.Editable extends Mercury.Region
250
248
  @element.get(0).contentEditable = true
251
249
  @element.css({overflow: 'auto'})
252
250
  else
253
- @html(@html())
251
+ @content(@content())
254
252
  @element.get(0).contentEditable = false
255
253
  @element.css({overflow: @element.data('originalOverflow')})
256
254
  @element.blur()
@@ -265,7 +263,7 @@ class @Mercury.Regions.Editable extends Mercury.Region
265
263
  handler.call(@, @selection(), options)
266
264
  else
267
265
  sibling = @element.get(0).previousSibling if action == 'indent'
268
- options.value = $('<div>').html(options.value).html() if action == 'insertHTML' && options.value && options.value.get
266
+ options.value = jQuery('<div>').html(options.value).html() if action == 'insertHTML' && options.value && options.value.get
269
267
  try
270
268
  @document.execCommand(action, false, options.value)
271
269
  catch error
@@ -285,13 +283,13 @@ class @Mercury.Regions.Editable extends Mercury.Region
285
283
 
286
284
  # if the key code was return, delete, or backspace store now -- unless it was the same as last time
287
285
  if knownKeyCode >= 0 && knownKeyCode != @lastKnownKeyCode # || !keyCode
288
- @history.push(@html(null, false, true))
286
+ @history.push(@content(null, false, true))
289
287
  else if keyCode
290
288
  # set a timeout for pushing to the history
291
- @historyTimeout = setTimeout((=> @history.push(@html(null, false, true))), waitTime * 1000)
289
+ @historyTimeout = setTimeout((=> @history.push(@content(null, false, true))), waitTime * 1000)
292
290
  else
293
291
  # push to the history immediately
294
- @history.push(@html(null, false, true))
292
+ @history.push(@content(null, false, true))
295
293
 
296
294
  @lastKnownKeyCode = knownKeyCode
297
295
 
@@ -315,33 +313,33 @@ class @Mercury.Regions.Editable extends Mercury.Region
315
313
  return element
316
314
 
317
315
 
318
- handlePaste: (prePasteHTML) ->
319
- prePasteHTML = prePasteHTML.replace(/^\<br\>/, '')
316
+ handlePaste: (prePasteContent) ->
317
+ prePasteContent = prePasteContent.replace(/^\<br\>/, '')
320
318
 
321
319
  # remove any regions that might have been pasted
322
320
  @element.find('.mercury-region').remove()
323
321
 
324
322
  # handle pasting from ms office etc
325
- html = @html()
326
- if html.indexOf('<!--StartFragment-->') > -1 || html.indexOf('="mso-') > -1 || html.indexOf('<o:') > -1 || html.indexOf('="Mso') > -1
323
+ content = @content()
324
+ if content.indexOf('<!--StartFragment-->') > -1 || content.indexOf('="mso-') > -1 || content.indexOf('<o:') > -1 || content.indexOf('="Mso') > -1
327
325
  # clean out all the tags from the pasted contents
328
- cleaned = prePasteHTML.singleDiff(@html()).sanitizeHTML()
326
+ cleaned = prePasteContent.singleDiff(@content()).sanitizeHTML()
329
327
  try
330
328
  # try to undo and put the cleaned html where the selection was
331
329
  @document.execCommand('undo', false, null)
332
330
  @execCommand('insertHTML', {value: cleaned})
333
331
  catch error
334
332
  # remove the pasted html and load up the cleaned contents into a modal
335
- @html(prePasteHTML)
333
+ @content(prePasteContent)
336
334
  Mercury.modal '/mercury/modals/sanitizer', {
337
335
  title: 'HTML Sanitizer (Starring Clippy)',
338
336
  afterLoad: -> @element.find('textarea').val(cleaned.replace(/<br\/>/g, '\n'))
339
337
  }
340
338
  else if Mercury.config.cleanStylesOnPaste
341
339
  # strip styles
342
- pasted = prePasteHTML.singleDiff(@html())
340
+ pasted = prePasteContent.singleDiff(@content())
343
341
 
344
- container = $('<div>').appendTo(@document.createDocumentFragment()).html(pasted)
342
+ container = jQuery('<div>').appendTo(@document.createDocumentFragment()).html(pasted)
345
343
  container.find('[style]').attr({style: null})
346
344
 
347
345
  @document.execCommand('undo', false, null)
@@ -350,64 +348,64 @@ class @Mercury.Regions.Editable extends Mercury.Region
350
348
 
351
349
  # Custom actions (eg. things that execCommand doesn't do, or doesn't do well)
352
350
  @actions: {
353
- insertrowbefore: -> Mercury.tableEditor.addRow('before')
351
+ insertRowBefore: -> Mercury.tableEditor.addRow('before')
354
352
 
355
- insertrowafter: -> Mercury.tableEditor.addRow('after')
353
+ insertRowAfter: -> Mercury.tableEditor.addRow('after')
356
354
 
357
- insertcolumnbefore: -> Mercury.tableEditor.addColumn('before')
355
+ insertColumnBefore: -> Mercury.tableEditor.addColumn('before')
358
356
 
359
- insertcolumnafter: -> Mercury.tableEditor.addColumn('after')
357
+ insertColumnAfter: -> Mercury.tableEditor.addColumn('after')
360
358
 
361
- deletecolumn: -> Mercury.tableEditor.removeColumn()
359
+ deleteColumn: -> Mercury.tableEditor.removeColumn()
362
360
 
363
- deleterow: -> Mercury.tableEditor.removeRow()
361
+ deleteRow: -> Mercury.tableEditor.removeRow()
364
362
 
365
- increasecolspan: -> Mercury.tableEditor.increaseColspan()
363
+ increaseColspan: -> Mercury.tableEditor.increaseColspan()
366
364
 
367
- decreasecolspan: -> Mercury.tableEditor.decreaseColspan()
365
+ decreaseColspan: -> Mercury.tableEditor.decreaseColspan()
368
366
 
369
- increaserowspan: -> Mercury.tableEditor.increaseRowspan()
367
+ increaseRowspan: -> Mercury.tableEditor.increaseRowspan()
370
368
 
371
- decreaserowspan: -> Mercury.tableEditor.decreaseRowspan()
369
+ decreaseRowspan: -> Mercury.tableEditor.decreaseRowspan()
372
370
 
373
- undo: -> @html(@history.undo())
371
+ undo: -> @content(@history.undo())
374
372
 
375
- redo: -> @html(@history.redo())
373
+ redo: -> @content(@history.redo())
376
374
 
377
- removeformatting: (selection) -> selection.insertTextNode(selection.textContent())
375
+ removeFormatting: (selection) -> selection.insertTextNode(selection.textContent())
378
376
 
379
- backcolor: (selection, options) -> selection.wrap("<span style=\"background-color:#{options.value.toHex()}\">", true)
377
+ backColor: (selection, options) -> selection.wrap("<span style=\"background-color:#{options.value.toHex()}\">", true)
380
378
 
381
379
  overline: (selection) -> selection.wrap('<span style="text-decoration:overline">', true)
382
380
 
383
381
  style: (selection, options) -> selection.wrap("<span class=\"#{options.value}\">", true)
384
382
 
385
- replaceHTML: (selection, options) -> @html(options.value)
383
+ replaceHTML: (selection, options) -> @content(options.value)
386
384
 
387
- insertImage: (selection, options) -> @execCommand('insertHTML', {value: $('<img/>', options.value)})
385
+ insertImage: (selection, options) -> @execCommand('insertHTML', {value: jQuery('<img/>', options.value)})
388
386
 
389
387
  insertLink: (selection, options) ->
390
- anchor = $("<#{options.value.tagName}>").attr(options.value.attrs).html(options.value.content)
388
+ anchor = jQuery("<#{options.value.tagName}>").attr(options.value.attrs).html(options.value.content)
391
389
  selection.insertNode(anchor)
392
390
 
393
391
  replaceLink: (selection, options) ->
394
- anchor = $("<#{options.value.tagName}>").attr(options.value.attrs).html(options.value.content)
392
+ anchor = jQuery("<#{options.value.tagName}>").attr(options.value.attrs).html(options.value.content)
395
393
  selection.selectNode(options.node)
396
- html = $('<div>').html(selection.content()).find('a').html()
397
- selection.replace($(anchor, selection.context).html(html))
394
+ html = jQuery('<div>').html(selection.content()).find('a').html()
395
+ selection.replace(jQuery(anchor, selection.context).html(html))
398
396
 
399
- insertsnippet: (selection, options) ->
397
+ insertSnippet: (selection, options) ->
400
398
  snippet = options.value
401
399
  if (existing = @element.find("[data-snippet=#{snippet.identity}]")).length
402
400
  selection.selectNode(existing.get(0))
403
401
  selection.insertNode(snippet.getHTML(@document))
404
402
 
405
- editsnippet: ->
403
+ editSnippet: ->
406
404
  return unless @snippet
407
405
  snippet = Mercury.Snippet.find(@snippet.data('snippet'))
408
406
  snippet.displayOptions()
409
407
 
410
- removesnippet: ->
408
+ removeSnippet: ->
411
409
  @snippet.remove() if @snippet
412
410
  Mercury.trigger('hide:toolbar', {type: 'snippet', immediately: true})
413
411
  }
@@ -427,11 +425,11 @@ class Mercury.Regions.Editable.Selection
427
425
  return null unless @range
428
426
  ancestor = @range.commonAncestorContainer
429
427
  ancestor = ancestor.parentNode if ancestor.nodeType == 3 && onlyTag
430
- return $(ancestor)
428
+ return jQuery(ancestor)
431
429
 
432
430
 
433
431
  wrap: (element, replace = false) ->
434
- element = $(element, @context).html(@fragment)
432
+ element = jQuery(element, @context).html(@fragment)
435
433
  @replace(element) if replace
436
434
  return element
437
435
 
@@ -446,24 +444,26 @@ class Mercury.Regions.Editable.Selection
446
444
 
447
445
  is: (elementType) ->
448
446
  content = @content()
449
- return $(content.firstChild) if content.childNodes.length == 1 && $(content.firstChild).is(elementType)
447
+ return jQuery(content.firstChild) if content.childNodes.length == 1 && jQuery(content.firstChild).is(elementType)
450
448
  return false
451
449
 
452
450
 
453
451
  forceSelection: (element) ->
454
- return unless $.browser.webkit
452
+ return unless jQuery.browser.webkit
455
453
  range = @context.createRange()
456
454
 
455
+ # todo: the \00 thing breaks when using uglifier, and is escapped to "0".. it's been fixed, but isn't available yet
456
+ # https://github.com/lautis/uglifier/issues/11
457
457
  if @range
458
458
  if @commonAncestor(true).closest('.mercury-snippet').length
459
- lastChild = @context.createTextNode('\00')
459
+ lastChild = @context.createTextNode(' ') #\00
460
460
  element.appendChild(lastChild)
461
461
  else
462
462
  if element.lastChild && element.lastChild.nodeType == 3 && element.lastChild.textContent.replace(/^[\s+|\n+]|[\s+|\n+]$/, '') == ''
463
463
  lastChild = element.lastChild
464
- element.lastChild.textContent = '\00'
464
+ element.lastChild.textContent = ' ' #\00
465
465
  else
466
- lastChild = @context.createTextNode('\00')
466
+ lastChild = @context.createTextNode(' ') #\00
467
467
  element.appendChild(lastChild)
468
468
 
469
469
  if lastChild
@@ -489,8 +489,8 @@ class Mercury.Regions.Editable.Selection
489
489
  placeMarker: ->
490
490
  return unless @range
491
491
 
492
- @startMarker = $('<em class="mercury-marker"/>', @context).get(0)
493
- @endMarker = $('<em class="mercury-marker"/>', @context).get(0)
492
+ @startMarker = jQuery('<em class="mercury-marker"/>', @context).get(0)
493
+ @endMarker = jQuery('<em class="mercury-marker"/>', @context).get(0)
494
494
 
495
495
  # put a single marker (the end)
496
496
  rangeEnd = @range.cloneRange()
@@ -508,8 +508,8 @@ class Mercury.Regions.Editable.Selection
508
508
 
509
509
 
510
510
  removeMarker: ->
511
- $(@startMarker).remove()
512
- $(@endMarker).remove()
511
+ jQuery(@startMarker).remove()
512
+ jQuery(@endMarker).remove()
513
513
 
514
514
 
515
515
  insertTextNode: (string) ->
@@ -522,7 +522,7 @@ class Mercury.Regions.Editable.Selection
522
522
 
523
523
  insertNode: (element) ->
524
524
  element = element.get(0) if element.get
525
- element = $(element, @context).get(0) if $.type(element) == 'string'
525
+ element = jQuery(element, @context).get(0) if jQuery.type(element) == 'string'
526
526
 
527
527
  @range.deleteContents()
528
528
  @range.insertNode(element)
@@ -538,7 +538,7 @@ class Mercury.Regions.Editable.Selection
538
538
 
539
539
  replace: (element) ->
540
540
  element = element.get(0) if element.get
541
- element = $(element, @context).get(0) if $.type(element) == 'string'
541
+ element = jQuery(element, @context).get(0) if jQuery.type(element) == 'string'
542
542
 
543
543
  @range.deleteContents()
544
544
  @range.insertNode(element)
@@ -18,16 +18,19 @@ class @Mercury.Regions.Markupable extends Mercury.Region
18
18
  height = @element.height()
19
19
 
20
20
  value = @element.html().replace(/^\s+|\s+$/g, '')
21
- @textarea = $('<textarea>', @document).val(value)
21
+ @textarea = jQuery('<textarea>', @document).val(value)
22
22
  @textarea.attr('class', @element.attr('class')).addClass('mercury-textarea')
23
23
  @textarea.css({border: 0, background: 'transparent', display: 'block', width: width, height: height, fontFamily: '"Courier New", Courier, monospace', fontSize: '14px'})
24
24
  @element.after(@textarea)
25
25
  @element.hide()
26
26
  @resize()
27
27
 
28
+ @previewElement = @element
29
+ @element = @textarea
30
+
28
31
 
29
32
  focus: ->
30
- @textarea.focus()
33
+ @element.focus()
31
34
 
32
35
 
33
36
  bindEvents: ->
@@ -44,17 +47,24 @@ class @Mercury.Regions.Markupable extends Mercury.Region
44
47
  return unless Mercury.region == @
45
48
  @execCommand(options.action, options) if options.action
46
49
 
47
- @textarea.bind 'dragenter', (event) =>
50
+ Mercury.bind 'unfocus:regions', (event) =>
51
+ return if @previewing
52
+ if Mercury.region == @
53
+ @element.blur()
54
+ @element.removeClass('focus')
55
+ Mercury.trigger('region:blurred', {region: @})
56
+
57
+ @element.bind 'dragenter', (event) =>
48
58
  return if @previewing
49
59
  event.preventDefault()
50
60
  event.originalEvent.dataTransfer.dropEffect = 'copy'
51
61
 
52
- @textarea.bind 'dragover', (event) =>
62
+ @element.bind 'dragover', (event) =>
53
63
  return if @previewing
54
64
  event.preventDefault()
55
65
  event.originalEvent.dataTransfer.dropEffect = 'copy'
56
66
 
57
- @textarea.bind 'drop', (event) =>
67
+ @element.bind 'drop', (event) =>
58
68
  return if @previewing
59
69
 
60
70
  # handle dropping snippets
@@ -69,26 +79,20 @@ class @Mercury.Regions.Markupable extends Mercury.Region
69
79
  @focus()
70
80
  Mercury.uploader(event.originalEvent.dataTransfer.files[0])
71
81
 
72
- @textarea.focus =>
82
+ @element.focus =>
73
83
  return if @previewing
74
84
  Mercury.region = @
75
- @textarea.addClass('focus')
85
+ @element.addClass('focus')
76
86
  Mercury.trigger('region:focused', {region: @})
77
87
 
78
- @textarea.blur =>
79
- return if @previewing
80
- @textarea.removeClass('focus')
81
- Mercury.trigger('region:blurred', {region: @})
82
-
83
- @textarea.keydown (event) =>
88
+ @element.keydown (event) =>
84
89
  return if @previewing
85
90
  Mercury.changes = true
86
91
  @resize()
87
92
  switch event.keyCode
88
-
89
93
  when 13 # enter or return
90
94
  selection = @selection()
91
- text = @textarea.val()
95
+ text = @element.val()
92
96
  start = text.lastIndexOf('\n', selection.start)
93
97
  end = text.indexOf('\n', selection.end)
94
98
  end = text.length if end < start
@@ -98,9 +102,7 @@ class @Mercury.Regions.Markupable extends Mercury.Region
98
102
  event.preventDefault()
99
103
  if /\d/.test(text[start + 1])
100
104
  lineText = text.substring(start, end)
101
- console.debug(lineText)
102
105
  if /(\d+)\./.test(lineText)
103
- console.debug(2)
104
106
  number = parseInt(RegExp.$1)
105
107
  selection.replace("\n#{number += 1}. ", false, true)
106
108
  event.preventDefault()
@@ -113,7 +115,6 @@ class @Mercury.Regions.Markupable extends Mercury.Region
113
115
 
114
116
  if event.metaKey
115
117
  switch event.keyCode
116
-
117
118
  when 66 # b
118
119
  @execCommand('bold')
119
120
  event.preventDefault()
@@ -128,34 +129,41 @@ class @Mercury.Regions.Markupable extends Mercury.Region
128
129
 
129
130
  @pushHistory(event.keyCode)
130
131
 
131
- @textarea.keyup =>
132
+ @element.keyup =>
132
133
  return if @previewing
133
134
  Mercury.trigger('region:update', {region: @})
134
135
 
135
- @element.click (event) =>
136
+ @element.mouseup =>
137
+ return if @previewing
138
+ @focus()
139
+ Mercury.trigger('region:focused', {region: @})
140
+
141
+ @previewElement.click (event) =>
136
142
  $(event.target).closest('a').attr('target', '_top') if @previewing
137
143
 
138
144
 
139
- html: (value = null, filterSnippets = true) ->
145
+ content: (value = null, filterSnippets = true) ->
140
146
  if value != null
141
147
  if $.type(value) == 'string'
142
- @textarea.val(value)
148
+ @element.val(value)
149
+ if jQuery.type(value) == 'string'
150
+ @element.val(value)
143
151
  else
144
- @textarea.val(value.html)
152
+ @element.val(value.html)
145
153
  @selection().select(value.selection.start, value.selection.end)
146
154
  else
147
- return @textarea.val()
155
+ return @element.val()
148
156
 
149
157
 
150
158
  togglePreview: ->
151
159
  if @previewing
152
- @element.hide()
153
- @textarea.show()
154
- else
155
- value = @converter.makeHtml(@textarea.val())
156
- @element.html(value)
160
+ @previewElement.hide()
157
161
  @element.show()
158
- @textarea.hide()
162
+ else
163
+ value = @converter.makeHtml(@element.val())
164
+ @previewElement.html(value)
165
+ @previewElement.show()
166
+ @element.hide()
159
167
  super
160
168
 
161
169
 
@@ -167,7 +175,7 @@ class @Mercury.Regions.Markupable extends Mercury.Region
167
175
 
168
176
 
169
177
  htmlAndSelection: ->
170
- return {html: @html(null, false), selection: @selection().serialize()}
178
+ return {html: @content(null, false), selection: @selection().serialize()}
171
179
 
172
180
 
173
181
  pushHistory: (keyCode) ->
@@ -194,12 +202,13 @@ class @Mercury.Regions.Markupable extends Mercury.Region
194
202
 
195
203
 
196
204
  selection: ->
197
- return new Mercury.Regions.Markupable.Selection(@textarea)
205
+ return new Mercury.Regions.Markupable.Selection(@element)
198
206
 
199
207
 
200
208
  resize: ->
201
- # adjustedHeight = Math.max(@textarea.get(0).scrollHeight, @textarea.get(0).clientHeight)
202
- # @textarea.height(adjustedHeight) if adjustedHeight >= @textarea.get(0).clientHeight
209
+ # todo: get this working if possible, and it seems to be useful
210
+ # adjustedHeight = Math.max(@textarea.get(0).scrollHeight, @textarea.get(0).clientHeight)
211
+ # @textarea.height(adjustedHeight) if adjustedHeight >= @textarea.get(0).clientHeight
203
212
 
204
213
 
205
214
  snippets: ->
@@ -208,13 +217,13 @@ class @Mercury.Regions.Markupable extends Mercury.Region
208
217
  # Actions
209
218
  @actions: {
210
219
 
211
- undo: -> @html(@history.undo())
220
+ undo: -> @content(@history.undo())
212
221
 
213
- redo: -> @html(@history.redo())
222
+ redo: -> @content(@history.redo())
214
223
 
215
224
  insertHTML: (selection, options) ->
216
225
  if options.value.get && element = options.value.get(0)
217
- options.value = $('<div>').html(element).html()
226
+ options.value = jQuery('<div>').html(element).html()
218
227
  selection.replace(options.value, false, true)
219
228
 
220
229
  insertImage: (selection, options) ->
@@ -223,9 +232,9 @@ class @Mercury.Regions.Markupable extends Mercury.Region
223
232
  insertLink: (selection, options) ->
224
233
  selection.replace("[#{options.value.content}](#{options.value.attrs.href} 'optional title')", true)
225
234
 
226
- insertunorderedlist: (selection) -> selection.addList('unordered')
235
+ insertUnorderedList: (selection) -> selection.addList('unordered')
227
236
 
228
- insertorderedlist: (selection) -> selection.addList('ordered')
237
+ insertOrderedList: (selection) -> selection.addList('ordered')
229
238
 
230
239
  style: (selection, options) -> selection.wrap("<span class=\"#{options.value}\">", '</span>')
231
240
 
@@ -261,9 +270,9 @@ class @Mercury.Regions.Markupable extends Mercury.Region
261
270
  outdent: (selection) ->
262
271
  selection.unWrapLine('> ', '', false, true)
263
272
 
264
- horizontalrule: (selection) -> selection.replace('\n- - -\n')
273
+ horizontalRule: (selection) -> selection.replace('\n- - -\n')
265
274
 
266
- insertsnippet: (selection, options) ->
275
+ insertSnippet: (selection, options) ->
267
276
  snippet = options.value
268
277
  selection.replace(snippet.getText())
269
278
 
@@ -377,4 +386,4 @@ class Mercury.Regions.Markupable.Selection
377
386
 
378
387
 
379
388
  textContent: ->
380
- return @text
389
+ return @text