scrivito_editors 0.30.1 → 0.40.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
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 = $(@)