| 876 | |
| 877 | FCKTableHandler.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 |
| 899 | FCKTableHandler.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. |
| 967 | FCKTableHandler.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 |
| 996 | FCKTableHandler.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 | } |