[ Index ] |
|
Code source de FCKeditor 2.4 |
1 /* 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 * File Name: fcktablehandler.js 22 * Manage table operations. 23 * 24 * File Authors: 25 * Frederico Caldeira Knabben (www.fckeditor.net) 26 */ 27 28 var FCKTableHandler = new Object() ; 29 30 FCKTableHandler.InsertRow = function() 31 { 32 // Get the row where the selection is placed in. 33 var oRow = FCKSelection.MoveToAncestorNode( 'TR' ) ; 34 if ( !oRow ) return ; 35 36 // Create a clone of the row. 37 var oNewRow = oRow.cloneNode( true ) ; 38 39 // Insert the new row (copy) before of it. 40 oRow.parentNode.insertBefore( oNewRow, oRow ) ; 41 42 // Clean the row (it seems that the new row has been added after it). 43 FCKTableHandler.ClearRow( oRow ) ; 44 } 45 46 FCKTableHandler.DeleteRows = function( row ) 47 { 48 // If no row has been passed as a parameter, 49 // then get the row where the selection is placed in. 50 if ( !row ) 51 row = FCKSelection.MoveToAncestorNode( 'TR' ) ; 52 if ( !row ) return ; 53 54 // Get the row's table. 55 var oTable = FCKTools.GetElementAscensor( row, 'TABLE' ) ; 56 57 // If just one row is available then delete the entire table. 58 if ( oTable.rows.length == 1 ) 59 { 60 FCKTableHandler.DeleteTable( oTable ) ; 61 return ; 62 } 63 64 // Delete the row. 65 row.parentNode.removeChild( row ) ; 66 } 67 68 FCKTableHandler.DeleteTable = function( table ) 69 { 70 // If no table has been passed as a parameer, 71 // then get the table where the selection is placed in. 72 if ( !table ) 73 { 74 table = FCKSelection.GetSelectedElement() ; 75 if ( !table || table.tagName != 'TABLE' ) 76 table = FCKSelection.MoveToAncestorNode( 'TABLE' ) ; 77 } 78 if ( !table ) return ; 79 80 // Delete the table. 81 FCKSelection.SelectNode( table ) ; 82 FCKSelection.Collapse(); 83 table.parentNode.removeChild( table ) ; 84 } 85 86 FCKTableHandler.InsertColumn = function() 87 { 88 // Get the cell where the selection is placed in. 89 var oCell = FCKSelection.MoveToAncestorNode('TD') || FCKSelection.MoveToAncestorNode('TH') ; 90 91 if ( !oCell ) return ; 92 93 // Get the cell's table. 94 var oTable = FCKTools.GetElementAscensor( oCell, 'TABLE' ) ; 95 96 // Get the index of the column to be created (based on the cell). 97 var iIndex = oCell.cellIndex + 1 ; 98 99 // Loop throw all rows available in the table. 100 for ( var i = 0 ; i < oTable.rows.length ; i++ ) 101 { 102 // Get the row. 103 var oRow = oTable.rows[i] ; 104 105 // If the row doens't have enought cells, ignore it. 106 if ( oRow.cells.length < iIndex ) 107 continue ; 108 109 oCell = oRow.cells[iIndex-1].cloneNode(false) ; 110 111 if ( FCKBrowserInfo.IsGecko ) 112 oCell.innerHTML = GECKO_BOGUS ; 113 114 // Get the cell that is placed in the new cell place. 115 var oBaseCell = oRow.cells[iIndex] ; 116 117 // If the cell is available (we are not in the last cell of the row). 118 if ( oBaseCell ) 119 oRow.insertBefore( oCell, oBaseCell ) ; // Insert the new cell just before of it. 120 else 121 oRow.appendChild( oCell ) ; // Append the cell at the end of the row. 122 } 123 } 124 125 FCKTableHandler.DeleteColumns = function() 126 { 127 // Get the cell where the selection is placed in. 128 var oCell = FCKSelection.MoveToAncestorNode('TD') || FCKSelection.MoveToAncestorNode('TH') ; 129 130 if ( !oCell ) return ; 131 132 // Get the cell's table. 133 var oTable = FCKTools.GetElementAscensor( oCell, 'TABLE' ) ; 134 135 // Get the cell index. 136 var iIndex = oCell.cellIndex ; 137 138 // Loop throw all rows (from down to up, because it's possible that some 139 // rows will be deleted). 140 for ( var i = oTable.rows.length - 1 ; i >= 0 ; i-- ) 141 { 142 // Get the row. 143 var oRow = oTable.rows[i] ; 144 145 // If the cell to be removed is the first one and the row has just one cell. 146 if ( iIndex == 0 && oRow.cells.length == 1 ) 147 { 148 // Remove the entire row. 149 FCKTableHandler.DeleteRows( oRow ) ; 150 continue ; 151 } 152 153 // If the cell to be removed exists the delete it. 154 if ( oRow.cells[iIndex] ) 155 oRow.removeChild( oRow.cells[iIndex] ) ; 156 } 157 } 158 159 FCKTableHandler.InsertCell = function( cell ) 160 { 161 // Get the cell where the selection is placed in. 162 var oCell = cell ? cell : FCKSelection.MoveToAncestorNode( 'TD' ) ; 163 if ( !oCell ) return null ; 164 165 // Create the new cell element to be added. 166 var oNewCell = FCK.EditorDocument.createElement( 'TD' ) ; 167 if ( FCKBrowserInfo.IsGecko ) 168 oNewCell.innerHTML = GECKO_BOGUS ; 169 // oNewCell.innerHTML = " " ; 170 171 // If it is the last cell in the row. 172 if ( oCell.cellIndex == oCell.parentNode.cells.length - 1 ) 173 { 174 // Add the new cell at the end of the row. 175 oCell.parentNode.appendChild( oNewCell ) ; 176 } 177 else 178 { 179 // Add the new cell before the next cell (after the active one). 180 oCell.parentNode.insertBefore( oNewCell, oCell.nextSibling ) ; 181 } 182 183 return oNewCell ; 184 } 185 186 FCKTableHandler.DeleteCell = function( cell ) 187 { 188 // If this is the last cell in the row. 189 if ( cell.parentNode.cells.length == 1 ) 190 { 191 // Delete the entire row. 192 FCKTableHandler.DeleteRows( FCKTools.GetElementAscensor( cell, 'TR' ) ) ; 193 return ; 194 } 195 196 // Delete the cell from the row. 197 cell.parentNode.removeChild( cell ) ; 198 } 199 200 FCKTableHandler.DeleteCells = function() 201 { 202 var aCells = FCKTableHandler.GetSelectedCells() ; 203 204 for ( var i = aCells.length - 1 ; i >= 0 ; i-- ) 205 { 206 FCKTableHandler.DeleteCell( aCells[i] ) ; 207 } 208 } 209 210 FCKTableHandler.MergeCells = function() 211 { 212 // Get all selected cells. 213 var aCells = FCKTableHandler.GetSelectedCells() ; 214 215 // At least 2 cells must be selected. 216 if ( aCells.length < 2 ) 217 return ; 218 219 // The merge can occour only if the selected cells are from the same row. 220 if ( aCells[0].parentNode != aCells[aCells.length-1].parentNode ) 221 return ; 222 223 // Calculate the new colSpan for the first cell. 224 var iColSpan = isNaN( aCells[0].colSpan ) ? 1 : aCells[0].colSpan ; 225 226 var sHtml = '' ; 227 var oCellsContents = FCK.EditorDocument.createDocumentFragment() ; 228 229 for ( var i = aCells.length - 1 ; i >= 0 ; i-- ) 230 { 231 var eCell = aCells[i] ; 232 233 // Move its contents to the document fragment. 234 for ( var c = eCell.childNodes.length - 1 ; c >= 0 ; c-- ) 235 { 236 var eChild = eCell.removeChild( eCell.childNodes[c] ) ; 237 238 if ( ( eChild.hasAttribute && eChild.hasAttribute('_moz_editor_bogus_node') ) || ( eChild.getAttribute && eChild.getAttribute( 'type', 2 ) == '_moz' ) ) 239 continue ; 240 241 oCellsContents.insertBefore( eChild, oCellsContents.firstChild ) ; 242 } 243 244 if ( i > 0 ) 245 { 246 // Accumulate the colspan of the cell. 247 iColSpan += isNaN( eCell.colSpan ) ? 1 : eCell.colSpan ; 248 249 // Delete the cell. 250 FCKTableHandler.DeleteCell( eCell ) ; 251 } 252 } 253 254 // Set the innerHTML of the remaining cell (the first one). 255 aCells[0].colSpan = iColSpan ; 256 257 if ( FCKBrowserInfo.IsGecko && oCellsContents.childNodes.length == 0 ) 258 aCells[0].innerHTML = GECKO_BOGUS ; 259 else 260 aCells[0].appendChild( oCellsContents ) ; 261 } 262 263 FCKTableHandler.SplitCell = function() 264 { 265 // Check that just one cell is selected, otherwise return. 266 var aCells = FCKTableHandler.GetSelectedCells() ; 267 if ( aCells.length != 1 ) 268 return ; 269 270 var aMap = this._CreateTableMap( aCells[0].parentNode.parentNode ) ; 271 var iCellIndex = FCKTableHandler._GetCellIndexSpan( aMap, aCells[0].parentNode.rowIndex , aCells[0] ) ; 272 273 var aCollCells = this._GetCollumnCells( aMap, iCellIndex ) ; 274 275 for ( var i = 0 ; i < aCollCells.length ; i++ ) 276 { 277 if ( aCollCells[i] == aCells[0] ) 278 { 279 var oNewCell = this.InsertCell( aCells[0] ) ; 280 if ( !isNaN( aCells[0].rowSpan ) && aCells[0].rowSpan > 1 ) 281 oNewCell.rowSpan = aCells[0].rowSpan ; 282 } 283 else 284 { 285 if ( isNaN( aCollCells[i].colSpan ) ) 286 aCollCells[i].colSpan = 2 ; 287 else 288 aCollCells[i].colSpan += 1 ; 289 } 290 } 291 } 292 293 // Get the cell index from a TableMap. 294 FCKTableHandler._GetCellIndexSpan = function( tableMap, rowIndex, cell ) 295 { 296 if ( tableMap.length < rowIndex + 1 ) 297 return null ; 298 299 var oRow = tableMap[ rowIndex ] ; 300 301 for ( var c = 0 ; c < oRow.length ; c++ ) 302 { 303 if ( oRow[c] == cell ) 304 return c ; 305 } 306 307 return null ; 308 } 309 310 // Get the cells available in a collumn of a TableMap. 311 FCKTableHandler._GetCollumnCells = function( tableMap, collumnIndex ) 312 { 313 var aCollCells = new Array() ; 314 315 for ( var r = 0 ; r < tableMap.length ; r++ ) 316 { 317 var oCell = tableMap[r][collumnIndex] ; 318 if ( oCell && ( aCollCells.length == 0 || aCollCells[ aCollCells.length - 1 ] != oCell ) ) 319 aCollCells[ aCollCells.length ] = oCell ; 320 } 321 322 return aCollCells ; 323 } 324 325 // This function is quite hard to explain. It creates a matrix representing all cells in a table. 326 // The difference here is that the "spanned" cells (colSpan and rowSpan) are duplicated on the matrix 327 // cells that are "spanned". For example, a row with 3 cells where the second cell has colSpan=2 and rowSpan=3 328 // will produce a bi-dimensional matrix with the following values (representing the cells): 329 // Cell1, Cell2, Cell2, Cell 3 330 // Cell4, Cell2, Cell2, Cell 5 331 FCKTableHandler._CreateTableMap = function( table ) 332 { 333 var aRows = table.rows ; 334 335 // Row and Collumn counters. 336 var r = -1 ; 337 338 var aMap = new Array() ; 339 340 for ( var i = 0 ; i < aRows.length ; i++ ) 341 { 342 r++ ; 343 if ( !aMap[r] ) 344 aMap[r] = new Array() ; 345 346 var c = -1 ; 347 348 for ( var j = 0 ; j < aRows[i].cells.length ; j++ ) 349 { 350 var oCell = aRows[i].cells[j] ; 351 352 c++ ; 353 while ( aMap[r][c] ) 354 c++ ; 355 356 var iColSpan = isNaN( oCell.colSpan ) ? 1 : oCell.colSpan ; 357 var iRowSpan = isNaN( oCell.rowSpan ) ? 1 : oCell.rowSpan ; 358 359 for ( var rs = 0 ; rs < iRowSpan ; rs++ ) 360 { 361 if ( !aMap[r + rs] ) 362 aMap[r + rs] = new Array() ; 363 364 for ( var cs = 0 ; cs < iColSpan ; cs++ ) 365 { 366 aMap[r + rs][c + cs] = aRows[i].cells[j] ; 367 } 368 } 369 370 c += iColSpan - 1 ; 371 } 372 } 373 return aMap ; 374 } 375 376 FCKTableHandler.ClearRow = function( tr ) 377 { 378 // Get the array of row's cells. 379 var aCells = tr.cells ; 380 381 // Replace the contents of each cell with "nothing". 382 for ( var i = 0 ; i < aCells.length ; i++ ) 383 { 384 if ( FCKBrowserInfo.IsGecko ) 385 aCells[i].innerHTML = GECKO_BOGUS ; 386 else 387 aCells[i].innerHTML = '' ; 388 } 389 }
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Sun Feb 25 15:28:05 2007 | par Balluche grâce à PHPXref 0.7 |