clipboard.js 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973
  1. /*!
  2. * clipboard.js v2.0.6
  3. * https://clipboardjs.com/
  4. *
  5. * Licensed MIT © Zeno Rocha
  6. */
  7. (function webpackUniversalModuleDefinition(root, factory) {
  8. if(typeof exports === 'object' && typeof module === 'object')
  9. module.exports = factory();
  10. else if(typeof define === 'function' && define.amd)
  11. define([], factory);
  12. else if(typeof exports === 'object')
  13. exports["ClipboardJS"] = factory();
  14. else
  15. root["ClipboardJS"] = factory();
  16. })(this, function() {
  17. return /******/ (function(modules) { // webpackBootstrap
  18. /******/ // The module cache
  19. /******/ var installedModules = {};
  20. /******/
  21. /******/ // The require function
  22. /******/ function __webpack_require__(moduleId) {
  23. /******/
  24. /******/ // Check if module is in cache
  25. /******/ if(installedModules[moduleId]) {
  26. /******/ return installedModules[moduleId].exports;
  27. /******/ }
  28. /******/ // Create a new module (and put it into the cache)
  29. /******/ var module = installedModules[moduleId] = {
  30. /******/ i: moduleId,
  31. /******/ l: false,
  32. /******/ exports: {}
  33. /******/ };
  34. /******/
  35. /******/ // Execute the module function
  36. /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
  37. /******/
  38. /******/ // Flag the module as loaded
  39. /******/ module.l = true;
  40. /******/
  41. /******/ // Return the exports of the module
  42. /******/ return module.exports;
  43. /******/ }
  44. /******/
  45. /******/
  46. /******/ // expose the modules object (__webpack_modules__)
  47. /******/ __webpack_require__.m = modules;
  48. /******/
  49. /******/ // expose the module cache
  50. /******/ __webpack_require__.c = installedModules;
  51. /******/
  52. /******/ // define getter function for harmony exports
  53. /******/ __webpack_require__.d = function(exports, name, getter) {
  54. /******/ if(!__webpack_require__.o(exports, name)) {
  55. /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
  56. /******/ }
  57. /******/ };
  58. /******/
  59. /******/ // define __esModule on exports
  60. /******/ __webpack_require__.r = function(exports) {
  61. /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
  62. /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
  63. /******/ }
  64. /******/ Object.defineProperty(exports, '__esModule', { value: true });
  65. /******/ };
  66. /******/
  67. /******/ // create a fake namespace object
  68. /******/ // mode & 1: value is a module id, require it
  69. /******/ // mode & 2: merge all properties of value into the ns
  70. /******/ // mode & 4: return value when already ns object
  71. /******/ // mode & 8|1: behave like require
  72. /******/ __webpack_require__.t = function(value, mode) {
  73. /******/ if(mode & 1) value = __webpack_require__(value);
  74. /******/ if(mode & 8) return value;
  75. /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
  76. /******/ var ns = Object.create(null);
  77. /******/ __webpack_require__.r(ns);
  78. /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
  79. /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
  80. /******/ return ns;
  81. /******/ };
  82. /******/
  83. /******/ // getDefaultExport function for compatibility with non-harmony modules
  84. /******/ __webpack_require__.n = function(module) {
  85. /******/ var getter = module && module.__esModule ?
  86. /******/ function getDefault() { return module['default']; } :
  87. /******/ function getModuleExports() { return module; };
  88. /******/ __webpack_require__.d(getter, 'a', getter);
  89. /******/ return getter;
  90. /******/ };
  91. /******/
  92. /******/ // Object.prototype.hasOwnProperty.call
  93. /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
  94. /******/
  95. /******/ // __webpack_public_path__
  96. /******/ __webpack_require__.p = "";
  97. /******/
  98. /******/
  99. /******/ // Load entry module and return exports
  100. /******/ return __webpack_require__(__webpack_require__.s = 6);
  101. /******/ })
  102. /************************************************************************/
  103. /******/ ([
  104. /* 0 */
  105. /***/ (function(module, exports) {
  106. function select(element) {
  107. var selectedText;
  108. if (element.nodeName === 'SELECT') {
  109. element.focus();
  110. selectedText = element.value;
  111. }
  112. else if (element.nodeName === 'INPUT' || element.nodeName === 'TEXTAREA') {
  113. var isReadOnly = element.hasAttribute('readonly');
  114. if (!isReadOnly) {
  115. element.setAttribute('readonly', '');
  116. }
  117. element.select();
  118. element.setSelectionRange(0, element.value.length);
  119. if (!isReadOnly) {
  120. element.removeAttribute('readonly');
  121. }
  122. selectedText = element.value;
  123. }
  124. else {
  125. if (element.hasAttribute('contenteditable')) {
  126. element.focus();
  127. }
  128. var selection = window.getSelection();
  129. var range = document.createRange();
  130. range.selectNodeContents(element);
  131. selection.removeAllRanges();
  132. selection.addRange(range);
  133. selectedText = selection.toString();
  134. }
  135. return selectedText;
  136. }
  137. module.exports = select;
  138. /***/ }),
  139. /* 1 */
  140. /***/ (function(module, exports) {
  141. function E () {
  142. // Keep this empty so it's easier to inherit from
  143. // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)
  144. }
  145. E.prototype = {
  146. on: function (name, callback, ctx) {
  147. var e = this.e || (this.e = {});
  148. (e[name] || (e[name] = [])).push({
  149. fn: callback,
  150. ctx: ctx
  151. });
  152. return this;
  153. },
  154. once: function (name, callback, ctx) {
  155. var self = this;
  156. function listener () {
  157. self.off(name, listener);
  158. callback.apply(ctx, arguments);
  159. };
  160. listener._ = callback
  161. return this.on(name, listener, ctx);
  162. },
  163. emit: function (name) {
  164. var data = [].slice.call(arguments, 1);
  165. var evtArr = ((this.e || (this.e = {}))[name] || []).slice();
  166. var i = 0;
  167. var len = evtArr.length;
  168. for (i; i < len; i++) {
  169. evtArr[i].fn.apply(evtArr[i].ctx, data);
  170. }
  171. return this;
  172. },
  173. off: function (name, callback) {
  174. var e = this.e || (this.e = {});
  175. var evts = e[name];
  176. var liveEvents = [];
  177. if (evts && callback) {
  178. for (var i = 0, len = evts.length; i < len; i++) {
  179. if (evts[i].fn !== callback && evts[i].fn._ !== callback)
  180. liveEvents.push(evts[i]);
  181. }
  182. }
  183. // Remove event from queue to prevent memory leak
  184. // Suggested by https://github.com/lazd
  185. // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910
  186. (liveEvents.length)
  187. ? e[name] = liveEvents
  188. : delete e[name];
  189. return this;
  190. }
  191. };
  192. module.exports = E;
  193. module.exports.TinyEmitter = E;
  194. /***/ }),
  195. /* 2 */
  196. /***/ (function(module, exports, __webpack_require__) {
  197. var is = __webpack_require__(3);
  198. var delegate = __webpack_require__(4);
  199. /**
  200. * Validates all params and calls the right
  201. * listener function based on its target type.
  202. *
  203. * @param {String|HTMLElement|HTMLCollection|NodeList} target
  204. * @param {String} type
  205. * @param {Function} callback
  206. * @return {Object}
  207. */
  208. function listen(target, type, callback) {
  209. if (!target && !type && !callback) {
  210. throw new Error('Missing required arguments');
  211. }
  212. if (!is.string(type)) {
  213. throw new TypeError('Second argument must be a String');
  214. }
  215. if (!is.fn(callback)) {
  216. throw new TypeError('Third argument must be a Function');
  217. }
  218. if (is.node(target)) {
  219. return listenNode(target, type, callback);
  220. }
  221. else if (is.nodeList(target)) {
  222. return listenNodeList(target, type, callback);
  223. }
  224. else if (is.string(target)) {
  225. return listenSelector(target, type, callback);
  226. }
  227. else {
  228. throw new TypeError('First argument must be a String, HTMLElement, HTMLCollection, or NodeList');
  229. }
  230. }
  231. /**
  232. * Adds an event listener to a HTML element
  233. * and returns a remove listener function.
  234. *
  235. * @param {HTMLElement} node
  236. * @param {String} type
  237. * @param {Function} callback
  238. * @return {Object}
  239. */
  240. function listenNode(node, type, callback) {
  241. node.addEventListener(type, callback);
  242. return {
  243. destroy: function() {
  244. node.removeEventListener(type, callback);
  245. }
  246. }
  247. }
  248. /**
  249. * Add an event listener to a list of HTML elements
  250. * and returns a remove listener function.
  251. *
  252. * @param {NodeList|HTMLCollection} nodeList
  253. * @param {String} type
  254. * @param {Function} callback
  255. * @return {Object}
  256. */
  257. function listenNodeList(nodeList, type, callback) {
  258. Array.prototype.forEach.call(nodeList, function(node) {
  259. node.addEventListener(type, callback);
  260. });
  261. return {
  262. destroy: function() {
  263. Array.prototype.forEach.call(nodeList, function(node) {
  264. node.removeEventListener(type, callback);
  265. });
  266. }
  267. }
  268. }
  269. /**
  270. * Add an event listener to a selector
  271. * and returns a remove listener function.
  272. *
  273. * @param {String} selector
  274. * @param {String} type
  275. * @param {Function} callback
  276. * @return {Object}
  277. */
  278. function listenSelector(selector, type, callback) {
  279. return delegate(document.body, selector, type, callback);
  280. }
  281. module.exports = listen;
  282. /***/ }),
  283. /* 3 */
  284. /***/ (function(module, exports) {
  285. /**
  286. * Check if argument is a HTML element.
  287. *
  288. * @param {Object} value
  289. * @return {Boolean}
  290. */
  291. exports.node = function(value) {
  292. return value !== undefined
  293. && value instanceof HTMLElement
  294. && value.nodeType === 1;
  295. };
  296. /**
  297. * Check if argument is a list of HTML elements.
  298. *
  299. * @param {Object} value
  300. * @return {Boolean}
  301. */
  302. exports.nodeList = function(value) {
  303. var type = Object.prototype.toString.call(value);
  304. return value !== undefined
  305. && (type === '[object NodeList]' || type === '[object HTMLCollection]')
  306. && ('length' in value)
  307. && (value.length === 0 || exports.node(value[0]));
  308. };
  309. /**
  310. * Check if argument is a string.
  311. *
  312. * @param {Object} value
  313. * @return {Boolean}
  314. */
  315. exports.string = function(value) {
  316. return typeof value === 'string'
  317. || value instanceof String;
  318. };
  319. /**
  320. * Check if argument is a function.
  321. *
  322. * @param {Object} value
  323. * @return {Boolean}
  324. */
  325. exports.fn = function(value) {
  326. var type = Object.prototype.toString.call(value);
  327. return type === '[object Function]';
  328. };
  329. /***/ }),
  330. /* 4 */
  331. /***/ (function(module, exports, __webpack_require__) {
  332. var closest = __webpack_require__(5);
  333. /**
  334. * Delegates event to a selector.
  335. *
  336. * @param {Element} element
  337. * @param {String} selector
  338. * @param {String} type
  339. * @param {Function} callback
  340. * @param {Boolean} useCapture
  341. * @return {Object}
  342. */
  343. function _delegate(element, selector, type, callback, useCapture) {
  344. var listenerFn = listener.apply(this, arguments);
  345. element.addEventListener(type, listenerFn, useCapture);
  346. return {
  347. destroy: function() {
  348. element.removeEventListener(type, listenerFn, useCapture);
  349. }
  350. }
  351. }
  352. /**
  353. * Delegates event to a selector.
  354. *
  355. * @param {Element|String|Array} [elements]
  356. * @param {String} selector
  357. * @param {String} type
  358. * @param {Function} callback
  359. * @param {Boolean} useCapture
  360. * @return {Object}
  361. */
  362. function delegate(elements, selector, type, callback, useCapture) {
  363. // Handle the regular Element usage
  364. if (typeof elements.addEventListener === 'function') {
  365. return _delegate.apply(null, arguments);
  366. }
  367. // Handle Element-less usage, it defaults to global delegation
  368. if (typeof type === 'function') {
  369. // Use `document` as the first parameter, then apply arguments
  370. // This is a short way to .unshift `arguments` without running into deoptimizations
  371. return _delegate.bind(null, document).apply(null, arguments);
  372. }
  373. // Handle Selector-based usage
  374. if (typeof elements === 'string') {
  375. elements = document.querySelectorAll(elements);
  376. }
  377. // Handle Array-like based usage
  378. return Array.prototype.map.call(elements, function (element) {
  379. return _delegate(element, selector, type, callback, useCapture);
  380. });
  381. }
  382. /**
  383. * Finds closest match and invokes callback.
  384. *
  385. * @param {Element} element
  386. * @param {String} selector
  387. * @param {String} type
  388. * @param {Function} callback
  389. * @return {Function}
  390. */
  391. function listener(element, selector, type, callback) {
  392. return function(e) {
  393. e.delegateTarget = closest(e.target, selector);
  394. if (e.delegateTarget) {
  395. callback.call(element, e);
  396. }
  397. }
  398. }
  399. module.exports = delegate;
  400. /***/ }),
  401. /* 5 */
  402. /***/ (function(module, exports) {
  403. var DOCUMENT_NODE_TYPE = 9;
  404. /**
  405. * A polyfill for Element.matches()
  406. */
  407. if (typeof Element !== 'undefined' && !Element.prototype.matches) {
  408. var proto = Element.prototype;
  409. proto.matches = proto.matchesSelector ||
  410. proto.mozMatchesSelector ||
  411. proto.msMatchesSelector ||
  412. proto.oMatchesSelector ||
  413. proto.webkitMatchesSelector;
  414. }
  415. /**
  416. * Finds the closest parent that matches a selector.
  417. *
  418. * @param {Element} element
  419. * @param {String} selector
  420. * @return {Function}
  421. */
  422. function closest (element, selector) {
  423. while (element && element.nodeType !== DOCUMENT_NODE_TYPE) {
  424. if (typeof element.matches === 'function' &&
  425. element.matches(selector)) {
  426. return element;
  427. }
  428. element = element.parentNode;
  429. }
  430. }
  431. module.exports = closest;
  432. /***/ }),
  433. /* 6 */
  434. /***/ (function(module, __webpack_exports__, __webpack_require__) {
  435. "use strict";
  436. __webpack_require__.r(__webpack_exports__);
  437. // EXTERNAL MODULE: ./node_modules/select/src/select.js
  438. var src_select = __webpack_require__(0);
  439. var select_default = /*#__PURE__*/__webpack_require__.n(src_select);
  440. // CONCATENATED MODULE: ./src/clipboard-action.js
  441. 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; };
  442. 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; }; }();
  443. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  444. /**
  445. * Inner class which performs selection from either `text` or `target`
  446. * properties and then executes copy or cut operations.
  447. */
  448. var clipboard_action_ClipboardAction = function () {
  449. /**
  450. * @param {Object} options
  451. */
  452. function ClipboardAction(options) {
  453. _classCallCheck(this, ClipboardAction);
  454. this.resolveOptions(options);
  455. this.initSelection();
  456. }
  457. /**
  458. * Defines base properties passed from constructor.
  459. * @param {Object} options
  460. */
  461. _createClass(ClipboardAction, [{
  462. key: 'resolveOptions',
  463. value: function resolveOptions() {
  464. var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  465. this.action = options.action;
  466. this.container = options.container;
  467. this.emitter = options.emitter;
  468. this.target = options.target;
  469. this.text = options.text;
  470. this.trigger = options.trigger;
  471. this.selectedText = '';
  472. }
  473. /**
  474. * Decides which selection strategy is going to be applied based
  475. * on the existence of `text` and `target` properties.
  476. */
  477. }, {
  478. key: 'initSelection',
  479. value: function initSelection() {
  480. if (this.text) {
  481. this.selectFake();
  482. } else if (this.target) {
  483. this.selectTarget();
  484. }
  485. }
  486. /**
  487. * Creates a fake textarea element, sets its value from `text` property,
  488. * and makes a selection on it.
  489. */
  490. }, {
  491. key: 'selectFake',
  492. value: function selectFake() {
  493. var _this = this;
  494. var isRTL = document.documentElement.getAttribute('dir') == 'rtl';
  495. this.removeFake();
  496. this.fakeHandlerCallback = function () {
  497. return _this.removeFake();
  498. };
  499. this.fakeHandler = this.container.addEventListener('click', this.fakeHandlerCallback) || true;
  500. this.fakeElem = document.createElement('textarea');
  501. // Prevent zooming on iOS
  502. this.fakeElem.style.fontSize = '12pt';
  503. // Reset box model
  504. this.fakeElem.style.border = '0';
  505. this.fakeElem.style.padding = '0';
  506. this.fakeElem.style.margin = '0';
  507. // Move element out of screen horizontally
  508. this.fakeElem.style.position = 'absolute';
  509. this.fakeElem.style[isRTL ? 'right' : 'left'] = '-9999px';
  510. // Move element to the same position vertically
  511. var yPosition = window.pageYOffset || document.documentElement.scrollTop;
  512. this.fakeElem.style.top = yPosition + 'px';
  513. this.fakeElem.setAttribute('readonly', '');
  514. this.fakeElem.value = this.text;
  515. this.container.appendChild(this.fakeElem);
  516. this.selectedText = select_default()(this.fakeElem);
  517. this.copyText();
  518. }
  519. /**
  520. * Only removes the fake element after another click event, that way
  521. * a user can hit `Ctrl+C` to copy because selection still exists.
  522. */
  523. }, {
  524. key: 'removeFake',
  525. value: function removeFake() {
  526. if (this.fakeHandler) {
  527. this.container.removeEventListener('click', this.fakeHandlerCallback);
  528. this.fakeHandler = null;
  529. this.fakeHandlerCallback = null;
  530. }
  531. if (this.fakeElem) {
  532. this.container.removeChild(this.fakeElem);
  533. this.fakeElem = null;
  534. }
  535. }
  536. /**
  537. * Selects the content from element passed on `target` property.
  538. */
  539. }, {
  540. key: 'selectTarget',
  541. value: function selectTarget() {
  542. this.selectedText = select_default()(this.target);
  543. this.copyText();
  544. }
  545. /**
  546. * Executes the copy operation based on the current selection.
  547. */
  548. }, {
  549. key: 'copyText',
  550. value: function copyText() {
  551. var succeeded = void 0;
  552. try {
  553. succeeded = document.execCommand(this.action);
  554. } catch (err) {
  555. succeeded = false;
  556. }
  557. this.handleResult(succeeded);
  558. }
  559. /**
  560. * Fires an event based on the copy operation result.
  561. * @param {Boolean} succeeded
  562. */
  563. }, {
  564. key: 'handleResult',
  565. value: function handleResult(succeeded) {
  566. this.emitter.emit(succeeded ? 'success' : 'error', {
  567. action: this.action,
  568. text: this.selectedText,
  569. trigger: this.trigger,
  570. clearSelection: this.clearSelection.bind(this)
  571. });
  572. }
  573. /**
  574. * Moves focus away from `target` and back to the trigger, removes current selection.
  575. */
  576. }, {
  577. key: 'clearSelection',
  578. value: function clearSelection() {
  579. if (this.trigger) {
  580. this.trigger.focus();
  581. }
  582. document.activeElement.blur();
  583. window.getSelection().removeAllRanges();
  584. }
  585. /**
  586. * Sets the `action` to be performed which can be either 'copy' or 'cut'.
  587. * @param {String} action
  588. */
  589. }, {
  590. key: 'destroy',
  591. /**
  592. * Destroy lifecycle.
  593. */
  594. value: function destroy() {
  595. this.removeFake();
  596. }
  597. }, {
  598. key: 'action',
  599. set: function set() {
  600. var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'copy';
  601. this._action = action;
  602. if (this._action !== 'copy' && this._action !== 'cut') {
  603. throw new Error('Invalid "action" value, use either "copy" or "cut"');
  604. }
  605. }
  606. /**
  607. * Gets the `action` property.
  608. * @return {String}
  609. */
  610. ,
  611. get: function get() {
  612. return this._action;
  613. }
  614. /**
  615. * Sets the `target` property using an element
  616. * that will be have its content copied.
  617. * @param {Element} target
  618. */
  619. }, {
  620. key: 'target',
  621. set: function set(target) {
  622. if (target !== undefined) {
  623. if (target && (typeof target === 'undefined' ? 'undefined' : _typeof(target)) === 'object' && target.nodeType === 1) {
  624. if (this.action === 'copy' && target.hasAttribute('disabled')) {
  625. throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');
  626. }
  627. if (this.action === 'cut' && (target.hasAttribute('readonly') || target.hasAttribute('disabled'))) {
  628. throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes');
  629. }
  630. this._target = target;
  631. } else {
  632. throw new Error('Invalid "target" value, use a valid Element');
  633. }
  634. }
  635. }
  636. /**
  637. * Gets the `target` property.
  638. * @return {String|HTMLElement}
  639. */
  640. ,
  641. get: function get() {
  642. return this._target;
  643. }
  644. }]);
  645. return ClipboardAction;
  646. }();
  647. /* harmony default export */ var clipboard_action = (clipboard_action_ClipboardAction);
  648. // EXTERNAL MODULE: ./node_modules/tiny-emitter/index.js
  649. var tiny_emitter = __webpack_require__(1);
  650. var tiny_emitter_default = /*#__PURE__*/__webpack_require__.n(tiny_emitter);
  651. // EXTERNAL MODULE: ./node_modules/good-listener/src/listen.js
  652. var listen = __webpack_require__(2);
  653. var listen_default = /*#__PURE__*/__webpack_require__.n(listen);
  654. // CONCATENATED MODULE: ./src/clipboard.js
  655. var clipboard_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; };
  656. var clipboard_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; }; }();
  657. function clipboard_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  658. 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; }
  659. 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; }
  660. /**
  661. * Base class which takes one or more elements, adds event listeners to them,
  662. * and instantiates a new `ClipboardAction` on each click.
  663. */
  664. var clipboard_Clipboard = function (_Emitter) {
  665. _inherits(Clipboard, _Emitter);
  666. /**
  667. * @param {String|HTMLElement|HTMLCollection|NodeList} trigger
  668. * @param {Object} options
  669. */
  670. function Clipboard(trigger, options) {
  671. clipboard_classCallCheck(this, Clipboard);
  672. var _this = _possibleConstructorReturn(this, (Clipboard.__proto__ || Object.getPrototypeOf(Clipboard)).call(this));
  673. _this.resolveOptions(options);
  674. _this.listenClick(trigger);
  675. return _this;
  676. }
  677. /**
  678. * Defines if attributes would be resolved using internal setter functions
  679. * or custom functions that were passed in the constructor.
  680. * @param {Object} options
  681. */
  682. clipboard_createClass(Clipboard, [{
  683. key: 'resolveOptions',
  684. value: function resolveOptions() {
  685. var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  686. this.action = typeof options.action === 'function' ? options.action : this.defaultAction;
  687. this.target = typeof options.target === 'function' ? options.target : this.defaultTarget;
  688. this.text = typeof options.text === 'function' ? options.text : this.defaultText;
  689. this.container = clipboard_typeof(options.container) === 'object' ? options.container : document.body;
  690. }
  691. /**
  692. * Adds a click event listener to the passed trigger.
  693. * @param {String|HTMLElement|HTMLCollection|NodeList} trigger
  694. */
  695. }, {
  696. key: 'listenClick',
  697. value: function listenClick(trigger) {
  698. var _this2 = this;
  699. this.listener = listen_default()(trigger, 'click', function (e) {
  700. return _this2.onClick(e);
  701. });
  702. }
  703. /**
  704. * Defines a new `ClipboardAction` on each click event.
  705. * @param {Event} e
  706. */
  707. }, {
  708. key: 'onClick',
  709. value: function onClick(e) {
  710. var trigger = e.delegateTarget || e.currentTarget;
  711. if (this.clipboardAction) {
  712. this.clipboardAction = null;
  713. }
  714. this.clipboardAction = new clipboard_action({
  715. action: this.action(trigger),
  716. target: this.target(trigger),
  717. text: this.text(trigger),
  718. container: this.container,
  719. trigger: trigger,
  720. emitter: this
  721. });
  722. }
  723. /**
  724. * Default `action` lookup function.
  725. * @param {Element} trigger
  726. */
  727. }, {
  728. key: 'defaultAction',
  729. value: function defaultAction(trigger) {
  730. return getAttributeValue('action', trigger);
  731. }
  732. /**
  733. * Default `target` lookup function.
  734. * @param {Element} trigger
  735. */
  736. }, {
  737. key: 'defaultTarget',
  738. value: function defaultTarget(trigger) {
  739. var selector = getAttributeValue('target', trigger);
  740. if (selector) {
  741. return document.querySelector(selector);
  742. }
  743. }
  744. /**
  745. * Returns the support of the given action, or all actions if no action is
  746. * given.
  747. * @param {String} [action]
  748. */
  749. }, {
  750. key: 'defaultText',
  751. /**
  752. * Default `text` lookup function.
  753. * @param {Element} trigger
  754. */
  755. value: function defaultText(trigger) {
  756. return getAttributeValue('text', trigger);
  757. }
  758. /**
  759. * Destroy lifecycle.
  760. */
  761. }, {
  762. key: 'destroy',
  763. value: function destroy() {
  764. this.listener.destroy();
  765. if (this.clipboardAction) {
  766. this.clipboardAction.destroy();
  767. this.clipboardAction = null;
  768. }
  769. }
  770. }], [{
  771. key: 'isSupported',
  772. value: function isSupported() {
  773. var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['copy', 'cut'];
  774. var actions = typeof action === 'string' ? [action] : action;
  775. var support = !!document.queryCommandSupported;
  776. actions.forEach(function (action) {
  777. support = support && !!document.queryCommandSupported(action);
  778. });
  779. return support;
  780. }
  781. }]);
  782. return Clipboard;
  783. }(tiny_emitter_default.a);
  784. /**
  785. * Helper function to retrieve attribute value.
  786. * @param {String} suffix
  787. * @param {Element} element
  788. */
  789. function getAttributeValue(suffix, element) {
  790. var attribute = 'data-clipboard-' + suffix;
  791. if (!element.hasAttribute(attribute)) {
  792. return;
  793. }
  794. return element.getAttribute(attribute);
  795. }
  796. /* harmony default export */ var clipboard = __webpack_exports__["default"] = (clipboard_Clipboard);
  797. /***/ })
  798. /******/ ])["default"];
  799. });