scrivito_editors 0.30.1 → 0.40.0.rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +10 -3
  3. data/app/assets/javascripts/redactor.js +6620 -6697
  4. data/app/assets/javascripts/scrivito_editors/binary_editor.js.coffee +49 -0
  5. data/app/assets/javascripts/scrivito_editors/date_editor.js.coffee +2 -2
  6. data/app/assets/javascripts/scrivito_editors/enum_editor.js.coffee +4 -1
  7. data/app/assets/javascripts/scrivito_editors/helpers/file_drop_zone.js.coffee +43 -0
  8. data/app/assets/javascripts/scrivito_editors/html_editor.js.coffee +96 -80
  9. data/app/assets/javascripts/scrivito_editors/image_editor.js.coffee +5 -39
  10. data/app/assets/javascripts/scrivito_editors/multienum_editor.js.coffee +4 -1
  11. data/app/assets/javascripts/scrivito_editors/placeholder.js.coffee +1 -0
  12. data/app/assets/javascripts/scrivito_editors/redactor_plugins/table.js +337 -0
  13. data/app/assets/javascripts/scrivito_editors/reference_editor.js.coffee +1 -1
  14. data/app/assets/javascripts/scrivito_editors/referencelist_editor.js.coffee +1 -1
  15. data/app/assets/javascripts/scrivito_editors/slider_editor.js.coffee +1 -1
  16. data/app/assets/javascripts/scrivito_editors/string_editor.js.coffee +1 -1
  17. data/app/assets/javascripts/scrivito_editors/text_editor.js.coffee +1 -1
  18. data/app/assets/javascripts/scrivito_editors_core.js +3 -1
  19. data/app/assets/stylesheets/{redactor.css.erb → redactor.css} +536 -596
  20. data/app/assets/stylesheets/scrivito_editors/binary_editor.css +14 -0
  21. data/app/assets/stylesheets/scrivito_editors/editors/html_editor.css +8 -5
  22. metadata +36 -34
  23. data/app/assets/fonts/redactor-font.eot +0 -0
  24. data/lib/scrivito_editors/version.rb +0 -3
@@ -0,0 +1,49 @@
1
+ $ ->
2
+ selector = '[data-scrivito-field-type=binary]:not([data-editor])'
3
+ status_indicator_class = 'image-editor-dragover'
4
+ image_container_class = 'scrivito-editor-image-container'
5
+
6
+ handle_file_upload = (event, element, file) ->
7
+ element.scrivito('save', file).then ->
8
+ element.scrivito('reload')
9
+
10
+ delete_binary = (cms_field) ->
11
+ if $(cms_field).scrivito('content')
12
+ $(cms_field).scrivito('save', null).then ->
13
+ $(cms_field).scrivito('reload')
14
+
15
+ binary_field_container = (binary_field) ->
16
+ if $(binary_field).prop('tagName') == 'IMG'
17
+ if $(binary_field).parent(".#{image_container_class}").length == 0
18
+ $(binary_field).wrap("<div class='#{image_container_class}'></div>")
19
+ $(binary_field).parent(".#{image_container_class}")
20
+ else
21
+ binary_field
22
+
23
+ add_delete_to_binary = (binary_element) ->
24
+ if $(binary_element).scrivito('content')
25
+ container = binary_field_container(binary_element)
26
+
27
+ if $(container).find('delete-binary').length == 0
28
+ delete_icon = $(
29
+ '<a href="#" class="delete-binary editing-button editing-red delete">' +
30
+ '<i class="editing-icon editing-icon-trash" /></a>'
31
+ )
32
+
33
+ delete_icon.click (event) ->
34
+ event.preventDefault()
35
+ delete_binary(binary_element)
36
+
37
+ $(container).prepend(delete_icon)
38
+
39
+ scrivito.on 'content', (content_root) ->
40
+ if scrivito.in_editable_view()
41
+ binary_elements = $(content_root).find(
42
+ "#{selector}[data-scrivito-editors-allow-delete]")
43
+
44
+ for binary_element in binary_elements
45
+ add_delete_to_binary(binary_element)
46
+
47
+ scrivito.on 'load', ->
48
+ if scrivito.in_editable_view()
49
+ scrivito.editors._file_drop_zone(selector, handle_file_upload, status_indicator_class)
@@ -22,7 +22,7 @@ $ ->
22
22
  cmsField.scrivito('save', datetime)
23
23
  .done ->
24
24
  cmsField.trigger('save.scrivito_editors')
25
- cmsField.trigger('scrivito_reload')
25
+ cmsField.scrivito('reload')
26
26
 
27
27
  $('body').on 'click', '[data-scrivito-field-type="date"]:not(.hasDatepicker):not([data-editor]), [data-editor~="date"]', (event) ->
28
28
  event.preventDefault()
@@ -42,9 +42,9 @@ $ ->
42
42
  template()
43
43
  .data('cmsField', cmsField)
44
44
  .insertAfter(cmsField)
45
- .val(content)
46
45
  .keyup(onKeyup)
47
46
  .datetimepicker(options)
47
+ .datetimepicker('setDate', $(cmsField).scrivito('content'))
48
48
  .focus()
49
49
 
50
50
  cmsField.hide()
@@ -22,7 +22,10 @@ $ ->
22
22
  cmsField.scrivito('save', content).done ->
23
23
  cmsField.trigger('save.scrivito_editors')
24
24
 
25
- $(document).on 'click', '[data-scrivito-field-type="enum"]:not([data-editor]), [data-editor~="enum"]', (event) ->
25
+ enumEditSelector = '[data-values][data-scrivito-field-type="enum"]' +
26
+ ':not([data-editor]), [data-editor~="enum"]'
27
+
28
+ $(document).on 'click', enumEditSelector, (event) ->
26
29
  cmsField = $(event.currentTarget)
27
30
  selected = cmsField.scrivito('content')
28
31
  values = cmsField.data('values')
@@ -0,0 +1,43 @@
1
+ fetch_file = (event) ->
2
+ data_transfer = event.originalEvent.dataTransfer
3
+ return unless data_transfer
4
+
5
+ files = data_transfer.files
6
+ if (files.length > 1)
7
+ alert('You dropped multiple files, but only one file is supported.')
8
+ return
9
+
10
+ files[0]
11
+
12
+ find_cms_field = (target) ->
13
+ if $(target).attr('data-scrivito-field-name')
14
+ $(target)
15
+ else
16
+ $(target).parent('[data-scrivito-field-name]')
17
+
18
+ scrivito.editors._file_drop_zone = (selector, callback, status_indicator_class) ->
19
+ # Disable DnD for all elements by default to prevent the user
20
+ # from accidentally opening an image in browser.
21
+ $('body').on 'dragover', -> false
22
+ $('body').on 'drop', -> false
23
+
24
+ status_indicator_class ||= 'scrivito-editor-dragover'
25
+
26
+ body_element = $('body')
27
+ body_element.on 'dragover.scrivito-editor', selector, (event) ->
28
+ event.preventDefault()
29
+ $(find_cms_field(event.target)).addClass(status_indicator_class)
30
+
31
+ body_element.on 'dragleave.scrivito-editor', selector, (event) ->
32
+ event.preventDefault()
33
+ $(find_cms_field(event.target)).removeClass(status_indicator_class)
34
+
35
+ body_element.on 'drop.scrivito-editor', selector, (event) ->
36
+ event.preventDefault()
37
+ cms_field = find_cms_field(event.target)
38
+ file = fetch_file(event)
39
+ $(cms_field).removeClass(status_indicator_class)
40
+
41
+ if file
42
+ callback(event, cms_field, file)
43
+
@@ -2,91 +2,95 @@
2
2
  # attributes and provides autosave on top of the default Redactor settings.
3
3
 
4
4
  # Check if the namespace for plugins exists and create it otherwise.
5
- unless @RedactorPlugins?
6
- @RedactorPlugins = {}
5
+ @RedactorPlugins ||= {}
7
6
 
8
- @RedactorPlugins.over_aggressive_cleanup_fix = init: -> @cleanSavePreCode = (html) -> html
9
-
10
- # Plugin for closing the editor with a button in the toolbar.
11
- @RedactorPlugins.close =
12
- init: ->
13
- @buttonAddFirst('close', 'Close', @closeAction)
14
-
15
- closeAction: (buttonName, buttonDOM, buttonObj, event) ->
16
- @.callback('blur')
7
+ # API to override Redactor options
8
+ # @api public
9
+ scrivito.editors.html_editor =
10
+ redactor:
11
+ options: {}
17
12
 
18
13
  $ ->
14
+ # Plugin for closing the editor with a button in the toolbar.
15
+ RedactorPlugins.scrivito_editors_close = ->
16
+ init: ->
17
+ button = @button.addFirst('close', 'Close')
18
+ @button.addCallback button, -> closeEditor @
19
+
19
20
  # Stores redactor options, custom settings and configures callbacks.
20
- redactorOptions = ->
21
- return {} =
22
- cleanSpaces: false
23
- convertLinks: false
24
- formattingPre: false
25
- paragraphy: false
26
- tidyHtml: false
27
-
28
- dropdownShowCallback: -> @_dropdownOpen = true
29
- dropdownHideCallback: -> @_dropdownOpen = false
30
- modalOpenedCallback: -> @_modalOpen = true
31
- modalClosedCallback: -> @_modalOpen = false
32
- focusCallback: -> @_hasFocus = true
33
-
34
- buttons: [
35
- 'formatting', 'bold', 'italic', 'deleted', 'underline',
36
- 'unorderedlist', 'orderedlist', 'table', 'link', 'html',
37
- ]
38
-
39
- # This options allows to configure what plugins are loaded. Plugins need to be defined in the
40
- # +RedactorPlugins+ namespace.
41
- plugins: ['close', 'over_aggressive_cleanup_fix']
42
-
43
- # This option allows you to set whether Redactor gets cursor focus on load or not.
44
- # http://imperavi.com/redactor/docs/settings/#set-focus
45
- focus: true
46
-
47
- # With this option turned on, Redactor will automatically replace divs to paragraphs.
48
- # http://imperavi.com/redactor/docs/settings/#set-convertDivs
49
- convertDivs: false
50
-
51
- # This callback fires every time when content changes in Redactor.
52
- # http://imperavi.com/redactor/docs/callbacks/#callback-changeCallback
53
- changeCallback: ->
54
- saveContents(@)
55
-
56
- # This callback is triggered when Redactor loses focus.
57
- # http://imperavi.com/redactor/docs/callbacks/#callback-blurCallback
58
- blurCallback: ->
59
- editor = @
60
- editor._hasFocus = false
61
- unless @_dropdownOpen || @_modalOpen
62
- # workaround for issue with context menu (e. g. unlink) being neither modal nor dropdown
63
- setTimeout ->
64
- unless editor._hasFocus
65
- saveContents(editor)
66
- editor.destroy()
67
- , 250
68
-
69
- # This callback is triggered when a key is released.
70
- # http://imperavi.com/redactor/docs/callbacks/#callback-keyupCallback
71
- keyupCallback: (event) ->
21
+ scrivito.editors.html_editor.redactor.default_options =
22
+ buttons: [
23
+ 'formatting', 'bold', 'italic', 'deleted', 'underline',
24
+ 'unorderedlist', 'orderedlist', 'table', 'link', 'html',
25
+ ]
26
+
27
+ buttonSource: true
28
+ cleanSpaces: false
29
+ cleanOnPaste: false
30
+ convertLinks: false
31
+ linkTooltip: false # disabled, causes unexpected blur on redactor 9 and 10
32
+ paragraphize: false
33
+
34
+ plugins: [
35
+ 'scrivito_editors_close'
36
+ 'table'
37
+ ]
38
+
39
+ replaceDivs: false
40
+ tabifier: false
41
+
42
+ blurCallback: -> closeEditor @
43
+ changeCallback: -> saveContents @
44
+ destroyCallback: -> saveContents @
45
+ dropdownShowCallback: -> saveContents @
46
+ modalOpenedCallback: -> saveContents @
47
+
48
+ keyupCallback: (event) ->
49
+ key = event.keyCode || event.which
50
+
51
+ if key == 27
72
52
  event.stopPropagation()
73
- key = event.keyCode || event.which
74
-
75
- if key == 27
76
- @.callback('blur')
77
- else
78
- saveContents(@)
79
-
80
- # This callback allows to get pasted code after clean on paste.
81
- # http://imperavi.com/redactor/docs/callbacks/#callback-pasteAfterCallback
82
- pasteAfterCallback: (html) ->
83
- saveContents(@)
84
- html
53
+ closeEditor @
54
+ else
55
+ saveContents @
56
+
57
+ initCallback: ->
58
+ cmsField = $(@.$element)
59
+ content = cmsField.scrivito('content')
60
+ @_initialScrivitoContent = content
61
+
62
+ # @code.get() is empty during init, so we get all HTML via selections
63
+ @selection.selectAll()
64
+ htmlWithSelection = @selection.getHtml()
65
+ @selection.removeMarkers()
66
+ html = @selection.getHtml()
67
+
68
+ if html != content
69
+ @code.set(content)
70
+ @selection.selectAll()
71
+ html = @selection.getHtml()
72
+ @focus.setEnd()
73
+ else
74
+ @code.set(htmlWithSelection)
75
+ @selection.restore()
76
+
77
+ @_initialRedactorContent = html
78
+
79
+ startCallback: ->
80
+ if document.getSelection().anchorNode
81
+ # see http://imperavi.com/redactor/examples/click-to-edit/
82
+ @insert.node @selection.getMarker(), false
83
+
84
+ # Close editor (implies save)
85
+ closeEditor = (editor) ->
86
+ cmsField = $(editor.$element)
87
+ editor.core.destroy()
88
+ cmsField.removeClass('scrivito_editors_redactor')
85
89
 
86
90
  # Saves the current editor content to the CMS.
87
91
  saveContents = (editor) ->
88
92
  cmsField = editor.$element
89
- content = editor.get()
93
+ content = getCurrentContent(editor)
90
94
 
91
95
  if content != cmsField.scrivito('content')
92
96
  cmsField.scrivito('save', content).done ->
@@ -94,16 +98,28 @@ $ ->
94
98
  else
95
99
  $.Deferred().resolve()
96
100
 
101
+ getCurrentContent = (editor) ->
102
+ content = editor.code.get()
103
+
104
+ if content == editor._initialRedactorContent
105
+ content = editor._initialScrivitoContent
106
+
107
+ content
108
+
109
+ getOptions = ->
110
+ $.extend {}, scrivito.editors.html_editor.redactor.default_options,
111
+ scrivito.editors.html_editor.redactor.options
112
+
97
113
  # Registers Redactor for all CMS html attributes found in the given scope of the DOM element.
98
114
  addOnclickRedactorHandlers = ->
99
115
  $(':root').on 'click.scrivito_editors', '[data-scrivito-field-type="html"]:not([data-editor]), [data-editor~="html"]', (event) ->
100
116
  event.preventDefault()
101
117
  cmsField = $(@)
102
118
 
103
- unless cmsField.hasClass('redactor_editor')
104
- cmsField.redactor(redactorOptions())
105
- cmsField.redactor('set', cmsField.scrivito('content'), false)
106
- cmsField.redactor('focus')
119
+ unless cmsField.hasClass('scrivito_editors_redactor')
120
+ cmsField
121
+ .redactor(getOptions())
122
+ .addClass('scrivito_editors_redactor')
107
123
 
108
124
  scrivito.on 'load', ->
109
125
  if scrivito.in_editable_view()
@@ -3,27 +3,10 @@ $ ->
3
3
 
4
4
  activateForFieldType = (fieldType) ->
5
5
  selector = 'img[data-scrivito-field-type=' + fieldType + ']:not([data-editor])'
6
- activateForSelector(selector)
6
+ scrivito.editors._file_drop_zone(selector, save)
7
7
 
8
- activateForSelector = (selector) ->
9
- bodyElement = $('body')
10
- bodyElement.on 'dragover.image-editor', selector, (event) ->
11
- event.preventDefault()
12
- $(event.target).addClass(statusIndicatorClass)
13
-
14
- bodyElement.on 'dragleave.image-editor', selector, (event) ->
15
- event.preventDefault()
16
- $(event.target).removeClass(statusIndicatorClass)
17
-
18
- bodyElement.on 'drop.image-editor', selector, (event) ->
19
- event.preventDefault()
20
- target = $(event.target)
21
- fieldType = target.attr('data-scrivito-field-type')
22
- save(event, $(event.target), fieldType)
23
-
24
- save = (event, element, fieldType) ->
25
- file = fetchFile(event, element)
26
- return unless file
8
+ save = (event, element, file) ->
9
+ fieldType = element.attr('data-scrivito-field-type')
27
10
 
28
11
  createImage(file).then (obj) ->
29
12
  value = switch
@@ -32,19 +15,7 @@ $ ->
32
15
  else $.error('Field type must be "reference" or "linklist".')
33
16
 
34
17
  element.scrivito('save', value).then ->
35
- element.trigger('scrivito_reload')
36
-
37
- fetchFile = (event, element) ->
38
- data_transfer = event.originalEvent.dataTransfer
39
- return unless data_transfer
40
-
41
- files = data_transfer.files
42
- if (files.length > 1)
43
- alert('You dropped multiple files, but only one file is supported.')
44
- element.removeClass(statusIndicatorClass)
45
- return
46
-
47
- files[0]
18
+ element.scrivito('reload')
48
19
 
49
20
  createImage = (file) ->
50
21
  name = file.name.replace(/[^a-z0-9_.$\-]/ig, '-')
@@ -63,9 +34,4 @@ $ ->
63
34
  activateForFieldType('reference')
64
35
 
65
36
  # Activate the image editor if it is explicitely selected.
66
- activateForSelector('[data-editor~="image"]')
67
-
68
- # Disable DnD for all elements by default to prevent the user
69
- # from accidentally opening an image in browser.
70
- $('body').on 'dragover', -> false
71
- $('body').on 'drop', -> false
37
+ scrivito.editors._file_drop_zone('[data-editor~="image"]', save,statusIndicatorClass)
@@ -23,7 +23,10 @@ $ ->
23
23
  cmsField.scrivito('save', content).done ->
24
24
  cmsField.trigger('save.scrivito_editors')
25
25
 
26
- $(document).on 'click', '[data-scrivito-field-type="multienum"]:not([data-editor]), [data-editor~="multienum"]', (event) ->
26
+ multienumEditSelector = '[data-values][data-scrivito-field-type="multienum"]' +
27
+ ':not([data-editor]), [data-editor~="multienum"]'
28
+
29
+ $(document).on 'click', multienumEditSelector, (event) ->
27
30
  cmsField = $(event.currentTarget)
28
31
  selected = cmsField.scrivito('content')
29
32
  values = cmsField.data('values')
@@ -6,6 +6,7 @@ $ ->
6
6
  # scrivito_tag(:div, @obj, :my_attribute, data: { placeholder: 'My custom placeholder text.' })
7
7
  addPlaceholder = ->
8
8
  cmsFields = $('[data-scrivito-field-type]')
9
+ .not('[data-scrivito-field-type$=enum]:not([data-values])')
9
10
 
10
11
  cmsFields.each ->
11
12
  cmsField = $(@)