source: sandbox/3.0/phpgwapi/js/ckeditor/_source/plugins/tabletools/plugin.js @ 2862

Revision 2862, 27.5 KB checked in by rodsouza, 14 years ago (diff)

Ticket #663 - Atualizando e centralizando o CKEditor (v. 3.2.1)

Line 
1/*
2Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.
3For licensing, see LICENSE.html or http://ckeditor.com/license
4*/
5
6(function()
7{
8        function removeRawAttribute( $node, attr )
9        {
10                if ( CKEDITOR.env.ie )
11                        $node.removeAttribute( attr );
12                else
13                        delete $node[ attr ];
14        }
15
16        var cellNodeRegex = /^(?:td|th)$/;
17
18        function getSelectedCells( selection )
19        {
20                // Walker will try to split text nodes, which will make the current selection
21                // invalid. So save bookmarks before doing anything.
22                var bookmarks = selection.createBookmarks();
23
24                var ranges = selection.getRanges();
25                var retval = [];
26                var database = {};
27
28                function moveOutOfCellGuard( node )
29                {
30                        // Apply to the first cell only.
31                        if ( retval.length > 0 )
32                                return;
33
34                        // If we are exiting from the first </td>, then the td should definitely be
35                        // included.
36                        if ( node.type == CKEDITOR.NODE_ELEMENT && cellNodeRegex.test( node.getName() )
37                                        && !node.getCustomData( 'selected_cell' ) )
38                        {
39                                CKEDITOR.dom.element.setMarker( database, node, 'selected_cell', true );
40                                retval.push( node );
41                        }
42                }
43
44                for ( var i = 0 ; i < ranges.length ; i++ )
45                {
46                        var range = ranges[ i ];
47
48                        if ( range.collapsed )
49                        {
50                                // Walker does not handle collapsed ranges yet - fall back to old API.
51                                var startNode = range.getCommonAncestor();
52                                var nearestCell = startNode.getAscendant( 'td', true ) || startNode.getAscendant( 'th', true );
53                                if ( nearestCell )
54                                        retval.push( nearestCell );
55                        }
56                        else
57                        {
58                                var walker = new CKEDITOR.dom.walker( range );
59                                var node;
60                                walker.guard = moveOutOfCellGuard;
61
62                                while ( ( node = walker.next() ) )
63                                {
64                                        // If may be possible for us to have a range like this:
65                                        // <td>^1</td><td>^2</td>
66                                        // The 2nd td shouldn't be included.
67                                        //
68                                        // So we have to take care to include a td we've entered only when we've
69                                        // walked into its children.
70
71                                        var parent = node.getParent();
72                                        if ( parent && cellNodeRegex.test( parent.getName() ) && !parent.getCustomData( 'selected_cell' ) )
73                                        {
74                                                CKEDITOR.dom.element.setMarker( database, parent, 'selected_cell', true );
75                                                retval.push( parent );
76                                        }
77                                }
78                        }
79                }
80
81                CKEDITOR.dom.element.clearAllMarkers( database );
82
83                // Restore selection position.
84                selection.selectBookmarks( bookmarks );
85
86                return retval;
87        }
88
89        function getFocusedCell( cellsToDelete ) {
90                var i = 0,
91                        last = cellsToDelete.length - 1,
92                        database = {},
93                        cell,focusedCell,
94                        tr;
95
96                while ( ( cell = cellsToDelete[ i++ ] ) )
97                        CKEDITOR.dom.element.setMarker( database, cell, 'delete_cell', true );
98
99                // 1.first we check left or right side focusable cell row by row;
100                i = 0;
101                while ( ( cell = cellsToDelete[ i++ ] ) )
102                {
103                        if ( ( focusedCell = cell.getPrevious() ) && !focusedCell.getCustomData( 'delete_cell' )
104                          || ( focusedCell = cell.getNext()     ) && !focusedCell.getCustomData( 'delete_cell' ) )
105                        {
106                                CKEDITOR.dom.element.clearAllMarkers( database );
107                                return focusedCell;
108                        }
109                }
110
111                CKEDITOR.dom.element.clearAllMarkers( database );
112
113                // 2. then we check the toppest row (outside the selection area square) focusable cell
114                tr = cellsToDelete[ 0 ].getParent();
115                if ( ( tr = tr.getPrevious() ) )
116                        return tr.getLast();
117
118                // 3. last we check the lowerest  row focusable cell
119                tr = cellsToDelete[ last ].getParent();
120                if ( ( tr = tr.getNext() ) )
121                        return tr.getChild( 0 );
122
123                return null;
124        }
125
126        function clearRow( $tr )
127        {
128                // Get the array of row's cells.
129                var $cells = $tr.cells;
130
131                // Empty all cells.
132                for ( var i = 0 ; i < $cells.length ; i++ )
133                {
134                        $cells[ i ].innerHTML = '';
135
136                        if ( !CKEDITOR.env.ie )
137                                ( new CKEDITOR.dom.element( $cells[ i ] ) ).appendBogus();
138                }
139        }
140
141        function insertRow( selection, insertBefore )
142        {
143                // Get the row where the selection is placed in.
144                var row = selection.getStartElement().getAscendant( 'tr' );
145                if ( !row )
146                        return;
147
148                // Create a clone of the row.
149                var newRow = row.clone( true );
150
151                // Insert the new row before of it.
152                newRow.insertBefore( row );
153
154                // Clean one of the rows to produce the illusion of inserting an empty row
155                // before or after.
156                clearRow( insertBefore ? newRow.$ : row.$ );
157        }
158
159        function deleteRows( selectionOrRow )
160        {
161                if ( selectionOrRow instanceof CKEDITOR.dom.selection )
162                {
163                        var cells = getSelectedCells( selectionOrRow ),
164                                cellsCount = cells.length,
165                                rowsToDelete = [],
166                                cursorPosition,
167                                previousRowIndex,
168                                nextRowIndex;
169
170                        // Queue up the rows - it's possible and likely that we have duplicates.
171                        for ( var i = 0 ; i < cellsCount ; i++ )
172                        {
173                                var row = cells[ i ].getParent(),
174                                                rowIndex = row.$.rowIndex;
175
176                                !i && ( previousRowIndex = rowIndex - 1 );
177                                rowsToDelete[ rowIndex ] = row;
178                                i == cellsCount - 1 && ( nextRowIndex = rowIndex + 1 );
179                        }
180
181                        var table = row.getAscendant( 'table' ),
182                                        rows =  table.$.rows,
183                                        rowCount = rows.length;
184
185                        // Where to put the cursor after rows been deleted?
186                        // 1. Into next sibling row if any;
187                        // 2. Into previous sibling row if any;
188                        // 3. Into table's parent element if it's the very last row.
189                        cursorPosition = new CKEDITOR.dom.element(
190                                nextRowIndex < rowCount && table.$.rows[ nextRowIndex ] ||
191                                previousRowIndex > 0 && table.$.rows[ previousRowIndex ] ||
192                                table.$.parentNode );
193
194                        for ( i = rowsToDelete.length ; i >= 0 ; i-- )
195                        {
196                                if ( rowsToDelete[ i ] )
197                                        deleteRows( rowsToDelete[ i ] );
198                        }
199
200                        return cursorPosition;
201                }
202                else if ( selectionOrRow instanceof CKEDITOR.dom.element )
203                {
204                        table = selectionOrRow.getAscendant( 'table' );
205
206                        if ( table.$.rows.length == 1 )
207                                table.remove();
208                        else
209                                selectionOrRow.remove();
210                }
211
212                return 0;
213        }
214
215        function insertColumn( selection, insertBefore )
216        {
217                // Get the cell where the selection is placed in.
218                var startElement = selection.getStartElement();
219                var cell = startElement.getAscendant( 'td', true ) || startElement.getAscendant( 'th', true );
220
221                if ( !cell )
222                        return;
223
224                // Get the cell's table.
225                var table = cell.getAscendant( 'table' );
226                var cellIndex = cell.$.cellIndex;
227
228                // Loop through all rows available in the table.
229                for ( var i = 0 ; i < table.$.rows.length ; i++ )
230                {
231                        var $row = table.$.rows[ i ];
232
233                        // If the row doesn't have enough cells, ignore it.
234                        if ( $row.cells.length < ( cellIndex + 1 ) )
235                                continue;
236
237                        cell = new CKEDITOR.dom.element( $row.cells[ cellIndex ].cloneNode( false ) );
238
239                        if ( !CKEDITOR.env.ie )
240                                cell.appendBogus();
241
242                        // Get back the currently selected cell.
243                        var baseCell = new CKEDITOR.dom.element( $row.cells[ cellIndex ] );
244                        if ( insertBefore )
245                                cell.insertBefore( baseCell );
246                        else
247                                cell.insertAfter( baseCell );
248                }
249        }
250
251        function deleteColumns( selectionOrCell )
252        {
253                if ( selectionOrCell instanceof CKEDITOR.dom.selection )
254                {
255                        var colsToDelete = getSelectedCells( selectionOrCell );
256                        for ( var i = colsToDelete.length ; i >= 0 ; i-- )
257                        {
258                                if ( colsToDelete[ i ] )
259                                        deleteColumns( colsToDelete[ i ] );
260                        }
261                }
262                else if ( selectionOrCell instanceof CKEDITOR.dom.element )
263                {
264                        // Get the cell's table.
265                        var table = selectionOrCell.getAscendant( 'table' );
266
267                        // Get the cell index.
268                        var cellIndex = selectionOrCell.$.cellIndex;
269
270                        /*
271                         * Loop through all rows from down to up, coz it's possible that some rows
272                         * will be deleted.
273                         */
274                        for ( i = table.$.rows.length - 1 ; i >= 0 ; i-- )
275                        {
276                                // Get the row.
277                                var row = new CKEDITOR.dom.element( table.$.rows[ i ] );
278
279                                // If the cell to be removed is the first one and the row has just one cell.
280                                if ( !cellIndex && row.$.cells.length == 1 )
281                                {
282                                        deleteRows( row );
283                                        continue;
284                                }
285
286                                // Else, just delete the cell.
287                                if ( row.$.cells[ cellIndex ] )
288                                        row.$.removeChild( row.$.cells[ cellIndex ] );
289                        }
290                }
291        }
292
293        function insertCell( selection, insertBefore )
294        {
295                var startElement = selection.getStartElement();
296                var cell = startElement.getAscendant( 'td', true ) || startElement.getAscendant( 'th', true );
297
298                if ( !cell )
299                        return;
300
301                // Create the new cell element to be added.
302                var newCell = cell.clone();
303                if ( !CKEDITOR.env.ie )
304                        newCell.appendBogus();
305
306                if ( insertBefore )
307                        newCell.insertBefore( cell );
308                else
309                        newCell.insertAfter( cell );
310        }
311
312        function deleteCells( selectionOrCell )
313        {
314                if ( selectionOrCell instanceof CKEDITOR.dom.selection )
315                {
316                        var cellsToDelete = getSelectedCells( selectionOrCell );
317                        var table = cellsToDelete[ 0 ] && cellsToDelete[ 0 ].getAscendant( 'table' );
318                        var cellToFocus   = getFocusedCell( cellsToDelete );
319
320                        for ( var i = cellsToDelete.length - 1 ; i >= 0 ; i-- )
321                                deleteCells( cellsToDelete[ i ] );
322
323                        if ( cellToFocus )
324                                placeCursorInCell( cellToFocus, true );
325                        else if ( table )
326                                table.remove();
327                }
328                else if ( selectionOrCell instanceof CKEDITOR.dom.element )
329                {
330                        var tr = selectionOrCell.getParent();
331                        if ( tr.getChildCount() == 1 )
332                                tr.remove();
333                        else
334                                selectionOrCell.remove();
335                }
336        }
337
338        // Remove filler at end and empty spaces around the cell content.
339        function trimCell( cell )
340        {
341                var bogus = cell.getBogus();
342                bogus && bogus.remove();
343                cell.trim();
344        }
345
346        function placeCursorInCell( cell, placeAtEnd )
347        {
348                var range = new CKEDITOR.dom.range( cell.getDocument() );
349                if ( !range[ 'moveToElementEdit' + ( placeAtEnd ? 'End' : 'Start' ) ]( cell ) )
350                {
351                        range.selectNodeContents( cell );
352                        range.collapse( placeAtEnd ? false : true );
353                }
354                range.select( true );
355        }
356
357        function buildTableMap( table )
358        {
359
360                var aRows = table.$.rows ;
361
362                // Row and Column counters.
363                var r = -1 ;
364
365                var aMap = [];
366
367                for ( var i = 0 ; i < aRows.length ; i++ )
368                {
369                        r++ ;
370                        !aMap[r] && ( aMap[r] = [] );
371
372                        var c = -1 ;
373
374                        for ( var j = 0 ; j < aRows[i].cells.length ; j++ )
375                        {
376                                var oCell = aRows[i].cells[j] ;
377
378                                c++ ;
379                                while ( aMap[r][c] )
380                                        c++ ;
381
382                                var iColSpan = isNaN( oCell.colSpan ) ? 1 : oCell.colSpan ;
383                                var iRowSpan = isNaN( oCell.rowSpan ) ? 1 : oCell.rowSpan ;
384
385                                for ( var rs = 0 ; rs < iRowSpan ; rs++ )
386                                {
387                                        if ( !aMap[r + rs] )
388                                                aMap[r + rs] = new Array() ;
389
390                                        for ( var cs = 0 ; cs < iColSpan ; cs++ )
391                                        {
392                                                aMap[r + rs][c + cs] = aRows[i].cells[j] ;
393                                        }
394                                }
395
396                                c += iColSpan - 1 ;
397                        }
398                }
399                return aMap ;
400        }
401
402        function cellInRow( tableMap, rowIndex, cell )
403        {
404                var oRow = tableMap[ rowIndex ];
405                if ( typeof cell == 'undefined' )
406                        return oRow;
407
408                for ( var c = 0 ; oRow && c < oRow.length ; c++ )
409                {
410                        if ( cell.is && oRow[c] == cell.$ )
411                                return c;
412                        else if ( c == cell )
413                                return new CKEDITOR.dom.element( oRow[ c ] );
414                }
415                return cell.is ? -1 : null;
416        }
417
418        function cellInCol( tableMap, colIndex, cell )
419        {
420                var oCol = [];
421                for ( var r = 0; r < tableMap.length; r++ )
422                {
423                        var row = tableMap[ r ];
424                        if ( typeof cell == 'undefined' )
425                                oCol.push( row[ colIndex ] );
426                        else if ( cell.is && row[ colIndex ] == cell.$ )
427                                return r;
428                        else if ( r == cell )
429                                return new CKEDITOR.dom.element( row[ colIndex ] );
430                }
431
432                return ( typeof cell == 'undefined' )? oCol : cell.is ? -1 :  null;
433        }
434
435        function mergeCells( selection, mergeDirection, isDetect )
436        {
437                var cells = getSelectedCells( selection );
438
439                // Invalid merge request if:
440                // 1. In batch mode despite that less than two selected.
441                // 2. In solo mode while not exactly only one selected.
442                // 3. Cells distributed in different table groups (e.g. from both thead and tbody).
443                var commonAncestor;
444                if ( ( mergeDirection ? cells.length != 1 : cells.length < 2 )
445                                || ( commonAncestor = selection.getCommonAncestor() )
446                                && commonAncestor.type == CKEDITOR.NODE_ELEMENT
447                                && commonAncestor.is( 'table' ) )
448                {
449                        return false;
450                }
451
452                var     cell,
453                        firstCell = cells[ 0 ],
454                        table = firstCell.getAscendant( 'table' ),
455                        map = buildTableMap( table ),
456                        mapHeight = map.length,
457                        mapWidth = map[ 0 ].length,
458                        startRow = firstCell.getParent().$.rowIndex,
459                        startColumn = cellInRow( map, startRow, firstCell );
460
461                if ( mergeDirection )
462                {
463                        var targetCell;
464                        try
465                        {
466                                targetCell =
467                                        map[ mergeDirection == 'up' ?
468                                                        ( startRow - 1 ):
469                                                        mergeDirection == 'down' ? ( startRow + 1 ) : startRow  ] [
470                                                 mergeDirection == 'left' ?
471                                                        ( startColumn - 1 ):
472                                                 mergeDirection == 'right' ?  ( startColumn + 1 ) : startColumn ];
473
474                        }
475                        catch( er )
476                        {
477                                return false;
478                        }
479
480                        // 1. No cell could be merged.
481                        // 2. Same cell actually.
482                        if ( !targetCell || firstCell.$ == targetCell  )
483                                return false;
484
485                        // Sort in map order regardless of the DOM sequence.
486                        cells[ ( mergeDirection == 'up' || mergeDirection == 'left' ) ?
487                                 'unshift' : 'push' ]( new CKEDITOR.dom.element( targetCell ) );
488                }
489
490                // Start from here are merging way ignorance (merge up/right, batch merge).
491                var     doc = firstCell.getDocument(),
492                        lastRowIndex = startRow,
493                        totalRowSpan = 0,
494                        totalColSpan = 0,
495                        // Use a documentFragment as buffer when appending cell contents.
496                        frag = !isDetect && new CKEDITOR.dom.documentFragment( doc ),
497                        dimension = 0;
498
499                for ( var i = 0; i < cells.length; i++ )
500                {
501                        cell = cells[ i ];
502
503                        var tr = cell.getParent(),
504                                cellFirstChild = cell.getFirst(),
505                                colSpan = cell.$.colSpan,
506                                rowSpan = cell.$.rowSpan,
507                                rowIndex = tr.$.rowIndex,
508                                colIndex = cellInRow( map, rowIndex, cell );
509
510                        // Accumulated the actual places taken by all selected cells.
511                        dimension += colSpan * rowSpan;
512                        // Accumulated the maximum virtual spans from column and row.
513                        totalColSpan = Math.max( totalColSpan, colIndex - startColumn + colSpan ) ;
514                        totalRowSpan = Math.max( totalRowSpan, rowIndex - startRow + rowSpan );
515
516                        if ( !isDetect )
517                        {
518                                // Trim all cell fillers and check to remove empty cells.
519                                if ( trimCell( cell ), cell.getChildren().count() )
520                                {
521                                        // Merge vertically cells as two separated paragraphs.
522                                        if ( rowIndex != lastRowIndex
523                                                && cellFirstChild
524                                                && !( cellFirstChild.isBlockBoundary
525                                                          && cellFirstChild.isBlockBoundary( { br : 1 } ) ) )
526                                        {
527                                                var last = frag.getLast( CKEDITOR.dom.walker.whitespaces( true ) );
528                                                if ( last && !( last.is && last.is( 'br' ) ) )
529                                                        frag.append( new CKEDITOR.dom.element( 'br' ) );
530                                        }
531
532                                        cell.moveChildren( frag );
533                                }
534                                i ? cell.remove() : cell.setHtml( '' );
535                        }
536                        lastRowIndex = rowIndex;
537                }
538
539                if ( !isDetect )
540                {
541                        frag.moveChildren( firstCell );
542
543                        if ( !CKEDITOR.env.ie )
544                                firstCell.appendBogus();
545
546                        if ( totalColSpan >= mapWidth )
547                                firstCell.removeAttribute( 'rowSpan' );
548                        else
549                                firstCell.$.rowSpan = totalRowSpan;
550
551                        if ( totalRowSpan >= mapHeight )
552                                firstCell.removeAttribute( 'colSpan' );
553                        else
554                                firstCell.$.colSpan = totalColSpan;
555
556                        // Swip empty <tr> left at the end of table due to the merging.
557                        var trs = new CKEDITOR.dom.nodeList( table.$.rows ),
558                                count = trs.count();
559
560                        for ( i = count - 1; i >= 0; i-- )
561                        {
562                                var tailTr = trs.getItem( i );
563                                if ( !tailTr.$.cells.length )
564                                {
565                                        tailTr.remove();
566                                        count++;
567                                        continue;
568                                }
569                        }
570
571                        return firstCell;
572                }
573                // Be able to merge cells only if actual dimension of selected
574                // cells equals to the caculated rectangle.
575                else
576                        return ( totalRowSpan * totalColSpan ) == dimension;
577        }
578
579        function verticalSplitCell ( selection, isDetect )
580        {
581                var cells = getSelectedCells( selection );
582                if ( cells.length > 1 )
583                        return false;
584                else if ( isDetect )
585                        return true;
586
587                var cell = cells[ 0 ],
588                        tr = cell.getParent(),
589                        table = tr.getAscendant( 'table' ),
590                        map = buildTableMap( table ),
591                        rowIndex = tr.$.rowIndex,
592                        colIndex = cellInRow( map, rowIndex, cell ),
593                        rowSpan = cell.$.rowSpan,
594                        newCell,
595                        newRowSpan,
596                        newCellRowSpan,
597                        newRowIndex;
598
599                if ( rowSpan > 1 )
600                {
601                        newRowSpan = Math.ceil( rowSpan / 2 );
602                        newCellRowSpan = Math.floor( rowSpan / 2 );
603                        newRowIndex = rowIndex + newRowSpan;
604                        var newCellTr = new CKEDITOR.dom.element( table.$.rows[ newRowIndex ] ),
605                                newCellRow = cellInRow( map, newRowIndex ),
606                                candidateCell;
607
608                        newCell = cell.clone();
609
610                        // Figure out where to insert the new cell by checking the vitual row.
611                        for ( var c = 0; c < newCellRow.length; c++ )
612                        {
613                                candidateCell = newCellRow[ c ];
614                                // Catch first cell actually following the column.
615                                if ( candidateCell.parentNode == newCellTr.$
616                                        && c > colIndex )
617                                {
618                                        newCell.insertBefore( new CKEDITOR.dom.element( candidateCell ) );
619                                        break;
620                                }
621                                else
622                                        candidateCell = null;
623                        }
624
625                        // The destination row is empty, append at will.
626                        if ( !candidateCell )
627                                newCellTr.append( newCell, true );
628                }
629                else
630                {
631                        newCellRowSpan = newRowSpan = 1;
632
633                        newCellTr = tr.clone();
634                        newCellTr.insertAfter( tr );
635                        newCellTr.append( newCell = cell.clone() );
636
637                        var cellsInSameRow = cellInRow( map, rowIndex );
638                        for ( var i = 0; i < cellsInSameRow.length; i++ )
639                                cellsInSameRow[ i ].rowSpan++;
640                }
641
642                if ( !CKEDITOR.env.ie )
643                        newCell.appendBogus();
644
645                cell.$.rowSpan = newRowSpan;
646                newCell.$.rowSpan = newCellRowSpan;
647                if ( newRowSpan == 1 )
648                        cell.removeAttribute( 'rowSpan' );
649                if ( newCellRowSpan == 1 )
650                        newCell.removeAttribute( 'rowSpan' );
651
652                return newCell;
653        }
654
655        function horizontalSplitCell( selection, isDetect )
656        {
657                var cells = getSelectedCells( selection );
658                if ( cells.length > 1 )
659                        return false;
660                else if ( isDetect )
661                        return true;
662
663                var cell = cells[ 0 ],
664                        tr = cell.getParent(),
665                        table = tr.getAscendant( 'table' ),
666                        map = buildTableMap( table ),
667                        rowIndex = tr.$.rowIndex,
668                        colIndex = cellInRow( map, rowIndex, cell ),
669                        colSpan = cell.$.colSpan,
670                        newCell,
671                        newColSpan,
672                        newCellColSpan;
673
674                if ( colSpan > 1 )
675                {
676                        newColSpan = Math.ceil( colSpan / 2 );
677                        newCellColSpan = Math.floor( colSpan / 2 );
678                }
679                else
680                {
681                        newCellColSpan = newColSpan = 1;
682                        var cellsInSameCol = cellInCol( map, colIndex );
683                        for ( var i = 0; i < cellsInSameCol.length; i++ )
684                                cellsInSameCol[ i ].colSpan++;
685                }
686                newCell = cell.clone();
687                newCell.insertAfter( cell );
688                if ( !CKEDITOR.env.ie )
689                        newCell.appendBogus();
690
691                cell.$.colSpan = newColSpan;
692                newCell.$.colSpan = newCellColSpan;
693                if ( newColSpan == 1 )
694                        cell.removeAttribute( 'colSpan' );
695                if ( newCellColSpan == 1 )
696                        newCell.removeAttribute( 'colSpan' );
697
698                return newCell;
699        }
700        // Context menu on table caption incorrect (#3834)
701        var contextMenuTags = { thead : 1, tbody : 1, tfoot : 1, td : 1, tr : 1, th : 1 };
702
703        CKEDITOR.plugins.tabletools =
704        {
705                init : function( editor )
706                {
707                        var lang = editor.lang.table;
708
709                        editor.addCommand( 'cellProperties', new CKEDITOR.dialogCommand( 'cellProperties' ) );
710                        CKEDITOR.dialog.add( 'cellProperties', this.path + 'dialogs/tableCell.js' );
711
712                        editor.addCommand( 'tableDelete',
713                                {
714                                        exec : function( editor )
715                                        {
716                                                var selection = editor.getSelection();
717                                                var startElement = selection && selection.getStartElement();
718                                                var table = startElement && startElement.getAscendant( 'table', true );
719
720                                                if ( !table )
721                                                        return;
722
723                                                // Maintain the selection point at where the table was deleted.
724                                                selection.selectElement( table );
725                                                var range = selection.getRanges()[0];
726                                                range.collapse();
727                                                selection.selectRanges( [ range ] );
728
729                                                // If the table's parent has only one child, remove it as well.
730                                                if ( table.getParent().getChildCount() == 1 )
731                                                        table.getParent().remove();
732                                                else
733                                                        table.remove();
734                                        }
735                                } );
736
737                        editor.addCommand( 'rowDelete',
738                                {
739                                        exec : function( editor )
740                                        {
741                                                var selection = editor.getSelection();
742                                                placeCursorInCell( deleteRows( selection ) );
743                                        }
744                                } );
745
746                        editor.addCommand( 'rowInsertBefore',
747                                {
748                                        exec : function( editor )
749                                        {
750                                                var selection = editor.getSelection();
751                                                insertRow( selection, true );
752                                        }
753                                } );
754
755                        editor.addCommand( 'rowInsertAfter',
756                                {
757                                        exec : function( editor )
758                                        {
759                                                var selection = editor.getSelection();
760                                                insertRow( selection );
761                                        }
762                                } );
763
764                        editor.addCommand( 'columnDelete',
765                                {
766                                        exec : function( editor )
767                                        {
768                                                var selection = editor.getSelection();
769                                                deleteColumns( selection );
770                                        }
771                                } );
772
773                        editor.addCommand( 'columnInsertBefore',
774                                {
775                                        exec : function( editor )
776                                        {
777                                                var selection = editor.getSelection();
778                                                insertColumn( selection, true );
779                                        }
780                                } );
781
782                        editor.addCommand( 'columnInsertAfter',
783                                {
784                                        exec : function( editor )
785                                        {
786                                                var selection = editor.getSelection();
787                                                insertColumn( selection );
788                                        }
789                                } );
790
791                        editor.addCommand( 'cellDelete',
792                                {
793                                        exec : function( editor )
794                                        {
795                                                var selection = editor.getSelection();
796                                                deleteCells( selection );
797                                        }
798                                } );
799
800                        editor.addCommand( 'cellMerge',
801                                {
802                                        exec : function( editor )
803                                        {
804                                                placeCursorInCell( mergeCells( editor.getSelection() ), true );
805                                        }
806                                } );
807
808                        editor.addCommand( 'cellMergeRight',
809                                {
810                                        exec : function( editor )
811                                        {
812                                                placeCursorInCell( mergeCells( editor.getSelection(), 'right' ), true );
813                                        }
814                                } );
815
816                        editor.addCommand( 'cellMergeDown',
817                                {
818                                        exec : function( editor )
819                                        {
820                                                placeCursorInCell( mergeCells( editor.getSelection(), 'down' ), true );
821                                        }
822                                } );
823
824                        editor.addCommand( 'cellVerticalSplit',
825                                {
826                                        exec : function( editor )
827                                        {
828                                                placeCursorInCell( verticalSplitCell( editor.getSelection() ) );
829                                        }
830                                } );
831
832                        editor.addCommand( 'cellHorizontalSplit',
833                                {
834                                        exec : function( editor )
835                                        {
836                                                placeCursorInCell( horizontalSplitCell( editor.getSelection() ) );
837                                        }
838                                } );
839
840                        editor.addCommand( 'cellInsertBefore',
841                                {
842                                        exec : function( editor )
843                                        {
844                                                var selection = editor.getSelection();
845                                                insertCell( selection, true );
846                                        }
847                                } );
848
849                        editor.addCommand( 'cellInsertAfter',
850                                {
851                                        exec : function( editor )
852                                        {
853                                                var selection = editor.getSelection();
854                                                insertCell( selection );
855                                        }
856                                } );
857
858                        // If the "menu" plugin is loaded, register the menu items.
859                        if ( editor.addMenuItems )
860                        {
861                                editor.addMenuItems(
862                                        {
863                                                tablecell :
864                                                {
865                                                        label : lang.cell.menu,
866                                                        group : 'tablecell',
867                                                        order : 1,
868                                                        getItems : function()
869                                                        {
870                                                                var selection = editor.getSelection(),
871                                                                        cells = getSelectedCells( selection );
872                                                                return {
873                                                                        tablecell_insertBefore : CKEDITOR.TRISTATE_OFF,
874                                                                        tablecell_insertAfter : CKEDITOR.TRISTATE_OFF,
875                                                                        tablecell_delete : CKEDITOR.TRISTATE_OFF,
876                                                                        tablecell_merge : mergeCells( selection, null, true ) ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED,
877                                                                        tablecell_merge_right : mergeCells( selection, 'right', true ) ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED,
878                                                                        tablecell_merge_down : mergeCells( selection, 'down', true ) ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED,
879                                                                        tablecell_split_vertical : verticalSplitCell( selection, true ) ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED,
880                                                                        tablecell_split_horizontal : horizontalSplitCell( selection, true ) ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED,
881                                                                        tablecell_properties : cells.length > 0 ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED
882                                                                };
883                                                        }
884                                                },
885
886                                                tablecell_insertBefore :
887                                                {
888                                                        label : lang.cell.insertBefore,
889                                                        group : 'tablecell',
890                                                        command : 'cellInsertBefore',
891                                                        order : 5
892                                                },
893
894                                                tablecell_insertAfter :
895                                                {
896                                                        label : lang.cell.insertAfter,
897                                                        group : 'tablecell',
898                                                        command : 'cellInsertAfter',
899                                                        order : 10
900                                                },
901
902                                                tablecell_delete :
903                                                {
904                                                        label : lang.cell.deleteCell,
905                                                        group : 'tablecell',
906                                                        command : 'cellDelete',
907                                                        order : 15
908                                                },
909
910                                                tablecell_merge :
911                                                {
912                                                        label : lang.cell.merge,
913                                                        group : 'tablecell',
914                                                        command : 'cellMerge',
915                                                        order : 16
916                                                },
917
918                                                tablecell_merge_right :
919                                                {
920                                                        label : lang.cell.mergeRight,
921                                                        group : 'tablecell',
922                                                        command : 'cellMergeRight',
923                                                        order : 17
924                                                },
925
926                                                tablecell_merge_down :
927                                                {
928                                                        label : lang.cell.mergeDown,
929                                                        group : 'tablecell',
930                                                        command : 'cellMergeDown',
931                                                        order : 18
932                                                },
933
934                                                tablecell_split_horizontal :
935                                                {
936                                                        label : lang.cell.splitHorizontal,
937                                                        group : 'tablecell',
938                                                        command : 'cellHorizontalSplit',
939                                                        order : 19
940                                                },
941
942                                                tablecell_split_vertical :
943                                                {
944                                                        label : lang.cell.splitVertical,
945                                                        group : 'tablecell',
946                                                        command : 'cellVerticalSplit',
947                                                        order : 20
948                                                },
949
950                                                tablecell_properties :
951                                                {
952                                                        label : lang.cell.title,
953                                                        group : 'tablecellproperties',
954                                                        command : 'cellProperties',
955                                                        order : 21
956                                                },
957
958                                                tablerow :
959                                                {
960                                                        label : lang.row.menu,
961                                                        group : 'tablerow',
962                                                        order : 1,
963                                                        getItems : function()
964                                                        {
965                                                                return {
966                                                                        tablerow_insertBefore : CKEDITOR.TRISTATE_OFF,
967                                                                        tablerow_insertAfter : CKEDITOR.TRISTATE_OFF,
968                                                                        tablerow_delete : CKEDITOR.TRISTATE_OFF
969                                                                };
970                                                        }
971                                                },
972
973                                                tablerow_insertBefore :
974                                                {
975                                                        label : lang.row.insertBefore,
976                                                        group : 'tablerow',
977                                                        command : 'rowInsertBefore',
978                                                        order : 5
979                                                },
980
981                                                tablerow_insertAfter :
982                                                {
983                                                        label : lang.row.insertAfter,
984                                                        group : 'tablerow',
985                                                        command : 'rowInsertAfter',
986                                                        order : 10
987                                                },
988
989                                                tablerow_delete :
990                                                {
991                                                        label : lang.row.deleteRow,
992                                                        group : 'tablerow',
993                                                        command : 'rowDelete',
994                                                        order : 15
995                                                },
996
997                                                tablecolumn :
998                                                {
999                                                        label : lang.column.menu,
1000                                                        group : 'tablecolumn',
1001                                                        order : 1,
1002                                                        getItems : function()
1003                                                        {
1004                                                                return {
1005                                                                        tablecolumn_insertBefore : CKEDITOR.TRISTATE_OFF,
1006                                                                        tablecolumn_insertAfter : CKEDITOR.TRISTATE_OFF,
1007                                                                        tablecolumn_delete : CKEDITOR.TRISTATE_OFF
1008                                                                };
1009                                                        }
1010                                                },
1011
1012                                                tablecolumn_insertBefore :
1013                                                {
1014                                                        label : lang.column.insertBefore,
1015                                                        group : 'tablecolumn',
1016                                                        command : 'columnInsertBefore',
1017                                                        order : 5
1018                                                },
1019
1020                                                tablecolumn_insertAfter :
1021                                                {
1022                                                        label : lang.column.insertAfter,
1023                                                        group : 'tablecolumn',
1024                                                        command : 'columnInsertAfter',
1025                                                        order : 10
1026                                                },
1027
1028                                                tablecolumn_delete :
1029                                                {
1030                                                        label : lang.column.deleteColumn,
1031                                                        group : 'tablecolumn',
1032                                                        command : 'columnDelete',
1033                                                        order : 15
1034                                                }
1035                                        });
1036                        }
1037
1038                        // If the "contextmenu" plugin is laoded, register the listeners.
1039                        if ( editor.contextMenu )
1040                        {
1041                                editor.contextMenu.addListener( function( element, selection )
1042                                        {
1043                                                if ( !element )
1044                                                        return null;
1045
1046                                                while ( element )
1047                                                {
1048                                                        if ( element.getName() in contextMenuTags )
1049                                                        {
1050                                                                return {
1051                                                                        tablecell : CKEDITOR.TRISTATE_OFF,
1052                                                                        tablerow : CKEDITOR.TRISTATE_OFF,
1053                                                                        tablecolumn : CKEDITOR.TRISTATE_OFF
1054                                                                };
1055                                                        }
1056                                                        element = element.getParent();
1057                                                }
1058
1059                                                return null;
1060                                        } );
1061                        }
1062                },
1063
1064                getSelectedCells : getSelectedCells
1065
1066        };
1067        CKEDITOR.plugins.add( 'tabletools', CKEDITOR.plugins.tabletools );
1068})();
Note: See TracBrowser for help on using the repository browser.