merge.js 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. /*jslint nomen: false*/
  2. /*global Trex, $tom, $tx, _FALSE, _NULL, _TRUE, TXMSG */
  3. TrexMessage.addMsg({
  4. '@table.merge.confirm': '셀을 병합하면 맨 위쪽 셀에 있는 값만 남고 나머지 값은 잃게 됩니다.',
  5. '@table.merge.more.select.cells': '두 개 이상의 셀을 선택해주세요.'
  6. });
  7. Trex.Table.Merge = Trex.Class.create({
  8. initialize: function (editor/*, config*/) {
  9. var canvas;
  10. canvas = editor.getCanvas();
  11. this.wysiwygPanel = canvas.getPanel(Trex.Canvas.__WYSIWYG_MODE);
  12. },
  13. /**
  14. * merge
  15. * @param {Trex.Table.Selector} tableSelector
  16. */
  17. merge: function (tableSelector) {
  18. var tdArr, td, selectedSize;
  19. tableSelector.reloadIndexer();
  20. tdArr = tableSelector.getSelectedTdArr();
  21. if (1 < tdArr.length) {
  22. var isExistContent = this.isExistContents(tdArr, 1);// 0번째는 merge시 남겨지는 데이터이므로 무시한다.
  23. if (isExistContent && confirm(TXMSG('@table.merge.confirm')) == _FALSE) {
  24. return;
  25. }
  26. selectedSize = tableSelector.getSizeOfSelected();
  27. td = tdArr[0];
  28. this.deleteCellForMerge(tdArr);
  29. this.extendCellForMerge(td, tableSelector, selectedSize);
  30. tableSelector.reset();
  31. tableSelector.selectByTd(td, td);
  32. Trex.TableUtil.collapseCaret(this.wysiwygPanel, td);
  33. } else {
  34. alert(TXMSG('@table.merge.more.select.cells'));
  35. }
  36. },
  37. isExistContents: function(tdArr, startIndex) {
  38. startIndex = startIndex || 0;// default 0
  39. var flag = _TRUE;
  40. for(var i= startIndex, max=tdArr.length; i<max; i++) {
  41. var entry = tdArr[i] || "";
  42. var html = entry.innerHTML.trim().toLowerCase().replace(/(&nbsp;|\s)/g, '');
  43. var equalBogusType1 = (html == "<p></p>"),// &nbsp; 는 치환하므로 존재할 수 없음
  44. equalBogusType2 = (html == "<p><br></p>"),
  45. equalEmpty = (html == "");
  46. if (equalBogusType1 || equalBogusType2 || equalEmpty) {
  47. flag = _FALSE;
  48. break;
  49. }
  50. }
  51. return flag;
  52. },
  53. /**
  54. * @private
  55. * @param {Array} tdArr
  56. */
  57. deleteCellForMerge: function (tdArr) {
  58. var data, trimedData, i, len;
  59. data = tdArr[0].innerHTML;
  60. len = tdArr.length;
  61. for (i = 1; i < len; i += 1) {
  62. trimedData = data.replace(Trex.__WORD_JOINER_REGEXP, "").trim();
  63. if (trimedData === "" || trimedData === "&nbsp;") {
  64. data = tdArr[i].innerHTML;
  65. }
  66. $tom.remove(tdArr[i]);
  67. }
  68. tdArr[0].innerHTML = data;
  69. },
  70. /**
  71. * @private
  72. * @param {Element} td
  73. * @param {Trex.Table.Selector} tableSelector
  74. * @param {Object} selectedSize
  75. */
  76. extendCellForMerge: function (td, tableSelector, selectedSize) {
  77. var selectedBoundary;
  78. selectedBoundary = tableSelector.getSelected();
  79. td.colSpan = selectedBoundary.right - selectedBoundary.left + 1;
  80. td.rowSpan = selectedBoundary.bottom - selectedBoundary.top + 1;
  81. if (td.style.width) {
  82. $tom.setWidth(td, selectedSize.width + "px");
  83. }
  84. if (td.style.height) {
  85. $tom.setHeight(td, selectedSize.height + "px");
  86. }
  87. },
  88. /**
  89. * resetMerge
  90. * @param {Trex.Table.Selector} tableSelector
  91. */
  92. resetMerge: function (tableSelector) {
  93. //TODO.azki cancel -> reset 으로 바꿀까!?
  94. var colResult, rowResult;
  95. tableSelector.reloadIndexer();
  96. colResult = this.splitCol(tableSelector);
  97. tableSelector.reloadIndexer();
  98. rowResult = this.splitRow(tableSelector);
  99. if (colResult === _FALSE && rowResult === _FALSE) {
  100. alert("이미 합쳐진 셀만 분할 가능합니다.");
  101. } else {
  102. tableSelector.reloadIndexer();
  103. }
  104. },
  105. /**
  106. * @private
  107. * @param {Trex.Table.Selector} tableSelector
  108. * @return {boolean} changed
  109. */
  110. splitCol: function (tableSelector) {
  111. var changed, tdArr, td, i, len, splitTdResult;
  112. changed = _FALSE;
  113. tdArr = tableSelector.getSelectedTdArr();
  114. len = tdArr.length;
  115. if (0 < len) {
  116. for (i = 0; i < len; i += 1) {
  117. td = tdArr[i];
  118. splitTdResult = this.splitTdByColSpan(td);
  119. changed = changed || splitTdResult;
  120. }
  121. }
  122. return changed;
  123. },
  124. /**
  125. * @private
  126. * @param {Trex.Table.Selector} tableSelector
  127. * @return {boolean} changed
  128. */
  129. splitRow: function (tableSelector) {
  130. var changed, tdArr, td, i, len, splitTdResult;
  131. changed = _FALSE;
  132. tdArr = tableSelector.getSelectedTdArr();
  133. len = tdArr.length;
  134. if (0 < len) {
  135. for (i = 0; i < len; i += 1) {
  136. td = tdArr[i];
  137. splitTdResult = this.splitTdByRowSpan(td);
  138. changed = changed || splitTdResult;
  139. }
  140. }
  141. return changed;
  142. },
  143. /**
  144. * @private
  145. * @param {Element} td
  146. * @return {boolean} changed
  147. */
  148. splitTdByColSpan: function (td) {
  149. var newTdCount, newTd, changed;
  150. newTdCount = td.colSpan - 1;
  151. changed = 0 < newTdCount;
  152. Trex.TableUtil.splitWidthByColSpan(td);
  153. td.colSpan = 1;
  154. while (0 < newTdCount) {
  155. newTd = Trex.TableUtil.cloneNodeForEmptyTd(td);
  156. //TODO.azki set border top/left.
  157. $tom.insertNext(newTd, td);
  158. newTdCount -= 1;
  159. }
  160. return changed;
  161. },
  162. /**
  163. * @private
  164. * @param {Element} td
  165. * @return {boolean} changed
  166. */
  167. splitTdByRowSpan: function (td) {
  168. var changed, newTdCount;
  169. newTdCount = td.rowSpan - 1;
  170. changed = 0 < newTdCount;
  171. Trex.TableUtil.splitHeightByRowSpan(td);
  172. while (0 < newTdCount) {
  173. this.splitTdOneByOne(td);
  174. newTdCount -= 1;
  175. }
  176. return changed;
  177. },
  178. /**
  179. * @private
  180. * @param {Element} td
  181. */
  182. splitTdOneByOne: function (td) {
  183. var trForInsert, tdForInsert, newTd;
  184. trForInsert = this.getTrForInsert(td);
  185. tdForInsert = this.getTdForInsert(td, trForInsert);
  186. newTd = Trex.TableUtil.cloneNodeForEmptyTd(td);
  187. newTd.rowSpan = 1;
  188. td.rowSpan -= 1;
  189. if (tdForInsert) {
  190. $tom.insertAt(newTd, tdForInsert);
  191. } else {
  192. $tom.append(trForInsert, newTd);
  193. }
  194. },
  195. /**
  196. * @private
  197. * @param {Element} td
  198. */
  199. getTrForInsert: function (td) {
  200. var i, len, trForInsert;
  201. trForInsert = $tom.parent(td);
  202. len = td.rowSpan - 1;
  203. for (i = 0; i < len; i += 1) {
  204. trForInsert = $tom.next(trForInsert, "tr");
  205. }
  206. return trForInsert;
  207. },
  208. /**
  209. * @private
  210. * @param {Element} td
  211. * @param {Element} trForInsert
  212. */
  213. getTdForInsert: function (td, trForInsert) {
  214. var tableIndexer, currentBoundary, colForInsert, cells, len, i, cell, cellBoundary;
  215. tableIndexer = Trex.TableUtil.getTableIndexerFromTd(td);
  216. currentBoundary = tableIndexer.getBoundary(td);
  217. colForInsert = currentBoundary.left;
  218. cells = trForInsert.cells;
  219. len = cells.length;
  220. for (i = 0; i < len; i += 1) {
  221. cell = cells[i];
  222. cellBoundary = tableIndexer.getBoundary(cell);
  223. if (colForInsert <= cellBoundary.left) {
  224. return cell;
  225. }
  226. }
  227. return _NULL;
  228. }
  229. });