[FEATURE] Configure CSS class as non-selectable in RTE 33/29633/7
authorStanislas Rolland <typo3@sjbr.ca>
Fri, 24 Oct 2014 18:48:45 +0000 (14:48 -0400)
committerStanislas Rolland <typo3@sjbr.ca>
Fri, 24 Oct 2014 20:22:49 +0000 (22:22 +0200)
To filter some useless classes for authors, we can configure classes as
non-selectable in block or text style selectors.

Releases: master
Resolves: #58122
Change-Id: I6b151cf0524fccac6681a813b73f847783a69b95
Reviewed-on: http://review.typo3.org/29633
Reviewed-by: Stanislas Rolland <typo3@sjbr.ca>
Tested-by: Stanislas Rolland <typo3@sjbr.ca>
typo3/sysext/core/Documentation/Changelog/master/Feature-58122-ConfigureClassAsNonSelectableInRte.rst [new file with mode: 0644]
typo3/sysext/rtehtmlarea/Classes/RteHtmlAreaBase.php
typo3/sysext/rtehtmlarea/Documentation/Configuration/PageTsconfig/classes/Index.rst
typo3/sysext/rtehtmlarea/htmlarea/plugins/BlockStyle/block-style.js
typo3/sysext/rtehtmlarea/htmlarea/plugins/EditElement/edit-element.js
typo3/sysext/rtehtmlarea/htmlarea/plugins/TableOperations/table-operations.js
typo3/sysext/rtehtmlarea/htmlarea/plugins/TextStyle/text-style.js

diff --git a/typo3/sysext/core/Documentation/Changelog/master/Feature-58122-ConfigureClassAsNonSelectableInRte.rst b/typo3/sysext/core/Documentation/Changelog/master/Feature-58122-ConfigureClassAsNonSelectableInRte.rst
new file mode 100644 (file)
index 0000000..9e51914
--- /dev/null
@@ -0,0 +1,21 @@
+=======================================================================
+Feature: #58122 - Configure class as non-selectable in Rich Text Editor
+=======================================================================
+
+Description
+===========
+
+It is now possible to configure a class as non-selectable in the style selectors of the Rich Text Editor.
+
+The syntax of this new property is
+       ::
+
+       RTE.classes.[ *classname* ] {
+               .selectable = boolean; if set to 0, the class is not selectable in the style selectors; if the property is omitted or set to 1, the class is selectable in the style selectors
+       }
+
+
+Impact
+======
+
+There is no impact on previous configurations.
index 6f2a78c..cba5006 100644 (file)
@@ -1065,7 +1065,7 @@ class RteHtmlAreaBase extends \TYPO3\CMS\Backend\Rte\AbstractRte {
                } else {
                        $RTEProperties = $this->RTEsetup['properties'];
                }
-               $classesArray = array('labels' => array(), 'values' => array(), 'noShow' => array(), 'alternating' => array(), 'counting' => array(), 'XOR' => array());
+               $classesArray = array('labels' => array(), 'values' => array(), 'noShow' => array(), 'alternating' => array(), 'counting' => array(), 'selectable' => array(), 'XOR' => array());
                $JSClassesArray = '';
                // Scanning the list of classes if specified in the RTE config
                if (is_array($RTEProperties['classes.'])) {
@@ -1082,6 +1082,9 @@ class RteHtmlAreaBase extends \TYPO3\CMS\Backend\Rte\AbstractRte {
                                if (is_array($conf['counting.'])) {
                                        $classesArray['counting'][$className] = $conf['counting.'];
                                }
+                               if (isset($conf['selectable'])) {
+                                       $classesArray['selectable'][$className] = $conf['selectable'];
+                               }
                        }
                }
                // Scanning the list of sets of mutually exclusives classes if specified in the RTE config
index bb2c174..c0603ab 100644 (file)
@@ -38,6 +38,7 @@ classes.[ *classname* ]
             .name = label of the class (may be a reference to an entry in a localization file of the form LLL:EXT:[fileref]:[labelkey])
             .value = the style for the class
             .noShow = boolean; if set, the style of the class is not used to render it in the pop-up selector.
+            .selectable = boolean; if set to 0, the class is not selectable in the style selectors; if the property is omitted, or set to 1, the class is selectable in the style selectors
             
             # specification of alternating classes for rows and/or columns of a table
             .alternating { 
index 24beb97..a85f281 100644 (file)
@@ -239,19 +239,21 @@ HTMLArea.BlockStyle = Ext.extend(HTMLArea.Plugin, {
                                allowedClasses = this.cssArray['all'];
                        }
                        for (var cssClass in allowedClasses) {
-                               var style = null;
-                               if (!this.pageTSconfiguration.disableStyleOnOptionLabel) {
-                                       if (HTMLArea.classesValues[cssClass] && !HTMLArea.classesNoShow[cssClass]) {
-                                               style = HTMLArea.classesValues[cssClass];
-                                       } else if (/-[0-9]+$/.test(cssClass) && HTMLArea.classesValues[RegExp.leftContext + '-'])  {
-                                               style = HTMLArea.classesValues[RegExp.leftContext + '-'];
+                               if (typeof HTMLArea.classesSelectable[cssClass] === 'undefined' || HTMLArea.classesSelectable[cssClass]) {
+                                       var style = null;
+                                       if (!this.pageTSconfiguration.disableStyleOnOptionLabel) {
+                                               if (HTMLArea.classesValues[cssClass] && !HTMLArea.classesNoShow[cssClass]) {
+                                                       style = HTMLArea.classesValues[cssClass];
+                                               } else if (/-[0-9]+$/.test(cssClass) && HTMLArea.classesValues[RegExp.leftContext + '-'])  {
+                                                       style = HTMLArea.classesValues[RegExp.leftContext + '-'];
+                                               }
                                        }
-                               }
-                               store.add(new store.recordType({
-                                       text: allowedClasses[cssClass],
-                                       value: cssClass,
-                                       style: style
-                               }));
+                                       store.add(new store.recordType({
+                                               text: allowedClasses[cssClass],
+                                               value: cssClass,
+                                               style: style
+                                       }));
+                               }
                        }
                }
        },
@@ -263,27 +265,34 @@ HTMLArea.BlockStyle = Ext.extend(HTMLArea.Plugin, {
                dropDown.setValue('none');
                if (classNames.length) {
                        var index = store.findExact('value', classNames[classNames.length-1]);
-                       if (index != -1) {
+                       if (index !== -1) {
                                dropDown.setValue(classNames[classNames.length-1]);
                                if (!defaultClass) {
                                        store.getAt(0).set('text', this.localize('Remove style'));
                                }
                        }
-                       if (index == -1 && !noUnknown) {
+                       if (index === -1 && !noUnknown) {
+                               var text = this.localize('Unknown style');
+                               var value = classNames[classNames.length-1];
+                               if (typeof HTMLArea.classesSelectable[value] !== 'undefined' && !HTMLArea.classesSelectable[value] && typeof HTMLArea.classesLabels[value] !== 'undefined') {
+                                       text = HTMLArea.classesLabels[value];
+                               }
                                store.add(new store.recordType({
-                                       text: this.localize('Unknown style'),
-                                       value: classNames[classNames.length-1]
+                                       text: text,
+                                       value: value,
+                                       style: (!(this.pageTSconfiguration && this.pageTSconfiguration.disableStyleOnOptionLabel) && HTMLArea.classesValues && HTMLArea.classesValues[value] && !HTMLArea.classesNoShow[value]) ? HTMLArea.classesValues[value] : null
                                }));
-                               index = store.getCount()-1;
-                               dropDown.setValue(classNames[classNames.length-1]);
+                               dropDown.setValue(value);
                                if (!defaultClass) {
                                        store.getAt(0).set('text', this.localize('Remove style'));
                                }
                        }
-                               // Remove already assigned classes from the dropDown box
+                       // Remove already assigned classes from the dropDown box
                        var classNamesString = ',' + classNames.join(',') + ',';
+                       var selectedValue = dropDown.getValue(), optionValue;
                        store.each(function (option) {
-                               if (classNamesString.indexOf(',' + option.get('value') + ',') != -1) {
+                               optionValue = option.get('value');
+                               if (classNamesString.indexOf(',' + optionValue + ',') !== -1 && optionValue !== selectedValue) {
                                        store.removeAt(store.indexOf(option));
                                }
                                return true;
index eda7864..3261476 100644 (file)
@@ -291,7 +291,7 @@ HTMLArea.EditElement = Ext.extend(HTMLArea.Plugin, {
                if (comboBox && this.stylePlugin) {
                        var classNames = HTMLArea.DOM.getClassNames(element);
                        this.stylePlugin.buildDropDownOptions(comboBox, nodeName);
-                       this.stylePlugin.setSelectedOption(comboBox, classNames, 'noUnknown');
+                       this.stylePlugin.setSelectedOption(comboBox, classNames);
                }
        },
        /*
index b9c0989..a5772f9 100644 (file)
@@ -1895,7 +1895,7 @@ HTMLArea.TableOperations = Ext.extend(HTMLArea.Plugin, {
                                var classNames = HTMLArea.DOM.getClassNames(element);
                        }
                        blockStyle.buildDropDownOptions(dropDown, nodeName);
-                       blockStyle.setSelectedOption(dropDown, classNames, 'noUnknown', defaultClass);
+                       blockStyle.setSelectedOption(dropDown, classNames, false, defaultClass);
                }
        },
        /*
index a7e7853..5ec74e4 100644 (file)
@@ -313,11 +313,13 @@ HTMLArea.TextStyle = Ext.extend(HTMLArea.Plugin, {
                                }
                        }
                        for (var cssClass in allowedClasses) {
-                               store.add(new store.recordType({
-                                       text: allowedClasses[cssClass],
-                                       value: cssClass,
-                                       style: (!(this.pageTSconfiguration && this.pageTSconfiguration.disableStyleOnOptionLabel) && HTMLArea.classesValues && HTMLArea.classesValues[cssClass] && !HTMLArea.classesNoShow[cssClass]) ? HTMLArea.classesValues[cssClass] : null
-                               }));
+                               if (typeof HTMLArea.classesSelectable[cssClass] === 'undefined' || HTMLArea.classesSelectable[cssClass]) {
+                                       store.add(new store.recordType({
+                                               text: allowedClasses[cssClass],
+                                               value: cssClass,
+                                               style: (!(this.pageTSconfiguration && this.pageTSconfiguration.disableStyleOnOptionLabel) && HTMLArea.classesValues && HTMLArea.classesValues[cssClass] && !HTMLArea.classesNoShow[cssClass]) ? HTMLArea.classesValues[cssClass] : null
+                                       }));
+                               }
                        }
                }
        },
@@ -329,27 +331,34 @@ HTMLArea.TextStyle = Ext.extend(HTMLArea.Plugin, {
                dropDown.setValue('none');
                if (classNames.length) {
                        var index = store.findExact('value', classNames[classNames.length-1]);
-                       if (index != -1) {
+                       if (index !== -1) {
                                dropDown.setValue(classNames[classNames.length-1]);
                                if (!defaultClass) {
                                        store.getAt(0).set('text', this.localize('Remove style'));
                                }
                        }
-                       if (index == -1 && !noUnknown) {
+                       if (index === -1 && !noUnknown) {
+                               var text = this.localize('Unknown style');
+                               var value = classNames[classNames.length-1];
+                               if (typeof HTMLArea.classesSelectable[value] !== 'undefined' && !HTMLArea.classesSelectable[value] && typeof HTMLArea.classesLabels[value] !== 'undefined') {
+                                       text = HTMLArea.classesLabels[value];
+                               }
                                store.add(new store.recordType({
-                                       text: this.localize('Unknown style'),
-                                       value: classNames[classNames.length-1]
+                                       text: text,
+                                       value: value,
+                                       style: (!(this.pageTSconfiguration && this.pageTSconfiguration.disableStyleOnOptionLabel) && HTMLArea.classesValues && HTMLArea.classesValues[value] && !HTMLArea.classesNoShow[value]) ? HTMLArea.classesValues[value] : null
                                }));
-                               index = store.getCount()-1;
-                               dropDown.setValue(classNames[classNames.length-1]);
+                               dropDown.setValue(value);
                                if (!defaultClass) {
                                        store.getAt(0).set('text', this.localize('Remove style'));
                                }
                        }
-                               // Remove already assigned classes from the dropDown box
+                       // Remove already assigned classes from the dropDown box
                        var classNamesString = ',' + classNames.join(',') + ',';
+                       var selectedValue = dropDown.getValue(), optionValue;
                        store.each(function (option) {
-                               if (classNamesString.indexOf("," + option.get('value') + ",") != -1) {
+                               optionValue = option.get('value');
+                               if (classNamesString.indexOf(',' + optionValue + ',') !== -1 && optionValue !== selectedValue) {
                                        store.removeAt(store.indexOf(option));
                                }
                                return true;