Added feature #9262: Adding counting classes to table rows/columns in RTE (thanks...
authorStanislas Rolland <typo3@sjbr.ca>
Thu, 4 Sep 2008 21:15:20 +0000 (21:15 +0000)
committerStanislas Rolland <typo3@sjbr.ca>
Thu, 4 Sep 2008 21:15:20 +0000 (21:15 +0000)
git-svn-id: https://svn.typo3.org/TYPO3v4/Core/trunk@4064 709f56b5-9817-0410-a4d7-c38de5d9e867

ChangeLog
typo3/sysext/rtehtmlarea/ChangeLog
typo3/sysext/rtehtmlarea/class.tx_rtehtmlarea_base.php
typo3/sysext/rtehtmlarea/doc/manual.sxw
typo3/sysext/rtehtmlarea/htmlarea/htmlarea.js
typo3/sysext/rtehtmlarea/htmlarea/plugins/BlockStyle/block-style.js
typo3/sysext/rtehtmlarea/htmlarea/plugins/TableOperations/table-operations.js

index c2066dd..1f038c0 100755 (executable)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2008-09-04  Stanislas Rolland  <typo3@sjbr.ca>
+
+       * Added feature #9262: Adding counting classes to table rows/columns in RTE (thanks to Thorsten Krohn)
+
 2008-09-04  Oliver Hader  <oliver@typo3.org>
 
        * Fixed bug #9227: Group field in Flexforms with a single table does not show selected items
index 96bc93b..30830d9 100644 (file)
@@ -1,3 +1,7 @@
+2008-09-04  Stanislas Rolland  <typo3@sjbr.ca>
+
+       * Added feature #9262: Adding counting classes to table rows/columns in RTE (thanks to Thorsten Krohn)
+
 2008-09-02  Stanislas Rolland  <typo3@sjbr.ca>
 
        * Added feature #9276: htmlArea RTE: allow wild cards in lists of allowed class names
index f3c3514..e2104c9 100644 (file)
@@ -1011,10 +1011,12 @@ class tx_rtehtmlarea_base extends t3lib_rteapi {
                $index = 0;
                $indexNoShow = 0;
                $indexAlternating = 0;
+               $indexCounting = 0;
                $JSClassesLabelsArray = 'HTMLArea.classesLabels = { ' . $linebreak;
                $JSClassesValuesArray = 'HTMLArea.classesValues = { ' . $linebreak;
                $JSClassesNoShowArray = 'HTMLArea.classesNoShow = { ' . $linebreak;
                $JSClassesAlternatingArray = 'HTMLArea.classesAlternating = { ' . $linebreak;
+               $JSClassesCountingArray = 'HTMLArea.classesCounting = { ' . $linebreak;
                $JSClassesXORArray = 'HTMLArea.classesXOR = { ' . $linebreak;
                
                        // Scanning the list of classes if specified in the RTE config
@@ -1032,6 +1034,10 @@ class tx_rtehtmlarea_base extends t3lib_rteapi {
                                        $JSClassesAlternatingArray .= ($indexAlternating?',':'') . '"' . $className . '":' . (is_array($conf['alternating.']) ? $this->buildNestedJSArray($conf['alternating.']) : ' "false"') . $linebreak;
                                        $indexAlternating++;
                                }
+                               if (is_array($conf['counting.'])) {
+                                       $JSClassesCountingArray .= ($indexCounting?',':'') . '"' . $className . '":' . (is_array($conf['counting.']) ? $this->buildNestedJSArray($conf['counting.']) : ' "false"') . $linebreak;
+                                       $indexCounting++;
+                               }
                                $index++;
                        }
                }
@@ -1051,9 +1057,10 @@ class tx_rtehtmlarea_base extends t3lib_rteapi {
                $JSClassesValuesArray .= '};' . $linebreak;
                $JSClassesNoShowArray .= '};' . $linebreak;
                $JSClassesAlternatingArray .= '};' . $linebreak;
+               $JSClassesCountingArray .= '};' . $linebreak;
                $JSClassesXORArray .= '};' . $linebreak;
                
-               return $JSClassesLabelsArray . $JSClassesValuesArray . $JSClassesNoShowArray . $JSClassesAlternatingArray . $JSClassesXORArray;
+               return $JSClassesLabelsArray . $JSClassesValuesArray . $JSClassesNoShowArray . $JSClassesAlternatingArray . $JSClassesCountingArray . $JSClassesXORArray;
        }
        
        /**
index 4f3027c..c7a37ba 100644 (file)
Binary files a/typo3/sysext/rtehtmlarea/doc/manual.sxw and b/typo3/sysext/rtehtmlarea/doc/manual.sxw differ
index a99ee41..441c0d6 100644 (file)
@@ -2110,20 +2110,32 @@ HTMLArea._stopEvent = function(ev) {
 };
 
 /*
- * Remove a class name from the class attribute
+ * Remove a class name from the class attribute of an element
+ *
+ * @param      object          el: the element
+ * @param      string          className: the class name to remove
+ * @param      boolean         substring: if true, remove the first class name starting with the given string
+ * @return     void
  */
-HTMLArea._removeClass = function(el, removeClassName) {
-       if(!(el && el.className)) return;
-       var cls = el.className.trim().split(" ");
-       var ar = new Array();
-       for (var i = cls.length; i > 0;) {
-               if (cls[--i] != removeClassName) ar[ar.length] = cls[i];
+HTMLArea._removeClass = function(el, className, substring) {
+       if (!el || !el.className) return;
+       var classes = el.className.trim().split(" ");
+       var newClasses = new Array();
+       for (var i = classes.length; --i >= 0;) {
+               if (!substring) {
+                       if (classes[i] != className) {
+                               newClasses[newClasses.length] = classes[i];
+                       }
+               } else if (classes[i].indexOf(className) != 0) {
+                       newClasses[newClasses.length] = classes[i];
+               }
        }
-       if (ar.length == 0) {
+       if (newClasses.length == 0) {
                if (!HTMLArea.is_opera) el.removeAttribute(HTMLArea.is_gecko ? "class" : "className");
                        else el.className = '';
-
-       } else el.className = ar.join(" ");
+       } else {
+               el.className = newClasses.join(" ");
+       }
 };
 
 /*
@@ -2144,13 +2156,18 @@ HTMLArea._addClass = function(el, addClassName) {
 };
 
 /*
- * Check if a class name is in the class attribute
+ * Check if a class name is in the class attribute of an element
+ *
+ * @param      object          el: the element
+ * @param      string          className: the class name to look for
+ * @param      boolean         substring: if true, look for a class name starting with the given string
+ * @return     boolean         true if the class name was found
  */
-HTMLArea._hasClass = function(el, className) {
+HTMLArea._hasClass = function(el, className, substring) {
        if (!el || !el.className) return false;
-       var cls = el.className.split(" ");
-       for (var i = cls.length; i > 0;) {
-               if(cls[--i] == className) return true;
+       var classes = el.className.trim().split(" ");
+       for (var i = classes.length; --i >= 0;) {
+               if (classes[i] == className || (substring && classes[i].indexOf(className) == 0)) return true;
        }
        return false;
 };
index ce7a954..fa8ba26 100644 (file)
@@ -162,6 +162,7 @@ BlockStyle = HTMLArea.Plugin.extend({
                                        HTMLArea._removeClass(node, classNames[i]);
                                        if (node.nodeName.toLowerCase() === "table" && this.editor.plugins.TableOperations) {
                                                this.editor.plugins.TableOperations.instance.removeAlternatingClasses(node, classNames[i]);
+                                               this.editor.plugins.TableOperations.instance.removeCountingClasses(node, classNames[i]);
                                        }
                                        break;
                                }
index 850fbb5..39c0408 100644 (file)
@@ -986,7 +986,7 @@ TableOperations = HTMLArea.Plugin.extend({
        },
        
        /*
-        * Applies to rows/cells the alternating classes of an alternating style scheme
+        * Applies to rows/cells the alternating and counting classes of an alternating or counting style scheme
         *
         * @param       object          table: the table to be re-styled
         *
@@ -994,7 +994,7 @@ TableOperations = HTMLArea.Plugin.extend({
         */
        reStyleTable : function (table) {
                if (table) {
-                       if (this.classesUrl && typeof(HTMLArea.classesAlternating) === "undefined") {
+                       if (this.classesUrl && (typeof(HTMLArea.classesAlternating) === "undefined" || typeof(HTMLArea.classesCounting) === "undefined")) {
                                this.getJavascriptFile(this.classesUrl);
                        }
                        var classNames = table.className.trim().split(" ");
@@ -1010,6 +1010,17 @@ TableOperations = HTMLArea.Plugin.extend({
                                                this.alternateColumns(table, classConfiguration);
                                        }
                                }
+                               classConfiguration = HTMLArea.classesCounting[classNames[i]];
+                               if (classConfiguration && classConfiguration.rows) {
+                                       if (classConfiguration.rows.rowClass) {
+                                               this.countRows(table, classConfiguration);
+                                       }
+                               }
+                               if (classConfiguration && classConfiguration.columns) {
+                                       if (classConfiguration.columns.columnClass) {
+                                               this.countColumns(table, classConfiguration);
+                                       }
+                               }
                        }
                }
        },
@@ -1126,6 +1137,129 @@ TableOperations = HTMLArea.Plugin.extend({
        },
        
        /*
+        * Removes from rows/cells the counting classes of an counting style scheme
+        *
+        * @param       object          table: the table to be re-styled
+        * @param       string          removeClass: the name of the class that identifies the counting style scheme
+        *
+        * @return      void
+        */
+       removeCountingClasses : function (table, removeClass) {
+               if (table) {
+                       if (this.classesUrl && typeof(HTMLArea.classesCounting) === "undefined") {
+                               this.getJavascriptFile(this.classesUrl);
+                       }
+                       var classConfiguration = HTMLArea.classesCounting[removeClass];
+                       if (classConfiguration) {
+                               if (classConfiguration.rows && classConfiguration.rows.rowClass) {
+                                       this.countRows(table, classConfiguration, true);
+                               }
+                               if (classConfiguration.columns && classConfiguration.columns.columnClass) {
+                                       this.countColumns(table, classConfiguration, true);
+                               }
+                       }
+               }
+       },
+
+       /*
+        * Applies/removes the counting classes of an counting rows style scheme
+        *
+        * @param       object          table: the table to be re-styled
+        * @param       object          classConfifuration: the counting sub-array of the configuration of the class
+        * @param       boolean         remove: if true, the classes are removed
+        *
+        * @return      void
+        */
+       countRows : function (table, classConfiguration, remove) {
+               var rowClass = { tbody : classConfiguration.rows.rowClass, thead : classConfiguration.rows.rowHeaderClass };
+               var rowLastClass = { tbody : classConfiguration.rows.rowLastClass, thead : classConfiguration.rows.rowHeaderLastClass };
+               var startAt = parseInt(classConfiguration.rows.startAt);
+               startAt = remove ? 1 : (startAt ? startAt : 1);
+               var rows = table.rows, type, baseClassName, rowClassName, lastRowClassName;
+                       // Loop through the rows
+               for (var i = startAt-1, n = rows.length; i < n; i++) {
+                       var row = rows[i];
+                       type = (row.parentNode.nodeName.toLowerCase() == "thead") ? "thead" : "tbody";
+                       baseClassName = rowClass[type];
+                       rowClassName = baseClassName + (i+1);
+                       lastRowClassName = rowLastClass[type];
+                       if (remove) {
+                               if (baseClassName) {
+                                       HTMLArea._removeClass(row, rowClassName);
+                               }
+                               if (lastRowClassName && i == n-1) {
+                                       HTMLArea._removeClass(row, lastRowClassName);
+                               }
+                       } else {
+                               if (baseClassName) {
+                                       if (HTMLArea._hasClass(row, baseClassName, true)) {
+                                               HTMLArea._removeClass(row, baseClassName, true);
+                                       }
+                                       HTMLArea._addClass(row, rowClassName);
+                               }
+                               if (lastRowClassName) {
+                                       if (i == n-1) {
+                                               HTMLArea._addClass(row, lastRowClassName);
+                                       } else if (HTMLArea._hasClass(row, lastRowClassName)) {
+                                               HTMLArea._removeClass(row, lastRowClassName);
+                                       }
+                               }
+                       }
+               }
+       },
+
+       /*
+        * Applies/removes the counting classes of a counting columns style scheme
+        *
+        * @param       object          table: the table to be re-styled
+        * @param       object          classConfifuration: the counting sub-array of the configuration of the class
+        * @param       boolean         remove: if true, the classes are removed
+        *
+        * @return      void
+        */
+       countColumns : function (table, classConfiguration, remove) {
+               var columnClass = { td : classConfiguration.columns.columnClass, th : classConfiguration.columns.columnHeaderClass };
+               var columnLastClass = { td : classConfiguration.columns.columnLastClass, th : classConfiguration.columns.columnHeaderLastClass };
+               var startAt = parseInt(classConfiguration.columns.startAt);
+               startAt = remove ? 1 : (startAt ? startAt : 1);
+               var rows = table.rows, type, baseClassName, columnClassName, lastColumnClassName;
+                       // Loop through the rows of the table
+               for (var i = rows.length; --i >= 0;) {
+                               // Loop through the cells
+                       var cells = rows[i].cells;
+                       for (var j = startAt-1, n = cells.length; j < n; j++) {
+                               var cell = cells[j];
+                               type = cell.nodeName.toLowerCase();
+                               baseClassName = columnClass[type];
+                               columnClassName = baseClassName + (j+1);
+                               lastColumnClassName = columnLastClass[type];
+                               if (remove) {
+                                       if (baseClassName) {
+                                               HTMLArea._removeClass(cell, columnClassName);
+                                       }
+                                       if (lastColumnClassName && j == n-1) {
+                                                       HTMLArea._removeClass(cell, lastColumnClassName);
+                                       }
+                               } else {
+                                       if (baseClassName) {
+                                               if (HTMLArea._hasClass(cell, baseClassName, true)) {
+                                                       HTMLArea._removeClass(cell, baseClassName, true);
+                                               }
+                                               HTMLArea._addClass(cell, columnClassName);
+                                       }
+                                       if (lastColumnClassName) {
+                                               if (j == n-1) {
+                                                       HTMLArea._addClass(cell, lastColumnClassName);
+                                               } else if (HTMLArea._hasClass(cell, lastColumnClassName)) {
+                                                       HTMLArea._removeClass(cell, lastColumnClassName);
+                                               }
+                                       }
+                               }
+                       }
+               }
+       },
+
+       /*
         * This function sets the headers cells on the table (top, left, both or none)
         *
         * @param       object          table: the table being edited