selector.js 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. /*jslint nomen: false*/
  2. /*global Trex, $tom, $tx, _FALSE, _NULL, _TRUE */
  3. Trex.Table.Selector = Trex.Class.create({
  4. SELECTED_CLASS_NAME: "tx_table_selected_cell",
  5. SELECTED_CSS_TEXT: "{background:#e9eeff !important}",
  6. initialize: function (editor/*, config*/) {
  7. this.canvas = editor.getCanvas();
  8. this.wysiwygPanel = this.canvas.getPanel(Trex.Canvas.__WYSIWYG_MODE);
  9. this.htmlBody = this.getHtmlBody();
  10. this.isDragging = _FALSE;
  11. this.currentTable = _NULL;
  12. this.currentTd = _NULL;
  13. this.paintedTdArr = [];
  14. this.startCellBoundary = new Trex.TableUtil.Boundary();
  15. this.endCellBoundary = this.startCellBoundary;
  16. this.selectedBoundary = new Trex.TableUtil.Boundary();
  17. this.tableIndexer = _NULL;
  18. this.applyCss();
  19. this.observeEvent();
  20. },
  21. /**
  22. * @private
  23. * @return {Element}
  24. */
  25. getHtmlBody: function () {
  26. var doc;
  27. doc = this.wysiwygPanel.getDocument();
  28. return doc.body;
  29. },
  30. /**
  31. * @private
  32. */
  33. applyCss: function () {
  34. var doc;
  35. doc = this.wysiwygPanel.getDocument();
  36. $tx.applyCSSText(doc, "." + this.SELECTED_CLASS_NAME + this.SELECTED_CSS_TEXT);
  37. },
  38. /**
  39. * @private
  40. * @param {Element} body
  41. */
  42. observeEvent: function () {
  43. var self;
  44. self = this;
  45. this.canvas.observeJob(Trex.Ev.__CANVAS_PANEL_MOUSEDOWN, function (e) {
  46. var elem;
  47. elem = $tx.element(e);
  48. self.onmousedown(elem);
  49. });
  50. $tx.observe(this.htmlBody, "mousemove", function (e) {
  51. var elem;
  52. elem = $tx.element(e);
  53. self.onmousemove(elem);
  54. });
  55. this.canvas.observeJob(Trex.Ev.__CANVAS_PANEL_MOUSEUP, function (e) {
  56. self.onmouseup();
  57. });
  58. var _tempWinTop; // #FTDUEDTR-1426
  59. try {
  60. _tempWinTop = _WIN.top;
  61. var _tempWinDoc = _tempWinTop.document;
  62. } catch(e) {
  63. _tempWinTop = _WIN;
  64. }
  65. $tx.observe(_tempWinTop, "mouseup", function (e) {
  66. self.onmouseup();
  67. });
  68. this.canvas.observeJob(Trex.Ev.__CANVAS_PANEL_KEYDOWN, function (e) {
  69. if (self.isDragging) {
  70. $tx.stop(e);
  71. self.reset();
  72. } else {
  73. self.onkeydown(e.ctrlKey, e.keyCode);
  74. }
  75. });
  76. this.canvas.observeJob(Trex.Ev.__CANVAS_DATA_INITIALIZE, function (mode) {
  77. if (mode === Trex.Canvas.__WYSIWYG_MODE) {
  78. self.clearSelected();
  79. }
  80. });
  81. },
  82. /**
  83. * @private
  84. * @param {Element} elem
  85. */
  86. onmousedown: function (elem) {
  87. var td, isTxInfo;
  88. this.reset();
  89. if (this.canvas.config.readonly === _FALSE) {
  90. td = Trex.TableUtil.getClosestByTagNames(["td", "th"], elem);
  91. isTxInfo = $tom.find(td, ".txc-info");
  92. if (td && !isTxInfo) {
  93. this.selectStart(td);
  94. this.turnOnDragging();
  95. }
  96. }
  97. },
  98. /**
  99. * @private
  100. * @param {Element} elem
  101. */
  102. onmousemove: function (elem) {
  103. var td, table, notSelected;
  104. if (this.isDragging) {
  105. td = Trex.TableUtil.getClosestByTagNames(["td", "th"], elem);
  106. if (td) {
  107. table = Trex.TableUtil.getClosestByTagNames(["table"], td);
  108. if (table === this.currentTable && td !== this.currentTd) {
  109. this.selectEnd(td);
  110. this.applySelected();
  111. Trex.TableUtil.collapseCaret(this.wysiwygPanel, elem);
  112. }
  113. } else {
  114. notSelected = (this.endCellBoundary === this.startCellBoundary);
  115. if (this.currentTd && notSelected) {
  116. this.selectEnd(this.currentTd);
  117. this.applySelected();
  118. Trex.TableUtil.collapseCaret(this.wysiwygPanel, elem);
  119. }
  120. }
  121. }
  122. },
  123. /**
  124. * @private
  125. */
  126. onmouseup: function () {
  127. if (this.isDragging) {
  128. this.turnOffDragging();
  129. }
  130. },
  131. /**
  132. * @private
  133. */
  134. onkeydown: function (ctrlKey, keyCode) {
  135. var selectedTdArr, len, i;
  136. if (ctrlKey === _FALSE) {
  137. if (keyCode === $tx.KEY_DELETE) {
  138. selectedTdArr = this.getSelectedTdArr();
  139. len = selectedTdArr.length;
  140. for (i = 0; i < len; i += 1) {
  141. Trex.TableUtil.emptyTd(selectedTdArr[i]);
  142. }
  143. }
  144. this.reset();
  145. }
  146. },
  147. /**
  148. * @private
  149. * @param {Element} td
  150. */
  151. selectStart: function (td) {
  152. this.currentTable = Trex.TableUtil.getClosestByTagNames(["table"], td);
  153. this.tableIndexer = new Trex.TableUtil.Indexer(this.currentTable);
  154. this.startCellBoundary = this.tableIndexer.getBoundary(td);
  155. this.endCellBoundary = this.startCellBoundary;
  156. this.currentTd = td;
  157. },
  158. /**
  159. * @private
  160. * @param {Element} td
  161. */
  162. selectEnd: function (td) {
  163. this.endCellBoundary = this.tableIndexer.getBoundary(td);
  164. this.currentTd = td;
  165. },
  166. /**
  167. * @private
  168. */
  169. applySelected: function () {
  170. this.calculateSelectedBoundary();
  171. this.extendSelectedBoundary();
  172. this.paint();
  173. },
  174. /**
  175. * @private
  176. */
  177. calculateSelectedBoundary: function () {
  178. this.selectedBoundary = new Trex.TableUtil.Boundary();
  179. this.selectedBoundary.merge(this.startCellBoundary);
  180. this.selectedBoundary.merge(this.endCellBoundary);
  181. },
  182. /**
  183. * @private
  184. */
  185. extendSelectedBoundary: function () {
  186. var needExtend;
  187. needExtend = this.selectedBoundary.isValid();
  188. while (needExtend) {
  189. needExtend = this.oneTimeExtendBoundary();
  190. }
  191. },
  192. /**
  193. * @private
  194. * @return {boolean} wasExtended
  195. */
  196. oneTimeExtendBoundary: function () {
  197. var selectedTdArr, i, len, extendedBoundary, wasExtended;
  198. selectedTdArr = this.tableIndexer.getTdArr(this.selectedBoundary);
  199. len = selectedTdArr.length;
  200. for (i = 0; i < len; i += 1) {
  201. extendedBoundary = this.tableIndexer.getBoundary(selectedTdArr[i]);
  202. wasExtended = this.selectedBoundary.merge(extendedBoundary);
  203. if (wasExtended) {
  204. return _TRUE;
  205. }
  206. }
  207. return _FALSE;
  208. },
  209. /**
  210. * @private
  211. */
  212. paint: function () {
  213. var tdArrToSelect, tdArrToUnselect;
  214. tdArrToSelect = this.tableIndexer.getTdArr(this.selectedBoundary);
  215. tdArrToUnselect = Array.prototype.without.apply(this.paintedTdArr, tdArrToSelect);
  216. this.paintSelected(tdArrToSelect);
  217. this.eraseSelected(tdArrToUnselect);
  218. },
  219. /**
  220. * @private
  221. * @param {Array} tdArr
  222. */
  223. paintSelected: function (tdArr) {
  224. var self;
  225. self = this;
  226. this.paintedTdArr = [];
  227. tdArr.each(function (td) {
  228. $tx.addClassName(td, self.SELECTED_CLASS_NAME);
  229. self.paintedTdArr.push(td);
  230. });
  231. },
  232. /**
  233. * @private
  234. * @param {Array} tdArr
  235. */
  236. eraseSelected: function (tdArr) {
  237. this.removeClassName(tdArr);
  238. this.paintedTdArr = Array.prototype.without.apply(this.paintedTdArr, tdArr);
  239. },
  240. /**
  241. * @private
  242. * @param {Array} tdArr
  243. */
  244. removeClassName: function (tdArr) {
  245. var self;
  246. self = this;
  247. tdArr.each(function (td) {
  248. var removeAttrResult;
  249. $tx.removeClassName(td, self.SELECTED_CLASS_NAME);
  250. if (td.className === "") {
  251. removeAttrResult = td.removeAttribute("class");
  252. if (removeAttrResult === _FALSE) { //for IE6, IE7.
  253. td.removeAttribute("className");
  254. }
  255. }
  256. });
  257. },
  258. /**
  259. * @private
  260. */
  261. clearSelected: function () {
  262. var tdArr;
  263. tdArr = $tom.collectAll(this.htmlBody, "." + this.SELECTED_CLASS_NAME);
  264. this.removeClassName(tdArr);
  265. this.paintedTdArr = [];
  266. },
  267. /**
  268. * @private
  269. */
  270. resetBoundary: function () {
  271. this.startCellBoundary = new Trex.TableUtil.Boundary();
  272. this.endCellBoundary = this.startCellBoundary;
  273. this.selectedBoundary = new Trex.TableUtil.Boundary();
  274. },
  275. /**
  276. * @private
  277. */
  278. turnOnDragging: function () {
  279. this.isDragging = _TRUE;
  280. },
  281. /**
  282. * @private
  283. */
  284. turnOffDragging: function () {
  285. this.isDragging = _FALSE;
  286. },
  287. /**
  288. * @private
  289. */
  290. resetDragging: function () {
  291. this.isDragging = _FALSE;
  292. this.currentTable = _NULL;
  293. this.currentTd = _NULL;
  294. },
  295. /**
  296. * isDuringSelection
  297. * @return {boolean} isDragging
  298. */
  299. isDuringSelection: function () {
  300. return this.isDragging;
  301. },
  302. /**
  303. * getIndexer
  304. * @return {Trex.TableUtil.Indexer} indexer
  305. */
  306. getIndexer: function () {
  307. return this.tableIndexer;
  308. },
  309. /**
  310. * getSelected
  311. * @return {Trex.TableUtil.Boundary} boundary
  312. */
  313. getSelected: function () {
  314. return this.selectedBoundary;
  315. },
  316. /**
  317. * getSelectedTdArr
  318. * @return {Array} tddArr
  319. */
  320. getSelectedTdArr: function () {
  321. if (this.selectedBoundary.isValid()) {
  322. return this.tableIndexer.getTdArr(this.selectedBoundary);
  323. }
  324. return [];
  325. },
  326. /**
  327. * selectByBoundary
  328. * @param {Trex.TableUtil.Boundary} boundary
  329. */
  330. selectByBoundary: function (boundary) {
  331. this.resetBoundary();
  332. this.selectedBoundary = boundary;
  333. this.paint();
  334. },
  335. /**
  336. * selectByTd
  337. * @param {Element} startTd
  338. * @param {Element} endTd
  339. */
  340. selectByTd: function (startTd, endTd) {
  341. this.selectStart(startTd);
  342. this.selectEnd(endTd);
  343. this.applySelected();
  344. },
  345. /**
  346. * reset
  347. */
  348. reset: function () {
  349. this.clearSelected();
  350. this.resetBoundary();
  351. this.resetDragging();
  352. this.reloadIndexer();
  353. },
  354. /**
  355. * reloadIndexer
  356. */
  357. reloadIndexer: function () {
  358. if (this.tableIndexer) {
  359. this.tableIndexer.reload();
  360. }
  361. },
  362. /**
  363. * getSizeOfSelected
  364. * @return {Object} size(width,height)
  365. */
  366. getSizeOfSelected: function () {
  367. var selectedTdArr, firstTd, lastTd, firstTdPosition, lastTdPosition;
  368. selectedTdArr = this.getSelectedTdArr();
  369. if (0 < selectedTdArr.length) {
  370. firstTd = selectedTdArr[0];
  371. lastTd = selectedTdArr[selectedTdArr.length - 1];
  372. firstTdPosition = $tom.getPosition(firstTd);
  373. lastTdPosition = $tom.getPosition(lastTd);
  374. return {
  375. width: lastTdPosition.x + lastTdPosition.width - firstTdPosition.x,
  376. height: lastTdPosition.y + lastTdPosition.height - firstTdPosition.y
  377. };
  378. }
  379. return {
  380. width: 0,
  381. height: 0
  382. };
  383. }
  384. });