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