$ ->
# 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()