2a64e469c8d3a952df0bac41941370f5c226a5e3df7819bc1ce3670b6cd836e78f5591712cd2e7ebc0403762be9ba1b1235b5b866d479300f5b51647d4b91d 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537
  1. 'use strict';
  2. exports.__esModule = true;
  3. var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
  4. var _element = require('./../../../helpers/dom/element');
  5. var _event = require('./../../../helpers/dom/event');
  6. var _object = require('./../../../helpers/object');
  7. var _browser = require('./../../../helpers/browser');
  8. var _eventManager = require('./../../../eventManager');
  9. var _eventManager2 = _interopRequireDefault(_eventManager);
  10. var _coords = require('./cell/coords');
  11. var _coords2 = _interopRequireDefault(_coords);
  12. var _base = require('./overlay/_base.js');
  13. var _base2 = _interopRequireDefault(_base);
  14. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  15. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  16. /**
  17. *
  18. */
  19. var Border = function () {
  20. /**
  21. * @param {Walkontable} wotInstance
  22. * @param {Object} settings
  23. */
  24. function Border(wotInstance, settings) {
  25. _classCallCheck(this, Border);
  26. if (!settings) {
  27. return;
  28. }
  29. this.eventManager = new _eventManager2.default(wotInstance);
  30. this.instance = wotInstance;
  31. this.wot = wotInstance;
  32. this.settings = settings;
  33. this.mouseDown = false;
  34. this.main = null;
  35. this.top = null;
  36. this.left = null;
  37. this.bottom = null;
  38. this.right = null;
  39. this.topStyle = null;
  40. this.leftStyle = null;
  41. this.bottomStyle = null;
  42. this.rightStyle = null;
  43. this.cornerDefaultStyle = {
  44. width: '5px',
  45. height: '5px',
  46. borderWidth: '2px',
  47. borderStyle: 'solid',
  48. borderColor: '#FFF'
  49. };
  50. this.corner = null;
  51. this.cornerStyle = null;
  52. this.createBorders(settings);
  53. this.registerListeners();
  54. }
  55. /**
  56. * Register all necessary events
  57. */
  58. _createClass(Border, [{
  59. key: 'registerListeners',
  60. value: function registerListeners() {
  61. var _this2 = this;
  62. this.eventManager.addEventListener(document.body, 'mousedown', function () {
  63. return _this2.onMouseDown();
  64. });
  65. this.eventManager.addEventListener(document.body, 'mouseup', function () {
  66. return _this2.onMouseUp();
  67. });
  68. var _loop = function _loop(c, len) {
  69. _this2.eventManager.addEventListener(_this2.main.childNodes[c], 'mouseenter', function (event) {
  70. return _this2.onMouseEnter(event, _this2.main.childNodes[c]);
  71. });
  72. };
  73. for (var c = 0, len = this.main.childNodes.length; c < len; c++) {
  74. _loop(c, len);
  75. }
  76. }
  77. /**
  78. * Mouse down listener
  79. *
  80. * @private
  81. */
  82. }, {
  83. key: 'onMouseDown',
  84. value: function onMouseDown() {
  85. this.mouseDown = true;
  86. }
  87. /**
  88. * Mouse up listener
  89. *
  90. * @private
  91. */
  92. }, {
  93. key: 'onMouseUp',
  94. value: function onMouseUp() {
  95. this.mouseDown = false;
  96. }
  97. /**
  98. * Mouse enter listener for fragment selection functionality.
  99. *
  100. * @private
  101. * @param {Event} event Dom event
  102. * @param {HTMLElement} parentElement Part of border element.
  103. */
  104. }, {
  105. key: 'onMouseEnter',
  106. value: function onMouseEnter(event, parentElement) {
  107. if (!this.mouseDown || !this.wot.getSetting('hideBorderOnMouseDownOver')) {
  108. return;
  109. }
  110. event.preventDefault();
  111. (0, _event.stopImmediatePropagation)(event);
  112. var _this = this;
  113. var bounds = parentElement.getBoundingClientRect();
  114. // Hide border to prevents selection jumping when fragmentSelection is enabled.
  115. parentElement.style.display = 'none';
  116. function isOutside(event) {
  117. if (event.clientY < Math.floor(bounds.top)) {
  118. return true;
  119. }
  120. if (event.clientY > Math.ceil(bounds.top + bounds.height)) {
  121. return true;
  122. }
  123. if (event.clientX < Math.floor(bounds.left)) {
  124. return true;
  125. }
  126. if (event.clientX > Math.ceil(bounds.left + bounds.width)) {
  127. return true;
  128. }
  129. }
  130. function handler(event) {
  131. if (isOutside(event)) {
  132. _this.eventManager.removeEventListener(document.body, 'mousemove', handler);
  133. parentElement.style.display = 'block';
  134. }
  135. }
  136. this.eventManager.addEventListener(document.body, 'mousemove', handler);
  137. }
  138. /**
  139. * Create border elements
  140. *
  141. * @param {Object} settings
  142. */
  143. }, {
  144. key: 'createBorders',
  145. value: function createBorders(settings) {
  146. this.main = document.createElement('div');
  147. var borderDivs = ['top', 'left', 'bottom', 'right', 'corner'];
  148. var style = this.main.style;
  149. style.position = 'absolute';
  150. style.top = 0;
  151. style.left = 0;
  152. for (var i = 0; i < 5; i++) {
  153. var position = borderDivs[i];
  154. var div = document.createElement('div');
  155. div.className = 'wtBorder ' + (this.settings.className || ''); // + borderDivs[i];
  156. if (this.settings[position] && this.settings[position].hide) {
  157. div.className += ' hidden';
  158. }
  159. style = div.style;
  160. style.backgroundColor = this.settings[position] && this.settings[position].color ? this.settings[position].color : settings.border.color;
  161. style.height = this.settings[position] && this.settings[position].width ? this.settings[position].width + 'px' : settings.border.width + 'px';
  162. style.width = this.settings[position] && this.settings[position].width ? this.settings[position].width + 'px' : settings.border.width + 'px';
  163. this.main.appendChild(div);
  164. }
  165. this.top = this.main.childNodes[0];
  166. this.left = this.main.childNodes[1];
  167. this.bottom = this.main.childNodes[2];
  168. this.right = this.main.childNodes[3];
  169. this.topStyle = this.top.style;
  170. this.leftStyle = this.left.style;
  171. this.bottomStyle = this.bottom.style;
  172. this.rightStyle = this.right.style;
  173. this.corner = this.main.childNodes[4];
  174. this.corner.className += ' corner';
  175. this.cornerStyle = this.corner.style;
  176. this.cornerStyle.width = this.cornerDefaultStyle.width;
  177. this.cornerStyle.height = this.cornerDefaultStyle.height;
  178. this.cornerStyle.border = [this.cornerDefaultStyle.borderWidth, this.cornerDefaultStyle.borderStyle, this.cornerDefaultStyle.borderColor].join(' ');
  179. if ((0, _browser.isMobileBrowser)()) {
  180. this.createMultipleSelectorHandles();
  181. }
  182. this.disappear();
  183. if (!this.wot.wtTable.bordersHolder) {
  184. this.wot.wtTable.bordersHolder = document.createElement('div');
  185. this.wot.wtTable.bordersHolder.className = 'htBorders';
  186. this.wot.wtTable.spreader.appendChild(this.wot.wtTable.bordersHolder);
  187. }
  188. this.wot.wtTable.bordersHolder.insertBefore(this.main, this.wot.wtTable.bordersHolder.firstChild);
  189. }
  190. /**
  191. * Create multiple selector handler for mobile devices
  192. */
  193. }, {
  194. key: 'createMultipleSelectorHandles',
  195. value: function createMultipleSelectorHandles() {
  196. this.selectionHandles = {
  197. topLeft: document.createElement('DIV'),
  198. topLeftHitArea: document.createElement('DIV'),
  199. bottomRight: document.createElement('DIV'),
  200. bottomRightHitArea: document.createElement('DIV')
  201. };
  202. var width = 10;
  203. var hitAreaWidth = 40;
  204. this.selectionHandles.topLeft.className = 'topLeftSelectionHandle';
  205. this.selectionHandles.topLeftHitArea.className = 'topLeftSelectionHandle-HitArea';
  206. this.selectionHandles.bottomRight.className = 'bottomRightSelectionHandle';
  207. this.selectionHandles.bottomRightHitArea.className = 'bottomRightSelectionHandle-HitArea';
  208. this.selectionHandles.styles = {
  209. topLeft: this.selectionHandles.topLeft.style,
  210. topLeftHitArea: this.selectionHandles.topLeftHitArea.style,
  211. bottomRight: this.selectionHandles.bottomRight.style,
  212. bottomRightHitArea: this.selectionHandles.bottomRightHitArea.style
  213. };
  214. var hitAreaStyle = {
  215. position: 'absolute',
  216. height: hitAreaWidth + 'px',
  217. width: hitAreaWidth + 'px',
  218. 'border-radius': parseInt(hitAreaWidth / 1.5, 10) + 'px'
  219. };
  220. for (var prop in hitAreaStyle) {
  221. if ((0, _object.hasOwnProperty)(hitAreaStyle, prop)) {
  222. this.selectionHandles.styles.bottomRightHitArea[prop] = hitAreaStyle[prop];
  223. this.selectionHandles.styles.topLeftHitArea[prop] = hitAreaStyle[prop];
  224. }
  225. }
  226. var handleStyle = {
  227. position: 'absolute',
  228. height: width + 'px',
  229. width: width + 'px',
  230. 'border-radius': parseInt(width / 1.5, 10) + 'px',
  231. background: '#F5F5FF',
  232. border: '1px solid #4285c8'
  233. };
  234. for (var _prop in handleStyle) {
  235. if ((0, _object.hasOwnProperty)(handleStyle, _prop)) {
  236. this.selectionHandles.styles.bottomRight[_prop] = handleStyle[_prop];
  237. this.selectionHandles.styles.topLeft[_prop] = handleStyle[_prop];
  238. }
  239. }
  240. this.main.appendChild(this.selectionHandles.topLeft);
  241. this.main.appendChild(this.selectionHandles.bottomRight);
  242. this.main.appendChild(this.selectionHandles.topLeftHitArea);
  243. this.main.appendChild(this.selectionHandles.bottomRightHitArea);
  244. }
  245. }, {
  246. key: 'isPartRange',
  247. value: function isPartRange(row, col) {
  248. if (this.wot.selections.area.cellRange) {
  249. if (row != this.wot.selections.area.cellRange.to.row || col != this.wot.selections.area.cellRange.to.col) {
  250. return true;
  251. }
  252. }
  253. return false;
  254. }
  255. }, {
  256. key: 'updateMultipleSelectionHandlesPosition',
  257. value: function updateMultipleSelectionHandlesPosition(row, col, top, left, width, height) {
  258. var handleWidth = parseInt(this.selectionHandles.styles.topLeft.width, 10);
  259. var hitAreaWidth = parseInt(this.selectionHandles.styles.topLeftHitArea.width, 10);
  260. this.selectionHandles.styles.topLeft.top = parseInt(top - handleWidth, 10) + 'px';
  261. this.selectionHandles.styles.topLeft.left = parseInt(left - handleWidth, 10) + 'px';
  262. this.selectionHandles.styles.topLeftHitArea.top = parseInt(top - hitAreaWidth / 4 * 3, 10) + 'px';
  263. this.selectionHandles.styles.topLeftHitArea.left = parseInt(left - hitAreaWidth / 4 * 3, 10) + 'px';
  264. this.selectionHandles.styles.bottomRight.top = parseInt(top + height, 10) + 'px';
  265. this.selectionHandles.styles.bottomRight.left = parseInt(left + width, 10) + 'px';
  266. this.selectionHandles.styles.bottomRightHitArea.top = parseInt(top + height - hitAreaWidth / 4, 10) + 'px';
  267. this.selectionHandles.styles.bottomRightHitArea.left = parseInt(left + width - hitAreaWidth / 4, 10) + 'px';
  268. if (this.settings.border.multipleSelectionHandlesVisible && this.settings.border.multipleSelectionHandlesVisible()) {
  269. this.selectionHandles.styles.topLeft.display = 'block';
  270. this.selectionHandles.styles.topLeftHitArea.display = 'block';
  271. if (this.isPartRange(row, col)) {
  272. this.selectionHandles.styles.bottomRight.display = 'none';
  273. this.selectionHandles.styles.bottomRightHitArea.display = 'none';
  274. } else {
  275. this.selectionHandles.styles.bottomRight.display = 'block';
  276. this.selectionHandles.styles.bottomRightHitArea.display = 'block';
  277. }
  278. } else {
  279. this.selectionHandles.styles.topLeft.display = 'none';
  280. this.selectionHandles.styles.bottomRight.display = 'none';
  281. this.selectionHandles.styles.topLeftHitArea.display = 'none';
  282. this.selectionHandles.styles.bottomRightHitArea.display = 'none';
  283. }
  284. if (row == this.wot.wtSettings.getSetting('fixedRowsTop') || col == this.wot.wtSettings.getSetting('fixedColumnsLeft')) {
  285. this.selectionHandles.styles.topLeft.zIndex = '9999';
  286. this.selectionHandles.styles.topLeftHitArea.zIndex = '9999';
  287. } else {
  288. this.selectionHandles.styles.topLeft.zIndex = '';
  289. this.selectionHandles.styles.topLeftHitArea.zIndex = '';
  290. }
  291. }
  292. /**
  293. * Show border around one or many cells
  294. *
  295. * @param {Array} corners
  296. */
  297. }, {
  298. key: 'appear',
  299. value: function appear(corners) {
  300. if (this.disabled) {
  301. return;
  302. }
  303. var isMultiple, fromTD, toTD, fromOffset, toOffset, containerOffset, top, minTop, left, minLeft, height, width, fromRow, fromColumn, toRow, toColumn, trimmingContainer, cornerOverlappingContainer, ilen;
  304. ilen = this.wot.wtTable.getRenderedRowsCount();
  305. for (var i = 0; i < ilen; i++) {
  306. var s = this.wot.wtTable.rowFilter.renderedToSource(i);
  307. if (s >= corners[0] && s <= corners[2]) {
  308. fromRow = s;
  309. break;
  310. }
  311. }
  312. for (var _i = ilen - 1; _i >= 0; _i--) {
  313. var _s = this.wot.wtTable.rowFilter.renderedToSource(_i);
  314. if (_s >= corners[0] && _s <= corners[2]) {
  315. toRow = _s;
  316. break;
  317. }
  318. }
  319. ilen = this.wot.wtTable.getRenderedColumnsCount();
  320. for (var _i2 = 0; _i2 < ilen; _i2++) {
  321. var _s2 = this.wot.wtTable.columnFilter.renderedToSource(_i2);
  322. if (_s2 >= corners[1] && _s2 <= corners[3]) {
  323. fromColumn = _s2;
  324. break;
  325. }
  326. }
  327. for (var _i3 = ilen - 1; _i3 >= 0; _i3--) {
  328. var _s3 = this.wot.wtTable.columnFilter.renderedToSource(_i3);
  329. if (_s3 >= corners[1] && _s3 <= corners[3]) {
  330. toColumn = _s3;
  331. break;
  332. }
  333. }
  334. if (fromRow === void 0 || fromColumn === void 0) {
  335. this.disappear();
  336. return;
  337. }
  338. isMultiple = fromRow !== toRow || fromColumn !== toColumn;
  339. fromTD = this.wot.wtTable.getCell(new _coords2.default(fromRow, fromColumn));
  340. toTD = isMultiple ? this.wot.wtTable.getCell(new _coords2.default(toRow, toColumn)) : fromTD;
  341. fromOffset = (0, _element.offset)(fromTD);
  342. toOffset = isMultiple ? (0, _element.offset)(toTD) : fromOffset;
  343. containerOffset = (0, _element.offset)(this.wot.wtTable.TABLE);
  344. minTop = fromOffset.top;
  345. height = toOffset.top + (0, _element.outerHeight)(toTD) - minTop;
  346. minLeft = fromOffset.left;
  347. width = toOffset.left + (0, _element.outerWidth)(toTD) - minLeft;
  348. top = minTop - containerOffset.top - 1;
  349. left = minLeft - containerOffset.left - 1;
  350. var style = (0, _element.getComputedStyle)(fromTD);
  351. if (parseInt(style.borderTopWidth, 10) > 0) {
  352. top += 1;
  353. height = height > 0 ? height - 1 : 0;
  354. }
  355. if (parseInt(style.borderLeftWidth, 10) > 0) {
  356. left += 1;
  357. width = width > 0 ? width - 1 : 0;
  358. }
  359. this.topStyle.top = top + 'px';
  360. this.topStyle.left = left + 'px';
  361. this.topStyle.width = width + 'px';
  362. this.topStyle.display = 'block';
  363. this.leftStyle.top = top + 'px';
  364. this.leftStyle.left = left + 'px';
  365. this.leftStyle.height = height + 'px';
  366. this.leftStyle.display = 'block';
  367. var delta = Math.floor(this.settings.border.width / 2);
  368. this.bottomStyle.top = top + height - delta + 'px';
  369. this.bottomStyle.left = left + 'px';
  370. this.bottomStyle.width = width + 'px';
  371. this.bottomStyle.display = 'block';
  372. this.rightStyle.top = top + 'px';
  373. this.rightStyle.left = left + width - delta + 'px';
  374. this.rightStyle.height = height + 1 + 'px';
  375. this.rightStyle.display = 'block';
  376. if ((0, _browser.isMobileBrowser)() || !this.hasSetting(this.settings.border.cornerVisible) || this.isPartRange(toRow, toColumn)) {
  377. this.cornerStyle.display = 'none';
  378. } else {
  379. this.cornerStyle.top = top + height - 4 + 'px';
  380. this.cornerStyle.left = left + width - 4 + 'px';
  381. this.cornerStyle.borderRightWidth = this.cornerDefaultStyle.borderWidth;
  382. this.cornerStyle.width = this.cornerDefaultStyle.width;
  383. // Hide the fill handle, so the possible further adjustments won't force unneeded scrollbars.
  384. this.cornerStyle.display = 'none';
  385. trimmingContainer = (0, _element.getTrimmingContainer)(this.wot.wtTable.TABLE);
  386. if (toColumn === this.wot.getSetting('totalColumns') - 1) {
  387. cornerOverlappingContainer = toTD.offsetLeft + (0, _element.outerWidth)(toTD) + parseInt(this.cornerDefaultStyle.width, 10) / 2 >= (0, _element.innerWidth)(trimmingContainer);
  388. if (cornerOverlappingContainer) {
  389. this.cornerStyle.left = Math.floor(left + width - 3 - parseInt(this.cornerDefaultStyle.width, 10) / 2) + 'px';
  390. this.cornerStyle.borderRightWidth = 0;
  391. }
  392. }
  393. if (toRow === this.wot.getSetting('totalRows') - 1) {
  394. cornerOverlappingContainer = toTD.offsetTop + (0, _element.outerHeight)(toTD) + parseInt(this.cornerDefaultStyle.height, 10) / 2 >= (0, _element.innerHeight)(trimmingContainer);
  395. if (cornerOverlappingContainer) {
  396. this.cornerStyle.top = Math.floor(top + height - 3 - parseInt(this.cornerDefaultStyle.height, 10) / 2) + 'px';
  397. this.cornerStyle.borderBottomWidth = 0;
  398. }
  399. }
  400. this.cornerStyle.display = 'block';
  401. }
  402. if ((0, _browser.isMobileBrowser)()) {
  403. this.updateMultipleSelectionHandlesPosition(fromRow, fromColumn, top, left, width, height);
  404. }
  405. }
  406. /**
  407. * Hide border
  408. */
  409. }, {
  410. key: 'disappear',
  411. value: function disappear() {
  412. this.topStyle.display = 'none';
  413. this.leftStyle.display = 'none';
  414. this.bottomStyle.display = 'none';
  415. this.rightStyle.display = 'none';
  416. this.cornerStyle.display = 'none';
  417. if ((0, _browser.isMobileBrowser)()) {
  418. this.selectionHandles.styles.topLeft.display = 'none';
  419. this.selectionHandles.styles.bottomRight.display = 'none';
  420. }
  421. }
  422. /**
  423. * @param {Function} setting
  424. * @returns {*}
  425. */
  426. }, {
  427. key: 'hasSetting',
  428. value: function hasSetting(setting) {
  429. if (typeof setting === 'function') {
  430. return setting();
  431. }
  432. return !!setting;
  433. }
  434. }]);
  435. return Border;
  436. }();
  437. exports.default = Border;