| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- 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
- */
- class ContextMenuCopyPaste extends BasePlugin {
- /**
- * @param {Object} hotInstance
- */
- constructor(hotInstance) {
- super(hotInstance);
- /**
- * Instance of {@link EventManager}.
- *
- * @type {EventManager}
- */
- 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;
- }
- /**
- * Check if the plugin is enabled in the handsontable settings.
- *
- * @returns {Boolean}
- */
- isEnabled() {
- return this.hot.getSettings().contextMenuCopyPaste;
- }
- /**
- * Enable plugin for this Handsontable instance.
- */
- enablePlugin() {
- 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', () => this.onAfterContextMenuShow());
- this.hot.addHook('afterContextMenuDefaultOptions', (options) => this.onAfterContextMenuDefaultOptions(options));
- this.registerEvents();
- super.enablePlugin();
- }
- /**
- * Disable plugin for this Handsontable instance.
- */
- disablePlugin() {
- super.disablePlugin();
- }
- /**
- * @private
- */
- registerEvents() {
- this.eventManager.addEventListener(document, 'mouseenter', () => this.removeCurrentClass());
- this.eventManager.addEventListener(document, 'mouseleave', () => this.removeZeroClipboardClass());
- }
- /**
- * Get a value to copy.
- *
- * @returns {String}
- */
- 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
- */
- onAfterContextMenuDefaultOptions(defaultOptions) {
- defaultOptions.items.unshift({
- key: 'copy',
- name: 'Copy',
- disabled() {
- return this.selection.selectedHeader.corner;
- },
- }, {
- key: 'paste',
- name: 'Paste',
- callback() {
- this.copyPaste.triggerPaste();
- },
- disabled() {
- return this.selection.selectedHeader.corner;
- },
- },
- {name: SEPARATOR}
- );
- }
- /**
- * After context menu show listener.
- *
- * @private
- */
- onAfterContextMenuShow() {
- const contextMenu = this.hot.getPlugin('contextMenu');
- const data = contextMenu.menu.hotMenu.getSourceData();
- // find position of 'copy' option.
- arrayEach(data, (item, index) => {
- if (item.key === 'copy') {
- let zeroClipboardInstance = new ZeroClipboard(contextMenu.menu.hotMenu.getCell(index, 0));
- zeroClipboardInstance.off();
- zeroClipboardInstance.on('copy', (event) => {
- let clipboard = event.clipboardData;
- clipboard.setData('text/plain', this.getCopyValue());
- this.hot.getSettings().outsideClickDeselects = this.outsideClickDeselectsCache;
- });
- return false;
- }
- });
- }
- /**
- * @private
- */
- removeCurrentClass() {
- const contextMenu = this.hot.getPlugin('contextMenu');
- if (!contextMenu.enabled) {
- return;
- }
- if (contextMenu.menu.isOpened()) {
- let 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
- */
- removeZeroClipboardClass() {
- const contextMenu = this.hot.getPlugin('contextMenu');
- if (!contextMenu.enabled) {
- return;
- }
- if (contextMenu.menu.isOpened()) {
- let element = contextMenu.menu.hotMenu.rootElement.querySelector('td.zeroclipboard-is-hover');
- if (element) {
- removeClass(element, 'zeroclipboard-is-hover');
- }
- }
- this.hot.getSettings().outsideClickDeselects = this.outsideClickDeselectsCache;
- }
- }
- registerPlugin('contextMenuCopyPaste', ContextMenuCopyPaste);
- export default ContextMenuCopyPaste;
|