table.cmds.js 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936
  1. /**
  2. * Created with JetBrains PhpStorm.
  3. * User: taoqili
  4. * Date: 13-2-20
  5. * Time: 下午6:25
  6. * To change this template use File | Settings | File Templates.
  7. */
  8. ;
  9. (function () {
  10. var UT = UE.UETable,
  11. getTableItemsByRange = function (editor) {
  12. return UT.getTableItemsByRange(editor);
  13. },
  14. getUETableBySelected = function (editor) {
  15. return UT.getUETableBySelected(editor)
  16. },
  17. getDefaultValue = function (editor, table) {
  18. return UT.getDefaultValue(editor, table);
  19. },
  20. getUETable = function (tdOrTable) {
  21. return UT.getUETable(tdOrTable);
  22. };
  23. UE.commands['inserttable'] = {
  24. queryCommandState: function () {
  25. return getTableItemsByRange(this).table ? -1 : 0;
  26. },
  27. execCommand: function (cmd, opt) {
  28. function createTable(opt, tdWidth) {
  29. var html = [],
  30. rowsNum = opt.numRows,
  31. colsNum = opt.numCols;
  32. for (var r = 0; r < rowsNum; r++) {
  33. html.push('<tr' + (r == 0 ? ' class="firstRow"':'') + '>');
  34. for (var c = 0; c < colsNum; c++) {
  35. html.push('<td width="' + tdWidth + '" vAlign="' + opt.tdvalign + '" >' + (browser.ie && browser.version < 11 ? domUtils.fillChar : '<br/>') + '</td>')
  36. }
  37. html.push('</tr>')
  38. }
  39. //禁止指定table-width
  40. return '<table><tbody>' + html.join('') + '</tbody></table>'
  41. }
  42. if (!opt) {
  43. opt = utils.extend({}, {
  44. numCols: this.options.defaultCols,
  45. numRows: this.options.defaultRows,
  46. tdvalign: this.options.tdvalign
  47. })
  48. }
  49. var me = this;
  50. var range = this.selection.getRange(),
  51. start = range.startContainer,
  52. firstParentBlock = domUtils.findParent(start, function (node) {
  53. return domUtils.isBlockElm(node);
  54. }, true) || me.body;
  55. var defaultValue = getDefaultValue(me),
  56. tableWidth = firstParentBlock.offsetWidth,
  57. tdWidth = Math.floor(tableWidth / opt.numCols - defaultValue.tdPadding * 2 - defaultValue.tdBorder);
  58. //todo其他属性
  59. !opt.tdvalign && (opt.tdvalign = me.options.tdvalign);
  60. me.execCommand("inserthtml", createTable(opt, tdWidth));
  61. }
  62. };
  63. UE.commands['insertparagraphbeforetable'] = {
  64. queryCommandState: function () {
  65. return getTableItemsByRange(this).cell ? 0 : -1;
  66. },
  67. execCommand: function () {
  68. var table = getTableItemsByRange(this).table;
  69. if (table) {
  70. var p = this.document.createElement("p");
  71. p.innerHTML = browser.ie ? '&nbsp;' : '<br />';
  72. table.parentNode.insertBefore(p, table);
  73. this.selection.getRange().setStart(p, 0).setCursor();
  74. }
  75. }
  76. };
  77. UE.commands['deletetable'] = {
  78. queryCommandState: function () {
  79. var rng = this.selection.getRange();
  80. return domUtils.findParentByTagName(rng.startContainer, 'table', true) ? 0 : -1;
  81. },
  82. execCommand: function (cmd, table) {
  83. var rng = this.selection.getRange();
  84. table = table || domUtils.findParentByTagName(rng.startContainer, 'table', true);
  85. if (table) {
  86. var next = table.nextSibling;
  87. if (!next) {
  88. next = domUtils.createElement(this.document, 'p', {
  89. 'innerHTML': browser.ie ? domUtils.fillChar : '<br/>'
  90. });
  91. table.parentNode.insertBefore(next, table);
  92. }
  93. domUtils.remove(table);
  94. rng = this.selection.getRange();
  95. if (next.nodeType == 3) {
  96. rng.setStartBefore(next)
  97. } else {
  98. rng.setStart(next, 0)
  99. }
  100. rng.setCursor(false, true)
  101. this.fireEvent("tablehasdeleted")
  102. }
  103. }
  104. };
  105. UE.commands['cellalign'] = {
  106. queryCommandState: function () {
  107. return getSelectedArr(this).length ? 0 : -1
  108. },
  109. execCommand: function (cmd, align) {
  110. var selectedTds = getSelectedArr(this);
  111. if (selectedTds.length) {
  112. for (var i = 0, ci; ci = selectedTds[i++];) {
  113. ci.setAttribute('align', align);
  114. }
  115. }
  116. }
  117. };
  118. UE.commands['cellvalign'] = {
  119. queryCommandState: function () {
  120. return getSelectedArr(this).length ? 0 : -1;
  121. },
  122. execCommand: function (cmd, valign) {
  123. var selectedTds = getSelectedArr(this);
  124. if (selectedTds.length) {
  125. for (var i = 0, ci; ci = selectedTds[i++];) {
  126. ci.setAttribute('vAlign', valign);
  127. }
  128. }
  129. }
  130. };
  131. UE.commands['insertcaption'] = {
  132. queryCommandState: function () {
  133. var table = getTableItemsByRange(this).table;
  134. if (table) {
  135. return table.getElementsByTagName('caption').length == 0 ? 1 : -1;
  136. }
  137. return -1;
  138. },
  139. execCommand: function () {
  140. var table = getTableItemsByRange(this).table;
  141. if (table) {
  142. var caption = this.document.createElement('caption');
  143. caption.innerHTML = browser.ie ? domUtils.fillChar : '<br/>';
  144. table.insertBefore(caption, table.firstChild);
  145. var range = this.selection.getRange();
  146. range.setStart(caption, 0).setCursor();
  147. }
  148. }
  149. };
  150. UE.commands['deletecaption'] = {
  151. queryCommandState: function () {
  152. var rng = this.selection.getRange(),
  153. table = domUtils.findParentByTagName(rng.startContainer, 'table');
  154. if (table) {
  155. return table.getElementsByTagName('caption').length == 0 ? -1 : 1;
  156. }
  157. return -1;
  158. },
  159. execCommand: function () {
  160. var rng = this.selection.getRange(),
  161. table = domUtils.findParentByTagName(rng.startContainer, 'table');
  162. if (table) {
  163. domUtils.remove(table.getElementsByTagName('caption')[0]);
  164. var range = this.selection.getRange();
  165. range.setStart(table.rows[0].cells[0], 0).setCursor();
  166. }
  167. }
  168. };
  169. UE.commands['inserttitle'] = {
  170. queryCommandState: function () {
  171. var table = getTableItemsByRange(this).table;
  172. if (table) {
  173. var firstRow = table.rows[0];
  174. return firstRow.cells[firstRow.cells.length-1].tagName.toLowerCase() != 'th' ? 0 : -1
  175. }
  176. return -1;
  177. },
  178. execCommand: function () {
  179. var table = getTableItemsByRange(this).table;
  180. if (table) {
  181. getUETable(table).insertRow(0, 'th');
  182. }
  183. var th = table.getElementsByTagName('th')[0];
  184. this.selection.getRange().setStart(th, 0).setCursor(false, true);
  185. }
  186. };
  187. UE.commands['deletetitle'] = {
  188. queryCommandState: function () {
  189. var table = getTableItemsByRange(this).table;
  190. if (table) {
  191. var firstRow = table.rows[0];
  192. return firstRow.cells[firstRow.cells.length-1].tagName.toLowerCase() == 'th' ? 0 : -1
  193. }
  194. return -1;
  195. },
  196. execCommand: function () {
  197. var table = getTableItemsByRange(this).table;
  198. if (table) {
  199. domUtils.remove(table.rows[0])
  200. }
  201. var td = table.getElementsByTagName('td')[0];
  202. this.selection.getRange().setStart(td, 0).setCursor(false, true);
  203. }
  204. };
  205. UE.commands['inserttitlecol'] = {
  206. queryCommandState: function () {
  207. var table = getTableItemsByRange(this).table;
  208. if (table) {
  209. var lastRow = table.rows[table.rows.length-1];
  210. return lastRow.getElementsByTagName('th').length ? -1 : 0;
  211. }
  212. return -1;
  213. },
  214. execCommand: function (cmd) {
  215. var table = getTableItemsByRange(this).table;
  216. if (table) {
  217. getUETable(table).insertCol(0, 'th');
  218. }
  219. resetTdWidth(table, this);
  220. var th = table.getElementsByTagName('th')[0];
  221. this.selection.getRange().setStart(th, 0).setCursor(false, true);
  222. }
  223. };
  224. UE.commands['deletetitlecol'] = {
  225. queryCommandState: function () {
  226. var table = getTableItemsByRange(this).table;
  227. if (table) {
  228. var lastRow = table.rows[table.rows.length-1];
  229. return lastRow.getElementsByTagName('th').length ? 0 : -1;
  230. }
  231. return -1;
  232. },
  233. execCommand: function () {
  234. var table = getTableItemsByRange(this).table;
  235. if (table) {
  236. for(var i = 0; i< table.rows.length; i++ ){
  237. domUtils.remove(table.rows[i].children[0])
  238. }
  239. }
  240. resetTdWidth(table, this);
  241. var td = table.getElementsByTagName('td')[0];
  242. this.selection.getRange().setStart(td, 0).setCursor(false, true);
  243. }
  244. };
  245. UE.commands["mergeright"] = {
  246. queryCommandState: function (cmd) {
  247. var tableItems = getTableItemsByRange(this),
  248. table = tableItems.table,
  249. cell = tableItems.cell;
  250. if (!table || !cell) return -1;
  251. var ut = getUETable(table);
  252. if (ut.selectedTds.length) return -1;
  253. var cellInfo = ut.getCellInfo(cell),
  254. rightColIndex = cellInfo.colIndex + cellInfo.colSpan;
  255. if (rightColIndex >= ut.colsNum) return -1; // 如果处于最右边则不能向右合并
  256. var rightCellInfo = ut.indexTable[cellInfo.rowIndex][rightColIndex],
  257. rightCell = table.rows[rightCellInfo.rowIndex].cells[rightCellInfo.cellIndex];
  258. if (!rightCell || cell.tagName != rightCell.tagName) return -1; // TH和TD不能相互合并
  259. // 当且仅当两个Cell的开始列号和结束列号一致时能进行合并
  260. return (rightCellInfo.rowIndex == cellInfo.rowIndex && rightCellInfo.rowSpan == cellInfo.rowSpan) ? 0 : -1;
  261. },
  262. execCommand: function (cmd) {
  263. var rng = this.selection.getRange(),
  264. bk = rng.createBookmark(true);
  265. var cell = getTableItemsByRange(this).cell,
  266. ut = getUETable(cell);
  267. ut.mergeRight(cell);
  268. rng.moveToBookmark(bk).select();
  269. }
  270. };
  271. UE.commands["mergedown"] = {
  272. queryCommandState: function (cmd) {
  273. var tableItems = getTableItemsByRange(this),
  274. table = tableItems.table,
  275. cell = tableItems.cell;
  276. if (!table || !cell) return -1;
  277. var ut = getUETable(table);
  278. if (ut.selectedTds.length)return -1;
  279. var cellInfo = ut.getCellInfo(cell),
  280. downRowIndex = cellInfo.rowIndex + cellInfo.rowSpan;
  281. if (downRowIndex >= ut.rowsNum) return -1; // 如果处于最下边则不能向下合并
  282. var downCellInfo = ut.indexTable[downRowIndex][cellInfo.colIndex],
  283. downCell = table.rows[downCellInfo.rowIndex].cells[downCellInfo.cellIndex];
  284. if (!downCell || cell.tagName != downCell.tagName) return -1; // TH和TD不能相互合并
  285. // 当且仅当两个Cell的开始列号和结束列号一致时能进行合并
  286. return (downCellInfo.colIndex == cellInfo.colIndex && downCellInfo.colSpan == cellInfo.colSpan) ? 0 : -1;
  287. },
  288. execCommand: function () {
  289. var rng = this.selection.getRange(),
  290. bk = rng.createBookmark(true);
  291. var cell = getTableItemsByRange(this).cell,
  292. ut = getUETable(cell);
  293. ut.mergeDown(cell);
  294. rng.moveToBookmark(bk).select();
  295. }
  296. };
  297. UE.commands["mergecells"] = {
  298. queryCommandState: function () {
  299. return getUETableBySelected(this) ? 0 : -1;
  300. },
  301. execCommand: function () {
  302. var ut = getUETableBySelected(this);
  303. if (ut && ut.selectedTds.length) {
  304. var cell = ut.selectedTds[0];
  305. ut.mergeRange();
  306. var rng = this.selection.getRange();
  307. if (domUtils.isEmptyBlock(cell)) {
  308. rng.setStart(cell, 0).collapse(true)
  309. } else {
  310. rng.selectNodeContents(cell)
  311. }
  312. rng.select();
  313. }
  314. }
  315. };
  316. UE.commands["insertrow"] = {
  317. queryCommandState: function () {
  318. var tableItems = getTableItemsByRange(this),
  319. cell = tableItems.cell;
  320. return cell && (cell.tagName == "TD" || (cell.tagName == 'TH' && tableItems.tr !== tableItems.table.rows[0])) &&
  321. getUETable(tableItems.table).rowsNum < this.options.maxRowNum ? 0 : -1;
  322. },
  323. execCommand: function () {
  324. var rng = this.selection.getRange(),
  325. bk = rng.createBookmark(true);
  326. var tableItems = getTableItemsByRange(this),
  327. cell = tableItems.cell,
  328. table = tableItems.table,
  329. ut = getUETable(table),
  330. cellInfo = ut.getCellInfo(cell);
  331. //ut.insertRow(!ut.selectedTds.length ? cellInfo.rowIndex:ut.cellsRange.beginRowIndex,'');
  332. if (!ut.selectedTds.length) {
  333. ut.insertRow(cellInfo.rowIndex, cell);
  334. } else {
  335. var range = ut.cellsRange;
  336. for (var i = 0, len = range.endRowIndex - range.beginRowIndex + 1; i < len; i++) {
  337. ut.insertRow(range.beginRowIndex, cell);
  338. }
  339. }
  340. rng.moveToBookmark(bk).select();
  341. if (table.getAttribute("interlaced") === "enabled")this.fireEvent("interlacetable", table);
  342. }
  343. };
  344. //后插入行
  345. UE.commands["insertrownext"] = {
  346. queryCommandState: function () {
  347. var tableItems = getTableItemsByRange(this),
  348. cell = tableItems.cell;
  349. return cell && (cell.tagName == "TD") && getUETable(tableItems.table).rowsNum < this.options.maxRowNum ? 0 : -1;
  350. },
  351. execCommand: function () {
  352. var rng = this.selection.getRange(),
  353. bk = rng.createBookmark(true);
  354. var tableItems = getTableItemsByRange(this),
  355. cell = tableItems.cell,
  356. table = tableItems.table,
  357. ut = getUETable(table),
  358. cellInfo = ut.getCellInfo(cell);
  359. //ut.insertRow(!ut.selectedTds.length? cellInfo.rowIndex + cellInfo.rowSpan : ut.cellsRange.endRowIndex + 1,'');
  360. if (!ut.selectedTds.length) {
  361. ut.insertRow(cellInfo.rowIndex + cellInfo.rowSpan, cell);
  362. } else {
  363. var range = ut.cellsRange;
  364. for (var i = 0, len = range.endRowIndex - range.beginRowIndex + 1; i < len; i++) {
  365. ut.insertRow(range.endRowIndex + 1, cell);
  366. }
  367. }
  368. rng.moveToBookmark(bk).select();
  369. if (table.getAttribute("interlaced") === "enabled")this.fireEvent("interlacetable", table);
  370. }
  371. };
  372. UE.commands["deleterow"] = {
  373. queryCommandState: function () {
  374. var tableItems = getTableItemsByRange(this);
  375. return tableItems.cell ? 0 : -1;
  376. },
  377. execCommand: function () {
  378. var cell = getTableItemsByRange(this).cell,
  379. ut = getUETable(cell),
  380. cellsRange = ut.cellsRange,
  381. cellInfo = ut.getCellInfo(cell),
  382. preCell = ut.getVSideCell(cell),
  383. nextCell = ut.getVSideCell(cell, true),
  384. rng = this.selection.getRange();
  385. if (utils.isEmptyObject(cellsRange)) {
  386. ut.deleteRow(cellInfo.rowIndex);
  387. } else {
  388. for (var i = cellsRange.beginRowIndex; i < cellsRange.endRowIndex + 1; i++) {
  389. ut.deleteRow(cellsRange.beginRowIndex);
  390. }
  391. }
  392. var table = ut.table;
  393. if (!table.getElementsByTagName('td').length) {
  394. var nextSibling = table.nextSibling;
  395. domUtils.remove(table);
  396. if (nextSibling) {
  397. rng.setStart(nextSibling, 0).setCursor(false, true);
  398. }
  399. } else {
  400. if (cellInfo.rowSpan == 1 || cellInfo.rowSpan == cellsRange.endRowIndex - cellsRange.beginRowIndex + 1) {
  401. if (nextCell || preCell) rng.selectNodeContents(nextCell || preCell).setCursor(false, true);
  402. } else {
  403. var newCell = ut.getCell(cellInfo.rowIndex, ut.indexTable[cellInfo.rowIndex][cellInfo.colIndex].cellIndex);
  404. if (newCell) rng.selectNodeContents(newCell).setCursor(false, true);
  405. }
  406. }
  407. if (table.getAttribute("interlaced") === "enabled")this.fireEvent("interlacetable", table);
  408. }
  409. };
  410. UE.commands["insertcol"] = {
  411. queryCommandState: function (cmd) {
  412. var tableItems = getTableItemsByRange(this),
  413. cell = tableItems.cell;
  414. return cell && (cell.tagName == "TD" || (cell.tagName == 'TH' && cell !== tableItems.tr.cells[0])) &&
  415. getUETable(tableItems.table).colsNum < this.options.maxColNum ? 0 : -1;
  416. },
  417. execCommand: function (cmd) {
  418. var rng = this.selection.getRange(),
  419. bk = rng.createBookmark(true);
  420. if (this.queryCommandState(cmd) == -1)return;
  421. var cell = getTableItemsByRange(this).cell,
  422. ut = getUETable(cell),
  423. cellInfo = ut.getCellInfo(cell);
  424. //ut.insertCol(!ut.selectedTds.length ? cellInfo.colIndex:ut.cellsRange.beginColIndex);
  425. if (!ut.selectedTds.length) {
  426. ut.insertCol(cellInfo.colIndex, cell);
  427. } else {
  428. var range = ut.cellsRange;
  429. for (var i = 0, len = range.endColIndex - range.beginColIndex + 1; i < len; i++) {
  430. ut.insertCol(range.beginColIndex, cell);
  431. }
  432. }
  433. rng.moveToBookmark(bk).select(true);
  434. }
  435. };
  436. UE.commands["insertcolnext"] = {
  437. queryCommandState: function () {
  438. var tableItems = getTableItemsByRange(this),
  439. cell = tableItems.cell;
  440. return cell && getUETable(tableItems.table).colsNum < this.options.maxColNum ? 0 : -1;
  441. },
  442. execCommand: function () {
  443. var rng = this.selection.getRange(),
  444. bk = rng.createBookmark(true);
  445. var cell = getTableItemsByRange(this).cell,
  446. ut = getUETable(cell),
  447. cellInfo = ut.getCellInfo(cell);
  448. //ut.insertCol(!ut.selectedTds.length ? cellInfo.colIndex + cellInfo.colSpan:ut.cellsRange.endColIndex +1);
  449. if (!ut.selectedTds.length) {
  450. ut.insertCol(cellInfo.colIndex + cellInfo.colSpan, cell);
  451. } else {
  452. var range = ut.cellsRange;
  453. for (var i = 0, len = range.endColIndex - range.beginColIndex + 1; i < len; i++) {
  454. ut.insertCol(range.endColIndex + 1, cell);
  455. }
  456. }
  457. rng.moveToBookmark(bk).select();
  458. }
  459. };
  460. UE.commands["deletecol"] = {
  461. queryCommandState: function () {
  462. var tableItems = getTableItemsByRange(this);
  463. return tableItems.cell ? 0 : -1;
  464. },
  465. execCommand: function () {
  466. var cell = getTableItemsByRange(this).cell,
  467. ut = getUETable(cell),
  468. range = ut.cellsRange,
  469. cellInfo = ut.getCellInfo(cell),
  470. preCell = ut.getHSideCell(cell),
  471. nextCell = ut.getHSideCell(cell, true);
  472. if (utils.isEmptyObject(range)) {
  473. ut.deleteCol(cellInfo.colIndex);
  474. } else {
  475. for (var i = range.beginColIndex; i < range.endColIndex + 1; i++) {
  476. ut.deleteCol(range.beginColIndex);
  477. }
  478. }
  479. var table = ut.table,
  480. rng = this.selection.getRange();
  481. if (!table.getElementsByTagName('td').length) {
  482. var nextSibling = table.nextSibling;
  483. domUtils.remove(table);
  484. if (nextSibling) {
  485. rng.setStart(nextSibling, 0).setCursor(false, true);
  486. }
  487. } else {
  488. if (domUtils.inDoc(cell, this.document)) {
  489. rng.setStart(cell, 0).setCursor(false, true);
  490. } else {
  491. if (nextCell && domUtils.inDoc(nextCell, this.document)) {
  492. rng.selectNodeContents(nextCell).setCursor(false, true);
  493. } else {
  494. if (preCell && domUtils.inDoc(preCell, this.document)) {
  495. rng.selectNodeContents(preCell).setCursor(true, true);
  496. }
  497. }
  498. }
  499. }
  500. }
  501. };
  502. UE.commands["splittocells"] = {
  503. queryCommandState: function () {
  504. var tableItems = getTableItemsByRange(this),
  505. cell = tableItems.cell;
  506. if (!cell) return -1;
  507. var ut = getUETable(tableItems.table);
  508. if (ut.selectedTds.length > 0) return -1;
  509. return cell && (cell.colSpan > 1 || cell.rowSpan > 1) ? 0 : -1;
  510. },
  511. execCommand: function () {
  512. var rng = this.selection.getRange(),
  513. bk = rng.createBookmark(true);
  514. var cell = getTableItemsByRange(this).cell,
  515. ut = getUETable(cell);
  516. ut.splitToCells(cell);
  517. rng.moveToBookmark(bk).select();
  518. }
  519. };
  520. UE.commands["splittorows"] = {
  521. queryCommandState: function () {
  522. var tableItems = getTableItemsByRange(this),
  523. cell = tableItems.cell;
  524. if (!cell) return -1;
  525. var ut = getUETable(tableItems.table);
  526. if (ut.selectedTds.length > 0) return -1;
  527. return cell && cell.rowSpan > 1 ? 0 : -1;
  528. },
  529. execCommand: function () {
  530. var rng = this.selection.getRange(),
  531. bk = rng.createBookmark(true);
  532. var cell = getTableItemsByRange(this).cell,
  533. ut = getUETable(cell);
  534. ut.splitToRows(cell);
  535. rng.moveToBookmark(bk).select();
  536. }
  537. };
  538. UE.commands["splittocols"] = {
  539. queryCommandState: function () {
  540. var tableItems = getTableItemsByRange(this),
  541. cell = tableItems.cell;
  542. if (!cell) return -1;
  543. var ut = getUETable(tableItems.table);
  544. if (ut.selectedTds.length > 0) return -1;
  545. return cell && cell.colSpan > 1 ? 0 : -1;
  546. },
  547. execCommand: function () {
  548. var rng = this.selection.getRange(),
  549. bk = rng.createBookmark(true);
  550. var cell = getTableItemsByRange(this).cell,
  551. ut = getUETable(cell);
  552. ut.splitToCols(cell);
  553. rng.moveToBookmark(bk).select();
  554. }
  555. };
  556. UE.commands["adaptbytext"] =
  557. UE.commands["adaptbywindow"] = {
  558. queryCommandState: function () {
  559. return getTableItemsByRange(this).table ? 0 : -1
  560. },
  561. execCommand: function (cmd) {
  562. var tableItems = getTableItemsByRange(this),
  563. table = tableItems.table;
  564. if (table) {
  565. if (cmd == 'adaptbywindow') {
  566. resetTdWidth(table, this);
  567. } else {
  568. var cells = domUtils.getElementsByTagName(table, "td th");
  569. utils.each(cells, function (cell) {
  570. cell.removeAttribute("width");
  571. });
  572. table.removeAttribute("width");
  573. }
  574. }
  575. }
  576. };
  577. //平均分配各列
  578. UE.commands['averagedistributecol'] = {
  579. queryCommandState: function () {
  580. var ut = getUETableBySelected(this);
  581. if (!ut) return -1;
  582. return ut.isFullRow() || ut.isFullCol() ? 0 : -1;
  583. },
  584. execCommand: function (cmd) {
  585. var me = this,
  586. ut = getUETableBySelected(me);
  587. function getAverageWidth() {
  588. var tb = ut.table,
  589. averageWidth, sumWidth = 0, colsNum = 0,
  590. tbAttr = getDefaultValue(me, tb);
  591. if (ut.isFullRow()) {
  592. sumWidth = tb.offsetWidth;
  593. colsNum = ut.colsNum;
  594. } else {
  595. var begin = ut.cellsRange.beginColIndex,
  596. end = ut.cellsRange.endColIndex,
  597. node;
  598. for (var i = begin; i <= end;) {
  599. node = ut.selectedTds[i];
  600. sumWidth += node.offsetWidth;
  601. i += node.colSpan;
  602. colsNum += 1;
  603. }
  604. }
  605. averageWidth = Math.ceil(sumWidth / colsNum) - tbAttr.tdBorder * 2 - tbAttr.tdPadding * 2;
  606. return averageWidth;
  607. }
  608. function setAverageWidth(averageWidth) {
  609. utils.each(domUtils.getElementsByTagName(ut.table, "th"), function (node) {
  610. node.setAttribute("width", "");
  611. });
  612. var cells = ut.isFullRow() ? domUtils.getElementsByTagName(ut.table, "td") : ut.selectedTds;
  613. utils.each(cells, function (node) {
  614. if (node.colSpan == 1) {
  615. node.setAttribute("width", averageWidth);
  616. }
  617. });
  618. }
  619. if (ut && ut.selectedTds.length) {
  620. setAverageWidth(getAverageWidth());
  621. }
  622. }
  623. };
  624. //平均分配各行
  625. UE.commands['averagedistributerow'] = {
  626. queryCommandState: function () {
  627. var ut = getUETableBySelected(this);
  628. if (!ut) return -1;
  629. if (ut.selectedTds && /th/ig.test(ut.selectedTds[0].tagName)) return -1;
  630. return ut.isFullRow() || ut.isFullCol() ? 0 : -1;
  631. },
  632. execCommand: function (cmd) {
  633. var me = this,
  634. ut = getUETableBySelected(me);
  635. function getAverageHeight() {
  636. var averageHeight, rowNum, sumHeight = 0,
  637. tb = ut.table,
  638. tbAttr = getDefaultValue(me, tb),
  639. tdpadding = parseInt(domUtils.getComputedStyle(tb.getElementsByTagName('td')[0], "padding-top"));
  640. if (ut.isFullCol()) {
  641. var captionArr = domUtils.getElementsByTagName(tb, "caption"),
  642. thArr = domUtils.getElementsByTagName(tb, "th"),
  643. captionHeight, thHeight;
  644. if (captionArr.length > 0) {
  645. captionHeight = captionArr[0].offsetHeight;
  646. }
  647. if (thArr.length > 0) {
  648. thHeight = thArr[0].offsetHeight;
  649. }
  650. sumHeight = tb.offsetHeight - (captionHeight || 0) - (thHeight || 0);
  651. rowNum = thArr.length == 0 ? ut.rowsNum : (ut.rowsNum - 1);
  652. } else {
  653. var begin = ut.cellsRange.beginRowIndex,
  654. end = ut.cellsRange.endRowIndex,
  655. count = 0,
  656. trs = domUtils.getElementsByTagName(tb, "tr");
  657. for (var i = begin; i <= end; i++) {
  658. sumHeight += trs[i].offsetHeight;
  659. count += 1;
  660. }
  661. rowNum = count;
  662. }
  663. //ie8下是混杂模式
  664. if (browser.ie && browser.version < 9) {
  665. averageHeight = Math.ceil(sumHeight / rowNum);
  666. } else {
  667. averageHeight = Math.ceil(sumHeight / rowNum) - tbAttr.tdBorder * 2 - tdpadding * 2;
  668. }
  669. return averageHeight;
  670. }
  671. function setAverageHeight(averageHeight) {
  672. var cells = ut.isFullCol() ? domUtils.getElementsByTagName(ut.table, "td") : ut.selectedTds;
  673. utils.each(cells, function (node) {
  674. if (node.rowSpan == 1) {
  675. node.setAttribute("height", averageHeight);
  676. }
  677. });
  678. }
  679. if (ut && ut.selectedTds.length) {
  680. setAverageHeight(getAverageHeight());
  681. }
  682. }
  683. };
  684. //单元格对齐方式
  685. UE.commands['cellalignment'] = {
  686. queryCommandState: function () {
  687. return getTableItemsByRange(this).table ? 0 : -1
  688. },
  689. execCommand: function (cmd, data) {
  690. var me = this,
  691. ut = getUETableBySelected(me);
  692. if (!ut) {
  693. var start = me.selection.getStart(),
  694. cell = start && domUtils.findParentByTagName(start, ["td", "th", "caption"], true);
  695. if (!/caption/ig.test(cell.tagName)) {
  696. domUtils.setAttributes(cell, data);
  697. } else {
  698. cell.style.textAlign = data.align;
  699. cell.style.verticalAlign = data.vAlign;
  700. }
  701. me.selection.getRange().setCursor(true);
  702. } else {
  703. utils.each(ut.selectedTds, function (cell) {
  704. domUtils.setAttributes(cell, data);
  705. });
  706. }
  707. },
  708. /**
  709. * 查询当前点击的单元格的对齐状态, 如果当前已经选择了多个单元格, 则会返回所有单元格经过统一协调过后的状态
  710. * @see UE.UETable.getTableCellAlignState
  711. */
  712. queryCommandValue: function (cmd) {
  713. var activeMenuCell = getTableItemsByRange( this).cell;
  714. if( !activeMenuCell ) {
  715. activeMenuCell = getSelectedArr(this)[0];
  716. }
  717. if (!activeMenuCell) {
  718. return null;
  719. } else {
  720. //获取同时选中的其他单元格
  721. var cells = UE.UETable.getUETable(activeMenuCell).selectedTds;
  722. !cells.length && ( cells = activeMenuCell );
  723. return UE.UETable.getTableCellAlignState(cells);
  724. }
  725. }
  726. };
  727. //表格对齐方式
  728. UE.commands['tablealignment'] = {
  729. queryCommandState: function () {
  730. if (browser.ie && browser.version < 8) {
  731. return -1;
  732. }
  733. return getTableItemsByRange(this).table ? 0 : -1
  734. },
  735. execCommand: function (cmd, value) {
  736. var me = this,
  737. start = me.selection.getStart(),
  738. table = start && domUtils.findParentByTagName(start, ["table"], true);
  739. if (table) {
  740. table.setAttribute("align",value);
  741. }
  742. }
  743. };
  744. //表格属性
  745. UE.commands['edittable'] = {
  746. queryCommandState: function () {
  747. return getTableItemsByRange(this).table ? 0 : -1
  748. },
  749. execCommand: function (cmd, color) {
  750. var rng = this.selection.getRange(),
  751. table = domUtils.findParentByTagName(rng.startContainer, 'table');
  752. if (table) {
  753. var arr = domUtils.getElementsByTagName(table, "td").concat(
  754. domUtils.getElementsByTagName(table, "th"),
  755. domUtils.getElementsByTagName(table, "caption")
  756. );
  757. utils.each(arr, function (node) {
  758. node.style.borderColor = color;
  759. });
  760. }
  761. }
  762. };
  763. //单元格属性
  764. UE.commands['edittd'] = {
  765. queryCommandState: function () {
  766. return getTableItemsByRange(this).table ? 0 : -1
  767. },
  768. execCommand: function (cmd, bkColor) {
  769. var me = this,
  770. ut = getUETableBySelected(me);
  771. if (!ut) {
  772. var start = me.selection.getStart(),
  773. cell = start && domUtils.findParentByTagName(start, ["td", "th", "caption"], true);
  774. if (cell) {
  775. cell.style.backgroundColor = bkColor;
  776. }
  777. } else {
  778. utils.each(ut.selectedTds, function (cell) {
  779. cell.style.backgroundColor = bkColor;
  780. });
  781. }
  782. }
  783. };
  784. UE.commands["settablebackground"] = {
  785. queryCommandState: function () {
  786. return getSelectedArr(this).length > 1 ? 0 : -1;
  787. },
  788. execCommand: function (cmd, value) {
  789. var cells, ut;
  790. cells = getSelectedArr(this);
  791. ut = getUETable(cells[0]);
  792. ut.setBackground(cells, value);
  793. }
  794. };
  795. UE.commands["cleartablebackground"] = {
  796. queryCommandState: function () {
  797. var cells = getSelectedArr(this);
  798. if (!cells.length)return -1;
  799. for (var i = 0, cell; cell = cells[i++];) {
  800. if (cell.style.backgroundColor !== "") return 0;
  801. }
  802. return -1;
  803. },
  804. execCommand: function () {
  805. var cells = getSelectedArr(this),
  806. ut = getUETable(cells[0]);
  807. ut.removeBackground(cells);
  808. }
  809. };
  810. UE.commands["interlacetable"] = UE.commands["uninterlacetable"] = {
  811. queryCommandState: function (cmd) {
  812. var table = getTableItemsByRange(this).table;
  813. if (!table) return -1;
  814. var interlaced = table.getAttribute("interlaced");
  815. if (cmd == "interlacetable") {
  816. //TODO 待定
  817. //是否需要待定,如果设置,则命令只能单次执行成功,但反射具备toggle效果;否则可以覆盖前次命令,但反射将不存在toggle效果
  818. return (interlaced === "enabled") ? -1 : 0;
  819. } else {
  820. return (!interlaced || interlaced === "disabled") ? -1 : 0;
  821. }
  822. },
  823. execCommand: function (cmd, classList) {
  824. var table = getTableItemsByRange(this).table;
  825. if (cmd == "interlacetable") {
  826. table.setAttribute("interlaced", "enabled");
  827. this.fireEvent("interlacetable", table, classList);
  828. } else {
  829. table.setAttribute("interlaced", "disabled");
  830. this.fireEvent("uninterlacetable", table);
  831. }
  832. }
  833. };
  834. UE.commands["setbordervisible"] = {
  835. queryCommandState: function (cmd) {
  836. var table = getTableItemsByRange(this).table;
  837. if (!table) return -1;
  838. return 0;
  839. },
  840. execCommand: function () {
  841. var table = getTableItemsByRange(this).table;
  842. utils.each(domUtils.getElementsByTagName(table,'td'),function(td){
  843. td.style.borderWidth = '1px';
  844. td.style.borderStyle = 'solid';
  845. })
  846. }
  847. };
  848. function resetTdWidth(table, editor) {
  849. var tds = domUtils.getElementsByTagName(table,'td th');
  850. utils.each(tds, function (td) {
  851. td.removeAttribute("width");
  852. });
  853. table.setAttribute('width', getTableWidth(editor, true, getDefaultValue(editor, table)));
  854. var tdsWidths = [];
  855. setTimeout(function () {
  856. utils.each(tds, function (td) {
  857. (td.colSpan == 1) && tdsWidths.push(td.offsetWidth)
  858. })
  859. utils.each(tds, function (td,i) {
  860. (td.colSpan == 1) && td.setAttribute("width", tdsWidths[i] + "");
  861. })
  862. }, 0);
  863. }
  864. function getTableWidth(editor, needIEHack, defaultValue) {
  865. var body = editor.body;
  866. return body.offsetWidth - (needIEHack ? parseInt(domUtils.getComputedStyle(body, 'margin-left'), 10) * 2 : 0) - defaultValue.tableBorder * 2 - (editor.options.offsetWidth || 0);
  867. }
  868. function getSelectedArr(editor) {
  869. var cell = getTableItemsByRange(editor).cell;
  870. if (cell) {
  871. var ut = getUETable(cell);
  872. return ut.selectedTds.length ? ut.selectedTds : [cell];
  873. } else {
  874. return [];
  875. }
  876. }
  877. })();