SaveAll = { instanceData: (instance) -> instance.resetDirty() snippets = {} # This is the Data we're going to post to the server snippet_ids = [] # This keeps track html classes we need to later replace for id, widget of instance.widgets.instances if widget.effectiveSnippetConfigured != undefined # This is an effectiveSnippet type widget snippet_id = "snippet_#{id}" snippets[snippet_id] = widget.data snippets[snippet_id]['class_name'] = widget.name widget.element.addClass(snippet_id) snippet_ids.push(snippet_id) # Replace the entire widget
...
with [snippet_0] content = $('
' + instance.getData() + '
') content.find(".#{snippet_id}").replaceWith("[#{snippet_id}]") for snippet_id in snippet_ids # Slightly different values for the different region types if instance.config.effectiveRegionType == 'snippets' content = content.text() content = content.replace(/\s+/gi, '') if content.indexOf('[snippet_') > -1 else if instance.config.toolbar == 'simple' content = content.text() else content = content.html() {content: content, snippets: snippets} exec: (editor) -> # Show a checkmark on the Save button try button = $("##{this.uiItems[0]._.id}").find('.cke_button__save_icon') button.css('background-image', 'url(/assets/ckeditor/plugins/effective_regions/icons/saving.png)') setTimeout( -> button.css('background-image', 'url(/assets/ckeditor/plugins/effective_regions/icons/save.png)') 2000 ) url = window.location.protocol + '//' + window.location.host + '/edit' + window.location.pathname # Collect all Effective::Region Data regionData = {} regionData[name] = @instanceData(instance) for name, instance of CKEDITOR.instances # Collect all the Effective::Menu Data menuData = {} $('.effective-menu').effectiveMenuEditor('serialize', menuData) $.ajax url: url type: 'PUT' dataType: 'json' data: { effective_regions: regionData, effective_menus: menuData } async: false complete: (data) -> $('.effective-menu').effectiveMenuEditor('saveComplete') if data.responseText == 'refresh' location.reload(true) } Exit = { exec: (editor) -> url = $.cookie('effective_regions_editting') url ||= window.location.href.replace('?edit=true', '') if url != undefined && url.length > 0 window.location = url else window.history.back() } Regions = { initFullRegion: (editor) -> # Remove any style attributes editor.on 'paste', (evt) -> data = $('
' + evt.data.dataValue + '
') data.find('[style]').removeAttr('style') evt.data.dataValue = data.html() initSimpleRegion: (editor) -> # Disable all tags filter = new CKEDITOR.filter('no_tags_allowed') editor.setActiveFilter(filter) # Disable wrapping content with

. This could break plugins. editor.config.autoParagraph = false # Disable enter button editor.on 'key', (event) -> event.cancel() if (event.data.keyCode == 13 || event.data.keyCode == 2228237) # Paste as plain text, but this doesn't work all the way editor.config.forcePasteAsPlainText = true editor.on 'paste', (evt) -> evt.data.dataValue = evt.data.dataValue.replace(/<[^<|>]+?>/gi,'') initSnippetRegion: (editor) -> # Disable wrapping content with

. This could break plugins. editor.config.autoParagraph = false # Disable enter button editor.on 'key', (event) -> event.cancel() unless (event.data.keyCode == 8) # 8 is backspace # Paste as plain text, but this doesn't work all the way editor.config.forcePasteAsPlainText = true editor.on 'paste', (evt) -> evt.data.dataValue = evt.data.dataValue.replace(/<[^<|>]+?>/gi,'') } Snippets = { snippets: undefined all: -> if @snippets == undefined $.ajax url: '/effective/snippets' type: 'GET' dataType: 'json' async: false complete: (data) -> Snippets.snippets = data.responseJSON @snippets build: (editor, name, values) -> snippet = {} snippet['effectiveSnippetConfigured'] = false snippet['dialog_url'] = values.dialog_url snippet['dialog'] = name if values.dialog_url snippet['inline'] = values.inline snippet['editables'] = values.editables if values.editables snippet['draggable'] = editor.config.effectiveRegionType != 'wrapped_snippets' snippet['template'] = "<#{values.tag} data-effective-snippet='#{name}'>" snippet['upcast'] = (element) -> element.attributes['data-effective-snippet'] == name snippet['loadTemplate'] = (widget) -> $.ajax url: "/effective/snippet/#{widget.name}" type: 'GET' data: {edit: true, effective_regions: {name: widget.name, data: widget.data}} async: false complete: (data) -> widget.element.setHtml(data.responseText) snippet['init'] = -> this.data[k] = v for k, v of $(this.element.$).data('snippet-data') this.on 'dialog', (evt) -> @effectiveSnippetConfigured = true this.on 'data', (evt) -> @loadTemplate(evt.sender) if @effectiveSnippetConfigured this.on 'ready', (evt) -> return true if @effectiveSnippetConfigured != true || evt.sender.editor.config.effectiveRegionType != 'wrapped_snippets' editor = evt.sender.editor # This makes sure an inserted snippet within a 'wrapped_snippets' region is inserted under
  1. try root = editor.getSelection().getCommonAncestor() root = root.getParent() while (root.hasClass('effective-region') == false && root.getName() != 'body') children = root.getChildren() node0 = children.getItem(0) node1 = children.getItem(1) node2 = children.getItem(2) # Find the first OL/UL, find its LI, clone it, then insert the widget into that LI if (node0.getName() == 'ol' || node0.getName() == 'ul') && (node1 == null || node1.hasClass('cke_widget_wrapper')) if (liNode = node0.getChild(0)).getName() == 'li' newNode = liNode.clone() newNode.append(this.wrapper) node0.append(newNode) node2.remove() if (node2 != null && node2.getName() == 'br') else if node0.hasClass('cke_widget_wrapper') && node2 != null && (node2.getName() == 'ol' || node2.getName() == 'ul') if (liNode = node2.getChild(0)).getName() == 'li' newNode = liNode.clone() newNode.append(this.wrapper) node2.append(newNode, true) # prepend it node1.remove() if (node1 != null && node1.getName() == 'br') snippet } Templates = { templates: undefined all: -> if @templates == undefined $.ajax url: '/effective/templates' type: 'GET' dataType: 'json' async: false complete: (data) -> Templates.templates = data.responseJSON @templates build: (definition) -> definition } BuildInsertSnippetDropdown = (editor, all_snippets) -> editor.ui.addRichCombo 'InsertSnippet', label: 'Insert Snippet', title: 'Insert Snippet', panel: css: [ CKEDITOR.skin.getPath( 'editor' ) ], multiSelect: false, init: -> for name, values of all_snippets if name != 'effective_asset' this.add(name, "#{values.label}", "#{values.description}") onClick: (value) -> editor.getCommand(value).exec(editor) onOpen: (evt) -> this.showAll() allowedSnippets = this._.panel._.editor.config.allowedSnippets if allowedSnippets.length > 0 for name, _ of this._.items this.hideItem(name) if allowedSnippets.indexOf(name) == -1 # Hide it, if it's not in allowedSnippets array CKEDITOR.plugins.add 'effective_regions', requires: 'widget', icons: 'save,exit', hidpi: true, init: (editor) -> # Saving editor.ui.addButton 'Save', {label: 'Save', command: 'effectiveRegionsSaveAll'} editor.addCommand('effectiveRegionsSaveAll', SaveAll) # Exit Button editor.ui.addButton 'Exit', {label: 'Exit', command: 'effectiveRegionsExit'} editor.addCommand('effectiveRegionsExit', Exit) # Regions Regions.initFullRegion(editor) if editor.config.effectiveRegionType == 'full' Regions.initSimpleRegion(editor) if editor.config.effectiveRegionType == 'simple' Regions.initSnippetRegion(editor) if editor.config.effectiveRegionType == 'snippets' Regions.initSnippetRegion(editor) if editor.config.effectiveRegionType == 'wrapped_snippets' # Snippets BuildInsertSnippetDropdown(editor, Snippets.all()) # Insert Snippets Dropdown # Initialize all the Snippets as CKeditor widgets for name, values of Snippets.all() snippet = Snippets.build(editor, name, values) editor.widgets.add(name, snippet) CKEDITOR.dialog.add(name, snippet.dialog_url) if snippet.dialog_url # Templates # these are loaded once per page, not for each editor (as the snippets are above) CKEDITOR.addTemplates 'effective_regions', imagesPath: CKEDITOR.getUrl( '/assets/effective/templates/' ), templates: Templates.build(template) for template in Templates.all()