diff --git a/administrator/language/en-GB/en-GB.plg_editors_tinymce.ini b/administrator/language/en-GB/en-GB.plg_editors_tinymce.ini index 71ab2a85d282d..c68417038437b 100644 --- a/administrator/language/en-GB/en-GB.plg_editors_tinymce.ini +++ b/administrator/language/en-GB/en-GB.plg_editors_tinymce.ini @@ -74,6 +74,8 @@ PLG_TINY_FIELD_NEWLINES_DESC="New lines will be created using the selected optio PLG_TINY_FIELD_NEWLINES_LABEL="New Lines" PLG_TINY_FIELD_NONBREAKING_DESC="Insert non-breaking space entities." PLG_TINY_FIELD_NONBREAKING_LABEL="Non-breaking" +PLG_TINY_FIELD_NUMBER_OF_SETS_LABEL="Number of Sets" +PLG_TINY_FIELD_NUMBER_OF_SETS_DESC="Number of sets that can be created. Minimum 3" PLG_TINY_FIELD_PASTE_DESC="Show or hide the Paste button." PLG_TINY_FIELD_PASTE_LABEL="Paste" PLG_TINY_FIELD_PATH_DESC="If set to ON, it displays the set classes for the marked text." @@ -135,8 +137,67 @@ PLG_TINY_FIELD_VISUALCHARS_DESC="See invisible characters, specifically non-brea PLG_TINY_FIELD_VISUALCHARS_LABEL="Visualchars" PLG_TINY_FIELD_WORDCOUNT_DESC="Turn on/off Wordcount." PLG_TINY_FIELD_WORDCOUNT_LABEL="Wordcount" +PLG_TINY_SET_TITLE="Set %s" +PLG_TINY_SET_PRESET_BUTTON_ADVANCED="Use advanced preset" +PLG_TINY_SET_PRESET_BUTTON_MEDIUM="Use medium preset" +PLG_TINY_SET_PRESET_BUTTON_SIMPLE="Use simple preset" PLG_TINY_TEMPLATE_LAYOUT1_DESC="HTML layout." PLG_TINY_TEMPLATE_LAYOUT1_TITLE="Layout" PLG_TINY_TEMPLATE_SNIPPET1_DESC="Simple HTML snippet." PLG_TINY_TEMPLATE_SNIPPET1_TITLE="Simple Snippet" PLG_TINY_XML_DESCRIPTION="TinyMCE is a platform independent web based JavaScript HTML WYSIWYG Editor." + +; TinyMCE toolbar buttons +PLG_TINY_TOOLBAR_BUTTON_ALIGNCENTER="Align center" +PLG_TINY_TOOLBAR_BUTTON_ALIGNJUSTIFY="Justify" +PLG_TINY_TOOLBAR_BUTTON_ALIGNLEFT="Align left" +PLG_TINY_TOOLBAR_BUTTON_ALIGNRIGHT="Align right" +PLG_TINY_TOOLBAR_BUTTON_ANCHOR="Anchor" +PLG_TINY_TOOLBAR_BUTTON_BACKCOLOR="Background color" +PLG_TINY_TOOLBAR_BUTTON_BLOCKQUOTE="Blockquote" +PLG_TINY_TOOLBAR_BUTTON_BOLD="Bold" +PLG_TINY_TOOLBAR_BUTTON_BULLIST="Bulleted list" +PLG_TINY_TOOLBAR_BUTTON_CHARMAP="Special character" +PLG_TINY_TOOLBAR_BUTTON_CODE="Source code" +PLG_TINY_TOOLBAR_BUTTON_CODESAMPLE="Codesample" +PLG_TINY_TOOLBAR_BUTTON_COPY="Copy" +PLG_TINY_TOOLBAR_BUTTON_CUT="Cut" +PLG_TINY_TOOLBAR_BUTTON_EMOTICONS="Emoticons" +PLG_TINY_TOOLBAR_BUTTON_FONTSELECT="Font Select" +PLG_TINY_TOOLBAR_BUTTON_FONTSIZESELECT="Fontsize Select" +PLG_TINY_TOOLBAR_BUTTON_FORECOLOR="Text color" +PLG_TINY_TOOLBAR_BUTTON_FORMATSELECT="Format select" +PLG_TINY_TOOLBAR_BUTTON_FULLSCREEN="Fullscreen" +PLG_TINY_TOOLBAR_BUTTON_HR="Horizontal line" +PLG_TINY_TOOLBAR_BUTTON_IMAGE="Insert/edit image" +PLG_TINY_TOOLBAR_BUTTON_INDENT="Increase indent" +PLG_TINY_TOOLBAR_BUTTON_INSERTDATETIME="Insert date/time" +PLG_TINY_TOOLBAR_BUTTON_ITALIC="Italic" +PLG_TINY_TOOLBAR_BUTTON_LINK="Insert/edit link" +PLG_TINY_TOOLBAR_BUTTON_LTR="Left to right" +PLG_TINY_TOOLBAR_BUTTON_MEDIA="Insert/edit video" +PLG_TINY_TOOLBAR_BUTTON_NONBREAKING="Nonbreaking space" +PLG_TINY_TOOLBAR_BUTTON_NUMLIST="Numbered list" +PLG_TINY_TOOLBAR_BUTTON_OUTDENT="Decrease indent" +PLG_TINY_TOOLBAR_BUTTON_PAGEBREAK="Page break" +PLG_TINY_TOOLBAR_BUTTON_PASTE="Paste" +PLG_TINY_TOOLBAR_BUTTON_PASTETEXT="Paste as text" +PLG_TINY_TOOLBAR_BUTTON_PREVIEW="Preview" +PLG_TINY_TOOLBAR_BUTTON_PRINT="Print" +PLG_TINY_TOOLBAR_BUTTON_REDO="Redo" +PLG_TINY_TOOLBAR_BUTTON_REMOVEFORMAT="Clear formatting" +PLG_TINY_TOOLBAR_BUTTON_RTL="Right to left" +PLG_TINY_TOOLBAR_BUTTON_SEARCHREPLACE="Find and replace" +PLG_TINY_TOOLBAR_BUTTON_SPELLCHECKER="Spellcheck" +PLG_TINY_TOOLBAR_BUTTON_STYLESELECT="Style Select" +PLG_TINY_TOOLBAR_BUTTON_STRIKETHROUGH="Strikethrough" +PLG_TINY_TOOLBAR_BUTTON_SUBSCRIPT="Subscript" +PLG_TINY_TOOLBAR_BUTTON_SUPERSCRIPT="Superscript" +PLG_TINY_TOOLBAR_BUTTON_TABLE="Table" +PLG_TINY_TOOLBAR_BUTTON_TEMPLATE="Template" +PLG_TINY_TOOLBAR_BUTTON_UNDERLINE="Underline" +PLG_TINY_TOOLBAR_BUTTON_UNDO="Undo" +PLG_TINY_TOOLBAR_BUTTON_UNLINK="Remove link" +PLG_TINY_TOOLBAR_BUTTON_VISUALBLOCKS="Show blocks" +PLG_TINY_TOOLBAR_BUTTON_VISUALCHARS="Show invisible characters" +PLG_TINY_TOOLBAR_BUTTON_SEPARATOR="Separator" diff --git a/layouts/plugins/editors/tinymce/field/tinymcebuilder.php b/layouts/plugins/editors/tinymce/field/tinymcebuilder.php new file mode 100644 index 0000000000000..e7eb535e1aca9 --- /dev/null +++ b/layouts/plugins/editors/tinymce/field/tinymcebuilder.php @@ -0,0 +1,198 @@ + section in form XML. + * @var boolean $hidden Is this field hidden in the form? + * @var string $hint Placeholder for the field. + * @var string $id DOM id of the field. + * @var string $label Label of the field. + * @var string $labelclass Classes to apply to the label. + * @var boolean $multiple Does this field support multiple values? + * @var string $name Name of the input field. + * @var string $onchange Onchange attribute for the field. + * @var string $onclick Onclick attribute for the field. + * @var string $pattern Pattern (Reg Ex) of value of the form field. + * @var boolean $readonly Is this field read only? + * @var boolean $repeat Allows extensions to duplicate elements. + * @var boolean $required Is this field required? + * @var integer $size Size attribute of the input. + * @var boolean $spellcheck Spellcheck state for the form field. + * @var string $validate Validation rules to apply. + * @var string $value Value attribute of the field. + * + * @var array $menus List of the menu items + * @var array $menubarSource Menu items for builder + * @var array $buttons List of the buttons + * @var array $buttonsSource Buttons by group, for the builder + * @var array $toolbarPreset Toolbar presset (default values) + * @var int $setsAmount Amount of sets + * @var array $setsNames List of Sets names + * @var JForm[] $setsForms Form with extra options for an each set + * + * @var JLayoutFile $this Context + */ + +JHtml::_('behavior.core'); +JHtml::_('stylesheet', 'media/editors/tinymce/skins/lightgray/skin.min.css', array('version' => 'auto', 'relative' => false)); +JHtml::_('jquery.ui', array('core', 'sortable')); +JHtml::_('script', 'editors/tinymce/tinymce-builder.js', array('version' => 'auto', 'relative' => true)); + +$doc = JFactory::getDocument(); +$doc->addScriptOptions('plg_editors_tinymce_builder', array( + 'menus' => $menus, + 'buttons' => $buttons, + 'toolbarPreset' => $toolbarPreset, + 'formControl' => $name . '[toolbars]', + ) +); +$doc->addStyleDeclaration(' + #joomla-tinymce-builder{ + margin-left: -180px; + } + .mce-menubar, + .mce-panel { + min-height: 18px; + border-bottom: 1px solid rgba(217,217,217,0.52); + white-space: normal; + } + .mce-tinymce { + margin-bottom: 20px; + } + .mce-panel .drop-area-highlight{ + background-color: #d0d0d0; + } + .mce-panel .mce-btn.ui-state-highlight{ + height: 28px; + width: 40px; + background-color: #409740; + border: 1px solid #f0f0f0; + } + .timymce-builder-toolbar .mce-btn.ui-state-highlight{ + height: 22px; + width: 28px; + } +'); + +?> +
+
+
+ +
+
+
+
+ +
+
+
+
+
+
+ + + + + +
+ 'btn-success', + 'medium' => 'btn-info', + 'advanced' => 'btn-warning', + ); + foreach ( $setsNames as $num => $title ): + + // Check whether the values exists, and if empty then use from preset + if (empty($value['toolbars'][$num]['menu']) + && empty($value['toolbars'][$num]['toolbar1']) + && empty($value['toolbars'][$num]['toolbar2'])) + { + // Take the preset for default value + switch ($num) { + case 0: + $preset = $toolbarPreset['advanced']; + break; + case 1: + $preset = $toolbarPreset['medium']; + break; + default: + $preset = $toolbarPreset['simple']; + } + + $value['toolbars'][$num] = $preset; + } + + // Take existing values + $valMenu = empty($value['toolbars'][$num]['menu']) ? array() : $value['toolbars'][$num]['menu']; + $valBar1 = empty($value['toolbars'][$num]['toolbar1']) ? array() : $value['toolbars'][$num]['toolbar1']; + $valBar2 = empty($value['toolbars'][$num]['toolbar2']) ? array() : $value['toolbars'][$num]['toolbar2']; + ?> +
+
+
+ + + + + + +
+
+ +
+
+
+
+
+
+
+
+
+
+ + + sublayout('setoptions', array('form' => $setsForms[$num])); ?> +
+ +
+
diff --git a/layouts/plugins/editors/tinymce/field/tinymcebuilder/setoptions.php b/layouts/plugins/editors/tinymce/field/tinymcebuilder/setoptions.php new file mode 100644 index 0000000000000..cd0feb3c17acf --- /dev/null +++ b/layouts/plugins/editors/tinymce/field/tinymcebuilder/setoptions.php @@ -0,0 +1,26 @@ + +
+getGroup(null) as $field):?> + renderField(); ?> + +
diff --git a/media/editors/tinymce/js/tinymce-builder.js b/media/editors/tinymce/js/tinymce-builder.js new file mode 100644 index 0000000000000..b04da84fee3fb --- /dev/null +++ b/media/editors/tinymce/js/tinymce-builder.js @@ -0,0 +1,270 @@ +/** + * @copyright Copyright (C) 2005 - 2016 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +;(function($) { + "use strict"; + + /** + * Joomla TinyMCE Builder + * + * @param {HTMLElement} container + * @param {Object} options + * @constructor + * + * @since __DEPLOY_VERSION__ + */ + var JoomlaTinyMCEBuilder = function(container, options) { + this.$container = $(container); + this.options = options; + + // Find source containers + this.$sourceMenu = this.$container.find('.timymce-builder-menu.source'); + this.$sourceToolbar = this.$container.find('.timymce-builder-toolbar.source'); + + // Find target containers + this.$targetMenu = this.$container.find('.timymce-builder-menu.target'); + this.$targetToolbar = this.$container.find('.timymce-builder-toolbar.target'); + + // Render Source elements + this.$sourceMenu.each(function(i, element){ + this.renderBar(element, 'menu'); + }.bind(this)); + this.$sourceToolbar.each(function(i, element){ + this.renderBar(element, 'toolbar'); + }.bind(this)); + + // Render Target elements + this.$targetMenu.each(function(i, element){ + this.renderBar(element, 'menu', null, true); + }.bind(this)); + this.$targetToolbar.each(function(i, element){ + this.renderBar(element, 'toolbar', null, true); + }.bind(this)); + + // Set up "drag&drop" stuff + var $copyHelper = null, removeIntent = false, self = this; + this.$sourceMenu.sortable({ + connectWith: this.$targetMenu, + items: '.mce-btn', + cancel: '', + placeholder: 'mce-btn ui-state-highlight', + start: function(event, ui) { + self.$targetMenu.addClass('drop-area-highlight'); + }, + helper: function(event, el) { + $copyHelper = el.clone().insertAfter(el); + return el; + }, + stop: function() { + $copyHelper && $copyHelper.remove(); + self.$targetMenu.removeClass('drop-area-highlight'); + } + }); + + this.$sourceToolbar.sortable({ + connectWith: this.$targetToolbar, + items: '.mce-btn', + cancel: '', + placeholder: 'mce-btn ui-state-highlight', + start: function(event, ui) { + self.$targetToolbar.addClass('drop-area-highlight'); + }, + helper: function(event, el) { + $copyHelper = el.clone().insertAfter(el); + return el; + }, + stop: function() { + $copyHelper && $copyHelper.remove(); + self.$targetToolbar.removeClass('drop-area-highlight'); + } + }); + + $().add(this.$targetMenu).add(this.$targetToolbar).sortable({ + items: '.mce-btn', + cancel: '', + placeholder: 'mce-btn ui-state-highlight', + receive: function(event, ui) { + $copyHelper = null; + var $el = ui.item, $cont = $(this); + self.appendInput($el, $cont.data('group'), $cont.data('set')) + }, + over: function (event, ui) { + removeIntent = false; + }, + out: function (event, ui) { + removeIntent = true; + }, + beforeStop: function (event, ui) { + if(removeIntent){ + ui.item.remove(); + } + } + }); + + // Bind actions buttons + this.$container.on('click', '.button-action', function(event){ + var $btn = $(event.target), action = $btn.data('action'), options = $btn.data(); + + if (this[action]) { + this[action].call(this, options); + } else { + throw new Error('Unsupported action ' + action); + } + }.bind(this)); + + }; + + /** + * Render the toolbar/menubar + * + * @param {HTMLElement} container The toolbar container + * @param {String} type The type toolbar or menu + * @param {Array|null} value The value + * @param {Boolean} withInput Whether append input + * + * @since __DEPLOY_VERSION__ + */ + JoomlaTinyMCEBuilder.prototype.renderBar = function(container, type, value, withInput) { + var $container = $(container), + group = $container.data('group'), + set = $container.data('set'), + items = type === 'menu' ? this.options.menus : this.options.buttons, + value = value ? value : ($container.data('value') || []), + item, name, $btn; + + for ( var i = 0, l = value.length; i < l; i++ ) { + name = value[i]; + item = items[name]; + + if (!item) { + continue; + } + + $btn = this.createButton(name, item, type); + $container.append($btn); + + // Enable tooltip + if ($btn.tooltip) { + $btn.tooltip({trigger: 'hover'}); + } + + // Add input + if (withInput) { + this.appendInput($btn, group, set); + } + } + }; + + /** + * Create the element needed for renderBar() + * @param {String} name + * @param {Object} info + * @param {String} type + * + * @return {jQuery} + * + * @since __DEPLOY_VERSION__ + */ + JoomlaTinyMCEBuilder.prototype.createButton = function(name, info, type){ + var $element = $('
', { + 'class': 'mce-btn', + 'data-name': name, + 'data-toggle': 'tooltip', + 'title': info.label + }); + var $btn = $('