Ticket #1865: 1865_3.patch

File 1865_3.patch, 8.8 KB (added by Koen Willems, 15 years ago)
  • fcktablehandler.js

     
    382382
    383383        this._ReplaceCellsByMarker( tableMap, '_SelectedCells', refCell ) ;
    384384        this._UnmarkCells( cells, '_SelectedCells' ) ;
     385        FCKTableHandler.SaveThead( refCell ) ;
    385386        this._InstallTableMap( tableMap, refCell.parentNode.parentNode ) ;
     387        FCKTableHandler.RestoreThead ( FCKTools.GetElementAscensor( refCell, 'TABLE' ), true ) ;
    386388        refCell.appendChild( cellContents ) ;
    387389
    388390        if ( FCKBrowserInfo.IsGeckoLike && ( ! refCell.firstChild ) )
     
    408410        refCell.appendChild( cellContents ) ;
    409411        this._MarkCells( [nextCell], '_Replace' ) ;
    410412        this._ReplaceCellsByMarker( tableMap, '_Replace', refCell ) ;
     413        FCKTableHandler.SaveThead( refCell ) ;
    411414        this._InstallTableMap( tableMap, refCell.parentNode.parentNode ) ;
     415        FCKTableHandler.RestoreThead ( FCKTools.GetElementAscensor( refCell, 'TABLE' ) ) ;
    412416
    413417        this._MoveCaretToCell( refCell, false ) ;
    414418}
     
    430434        refCell.appendChild( cellContents ) ;
    431435        this._MarkCells( [nextCell], '_Replace' ) ;
    432436        this._ReplaceCellsByMarker( tableMap, '_Replace', refCell ) ;
     437        FCKTableHandler.SaveThead( refCell ) ;
    433438        this._InstallTableMap( tableMap, refCell.parentNode.parentNode ) ;
     439        FCKTableHandler.RestoreThead ( FCKTools.GetElementAscensor( refCell, 'TABLE' ), true ) ;
    434440
    435441        this._MoveCaretToCell( refCell, false ) ;
    436442}
     
    496502                tableMap = newTableMap ;
    497503        }
    498504
     505        FCKTableHandler.SaveThead( refCell ) ;
    499506        this._InstallTableMap( tableMap, refCell.parentNode.parentNode ) ;
     507        FCKTableHandler.RestoreThead ( FCKTools.GetElementAscensor( refCell, 'TABLE' ) ) ;
    500508}
    501509
    502510FCKTableHandler.VerticalSplitCell = function()
     
    540548                        newCell.colSpan = currentColSpan ;
    541549                if ( FCKBrowserInfo.IsGeckoLike )
    542550                        FCKTools.AppendBogusBr( newCell ) ;
    543                 currentCell.parentNode.parentNode.rows[newCellRowIndex].insertBefore( newCell, insertMarker ) ;
     551                currentCell.parentNode.parentNode.parentNode.rows[newCellRowIndex].insertBefore( newCell, insertMarker ) ;
    544552        }
    545553        else
    546554        {
    547555                // 1. Insert a new row.
    548556                var newCellRowIndex = currentRowIndex + 1 ;
    549557                var newRow = FCK.EditorDocument.createElement( 'tr' ) ;
    550                 var tBody = currentCell.parentNode.parentNode ;
    551                 if ( tBody.rows.length > newCellRowIndex )
    552                         tBody.insertBefore( newRow, tBody.rows[newCellRowIndex] ) ;
     558                var oTable = FCKTools.GetElementAscensor( currentCell, 'TABLE' ) ;
     559
     560                if( oTable.tHead )
     561                {
     562                        var theadRows = oTable.tHead.rows.length ;
     563
     564                        if ( currentCell.parentNode.parentNode.tagName == 'TBODY' && currentCell.parentNode.parentNode.rows.length  <= newCellRowIndex - theadRows )
     565                                currentCell.parentNode.parentNode.appendChild(newRow) ;
     566                        else if ( currentCell.parentNode.parentNode.tagName == 'THEAD' && currentCell.parentNode.parentNode.rows.length  <= newCellRowIndex )
     567                                currentCell.parentNode.parentNode.appendChild(newRow) ;
     568                        else if( currentCell.parentNode.parentNode.tagName == 'TBODY' )
     569                                currentCell.parentNode.parentNode.insertBefore( newRow, currentCell.parentNode.parentNode.rows[newCellRowIndex - theadRows] ) ;
     570                        else
     571                                currentCell.parentNode.parentNode.insertBefore( newRow, currentCell.parentNode.parentNode.rows[newCellRowIndex] ) ;
     572                }
    553573                else
    554                         tBody.appendChild( newRow ) ;
     574                {
     575                        if( currentCell.parentNode.parentNode.rows.length  <= newCellRowIndex)
     576                                currentCell.parentNode.parentNode.appendChild(newRow) ;
     577                        else
     578                                currentCell.parentNode.parentNode.insertBefore( newRow, currentCell.parentNode.parentNode.rows[newCellRowIndex] ) ;
     579                }
    555580
    556581                // 2. +1 to rowSpan for all cells crossing currentCell's row.
    557582                for ( var i = 0 ; i < tableMap[currentRowIndex].length ; )
     
    619644//              Cell4, Cell2, Cell2, Cell2, Cell 5
    620645FCKTableHandler._CreateTableMap = function( refCell )
    621646{
    622         // It's really a tbody, thead or tfoot. This is only temporary.
    623         var table = (refCell.nodeName == 'TABLE' ? refCell : refCell.parentNode.parentNode ) ;
     647        var table = (refCell.nodeName == 'TABLE' ? refCell : refCell.parentNode.parentNode.parentNode ) ;
    624648
    625649        var aRows = table.rows ;
    626650
     
    849873
    850874        return { 'refCell' : refCell, 'nextCell' : nextCell, 'tableMap' : tableMap } ;
    851875}
     876
     877FCKTableHandler.SaveThead = function( refCell )
     878{
     879        var table = FCKTools.GetElementAscensor( refCell, 'TABLE' ) ;
     880
     881        if ( table.tHead )
     882        {
     883                // Attach an attribute called '_dirtythead' to all th- and td-cels of the thead ;
     884                // Use the cells of thead instead of the rows, because _InstallTableMap() strips out all the attributes of rows;
     885                var aCells = FCKTableHandler.getElementsByTagNames( 'th,td', table.tHead ) ;
     886                for ( var i = 0; i < aCells.length; i++ )
     887                        aCells[i]._dirtythead = true ;
     888
     889                // Put al the rows of thead into the first tbody, removing them from thead
     890                FCKDomTools.MoveChildren( table.tHead, table.tBodies[0], true ) ;
     891
     892                // Remove thead
     893                table.removeChild( table.tHead ) ;
     894        }
     895        return ;
     896}
     897
     898// Restore thead if there should be one
     899FCKTableHandler.RestoreThead = function( table, merged )
     900{
     901        // First remove empty rows after merging down
     902        // and repair rowspan of the cells in the previous non_empty row
     903        if ( merged )
     904        {
     905                FCKTableHandler.RepairRowspan( table ) ;
     906
     907                var aRows = table.getElementsByTagName( 'TR' ) ;
     908                for ( var i = 0; i < aRows.length; i++ )
     909                {
     910                        if ( aRows[i].cells.length == 0 )
     911                                aRows[i].parentNode.removeChild( aRows[i] ) ;
     912                }
     913        }
     914
     915        // If there are cells with an attribute '_dirtythead' in the first tbody create a thead;
     916        // Remove the attribute '_dirtyhead' from those cells and give their row an attribute '_dirtyrow',
     917        // so complete rows instead of single cells can be moved to thead.
     918        var makeThead = 0 ;
     919        var aCells = FCKTableHandler.getElementsByTagNames( 'th,td', table ) ;
     920        for ( var i = 0; i < aCells.length; i++ )
     921        {
     922                if ( aCells[i]._dirtythead == true )
     923                {
     924                        FCKDomTools.ClearElementJSProperty( aCells[i], '_dirtythead' ) ;
     925                        aCells[i].parentNode._dirtyrow = true ;
     926                        makeThead = 1 ;
     927                }
     928        }
     929
     930        // Thead should be created
     931        if ( makeThead == 1 )
     932        {
     933                var oThead = FCK.EditorDocument.createElement( 'THEAD' ) ;
     934                // When applying a tfoot it should be inserted before tfoot; look at it later when fckeditor supports tfoot!
     935                table.insertBefore( oThead, table.tBodies[0] ) ;
     936
     937                var aRows = table.getElementsByTagName( 'TR' ) ;
     938                for ( var i = 0; i < aRows.length; i++ )
     939                {
     940                        // If they have an attribute '_dirtyrow',
     941                        if ( aRows[i]._dirtyrow === true )
     942                        {
     943                                // remove that attribute in the rows in thead,
     944                                FCKDomTools.ClearElementJSProperty( aRows[i], '_dirtyrow' ) ;
     945
     946                                // and move the row to thead, removing it from tbody[0]
     947                                FCKDomTools.MoveNode( aRows[i], oThead ) ;
     948                        }
     949                }
     950        }
     951        // Remove empty rows again.
     952        // It looks stupid, doing this twice ..., but it's the only way.
     953        if ( merged && FCKBrowserInfo.IsGeckoLike )
     954        {
     955                var aRows = table.getElementsByTagName( 'TR' ) ;
     956                for ( var i = 0; i < aRows.length; i++ )
     957                {
     958                        if ( aRows[i].cells.length == 0 )
     959                                aRows[i].parentNode.removeChild( aRows[i] ) ;
     960                }
     961        }
     962        return ;
     963}
     964
     965// After merging down empty rows are leftover.
     966// The rowspan of the cells in the previous (non-empty) row have to be lowered with the number of empty rows.
     967FCKTableHandler.RepairRowspan = function( table )
     968{
     969        var aRows = table.getElementsByTagName( 'TR' ) ;
     970        for ( var i = 0; i< aRows.length; i++ )
     971        {
     972                if ( FCKDomTools.CheckIsEmptyElement( aRows[i] ) )
     973                {
     974                        // Loop upwards to a non-empty previous row
     975                        var t = 1 ;
     976                        while ( FCKDomTools.CheckIsEmptyElement( aRows[i-t] ) )
     977                                t++ ;
     978
     979                        if ( aRows[i-t] )
     980                        {
     981                                var aWrongCells = FCKTableHandler.getElementsByTagNames( 'th,td', aRows[i-t] ) ;
     982                                for ( j = 0; j < aWrongCells.length; j++ )
     983                                {
     984                                        if ( aWrongCells[j].rowSpan >= 2 )
     985                                                aWrongCells[j].rowSpan -- ;
     986                                        if ( aWrongCells[j].rowSpan == 1 )
     987                                                aWrongCells[j].removeAttribute( 'rowspan' ) ;
     988                                }
     989                        }
     990                }
     991        }
     992        return ;
     993}
     994
     995// See http://www.quirksmode.org/dom/getElementsByTagNames.html
     996FCKTableHandler.getElementsByTagNames = function( list,obj )
     997{
     998        var tagNames = list.split( ',' ) ;
     999        var resultArray = new Array() ;
     1000        for ( var i=0; i<tagNames.length; i++ )
     1001        {
     1002                var tags = obj.getElementsByTagName( tagNames[i] ) ;
     1003                for ( var j=0; j<tags.length; j++ )
     1004                {
     1005                        resultArray.push( tags[j] ) ;
     1006                }
     1007        }
     1008        var testNode = resultArray[0] ;
     1009        if ( !testNode ) return [] ;
     1010        if ( testNode.sourceIndex )
     1011        {
     1012                resultArray.sort( function ( a,b )
     1013                {
     1014                        return a.sourceIndex - b.sourceIndex ;
     1015                } ) ;
     1016        }
     1017        else if ( testNode.compareDocumentPosition )
     1018        {
     1019                resultArray.sort( function ( a,b )
     1020                {
     1021                        return 3 - ( a.compareDocumentPosition( b ) & 6 ) ;
     1022                } ) ;
     1023        }
     1024        return resultArray;
     1025}
© 2003 – 2022, CKSource sp. z o.o. sp.k. All rights reserved. | Terms of use | Privacy policy