[ Index ] |
|
Code source de Joomla 1.0.13 |
1 /** 2 * $Id: editor_plugin_src.js 126 2006-10-22 16:19:55Z spocke $ 3 * 4 * @author Moxiecode 5 * @copyright Copyright © 2004-2006, Moxiecode Systems AB, All rights reserved. 6 */ 7 8 /* Import plugin specific language pack */ 9 tinyMCE.importPluginLanguagePack('table'); 10 11 var TinyMCE_TablePlugin = { 12 getInfo : function() { 13 return { 14 longname : 'Tables', 15 author : 'Moxiecode Systems AB', 16 authorurl : 'http://tinymce.moxiecode.com', 17 infourl : 'http://tinymce.moxiecode.com/tinymce/docs/plugin_table.html', 18 version : tinyMCE.majorVersion + "." + tinyMCE.minorVersion 19 }; 20 }, 21 22 initInstance : function(inst) { 23 if (tinyMCE.isGecko) { 24 var doc = inst.getDoc(); 25 tinyMCE.addEvent(doc, "mouseup", TinyMCE_TablePlugin._mouseDownHandler); 26 } 27 28 inst.tableRowClipboard = null; 29 }, 30 31 /** 32 * Returns the HTML contents of the table control. 33 */ 34 getControlHTML : function(control_name) { 35 var controls = new Array( 36 ['table', 'table.gif', 'lang_table_desc', 'mceInsertTable', true], 37 ['delete_table', 'table_delete.gif', 'lang_table_del', 'mceTableDelete'], 38 ['delete_col', 'table_delete_col.gif', 'lang_table_delete_col_desc', 'mceTableDeleteCol'], 39 ['delete_row', 'table_delete_row.gif', 'lang_table_delete_row_desc', 'mceTableDeleteRow'], 40 ['col_after', 'table_insert_col_after.gif', 'lang_table_col_after_desc', 'mceTableInsertColAfter'], 41 ['col_before', 'table_insert_col_before.gif', 'lang_table_col_before_desc', 'mceTableInsertColBefore'], 42 ['row_after', 'table_insert_row_after.gif', 'lang_table_row_after_desc', 'mceTableInsertRowAfter'], 43 ['row_before', 'table_insert_row_before.gif', 'lang_table_row_before_desc', 'mceTableInsertRowBefore'], 44 ['row_props', 'table_row_props.gif', 'lang_table_row_desc', 'mceTableRowProps', true], 45 ['cell_props', 'table_cell_props.gif', 'lang_table_cell_desc', 'mceTableCellProps', true], 46 ['split_cells', 'table_split_cells.gif', 'lang_table_split_cells_desc', 'mceTableSplitCells', true], 47 ['merge_cells', 'table_merge_cells.gif', 'lang_table_merge_cells_desc', 'mceTableMergeCells', true]); 48 49 // Render table control 50 for (var i=0; i<controls.length; i++) { 51 var but = controls[i]; 52 var cmd = 'tinyMCE.execInstanceCommand(\'{$editor_id}\',\'' + but[3] + '\', ' + (but.length > 4 ? but[4] : false) + (but.length > 5 ? ', \'' + but[5] + '\'' : '') + ');return false;'; 53 54 if (but[0] == control_name) 55 return tinyMCE.getButtonHTML(control_name, but[2], '{$pluginurl}/images/'+ but[1], but[3], (but.length > 4 ? but[4] : false)); 56 } 57 58 // Special tablecontrols 59 if (control_name == "tablecontrols") { 60 var html = ""; 61 62 html += tinyMCE.getControlHTML("table"); 63 html += tinyMCE.getControlHTML("separator"); 64 html += tinyMCE.getControlHTML("row_props"); 65 html += tinyMCE.getControlHTML("cell_props"); 66 html += tinyMCE.getControlHTML("separator"); 67 html += tinyMCE.getControlHTML("row_before"); 68 html += tinyMCE.getControlHTML("row_after"); 69 html += tinyMCE.getControlHTML("delete_row"); 70 html += tinyMCE.getControlHTML("separator"); 71 html += tinyMCE.getControlHTML("col_before"); 72 html += tinyMCE.getControlHTML("col_after"); 73 html += tinyMCE.getControlHTML("delete_col"); 74 html += tinyMCE.getControlHTML("separator"); 75 html += tinyMCE.getControlHTML("split_cells"); 76 html += tinyMCE.getControlHTML("merge_cells"); 77 78 return html; 79 } 80 81 return ""; 82 }, 83 84 /** 85 * Executes the table commands. 86 */ 87 execCommand : function(editor_id, element, command, user_interface, value) { 88 // Is table command 89 switch (command) { 90 case "mceInsertTable": 91 case "mceTableRowProps": 92 case "mceTableCellProps": 93 case "mceTableSplitCells": 94 case "mceTableMergeCells": 95 case "mceTableInsertRowBefore": 96 case "mceTableInsertRowAfter": 97 case "mceTableDeleteRow": 98 case "mceTableInsertColBefore": 99 case "mceTableInsertColAfter": 100 case "mceTableDeleteCol": 101 case "mceTableCutRow": 102 case "mceTableCopyRow": 103 case "mceTablePasteRowBefore": 104 case "mceTablePasteRowAfter": 105 case "mceTableDelete": 106 var inst = tinyMCE.getInstanceById(editor_id); 107 108 inst.execCommand('mceBeginUndoLevel'); 109 TinyMCE_TablePlugin._doExecCommand(editor_id, element, command, user_interface, value); 110 inst.execCommand('mceEndUndoLevel'); 111 112 return true; 113 } 114 115 // Pass to next handler in chain 116 return false; 117 }, 118 119 handleNodeChange : function(editor_id, node, undo_index, undo_levels, visual_aid, any_selection) { 120 var colspan = "1", rowspan = "1", tdElm; 121 122 var inst = tinyMCE.getInstanceById(editor_id); 123 124 // Reset table controls 125 tinyMCE.switchClass(editor_id + '_table', 'mceButtonNormal'); 126 tinyMCE.switchClass(editor_id + '_delete_table', 'mceButtonDisabled'); 127 tinyMCE.switchClass(editor_id + '_row_props', 'mceButtonDisabled'); 128 tinyMCE.switchClass(editor_id + '_cell_props', 'mceButtonDisabled'); 129 tinyMCE.switchClass(editor_id + '_row_before', 'mceButtonDisabled'); 130 tinyMCE.switchClass(editor_id + '_row_after', 'mceButtonDisabled'); 131 tinyMCE.switchClass(editor_id + '_delete_row', 'mceButtonDisabled'); 132 tinyMCE.switchClass(editor_id + '_col_before', 'mceButtonDisabled'); 133 tinyMCE.switchClass(editor_id + '_col_after', 'mceButtonDisabled'); 134 tinyMCE.switchClass(editor_id + '_delete_col', 'mceButtonDisabled'); 135 tinyMCE.switchClass(editor_id + '_split_cells', 'mceButtonDisabled'); 136 tinyMCE.switchClass(editor_id + '_merge_cells', 'mceButtonDisabled'); 137 138 // Within a td element 139 if (tdElm = tinyMCE.getParentElement(node, "td,th")) { 140 tinyMCE.switchClass(editor_id + '_cell_props', 'mceButtonSelected'); 141 tinyMCE.switchClass(editor_id + '_delete_table', 'mceButtonNormal'); 142 tinyMCE.switchClass(editor_id + '_row_before', 'mceButtonNormal'); 143 tinyMCE.switchClass(editor_id + '_row_after', 'mceButtonNormal'); 144 tinyMCE.switchClass(editor_id + '_delete_row', 'mceButtonNormal'); 145 tinyMCE.switchClass(editor_id + '_col_before', 'mceButtonNormal'); 146 tinyMCE.switchClass(editor_id + '_col_after', 'mceButtonNormal'); 147 tinyMCE.switchClass(editor_id + '_delete_col', 'mceButtonNormal'); 148 149 colspan = tinyMCE.getAttrib(tdElm, "colspan"); 150 rowspan = tinyMCE.getAttrib(tdElm, "rowspan"); 151 152 colspan = colspan == "" ? "1" : colspan; 153 rowspan = rowspan == "" ? "1" : rowspan; 154 155 if (colspan != "1" || rowspan != "1") 156 tinyMCE.switchClass(editor_id + '_split_cells', 'mceButtonNormal'); 157 } 158 159 // Within a tr element 160 if (tinyMCE.getParentElement(node, "tr")) 161 tinyMCE.switchClass(editor_id + '_row_props', 'mceButtonSelected'); 162 163 // Within table 164 if (tinyMCE.getParentElement(node, "table")) { 165 tinyMCE.switchClass(editor_id + '_table', 'mceButtonSelected'); 166 tinyMCE.switchClass(editor_id + '_merge_cells', 'mceButtonNormal'); 167 } 168 }, 169 170 // Private plugin internal methods 171 172 _mouseDownHandler : function(e) { 173 var elm = tinyMCE.isMSIE ? event.srcElement : e.target; 174 var focusElm = tinyMCE.selectedInstance.getFocusElement(); 175 176 // If press on special Mozilla create TD/TR thingie 177 if (elm.nodeName == "BODY" && (focusElm.nodeName == "TD" || focusElm.nodeName == "TH" || (focusElm.parentNode && focusElm.parentNode.nodeName == "TD") ||(focusElm.parentNode && focusElm.parentNode.nodeName == "TH") )) { 178 window.setTimeout(function() { 179 var tableElm = tinyMCE.getParentElement(focusElm, "table"); 180 tinyMCE.handleVisualAid(tableElm, true, tinyMCE.settings['visual'], tinyMCE.selectedInstance); 181 }, 10); 182 } 183 }, 184 185 /** 186 * Executes the table commands. 187 */ 188 _doExecCommand : function(editor_id, element, command, user_interface, value) { 189 var inst = tinyMCE.getInstanceById(editor_id); 190 var focusElm = inst.getFocusElement(); 191 var trElm = tinyMCE.getParentElement(focusElm, "tr"); 192 var tdElm = tinyMCE.getParentElement(focusElm, "td,th"); 193 var tableElm = tinyMCE.getParentElement(focusElm, "table"); 194 var doc = inst.contentWindow.document; 195 var tableBorder = tableElm ? tableElm.getAttribute("border") : ""; 196 197 // Get first TD if no TD found 198 if (trElm && tdElm == null) 199 tdElm = trElm.cells[0]; 200 201 // ------- Inner functions --------- 202 function inArray(ar, v) { 203 for (var i=0; i<ar.length; i++) { 204 // Is array 205 if (ar[i].length > 0 && inArray(ar[i], v)) 206 return true; 207 208 // Found value 209 if (ar[i] == v) 210 return true; 211 } 212 213 return false; 214 } 215 216 function makeTD() { 217 var newTD = doc.createElement("td"); 218 newTD.innerHTML = " "; 219 } 220 221 function getColRowSpan(td) { 222 var colspan = tinyMCE.getAttrib(td, "colspan"); 223 var rowspan = tinyMCE.getAttrib(td, "rowspan"); 224 225 colspan = colspan == "" ? 1 : parseInt(colspan); 226 rowspan = rowspan == "" ? 1 : parseInt(rowspan); 227 228 return {colspan : colspan, rowspan : rowspan}; 229 } 230 231 function getCellPos(grid, td) { 232 var x, y; 233 234 for (y=0; y<grid.length; y++) { 235 for (x=0; x<grid[y].length; x++) { 236 if (grid[y][x] == td) 237 return {cellindex : x, rowindex : y}; 238 } 239 } 240 241 return null; 242 } 243 244 function getCell(grid, row, col) { 245 if (grid[row] && grid[row][col]) 246 return grid[row][col]; 247 248 return null; 249 } 250 251 function getTableGrid(table) { 252 var grid = new Array(), rows = table.rows, x, y, td, sd, xstart, x2, y2; 253 254 for (y=0; y<rows.length; y++) { 255 for (x=0; x<rows[y].cells.length; x++) { 256 td = rows[y].cells[x]; 257 sd = getColRowSpan(td); 258 259 // All ready filled 260 for (xstart = x; grid[y] && grid[y][xstart]; xstart++) ; 261 262 // Fill box 263 for (y2=y; y2<y+sd['rowspan']; y2++) { 264 if (!grid[y2]) 265 grid[y2] = new Array(); 266 267 for (x2=xstart; x2<xstart+sd['colspan']; x2++) 268 grid[y2][x2] = td; 269 } 270 } 271 } 272 273 return grid; 274 } 275 276 function trimRow(table, tr, td, new_tr) { 277 var grid = getTableGrid(table), cpos = getCellPos(grid, td); 278 var cells, lastElm; 279 280 // Time to crop away some 281 if (new_tr.cells.length != tr.childNodes.length) { 282 cells = tr.childNodes; 283 lastElm = null; 284 285 for (var x=0; td = getCell(grid, cpos.rowindex, x); x++) { 286 var remove = true; 287 var sd = getColRowSpan(td); 288 289 // Remove due to rowspan 290 if (inArray(cells, td)) { 291 new_tr.childNodes[x]._delete = true; 292 } else if ((lastElm == null || td != lastElm) && sd.colspan > 1) { // Remove due to colspan 293 for (var i=x; i<x+td.colSpan; i++) 294 new_tr.childNodes[i]._delete = true; 295 } 296 297 if ((lastElm == null || td != lastElm) && sd.rowspan > 1) 298 td.rowSpan = sd.rowspan + 1; 299 300 lastElm = td; 301 } 302 303 deleteMarked(tableElm); 304 } 305 } 306 307 function prevElm(node, name) { 308 while ((node = node.previousSibling) != null) { 309 if (node.nodeName == name) 310 return node; 311 } 312 313 return null; 314 } 315 316 function nextElm(node, names) { 317 var namesAr = names.split(','); 318 319 while ((node = node.nextSibling) != null) { 320 for (var i=0; i<namesAr.length; i++) { 321 if (node.nodeName.toLowerCase() == namesAr[i].toLowerCase() ) 322 return node; 323 } 324 } 325 326 return null; 327 } 328 329 function deleteMarked(tbl) { 330 if (tbl.rows == 0) 331 return; 332 333 var tr = tbl.rows[0]; 334 do { 335 var next = nextElm(tr, "TR"); 336 337 // Delete row 338 if (tr._delete) { 339 tr.parentNode.removeChild(tr); 340 continue; 341 } 342 343 // Delete cells 344 var td = tr.cells[0]; 345 if (td.cells > 1) { 346 do { 347 var nexttd = nextElm(td, "TD,TH"); 348 349 if (td._delete) 350 td.parentNode.removeChild(td); 351 } while ((td = nexttd) != null); 352 } 353 } while ((tr = next) != null); 354 } 355 356 function addRows(td_elm, tr_elm, rowspan) { 357 // Add rows 358 td_elm.rowSpan = 1; 359 var trNext = nextElm(tr_elm, "TR"); 360 for (var i=1; i<rowspan && trNext; i++) { 361 var newTD = doc.createElement("td"); 362 newTD.innerHTML = " "; 363 364 if (tinyMCE.isMSIE) 365 trNext.insertBefore(newTD, trNext.cells(td_elm.cellIndex)); 366 else 367 trNext.insertBefore(newTD, trNext.cells[td_elm.cellIndex]); 368 369 trNext = nextElm(trNext, "TR"); 370 } 371 } 372 373 function copyRow(doc, table, tr) { 374 var grid = getTableGrid(table); 375 var newTR = tr.cloneNode(false); 376 var cpos = getCellPos(grid, tr.cells[0]); 377 var lastCell = null; 378 var tableBorder = tinyMCE.getAttrib(table, "border"); 379 var tdElm = null; 380 381 for (var x=0; tdElm = getCell(grid, cpos.rowindex, x); x++) { 382 var newTD = null; 383 384 if (lastCell != tdElm) { 385 for (var i=0; i<tr.cells.length; i++) { 386 if (tdElm == tr.cells[i]) { 387 newTD = tdElm.cloneNode(true); 388 break; 389 } 390 } 391 } 392 393 if (newTD == null) { 394 newTD = doc.createElement("td"); 395 newTD.innerHTML = " "; 396 } 397 398 // Reset col/row span 399 newTD.colSpan = 1; 400 newTD.rowSpan = 1; 401 402 newTR.appendChild(newTD); 403 404 lastCell = tdElm; 405 } 406 407 return newTR; 408 } 409 410 // ---- Commands ----- 411 412 // Handle commands 413 switch (command) { 414 case "mceTableRowProps": 415 if (trElm == null) 416 return true; 417 418 if (user_interface) { 419 // Setup template 420 var template = new Array(); 421 422 template['file'] = '../../plugins/table/row.htm'; 423 template['width'] = 380; 424 template['height'] = 295; 425 426 // Language specific width and height addons 427 template['width'] += tinyMCE.getLang('lang_table_rowprops_delta_width', 0); 428 template['height'] += tinyMCE.getLang('lang_table_rowprops_delta_height', 0); 429 430 // Open window 431 tinyMCE.openWindow(template, {editor_id : inst.editorId, inline : "yes"}); 432 } 433 434 return true; 435 436 case "mceTableCellProps": 437 if (tdElm == null) 438 return true; 439 440 if (user_interface) { 441 // Setup template 442 var template = new Array(); 443 444 template['file'] = '../../plugins/table/cell.htm'; 445 template['width'] = 380; 446 template['height'] = 295; 447 448 // Language specific width and height addons 449 template['width'] += tinyMCE.getLang('lang_table_cellprops_delta_width', 0); 450 template['height'] += tinyMCE.getLang('lang_table_cellprops_delta_height', 0); 451 452 // Open window 453 tinyMCE.openWindow(template, {editor_id : inst.editorId, inline : "yes"}); 454 } 455 456 return true; 457 458 case "mceInsertTable": 459 if (user_interface) { 460 // Setup template 461 var template = new Array(); 462 463 template['file'] = '../../plugins/table/table.htm'; 464 template['width'] = 380; 465 template['height'] = 295; 466 467 // Language specific width and height addons 468 template['width'] += tinyMCE.getLang('lang_table_table_delta_width', 0); 469 template['height'] += tinyMCE.getLang('lang_table_table_delta_height', 0); 470 471 // Open window 472 tinyMCE.openWindow(template, {editor_id : inst.editorId, inline : "yes", action : value}); 473 } 474 475 return true; 476 477 case "mceTableDelete": 478 var table = tinyMCE.getParentElement(inst.getFocusElement(), "table"); 479 if (table) { 480 table.parentNode.removeChild(table); 481 inst.repaint(); 482 } 483 return true; 484 485 case "mceTableSplitCells": 486 case "mceTableMergeCells": 487 case "mceTableInsertRowBefore": 488 case "mceTableInsertRowAfter": 489 case "mceTableDeleteRow": 490 case "mceTableInsertColBefore": 491 case "mceTableInsertColAfter": 492 case "mceTableDeleteCol": 493 case "mceTableCutRow": 494 case "mceTableCopyRow": 495 case "mceTablePasteRowBefore": 496 case "mceTablePasteRowAfter": 497 // No table just return (invalid command) 498 if (!tableElm) 499 return true; 500 501 // Table has a tbody use that reference 502 // Changed logic by ApTest 2005.07.12 (www.aptest.com) 503 // Now lookk at the focused element and take its parentNode. That will be a tbody or a table. 504 if (trElm && tableElm != trElm.parentNode) 505 tableElm = trElm.parentNode; 506 507 if (tableElm && trElm) { 508 switch (command) { 509 case "mceTableCutRow": 510 if (!trElm || !tdElm) 511 return true; 512 513 inst.tableRowClipboard = copyRow(doc, tableElm, trElm); 514 inst.execCommand("mceTableDeleteRow"); 515 break; 516 517 case "mceTableCopyRow": 518 if (!trElm || !tdElm) 519 return true; 520 521 inst.tableRowClipboard = copyRow(doc, tableElm, trElm); 522 break; 523 524 case "mceTablePasteRowBefore": 525 if (!trElm || !tdElm) 526 return true; 527 528 var newTR = inst.tableRowClipboard.cloneNode(true); 529 530 var prevTR = prevElm(trElm, "TR"); 531 if (prevTR != null) 532 trimRow(tableElm, prevTR, prevTR.cells[0], newTR); 533 534 trElm.parentNode.insertBefore(newTR, trElm); 535 break; 536 537 case "mceTablePasteRowAfter": 538 if (!trElm || !tdElm) 539 return true; 540 541 var nextTR = nextElm(trElm, "TR"); 542 var newTR = inst.tableRowClipboard.cloneNode(true); 543 544 trimRow(tableElm, trElm, tdElm, newTR); 545 546 if (nextTR == null) 547 trElm.parentNode.appendChild(newTR); 548 else 549 nextTR.parentNode.insertBefore(newTR, nextTR); 550 551 break; 552 553 case "mceTableInsertRowBefore": 554 if (!trElm || !tdElm) 555 return true; 556 557 var grid = getTableGrid(tableElm); 558 var cpos = getCellPos(grid, tdElm); 559 var newTR = doc.createElement("tr"); 560 var lastTDElm = null; 561 562 cpos.rowindex--; 563 if (cpos.rowindex < 0) 564 cpos.rowindex = 0; 565 566 // Create cells 567 for (var x=0; tdElm = getCell(grid, cpos.rowindex, x); x++) { 568 if (tdElm != lastTDElm) { 569 var sd = getColRowSpan(tdElm); 570 571 if (sd['rowspan'] == 1) { 572 var newTD = doc.createElement("td"); 573 574 newTD.innerHTML = " "; 575 newTD.colSpan = tdElm.colSpan; 576 577 newTR.appendChild(newTD); 578 } else 579 tdElm.rowSpan = sd['rowspan'] + 1; 580 581 lastTDElm = tdElm; 582 } 583 } 584 585 trElm.parentNode.insertBefore(newTR, trElm); 586 587 grid = getTableGrid(tableElm); 588 inst.selection.selectNode(getCell(grid, cpos.rowindex + 1, cpos.cellindex), tinyMCE.isGecko, true); // Only collape on gecko 589 break; 590 591 case "mceTableInsertRowAfter": 592 if (!trElm || !tdElm) 593 return true; 594 595 var grid = getTableGrid(tableElm); 596 var cpos = getCellPos(grid, tdElm); 597 var newTR = doc.createElement("tr"); 598 var lastTDElm = null; 599 600 // Create cells 601 for (var x=0; tdElm = getCell(grid, cpos.rowindex, x); x++) { 602 if (tdElm != lastTDElm) { 603 var sd = getColRowSpan(tdElm); 604 605 if (sd['rowspan'] == 1) { 606 var newTD = doc.createElement("td"); 607 608 newTD.innerHTML = " "; 609 newTD.colSpan = tdElm.colSpan; 610 611 newTR.appendChild(newTD); 612 } else 613 tdElm.rowSpan = sd['rowspan'] + 1; 614 615 lastTDElm = tdElm; 616 } 617 } 618 619 if (newTR.hasChildNodes()) { 620 var nextTR = nextElm(trElm, "TR"); 621 if (nextTR) 622 nextTR.parentNode.insertBefore(newTR, nextTR); 623 else 624 tableElm.appendChild(newTR); 625 } 626 627 grid = getTableGrid(tableElm); 628 inst.selection.selectNode(getCell(grid, cpos.rowindex, cpos.cellindex), tinyMCE.isGecko, true); // Only collape on gecko 629 break; 630 631 case "mceTableDeleteRow": 632 if (!trElm || !tdElm) 633 return true; 634 635 var grid = getTableGrid(tableElm); 636 var cpos = getCellPos(grid, tdElm); 637 638 // Only one row, remove whole table 639 if (grid.length == 1) { 640 tableElm = tinyMCE.getParentElement(tableElm, "table"); // Look for table instead of tbody 641 tableElm.parentNode.removeChild(tableElm); 642 return true; 643 } 644 645 // Move down row spanned cells 646 var cells = trElm.cells; 647 var nextTR = nextElm(trElm, "TR"); 648 for (var x=0; x<cells.length; x++) { 649 if (cells[x].rowSpan > 1) { 650 var newTD = cells[x].cloneNode(true); 651 var sd = getColRowSpan(cells[x]); 652 653 newTD.rowSpan = sd.rowspan - 1; 654 655 var nextTD = nextTR.cells[x]; 656 657 if (nextTD == null) 658 nextTR.appendChild(newTD); 659 else 660 nextTR.insertBefore(newTD, nextTD); 661 } 662 } 663 664 // Delete cells 665 var lastTDElm = null; 666 for (var x=0; tdElm = getCell(grid, cpos.rowindex, x); x++) { 667 if (tdElm != lastTDElm) { 668 var sd = getColRowSpan(tdElm); 669 670 if (sd.rowspan > 1) { 671 tdElm.rowSpan = sd.rowspan - 1; 672 } else { 673 trElm = tdElm.parentNode; 674 675 if (trElm.parentNode) 676 trElm._delete = true; 677 } 678 679 lastTDElm = tdElm; 680 } 681 } 682 683 deleteMarked(tableElm); 684 685 cpos.rowindex--; 686 if (cpos.rowindex < 0) 687 cpos.rowindex = 0; 688 689 // Recalculate grid and select 690 grid = getTableGrid(tableElm); 691 inst.selection.selectNode(getCell(grid, cpos.rowindex, 0), tinyMCE.isGecko, true); // Only collape on gecko 692 break; 693 694 case "mceTableInsertColBefore": 695 if (!trElm || !tdElm) 696 return true; 697 698 var grid = getTableGrid(tableElm); 699 var cpos = getCellPos(grid, tdElm); 700 var lastTDElm = null; 701 702 for (var y=0; tdElm = getCell(grid, y, cpos.cellindex); y++) { 703 if (tdElm != lastTDElm) { 704 var sd = getColRowSpan(tdElm); 705 706 if (sd['colspan'] == 1) { 707 var newTD = doc.createElement(tdElm.nodeName); 708 709 newTD.innerHTML = " "; 710 newTD.rowSpan = tdElm.rowSpan; 711 712 tdElm.parentNode.insertBefore(newTD, tdElm); 713 } else 714 tdElm.colSpan++; 715 716 lastTDElm = tdElm; 717 } 718 } 719 720 grid = getTableGrid(tableElm); 721 inst.selection.selectNode(getCell(grid, cpos.rowindex, cpos.cellindex + 1), tinyMCE.isGecko, true); // Only collape on gecko 722 break; 723 724 case "mceTableInsertColAfter": 725 if (!trElm || !tdElm) 726 return true; 727 728 var grid = getTableGrid(tableElm); 729 var cpos = getCellPos(grid, tdElm); 730 var lastTDElm = null; 731 732 for (var y=0; tdElm = getCell(grid, y, cpos.cellindex); y++) { 733 if (tdElm != lastTDElm) { 734 var sd = getColRowSpan(tdElm); 735 736 if (sd['colspan'] == 1) { 737 var newTD = doc.createElement(tdElm.nodeName); 738 739 newTD.innerHTML = " "; 740 newTD.rowSpan = tdElm.rowSpan; 741 742 var nextTD = nextElm(tdElm, "TD,TH"); 743 if (nextTD == null) 744 tdElm.parentNode.appendChild(newTD); 745 else 746 nextTD.parentNode.insertBefore(newTD, nextTD); 747 } else 748 tdElm.colSpan++; 749 750 lastTDElm = tdElm; 751 } 752 } 753 754 grid = getTableGrid(tableElm); 755 inst.selection.selectNode(getCell(grid, cpos.rowindex, cpos.cellindex), tinyMCE.isGecko, true); // Only collape on gecko 756 break; 757 758 case "mceTableDeleteCol": 759 if (!trElm || !tdElm) 760 return true; 761 762 var grid = getTableGrid(tableElm); 763 var cpos = getCellPos(grid, tdElm); 764 var lastTDElm = null; 765 766 // Only one col, remove whole table 767 if (grid.length > 1 && grid[0].length <= 1) { 768 tableElm = tinyMCE.getParentElement(tableElm, "table"); // Look for table instead of tbody 769 tableElm.parentNode.removeChild(tableElm); 770 return true; 771 } 772 773 // Delete cells 774 for (var y=0; tdElm = getCell(grid, y, cpos.cellindex); y++) { 775 if (tdElm != lastTDElm) { 776 var sd = getColRowSpan(tdElm); 777 778 if (sd['colspan'] > 1) 779 tdElm.colSpan = sd['colspan'] - 1; 780 else { 781 if (tdElm.parentNode) 782 tdElm.parentNode.removeChild(tdElm); 783 } 784 785 lastTDElm = tdElm; 786 } 787 } 788 789 cpos.cellindex--; 790 if (cpos.cellindex < 0) 791 cpos.cellindex = 0; 792 793 // Recalculate grid and select 794 grid = getTableGrid(tableElm); 795 inst.selection.selectNode(getCell(grid, cpos.rowindex, 0), tinyMCE.isGecko, true); // Only collape on gecko 796 break; 797 798 case "mceTableSplitCells": 799 if (!trElm || !tdElm) 800 return true; 801 802 var spandata = getColRowSpan(tdElm); 803 804 var colspan = spandata["colspan"]; 805 var rowspan = spandata["rowspan"]; 806 807 // Needs splitting 808 if (colspan > 1 || rowspan > 1) { 809 // Generate cols 810 tdElm.colSpan = 1; 811 for (var i=1; i<colspan; i++) { 812 var newTD = doc.createElement("td"); 813 814 newTD.innerHTML = " "; 815 816 trElm.insertBefore(newTD, nextElm(tdElm, "TD,TH")); 817 818 if (rowspan > 1) 819 addRows(newTD, trElm, rowspan); 820 } 821 822 addRows(tdElm, trElm, rowspan); 823 } 824 825 // Apply visual aids 826 tableElm = tinyMCE.getParentElement(inst.getFocusElement(), "table"); 827 break; 828 829 case "mceTableMergeCells": 830 var rows = new Array(); 831 var sel = inst.getSel(); 832 var grid = getTableGrid(tableElm); 833 834 if (tinyMCE.isMSIE || sel.rangeCount == 1) { 835 if (user_interface) { 836 // Setup template 837 var template = new Array(); 838 var sp = getColRowSpan(tdElm); 839 840 template['file'] = '../../plugins/table/merge_cells.htm'; 841 template['width'] = 250; 842 template['height'] = 105 + (tinyMCE.isNS7 ? 25 : 0); 843 844 // Language specific width and height addons 845 template['width'] += tinyMCE.getLang('lang_table_merge_cells_delta_width', 0); 846 template['height'] += tinyMCE.getLang('lang_table_merge_cells_delta_height', 0); 847 848 // Open window 849 tinyMCE.openWindow(template, {editor_id : inst.editorId, inline : "yes", action : "update", numcols : sp.colspan, numrows : sp.rowspan}); 850 851 return true; 852 } else { 853 var numRows = parseInt(value['numrows']); 854 var numCols = parseInt(value['numcols']); 855 var cpos = getCellPos(grid, tdElm); 856 857 if (("" + numRows) == "NaN") 858 numRows = 1; 859 860 if (("" + numCols) == "NaN") 861 numCols = 1; 862 863 // Get rows and cells 864 var tRows = tableElm.rows; 865 for (var y=cpos.rowindex; y<grid.length; y++) { 866 var rowCells = new Array(); 867 868 for (var x=cpos.cellindex; x<grid[y].length; x++) { 869 var td = getCell(grid, y, x); 870 871 if (td && !inArray(rows, td) && !inArray(rowCells, td)) { 872 var cp = getCellPos(grid, td); 873 874 // Within range 875 if (cp.cellindex < cpos.cellindex+numCols && cp.rowindex < cpos.rowindex+numRows) 876 rowCells[rowCells.length] = td; 877 } 878 } 879 880 if (rowCells.length > 0) 881 rows[rows.length] = rowCells; 882 } 883 884 //return true; 885 } 886 } else { 887 var cells = new Array(); 888 var sel = inst.getSel(); 889 var lastTR = null; 890 var curRow = null; 891 var x1 = -1, y1 = -1, x2, y2; 892 893 // Only one cell selected, whats the point? 894 if (sel.rangeCount < 2) 895 return true; 896 897 // Get all selected cells 898 for (var i=0; i<sel.rangeCount; i++) { 899 var rng = sel.getRangeAt(i); 900 var tdElm = rng.startContainer.childNodes[rng.startOffset]; 901 902 if (!tdElm) 903 break; 904 905 if (tdElm.nodeName == "TD") 906 cells[cells.length] = tdElm; 907 } 908 909 // Get rows and cells 910 var tRows = tableElm.rows; 911 for (var y=0; y<tRows.length; y++) { 912 var rowCells = new Array(); 913 914 for (var x=0; x<tRows[y].cells.length; x++) { 915 var td = tRows[y].cells[x]; 916 917 for (var i=0; i<cells.length; i++) { 918 if (td == cells[i]) { 919 rowCells[rowCells.length] = td; 920 } 921 } 922 } 923 924 if (rowCells.length > 0) 925 rows[rows.length] = rowCells; 926 } 927 928 // Find selected cells in grid and box 929 var curRow = new Array(); 930 var lastTR = null; 931 for (var y=0; y<grid.length; y++) { 932 for (var x=0; x<grid[y].length; x++) { 933 grid[y][x]._selected = false; 934 935 for (var i=0; i<cells.length; i++) { 936 if (grid[y][x] == cells[i]) { 937 // Get start pos 938 if (x1 == -1) { 939 x1 = x; 940 y1 = y; 941 } 942 943 // Get end pos 944 x2 = x; 945 y2 = y; 946 947 grid[y][x]._selected = true; 948 } 949 } 950 } 951 } 952 953 // Is there gaps, if so deny 954 for (var y=y1; y<=y2; y++) { 955 for (var x=x1; x<=x2; x++) { 956 if (!grid[y][x]._selected) { 957 alert("Invalid selection for merge."); 958 return true; 959 } 960 } 961 } 962 } 963 964 // Validate selection and get total rowspan and colspan 965 var rowSpan = 1, colSpan = 1; 966 967 // Validate horizontal and get total colspan 968 var lastRowSpan = -1; 969 for (var y=0; y<rows.length; y++) { 970 var rowColSpan = 0; 971 972 for (var x=0; x<rows[y].length; x++) { 973 var sd = getColRowSpan(rows[y][x]); 974 975 rowColSpan += sd['colspan']; 976 977 if (lastRowSpan != -1 && sd['rowspan'] != lastRowSpan) { 978 alert("Invalid selection for merge."); 979 return true; 980 } 981 982 lastRowSpan = sd['rowspan']; 983 } 984 985 if (rowColSpan > colSpan) 986 colSpan = rowColSpan; 987 988 lastRowSpan = -1; 989 } 990 991 // Validate vertical and get total rowspan 992 var lastColSpan = -1; 993 for (var x=0; x<rows[0].length; x++) { 994 var colRowSpan = 0; 995 996 for (var y=0; y<rows.length; y++) { 997 var sd = getColRowSpan(rows[y][x]); 998 999 colRowSpan += sd['rowspan']; 1000 1001 if (lastColSpan != -1 && sd['colspan'] != lastColSpan) { 1002 alert("Invalid selection for merge."); 1003 return true; 1004 } 1005 1006 lastColSpan = sd['colspan']; 1007 } 1008 1009 if (colRowSpan > rowSpan) 1010 rowSpan = colRowSpan; 1011 1012 lastColSpan = -1; 1013 } 1014 1015 // Setup td 1016 tdElm = rows[0][0]; 1017 tdElm.rowSpan = rowSpan; 1018 tdElm.colSpan = colSpan; 1019 1020 // Merge cells 1021 for (var y=0; y<rows.length; y++) { 1022 for (var x=0; x<rows[y].length; x++) { 1023 var html = rows[y][x].innerHTML; 1024 var chk = tinyMCE.regexpReplace(html, "[ \t\r\n]", ""); 1025 1026 if (chk != "<br/>" && chk != "<br>" && chk != " " && (x+y > 0)) 1027 tdElm.innerHTML += html; 1028 1029 // Not current cell 1030 if (rows[y][x] != tdElm && !rows[y][x]._deleted) { 1031 var cpos = getCellPos(grid, rows[y][x]); 1032 var tr = rows[y][x].parentNode; 1033 1034 tr.removeChild(rows[y][x]); 1035 rows[y][x]._deleted = true; 1036 1037 // Empty TR, remove it 1038 if (!tr.hasChildNodes()) { 1039 tr.parentNode.removeChild(tr); 1040 1041 var lastCell = null; 1042 for (var x=0; cellElm = getCell(grid, cpos.rowindex, x); x++) { 1043 if (cellElm != lastCell && cellElm.rowSpan > 1) 1044 cellElm.rowSpan--; 1045 1046 lastCell = cellElm; 1047 } 1048 1049 if (tdElm.rowSpan > 1) 1050 tdElm.rowSpan--; 1051 } 1052 } 1053 } 1054 } 1055 1056 break; 1057 } 1058 1059 tableElm = tinyMCE.getParentElement(inst.getFocusElement(), "table"); 1060 tinyMCE.handleVisualAid(tableElm, true, tinyMCE.settings['visual'], tinyMCE.selectedInstance); 1061 tinyMCE.triggerNodeChange(); 1062 inst.repaint(); 1063 } 1064 1065 return true; 1066 } 1067 1068 // Pass to next handler in chain 1069 return false; 1070 } 1071 }; 1072 1073 tinyMCE.addPlugin("table", TinyMCE_TablePlugin);
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Wed Nov 21 14:43:32 2007 | par Balluche grâce à PHPXref 0.7 |
![]() |