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; }; 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; }; }(); 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); } }; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 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; } 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; } import ZeroClipboard from 'zeroclipboard'; import BasePlugin from './../_base'; import { removeClass } from './../../helpers/dom/element'; import { arrayEach } from './../../helpers/array'; import EventManager from './../../eventManager'; import { registerPlugin } from './../../plugins'; import { SEPARATOR } from './../contextMenu/predefinedItems'; /** * @description * This plugin adds a copy/paste functionality to the context menu. Due to browser restrictions, it uses ZeroClipboard to allow * copying data with a click. * * @plugin ContextMenuCopyPaste * @dependencies ContextMenu */ var ContextMenuCopyPaste = function (_BasePlugin) { _inherits(ContextMenuCopyPaste, _BasePlugin); /** * @param {Object} hotInstance */ function ContextMenuCopyPaste(hotInstance) { _classCallCheck(this, ContextMenuCopyPaste); /** * Instance of {@link EventManager}. * * @type {EventManager} */ var _this = _possibleConstructorReturn(this, (ContextMenuCopyPaste.__proto__ || Object.getPrototypeOf(ContextMenuCopyPaste)).call(this, hotInstance)); _this.eventManager = new EventManager(_this); /** * Path to swf file which is necessary for ZeroClipboard. * * @type {String} */ _this.swfPath = null; /** * outsideClickDeselectsCache setting cache. * * @type {Boolean} */ _this.outsideClickDeselectsCache = null; return _this; } /** * Check if the plugin is enabled in the handsontable settings. * * @returns {Boolean} */ _createClass(ContextMenuCopyPaste, [{ key: 'isEnabled', value: function isEnabled() { return this.hot.getSettings().contextMenuCopyPaste; } /** * Enable plugin for this Handsontable instance. */ }, { key: 'enablePlugin', value: function enablePlugin() { var _this2 = this; if (this.enabled) { return; } if (_typeof(this.hot.getSettings().contextMenuCopyPaste) === 'object') { this.swfPath = this.hot.getSettings().contextMenuCopyPaste.swfPath; } if (typeof ZeroClipboard === 'undefined') { 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.'); } try { /* eslint-disable no-new */ new ActiveXObject('ShockwaveFlash.ShockwaveFlash'); } catch (exception) { if (typeof navigator.mimeTypes['application/x-shockwave-flash'] == 'undefined') { console.error('To be able to use the Copy/Paste feature from the context menu, your browser needs to have Flash Plugin installed.'); } } if (this.swfPath) { ZeroClipboard.config({ swfPath: this.swfPath }); } this.hot.addHook('afterContextMenuShow', function () { return _this2.onAfterContextMenuShow(); }); this.hot.addHook('afterContextMenuDefaultOptions', function (options) { return _this2.onAfterContextMenuDefaultOptions(options); }); this.registerEvents(); _get(ContextMenuCopyPaste.prototype.__proto__ || Object.getPrototypeOf(ContextMenuCopyPaste.prototype), 'enablePlugin', this).call(this); } /** * Disable plugin for this Handsontable instance. */ }, { key: 'disablePlugin', value: function disablePlugin() { _get(ContextMenuCopyPaste.prototype.__proto__ || Object.getPrototypeOf(ContextMenuCopyPaste.prototype), 'disablePlugin', this).call(this); } /** * @private */ }, { key: 'registerEvents', value: function registerEvents() { var _this3 = this; this.eventManager.addEventListener(document, 'mouseenter', function () { return _this3.removeCurrentClass(); }); this.eventManager.addEventListener(document, 'mouseleave', function () { return _this3.removeZeroClipboardClass(); }); } /** * Get a value to copy. * * @returns {String} */ }, { key: 'getCopyValue', value: function getCopyValue() { this.hot.copyPaste.setCopyableText(); this.hot.copyPaste.copyPasteInstance.triggerCopy(); return this.hot.copyPaste.copyPasteInstance.elTextarea.value; } /** * Add Copy and Paste functionality to the context menu. * * @private * @param {Object} defaultOptions */ }, { key: 'onAfterContextMenuDefaultOptions', value: function onAfterContextMenuDefaultOptions(defaultOptions) { defaultOptions.items.unshift({ key: 'copy', name: 'Copy', disabled: function disabled() { return this.selection.selectedHeader.corner; } }, { key: 'paste', name: 'Paste', callback: function callback() { this.copyPaste.triggerPaste(); }, disabled: function disabled() { return this.selection.selectedHeader.corner; } }, { name: SEPARATOR }); } /** * After context menu show listener. * * @private */ }, { key: 'onAfterContextMenuShow', value: function onAfterContextMenuShow() { var _this4 = this; var contextMenu = this.hot.getPlugin('contextMenu'); var data = contextMenu.menu.hotMenu.getSourceData(); // find position of 'copy' option. arrayEach(data, function (item, index) { if (item.key === 'copy') { var zeroClipboardInstance = new ZeroClipboard(contextMenu.menu.hotMenu.getCell(index, 0)); zeroClipboardInstance.off(); zeroClipboardInstance.on('copy', function (event) { var clipboard = event.clipboardData; clipboard.setData('text/plain', _this4.getCopyValue()); _this4.hot.getSettings().outsideClickDeselects = _this4.outsideClickDeselectsCache; }); return false; } }); } /** * @private */ }, { key: 'removeCurrentClass', value: function removeCurrentClass() { var contextMenu = this.hot.getPlugin('contextMenu'); if (!contextMenu.enabled) { return; } if (contextMenu.menu.isOpened()) { var element = contextMenu.menu.hotMenu.rootElement.querySelector('td.current'); if (element) { removeClass(element, 'current'); } } this.outsideClickDeselectsCache = this.hot.getSettings().outsideClickDeselects; this.hot.getSettings().outsideClickDeselects = false; } /** * @private */ }, { key: 'removeZeroClipboardClass', value: function removeZeroClipboardClass() { var contextMenu = this.hot.getPlugin('contextMenu'); if (!contextMenu.enabled) { return; } if (contextMenu.menu.isOpened()) { var element = contextMenu.menu.hotMenu.rootElement.querySelector('td.zeroclipboard-is-hover'); if (element) { removeClass(element, 'zeroclipboard-is-hover'); } } this.hot.getSettings().outsideClickDeselects = this.outsideClickDeselectsCache; } }]); return ContextMenuCopyPaste; }(BasePlugin); registerPlugin('contextMenuCopyPaste', ContextMenuCopyPaste); export default ContextMenuCopyPaste;