Skip to content

Commit

Permalink
added undo managing and pairs file
Browse files Browse the repository at this point in the history
  • Loading branch information
Jeremy Jackson & Terrence Lee committed May 17, 2011
1 parent 40c1228 commit 2d1fbc5
Show file tree
Hide file tree
Showing 10 changed files with 193 additions and 27 deletions.
16 changes: 16 additions & 0 deletions .pairs
@@ -0,0 +1,16 @@
pairs:
aw: Alex Welch; alex.welch
an: Anthony Navarre; anthony.navarre
jz: Jay Zeschin; jay.zeschin
br: Brian Rose; brian.rose
dp: Don Petersen; don.petersen
jj: Jeremy Jackson; jeremy.jackson
aj: Andrew Jaswa; andrew.jaswa
jg: Justin Gitlin; justin.gitlin
gv: Gabe Varela; gabe.varela
mk: Matt Kitt; matt.kitt
cw: Craig Williams; craig.williams
tl: Terrence Lee; terrence.lee
email:
prefix: pair
domain: factorylabs.com
2 changes: 1 addition & 1 deletion app/assets/javascripts/carmenta/carmenta_editor.js.coffee
Expand Up @@ -64,7 +64,7 @@ class CarmentaEditor
type = region.data('type').titleize()
@regions.push(new Carmenta.Regions[type](region, {window: @iframe.get(0).contentWindow}))
catch error
alert(error)
alert(error) if Carmenta.debug
alert("Region type is malformed, no data-type provided, or \"#{type}\" is unknown.")


Expand Down
30 changes: 27 additions & 3 deletions app/assets/javascripts/carmenta/history_buffer.js.coffee
@@ -1,5 +1,29 @@
class HistoryBuffer extends Array
class Carmenta.HistoryBuffer

constructor: ->
@push(arguments)
constructor: (@maxLength = 200) ->
@index = 0
@stack = []


push: (item) ->
return if @stack[@index] && @stack[@index].replace(/<em class="carmenta-marker"><\/em>/g, '') == item.replace(/<em class="carmenta-marker"><\/em>/g, '') # if it's the same, don't do anything

@stack = @stack[0...@index + 1]
@stack.push(item)
@stack.shift() if @stack.length > @maxLength
@index = @stack.length - 1

console.debug('----------------------------------------------------------------', @stack.length)
console.debug(@stack[0...@stack.length])


undo: ->
return null if @index < 1
@index -= 1
return @stack[@index]


redo: ->
return null if @index > @stack.length - 2
@index += 1
return @stack[@index]
89 changes: 74 additions & 15 deletions app/assets/javascripts/carmenta/regions/editable.js.coffee
Expand Up @@ -10,9 +10,10 @@ class Carmenta.Regions.Editable
@window = @options.window
@document = @window.document
@type = @element.data('type')
@history = new HistoryBuffer()
@history = new Carmenta.HistoryBuffer()
@build()
@bindEvents()
@pushHistory()


build: ->
Expand All @@ -29,19 +30,22 @@ class Carmenta.Regions.Editable
# mozilla: there's some weird behavior when the element isn't a div
@specialContainer = $.browser.mozilla && @element.get(0).tagName != 'DIV'

# make it editable and add the basic editor settings
# make it editable
@element.get(0).contentEditable = true
@execCommand('styleWithCSS', {value: false})
@execCommand('insertBROnReturn', {value: true})
@execCommand('enableInlineTableEditing', {value: false})
@execCommand('enableObjectResizing', {value: false})

# add the basic editor settings to the document (only once)
unless @document.carmentaEditing
@document.execCommand('styleWithCSS', false, false)
@document.execCommand('insertBROnReturn', false, true)
@document.execCommand('enableInlineTableEditing', false, false)
@document.execCommand('enableObjectResizing', false, false)
@document.carmentaEditing = true


bindEvents: ->
Carmenta.bind 'focus:frame', =>
return unless Carmenta.region == @
@focus()
Carmenta.trigger('region:update', {region: @})

Carmenta.bind 'action', (event, options) =>
return unless Carmenta.region == @
Expand All @@ -59,25 +63,38 @@ class Carmenta.Regions.Editable

@element.focus =>
Carmenta.region = @
Carmenta.trigger('region:focused', {region: @})

@element.blur =>
Carmenta.trigger('region:blur', {region: @})
Carmenta.trigger('region:blurred', {region: @})

@element.mouseup =>
@pushHistory()
Carmenta.trigger('region:update', {region: @})

@element.keydown (event) =>
Carmenta.changes = true
switch event.keyCode

when 90 # undo / redo
return unless event.metaKey
event.preventDefault()
if event.shiftKey
@execCommand('redo')
else
@pushHistory()
@execCommand('undo')

return

when 13 # enter
if $.browser.webkit
event.preventDefault()
@execCommand('insertlinebreak')
@document.execCommand('insertlinebreak', false, null)
else if @specialContainer
# mozilla: pressing enter in any elemeny besides a div handles strangely
@execCommand('insertHTML', {value: '<br/>'})
event.preventDefault()
@document.execCommand('insertHTML', false, '<br/>')

when 90 # undo and redo
break unless event.metaKey
Expand Down Expand Up @@ -111,17 +128,29 @@ class Carmenta.Regions.Editable
@execCommand('underline')
event.preventDefault()

@pushHistory(event.keyCode)

@element.keyup =>
Carmenta.trigger('region:update', {region: @})
# Carmenta.trigger('region:update', {region: @})


html: (value = null) ->
html: (value = null, includeMarker = false) ->
if value
@element.html(value)
@selection().selectMarker(@element)
else
@element.find('meta').remove()
@element.html().replace(/^\s+|\s+$/g, '')
if includeMarker
selection = @selection()
selection.placeMarker()

# sanitizes the html before we return it
container = $('<div>').appendTo(@document.createDocumentFragment())
container.html(@element.html().replace(/^\s+|\s+$/g, ''))
html = container.html()

selection.removeMarker() if includeMarker
return html


selection: ->
Expand All @@ -130,6 +159,7 @@ class Carmenta.Regions.Editable

focus: ->
@element.focus()
Carmenta.trigger('region:update', {region: @})


path: ->
Expand Down Expand Up @@ -165,26 +195,55 @@ class Carmenta.Regions.Editable


execCommand: (action, options = {}) ->
@element.focus
@element.focus()
@pushHistory() unless action == 'undo' || action == 'redo'

Carmenta.log('execCommand', action, options.value)

# use a custom handler if there's one, otherwise use execCommand
if handler = Carmenta.config.behaviors[action] || Carmenta.Regions.Editable.actions[action]
handler.call(@, @selection(), options)
else
sibling = @element.get(0).previousSibling if action == 'indent'
options.value = $('<div>').html(options.value).html() if action == 'insertHTML' && options.value && options.value.get
Carmenta.log('execCommand', action, options.value)
try
@document.execCommand(action, false, options.value)
catch error
# mozilla: indenting when there's no br tag handles strangely
@element.prev().remove() if action == 'indent' && @element.prev() != sibling


pushHistory: (keyCode) ->
# when pressing return, delete or backspace it should push to the history
# all other times it should store if there's a 1 second pause
keyCodes = [13, 46, 8]
waitTime = 2.5
knownKeyCode = keyCodes.indexOf(keyCode) if keyCode

# clear any pushes to the history
clearTimeout(@historyTimeout)

# if the key code was return, delete, or backspace store now -- unless it was the same as last time
if knownKeyCode >= 0 && knownKeyCode != @lastKnownKeyCode # || !keyCode
@history.push(@html(null, true))
else if keyCode
# set a timeout for pushing to the history
@historyTimeout = setTimeout((=> @history.push(@html(null, true))), waitTime * 1000)
else
# push to the history immediately
@history.push(@html(null, true))

@lastKnownKeyCode = knownKeyCode



# Custom handled actions (eg. things that execCommand doesn't do, or doesn't do well)
Carmenta.Regions.Editable.actions =

undo: -> @html(@history.undo())

redo: -> @html(@history.redo())

removeformatting: (selection) -> selection.insertTextNode(selection.textContent())

backcolor: (selection, options) -> selection.wrap("<span style=\"background-color:#{options.value.toHex()}\">", true)
Expand Down
Expand Up @@ -27,6 +27,46 @@ class Carmenta.Regions.Editable.Selection
return @range.cloneContents()


selectMarker: (context) ->
markers = context.find('em.carmenta-marker')
return unless markers.length

range = @context.createRange()
range.setStartBefore(markers.get(0))
range.setEndBefore(markers.get(1)) if markers.length >= 2

markers.remove()

@selection.removeAllRanges()
@selection.addRange(range)


placeMarker: ->
return unless @range

@startMarker = $('<em class="carmenta-marker"/>', @context).get(0)
@endMarker = $('<em class="carmenta-marker"/>', @context).get(0)

# put a single marker (the end)
rangeEnd = @range.cloneRange()
rangeEnd.collapse(false)
rangeEnd.insertNode(@endMarker)

unless @range.collapsed
# put a start marker
rangeStart = @range.cloneRange()
rangeStart.collapse(true)
rangeStart.insertNode(@startMarker)

@selection.removeAllRanges()
@selection.addRange(@range)


removeMarker: ->
$(@startMarker).remove()
$(@endMarker).remove()


insertTextNode: (string) ->
node = @context.createTextNode(string)
@range.extractContents()
Expand Down
2 changes: 1 addition & 1 deletion app/assets/javascripts/carmenta/regions/snippet.js.coffee
Expand Up @@ -4,4 +4,4 @@ class Carmenta.Regions.Snippet
constructor: (@element) ->
Carmenta.log('making snippetable', @element)

@history = new HistoryBuffer()
@history = new Carmenta.HistoryBuffer()
4 changes: 2 additions & 2 deletions app/assets/javascripts/carmenta/toolbar.js.coffee
Expand Up @@ -44,10 +44,10 @@ class Carmenta.Toolbar


bindEvents: ->
Carmenta.bind 'region:update', (event, options) =>
Carmenta.bind 'region:focused', (event, options) =>
@element.find(".carmenta-#{options.region.type}-toolbar").removeClass('disabled')

Carmenta.bind 'region:blur', (event, options) =>
Carmenta.bind 'region:blurred', (event, options) =>
@element.find(".carmenta-#{options.region.type}-toolbar").addClass('disabled')

@element.click -> Carmenta.trigger('hide:dialogs')
Expand Down
2 changes: 1 addition & 1 deletion app/views/carmenta/modals/character.html.haml
Expand Up @@ -248,4 +248,4 @@
.character{ 'data-entity' => "#9827", :title => "black club suit (shamrock)" } &#9827;
.character{ 'data-entity' => "#9829", :title => "black heart suit (valentine)" } &#9829;
.character{ 'data-entity' => "#9830", :title => "black diamond suit" } &#9830;
.character{ 'data-entity' => "#x2603", :title => "snowman" } &#x2603;
.character{ 'data-entity' => "#x2603", :title => "snowman" } &#x2603;
4 changes: 0 additions & 4 deletions app/views/carmenta/modals/sanitizer.html.haml
Expand Up @@ -2,7 +2,3 @@
.information It looks like you've pasted directly from Microsoft Office!<br/><br/>Sadly though, your browser wasn't able to properly handle what you pasted. But that's ok, I've sanitized it for you!
%textarea{ :rows => '10', :wrap => 'off' }
%strong You can just copy and paste the sanitized content that appears above.


something here
asdasdasd
31 changes: 31 additions & 0 deletions app/views/carmenta/modals/table.html.haml
@@ -0,0 +1,31 @@
%form#carmenta_table{ :style => 'width:700px' }

.carmenta-modal-pane-container
.carmenta-modal-pane
#table_display
%table{ :style => 'width:100%;height:300px;', :border => '1', :cellpadding => '1' }
%tr
%td
%td
%tr
%td
%td

#table_options
.legend Structure Options
%fieldset
%p
%input{ :type => 'button', :value => '+' }/
%input{ :type => 'button', :value => '-' }/

.legend Display Options
%fieldset
%p
%label{ :for => 'alignment' } Alignment
%select#alignment{ :name => 'alignment' }
%option{ :value => '', :selected => true } None
%option{ :value => 'left' } Left
%option{ :value => 'right' } Right

.carmenta-modal-controls
%input{ :type => 'submit', :value => 'Insert Table' }

0 comments on commit 2d1fbc5

Please sign in to comment.