[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-includes/js/ -> clipboard.js (source)

   1  /*!
   2   * clipboard.js v2.0.4
   3   * https://zenorocha.github.io/clipboard.js
   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 = 0);
 101  /******/ })
 102  /************************************************************************/
 103  /******/ ([
 104  /* 0 */
 105  /***/ (function(module, exports, __webpack_require__) {
 106  
 107  "use strict";
 108  
 109  
 110  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; };
 111  
 112  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; }; }();
 113  
 114  var _clipboardAction = __webpack_require__(1);
 115  
 116  var _clipboardAction2 = _interopRequireDefault(_clipboardAction);
 117  
 118  var _tinyEmitter = __webpack_require__(3);
 119  
 120  var _tinyEmitter2 = _interopRequireDefault(_tinyEmitter);
 121  
 122  var _goodListener = __webpack_require__(4);
 123  
 124  var _goodListener2 = _interopRequireDefault(_goodListener);
 125  
 126  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 127  
 128  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
 129  
 130  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; }
 131  
 132  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; }
 133  
 134  /**
 135   * Base class which takes one or more elements, adds event listeners to them,
 136   * and instantiates a new `ClipboardAction` on each click.
 137   */
 138  var Clipboard = function (_Emitter) {
 139      _inherits(Clipboard, _Emitter);
 140  
 141      /**
 142       * @param {String|HTMLElement|HTMLCollection|NodeList} trigger
 143       * @param {Object} options
 144       */
 145      function Clipboard(trigger, options) {
 146          _classCallCheck(this, Clipboard);
 147  
 148          var _this = _possibleConstructorReturn(this, (Clipboard.__proto__ || Object.getPrototypeOf(Clipboard)).call(this));
 149  
 150          _this.resolveOptions(options);
 151          _this.listenClick(trigger);
 152          return _this;
 153      }
 154  
 155      /**
 156       * Defines if attributes would be resolved using internal setter functions
 157       * or custom functions that were passed in the constructor.
 158       * @param {Object} options
 159       */
 160  
 161  
 162      _createClass(Clipboard, [{
 163          key: 'resolveOptions',
 164          value: function resolveOptions() {
 165              var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
 166  
 167              this.action = typeof options.action === 'function' ? options.action : this.defaultAction;
 168              this.target = typeof options.target === 'function' ? options.target : this.defaultTarget;
 169              this.text = typeof options.text === 'function' ? options.text : this.defaultText;
 170              this.container = _typeof(options.container) === 'object' ? options.container : document.body;
 171          }
 172  
 173          /**
 174           * Adds a click event listener to the passed trigger.
 175           * @param {String|HTMLElement|HTMLCollection|NodeList} trigger
 176           */
 177  
 178      }, {
 179          key: 'listenClick',
 180          value: function listenClick(trigger) {
 181              var _this2 = this;
 182  
 183              this.listener = (0, _goodListener2.default)(trigger, 'click', function (e) {
 184                  return _this2.onClick(e);
 185              });
 186          }
 187  
 188          /**
 189           * Defines a new `ClipboardAction` on each click event.
 190           * @param {Event} e
 191           */
 192  
 193      }, {
 194          key: 'onClick',
 195          value: function onClick(e) {
 196              var trigger = e.delegateTarget || e.currentTarget;
 197  
 198              if (this.clipboardAction) {
 199                  this.clipboardAction = null;
 200              }
 201  
 202              this.clipboardAction = new _clipboardAction2.default({
 203                  action: this.action(trigger),
 204                  target: this.target(trigger),
 205                  text: this.text(trigger),
 206                  container: this.container,
 207                  trigger: trigger,
 208                  emitter: this
 209              });
 210          }
 211  
 212          /**
 213           * Default `action` lookup function.
 214           * @param {Element} trigger
 215           */
 216  
 217      }, {
 218          key: 'defaultAction',
 219          value: function defaultAction(trigger) {
 220              return getAttributeValue('action', trigger);
 221          }
 222  
 223          /**
 224           * Default `target` lookup function.
 225           * @param {Element} trigger
 226           */
 227  
 228      }, {
 229          key: 'defaultTarget',
 230          value: function defaultTarget(trigger) {
 231              var selector = getAttributeValue('target', trigger);
 232  
 233              if (selector) {
 234                  return document.querySelector(selector);
 235              }
 236          }
 237  
 238          /**
 239           * Returns the support of the given action, or all actions if no action is
 240           * given.
 241           * @param {String} [action]
 242           */
 243  
 244      }, {
 245          key: 'defaultText',
 246  
 247  
 248          /**
 249           * Default `text` lookup function.
 250           * @param {Element} trigger
 251           */
 252          value: function defaultText(trigger) {
 253              return getAttributeValue('text', trigger);
 254          }
 255  
 256          /**
 257           * Destroy lifecycle.
 258           */
 259  
 260      }, {
 261          key: 'destroy',
 262          value: function destroy() {
 263              this.listener.destroy();
 264  
 265              if (this.clipboardAction) {
 266                  this.clipboardAction.destroy();
 267                  this.clipboardAction = null;
 268              }
 269          }
 270      }], [{
 271          key: 'isSupported',
 272          value: function isSupported() {
 273              var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['copy', 'cut'];
 274  
 275              var actions = typeof action === 'string' ? [action] : action;
 276              var support = !!document.queryCommandSupported;
 277  
 278              actions.forEach(function (action) {
 279                  support = support && !!document.queryCommandSupported(action);
 280              });
 281  
 282              return support;
 283          }
 284      }]);
 285  
 286      return Clipboard;
 287  }(_tinyEmitter2.default);
 288  
 289  /**
 290   * Helper function to retrieve attribute value.
 291   * @param {String} suffix
 292   * @param {Element} element
 293   */
 294  
 295  
 296  function getAttributeValue(suffix, element) {
 297      var attribute = 'data-clipboard-' + suffix;
 298  
 299      if (!element.hasAttribute(attribute)) {
 300          return;
 301      }
 302  
 303      return element.getAttribute(attribute);
 304  }
 305  
 306  module.exports = Clipboard;
 307  
 308  /***/ }),
 309  /* 1 */
 310  /***/ (function(module, exports, __webpack_require__) {
 311  
 312  "use strict";
 313  
 314  
 315  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; };
 316  
 317  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; }; }();
 318  
 319  var _select = __webpack_require__(2);
 320  
 321  var _select2 = _interopRequireDefault(_select);
 322  
 323  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 324  
 325  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
 326  
 327  /**
 328   * Inner class which performs selection from either `text` or `target`
 329   * properties and then executes copy or cut operations.
 330   */
 331  var ClipboardAction = function () {
 332      /**
 333       * @param {Object} options
 334       */
 335      function ClipboardAction(options) {
 336          _classCallCheck(this, ClipboardAction);
 337  
 338          this.resolveOptions(options);
 339          this.initSelection();
 340      }
 341  
 342      /**
 343       * Defines base properties passed from constructor.
 344       * @param {Object} options
 345       */
 346  
 347  
 348      _createClass(ClipboardAction, [{
 349          key: 'resolveOptions',
 350          value: function resolveOptions() {
 351              var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
 352  
 353              this.action = options.action;
 354              this.container = options.container;
 355              this.emitter = options.emitter;
 356              this.target = options.target;
 357              this.text = options.text;
 358              this.trigger = options.trigger;
 359  
 360              this.selectedText = '';
 361          }
 362  
 363          /**
 364           * Decides which selection strategy is going to be applied based
 365           * on the existence of `text` and `target` properties.
 366           */
 367  
 368      }, {
 369          key: 'initSelection',
 370          value: function initSelection() {
 371              if (this.text) {
 372                  this.selectFake();
 373              } else if (this.target) {
 374                  this.selectTarget();
 375              }
 376          }
 377  
 378          /**
 379           * Creates a fake textarea element, sets its value from `text` property,
 380           * and makes a selection on it.
 381           */
 382  
 383      }, {
 384          key: 'selectFake',
 385          value: function selectFake() {
 386              var _this = this;
 387  
 388              var isRTL = document.documentElement.getAttribute('dir') == 'rtl';
 389  
 390              this.removeFake();
 391  
 392              this.fakeHandlerCallback = function () {
 393                  return _this.removeFake();
 394              };
 395              this.fakeHandler = this.container.addEventListener('click', this.fakeHandlerCallback) || true;
 396  
 397              this.fakeElem = document.createElement('textarea');
 398              // Prevent zooming on iOS
 399              this.fakeElem.style.fontSize = '12pt';
 400              // Reset box model
 401              this.fakeElem.style.border = '0';
 402              this.fakeElem.style.padding = '0';
 403              this.fakeElem.style.margin = '0';
 404              // Move element out of screen horizontally
 405              this.fakeElem.style.position = 'absolute';
 406              this.fakeElem.style[isRTL ? 'right' : 'left'] = '-9999px';
 407              // Move element to the same position vertically
 408              var yPosition = window.pageYOffset || document.documentElement.scrollTop;
 409              this.fakeElem.style.top = yPosition + 'px';
 410  
 411              this.fakeElem.setAttribute('readonly', '');
 412              this.fakeElem.value = this.text;
 413  
 414              this.container.appendChild(this.fakeElem);
 415  
 416              this.selectedText = (0, _select2.default)(this.fakeElem);
 417              this.copyText();
 418          }
 419  
 420          /**
 421           * Only removes the fake element after another click event, that way
 422           * a user can hit `Ctrl+C` to copy because selection still exists.
 423           */
 424  
 425      }, {
 426          key: 'removeFake',
 427          value: function removeFake() {
 428              if (this.fakeHandler) {
 429                  this.container.removeEventListener('click', this.fakeHandlerCallback);
 430                  this.fakeHandler = null;
 431                  this.fakeHandlerCallback = null;
 432              }
 433  
 434              if (this.fakeElem) {
 435                  this.container.removeChild(this.fakeElem);
 436                  this.fakeElem = null;
 437              }
 438          }
 439  
 440          /**
 441           * Selects the content from element passed on `target` property.
 442           */
 443  
 444      }, {
 445          key: 'selectTarget',
 446          value: function selectTarget() {
 447              this.selectedText = (0, _select2.default)(this.target);
 448              this.copyText();
 449          }
 450  
 451          /**
 452           * Executes the copy operation based on the current selection.
 453           */
 454  
 455      }, {
 456          key: 'copyText',
 457          value: function copyText() {
 458              var succeeded = void 0;
 459  
 460              try {
 461                  succeeded = document.execCommand(this.action);
 462              } catch (err) {
 463                  succeeded = false;
 464              }
 465  
 466              this.handleResult(succeeded);
 467          }
 468  
 469          /**
 470           * Fires an event based on the copy operation result.
 471           * @param {Boolean} succeeded
 472           */
 473  
 474      }, {
 475          key: 'handleResult',
 476          value: function handleResult(succeeded) {
 477              this.emitter.emit(succeeded ? 'success' : 'error', {
 478                  action: this.action,
 479                  text: this.selectedText,
 480                  trigger: this.trigger,
 481                  clearSelection: this.clearSelection.bind(this)
 482              });
 483          }
 484  
 485          /**
 486           * Moves focus away from `target` and back to the trigger, removes current selection.
 487           */
 488  
 489      }, {
 490          key: 'clearSelection',
 491          value: function clearSelection() {
 492              if (this.trigger) {
 493                  this.trigger.focus();
 494              }
 495  
 496              window.getSelection().removeAllRanges();
 497          }
 498  
 499          /**
 500           * Sets the `action` to be performed which can be either 'copy' or 'cut'.
 501           * @param {String} action
 502           */
 503  
 504      }, {
 505          key: 'destroy',
 506  
 507  
 508          /**
 509           * Destroy lifecycle.
 510           */
 511          value: function destroy() {
 512              this.removeFake();
 513          }
 514      }, {
 515          key: 'action',
 516          set: function set() {
 517              var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'copy';
 518  
 519              this._action = action;
 520  
 521              if (this._action !== 'copy' && this._action !== 'cut') {
 522                  throw new Error('Invalid "action" value, use either "copy" or "cut"');
 523              }
 524          }
 525  
 526          /**
 527           * Gets the `action` property.
 528           * @return {String}
 529           */
 530          ,
 531          get: function get() {
 532              return this._action;
 533          }
 534  
 535          /**
 536           * Sets the `target` property using an element
 537           * that will be have its content copied.
 538           * @param {Element} target
 539           */
 540  
 541      }, {
 542          key: 'target',
 543          set: function set(target) {
 544              if (target !== undefined) {
 545                  if (target && (typeof target === 'undefined' ? 'undefined' : _typeof(target)) === 'object' && target.nodeType === 1) {
 546                      if (this.action === 'copy' && target.hasAttribute('disabled')) {
 547                          throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');
 548                      }
 549  
 550                      if (this.action === 'cut' && (target.hasAttribute('readonly') || target.hasAttribute('disabled'))) {
 551                          throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes');
 552                      }
 553  
 554                      this._target = target;
 555                  } else {
 556                      throw new Error('Invalid "target" value, use a valid Element');
 557                  }
 558              }
 559          }
 560  
 561          /**
 562           * Gets the `target` property.
 563           * @return {String|HTMLElement}
 564           */
 565          ,
 566          get: function get() {
 567              return this._target;
 568          }
 569      }]);
 570  
 571      return ClipboardAction;
 572  }();
 573  
 574  module.exports = ClipboardAction;
 575  
 576  /***/ }),
 577  /* 2 */
 578  /***/ (function(module, exports) {
 579  
 580  function select(element) {
 581      var selectedText;
 582  
 583      if (element.nodeName === 'SELECT') {
 584          element.focus();
 585  
 586          selectedText = element.value;
 587      }
 588      else if (element.nodeName === 'INPUT' || element.nodeName === 'TEXTAREA') {
 589          var isReadOnly = element.hasAttribute('readonly');
 590  
 591          if (!isReadOnly) {
 592              element.setAttribute('readonly', '');
 593          }
 594  
 595          element.select();
 596          element.setSelectionRange(0, element.value.length);
 597  
 598          if (!isReadOnly) {
 599              element.removeAttribute('readonly');
 600          }
 601  
 602          selectedText = element.value;
 603      }
 604      else {
 605          if (element.hasAttribute('contenteditable')) {
 606              element.focus();
 607          }
 608  
 609          var selection = window.getSelection();
 610          var range = document.createRange();
 611  
 612          range.selectNodeContents(element);
 613          selection.removeAllRanges();
 614          selection.addRange(range);
 615  
 616          selectedText = selection.toString();
 617      }
 618  
 619      return selectedText;
 620  }
 621  
 622  module.exports = select;
 623  
 624  
 625  /***/ }),
 626  /* 3 */
 627  /***/ (function(module, exports) {
 628  
 629  function E () {
 630    // Keep this empty so it's easier to inherit from
 631    // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)
 632  }
 633  
 634  E.prototype = {
 635    on: function (name, callback, ctx) {
 636      var e = this.e || (this.e = {});
 637  
 638      (e[name] || (e[name] = [])).push({
 639        fn: callback,
 640        ctx: ctx
 641      });
 642  
 643      return this;
 644    },
 645  
 646    once: function (name, callback, ctx) {
 647      var self = this;
 648      function listener () {
 649        self.off(name, listener);
 650        callback.apply(ctx, arguments);
 651      };
 652  
 653      listener._ = callback
 654      return this.on(name, listener, ctx);
 655    },
 656  
 657    emit: function (name) {
 658      var data = [].slice.call(arguments, 1);
 659      var evtArr = ((this.e || (this.e = {}))[name] || []).slice();
 660      var i = 0;
 661      var len = evtArr.length;
 662  
 663      for (i; i < len; i++) {
 664        evtArr[i].fn.apply(evtArr[i].ctx, data);
 665      }
 666  
 667      return this;
 668    },
 669  
 670    off: function (name, callback) {
 671      var e = this.e || (this.e = {});
 672      var evts = e[name];
 673      var liveEvents = [];
 674  
 675      if (evts && callback) {
 676        for (var i = 0, len = evts.length; i < len; i++) {
 677          if (evts[i].fn !== callback && evts[i].fn._ !== callback)
 678            liveEvents.push(evts[i]);
 679        }
 680      }
 681  
 682      // Remove event from queue to prevent memory leak
 683      // Suggested by https://github.com/lazd
 684      // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910
 685  
 686      (liveEvents.length)
 687        ? e[name] = liveEvents
 688        : delete e[name];
 689  
 690      return this;
 691    }
 692  };
 693  
 694  module.exports = E;
 695  
 696  
 697  /***/ }),
 698  /* 4 */
 699  /***/ (function(module, exports, __webpack_require__) {
 700  
 701  var is = __webpack_require__(5);
 702  var delegate = __webpack_require__(6);
 703  
 704  /**
 705   * Validates all params and calls the right
 706   * listener function based on its target type.
 707   *
 708   * @param {String|HTMLElement|HTMLCollection|NodeList} target
 709   * @param {String} type
 710   * @param {Function} callback
 711   * @return {Object}
 712   */
 713  function listen(target, type, callback) {
 714      if (!target && !type && !callback) {
 715          throw new Error('Missing required arguments');
 716      }
 717  
 718      if (!is.string(type)) {
 719          throw new TypeError('Second argument must be a String');
 720      }
 721  
 722      if (!is.fn(callback)) {
 723          throw new TypeError('Third argument must be a Function');
 724      }
 725  
 726      if (is.node(target)) {
 727          return listenNode(target, type, callback);
 728      }
 729      else if (is.nodeList(target)) {
 730          return listenNodeList(target, type, callback);
 731      }
 732      else if (is.string(target)) {
 733          return listenSelector(target, type, callback);
 734      }
 735      else {
 736          throw new TypeError('First argument must be a String, HTMLElement, HTMLCollection, or NodeList');
 737      }
 738  }
 739  
 740  /**
 741   * Adds an event listener to a HTML element
 742   * and returns a remove listener function.
 743   *
 744   * @param {HTMLElement} node
 745   * @param {String} type
 746   * @param {Function} callback
 747   * @return {Object}
 748   */
 749  function listenNode(node, type, callback) {
 750      node.addEventListener(type, callback);
 751  
 752      return {
 753          destroy: function() {
 754              node.removeEventListener(type, callback);
 755          }
 756      }
 757  }
 758  
 759  /**
 760   * Add an event listener to a list of HTML elements
 761   * and returns a remove listener function.
 762   *
 763   * @param {NodeList|HTMLCollection} nodeList
 764   * @param {String} type
 765   * @param {Function} callback
 766   * @return {Object}
 767   */
 768  function listenNodeList(nodeList, type, callback) {
 769      Array.prototype.forEach.call(nodeList, function(node) {
 770          node.addEventListener(type, callback);
 771      });
 772  
 773      return {
 774          destroy: function() {
 775              Array.prototype.forEach.call(nodeList, function(node) {
 776                  node.removeEventListener(type, callback);
 777              });
 778          }
 779      }
 780  }
 781  
 782  /**
 783   * Add an event listener to a selector
 784   * and returns a remove listener function.
 785   *
 786   * @param {String} selector
 787   * @param {String} type
 788   * @param {Function} callback
 789   * @return {Object}
 790   */
 791  function listenSelector(selector, type, callback) {
 792      return delegate(document.body, selector, type, callback);
 793  }
 794  
 795  module.exports = listen;
 796  
 797  
 798  /***/ }),
 799  /* 5 */
 800  /***/ (function(module, exports) {
 801  
 802  /**
 803   * Check if argument is a HTML element.
 804   *
 805   * @param {Object} value
 806   * @return {Boolean}
 807   */
 808  exports.node = function(value) {
 809      return value !== undefined
 810          && value instanceof HTMLElement
 811          && value.nodeType === 1;
 812  };
 813  
 814  /**
 815   * Check if argument is a list of HTML elements.
 816   *
 817   * @param {Object} value
 818   * @return {Boolean}
 819   */
 820  exports.nodeList = function(value) {
 821      var type = Object.prototype.toString.call(value);
 822  
 823      return value !== undefined
 824          && (type === '[object NodeList]' || type === '[object HTMLCollection]')
 825          && ('length' in value)
 826          && (value.length === 0 || exports.node(value[0]));
 827  };
 828  
 829  /**
 830   * Check if argument is a string.
 831   *
 832   * @param {Object} value
 833   * @return {Boolean}
 834   */
 835  exports.string = function(value) {
 836      return typeof value === 'string'
 837          || value instanceof String;
 838  };
 839  
 840  /**
 841   * Check if argument is a function.
 842   *
 843   * @param {Object} value
 844   * @return {Boolean}
 845   */
 846  exports.fn = function(value) {
 847      var type = Object.prototype.toString.call(value);
 848  
 849      return type === '[object Function]';
 850  };
 851  
 852  
 853  /***/ }),
 854  /* 6 */
 855  /***/ (function(module, exports, __webpack_require__) {
 856  
 857  var closest = __webpack_require__(7);
 858  
 859  /**
 860   * Delegates event to a selector.
 861   *
 862   * @param {Element} element
 863   * @param {String} selector
 864   * @param {String} type
 865   * @param {Function} callback
 866   * @param {Boolean} useCapture
 867   * @return {Object}
 868   */
 869  function _delegate(element, selector, type, callback, useCapture) {
 870      var listenerFn = listener.apply(this, arguments);
 871  
 872      element.addEventListener(type, listenerFn, useCapture);
 873  
 874      return {
 875          destroy: function() {
 876              element.removeEventListener(type, listenerFn, useCapture);
 877          }
 878      }
 879  }
 880  
 881  /**
 882   * Delegates event to a selector.
 883   *
 884   * @param {Element|String|Array} [elements]
 885   * @param {String} selector
 886   * @param {String} type
 887   * @param {Function} callback
 888   * @param {Boolean} useCapture
 889   * @return {Object}
 890   */
 891  function delegate(elements, selector, type, callback, useCapture) {
 892      // Handle the regular Element usage
 893      if (typeof elements.addEventListener === 'function') {
 894          return _delegate.apply(null, arguments);
 895      }
 896  
 897      // Handle Element-less usage, it defaults to global delegation
 898      if (typeof type === 'function') {
 899          // Use `document` as the first parameter, then apply arguments
 900          // This is a short way to .unshift `arguments` without running into deoptimizations
 901          return _delegate.bind(null, document).apply(null, arguments);
 902      }
 903  
 904      // Handle Selector-based usage
 905      if (typeof elements === 'string') {
 906          elements = document.querySelectorAll(elements);
 907      }
 908  
 909      // Handle Array-like based usage
 910      return Array.prototype.map.call(elements, function (element) {
 911          return _delegate(element, selector, type, callback, useCapture);
 912      });
 913  }
 914  
 915  /**
 916   * Finds closest match and invokes callback.
 917   *
 918   * @param {Element} element
 919   * @param {String} selector
 920   * @param {String} type
 921   * @param {Function} callback
 922   * @return {Function}
 923   */
 924  function listener(element, selector, type, callback) {
 925      return function(e) {
 926          e.delegateTarget = closest(e.target, selector);
 927  
 928          if (e.delegateTarget) {
 929              callback.call(element, e);
 930          }
 931      }
 932  }
 933  
 934  module.exports = delegate;
 935  
 936  
 937  /***/ }),
 938  /* 7 */
 939  /***/ (function(module, exports) {
 940  
 941  var DOCUMENT_NODE_TYPE = 9;
 942  
 943  /**
 944   * A polyfill for Element.matches()
 945   */
 946  if (typeof Element !== 'undefined' && !Element.prototype.matches) {
 947      var proto = Element.prototype;
 948  
 949      proto.matches = proto.matchesSelector ||
 950                      proto.mozMatchesSelector ||
 951                      proto.msMatchesSelector ||
 952                      proto.oMatchesSelector ||
 953                      proto.webkitMatchesSelector;
 954  }
 955  
 956  /**
 957   * Finds the closest parent that matches a selector.
 958   *
 959   * @param {Element} element
 960   * @param {String} selector
 961   * @return {Function}
 962   */
 963  function closest (element, selector) {
 964      while (element && element.nodeType !== DOCUMENT_NODE_TYPE) {
 965          if (typeof element.matches === 'function' &&
 966              element.matches(selector)) {
 967            return element;
 968          }
 969          element = element.parentNode;
 970      }
 971  }
 972  
 973  module.exports = closest;
 974  
 975  
 976  /***/ })
 977  /******/ ]);
 978  });


Generated : Fri May 29 08:20:01 2020 Cross-referenced by PHPXref