/** * Creates an inline wysiwyg editor. * * The `ep.uiEditor` method creates an inline wysiwyg editor. * * ### Examples * Creates a wysiwyg editor depending on a textarea with id and name attributes. Textareas with the same value in the name attribute become a shared toolbar. * * JavaScript: * * ep('#editorID').uiEditor({ * 'name': 'editorName', * 'toolbar': 'Mini', * 'disable': true, * 'hideToolbarOnStartup': false, * 'noToolbar': true, * 'useAbsolute': true, * 'blogPostMode': true, * 'pluginOptions': {} * }); * * HTML: * * <div style="clear:both; position:relative;"> * <textarea style="visiblity:hidden;" name="editorName" id="editorID">Some Content</textarea> * </div> * * * @class jQuery.ui.uiEditor * @extends jQuery.widget * * @uses ep * @uses jQuery.ckeditor.adapters.jquery * @uses jQuery.event.special.dom * @since 6.15.0 */ /** * Reloads the toolbar depending on the language of the current editor. * * @param {String} editorName Name of the editor handed over with the name option when editor widget gets initialized. * * @method reloadToolbar * @member jQuery.ui.uiEditor * * @since 6.15.0 */ /** * @cfg {String} name Name of the editor (corresponds to the name attribute of the textarea). */ /** * @cfg {String} toolbar Indicates which toolbar should be used. If option is not handed over a default value from the config.js is used (depending on screen width, content etc.). Possible values: 'Full', 'FullPageBreak', 'Mini', 'MiniPageBreak' */ /** * @cfg {Boolean} disable Boolean Flag which indicates if the editor is disabled (true) on startup. */ /** * @cfg {Boolean} hideToolbarOnStartup Boolean Flag which indicates if the toolbar should be hidden (true) on startup. */ /** * @cfg {Boolean} noToolbar Boolean Flag which indicates if editor has a toolbar. */ /** * @cfg {Boolean} useAbsolute Boolean Flag which indicates if an absolute url should be used in the linkpicker plugin. */ /** * @cfg {Boolean} blogPostMode Boolean Flag which indicates if the toolbar should contain button to insert a pagebreak. */ /** * @cfg {Object} pluginOptions Additional options for plugins */ /** * See `jQuery.ui.uiEditor` for details. * * @param {Object} options A map of additional options pass to the method. * @param {String} name Name of the editor (corresponds to the name attribute of the textarea). * @param {String} toolbar Indicates which toolbar should be used. If option is not handed over a default value from the config.js is used (depending on screen width, content etc.). Possible values: 'Full', 'FullPageBreak', 'Mini', 'MiniPageBreak' * @param {Boolean} disable Boolean Flag which indicates if the editor is disabled (true) on startup. * @param {Boolean} hideToolbarOnStartup Boolean Flag which indicates if the toolbar should be hidden (true) on startup. * @param {Boolean} noToolbar Boolean Flag which indicates if editor has a toolbar. * @param {Boolean} useAbsolute Boolean Flag which indicates if an absolute url should be used in the linkpicker plugin. * @param {Boolean} blogPostMode Boolean Flag which indicates if the toolbar should contain button to insert a pagebreak. * @param {Object} pluginOptions Additional options for plugins * * @method uiEditor * @member jQuery * * @since 6.15.0 */ /* * @copyright © Copyright 2006-2010, epages GmbH, All Rights Reserved. * * @module ep.ui.editor * * @revision $Revision: 1.20 $ */ /*global define, window*/ /*jslint vars:true, plusplus:true, nomen:true*/ define("ep/ui/editor-unity", [ "jquery", "ep", "scribe-loader", "$tmpl!ep/ui/editor-unity-scribe-toolbar-dropdown", "$tmpl!ep/ui/editor-unity-scribe-placeholder", "$dict!ep/dict", "jquery/ui/widget", "jquery/tmpl" ], function ($, ep, scribe, tmplDropDown, tmplPlaceholder, scribeButtonDict) { 'use strict'; /* * @dictionary ep.dict * * * @translation {bold} * {italic} * {underline} * {strikeThrough} * {linkTooltip} * {unlink} * {insertOrderedList} * {insertUnorderedList} * {justifyLeft} * {justifyCenter} * {justifyRight} * {blockquote} */ var translationsDialog = { bold: scribeButtonDict.translate('bold'), italic: scribeButtonDict.translate('italic'), underline: scribeButtonDict.translate('underline'), strikeThrough: scribeButtonDict.translate('strikeThrough'), linkTooltip: scribeButtonDict.translate('linkTooltip'), unlink: scribeButtonDict.translate('unlink'), insertOrderedList: scribeButtonDict.translate('insertOrderedList'), insertUnorderedList: scribeButtonDict.translate('insertUnorderedList'), justifyLeft: scribeButtonDict.translate('justifyLeft'), justifyCenter: scribeButtonDict.translate('justifyCenter'), justifyRight: scribeButtonDict.translate('justifyRight'), blockquote: scribeButtonDict.translate('blockquote'), paragraphDefault: scribeButtonDict.translate('ParagraphDefault'), paragraphHeading1: scribeButtonDict.translate('ParagraphHeading1'), paragraphHeading2: scribeButtonDict.translate('ParagraphHeading2'), paragraphHeading3: scribeButtonDict.translate('ParagraphHeading3') }; $.widget('ui.uiEditorUnity', { // scribe: undefined, // toolbar : undefined, // textarea: undefined, // renderButtons: undefined, options: { // toolbarNode: undefined, name: 'textarea_' + new Date().getTime(), // Dropdown buttons renderButtons: [ {command: 'p', title: 'Standard', translation: translationsDialog.paragraphDefault}, {command: 'h1', title: 'Headline 1', translation: translationsDialog.paragraphHeading1}, {command: 'h2', title: 'Headline 2', translation: translationsDialog.paragraphHeading2}, {command: 'h3', title: 'Headline 3', translation: translationsDialog.paragraphHeading3} ], // Placeholder buttons // "placeholder": [ // {"description": "Bestellnummer", "code": "#Alias"}, // {"description": "Bestelldatum", "code": "#CreationDate[date]"} // ], // Toolbar buttonsjavascript buttons: [ {title: 'Bold', 'data-command-name': 'bold', class: 'dali-plugin-text-toolbar-button dali-plugin-text-toolbar-button-bold'}, {title: 'Italic', 'data-command-name': 'italic', class: 'dali-plugin-text-toolbar-button dali-plugin-text-toolbar-button-italic'}, {title: 'Underline', 'data-command-name': 'underline', class: 'dali-plugin-text-toolbar-button dali-plugin-text-toolbar-button-underline'}, {title: 'Blockquote', 'data-command-name': 'blockquote', class: 'dali-plugin-text-toolbar-button dali-plugin-text-toolbar-button-blockquote'}, {title: 'Insert hyperlink', 'data-command-name': 'linkTooltip', class: 'dali-plugin-text-toolbar-button dali-plugin-text-toolbar-button-link'}, {title: 'Remove hyperlink', 'data-command-name': 'unlink', class: 'dali-plugin-text-toolbar-button dali-plugin-text-toolbar-button-unlink'}, {title: 'Insert ordered list', 'data-command-name': 'insertOrderedList', class: 'dali-plugin-text-toolbar-button dali-plugin-text-toolbar-button-ordered-list'}, {title: 'Insert unordered list', 'data-command-name': 'insertUnorderedList', class: 'dali-plugin-text-toolbar-button dali-plugin-text-toolbar-button-unordered-list'}, {title: 'Justify left', 'data-command-name': 'justifyLeft', class: 'dali-plugin-text-toolbar-button dali-plugin-text-toolbar-button-justify-left'}, {title: 'Justify center', 'data-command-name': 'justifyCenter', class: 'dali-plugin-text-toolbar-button dali-plugin-text-toolbar-button-justify-center'}, {title: 'Justify right', 'data-command-name': 'justifyRight', class: 'dali-plugin-text-toolbar-button dali-plugin-text-toolbar-button-justify-right'} ] }, _create: function () { var self = this, elem = self.element, o = self.options, $toolbar; if (o.toolbarNode === undefined) { o.toolbarNode = $('<div class="toolbar" />'); elem.before(o.toolbarNode); } // build placeholderButton object if placeholder are handed over if (o.placeholder) { self._buildPlaceholderButtons(); } // create toolbar (inclusive buttons) $toolbar = self._buildToolbar(o.toolbarNode); // instantiate scribe self.scribe = scribe(elem, $toolbar[0]); // create textarea self._buildTextarea(); // register event handler to update textarea self.scribe.on('content-changed', $.proxy(self, '_updateHTML')); // insert content (setContent triggers event 'content-changed') // self.scribe.setContent(elem.text()); self.scribe.setHTML(elem.text()); // set buttons active on loading window.setTimeout(function () { elem.closest('.ep-wysiwyg-wrapper').find('button').prop('disabled', null); }, 0); // trigger first content-changed event // self.scribe.trigger('content-changed'); }, _renderButton: function (buttonDef) { var $button = $('<button type="button"/>'); // add button properties (title, data-command-name ..) // attribute refers to the buttons object keys, buttonDef[attribute] returns value refering to this key // data-command-name values are used in the dict for translation, therefore only they can be used for the title value translations Object.keys(buttonDef).forEach(function (attribute) { $button.attr(attribute, ((attribute === 'title') ? translationsDialog[buttonDef['data-command-name']] : buttonDef[attribute])); }); return $button; }, _renderToolbarDropDown: function () { var self = this, o = self.options; self.dropdown = tmplDropDown({ renderButtons: o.renderButtons }); // load template and push named tmpl elements to current instance $.extend(self, self.dropdown.tmplItem('elements')); // prevent default action self.dropdown.find('.dali-plugin-text-toolbar-dropdown-button').on('click.scribeDropdown', function (e) { e.preventDefault(); }); return self.dropdown; }, _renderToolbarPlaceholder: function () { var self = this, o = self.options; self.placeholder = tmplPlaceholder({ placeholderButtons: self.placeholderButtons }); // load template and push named tmpl elements to current instance $.extend(self, self.placeholder.tmplItem('elements')); // prevent default action self.placeholder.find('.dali-plugin-placeholder-dropdown-button').on('click.scribeDropdown', function (e) { e.preventDefault(); }); return self.placeholder; }, _buildToolbar: function (toolbarNode) { var self = this, o = self.options; // create toolbar node if necessary if (self.toolbar === undefined) { self.toolbar = $(toolbarNode); } self.toolbar.append(self._renderToolbarDropDown()); // append buttons (defined in options) to toolbar o.buttons.forEach(function (button) { self.toolbar.append(self._renderButton(button)); }); // if placeholder should be rendered if (self.placeholderButtons) { self.toolbar.append(self._renderToolbarPlaceholder()); } return self.toolbar; }, _buildTextarea: function () { var self = this, o = self.options; self.textarea = $('<textarea readonly />'); self.textarea .attr('name', o.name) .addClass('scribe-textarea HideElement'); // insert textarea after "self.element" self.element.after(self.textarea); return self.textarea; }, _updateHTML: function () { var self = this; // set new value to textarea and remove "<p><br></p>" self.textarea.val(self.scribe.getHTML()); if (self.textarea.val() === "<p><br></p>") { self.textarea.val(""); } // if change event is called initially if (self.triggered !== undefined) { // trigger change event on textarea => show warn message is shown when leaving the page without saving self.textarea.trigger('change'); } // set indicator to trigger change event after initial call self.triggered = true; }, _buildPlaceholderButtons: function () { var self = this, o = self.options, i; self.placeholderButtons = []; for (i=0; i<o.placeholder.length; i++) { // build placeholder buttons with the following format // {command: '#Alias', title: 'Bestellnummer', translation: 'Bestellnummer', placeholder: '#Alias'} self.placeholderButtons[i] = { command: o.placeholder[i].code, title: o.placeholder[i].description, translation: o.placeholder[i].description, placeholder: o.placeholder[i].code }; } }, destroy: function () { var self = this; self._superApply(arguments); } }); return ep; });