Subversion Repositories Applications.papyrus

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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