contextMenuCopyPaste.js 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
  2. 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; }; }();
  3. var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
  4. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  5. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  6. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  7. import ZeroClipboard from 'zeroclipboard';
  8. import BasePlugin from './../_base';
  9. import { removeClass } from './../../helpers/dom/element';
  10. import { arrayEach } from './../../helpers/array';
  11. import EventManager from './../../eventManager';
  12. import { registerPlugin } from './../../plugins';
  13. import { SEPARATOR } from './../contextMenu/predefinedItems';
  14. /**
  15. * @description
  16. * This plugin adds a copy/paste functionality to the context menu. Due to browser restrictions, it uses ZeroClipboard to allow
  17. * copying data with a click.
  18. *
  19. * @plugin ContextMenuCopyPaste
  20. * @dependencies ContextMenu
  21. */
  22. var ContextMenuCopyPaste = function (_BasePlugin) {
  23. _inherits(ContextMenuCopyPaste, _BasePlugin);
  24. /**
  25. * @param {Object} hotInstance
  26. */
  27. function ContextMenuCopyPaste(hotInstance) {
  28. _classCallCheck(this, ContextMenuCopyPaste);
  29. /**
  30. * Instance of {@link EventManager}.
  31. *
  32. * @type {EventManager}
  33. */
  34. var _this = _possibleConstructorReturn(this, (ContextMenuCopyPaste.__proto__ || Object.getPrototypeOf(ContextMenuCopyPaste)).call(this, hotInstance));
  35. _this.eventManager = new EventManager(_this);
  36. /**
  37. * Path to swf file which is necessary for ZeroClipboard.
  38. *
  39. * @type {String}
  40. */
  41. _this.swfPath = null;
  42. /**
  43. * outsideClickDeselectsCache setting cache.
  44. *
  45. * @type {Boolean}
  46. */
  47. _this.outsideClickDeselectsCache = null;
  48. return _this;
  49. }
  50. /**
  51. * Check if the plugin is enabled in the handsontable settings.
  52. *
  53. * @returns {Boolean}
  54. */
  55. _createClass(ContextMenuCopyPaste, [{
  56. key: 'isEnabled',
  57. value: function isEnabled() {
  58. return this.hot.getSettings().contextMenuCopyPaste;
  59. }
  60. /**
  61. * Enable plugin for this Handsontable instance.
  62. */
  63. }, {
  64. key: 'enablePlugin',
  65. value: function enablePlugin() {
  66. var _this2 = this;
  67. if (this.enabled) {
  68. return;
  69. }
  70. if (_typeof(this.hot.getSettings().contextMenuCopyPaste) === 'object') {
  71. this.swfPath = this.hot.getSettings().contextMenuCopyPaste.swfPath;
  72. }
  73. if (typeof ZeroClipboard === 'undefined') {
  74. console.error('To be able to use the Copy/Paste feature from the context menu, you need to manually include ZeroClipboard.js file to your website.');
  75. }
  76. try {
  77. /* eslint-disable no-new */
  78. new ActiveXObject('ShockwaveFlash.ShockwaveFlash');
  79. } catch (exception) {
  80. if (typeof navigator.mimeTypes['application/x-shockwave-flash'] == 'undefined') {
  81. console.error('To be able to use the Copy/Paste feature from the context menu, your browser needs to have Flash Plugin installed.');
  82. }
  83. }
  84. if (this.swfPath) {
  85. ZeroClipboard.config({
  86. swfPath: this.swfPath
  87. });
  88. }
  89. this.hot.addHook('afterContextMenuShow', function () {
  90. return _this2.onAfterContextMenuShow();
  91. });
  92. this.hot.addHook('afterContextMenuDefaultOptions', function (options) {
  93. return _this2.onAfterContextMenuDefaultOptions(options);
  94. });
  95. this.registerEvents();
  96. _get(ContextMenuCopyPaste.prototype.__proto__ || Object.getPrototypeOf(ContextMenuCopyPaste.prototype), 'enablePlugin', this).call(this);
  97. }
  98. /**
  99. * Disable plugin for this Handsontable instance.
  100. */
  101. }, {
  102. key: 'disablePlugin',
  103. value: function disablePlugin() {
  104. _get(ContextMenuCopyPaste.prototype.__proto__ || Object.getPrototypeOf(ContextMenuCopyPaste.prototype), 'disablePlugin', this).call(this);
  105. }
  106. /**
  107. * @private
  108. */
  109. }, {
  110. key: 'registerEvents',
  111. value: function registerEvents() {
  112. var _this3 = this;
  113. this.eventManager.addEventListener(document, 'mouseenter', function () {
  114. return _this3.removeCurrentClass();
  115. });
  116. this.eventManager.addEventListener(document, 'mouseleave', function () {
  117. return _this3.removeZeroClipboardClass();
  118. });
  119. }
  120. /**
  121. * Get a value to copy.
  122. *
  123. * @returns {String}
  124. */
  125. }, {
  126. key: 'getCopyValue',
  127. value: function getCopyValue() {
  128. this.hot.copyPaste.setCopyableText();
  129. this.hot.copyPaste.copyPasteInstance.triggerCopy();
  130. return this.hot.copyPaste.copyPasteInstance.elTextarea.value;
  131. }
  132. /**
  133. * Add Copy and Paste functionality to the context menu.
  134. *
  135. * @private
  136. * @param {Object} defaultOptions
  137. */
  138. }, {
  139. key: 'onAfterContextMenuDefaultOptions',
  140. value: function onAfterContextMenuDefaultOptions(defaultOptions) {
  141. defaultOptions.items.unshift({
  142. key: 'copy',
  143. name: 'Copy',
  144. disabled: function disabled() {
  145. return this.selection.selectedHeader.corner;
  146. }
  147. }, {
  148. key: 'paste',
  149. name: 'Paste',
  150. callback: function callback() {
  151. this.copyPaste.triggerPaste();
  152. },
  153. disabled: function disabled() {
  154. return this.selection.selectedHeader.corner;
  155. }
  156. }, { name: SEPARATOR });
  157. }
  158. /**
  159. * After context menu show listener.
  160. *
  161. * @private
  162. */
  163. }, {
  164. key: 'onAfterContextMenuShow',
  165. value: function onAfterContextMenuShow() {
  166. var _this4 = this;
  167. var contextMenu = this.hot.getPlugin('contextMenu');
  168. var data = contextMenu.menu.hotMenu.getSourceData();
  169. // find position of 'copy' option.
  170. arrayEach(data, function (item, index) {
  171. if (item.key === 'copy') {
  172. var zeroClipboardInstance = new ZeroClipboard(contextMenu.menu.hotMenu.getCell(index, 0));
  173. zeroClipboardInstance.off();
  174. zeroClipboardInstance.on('copy', function (event) {
  175. var clipboard = event.clipboardData;
  176. clipboard.setData('text/plain', _this4.getCopyValue());
  177. _this4.hot.getSettings().outsideClickDeselects = _this4.outsideClickDeselectsCache;
  178. });
  179. return false;
  180. }
  181. });
  182. }
  183. /**
  184. * @private
  185. */
  186. }, {
  187. key: 'removeCurrentClass',
  188. value: function removeCurrentClass() {
  189. var contextMenu = this.hot.getPlugin('contextMenu');
  190. if (!contextMenu.enabled) {
  191. return;
  192. }
  193. if (contextMenu.menu.isOpened()) {
  194. var element = contextMenu.menu.hotMenu.rootElement.querySelector('td.current');
  195. if (element) {
  196. removeClass(element, 'current');
  197. }
  198. }
  199. this.outsideClickDeselectsCache = this.hot.getSettings().outsideClickDeselects;
  200. this.hot.getSettings().outsideClickDeselects = false;
  201. }
  202. /**
  203. * @private
  204. */
  205. }, {
  206. key: 'removeZeroClipboardClass',
  207. value: function removeZeroClipboardClass() {
  208. var contextMenu = this.hot.getPlugin('contextMenu');
  209. if (!contextMenu.enabled) {
  210. return;
  211. }
  212. if (contextMenu.menu.isOpened()) {
  213. var element = contextMenu.menu.hotMenu.rootElement.querySelector('td.zeroclipboard-is-hover');
  214. if (element) {
  215. removeClass(element, 'zeroclipboard-is-hover');
  216. }
  217. }
  218. this.hot.getSettings().outsideClickDeselects = this.outsideClickDeselectsCache;
  219. }
  220. }]);
  221. return ContextMenuCopyPaste;
  222. }(BasePlugin);
  223. registerPlugin('contextMenuCopyPaste', ContextMenuCopyPaste);
  224. export default ContextMenuCopyPaste;