UNPKG

xl-infinite-tree

Version:

A browser-ready tree library that can efficiently display a large amount of data using infinite scrolling.

1,497 lines (1,211 loc) 136 kB
/*! xl-infinite-tree v1.14.14 | (c) 2020 Cheton Wu <cheton@gmail.com> | MIT | https://github.com/cheton/infinite-tree */ (function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if(typeof define === 'function' && define.amd) define([], factory); else if(typeof exports === 'object') exports["InfiniteTree"] = factory(); else root["InfiniteTree"] = factory(); })(typeof self !== 'undefined' ? self : this, function() { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { /******/ configurable: false, /******/ enumerable: true, /******/ get: getter /******/ }); /******/ } /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = 7); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. var R = typeof Reflect === 'object' ? Reflect : null var ReflectApply = R && typeof R.apply === 'function' ? R.apply : function ReflectApply(target, receiver, args) { return Function.prototype.apply.call(target, receiver, args); } var ReflectOwnKeys if (R && typeof R.ownKeys === 'function') { ReflectOwnKeys = R.ownKeys } else if (Object.getOwnPropertySymbols) { ReflectOwnKeys = function ReflectOwnKeys(target) { return Object.getOwnPropertyNames(target) .concat(Object.getOwnPropertySymbols(target)); }; } else { ReflectOwnKeys = function ReflectOwnKeys(target) { return Object.getOwnPropertyNames(target); }; } function ProcessEmitWarning(warning) { if (console && console.warn) console.warn(warning); } var NumberIsNaN = Number.isNaN || function NumberIsNaN(value) { return value !== value; } function EventEmitter() { EventEmitter.init.call(this); } module.exports = EventEmitter; // Backwards-compat with node 0.10.x EventEmitter.EventEmitter = EventEmitter; EventEmitter.prototype._events = undefined; EventEmitter.prototype._eventsCount = 0; EventEmitter.prototype._maxListeners = undefined; // By default EventEmitters will print a warning if more than 10 listeners are // added to it. This is a useful default which helps finding memory leaks. var defaultMaxListeners = 10; function checkListener(listener) { if (typeof listener !== 'function') { throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener); } } Object.defineProperty(EventEmitter, 'defaultMaxListeners', { enumerable: true, get: function() { return defaultMaxListeners; }, set: function(arg) { if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) { throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + arg + '.'); } defaultMaxListeners = arg; } }); EventEmitter.init = function() { if (this._events === undefined || this._events === Object.getPrototypeOf(this)._events) { this._events = Object.create(null); this._eventsCount = 0; } this._maxListeners = this._maxListeners || undefined; }; // Obviously not all Emitters should be limited to 10. This function allows // that to be increased. Set to zero for unlimited. EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) { if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) { throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received ' + n + '.'); } this._maxListeners = n; return this; }; function _getMaxListeners(that) { if (that._maxListeners === undefined) return EventEmitter.defaultMaxListeners; return that._maxListeners; } EventEmitter.prototype.getMaxListeners = function getMaxListeners() { return _getMaxListeners(this); }; EventEmitter.prototype.emit = function emit(type) { var args = []; for (var i = 1; i < arguments.length; i++) args.push(arguments[i]); var doError = (type === 'error'); var events = this._events; if (events !== undefined) doError = (doError && events.error === undefined); else if (!doError) return false; // If there is no 'error' event listener then throw. if (doError) { var er; if (args.length > 0) er = args[0]; if (er instanceof Error) { // Note: The comments on the `throw` lines are intentional, they show // up in Node's output if this results in an unhandled exception. throw er; // Unhandled 'error' event } // At least give some kind of context to the user var err = new Error('Unhandled error.' + (er ? ' (' + er.message + ')' : '')); err.context = er; throw err; // Unhandled 'error' event } var handler = events[type]; if (handler === undefined) return false; if (typeof handler === 'function') { ReflectApply(handler, this, args); } else { var len = handler.length; var listeners = arrayClone(handler, len); for (var i = 0; i < len; ++i) ReflectApply(listeners[i], this, args); } return true; }; function _addListener(target, type, listener, prepend) { var m; var events; var existing; checkListener(listener); events = target._events; if (events === undefined) { events = target._events = Object.create(null); target._eventsCount = 0; } else { // To avoid recursion in the case that type === "newListener"! Before // adding it to the listeners, first emit "newListener". if (events.newListener !== undefined) { target.emit('newListener', type, listener.listener ? listener.listener : listener); // Re-assign `events` because a newListener handler could have caused the // this._events to be assigned to a new object events = target._events; } existing = events[type]; } if (existing === undefined) { // Optimize the case of one listener. Don't need the extra array object. existing = events[type] = listener; ++target._eventsCount; } else { if (typeof existing === 'function') { // Adding the second element, need to change to array. existing = events[type] = prepend ? [listener, existing] : [existing, listener]; // If we've already got an array, just append. } else if (prepend) { existing.unshift(listener); } else { existing.push(listener); } // Check for listener leak m = _getMaxListeners(target); if (m > 0 && existing.length > m && !existing.warned) { existing.warned = true; // No error code for this since it is a Warning // eslint-disable-next-line no-restricted-syntax var w = new Error('Possible EventEmitter memory leak detected. ' + existing.length + ' ' + String(type) + ' listeners ' + 'added. Use emitter.setMaxListeners() to ' + 'increase limit'); w.name = 'MaxListenersExceededWarning'; w.emitter = target; w.type = type; w.count = existing.length; ProcessEmitWarning(w); } } return target; } EventEmitter.prototype.addListener = function addListener(type, listener) { return _addListener(this, type, listener, false); }; EventEmitter.prototype.on = EventEmitter.prototype.addListener; EventEmitter.prototype.prependListener = function prependListener(type, listener) { return _addListener(this, type, listener, true); }; function onceWrapper() { if (!this.fired) { this.target.removeListener(this.type, this.wrapFn); this.fired = true; if (arguments.length === 0) return this.listener.call(this.target); return this.listener.apply(this.target, arguments); } } function _onceWrap(target, type, listener) { var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener }; var wrapped = onceWrapper.bind(state); wrapped.listener = listener; state.wrapFn = wrapped; return wrapped; } EventEmitter.prototype.once = function once(type, listener) { checkListener(listener); this.on(type, _onceWrap(this, type, listener)); return this; }; EventEmitter.prototype.prependOnceListener = function prependOnceListener(type, listener) { checkListener(listener); this.prependListener(type, _onceWrap(this, type, listener)); return this; }; // Emits a 'removeListener' event if and only if the listener was removed. EventEmitter.prototype.removeListener = function removeListener(type, listener) { var list, events, position, i, originalListener; checkListener(listener); events = this._events; if (events === undefined) return this; list = events[type]; if (list === undefined) return this; if (list === listener || list.listener === listener) { if (--this._eventsCount === 0) this._events = Object.create(null); else { delete events[type]; if (events.removeListener) this.emit('removeListener', type, list.listener || listener); } } else if (typeof list !== 'function') { position = -1; for (i = list.length - 1; i >= 0; i--) { if (list[i] === listener || list[i].listener === listener) { originalListener = list[i].listener; position = i; break; } } if (position < 0) return this; if (position === 0) list.shift(); else { spliceOne(list, position); } if (list.length === 1) events[type] = list[0]; if (events.removeListener !== undefined) this.emit('removeListener', type, originalListener || listener); } return this; }; EventEmitter.prototype.off = EventEmitter.prototype.removeListener; EventEmitter.prototype.removeAllListeners = function removeAllListeners(type) { var listeners, events, i; events = this._events; if (events === undefined) return this; // not listening for removeListener, no need to emit if (events.removeListener === undefined) { if (arguments.length === 0) { this._events = Object.create(null); this._eventsCount = 0; } else if (events[type] !== undefined) { if (--this._eventsCount === 0) this._events = Object.create(null); else delete events[type]; } return this; } // emit removeListener for all listeners on all events if (arguments.length === 0) { var keys = Object.keys(events); var key; for (i = 0; i < keys.length; ++i) { key = keys[i]; if (key === 'removeListener') continue; this.removeAllListeners(key); } this.removeAllListeners('removeListener'); this._events = Object.create(null); this._eventsCount = 0; return this; } listeners = events[type]; if (typeof listeners === 'function') { this.removeListener(type, listeners); } else if (listeners !== undefined) { // LIFO order for (i = listeners.length - 1; i >= 0; i--) { this.removeListener(type, listeners[i]); } } return this; }; function _listeners(target, type, unwrap) { var events = target._events; if (events === undefined) return []; var evlistener = events[type]; if (evlistener === undefined) return []; if (typeof evlistener === 'function') return unwrap ? [evlistener.listener || evlistener] : [evlistener]; return unwrap ? unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length); } EventEmitter.prototype.listeners = function listeners(type) { return _listeners(this, type, true); }; EventEmitter.prototype.rawListeners = function rawListeners(type) { return _listeners(this, type, false); }; EventEmitter.listenerCount = function(emitter, type) { if (typeof emitter.listenerCount === 'function') { return emitter.listenerCount(type); } else { return listenerCount.call(emitter, type); } }; EventEmitter.prototype.listenerCount = listenerCount; function listenerCount(type) { var events = this._events; if (events !== undefined) { var evlistener = events[type]; if (typeof evlistener === 'function') { return 1; } else if (evlistener !== undefined) { return evlistener.length; } } return 0; } EventEmitter.prototype.eventNames = function eventNames() { return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : []; }; function arrayClone(arr, n) { var copy = new Array(n); for (var i = 0; i < n; ++i) copy[i] = arr[i]; return copy; } function spliceOne(list, index) { for (; index + 1 < list.length; index++) list[index] = list[index + 1]; list.pop(); } function unwrapListeners(arr) { var ret = new Array(arr.length); for (var i = 0; i < ret.length; ++i) { ret[i] = arr[i].listener || arr[i]; } return ret; } /***/ }), /* 1 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! Copyright (c) 2017 Jed Watson. Licensed under the MIT License (MIT), see http://jedwatson.github.io/classnames */ /* global define */ (function () { 'use strict'; var hasOwn = {}.hasOwnProperty; function classNames () { var classes = []; for (var i = 0; i < arguments.length; i++) { var arg = arguments[i]; if (!arg) continue; var argType = typeof arg; if (argType === 'string' || argType === 'number') { classes.push(arg); } else if (Array.isArray(arg) && arg.length) { var inner = classNames.apply(null, arg); if (inner) { classes.push(inner); } } else if (argType === 'object') { for (var key in arg) { if (hasOwn.call(arg, key) && arg[key]) { classes.push(key); } } } } return classes.join(' '); } if (typeof module !== 'undefined' && module.exports) { classNames.default = classNames; module.exports = classNames; } else if (true) { // register as 'classnames', consistent with npm package name !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = (function () { return classNames; }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); } else { window.classNames = classNames; } }()); /***/ }), /* 2 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; exports.__esModule = true; /* eslint no-restricted-syntax: 0 */ var extend = function extend(target) { for (var _len = arguments.length, sources = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { sources[_key - 1] = arguments[_key]; } if (target === undefined || target === null) { throw new TypeError('Cannot convert undefined or null to object'); } var output = Object(target); for (var index = 0; index < sources.length; index++) { var source = sources[index]; if (source !== undefined && source !== null) { for (var key in source) { if (source.hasOwnProperty(key)) { output[key] = source[key]; } } } } return output; }; exports['default'] = extend; /***/ }), /* 3 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; exports.__esModule = true; var _extend = __webpack_require__(2); var _extend2 = _interopRequireDefault(_extend); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var Node = function () { function Node(node) { _classCallCheck(this, Node); this.id = null; this.parent = null; this.children = []; this.state = {}; (0, _extend2['default'])(this, node); this.children = this.children || []; } // Returns a boolean value indicating whether a node is a descendant of a given node or not. // @param {object} node Specifies the node that may be contained by (a descendant of) a specified node. // @return {boolean} Returns true if a node is a descendant of a specified node, otherwise false. A descendant can be a child, grandchild, great-grandchild, and so on. Node.prototype.contains = function contains(node) { while (node instanceof Node && node !== this) { if (node.parent === this) { return true; } node = node.parent; } return false; }; // Gets a child node at the specified index. // @param {number} The index of the child node. // @return {object} Returns an object that defines the node, null otherwise. Node.prototype.getChildAt = function getChildAt(index) { var node = null; if (this.children.length > 0 && index >= 0 && index < this.children.length) { node = this.children[index]; } return node; }; // Gets the child nodes. // @return {array} Returns an array of objects that define the nodes. Node.prototype.getChildren = function getChildren() { return this.children; }; // Gets the first child node. // @return {object} Returns an object that defines the node, null otherwise. Node.prototype.getFirstChild = function getFirstChild() { var node = null; if (this.children.length > 0) { node = this.children[0]; } return node; }; // Gets the last child node. // @return {object} Returns an object that defines the node, null otherwise. Node.prototype.getLastChild = function getLastChild() { var node = null; if (this.children.length > 0) { node = this.children[this.children.length - 1]; } return node; }; // Gets the next sibling node. // @return {object} Returns an object that defines the node, null otherwise. Node.prototype.getNextSibling = function getNextSibling() { var node = null; if (this.parent) { var index = this.parent.children.indexOf(this); if (index >= 0 && index < this.parent.children.length - 1) { node = this.parent.children[index + 1]; } } return node; }; // Gets the parent node. // @return {object} Returns an object that defines the node, null otherwise. Node.prototype.getParent = function getParent() { return this.parent; }; // Gets the previous sibling node. // @return {object} Returns an object that defines the node, null otherwise. Node.prototype.getPreviousSibling = function getPreviousSibling() { var node = null; if (this.parent) { var index = this.parent.children.indexOf(this); if (index > 0 && index < this.parent.children.length) { node = this.parent.children[index - 1]; } } return node; }; // Checks whether this node has children. // @return {boolean} Returns true if the node has children, false otherwise. Node.prototype.hasChildren = function hasChildren() { return this.children.length > 0; }; // Checks whether this node is the last child of its parent. // @return {boolean} Returns true if the node is the last child of its parent, false otherwise. Node.prototype.isLastChild = function isLastChild() { var hasNextSibling = this.getNextSibling(); return !hasNextSibling; }; return Node; }(); exports['default'] = Node; /***/ }), /* 4 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; exports.__esModule = true; var ensureArray = function ensureArray() { for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } if (args.length === 0 || args[0] === undefined || args[0] === null) { return []; } if (args.length === 1) { return [].concat(args[0]); } return [].concat(args); }; exports["default"] = ensureArray; /***/ }), /* 5 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; exports.__esModule = true; var getElementStyle = function getElementStyle(el, prop) { return window.getComputedStyle ? window.getComputedStyle(el)[prop] : el.currentStyle[prop]; }; var preventDefault = function preventDefault(e) { if (typeof e.preventDefault !== 'undefined') { e.preventDefault(); } else { e.returnValue = false; } }; var stopPropagation = function stopPropagation(e) { if (typeof e.stopPropagation !== 'undefined') { e.stopPropagation(); } else { e.cancelBubble = true; } }; // https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Compatibility var addEventListener = function addEventListener(target, type, listener) { if (target.addEventListener) { // Standard target.addEventListener(type, listener, false); } else if (target.attachEvent) { // IE8 // In Internet Explorer versions before IE 9, you have to use attachEvent rather than the standard addEventListener. target.attachEvent('on' + type, listener); } }; // https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener var removeEventListener = function removeEventListener(target, type, listener) { if (target.removeEventListener) { // Standard target.removeEventListener(type, listener, false); } else if (target.detachEvent) { // IE8 // In Internet Explorer versions before IE 9, you have to use detachEvent rather than the standard removeEventListener. target.detachEvent('on' + type, listener); } }; exports.getElementStyle = getElementStyle; exports.preventDefault = preventDefault; exports.stopPropagation = stopPropagation; exports.addEventListener = addEventListener; exports.removeEventListener = removeEventListener; /***/ }), /* 6 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /*! * escape-html * Copyright(c) 2012-2013 TJ Holowaychuk * Copyright(c) 2015 Andreas Lubbe * Copyright(c) 2015 Tiancheng "Timothy" Gu * MIT Licensed */ /** * Module variables. * @private */ var matchHtmlRegExp = /["'&<>]/; /** * Module exports. * @public */ module.exports = escapeHtml; /** * Escape special characters in the given string of html. * * @param {string} string The string to escape for inserting into HTML * @return {string} * @public */ function escapeHtml(string) { var str = '' + string; var match = matchHtmlRegExp.exec(str); if (!match) { return str; } var escape; var html = ''; var index = 0; var lastIndex = 0; for (index = match.index; index < str.length; index++) { switch (str.charCodeAt(index)) { case 34: // " escape = '&quot;'; break; case 38: // & escape = '&amp;'; break; case 39: // ' escape = '&#39;'; break; case 60: // < escape = '&lt;'; break; case 62: // > escape = '&gt;'; break; default: continue; } if (lastIndex !== index) { html += str.substring(lastIndex, index); } lastIndex = index + 1; html += escape; } return lastIndex !== index ? html + str.substring(lastIndex, index) : html; } /***/ }), /* 7 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var _infiniteTree = __webpack_require__(8); var _infiniteTree2 = _interopRequireDefault(_infiniteTree); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } module.exports = _infiniteTree2['default']; /***/ }), /* 8 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; exports.__esModule = true; 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 _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var _events = __webpack_require__(0); var _events2 = _interopRequireDefault(_events); var _classnames = __webpack_require__(1); var _classnames2 = _interopRequireDefault(_classnames); var _elementClass = __webpack_require__(9); var _elementClass2 = _interopRequireDefault(_elementClass); var _isDom = __webpack_require__(10); var _isDom2 = _interopRequireDefault(_isDom); var _flattree = __webpack_require__(13); var _clusterize = __webpack_require__(15); var _clusterize2 = _interopRequireDefault(_clusterize); var _ensureArray = __webpack_require__(4); var _ensureArray2 = _interopRequireDefault(_ensureArray); var _extend = __webpack_require__(17); var _extend2 = _interopRequireDefault(_extend); var _utilities = __webpack_require__(18); var _lookupTable = __webpack_require__(19); var _lookupTable2 = _interopRequireDefault(_lookupTable); var _renderer = __webpack_require__(20); var _dom = __webpack_require__(5); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 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; } /* eslint no-continue: 0 */ /* eslint operator-assignment: 0 */ var noop = function noop() {}; var error = function error(format) { for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { args[_key - 1] = arguments[_key]; } var argIndex = 0; var message = 'Error: ' + format.replace(/%s/g, function () { return args[argIndex++]; }); if (console && console.error) { console.error(message); } try { // This error was thrown as a convenience so that you can use this stack // to find the callsite that caused this error to fire. throw new Error(message); } catch (e) { // Ignore } }; var ensureNodeInstance = function ensureNodeInstance(node) { if (!node) { // undefined or null return false; } if (!(node instanceof _flattree.Node)) { error('The node must be a Node object.'); return false; } return true; }; var createRootNode = function createRootNode(rootNode) { return (0, _extend2['default'])(rootNode || new _flattree.Node(), { parent: null, children: [], state: { depth: -1, open: true, // always open path: '', prefixMask: '', total: 0 } }); }; var InfiniteTree = function (_events$EventEmitter) { _inherits(InfiniteTree, _events$EventEmitter); // Creates new InfiniteTree object. function InfiniteTree(el, options) { _classCallCheck(this, InfiniteTree); var _this = _possibleConstructorReturn(this, _events$EventEmitter.call(this)); _this.options = { autoOpen: false, blocksInCluster: 4, droppable: false, shouldLoadNodes: null, loadNodes: null, rowRenderer: _renderer.defaultRowRenderer, selectable: true, shouldSelectNode: null, // When el is not specified, the tree will run in the stealth mode el: null, // The following options will have no effect in the stealth mode layout: 'div', noDataClass: 'infinite-tree-no-data', noDataText: 'No data', nodeIdAttr: 'data-id', togglerClass: 'infinite-tree-toggler' }; _this.state = { openNodes: [], rootNode: createRootNode(), selectedNode: null }; _this.clusterize = null; _this.nodeTable = new _lookupTable2['default'](); _this.nodes = []; _this.rows = []; _this.filtered = false; _this.scrollElement = null; _this.contentElement = null; _this.draggableTarget = null; _this.droppableTarget = null; _this.contentListener = { 'click': function click(event) { event = event || window.event; // Wrap stopPropagation that allows click event handler to stop execution // by setting the cancelBubble property var stopPropagation = event.stopPropagation; event.stopPropagation = function () { // Setting the cancelBubble property in browsers that don't support it doesn't hurt. // Of course it doesn't actually cancel the bubbling, but the assignment itself is safe. event.cancelBubble = true; if (stopPropagation) { stopPropagation.call(event); } }; // Call setTimeout(fn, 0) to re-queues the execution of subsequent calls, it allows the // click event to bubble up to higher level event handlers before handling tree events. setTimeout(function () { // Stop execution if the cancelBubble property is set to true by higher level event handlers if (event.cancelBubble === true) { return; } // Emit a "click" event _this.emit('click', event); // Stop execution if the cancelBubble property is set to true after emitting the click event if (event.cancelBubble === true) { return; } var itemTarget = null; var clickToggler = false; if (event.target) { itemTarget = event.target !== event.currentTarget ? event.target : null; } else if (event.srcElement) { // IE8 itemTarget = event.srcElement; } while (itemTarget && itemTarget.parentElement !== _this.contentElement) { if ((0, _elementClass2['default'])(itemTarget).has(_this.options.togglerClass)) { clickToggler = true; } itemTarget = itemTarget.parentElement; } if (!itemTarget || itemTarget.hasAttribute('disabled')) { return; } var id = itemTarget.getAttribute(_this.options.nodeIdAttr); var node = _this.getNodeById(id); if (!node) { return; } // Click on the toggler to open/close a tree node if (clickToggler) { _this.toggleNode(node, { async: true }); return; } _this.selectNode(node); // selectNode will re-render the tree }, 0); }, 'dblclick': function dblclick(event) { // Emit a "doubleClick" event _this.emit('doubleClick', event); }, 'keydown': function keydown(event) { // Emit a "keyDown" event _this.emit('keyDown', event); }, 'keyup': function keyup(event) { // Emit a "keyUp" event _this.emit('keyUp', event); }, // https://developer.mozilla.org/en-US/docs/Web/Events/dragstart // The dragstart event is fired when the user starts dragging an element or text selection. 'dragstart': function dragstart(event) { event = event || window.event; _this.draggableTarget = event.target || event.srcElement; }, // https://developer.mozilla.org/en-US/docs/Web/Events/dragend // The dragend event is fired when a drag operation is being ended (by releasing a mouse button or hitting the escape key). 'dragend': function dragend(event) { event = event || window.event; var _this$options$droppab = _this.options.droppable.hoverClass, hoverClass = _this$options$droppab === undefined ? '' : _this$options$droppab; // Draggable _this.draggableTarget = null; // Droppable if (_this.droppableTarget) { (0, _elementClass2['default'])(_this.droppableTarget).remove(hoverClass); _this.droppableTarget = null; } }, // https://developer.mozilla.org/en-US/docs/Web/Events/dragenter // The dragenter event is fired when a dragged element or text selection enters a valid drop target. 'dragenter': function dragenter(event) { event = event || window.event; var itemTarget = null; if (event.target) { itemTarget = event.target !== event.currentTarget ? event.target : null; } else if (event.srcElement) { // IE8 itemTarget = event.srcElement; } while (itemTarget && itemTarget.parentElement !== _this.contentElement) { itemTarget = itemTarget.parentElement; } if (!itemTarget) { return; } if (_this.droppableTarget === itemTarget) { return; } var _this$options$droppab2 = _this.options.droppable, accept = _this$options$droppab2.accept, _this$options$droppab3 = _this$options$droppab2.hoverClass, hoverClass = _this$options$droppab3 === undefined ? '' : _this$options$droppab3; (0, _elementClass2['default'])(_this.droppableTarget).remove(hoverClass); _this.droppableTarget = null; var canDrop = true; // Defaults to true if (typeof accept === 'function') { var id = itemTarget.getAttribute(_this.options.nodeIdAttr); var node = _this.getNodeById(id); canDrop = !!accept.call(_this, event, { type: 'dragenter', draggableTarget: _this.draggableTarget, droppableTarget: itemTarget, node: node }); } if (canDrop) { (0, _elementClass2['default'])(itemTarget).add(hoverClass); _this.droppableTarget = itemTarget; } }, // https://developer.mozilla.org/en-US/docs/Web/Events/dragover // The dragover event is fired when an element or text selection is being dragged over a valid drop target (every few hundred milliseconds). 'dragover': function dragover(event) { event = event || window.event; (0, _dom.preventDefault)(event); }, // https://developer.mozilla.org/en-US/docs/Web/Events/drop // The drop event is fired when an element or text selection is dropped on a valid drop target. 'drop': function drop(event) { event = event || window.event; // prevent default action (open as link for some elements) (0, _dom.preventDefault)(event); if (!(_this.draggableTarget && _this.droppableTarget)) { return; } var _this$options$droppab4 = _this.options.droppable, accept = _this$options$droppab4.accept, drop = _this$options$droppab4.drop, _this$options$droppab5 = _this$options$droppab4.hoverClass, hoverClass = _this$options$droppab5 === undefined ? '' : _this$options$droppab5; var id = _this.droppableTarget.getAttribute(_this.options.nodeIdAttr); var node = _this.getNodeById(id); var canDrop = true; // Defaults to true if (typeof accept === 'function') { canDrop = !!accept.call(_this, event, { type: 'drop', draggableTarget: _this.draggableTarget, droppableTarget: _this.droppableTarget, node: node }); } if (canDrop && typeof drop === 'function') { drop.call(_this, event, { draggableTarget: _this.draggableTarget, droppableTarget: _this.droppableTarget, node: node }); } (0, _elementClass2['default'])(_this.droppableTarget).remove(hoverClass); _this.droppableTarget = null; } }; if ((0, _isDom2['default'])(el)) { options = _extends({}, options, { el: el }); } else if (el && (typeof el === 'undefined' ? 'undefined' : _typeof(el)) === 'object') { options = el; } // Assign options _this.options = _extends({}, _this.options, options); _this.create(); // Load tree data if it's provided if (_this.options.data) { _this.loadData(_this.options.data); } return _this; } // The following elements will have no effect in the stealth mode InfiniteTree.prototype.create = function create() { var _this2 = this; if (this.options.el) { var tag = null; this.scrollElement = document.createElement('div'); if (this.options.layout === 'table') { var tableElement = document.createElement('table'); tableElement.className = (0, _classnames2['default'])('infinite-tree', 'infinite-tree-table'); var contentElement = document.createElement('tbody'); tableElement.appendChild(contentElement); this.scrollElement.appendChild(tableElement); this.contentElement = contentElement; // The tag name for supporting elements tag = 'tr'; } else { var _contentElement = document.createElement('div'); this.scrollElement.appendChild(_contentElement); this.contentElement = _contentElement; // The tag name for supporting elements tag = 'div'; } this.scrollElement.className = (0, _classnames2['default'])('infinite-tree', 'infinite-tree-scroll'); this.contentElement.className = (0, _classnames2['default'])('infinite-tree', 'infinite-tree-content'); this.options.el.appendChild(this.scrollElement); this.clusterize = new _clusterize2['default']({ tag: tag, rows: [], scrollElement: this.scrollElement, contentElement: this.contentElement, emptyText: this.options.noDataText, emptyClass: this.options.noDataClass, blocksInCluster: this.options.blocksInCluster }); this.clusterize.on('clusterWillChange', function () { _this2.emit('clusterWillChange'); }); this.clusterize.on('clusterDidChange', function () { _this2.emit('clusterDidChange'); }); (0, _dom.addEventListener)(this.contentElement, 'click', this.contentListener.click); (0, _dom.addEventListener)(this.contentElement, 'dblclick', this.contentListener.dblclick); (0, _dom.addEventListener)(this.contentElement, 'keydown', this.contentListener.keydown); (0, _dom.addEventListener)(this.contentElement, 'keyup', this.contentListener.keyup); if (this.options.droppable) { (0, _dom.addEventListener)(document, 'dragstart', this.contentListener.dragstart); (0, _dom.addEventListener)(document, 'dragend', this.contentListener.dragend); (0, _dom.addEventListener)(this.contentElement, 'dragenter', this.contentListener.dragenter); (0, _dom.addEventListener)(this.contentElement, 'dragleave', this.contentListener.dragleave); (0, _dom.addEventListener)(this.contentElement, 'dragover', this.contentListener.dragover); (0, _dom.addEventListener)(this.contentElement, 'drop', this.contentListener.drop); } } }; InfiniteTree.prototype.destroy = function destroy() { this.clear(); if (this.options.el) { (0, _dom.removeEventListener)(this.contentElement, 'click', this.contentListener.click); (0, _dom.removeEventListener)(this.contentElement, 'dblclick', this.contentListener.dblclick); (0, _dom.removeEventListener)(this.contentElement, 'keydown', this.contentListener.keydown); (0, _dom.removeEventListener)(this.contentElement, 'keyup', this.contentListener.keyup); if (this.options.droppable) { (0, _dom.removeEventListener)(document, 'dragstart', this.contentListener.dragstart); (0, _dom.removeEventListener)(document, 'dragend', this.contentListener.dragend); (0, _dom.removeEventListener)(this.contentElement, 'dragenter', this.contentListener.dragenter); (0, _dom.removeEventListener)(this.contentElement, 'dragleave', this.contentListener.dragleave); (0, _dom.removeEventListener)(this.contentElement, 'dragover', this.contentListener.dragover); (0, _dom.removeEventListener)(this.contentElement, 'drop', this.contentListener.drop); } if (this.clusterize) { this.clusterize.destroy(true); // True to remove all data from the list this.clusterize = null; } // Remove all child nodes while (this.contentElement.firstChild) { this.contentElement.removeChild(this.contentElement.firstChild); } while (this.scrollElement.firstChild) { this.scrollElement.removeChild(this.scrollElement.firstChild); } var containerElement = this.options.el; while (containerElement.firstChild) { containerElement.removeChild(containerElement.firstChild); } this.contentElement = null; this.scrollElement = null; } }; // Adds an array of new child nodes to a parent node at the specified index. // * If the parent is null or undefined, inserts new childs at the specified index in the top-level. // * If the parent has children, the method adds the new child to it at the specified index. // * If the parent does not have children, the method adds the new child to the parent. // * If the index value is greater than or equal to the number of children in the parent, the method adds the child at the end of the children. // @param {Array} newNodes An array of new child nodes. // @param {number} [index] The 0-based index of where to insert the child node. // @param {Node} parentNode The Node object that defines the parent node. // @return {boolean} Returns true on success, false otherwise. InfiniteTree.prototype.addChildNodes = function addChildNodes(newNodes, index, parentNode) { var _this3 = this; newNodes = [].concat(newNodes || []); // Ensure array if (newNodes.length === 0) { return false; } parentNode = parentNode || this.state.rootNode; // Defaults to rootNode if not specified if (index === undefined) { index = parentNode.children.length; } if (!ensureNodeInstance(parentNode)) { return false; } // Assign parent newNodes.forEach(function (newNode) { newNode.parent = parentNode; }); // Insert new child node at the specified index parentNode.children.splice.apply(parentNode.children, [index, 0].concat(newNodes)); // Get the index of the first new node within the array of child nodes index = parentNode.children.indexOf(newNodes[0]); var deleteCount = parentNode.state.total; var nodes = (0, _flattree.flatten)(parentNode.children, { openNodes: this.state.openNodes }); var rows = []; // Update rows rows.length = nodes.length; for (var i = 0; i < nodes.length; ++i) { var node = nodes[i]; rows[i] = this.options.rowRenderer(node, this.options); } if (parentNode === this.state.rootNode) { this.nodes = nodes; this.rows = rows; } else { var parentOffset = this.nodes.indexOf(parentNode); if (parentOffset >= 0) {