Changeset 480

Show
Ignore:
Timestamp:
2007-07-20 02:09:43 (17 months ago)
Author:
martinkou
Message:

Fixed #125 : Implemented click-and-drag table column resizing as a the 'dragresizetable' plugin.

Location:
FCKeditor/trunk
Files:
2 added
10 modified

Legend:

Unmodified
Added
Removed
  • FCKeditor/trunk/editor/_source/classes/fckspecialcombo.js

    r248 r480  
    139139        for ( var i in this.Items ) 
    140140        { 
     141                if ( !this.Items[i] ) continue; 
    141142                this.Items[i].className = this.Items[i].originalClass = 'SC_Item' ; 
    142143                this.Items[i].Selected = false ; 
  • FCKeditor/trunk/editor/_source/commandclasses/fck_othercommands.js

    r403 r480  
    9999        if ( typeof( fontSize ) == 'string' ) fontSize = parseInt(fontSize, 10) ; 
    100100 
    101         if ( fontSize == null || fontSize == '' ) 
    102         { 
    103                 // TODO: Remove font size attribute (Now it works with size 3. Will it work forever?) 
    104                 FCK.ExecuteNamedCommand( 'FontSize', 3 ) ; 
     101        // If user wants the font size cleared, we have to find 
     102        // where the font size tag is and go clear it (if there's one) 
     103        if ( !fontSize || fontSize == null || fontSize == '' ) 
     104        { 
     105                var oFont = FCK.Selection.MoveToAncestorNode('FONT'); 
     106                if ( oFont && oFont.getAttribute("size") ) 
     107                { 
     108                        //if the only thing here is SIZE, collapse the whole tag 
     109                        if (oFont.attributes.length == 1 || 
     110                                (oFont.outerHTML && oFont.outerHTML.search(/<FONT size=["]*\d["]*>/i))) 
     111                        { 
     112                                FCKTools.RemoveOuterTags(oFont); 
     113                        } 
     114                        else 
     115                                oFont.removeAttribute("size"); 
     116                }        
     117 
    105118        } 
    106119        else 
  • FCKeditor/trunk/editor/_source/internals/fck_gecko.js

    r403 r480  
    3939        } 
    4040 
     41        //allow the table handler to handle mouse messages for dynamic table sizing 
     42        this._ExecMouseDown = function(e) 
     43        { 
     44                FCK.Events.FireEvent( "OnMouseDown",e ) ; 
     45        } 
     46 
     47        this._ExecMouseMove = function(e) 
     48        { 
     49                FCK.Events.FireEvent( "OnMouseMove",e ) ; 
     50        } 
     51 
     52        this._ExecMouseUp = function(e) 
     53        { 
     54                FCK.Events.FireEvent( "OnMouseUp",e ) ; 
     55        } 
    4156        this.ExecOnSelectionChangeTimer = function() 
    4257        { 
     
    6277        // Record changes for the undo system when there are key down events. 
    6378        this.EditorDocument.addEventListener( 'keydown', this._KeyDownListener, false ) ; 
     79 
     80         
     81        //Hooks for table sizing 
     82        this.EditorDocument.addEventListener( 'mousedown', this._ExecMouseDown, true ) ; 
     83        this.EditorDocument.addEventListener( 'mouseup', this._ExecMouseUp, true ) ; 
     84        this.EditorDocument.addEventListener( 'mousemove', this._ExecMouseMove, true ) ; 
    6485 
    6586        // Reset the context menu. 
     
    99120        Print   : true, 
    100121        Paste   : true, 
     122 
    101123        Cut     : true, 
    102124        Copy    : true 
  • FCKeditor/trunk/editor/_source/internals/fck_ie.js

    r425 r480  
    7070                FCK.EditorWindow.event.returnValue      = false ; 
    7171        } 
     72        FCK.Events.FireEvent( "OnMouseUp",FCK.EditorWindow.event) ; 
     73} 
     74 
     75function Doc_OnMouseDown() 
     76{ 
     77        FCK.Events.FireEvent( "OnMouseDown",FCK.EditorWindow.event ) ; 
     78} 
     79 
     80function Doc_OnMouseMove() 
     81{ 
     82        FCK.Events.FireEvent( "OnMouseMove",FCK.EditorWindow.event) ; 
    7283} 
    7384 
     
    103114 
    104115        this.EditorDocument.attachEvent("ondblclick", Doc_OnDblClick ) ; 
     116         
     117        //additions for table sizing 
     118        this.EditorDocument.attachEvent( 'onmousedown', Doc_OnMouseDown ) ; 
     119        this.EditorDocument.attachEvent( 'onmousemove', Doc_OnMouseMove ) ; 
    105120 
    106121        // Catch cursor selection changes. 
  • FCKeditor/trunk/editor/_source/internals/fckselection_gecko.js

    r132 r480  
    150150        return oSel ; 
    151151} 
     152 
     153// If FCKSelection is inside a table, return <td>'s so we can work on each 
     154// one as a separate element 
     155FCKSelection.TableNodes = function() 
     156{ 
     157        var oSel = FCK.EditorWindow.getSelection(); 
     158        var aNodes = new Array(); 
     159        if (this.HasAncestorNode("TABLE")) 
     160        { 
     161                var oTable = this.MoveToAncestorNode("TABLE"); 
     162                for (var r = 0; r < oTable.rows.length; r++) 
     163                { 
     164                        for (var c = 0; c < oTable.rows[r].cells.length; c++) 
     165                        { 
     166                                if (oSel.containsNode(oTable.rows[r].cells[c],true)) 
     167                                { 
     168                                        aNodes[aNodes.length] = oTable.rows[r].cells[c]; 
     169                                } 
     170                        } 
     171                } 
     172        } 
     173        return aNodes; 
     174} 
     175 
     176FCKSelection.SelectedHTML = function() 
     177{ 
     178        var oSel = FCK.EditorWindow.getSelection(); 
     179        var strHTML = ""; 
     180        //convert to a text range and walk the elements 
     181        for ( var i = 0 ; i < oSel.rangeCount ; i++ ) 
     182        { 
     183                var df = oSel.getRangeAt(i).cloneContents(); 
     184                 
     185                for (var j = 0; j < df.childNodes.length; j++) 
     186                { 
     187                        if (df.childNodes[j].nodeName == "#text") 
     188                                {if (df.childNodes[j].textContent) strHTML += df.childNodes[j].textContent;} 
     189                        else 
     190                                strHTML += '<' + df.childNodes[j].nodeName + '>' 
     191                                                + df.childNodes[j].innerHTML 
     192                                                + '</' + df.childNodes[j].nodeName + '>'; 
     193                } 
     194        } 
     195        return strHTML; 
     196} 
     197 
  • FCKeditor/trunk/editor/_source/internals/fckselection_ie.js

    r280 r480  
    4747        { 
    4848                case 'Control' : 
     49                        if (!FCKSelection.GetSelectedElement()) return; 
    4950                        return FCKSelection.GetSelectedElement().parentElement ; 
    5051                case 'None' : 
     
    110111        return false ; 
    111112} ; 
     113// If FCKSelection is inside a table, return <td>'s so we can work on each 
     114// one as a separate element 
     115FCKSelection.TableNodes = function() 
     116{ 
     117        var oRange = FCK.EditorDocument.selection.createRange() ; 
     118        if (!oRange.htmlText.search(/<TD /)) return; 
     119        var oCellRange = oRange.duplicate(); 
     120        var oTable = this.MoveToAncestorNode("TABLE"); 
     121        if (!oTable) return; 
     122        var aNodes = new Array(); 
     123        for (var i = 0; i < oTable.cells.length; i++) 
     124        { 
     125                oCellRange.moveToElementText(oTable.cells[i]); 
     126                if (oRange.inRange(oCellRange)) 
     127                { 
     128                        aNodes[aNodes.length] = oTable.cells[i]; 
     129                } 
     130        } 
     131        return aNodes; 
     132} 
     133 
    112134 
    113135// The "nodeTagName" parameter must be UPPER CASE. 
     
    157179} ; 
    158180 
     181FCKSelection.SelectedHTML = function() 
     182{ 
     183        return FCK.EditorDocument.selection.createRange().htmlText; 
     184} 
    159185 
  • FCKeditor/trunk/editor/_source/internals/fckselection.js

    r132 r480  
    2323 
    2424var FCKSelection = FCK.Selection = new Object() ; 
     25 
  • FCKeditor/trunk/editor/_source/internals/fcktablehandler.js

    r435 r480  
    11/* 
    2  * FCKeditor - The text editor for Internet - http://www.fckeditor.net 
    3  * Copyright (C) 2003-2007 Frederico Caldeira Knabben 
    4  * 
    5  * == BEGIN LICENSE == 
    6  * 
    7  * Licensed under the terms of any of the following licenses at your 
    8  * choice: 
    9  * 
    10  *  - GNU General Public License Version 2 or later (the "GPL") 
    11  *    http://www.gnu.org/licenses/gpl.html 
    12  * 
    13  *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL") 
    14  *    http://www.gnu.org/licenses/lgpl.html 
    15  * 
    16  *  - Mozilla Public License Version 1.1 or later (the "MPL") 
    17  *    http://www.mozilla.org/MPL/MPL-1.1.html 
    18  * 
    19  * == END LICENSE == 
    20  * 
    21  * Manage table operations. 
    22  */ 
     2       * FCKeditor - The text editor for Internet - http://www.fckeditor.net 
     3       * Copyright (C) 2003-2007 Frederico Caldeira Knabben 
     4       * 
     5       * == BEGIN LICENSE == 
     6       * 
     7       * Licensed under the terms of any of the following licenses at your 
     8       * choice: 
     9       * 
     10       *  - GNU General Public License Version 2 or later (the "GPL") 
     11       *    http://www.gnu.org/licenses/gpl.html 
     12       * 
     13       *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL") 
     14       *    http://www.gnu.org/licenses/lgpl.html 
     15       * 
     16       *  - Mozilla Public License Version 1.1 or later (the "MPL") 
     17       *    http://www.mozilla.org/MPL/MPL-1.1.html 
     18       * 
     19       * == END LICENSE == 
     20       * 
     21       * Manage table operations. 
     22       */ 
    2323 
    2424var FCKTableHandler = new Object() ; 
     
    4242FCKTableHandler.DeleteRows = function( row ) 
    4343{ 
    44         // If no row has been passed as a parameter, 
    45         // then get the row where the selection is placed in. 
    46         if ( !row ) 
    47                 row = FCKSelection.MoveToAncestorNode( 'TR' ) ; 
    48         if ( !row ) return ; 
     44        // If no row has been passed as a parameer, 
     45        // then get the row( s ) containing the cells where the selection is placed in.  
     46        // If user selected multiple rows ( by selecting multiple cells ), walk 
     47        // the selected cell list and delete the rows containing the selected cells 
     48        if ( ! row ) 
     49        { 
     50                var aCells = FCKTableHandler.GetSelectedCells() ; 
     51                var aRowsToDelete = new Array() ; 
     52                //queue up the rows -- it's possible ( and likely ) that we may get duplicates 
     53                for ( var i = 0; i < aCells.length; i++ ) 
     54                { 
     55                        var oRow = FCKTools.GetElementAscensor( aCells[i],'TR' ) ; 
     56                        aRowsToDelete[oRow.rowIndex] = oRow ; 
     57                } 
     58                for ( var i = aRowsToDelete.length; i >= 0; i-- ) 
     59                { 
     60                        if ( aRowsToDelete[i] ) 
     61                                FCKTableHandler.DeleteRows( aRowsToDelete[i] ); 
     62                } 
     63                return ; 
     64        } 
    4965 
    5066        // Get the row's table. 
     
    7793        FCKSelection.SelectNode( table ) ; 
    7894        FCKSelection.Collapse(); 
    79         table.parentNode.removeChild( table ) ; 
     95 
     96        // if the table is wrapped with a singleton <p> ( or something similar ), remove 
     97        // the surrounding tag -- which likely won't show after deletion anyway 
     98        if ( table.parentNode.childNodes.length == 1 ) 
     99                table.parentNode.parentNode.removeChild( table.parentNode ); 
     100        else 
     101                table.parentNode.removeChild( table  ) ; 
    80102} 
    81103 
     
    83105{ 
    84106        // Get the cell where the selection is placed in. 
    85         var oCell = FCKSelection.MoveToAncestorNode('TD') || FCKSelection.MoveToAncestorNode('TH') ; 
    86  
    87         if ( !oCell )  
    88         { 
    89                 // oCell not fouund could be due to multiple selection ranges on tables in Gecko. 
    90                 // We have another function to find the table cell for this special case. 
    91                 if ( ! FCKBrowserInfo.IsIE ) 
    92                 { 
    93                         var node = this._GetSelectedCellFromGecko( true ) ; 
    94                         if ( node ) 
    95                                 oCell = node ; 
    96                         else 
    97                                 return null ; 
    98                 } 
    99                 else 
    100                         return null ; 
    101         } 
     107        var oCell = null ; 
     108        var nodes = this.GetSelectedCells() ; 
     109        if ( nodes && nodes.length ) 
     110                oCell = nodes[ insertBefore ? 0 : ( nodes.length - 1 ) ] ; 
     111        if ( ! oCell ) 
     112                return null ; 
    102113 
    103114        // Get the cell's table. 
     
    133144} 
    134145 
    135 FCKTableHandler.DeleteColumns = function() 
    136 { 
    137         // Get the cell where the selection is placed in. 
    138         var oCell = FCKSelection.MoveToAncestorNode('TD') || FCKSelection.MoveToAncestorNode('TH') ; 
     146FCKTableHandler.DeleteColumns = function( oCell ) 
     147{ 
     148        // if user selected multiple cols ( by selecting multiple cells ), walk 
     149        // the selected cell list and delete the rows containing the selected cells 
     150        if ( !oCell  ) 
     151        { 
     152                var aColsToDelete = FCKTableHandler.GetSelectedCells(); 
     153                for ( var i = aColsToDelete.length; i >= 0; i--  ) 
     154                { 
     155                        if ( aColsToDelete[i]  ) 
     156                                FCKTableHandler.DeleteColumns( aColsToDelete[i]  ); 
     157                } 
     158                return; 
     159        } 
    139160 
    140161        if ( !oCell ) return ; 
     
    170191{ 
    171192        // Get the cell where the selection is placed in. 
    172         var oCell = cell ? cell : FCKSelection.MoveToAncestorNode( 'TD' ) ; 
    173         if ( !oCell )  
    174         { 
    175                 // oCell not fouund could be due to multiple selection ranges on tables in Gecko. 
    176                 // We have another function to find the table cell for this special case. 
    177                 if ( ! FCKBrowserInfo.IsIE ) 
    178                 { 
    179                         var node = this._GetSelectedCellFromGecko( true ) ; 
    180                         if ( node ) 
    181                                 oCell = node ; 
    182                         else 
    183                                 return null ; 
    184                 } 
    185                 else 
    186                         return null ; 
    187         } 
     193        var oCell = null ; 
     194        var nodes = this.GetSelectedCells() ; 
     195        if ( nodes && nodes.length ) 
     196                oCell = nodes[ insertBefore ? 0 : ( nodes.length - 1 ) ] ; 
     197        if ( ! oCell ) 
     198                return null ; 
    188199 
    189200        // Create the new cell element to be added. 
     
    191202        if ( FCKBrowserInfo.IsGecko ) 
    192203                oNewCell.innerHTML = GECKO_BOGUS ; 
    193 //      oNewCell.innerHTML = "&nbsp;" ; 
     204        //      oNewCell.innerHTML = "&nbsp;" ; 
    194205 
    195206        if ( !insertBefore && oCell.cellIndex == oCell.parentNode.cells.length - 1 ) 
     
    256267                                continue ; 
    257268 
    258                                 oCellsContents.insertBefore( eChild, oCellsContents.firstChild ) ; 
     269                        oCellsContents.insertBefore( eChild, oCellsContents.firstChild ) ; 
    259270                } 
    260271 
     
    288299        var iCellIndex = FCKTableHandler._GetCellIndexSpan( aMap, aCells[0].parentNode.rowIndex , aCells[0] ) ; 
    289300 
    290         var aCollCells = this._GetCollumnCells( aMap, iCellIndex ) ; 
     301        var aCollCells = this._GetColumnCells( aMap, iCellIndex ) ; 
    291302 
    292303        for ( var i = 0 ; i < aCollCells.length ; i++ ) 
     
    325336} 
    326337 
    327 // Get the cells available in a collumn of a TableMap. 
    328 FCKTableHandler._GetCollumnCells = function( tableMap, collumnIndex ) 
     338// Get the cell location from a TableMap. Returns an array with an [x,y] location 
     339FCKTableHandler._GetCellLocation = function( tableMap, cell  ) 
     340{ 
     341        for ( var i = 0 ; i < tableMap.length; i++ ) 
     342        { 
     343                for ( var c = 0 ; c < tableMap[i].length ; c++  ) 
     344                { 
     345                        if ( tableMap[i][c] == cell  ) return [i,c]; 
     346                } 
     347        } 
     348        return null ; 
     349} 
     350 
     351// Get the cells available in a column of a TableMap. 
     352FCKTableHandler._GetColumnCells = function( tableMap, columnIndex ) 
    329353{ 
    330354        var aCollCells = new Array() ; 
     
    332356        for ( var r = 0 ; r < tableMap.length ; r++ ) 
    333357        { 
    334                 var oCell = tableMap[r][collumnIndex] ; 
     358                var oCell = tableMap[r][columnIndex] ; 
    335359                if ( oCell && ( aCollCells.length == 0 || aCollCells[ aCollCells.length - 1 ] != oCell ) ) 
    336360                        aCollCells[ aCollCells.length ] = oCell ; 
     
    405429        } 
    406430} 
    407  
    408 FCKTableHandler._GetSelectedCellFromGecko = function( getLastCell ) 
    409 { 
    410         var sel = FCK.EditorWindow.getSelection() ; 
    411         if ( sel.rangeCount < 1 ) 
    412                 return null ; 
    413         var range = getLastCell ? sel.getRangeAt( sel.rangeCount - 1 ) : sel.getRangeAt( 0 ) ; 
    414         var node = getLastCell ? range.endContainer : range.startContainer ; 
    415  
    416         // Gecko returns a <TR> as startContainer and endContainer when cells are selected. 
    417         // We need to find back the final <TD|TH> that's being selected. 
    418         if ( node.nodeType == 1 && node.tagName.toLowerCase() == 'tr' ) 
    419         { 
    420                 for ( var i = range.startOffset ; i <= range.endOffset ; i++ ) 
    421                 { 
    422                         var candidate = node.childNodes[i] ; 
    423                         var tag = candidate.tagName.toLowerCase() ; 
    424                         if ( candidate.nodeType == 1 && ( tag == 'td' || tag == 'th' ) ) 
    425                         { 
    426                                 node = node.childNodes[i] ; 
    427                                 break ; 
    428                         } 
    429                 } 
    430         } 
    431         // For safety, we have to be ready for the 'usual' case as well. 
    432         else 
    433         { 
    434                 while ( node && node.tagName.toLowerCase() != 'td' && node.tagName.toLowerCase() != 'th' ) 
    435                         node = node.parentNode ; 
    436         } 
    437  
    438         // Have we found the <TD|TH> node we wanted, finally? If yes, return the found node. If not, abort. 
    439         if ( node.tagName.toLowerCase() != 'td' && node.tagName.toLowerCase() != 'th' ) 
    440                 return null ; 
    441         else 
    442                 return node ; 
    443 } 
  • FCKeditor/trunk/editor/_source/internals/fcktools.js

    r428 r480  
    9494                return '' ; 
    9595 
    96         text = text.replace( /&/g, '&amp;' ) ; 
    97         text = text.replace( /</g, '&lt;' ) ; 
    98         text = text.replace( />/g, '&gt;' ) ; 
    99  
    100         return text ; 
    10196} 
    10297 
  • FCKeditor/trunk/fckconfig.js

    r438 r480  
    4949 
    5050// FCKConfig.Plugins.Add( 'autogrow' ) ; 
     51// FCKConfig.Plugins.Add( 'dragresizetable' ); 
    5152FCKConfig.AutoGrowMax = 400 ; 
    5253