229 lines
8.0 KiB
JavaScript
229 lines
8.0 KiB
JavaScript
(function (global, factory) {
|
|
if (typeof define === "function" && define.amd) {
|
|
define(['module', 'select'], factory);
|
|
} else if (typeof exports !== "undefined") {
|
|
factory(module, require('select'));
|
|
} else {
|
|
var mod = {
|
|
exports: {}
|
|
};
|
|
factory(mod, global.select);
|
|
global.clipboardAction = mod.exports;
|
|
}
|
|
})(this, function (module, _select) {
|
|
'use strict';
|
|
|
|
var _select2 = _interopRequireDefault(_select);
|
|
|
|
function _interopRequireDefault(obj) {
|
|
return obj && obj.__esModule ? obj : {
|
|
default: obj
|
|
};
|
|
}
|
|
|
|
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;
|
|
};
|
|
|
|
function _classCallCheck(instance, Constructor) {
|
|
if (!(instance instanceof Constructor)) {
|
|
throw new TypeError("Cannot call a class as a function");
|
|
}
|
|
}
|
|
|
|
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 ClipboardAction = function () {
|
|
/**
|
|
* @param {Object} options
|
|
*/
|
|
function ClipboardAction(options) {
|
|
_classCallCheck(this, ClipboardAction);
|
|
|
|
this.resolveOptions(options);
|
|
this.initSelection();
|
|
}
|
|
|
|
/**
|
|
* Defines base properties passed from constructor.
|
|
* @param {Object} options
|
|
*/
|
|
|
|
|
|
_createClass(ClipboardAction, [{
|
|
key: 'resolveOptions',
|
|
value: function resolveOptions() {
|
|
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
|
|
this.action = options.action;
|
|
this.container = options.container;
|
|
this.emitter = options.emitter;
|
|
this.target = options.target;
|
|
this.text = options.text;
|
|
this.trigger = options.trigger;
|
|
|
|
this.selectedText = '';
|
|
}
|
|
}, {
|
|
key: 'initSelection',
|
|
value: function initSelection() {
|
|
if (this.text) {
|
|
this.selectFake();
|
|
} else if (this.target) {
|
|
this.selectTarget();
|
|
}
|
|
}
|
|
}, {
|
|
key: 'selectFake',
|
|
value: function selectFake() {
|
|
var _this = this;
|
|
|
|
var isRTL = document.documentElement.getAttribute('dir') == 'rtl';
|
|
|
|
this.removeFake();
|
|
|
|
this.fakeHandlerCallback = function () {
|
|
return _this.removeFake();
|
|
};
|
|
this.fakeHandler = this.container.addEventListener('click', this.fakeHandlerCallback) || true;
|
|
|
|
this.fakeElem = document.createElement('textarea');
|
|
// Prevent zooming on iOS
|
|
this.fakeElem.style.fontSize = '12pt';
|
|
// Reset box model
|
|
this.fakeElem.style.border = '0';
|
|
this.fakeElem.style.padding = '0';
|
|
this.fakeElem.style.margin = '0';
|
|
// Move element out of screen horizontally
|
|
this.fakeElem.style.position = 'absolute';
|
|
this.fakeElem.style[isRTL ? 'right' : 'left'] = '-9999px';
|
|
// Move element to the same position vertically
|
|
var yPosition = window.pageYOffset || document.documentElement.scrollTop;
|
|
this.fakeElem.style.top = yPosition + 'px';
|
|
|
|
this.fakeElem.setAttribute('readonly', '');
|
|
this.fakeElem.value = this.text;
|
|
|
|
this.container.appendChild(this.fakeElem);
|
|
|
|
this.selectedText = (0, _select2.default)(this.fakeElem);
|
|
this.copyText();
|
|
}
|
|
}, {
|
|
key: 'removeFake',
|
|
value: function removeFake() {
|
|
if (this.fakeHandler) {
|
|
this.container.removeEventListener('click', this.fakeHandlerCallback);
|
|
this.fakeHandler = null;
|
|
this.fakeHandlerCallback = null;
|
|
}
|
|
|
|
if (this.fakeElem) {
|
|
this.container.removeChild(this.fakeElem);
|
|
this.fakeElem = null;
|
|
}
|
|
}
|
|
}, {
|
|
key: 'selectTarget',
|
|
value: function selectTarget() {
|
|
this.selectedText = (0, _select2.default)(this.target);
|
|
this.copyText();
|
|
}
|
|
}, {
|
|
key: 'copyText',
|
|
value: function copyText() {
|
|
var succeeded = void 0;
|
|
|
|
try {
|
|
succeeded = document.execCommand(this.action);
|
|
} catch (err) {
|
|
succeeded = false;
|
|
}
|
|
|
|
this.handleResult(succeeded);
|
|
}
|
|
}, {
|
|
key: 'handleResult',
|
|
value: function handleResult(succeeded) {
|
|
this.emitter.emit(succeeded ? 'success' : 'error', {
|
|
action: this.action,
|
|
text: this.selectedText,
|
|
trigger: this.trigger,
|
|
clearSelection: this.clearSelection.bind(this)
|
|
});
|
|
}
|
|
}, {
|
|
key: 'clearSelection',
|
|
value: function clearSelection() {
|
|
if (this.trigger) {
|
|
this.trigger.focus();
|
|
}
|
|
|
|
window.getSelection().removeAllRanges();
|
|
}
|
|
}, {
|
|
key: 'destroy',
|
|
value: function destroy() {
|
|
this.removeFake();
|
|
}
|
|
}, {
|
|
key: 'action',
|
|
set: function set() {
|
|
var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'copy';
|
|
|
|
this._action = action;
|
|
|
|
if (this._action !== 'copy' && this._action !== 'cut') {
|
|
throw new Error('Invalid "action" value, use either "copy" or "cut"');
|
|
}
|
|
},
|
|
get: function get() {
|
|
return this._action;
|
|
}
|
|
}, {
|
|
key: 'target',
|
|
set: function set(target) {
|
|
if (target !== undefined) {
|
|
if (target && (typeof target === 'undefined' ? 'undefined' : _typeof(target)) === 'object' && target.nodeType === 1) {
|
|
if (this.action === 'copy' && target.hasAttribute('disabled')) {
|
|
throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');
|
|
}
|
|
|
|
if (this.action === 'cut' && (target.hasAttribute('readonly') || target.hasAttribute('disabled'))) {
|
|
throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes');
|
|
}
|
|
|
|
this._target = target;
|
|
} else {
|
|
throw new Error('Invalid "target" value, use a valid Element');
|
|
}
|
|
}
|
|
},
|
|
get: function get() {
|
|
return this._target;
|
|
}
|
|
}]);
|
|
|
|
return ClipboardAction;
|
|
}();
|
|
|
|
module.exports = ClipboardAction;
|
|
}); |