table.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. /*jslint onevar: false, nomen: false*/
  2. /*global Trex, TrexMessage, TXMSG, $tom, $tx, _FALSE, _NULL, _TRUE */
  3. Trex.MarkupTemplate.add('table.col.resize.dragger', '<div class="tx-table-col-resize-dragger" style="position:absolute; overflow:hidden; top: 0; left: 0; width: 3px; height: 100%; cursor:col-resize;"><\/div>');
  4. Trex.MarkupTemplate.add('table.row.resize.dragger', '<div class="tx-table-row-resize-dragger" style="position:absolute; overflow:hidden; top: 0; left: 0; width: 100%; height: 3px; cursor:row-resize;"><\/div>');
  5. TrexMessage.addMsg({
  6. '@table.noselect.alert': "테이블을 선택하신 후 사용가능합니다."
  7. });
  8. Trex.Table = {};
  9. Trex.module("table selector", function (editor, toolbar, sidebar, canvas, config) {
  10. var initDragger;
  11. initDragger = function (canvas) {
  12. var colDragger, rowDragger, wysiwygEl;
  13. colDragger = Trex.MarkupTemplate.get("table.col.resize.dragger").evaluateAsDom({});
  14. rowDragger = Trex.MarkupTemplate.get("table.row.resize.dragger").evaluateAsDom({});
  15. wysiwygEl = canvas.wysiwygEl;
  16. $tom.insertFirst(wysiwygEl, colDragger);
  17. $tom.insertFirst(wysiwygEl, rowDragger);
  18. $tx.hide(colDragger);
  19. $tx.hide(rowDragger);
  20. };
  21. canvas.observeJob(Trex.Ev.__CANVAS_PANEL_BACKSPACE_TABLE, function(node) {
  22. $tom.remove(node);
  23. });
  24. canvas.observeJob(Trex.Ev.__IFRAME_LOAD_COMPLETE, function () {
  25. var tableSelect, tableMerge, tableInsert, tableDelete, tableBorder, tableTemplateLoader;
  26. tableSelect = new Trex.Table.Selector(editor, config);
  27. tableMerge = new Trex.Table.Merge(editor, config);
  28. tableInsert = new Trex.Table.Insert(editor, config);
  29. tableDelete = new Trex.Table.Delete(editor, config);
  30. tableBorder = new Trex.Table.Border(editor, config);
  31. tableTemplateLoader = new Trex.Table.TemplateLoader();
  32. initDragger(canvas);
  33. var wysiwygPanel = canvas.getPanel(Trex.Canvas.__WYSIWYG_MODE);
  34. var processor = wysiwygPanel.getProcessor();
  35. /**
  36. * selectCellByCaret
  37. * 캐럿의 위치에 해당하는 cell 을 선택한다.
  38. */
  39. var selectCellByCaret = function () {
  40. var node, td;
  41. if (tableSelect.getSelected().isValid() === _FALSE) {
  42. node = processor.getNode();
  43. td = Trex.TableUtil.getClosestByTagNames(["td", "th"], node);
  44. if (td) {
  45. tableSelect.selectByTd(td, td);
  46. }
  47. }
  48. };
  49. /**
  50. * table 을 선택하면 advanced 가 열림.
  51. * //CHECK:
  52. * table 버튼들의 위치가 advanced 라고 가정하고 있음.
  53. */
  54. canvas.observeElement({
  55. tag: 'table'
  56. }, function (elem) {
  57. if (toolbar.tools.advanced) {
  58. toolbar.tools.advanced.forceOpen();
  59. }
  60. });
  61. /**
  62. * border 를 적용하기 위한 4가지 옵션값.
  63. */
  64. var borderProperty = {
  65. range: "all",
  66. color: "",
  67. height: 1,
  68. type: "solid"
  69. };
  70. var setDefaultBorderProperty = function () {
  71. var tool = toolbar.tools.cellslinecolor;
  72. if (tool) {
  73. borderProperty.color = tool.config.defaultcolor;
  74. }
  75. };
  76. setDefaultBorderProperty();
  77. var alertFromNoSelect = function () {
  78. alert(TXMSG('@table.noselect.alert'));
  79. };
  80. processor.table = {
  81. /**
  82. * getTdArr
  83. * 선택한 cell 들의 array.
  84. * //CHECK: getSelectedCells ?
  85. * 지금보니 이름이 마음에 들지 않네...
  86. * @return {Array}
  87. */
  88. getTdArr: function () {
  89. return tableSelect.getSelectedTdArr();
  90. },
  91. /**
  92. * isDuringSelection
  93. * 선택을 하고 있는 중인지 여부(선택을 위한 드래그 중).
  94. * @return {boolean}
  95. */
  96. isDuringSelection: function () {
  97. return tableSelect.isDuringSelection();
  98. },
  99. execute: function (fn, noCaretSelect) {
  100. if (! noCaretSelect) {
  101. selectCellByCaret();
  102. }
  103. if (tableSelect.getSelected().isValid()) {
  104. fn();
  105. canvas.history.saveHistory();
  106. } else {
  107. alertFromNoSelect();
  108. }
  109. },
  110. merge: function () {
  111. this.execute(function () {
  112. tableMerge.merge(tableSelect);
  113. }, _TRUE);
  114. },
  115. resetMerge: function () {
  116. this.execute(function () {
  117. tableMerge.resetMerge(tableSelect);
  118. });
  119. },
  120. insertRowAbove: function () {
  121. this.execute(function () {
  122. tableInsert.insertRowAbove(tableSelect);
  123. });
  124. },
  125. insertRowBelow: function () {
  126. this.execute(function () {
  127. tableInsert.insertRowBelow(tableSelect);
  128. });
  129. },
  130. insertColLeft: function () {
  131. this.execute(function () {
  132. tableInsert.insertColLeft(tableSelect);
  133. });
  134. },
  135. insertColRight: function () {
  136. this.execute(function () {
  137. tableInsert.insertColRight(tableSelect);
  138. });
  139. },
  140. deleteRow: function () {
  141. this.execute(function () {
  142. tableDelete.deleteRow(tableSelect);
  143. });
  144. },
  145. deleteCol: function () {
  146. this.execute(function () {
  147. tableDelete.deleteCol(tableSelect);
  148. });
  149. },
  150. setBorderRange: function (outlineType) {
  151. borderProperty.range = outlineType;
  152. },
  153. setBorderColor: function (color) {
  154. borderProperty.color = color;
  155. toolbar.fireJobs(Trex.Ev.__TOOL_CELL_LINE_CHANGE, {
  156. color: color
  157. });
  158. },
  159. setBorderHeight: function (height) {
  160. borderProperty.height = height;
  161. toolbar.fireJobs(Trex.Ev.__TOOL_CELL_LINE_CHANGE, {
  162. height: height
  163. });
  164. },
  165. setBorderType: function (type) {
  166. borderProperty.type = type;
  167. toolbar.fireJobs(Trex.Ev.__TOOL_CELL_LINE_CHANGE, {
  168. type: type
  169. });
  170. },
  171. setNoBorder: function () {
  172. var self = this;
  173. this.execute(function () {
  174. tableBorder.setTableSelect(tableSelect);
  175. tableBorder.setBorderRange("all");
  176. tableBorder.changeBorderColor(self.getTdArr(), "");
  177. tableBorder.changeBorderHeight(self.getTdArr(), "0");
  178. tableBorder.changeBorderType(self.getTdArr(), "none");
  179. });
  180. },
  181. setBorderButtons: function (color, height, type) {
  182. var tool;
  183. tool = toolbar.tools.cellslinecolor;
  184. if (tool) {
  185. tool.execute(color);
  186. }
  187. tool = toolbar.tools.cellslineheight;
  188. if (tool) {
  189. tool.execute(height);
  190. }
  191. tool = toolbar.tools.cellslinestyle;
  192. if (tool) {
  193. tool.execute(type);
  194. }
  195. },
  196. getBorderProperty: function () {
  197. return {
  198. color: borderProperty.color,
  199. height: borderProperty.height,
  200. type: borderProperty.type
  201. };
  202. },
  203. applyBorder: function () {
  204. var self = this;
  205. this.execute(function () {
  206. tableBorder.setTableSelect(tableSelect);
  207. tableBorder.setBorderRange(borderProperty.range);
  208. tableBorder.changeBorderColor(self.getTdArr(), borderProperty.color);
  209. tableBorder.changeBorderHeight(self.getTdArr(), borderProperty.height);
  210. tableBorder.changeBorderType(self.getTdArr(), borderProperty.type);
  211. self.addBorderHistory();
  212. });
  213. },
  214. addBorderHistory: function () {
  215. var tool;
  216. tool = toolbar.tools.cellslinepreview;
  217. if (tool) {
  218. tool.addBorderHistory(borderProperty);
  219. }
  220. },
  221. tableBackground: function (value) {
  222. var self = this;
  223. this.execute(function () {
  224. var style, tdArr, i, len;
  225. style = {
  226. "backgroundColor": value
  227. };
  228. tdArr = self.getTdArr();
  229. len = tdArr.length;
  230. for (i = 0; i < len; i += 1) {
  231. $tx.setStyle(tdArr[i], style);
  232. }
  233. tableSelect.reset();
  234. });
  235. },
  236. setTemplateStyle: function (table, templateIndex) {
  237. if (table) {
  238. var self = this;
  239. tableTemplateLoader.getTemplate(templateIndex, function(template) {
  240. template.apply(table);
  241. self._applyTemplateOutline(table, template.templateData);
  242. tableSelect.reset();
  243. });
  244. } else {
  245. alertFromNoSelect();
  246. }
  247. },
  248. /**
  249. * 테이블 템플릿을 적용해도 테두리에 대한 정확한 적용이 되지않아 흰색 혹은 none의 상태가 된다.
  250. * 이를 보완하기 위해서 테이블 기본 기능을 이용해서 테두리를 재설정 한다.
  251. *
  252. * @param table
  253. * @param templateData
  254. * @private
  255. */
  256. _applyTemplateOutline: function(table, templateData) {
  257. var item = templateData;
  258. var self = this;
  259. var outlineBorder = {
  260. top: this._parseBorderStyle(item.firstRow.borderTop),
  261. right: this._parseBorderStyle(item.lastCol.borderRight || item.common.borderRight),
  262. bottom: this._parseBorderStyle(item.lastRow.borderBottom || item.common.borderBottom),
  263. left: this._parseBorderStyle(item.firstCol.borderLeft)
  264. };
  265. var tableMatrixer = new Trex.Tool.Table.TableCellMatrixer(table);
  266. var tdMatrix = tableMatrixer.getTdMatrix();
  267. var rowSize = tableMatrixer.getRowSize();
  268. var colSize = tableMatrixer.getColSize();
  269. if (tdMatrix && tdMatrix.length) {
  270. tableSelect.selectByTd(tdMatrix[0][0], tdMatrix[rowSize-1][colSize-1]);
  271. tableBorder.setTableSelect(tableSelect);
  272. var direction = ['top', 'right', 'bottom', 'left'];
  273. direction.each(function(dir){
  274. tableBorder.setBorderRange(dir);
  275. tableBorder.changeBorderColor(self.getTdArr(), outlineBorder[dir]['color']);
  276. tableBorder.changeBorderHeight(self.getTdArr(), outlineBorder[dir]['height']);
  277. tableBorder.changeBorderType(self.getTdArr(), outlineBorder[dir]['type']);
  278. });
  279. }
  280. },
  281. /**
  282. * border style을 파싱해서 object로 반환한다.
  283. *
  284. * ex1. "1px solid red"
  285. * ex2. "none"
  286. *
  287. * @param styleString
  288. * @returns {object}
  289. * @private
  290. */
  291. _parseBorderStyle: function(styleString) {
  292. styleString = styleString.trim().toLowerCase();
  293. if (styleString === 'none') {
  294. return {
  295. height: 'none',
  296. type: 'solid',
  297. color: 'transparent'
  298. };
  299. } else {
  300. var parts = styleString.split(' ');
  301. if (parts.length != 3) {
  302. parts = ['1px', 'solid', '#000'];
  303. }
  304. return {
  305. height: parts[0].parsePx() || 1,
  306. type: parts[1],
  307. color: parts[2]
  308. };
  309. }
  310. }
  311. };
  312. toolbar.fireJobs(Trex.Ev.__TOOL_CELL_LINE_CHANGE, {
  313. color: borderProperty.color,
  314. height: borderProperty.height,
  315. type: borderProperty.type,
  316. fromInit: _TRUE
  317. });
  318. toolbar.observeJob(Trex.Ev.__TOOL_CLICK, function (identity) {
  319. if ([
  320. "fontfamily",
  321. "fontsize",
  322. "bold",
  323. "underline",
  324. "italic",
  325. "strike",
  326. "forecolor",
  327. "backcolor",
  328. "indent",
  329. "outdent",
  330. "alignleft",
  331. "aligncenter",
  332. "alignright",
  333. "alignfull",
  334. "mergecells",
  335. "splitcells",
  336. "insertcells",
  337. "deletecells",
  338. "cellsoutline",
  339. "cellslinecolor",
  340. "cellslineheight",
  341. "cellslinestyle",
  342. "cellslinepreview",
  343. "tablebackcolor",
  344. "tabletemplate"
  345. ].contains(identity) === _FALSE) {
  346. tableSelect.reset();
  347. }
  348. if (identity === "tablebackcolor") {
  349. selectCellByCaret();
  350. }
  351. });
  352. });
  353. });