$ -> # This file integrates contenteditable for string attributes. onKey = (event) -> cmsField = $(event.currentTarget) key = event.keyCode || event.which switch key when 13 # Enter if !isNewlineAllowed(cmsField) event.preventDefault() cmsField.blur() when 27 # Esc event.stopPropagation() cmsField.blur() onInput = (event) -> cmsField = $(event.currentTarget) save(cmsField) onFocus = (event) -> cmsField = $(event.currentTarget) prepareForEditing(cmsField) onBlur = (event) -> cmsField = $(event.currentTarget) save(cmsField).done -> cmsField.trigger('scrivito_editors:blur') finishEditing(cmsField) save = (cmsField) -> content = getCurrentContent(cmsField) # Save only if the content has changed. if content != cmsField.scrivito('content') cmsField.scrivito('save', content).done -> cmsField.trigger('save.scrivito_editors') else $.Deferred().resolve() getCurrentContent = (cmsField) -> cleanUp(cmsField) clone = cmsFieldAndPastedContent(cmsField).clone() # Starting with empty element, entering 3 lines, per browser: # Chrome: 1
2
3
# IE:

1

2

3

# Firefox: 1
2
3
clone.find('div:not(:has(br)),p:not(:first)').before('\n') clone.find('br').replaceWith('\n') content = clone.text() clone.remove() content cleanUp = (cmsField) -> siblings = cmsFieldAndPastedContent(cmsField) pasted = siblings.not(cmsField) if pasted.length > 0 pasted.remove() cmsField.text(siblings.text()) cmsFieldAndPastedContent = (cmsField) -> siblingsBefore = cmsField.data('scrivito_editors_siblings_before_edit') siblings = cmsField.siblings() needsReset = !siblingsBefore || siblings.filter(siblingsBefore).length < siblingsBefore.length if needsReset cmsField.data('scrivito_editors_siblings_before_edit', siblings) else cmsField.siblings().addBack().not(siblingsBefore) _deprecationLogged = false isNewlineAllowed = (cmsField) -> if cmsField.data('editor') == 'text' if !_deprecationLogged console.warn 'Scrivito editors: data-editor="text" is deprecated, please use data-editor="string" data-newlines="true" instead.' _deprecationLogged = true return true return true if cmsField.data('newlines') == true return false if cmsField.data('newlines') == false cmsField.css('white-space').match /pre/ prepareForEditing = (cmsField) -> if isNewlineAllowed(cmsField) && !cmsField.data('scrivito_editors_prepared_for_editing') cmsField.data('scrivito_editors_prepared_for_editing', true) html = cmsField.html() htmlNl2Br = html.replace(/\n/g, '
') if html != htmlNl2Br cmsField.html(htmlNl2Br) finishEditing = (cmsField) -> cmsField.data('scrivito_editors_prepared_for_editing', false) cmsField.text(cmsField.scrivito('content')) DOUBLE_CLICK_MS = 300 editSelector = ''' [data-scrivito-field-type="string"]:not([data-editor]):not([data-scrivito-field-name=_permalink]), [data-editor~="string"], [data-editor~="text"] ''' initialize = -> $(':root').on 'mouseenter', editSelector, (event) -> cmsField = $(@) unless cmsField.attr('contenteditable')? cmsField .attr('contenteditable', true) .blur(onBlur) .focus(onFocus) .keypress(onKey) .keyup(onKey) if cmsField.attr('data-autosave') != 'false' cmsField.on('cut input keypress keyup paste', onInput) prepareForEditing(cmsField) $(':root').on 'click', editSelector, (event) -> cmsField = $(@) cmsField.attr('contenteditable', true) cleanUp(cmsField) # Prevent editable link strings from being opened on click, but allow an enforcing double click unless event.timeStamp - cmsField.data('scrivito_editors_last_click') < DOUBLE_CLICK_MS event.preventDefault() cmsField.data('scrivito_editors_last_click', event.timeStamp) scrivito.on 'load', -> if scrivito.in_editable_view() initialize()