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