(function () { "use strict"; var debug = false; var pluginName = 'simpleTemplate'; var attrPrefix = 'data-st-'; var pluginAttr = attrPrefix + 'if'; var lang = CKEDITOR.lang.detect('en') || 'en'; CKEDITOR.lang[lang] = CKEDITOR.lang[lang] || {}; CKEDITOR.lang[lang][pluginName] = { simpleTemplate: { toolbar: 'Template' }, simpleTemplateRemove: { toolbar: 'Remove Template' }, title: 'Simple Template', info: 'Template Properties', condition: 'Condition', comment: 'Comment', errEmpty: 'Condition can not be empty', errFormat: 'Condition is in wrong format', errPlaceholder: 'Unknown placeholder used in the condition' }; CKEDITOR.lang[lang]['templatePlaceholder'] = { label: 'Template Placeholders' }; debug && console.info(pluginName, 'init'); function escapeHtml(unsafe) { return unsafe .replace(/&/g, "&") .replace(//g, ">") .replace(/"/g, """) .replace(/'/g, "'"); } var initPlaceholderSpace = function (editor) { var placeholders = editor.config.templatePlaceholders; if (!placeholders || !placeholders.length) { return; } var spaceId = editor.ui.spaceId('templatePlaceholder'); var renderSpace = function () { var html = 'Constants:'; for (var i = 0, c = placeholders.length; i < c; ++i) { html += ' {' + escapeHtml(placeholders[i]) + '}'; } return html; }; editor.on('uiSpace', function (event) { if (event.data.space == 'bottom') { event.data.html = '' + editor.lang.templatePlaceholder.label + '' + '' + renderSpace() + '' + '
' + event.data.html; } }); // Register the ui element to the focus manager. editor.on('uiReady', function () { var element = editor.ui.space('templatePlaceholder'); element && editor.focusManager.add(element, 1); }); }; CKEDITOR.plugins.add(pluginName, { requires: 'dialog', onLoad: function () { debug && console.info(pluginName, 'plugin.onLoad'); CKEDITOR.addCss('[' + attrPrefix + 'if] {' + 'position: relative;' + 'border: 1px dashed #dfdfdf;' + '}' + '\n' + '[' + attrPrefix + 'comment]::after {' + 'content: attr(data-st-comment);' + 'color: #353535;' + 'opacity: 0.5;' + 'font-size: 12px;' + 'line-height: 12px;' + 'position: absolute;' + 'right: 0;' + 'top: 0;' + '}' ); }, init: function (editor) { debug && console.info(pluginName, 'plugin.init'); var lang = editor.lang[pluginName]; editor.addCommand('simpleTemplate', new CKEDITOR.dialogCommand('simpleTemplate')); editor.addCommand('simpleTemplateRemove', new CKEDITOR.simpleTemplateRemove()); editor.ui.addButton && editor.ui.addButton('simpleTemplate', { label: lang.simpleTemplate.toolbar, command: 'simpleTemplate', toolbar: 'simpleTemplateBar,10', icon: this.path + 'icons/tpl.png' }); editor.ui.addButton && editor.ui.addButton('simpleTemplateRemove', { label: lang.simpleTemplateRemove.toolbar, command: 'simpleTemplateRemove', toolbar: 'simpleTemplateBar,20', icon: this.path + 'icons/tpl-rm.png' }); if (editor.addMenuItems) { editor.addMenuItems({ simpleTemplate: { label: lang.title, command: 'simpleTemplate', group: 'simpleTemplateBar' } }); } if (editor.contextMenu) { editor.contextMenu.addListener(function (element, selection) { if (element && element.hasAttribute(pluginAttr)) { return {simpleTemplate: CKEDITOR.TRISTATE_OFF}; } }); } initPlaceholderSpace(editor); }, afterInit: function (editor) { editor.on('afterCommandExec', function (e) { var el; if (e.data.name == 'enter') { el = e.editor.getSelection().getStartElement(); el.removeAttributes([pluginAttr, attrPrefix + 'comment']); } }); } }); CKEDITOR.simpleTemplateRemove = function() {}; CKEDITOR.simpleTemplateRemove.prototype = { contextSensitive: 1, startDisabled: 1, exec: function(editor) { debug && console.log('simpleTemplateRemove.exec', arguments); var elements = editor.elementPath().elements; var element; for (var i = 0, c = elements.length; i < c; ++i) { if (elements[i].$.getAttribute('data-st-if')) { element = elements[i]; break; } } if (element) { element.removeAttribute(pluginAttr); element.removeAttribute(attrPrefix + 'comment'); this.refresh(editor, editor.elementPath()); } }, refresh: function (editor, path) { var elements = path.elements; var element; for (var i = 0, c = elements.length; i < c; ++i) { if (elements[i].$.getAttribute(pluginAttr)) { element = elements[i]; break; } } if (element) { this.setState(CKEDITOR.TRISTATE_OFF); } else { this.setState(CKEDITOR.TRISTATE_DISABLED); } } }; CKEDITOR.dialog.add('simpleTemplate', function (editor) { // editor.config.templatePlaceholders var langId = CKEDITOR.lang.detect('en') || 'en'; var lang = CKEDITOR.lang[langId][pluginName]; var setupValue = function (element) { if (element.hasAttribute(this.attr)) { var value = element.getAttribute(this.attr); this.setValue(value); } }; var commitValue = function (element) { var value = CKEDITOR.tools.trim(this.getValue()); if (value === '') { element.removeAttribute(this.attr); } else { element.setAttribute(this.attr, value); } }; return { title: lang.title, minWidth: 350, minHeight: 150, contents: [ { id: 'info', label: lang.info, title: lang.info, elements: [ { id: 'comment', attr: attrPrefix + 'comment', type: 'text', label: lang.comment, setup: setupValue, commit: commitValue }, { id: 'if', attr: attrPrefix + 'if', type: 'text', label: lang.condition, required: true, setup: setupValue, commit: commitValue, validate: function () { var value = this.getValue(), match, err; if (true !== (err = CKEDITOR.dialog.validate.notEmpty(lang.errEmpty).apply(this))) { return err; } if (null == (match = value.match(/^!?(\w+)$/i))) { return lang.errFormat; } if (editor.config.templatePlaceholders && -1 === CKEDITOR.tools.indexOf(editor.config.templatePlaceholders, match[1])) { return lang.errPlaceholder; } return true; } } ] } ], onShow: function() { debug && console.log('dialog.simpleTemplate onShow', this, arguments); var editor = this.getParentEditor(), elements = editor.elementPath().elements, element; for (var i = 0, c = elements.length; i < c; ++i) { if (elements[i].hasAttribute('data-st-if')) { element = elements[i]; break; } } if (element) { editor.getSelection().selectElement(element); } else { element = editor.getSelection().getSelectedElement(); } if (element) this.setupContent(element); }, onOk: function() { debug && console.log('dialog.simpleTemplate onOk', this, arguments); var editor = this.getParentEditor(), elements = editor.elementPath().elements, element; for (var i = 0, c = elements.length; i < c; ++i) { if (elements[i].hasAttribute('data-st-if')) { element = elements[i]; break; } } if (!element) { element = editor.getSelection().getSelectedElement() || editor.getSelection().getStartElement(); } if (element) this.commitContent(element); }, onFocus: function() { debug && console.log('dialog.simpleTemplate onFocus', this, arguments); var condition = this.getContentElement('info', 'condition'); if (condition) { condition.select(); } } }; }); })();