24130 lines
1.3 MiB
JavaScript
24130 lines
1.3 MiB
JavaScript
|
|
(function (global, factory) {
|
|||
|
|
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
|||
|
|
typeof define === 'function' && define.amd ? define(['exports'], factory) :
|
|||
|
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.wangEditor = {}));
|
|||
|
|
})(this, (function (exports) { 'use strict';
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @description browser polyfill
|
|||
|
|
* @author wangfupeng
|
|||
|
|
*/
|
|||
|
|
var _a;
|
|||
|
|
// @ts-nocheck
|
|||
|
|
// 必须是浏览器环境
|
|||
|
|
if (typeof global === 'undefined') {
|
|||
|
|
// 检查 IE 浏览器
|
|||
|
|
if ('ActiveXObject' in window) {
|
|||
|
|
var info = '抱歉,wangEditor V5+ 版本开始,不在支持 IE 浏览器';
|
|||
|
|
info += '\n Sorry, wangEditor V5+ versions do not support IE browser.';
|
|||
|
|
console.error(info);
|
|||
|
|
}
|
|||
|
|
globalThisPolyfill();
|
|||
|
|
AggregateErrorPolyfill();
|
|||
|
|
}
|
|||
|
|
else if (global && ((_a = global.navigator) === null || _a === void 0 ? void 0 : _a.userAgent.match('QQBrowser'))) {
|
|||
|
|
// 兼容 QQ 浏览器 AggregateError 报错
|
|||
|
|
globalThisPolyfill();
|
|||
|
|
AggregateErrorPolyfill();
|
|||
|
|
}
|
|||
|
|
function globalThisPolyfill() {
|
|||
|
|
// 部分浏览器不支持 globalThis
|
|||
|
|
if (typeof globalThis === 'undefined') {
|
|||
|
|
// @ts-ignore
|
|||
|
|
window.globalThis = window;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function AggregateErrorPolyfill() {
|
|||
|
|
if (typeof AggregateError === 'undefined') {
|
|||
|
|
window.AggregateError = function (errors, msg) {
|
|||
|
|
var err = new Error(msg);
|
|||
|
|
err.errors = errors;
|
|||
|
|
return err;
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @description node polyfill
|
|||
|
|
* @author wangfupeng
|
|||
|
|
*/
|
|||
|
|
// @ts-nocheck
|
|||
|
|
// 必须是 node 环境
|
|||
|
|
if (typeof global === 'object') {
|
|||
|
|
// 用于 nodejs ,避免报错
|
|||
|
|
var globalProperty = Object.getOwnPropertyDescriptor(global, 'window');
|
|||
|
|
// global.window 为空则直接写入
|
|||
|
|
// 部分框架下已经定义了global.window且是不可写属性
|
|||
|
|
if (!global.window || globalProperty.set) {
|
|||
|
|
global.window = global;
|
|||
|
|
global.requestAnimationFrame = function () { };
|
|||
|
|
global.navigator = {
|
|||
|
|
userAgent: '',
|
|||
|
|
};
|
|||
|
|
global.location = {
|
|||
|
|
hostname: '0.0.0.0',
|
|||
|
|
port: 0,
|
|||
|
|
protocol: 'http:',
|
|||
|
|
};
|
|||
|
|
global.btoa = function () { };
|
|||
|
|
global.crypto = {
|
|||
|
|
getRandomValues: function (buffer) {
|
|||
|
|
return nodeCrypto.randomFillSync(buffer);
|
|||
|
|
},
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
if (global.document != null) {
|
|||
|
|
// SSR 环境下可能会报错 (issue 4409)
|
|||
|
|
if (global.document.getElementsByTagName == null) {
|
|||
|
|
global.document.getElementsByTagName = function () { return []; };
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
|||
|
|
|
|||
|
|
function getDefaultExportFromCjs (x) {
|
|||
|
|
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function createCommonjsModule$1(fn) {
|
|||
|
|
var module = { exports: {} };
|
|||
|
|
return fn(module, module.exports), module.exports;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/*!
|
|||
|
|
* is-plain-object <https://github.com/jonschlinkert/is-plain-object>
|
|||
|
|
*
|
|||
|
|
* Copyright (c) 2014-2017, Jon Schlinkert.
|
|||
|
|
* Released under the MIT License.
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
function isObject$4(o) {
|
|||
|
|
return Object.prototype.toString.call(o) === '[object Object]';
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function isPlainObject$2(o) {
|
|||
|
|
var ctor,prot;
|
|||
|
|
|
|||
|
|
if (isObject$4(o) === false) return false;
|
|||
|
|
|
|||
|
|
// If has modified constructor
|
|||
|
|
ctor = o.constructor;
|
|||
|
|
if (ctor === undefined) return true;
|
|||
|
|
|
|||
|
|
// If has modified prototype
|
|||
|
|
prot = ctor.prototype;
|
|||
|
|
if (isObject$4(prot) === false) return false;
|
|||
|
|
|
|||
|
|
// If constructor does not have an Object-specific method
|
|||
|
|
if (prot.hasOwnProperty('isPrototypeOf') === false) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Most likely a plain Object
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var isPlainObject_2 = isPlainObject$2;
|
|||
|
|
|
|||
|
|
var isPlainObject_1 = /*#__PURE__*/Object.defineProperty({
|
|||
|
|
isPlainObject: isPlainObject_2
|
|||
|
|
}, '__esModule', {value: true});
|
|||
|
|
|
|||
|
|
var _ref;
|
|||
|
|
|
|||
|
|
// Should be no imports here!
|
|||
|
|
// Some things that should be evaluated before all else...
|
|||
|
|
// We only want to know if non-polyfilled symbols are available
|
|||
|
|
var hasSymbol = typeof Symbol !== "undefined" && typeof
|
|||
|
|
/*#__PURE__*/
|
|||
|
|
Symbol("x") === "symbol";
|
|||
|
|
var hasMap = typeof Map !== "undefined";
|
|||
|
|
var hasSet = typeof Set !== "undefined";
|
|||
|
|
var hasProxies = typeof Proxy !== "undefined" && typeof Proxy.revocable !== "undefined" && typeof Reflect !== "undefined";
|
|||
|
|
/**
|
|||
|
|
* The sentinel value returned by producers to replace the draft with undefined.
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
var NOTHING = hasSymbol ?
|
|||
|
|
/*#__PURE__*/
|
|||
|
|
Symbol.for("immer-nothing") : (_ref = {}, _ref["immer-nothing"] = true, _ref);
|
|||
|
|
/**
|
|||
|
|
* To let Immer treat your class instances as plain immutable objects
|
|||
|
|
* (albeit with a custom prototype), you must define either an instance property
|
|||
|
|
* or a static property on each of your custom classes.
|
|||
|
|
*
|
|||
|
|
* Otherwise, your class instance will never be drafted, which means it won't be
|
|||
|
|
* safe to mutate in a produce callback.
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
var DRAFTABLE = hasSymbol ?
|
|||
|
|
/*#__PURE__*/
|
|||
|
|
Symbol.for("immer-draftable") : "__$immer_draftable";
|
|||
|
|
var DRAFT_STATE = hasSymbol ?
|
|||
|
|
/*#__PURE__*/
|
|||
|
|
Symbol.for("immer-state") : "__$immer_state"; // Even a polyfilled Symbol might provide Symbol.iterator
|
|||
|
|
|
|||
|
|
var iteratorSymbol$1 = typeof Symbol != "undefined" && Symbol.iterator || "@@iterator";
|
|||
|
|
|
|||
|
|
var errors = {
|
|||
|
|
0: "Illegal state",
|
|||
|
|
1: "Immer drafts cannot have computed properties",
|
|||
|
|
2: "This object has been frozen and should not be mutated",
|
|||
|
|
3: function _(data) {
|
|||
|
|
return "Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? " + data;
|
|||
|
|
},
|
|||
|
|
4: "An immer producer returned a new value *and* modified its draft. Either return a new value *or* modify the draft.",
|
|||
|
|
5: "Immer forbids circular references",
|
|||
|
|
6: "The first or second argument to `produce` must be a function",
|
|||
|
|
7: "The third argument to `produce` must be a function or undefined",
|
|||
|
|
8: "First argument to `createDraft` must be a plain object, an array, or an immerable object",
|
|||
|
|
9: "First argument to `finishDraft` must be a draft returned by `createDraft`",
|
|||
|
|
10: "The given draft is already finalized",
|
|||
|
|
11: "Object.defineProperty() cannot be used on an Immer draft",
|
|||
|
|
12: "Object.setPrototypeOf() cannot be used on an Immer draft",
|
|||
|
|
13: "Immer only supports deleting array indices",
|
|||
|
|
14: "Immer only supports setting array indices and the 'length' property",
|
|||
|
|
15: function _(path) {
|
|||
|
|
return "Cannot apply patch, path doesn't resolve: " + path;
|
|||
|
|
},
|
|||
|
|
16: 'Sets cannot have "replace" patches.',
|
|||
|
|
17: function _(op) {
|
|||
|
|
return "Unsupported patch operation: " + op;
|
|||
|
|
},
|
|||
|
|
18: function _(plugin) {
|
|||
|
|
return "The plugin for '" + plugin + "' has not been loaded into Immer. To enable the plugin, import and call `enable" + plugin + "()` when initializing your application.";
|
|||
|
|
},
|
|||
|
|
20: "Cannot use proxies if Proxy, Proxy.revocable or Reflect are not available",
|
|||
|
|
21: function _(thing) {
|
|||
|
|
return "produce can only be called on things that are draftable: plain objects, arrays, Map, Set or classes that are marked with '[immerable]: true'. Got '" + thing + "'";
|
|||
|
|
},
|
|||
|
|
22: function _(thing) {
|
|||
|
|
return "'current' expects a draft, got: " + thing;
|
|||
|
|
},
|
|||
|
|
23: function _(thing) {
|
|||
|
|
return "'original' expects a draft, got: " + thing;
|
|||
|
|
},
|
|||
|
|
24: "Patching reserved attributes like __proto__, prototype and constructor is not allowed"
|
|||
|
|
};
|
|||
|
|
function die(error) {
|
|||
|
|
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|||
|
|
args[_key - 1] = arguments[_key];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
{
|
|||
|
|
var e = errors[error];
|
|||
|
|
var msg = !e ? "unknown error nr: " + error : typeof e === "function" ? e.apply(null, args) : e;
|
|||
|
|
throw new Error("[Immer] " + msg);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/** Returns true if the given value is an Immer draft */
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
function isDraft(value) {
|
|||
|
|
return !!value && !!value[DRAFT_STATE];
|
|||
|
|
}
|
|||
|
|
/** Returns true if the given value can be drafted by Immer */
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
function isDraftable(value) {
|
|||
|
|
if (!value) return false;
|
|||
|
|
return isPlainObject$1(value) || Array.isArray(value) || !!value[DRAFTABLE] || !!value.constructor[DRAFTABLE] || isMap(value) || isSet(value);
|
|||
|
|
}
|
|||
|
|
var objectCtorString =
|
|||
|
|
/*#__PURE__*/
|
|||
|
|
Object.prototype.constructor.toString();
|
|||
|
|
|
|||
|
|
|
|||
|
|
function isPlainObject$1(value) {
|
|||
|
|
if (!value || typeof value !== "object") return false;
|
|||
|
|
var proto = Object.getPrototypeOf(value);
|
|||
|
|
|
|||
|
|
if (proto === null) {
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var Ctor = Object.hasOwnProperty.call(proto, "constructor") && proto.constructor;
|
|||
|
|
if (Ctor === Object) return true;
|
|||
|
|
return typeof Ctor == "function" && Function.toString.call(Ctor) === objectCtorString;
|
|||
|
|
}
|
|||
|
|
function original(value) {
|
|||
|
|
if (!isDraft(value)) die(23, value);
|
|||
|
|
return value[DRAFT_STATE].base_;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
var ownKeys$a = typeof Reflect !== "undefined" && Reflect.ownKeys ? Reflect.ownKeys : typeof Object.getOwnPropertySymbols !== "undefined" ? function (obj) {
|
|||
|
|
return Object.getOwnPropertyNames(obj).concat(Object.getOwnPropertySymbols(obj));
|
|||
|
|
} :
|
|||
|
|
/* istanbul ignore next */
|
|||
|
|
Object.getOwnPropertyNames;
|
|||
|
|
var getOwnPropertyDescriptors = Object.getOwnPropertyDescriptors || function getOwnPropertyDescriptors(target) {
|
|||
|
|
// Polyfill needed for Hermes and IE, see https://github.com/facebook/hermes/issues/274
|
|||
|
|
var res = {};
|
|||
|
|
ownKeys$a(target).forEach(function (key) {
|
|||
|
|
res[key] = Object.getOwnPropertyDescriptor(target, key);
|
|||
|
|
});
|
|||
|
|
return res;
|
|||
|
|
};
|
|||
|
|
function each$1(obj, iter, enumerableOnly) {
|
|||
|
|
if (enumerableOnly === void 0) {
|
|||
|
|
enumerableOnly = false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (getArchtype(obj) === 0
|
|||
|
|
/* Object */
|
|||
|
|
) {
|
|||
|
|
(enumerableOnly ? Object.keys : ownKeys$a)(obj).forEach(function (key) {
|
|||
|
|
if (!enumerableOnly || typeof key !== "symbol") iter(key, obj[key], obj);
|
|||
|
|
});
|
|||
|
|
} else {
|
|||
|
|
obj.forEach(function (entry, index) {
|
|||
|
|
return iter(index, entry, obj);
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
function getArchtype(thing) {
|
|||
|
|
/* istanbul ignore next */
|
|||
|
|
var state = thing[DRAFT_STATE];
|
|||
|
|
return state ? state.type_ > 3 ? state.type_ - 4 // cause Object and Array map back from 4 and 5
|
|||
|
|
: state.type_ // others are the same
|
|||
|
|
: Array.isArray(thing) ? 1
|
|||
|
|
/* Array */
|
|||
|
|
: isMap(thing) ? 2
|
|||
|
|
/* Map */
|
|||
|
|
: isSet(thing) ? 3
|
|||
|
|
/* Set */
|
|||
|
|
: 0
|
|||
|
|
/* Object */
|
|||
|
|
;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
function has(thing, prop) {
|
|||
|
|
return getArchtype(thing) === 2
|
|||
|
|
/* Map */
|
|||
|
|
? thing.has(prop) : Object.prototype.hasOwnProperty.call(thing, prop);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
function get(thing, prop) {
|
|||
|
|
// @ts-ignore
|
|||
|
|
return getArchtype(thing) === 2
|
|||
|
|
/* Map */
|
|||
|
|
? thing.get(prop) : thing[prop];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
function set(thing, propOrOldValue, value) {
|
|||
|
|
var t = getArchtype(thing);
|
|||
|
|
if (t === 2
|
|||
|
|
/* Map */
|
|||
|
|
) thing.set(propOrOldValue, value);else if (t === 3
|
|||
|
|
/* Set */
|
|||
|
|
) {
|
|||
|
|
thing.delete(propOrOldValue);
|
|||
|
|
thing.add(value);
|
|||
|
|
} else thing[propOrOldValue] = value;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
function is$1(x, y) {
|
|||
|
|
// From: https://github.com/facebook/fbjs/blob/c69904a511b900266935168223063dd8772dfc40/packages/fbjs/src/core/shallowEqual.js
|
|||
|
|
if (x === y) {
|
|||
|
|
return x !== 0 || 1 / x === 1 / y;
|
|||
|
|
} else {
|
|||
|
|
return x !== x && y !== y;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
function isMap(target) {
|
|||
|
|
return hasMap && target instanceof Map;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
function isSet(target) {
|
|||
|
|
return hasSet && target instanceof Set;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
function latest(state) {
|
|||
|
|
return state.copy_ || state.base_;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
function shallowCopy(base) {
|
|||
|
|
if (Array.isArray(base)) return Array.prototype.slice.call(base);
|
|||
|
|
var descriptors = getOwnPropertyDescriptors(base);
|
|||
|
|
delete descriptors[DRAFT_STATE];
|
|||
|
|
var keys = ownKeys$a(descriptors);
|
|||
|
|
|
|||
|
|
for (var i = 0; i < keys.length; i++) {
|
|||
|
|
var key = keys[i];
|
|||
|
|
var desc = descriptors[key];
|
|||
|
|
|
|||
|
|
if (desc.writable === false) {
|
|||
|
|
desc.writable = true;
|
|||
|
|
desc.configurable = true;
|
|||
|
|
} // like object.assign, we will read any _own_, get/set accessors. This helps in dealing
|
|||
|
|
// with libraries that trap values, like mobx or vue
|
|||
|
|
// unlike object.assign, non-enumerables will be copied as well
|
|||
|
|
|
|||
|
|
|
|||
|
|
if (desc.get || desc.set) descriptors[key] = {
|
|||
|
|
configurable: true,
|
|||
|
|
writable: true,
|
|||
|
|
enumerable: desc.enumerable,
|
|||
|
|
value: base[key]
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return Object.create(Object.getPrototypeOf(base), descriptors);
|
|||
|
|
}
|
|||
|
|
function freeze(obj, deep) {
|
|||
|
|
if (deep === void 0) {
|
|||
|
|
deep = false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (isFrozen(obj) || isDraft(obj) || !isDraftable(obj)) return obj;
|
|||
|
|
|
|||
|
|
if (getArchtype(obj) > 1
|
|||
|
|
/* Map or Set */
|
|||
|
|
) {
|
|||
|
|
obj.set = obj.add = obj.clear = obj.delete = dontMutateFrozenCollections;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Object.freeze(obj);
|
|||
|
|
if (deep) each$1(obj, function (key, value) {
|
|||
|
|
return freeze(value, true);
|
|||
|
|
}, true);
|
|||
|
|
return obj;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function dontMutateFrozenCollections() {
|
|||
|
|
die(2);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function isFrozen(obj) {
|
|||
|
|
if (obj == null || typeof obj !== "object") return true; // See #600, IE dies on non-objects in Object.isFrozen
|
|||
|
|
|
|||
|
|
return Object.isFrozen(obj);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/** Plugin utilities */
|
|||
|
|
|
|||
|
|
var plugins = {};
|
|||
|
|
function getPlugin(pluginKey) {
|
|||
|
|
var plugin = plugins[pluginKey];
|
|||
|
|
|
|||
|
|
if (!plugin) {
|
|||
|
|
die(18, pluginKey);
|
|||
|
|
} // @ts-ignore
|
|||
|
|
|
|||
|
|
|
|||
|
|
return plugin;
|
|||
|
|
}
|
|||
|
|
function loadPlugin(pluginKey, implementation) {
|
|||
|
|
if (!plugins[pluginKey]) plugins[pluginKey] = implementation;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var currentScope;
|
|||
|
|
function getCurrentScope() {
|
|||
|
|
if ( !currentScope) die(0);
|
|||
|
|
return currentScope;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function createScope(parent_, immer_) {
|
|||
|
|
return {
|
|||
|
|
drafts_: [],
|
|||
|
|
parent_: parent_,
|
|||
|
|
immer_: immer_,
|
|||
|
|
// Whenever the modified draft contains a draft from another scope, we
|
|||
|
|
// need to prevent auto-freezing so the unowned draft can be finalized.
|
|||
|
|
canAutoFreeze_: true,
|
|||
|
|
unfinalizedDrafts_: 0
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function usePatchesInScope(scope, patchListener) {
|
|||
|
|
if (patchListener) {
|
|||
|
|
getPlugin("Patches"); // assert we have the plugin
|
|||
|
|
|
|||
|
|
scope.patches_ = [];
|
|||
|
|
scope.inversePatches_ = [];
|
|||
|
|
scope.patchListener_ = patchListener;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function revokeScope(scope) {
|
|||
|
|
leaveScope(scope);
|
|||
|
|
scope.drafts_.forEach(revokeDraft); // @ts-ignore
|
|||
|
|
|
|||
|
|
scope.drafts_ = null;
|
|||
|
|
}
|
|||
|
|
function leaveScope(scope) {
|
|||
|
|
if (scope === currentScope) {
|
|||
|
|
currentScope = scope.parent_;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function enterScope(immer) {
|
|||
|
|
return currentScope = createScope(currentScope, immer);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function revokeDraft(draft) {
|
|||
|
|
var state = draft[DRAFT_STATE];
|
|||
|
|
if (state.type_ === 0
|
|||
|
|
/* ProxyObject */
|
|||
|
|
|| state.type_ === 1
|
|||
|
|
/* ProxyArray */
|
|||
|
|
) state.revoke_();else state.revoked_ = true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function processResult(result, scope) {
|
|||
|
|
scope.unfinalizedDrafts_ = scope.drafts_.length;
|
|||
|
|
var baseDraft = scope.drafts_[0];
|
|||
|
|
var isReplaced = result !== undefined && result !== baseDraft;
|
|||
|
|
if (!scope.immer_.useProxies_) getPlugin("ES5").willFinalizeES5_(scope, result, isReplaced);
|
|||
|
|
|
|||
|
|
if (isReplaced) {
|
|||
|
|
if (baseDraft[DRAFT_STATE].modified_) {
|
|||
|
|
revokeScope(scope);
|
|||
|
|
die(4);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (isDraftable(result)) {
|
|||
|
|
// Finalize the result in case it contains (or is) a subset of the draft.
|
|||
|
|
result = finalize(scope, result);
|
|||
|
|
if (!scope.parent_) maybeFreeze(scope, result);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (scope.patches_) {
|
|||
|
|
getPlugin("Patches").generateReplacementPatches_(baseDraft[DRAFT_STATE], result, scope.patches_, scope.inversePatches_);
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
// Finalize the base draft.
|
|||
|
|
result = finalize(scope, baseDraft, []);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
revokeScope(scope);
|
|||
|
|
|
|||
|
|
if (scope.patches_) {
|
|||
|
|
scope.patchListener_(scope.patches_, scope.inversePatches_);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return result !== NOTHING ? result : undefined;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function finalize(rootScope, value, path) {
|
|||
|
|
// Don't recurse in tho recursive data structures
|
|||
|
|
if (isFrozen(value)) return value;
|
|||
|
|
var state = value[DRAFT_STATE]; // A plain object, might need freezing, might contain drafts
|
|||
|
|
|
|||
|
|
if (!state) {
|
|||
|
|
each$1(value, function (key, childValue) {
|
|||
|
|
return finalizeProperty(rootScope, state, value, key, childValue, path);
|
|||
|
|
}, true // See #590, don't recurse into non-enumerable of non drafted objects
|
|||
|
|
);
|
|||
|
|
return value;
|
|||
|
|
} // Never finalize drafts owned by another scope.
|
|||
|
|
|
|||
|
|
|
|||
|
|
if (state.scope_ !== rootScope) return value; // Unmodified draft, return the (frozen) original
|
|||
|
|
|
|||
|
|
if (!state.modified_) {
|
|||
|
|
maybeFreeze(rootScope, state.base_, true);
|
|||
|
|
return state.base_;
|
|||
|
|
} // Not finalized yet, let's do that now
|
|||
|
|
|
|||
|
|
|
|||
|
|
if (!state.finalized_) {
|
|||
|
|
state.finalized_ = true;
|
|||
|
|
state.scope_.unfinalizedDrafts_--;
|
|||
|
|
var result = // For ES5, create a good copy from the draft first, with added keys and without deleted keys.
|
|||
|
|
state.type_ === 4
|
|||
|
|
/* ES5Object */
|
|||
|
|
|| state.type_ === 5
|
|||
|
|
/* ES5Array */
|
|||
|
|
? state.copy_ = shallowCopy(state.draft_) : state.copy_; // Finalize all children of the copy
|
|||
|
|
// For sets we clone before iterating, otherwise we can get in endless loop due to modifying during iteration, see #628
|
|||
|
|
// Although the original test case doesn't seem valid anyway, so if this in the way we can turn the next line
|
|||
|
|
// back to each(result, ....)
|
|||
|
|
|
|||
|
|
each$1(state.type_ === 3
|
|||
|
|
/* Set */
|
|||
|
|
? new Set(result) : result, function (key, childValue) {
|
|||
|
|
return finalizeProperty(rootScope, state, result, key, childValue, path);
|
|||
|
|
}); // everything inside is frozen, we can freeze here
|
|||
|
|
|
|||
|
|
maybeFreeze(rootScope, result, false); // first time finalizing, let's create those patches
|
|||
|
|
|
|||
|
|
if (path && rootScope.patches_) {
|
|||
|
|
getPlugin("Patches").generatePatches_(state, path, rootScope.patches_, rootScope.inversePatches_);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return state.copy_;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function finalizeProperty(rootScope, parentState, targetObject, prop, childValue, rootPath) {
|
|||
|
|
if ( childValue === targetObject) die(5);
|
|||
|
|
|
|||
|
|
if (isDraft(childValue)) {
|
|||
|
|
var path = rootPath && parentState && parentState.type_ !== 3
|
|||
|
|
/* Set */
|
|||
|
|
&& // Set objects are atomic since they have no keys.
|
|||
|
|
!has(parentState.assigned_, prop) // Skip deep patches for assigned keys.
|
|||
|
|
? rootPath.concat(prop) : undefined; // Drafts owned by `scope` are finalized here.
|
|||
|
|
|
|||
|
|
var res = finalize(rootScope, childValue, path);
|
|||
|
|
set(targetObject, prop, res); // Drafts from another scope must prevented to be frozen
|
|||
|
|
// if we got a draft back from finalize, we're in a nested produce and shouldn't freeze
|
|||
|
|
|
|||
|
|
if (isDraft(res)) {
|
|||
|
|
rootScope.canAutoFreeze_ = false;
|
|||
|
|
} else return;
|
|||
|
|
} // Search new objects for unfinalized drafts. Frozen objects should never contain drafts.
|
|||
|
|
|
|||
|
|
|
|||
|
|
if (isDraftable(childValue) && !isFrozen(childValue)) {
|
|||
|
|
if (!rootScope.immer_.autoFreeze_ && rootScope.unfinalizedDrafts_ < 1) {
|
|||
|
|
// optimization: if an object is not a draft, and we don't have to
|
|||
|
|
// deepfreeze everything, and we are sure that no drafts are left in the remaining object
|
|||
|
|
// cause we saw and finalized all drafts already; we can stop visiting the rest of the tree.
|
|||
|
|
// This benefits especially adding large data tree's without further processing.
|
|||
|
|
// See add-data.js perf test
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
finalize(rootScope, childValue); // immer deep freezes plain objects, so if there is no parent state, we freeze as well
|
|||
|
|
|
|||
|
|
if (!parentState || !parentState.scope_.parent_) maybeFreeze(rootScope, childValue);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function maybeFreeze(scope, value, deep) {
|
|||
|
|
if (deep === void 0) {
|
|||
|
|
deep = false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (scope.immer_.autoFreeze_ && scope.canAutoFreeze_) {
|
|||
|
|
freeze(value, deep);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Returns a new draft of the `base` object.
|
|||
|
|
*
|
|||
|
|
* The second argument is the parent draft-state (used internally).
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
function createProxyProxy(base, parent) {
|
|||
|
|
var isArray = Array.isArray(base);
|
|||
|
|
var state = {
|
|||
|
|
type_: isArray ? 1
|
|||
|
|
/* ProxyArray */
|
|||
|
|
: 0
|
|||
|
|
/* ProxyObject */
|
|||
|
|
,
|
|||
|
|
// Track which produce call this is associated with.
|
|||
|
|
scope_: parent ? parent.scope_ : getCurrentScope(),
|
|||
|
|
// True for both shallow and deep changes.
|
|||
|
|
modified_: false,
|
|||
|
|
// Used during finalization.
|
|||
|
|
finalized_: false,
|
|||
|
|
// Track which properties have been assigned (true) or deleted (false).
|
|||
|
|
assigned_: {},
|
|||
|
|
// The parent draft state.
|
|||
|
|
parent_: parent,
|
|||
|
|
// The base state.
|
|||
|
|
base_: base,
|
|||
|
|
// The base proxy.
|
|||
|
|
draft_: null,
|
|||
|
|
// The base copy with any updated values.
|
|||
|
|
copy_: null,
|
|||
|
|
// Called by the `produce` function.
|
|||
|
|
revoke_: null,
|
|||
|
|
isManual_: false
|
|||
|
|
}; // the traps must target something, a bit like the 'real' base.
|
|||
|
|
// but also, we need to be able to determine from the target what the relevant state is
|
|||
|
|
// (to avoid creating traps per instance to capture the state in closure,
|
|||
|
|
// and to avoid creating weird hidden properties as well)
|
|||
|
|
// So the trick is to use 'state' as the actual 'target'! (and make sure we intercept everything)
|
|||
|
|
// Note that in the case of an array, we put the state in an array to have better Reflect defaults ootb
|
|||
|
|
|
|||
|
|
var target = state;
|
|||
|
|
var traps = objectTraps;
|
|||
|
|
|
|||
|
|
if (isArray) {
|
|||
|
|
target = [state];
|
|||
|
|
traps = arrayTraps;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var _Proxy$revocable = Proxy.revocable(target, traps),
|
|||
|
|
revoke = _Proxy$revocable.revoke,
|
|||
|
|
proxy = _Proxy$revocable.proxy;
|
|||
|
|
|
|||
|
|
state.draft_ = proxy;
|
|||
|
|
state.revoke_ = revoke;
|
|||
|
|
return proxy;
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Object drafts
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
var objectTraps = {
|
|||
|
|
get: function get(state, prop) {
|
|||
|
|
if (prop === DRAFT_STATE) return state;
|
|||
|
|
var source = latest(state);
|
|||
|
|
|
|||
|
|
if (!has(source, prop)) {
|
|||
|
|
// non-existing or non-own property...
|
|||
|
|
return readPropFromProto(state, source, prop);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var value = source[prop];
|
|||
|
|
|
|||
|
|
if (state.finalized_ || !isDraftable(value)) {
|
|||
|
|
return value;
|
|||
|
|
} // Check for existing draft in modified state.
|
|||
|
|
// Assigned values are never drafted. This catches any drafts we created, too.
|
|||
|
|
|
|||
|
|
|
|||
|
|
if (value === peek(state.base_, prop)) {
|
|||
|
|
prepareCopy(state);
|
|||
|
|
return state.copy_[prop] = createProxy(state.scope_.immer_, value, state);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return value;
|
|||
|
|
},
|
|||
|
|
has: function has(state, prop) {
|
|||
|
|
return prop in latest(state);
|
|||
|
|
},
|
|||
|
|
ownKeys: function ownKeys(state) {
|
|||
|
|
return Reflect.ownKeys(latest(state));
|
|||
|
|
},
|
|||
|
|
set: function set(state, prop
|
|||
|
|
/* strictly not, but helps TS */
|
|||
|
|
, value) {
|
|||
|
|
var desc = getDescriptorFromProto(latest(state), prop);
|
|||
|
|
|
|||
|
|
if (desc === null || desc === void 0 ? void 0 : desc.set) {
|
|||
|
|
// special case: if this write is captured by a setter, we have
|
|||
|
|
// to trigger it with the correct context
|
|||
|
|
desc.set.call(state.draft_, value);
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!state.modified_) {
|
|||
|
|
// the last check is because we need to be able to distinguish setting a non-existing to undefined (which is a change)
|
|||
|
|
// from setting an existing property with value undefined to undefined (which is not a change)
|
|||
|
|
var current = peek(latest(state), prop); // special case, if we assigning the original value to a draft, we can ignore the assignment
|
|||
|
|
|
|||
|
|
var currentState = current === null || current === void 0 ? void 0 : current[DRAFT_STATE];
|
|||
|
|
|
|||
|
|
if (currentState && currentState.base_ === value) {
|
|||
|
|
state.copy_[prop] = value;
|
|||
|
|
state.assigned_[prop] = false;
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (is$1(value, current) && (value !== undefined || has(state.base_, prop))) return true;
|
|||
|
|
prepareCopy(state);
|
|||
|
|
markChanged(state);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (state.copy_[prop] === value && // special case: NaN
|
|||
|
|
typeof value !== "number" && ( // special case: handle new props with value 'undefined'
|
|||
|
|
value !== undefined || prop in state.copy_)) return true; // @ts-ignore
|
|||
|
|
|
|||
|
|
state.copy_[prop] = value;
|
|||
|
|
state.assigned_[prop] = true;
|
|||
|
|
return true;
|
|||
|
|
},
|
|||
|
|
deleteProperty: function deleteProperty(state, prop) {
|
|||
|
|
// The `undefined` check is a fast path for pre-existing keys.
|
|||
|
|
if (peek(state.base_, prop) !== undefined || prop in state.base_) {
|
|||
|
|
state.assigned_[prop] = false;
|
|||
|
|
prepareCopy(state);
|
|||
|
|
markChanged(state);
|
|||
|
|
} else {
|
|||
|
|
// if an originally not assigned property was deleted
|
|||
|
|
delete state.assigned_[prop];
|
|||
|
|
} // @ts-ignore
|
|||
|
|
|
|||
|
|
|
|||
|
|
if (state.copy_) delete state.copy_[prop];
|
|||
|
|
return true;
|
|||
|
|
},
|
|||
|
|
// Note: We never coerce `desc.value` into an Immer draft, because we can't make
|
|||
|
|
// the same guarantee in ES5 mode.
|
|||
|
|
getOwnPropertyDescriptor: function getOwnPropertyDescriptor(state, prop) {
|
|||
|
|
var owner = latest(state);
|
|||
|
|
var desc = Reflect.getOwnPropertyDescriptor(owner, prop);
|
|||
|
|
if (!desc) return desc;
|
|||
|
|
return {
|
|||
|
|
writable: true,
|
|||
|
|
configurable: state.type_ !== 1
|
|||
|
|
/* ProxyArray */
|
|||
|
|
|| prop !== "length",
|
|||
|
|
enumerable: desc.enumerable,
|
|||
|
|
value: owner[prop]
|
|||
|
|
};
|
|||
|
|
},
|
|||
|
|
defineProperty: function defineProperty() {
|
|||
|
|
die(11);
|
|||
|
|
},
|
|||
|
|
getPrototypeOf: function getPrototypeOf(state) {
|
|||
|
|
return Object.getPrototypeOf(state.base_);
|
|||
|
|
},
|
|||
|
|
setPrototypeOf: function setPrototypeOf() {
|
|||
|
|
die(12);
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
/**
|
|||
|
|
* Array drafts
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
var arrayTraps = {};
|
|||
|
|
each$1(objectTraps, function (key, fn) {
|
|||
|
|
// @ts-ignore
|
|||
|
|
arrayTraps[key] = function () {
|
|||
|
|
arguments[0] = arguments[0][0];
|
|||
|
|
return fn.apply(this, arguments);
|
|||
|
|
};
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
arrayTraps.deleteProperty = function (state, prop) {
|
|||
|
|
if ( isNaN(parseInt(prop))) die(13);
|
|||
|
|
return objectTraps.deleteProperty.call(this, state[0], prop);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
arrayTraps.set = function (state, prop, value) {
|
|||
|
|
if ( prop !== "length" && isNaN(parseInt(prop))) die(14);
|
|||
|
|
return objectTraps.set.call(this, state[0], prop, value, state[0]);
|
|||
|
|
}; // Access a property without creating an Immer draft.
|
|||
|
|
|
|||
|
|
|
|||
|
|
function peek(draft, prop) {
|
|||
|
|
var state = draft[DRAFT_STATE];
|
|||
|
|
var source = state ? latest(state) : draft;
|
|||
|
|
return source[prop];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function readPropFromProto(state, source, prop) {
|
|||
|
|
var _desc$get;
|
|||
|
|
|
|||
|
|
var desc = getDescriptorFromProto(source, prop);
|
|||
|
|
return desc ? "value" in desc ? desc.value : // This is a very special case, if the prop is a getter defined by the
|
|||
|
|
// prototype, we should invoke it with the draft as context!
|
|||
|
|
(_desc$get = desc.get) === null || _desc$get === void 0 ? void 0 : _desc$get.call(state.draft_) : undefined;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function getDescriptorFromProto(source, prop) {
|
|||
|
|
// 'in' checks proto!
|
|||
|
|
if (!(prop in source)) return undefined;
|
|||
|
|
var proto = Object.getPrototypeOf(source);
|
|||
|
|
|
|||
|
|
while (proto) {
|
|||
|
|
var desc = Object.getOwnPropertyDescriptor(proto, prop);
|
|||
|
|
if (desc) return desc;
|
|||
|
|
proto = Object.getPrototypeOf(proto);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return undefined;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function markChanged(state) {
|
|||
|
|
if (!state.modified_) {
|
|||
|
|
state.modified_ = true;
|
|||
|
|
|
|||
|
|
if (state.parent_) {
|
|||
|
|
markChanged(state.parent_);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function prepareCopy(state) {
|
|||
|
|
if (!state.copy_) {
|
|||
|
|
state.copy_ = shallowCopy(state.base_);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var Immer =
|
|||
|
|
/*#__PURE__*/
|
|||
|
|
function () {
|
|||
|
|
function Immer(config) {
|
|||
|
|
var _this = this;
|
|||
|
|
|
|||
|
|
this.useProxies_ = hasProxies;
|
|||
|
|
this.autoFreeze_ = true;
|
|||
|
|
/**
|
|||
|
|
* The `produce` function takes a value and a "recipe function" (whose
|
|||
|
|
* return value often depends on the base state). The recipe function is
|
|||
|
|
* free to mutate its first argument however it wants. All mutations are
|
|||
|
|
* only ever applied to a __copy__ of the base state.
|
|||
|
|
*
|
|||
|
|
* Pass only a function to create a "curried producer" which relieves you
|
|||
|
|
* from passing the recipe function every time.
|
|||
|
|
*
|
|||
|
|
* Only plain objects and arrays are made mutable. All other objects are
|
|||
|
|
* considered uncopyable.
|
|||
|
|
*
|
|||
|
|
* Note: This function is __bound__ to its `Immer` instance.
|
|||
|
|
*
|
|||
|
|
* @param {any} base - the initial state
|
|||
|
|
* @param {Function} producer - function that receives a proxy of the base state as first argument and which can be freely modified
|
|||
|
|
* @param {Function} patchListener - optional function that will be called with all the patches produced here
|
|||
|
|
* @returns {any} a new state, or the initial state if nothing was modified
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
this.produce = function (base, recipe, patchListener) {
|
|||
|
|
// curried invocation
|
|||
|
|
if (typeof base === "function" && typeof recipe !== "function") {
|
|||
|
|
var defaultBase = recipe;
|
|||
|
|
recipe = base;
|
|||
|
|
var self = _this;
|
|||
|
|
return function curriedProduce(base) {
|
|||
|
|
var _this2 = this;
|
|||
|
|
|
|||
|
|
if (base === void 0) {
|
|||
|
|
base = defaultBase;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|||
|
|
args[_key - 1] = arguments[_key];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return self.produce(base, function (draft) {
|
|||
|
|
var _recipe;
|
|||
|
|
|
|||
|
|
return (_recipe = recipe).call.apply(_recipe, [_this2, draft].concat(args));
|
|||
|
|
}); // prettier-ignore
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (typeof recipe !== "function") die(6);
|
|||
|
|
if (patchListener !== undefined && typeof patchListener !== "function") die(7);
|
|||
|
|
var result; // Only plain objects, arrays, and "immerable classes" are drafted.
|
|||
|
|
|
|||
|
|
if (isDraftable(base)) {
|
|||
|
|
var scope = enterScope(_this);
|
|||
|
|
var proxy = createProxy(_this, base, undefined);
|
|||
|
|
var hasError = true;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
result = recipe(proxy);
|
|||
|
|
hasError = false;
|
|||
|
|
} finally {
|
|||
|
|
// finally instead of catch + rethrow better preserves original stack
|
|||
|
|
if (hasError) revokeScope(scope);else leaveScope(scope);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (typeof Promise !== "undefined" && result instanceof Promise) {
|
|||
|
|
return result.then(function (result) {
|
|||
|
|
usePatchesInScope(scope, patchListener);
|
|||
|
|
return processResult(result, scope);
|
|||
|
|
}, function (error) {
|
|||
|
|
revokeScope(scope);
|
|||
|
|
throw error;
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
usePatchesInScope(scope, patchListener);
|
|||
|
|
return processResult(result, scope);
|
|||
|
|
} else if (!base || typeof base !== "object") {
|
|||
|
|
result = recipe(base);
|
|||
|
|
if (result === NOTHING) return undefined;
|
|||
|
|
if (result === undefined) result = base;
|
|||
|
|
if (_this.autoFreeze_) freeze(result, true);
|
|||
|
|
return result;
|
|||
|
|
} else die(21, base);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
this.produceWithPatches = function (arg1, arg2, arg3) {
|
|||
|
|
if (typeof arg1 === "function") {
|
|||
|
|
return function (state) {
|
|||
|
|
for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
|
|||
|
|
args[_key2 - 1] = arguments[_key2];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return _this.produceWithPatches(state, function (draft) {
|
|||
|
|
return arg1.apply(void 0, [draft].concat(args));
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var patches, inversePatches;
|
|||
|
|
|
|||
|
|
var nextState = _this.produce(arg1, arg2, function (p, ip) {
|
|||
|
|
patches = p;
|
|||
|
|
inversePatches = ip;
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
return [nextState, patches, inversePatches];
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
if (typeof (config === null || config === void 0 ? void 0 : config.useProxies) === "boolean") this.setUseProxies(config.useProxies);
|
|||
|
|
if (typeof (config === null || config === void 0 ? void 0 : config.autoFreeze) === "boolean") this.setAutoFreeze(config.autoFreeze);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var _proto = Immer.prototype;
|
|||
|
|
|
|||
|
|
_proto.createDraft = function createDraft(base) {
|
|||
|
|
if (!isDraftable(base)) die(8);
|
|||
|
|
if (isDraft(base)) base = current(base);
|
|||
|
|
var scope = enterScope(this);
|
|||
|
|
var proxy = createProxy(this, base, undefined);
|
|||
|
|
proxy[DRAFT_STATE].isManual_ = true;
|
|||
|
|
leaveScope(scope);
|
|||
|
|
return proxy;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
_proto.finishDraft = function finishDraft(draft, patchListener) {
|
|||
|
|
var state = draft && draft[DRAFT_STATE];
|
|||
|
|
|
|||
|
|
{
|
|||
|
|
if (!state || !state.isManual_) die(9);
|
|||
|
|
if (state.finalized_) die(10);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var scope = state.scope_;
|
|||
|
|
usePatchesInScope(scope, patchListener);
|
|||
|
|
return processResult(undefined, scope);
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Pass true to automatically freeze all copies created by Immer.
|
|||
|
|
*
|
|||
|
|
* By default, auto-freezing is enabled.
|
|||
|
|
*/
|
|||
|
|
;
|
|||
|
|
|
|||
|
|
_proto.setAutoFreeze = function setAutoFreeze(value) {
|
|||
|
|
this.autoFreeze_ = value;
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Pass true to use the ES2015 `Proxy` class when creating drafts, which is
|
|||
|
|
* always faster than using ES5 proxies.
|
|||
|
|
*
|
|||
|
|
* By default, feature detection is used, so calling this is rarely necessary.
|
|||
|
|
*/
|
|||
|
|
;
|
|||
|
|
|
|||
|
|
_proto.setUseProxies = function setUseProxies(value) {
|
|||
|
|
if (value && !hasProxies) {
|
|||
|
|
die(20);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
this.useProxies_ = value;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
_proto.applyPatches = function applyPatches(base, patches) {
|
|||
|
|
// If a patch replaces the entire state, take that replacement as base
|
|||
|
|
// before applying patches
|
|||
|
|
var i;
|
|||
|
|
|
|||
|
|
for (i = patches.length - 1; i >= 0; i--) {
|
|||
|
|
var patch = patches[i];
|
|||
|
|
|
|||
|
|
if (patch.path.length === 0 && patch.op === "replace") {
|
|||
|
|
base = patch.value;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
} // If there was a patch that replaced the entire state, start from the
|
|||
|
|
// patch after that.
|
|||
|
|
|
|||
|
|
|
|||
|
|
if (i > -1) {
|
|||
|
|
patches = patches.slice(i + 1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var applyPatchesImpl = getPlugin("Patches").applyPatches_;
|
|||
|
|
|
|||
|
|
if (isDraft(base)) {
|
|||
|
|
// N.B: never hits if some patch a replacement, patches are never drafts
|
|||
|
|
return applyPatchesImpl(base, patches);
|
|||
|
|
} // Otherwise, produce a copy of the base state.
|
|||
|
|
|
|||
|
|
|
|||
|
|
return this.produce(base, function (draft) {
|
|||
|
|
return applyPatchesImpl(draft, patches);
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
return Immer;
|
|||
|
|
}();
|
|||
|
|
function createProxy(immer, value, parent) {
|
|||
|
|
// precondition: createProxy should be guarded by isDraftable, so we know we can safely draft
|
|||
|
|
var draft = isMap(value) ? getPlugin("MapSet").proxyMap_(value, parent) : isSet(value) ? getPlugin("MapSet").proxySet_(value, parent) : immer.useProxies_ ? createProxyProxy(value, parent) : getPlugin("ES5").createES5Proxy_(value, parent);
|
|||
|
|
var scope = parent ? parent.scope_ : getCurrentScope();
|
|||
|
|
scope.drafts_.push(draft);
|
|||
|
|
return draft;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function current(value) {
|
|||
|
|
if (!isDraft(value)) die(22, value);
|
|||
|
|
return currentImpl(value);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function currentImpl(value) {
|
|||
|
|
if (!isDraftable(value)) return value;
|
|||
|
|
var state = value[DRAFT_STATE];
|
|||
|
|
var copy;
|
|||
|
|
var archType = getArchtype(value);
|
|||
|
|
|
|||
|
|
if (state) {
|
|||
|
|
if (!state.modified_ && (state.type_ < 4 || !getPlugin("ES5").hasChanges_(state))) return state.base_; // Optimization: avoid generating new drafts during copying
|
|||
|
|
|
|||
|
|
state.finalized_ = true;
|
|||
|
|
copy = copyHelper(value, archType);
|
|||
|
|
state.finalized_ = false;
|
|||
|
|
} else {
|
|||
|
|
copy = copyHelper(value, archType);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
each$1(copy, function (key, childValue) {
|
|||
|
|
if (state && get(state.base_, key) === childValue) return; // no need to copy or search in something that didn't change
|
|||
|
|
|
|||
|
|
set(copy, key, currentImpl(childValue));
|
|||
|
|
}); // In the future, we might consider freezing here, based on the current settings
|
|||
|
|
|
|||
|
|
return archType === 3
|
|||
|
|
/* Set */
|
|||
|
|
? new Set(copy) : copy;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function copyHelper(value, archType) {
|
|||
|
|
// creates a shallow copy, even if it is a map or set
|
|||
|
|
switch (archType) {
|
|||
|
|
case 2
|
|||
|
|
/* Map */
|
|||
|
|
:
|
|||
|
|
return new Map(value);
|
|||
|
|
|
|||
|
|
case 3
|
|||
|
|
/* Set */
|
|||
|
|
:
|
|||
|
|
// Set will be cloned as array temporarily, so that we can replace individual items
|
|||
|
|
return Array.from(value);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return shallowCopy(value);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function enableES5() {
|
|||
|
|
function willFinalizeES5_(scope, result, isReplaced) {
|
|||
|
|
if (!isReplaced) {
|
|||
|
|
if (scope.patches_) {
|
|||
|
|
markChangesRecursively(scope.drafts_[0]);
|
|||
|
|
} // This is faster when we don't care about which attributes changed.
|
|||
|
|
|
|||
|
|
|
|||
|
|
markChangesSweep(scope.drafts_);
|
|||
|
|
} // When a child draft is returned, look for changes.
|
|||
|
|
else if (isDraft(result) && result[DRAFT_STATE].scope_ === scope) {
|
|||
|
|
markChangesSweep(scope.drafts_);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function createES5Draft(isArray, base) {
|
|||
|
|
if (isArray) {
|
|||
|
|
var draft = new Array(base.length);
|
|||
|
|
|
|||
|
|
for (var i = 0; i < base.length; i++) {
|
|||
|
|
Object.defineProperty(draft, "" + i, proxyProperty(i, true));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return draft;
|
|||
|
|
} else {
|
|||
|
|
var _descriptors = getOwnPropertyDescriptors(base);
|
|||
|
|
|
|||
|
|
delete _descriptors[DRAFT_STATE];
|
|||
|
|
var keys = ownKeys$a(_descriptors);
|
|||
|
|
|
|||
|
|
for (var _i = 0; _i < keys.length; _i++) {
|
|||
|
|
var key = keys[_i];
|
|||
|
|
_descriptors[key] = proxyProperty(key, isArray || !!_descriptors[key].enumerable);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return Object.create(Object.getPrototypeOf(base), _descriptors);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function createES5Proxy_(base, parent) {
|
|||
|
|
var isArray = Array.isArray(base);
|
|||
|
|
var draft = createES5Draft(isArray, base);
|
|||
|
|
var state = {
|
|||
|
|
type_: isArray ? 5
|
|||
|
|
/* ES5Array */
|
|||
|
|
: 4
|
|||
|
|
/* ES5Object */
|
|||
|
|
,
|
|||
|
|
scope_: parent ? parent.scope_ : getCurrentScope(),
|
|||
|
|
modified_: false,
|
|||
|
|
finalized_: false,
|
|||
|
|
assigned_: {},
|
|||
|
|
parent_: parent,
|
|||
|
|
// base is the object we are drafting
|
|||
|
|
base_: base,
|
|||
|
|
// draft is the draft object itself, that traps all reads and reads from either the base (if unmodified) or copy (if modified)
|
|||
|
|
draft_: draft,
|
|||
|
|
copy_: null,
|
|||
|
|
revoked_: false,
|
|||
|
|
isManual_: false
|
|||
|
|
};
|
|||
|
|
Object.defineProperty(draft, DRAFT_STATE, {
|
|||
|
|
value: state,
|
|||
|
|
// enumerable: false <- the default
|
|||
|
|
writable: true
|
|||
|
|
});
|
|||
|
|
return draft;
|
|||
|
|
} // property descriptors are recycled to make sure we don't create a get and set closure per property,
|
|||
|
|
// but share them all instead
|
|||
|
|
|
|||
|
|
|
|||
|
|
var descriptors = {};
|
|||
|
|
|
|||
|
|
function proxyProperty(prop, enumerable) {
|
|||
|
|
var desc = descriptors[prop];
|
|||
|
|
|
|||
|
|
if (desc) {
|
|||
|
|
desc.enumerable = enumerable;
|
|||
|
|
} else {
|
|||
|
|
descriptors[prop] = desc = {
|
|||
|
|
configurable: true,
|
|||
|
|
enumerable: enumerable,
|
|||
|
|
get: function get() {
|
|||
|
|
var state = this[DRAFT_STATE];
|
|||
|
|
assertUnrevoked(state); // @ts-ignore
|
|||
|
|
|
|||
|
|
return objectTraps.get(state, prop);
|
|||
|
|
},
|
|||
|
|
set: function set(value) {
|
|||
|
|
var state = this[DRAFT_STATE];
|
|||
|
|
assertUnrevoked(state); // @ts-ignore
|
|||
|
|
|
|||
|
|
objectTraps.set(state, prop, value);
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return desc;
|
|||
|
|
} // This looks expensive, but only proxies are visited, and only objects without known changes are scanned.
|
|||
|
|
|
|||
|
|
|
|||
|
|
function markChangesSweep(drafts) {
|
|||
|
|
// The natural order of drafts in the `scope` array is based on when they
|
|||
|
|
// were accessed. By processing drafts in reverse natural order, we have a
|
|||
|
|
// better chance of processing leaf nodes first. When a leaf node is known to
|
|||
|
|
// have changed, we can avoid any traversal of its ancestor nodes.
|
|||
|
|
for (var i = drafts.length - 1; i >= 0; i--) {
|
|||
|
|
var state = drafts[i][DRAFT_STATE];
|
|||
|
|
|
|||
|
|
if (!state.modified_) {
|
|||
|
|
switch (state.type_) {
|
|||
|
|
case 5
|
|||
|
|
/* ES5Array */
|
|||
|
|
:
|
|||
|
|
if (hasArrayChanges(state)) markChanged(state);
|
|||
|
|
break;
|
|||
|
|
|
|||
|
|
case 4
|
|||
|
|
/* ES5Object */
|
|||
|
|
:
|
|||
|
|
if (hasObjectChanges(state)) markChanged(state);
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function markChangesRecursively(object) {
|
|||
|
|
if (!object || typeof object !== "object") return;
|
|||
|
|
var state = object[DRAFT_STATE];
|
|||
|
|
if (!state) return;
|
|||
|
|
var base_ = state.base_,
|
|||
|
|
draft_ = state.draft_,
|
|||
|
|
assigned_ = state.assigned_,
|
|||
|
|
type_ = state.type_;
|
|||
|
|
|
|||
|
|
if (type_ === 4
|
|||
|
|
/* ES5Object */
|
|||
|
|
) {
|
|||
|
|
// Look for added keys.
|
|||
|
|
// probably there is a faster way to detect changes, as sweep + recurse seems to do some
|
|||
|
|
// unnecessary work.
|
|||
|
|
// also: probably we can store the information we detect here, to speed up tree finalization!
|
|||
|
|
each$1(draft_, function (key) {
|
|||
|
|
if (key === DRAFT_STATE) return; // The `undefined` check is a fast path for pre-existing keys.
|
|||
|
|
|
|||
|
|
if (base_[key] === undefined && !has(base_, key)) {
|
|||
|
|
assigned_[key] = true;
|
|||
|
|
markChanged(state);
|
|||
|
|
} else if (!assigned_[key]) {
|
|||
|
|
// Only untouched properties trigger recursion.
|
|||
|
|
markChangesRecursively(draft_[key]);
|
|||
|
|
}
|
|||
|
|
}); // Look for removed keys.
|
|||
|
|
|
|||
|
|
each$1(base_, function (key) {
|
|||
|
|
// The `undefined` check is a fast path for pre-existing keys.
|
|||
|
|
if (draft_[key] === undefined && !has(draft_, key)) {
|
|||
|
|
assigned_[key] = false;
|
|||
|
|
markChanged(state);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
} else if (type_ === 5
|
|||
|
|
/* ES5Array */
|
|||
|
|
) {
|
|||
|
|
if (hasArrayChanges(state)) {
|
|||
|
|
markChanged(state);
|
|||
|
|
assigned_.length = true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (draft_.length < base_.length) {
|
|||
|
|
for (var i = draft_.length; i < base_.length; i++) {
|
|||
|
|
assigned_[i] = false;
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
for (var _i2 = base_.length; _i2 < draft_.length; _i2++) {
|
|||
|
|
assigned_[_i2] = true;
|
|||
|
|
}
|
|||
|
|
} // Minimum count is enough, the other parts has been processed.
|
|||
|
|
|
|||
|
|
|
|||
|
|
var min = Math.min(draft_.length, base_.length);
|
|||
|
|
|
|||
|
|
for (var _i3 = 0; _i3 < min; _i3++) {
|
|||
|
|
// Only untouched indices trigger recursion.
|
|||
|
|
if (assigned_[_i3] === undefined) markChangesRecursively(draft_[_i3]);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function hasObjectChanges(state) {
|
|||
|
|
var base_ = state.base_,
|
|||
|
|
draft_ = state.draft_; // Search for added keys and changed keys. Start at the back, because
|
|||
|
|
// non-numeric keys are ordered by time of definition on the object.
|
|||
|
|
|
|||
|
|
var keys = ownKeys$a(draft_);
|
|||
|
|
|
|||
|
|
for (var i = keys.length - 1; i >= 0; i--) {
|
|||
|
|
var key = keys[i];
|
|||
|
|
if (key === DRAFT_STATE) continue;
|
|||
|
|
var baseValue = base_[key]; // The `undefined` check is a fast path for pre-existing keys.
|
|||
|
|
|
|||
|
|
if (baseValue === undefined && !has(base_, key)) {
|
|||
|
|
return true;
|
|||
|
|
} // Once a base key is deleted, future changes go undetected, because its
|
|||
|
|
// descriptor is erased. This branch detects any missed changes.
|
|||
|
|
else {
|
|||
|
|
var value = draft_[key];
|
|||
|
|
|
|||
|
|
var _state = value && value[DRAFT_STATE];
|
|||
|
|
|
|||
|
|
if (_state ? _state.base_ !== baseValue : !is$1(value, baseValue)) {
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
} // At this point, no keys were added or changed.
|
|||
|
|
// Compare key count to determine if keys were deleted.
|
|||
|
|
|
|||
|
|
|
|||
|
|
var baseIsDraft = !!base_[DRAFT_STATE];
|
|||
|
|
return keys.length !== ownKeys$a(base_).length + (baseIsDraft ? 0 : 1); // + 1 to correct for DRAFT_STATE
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function hasArrayChanges(state) {
|
|||
|
|
var draft_ = state.draft_;
|
|||
|
|
if (draft_.length !== state.base_.length) return true; // See #116
|
|||
|
|
// If we first shorten the length, our array interceptors will be removed.
|
|||
|
|
// If after that new items are added, result in the same original length,
|
|||
|
|
// those last items will have no intercepting property.
|
|||
|
|
// So if there is no own descriptor on the last position, we know that items were removed and added
|
|||
|
|
// N.B.: splice, unshift, etc only shift values around, but not prop descriptors, so we only have to check
|
|||
|
|
// the last one
|
|||
|
|
|
|||
|
|
var descriptor = Object.getOwnPropertyDescriptor(draft_, draft_.length - 1); // descriptor can be null, but only for newly created sparse arrays, eg. new Array(10)
|
|||
|
|
|
|||
|
|
if (descriptor && !descriptor.get) return true; // For all other cases, we don't have to compare, as they would have been picked up by the index setters
|
|||
|
|
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function hasChanges_(state) {
|
|||
|
|
return state.type_ === 4
|
|||
|
|
/* ES5Object */
|
|||
|
|
? hasObjectChanges(state) : hasArrayChanges(state);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function assertUnrevoked(state
|
|||
|
|
/*ES5State | MapState | SetState*/
|
|||
|
|
) {
|
|||
|
|
if (state.revoked_) die(3, JSON.stringify(latest(state)));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
loadPlugin("ES5", {
|
|||
|
|
createES5Proxy_: createES5Proxy_,
|
|||
|
|
willFinalizeES5_: willFinalizeES5_,
|
|||
|
|
hasChanges_: hasChanges_
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function enablePatches() {
|
|||
|
|
var REPLACE = "replace";
|
|||
|
|
var ADD = "add";
|
|||
|
|
var REMOVE = "remove";
|
|||
|
|
|
|||
|
|
function generatePatches_(state, basePath, patches, inversePatches) {
|
|||
|
|
switch (state.type_) {
|
|||
|
|
case 0
|
|||
|
|
/* ProxyObject */
|
|||
|
|
:
|
|||
|
|
case 4
|
|||
|
|
/* ES5Object */
|
|||
|
|
:
|
|||
|
|
case 2
|
|||
|
|
/* Map */
|
|||
|
|
:
|
|||
|
|
return generatePatchesFromAssigned(state, basePath, patches, inversePatches);
|
|||
|
|
|
|||
|
|
case 5
|
|||
|
|
/* ES5Array */
|
|||
|
|
:
|
|||
|
|
case 1
|
|||
|
|
/* ProxyArray */
|
|||
|
|
:
|
|||
|
|
return generateArrayPatches(state, basePath, patches, inversePatches);
|
|||
|
|
|
|||
|
|
case 3
|
|||
|
|
/* Set */
|
|||
|
|
:
|
|||
|
|
return generateSetPatches(state, basePath, patches, inversePatches);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function generateArrayPatches(state, basePath, patches, inversePatches) {
|
|||
|
|
var base_ = state.base_,
|
|||
|
|
assigned_ = state.assigned_;
|
|||
|
|
var copy_ = state.copy_; // Reduce complexity by ensuring `base` is never longer.
|
|||
|
|
|
|||
|
|
if (copy_.length < base_.length) {
|
|||
|
|
var _ref = [copy_, base_];
|
|||
|
|
base_ = _ref[0];
|
|||
|
|
copy_ = _ref[1];
|
|||
|
|
var _ref2 = [inversePatches, patches];
|
|||
|
|
patches = _ref2[0];
|
|||
|
|
inversePatches = _ref2[1];
|
|||
|
|
} // Process replaced indices.
|
|||
|
|
|
|||
|
|
|
|||
|
|
for (var i = 0; i < base_.length; i++) {
|
|||
|
|
if (assigned_[i] && copy_[i] !== base_[i]) {
|
|||
|
|
var path = basePath.concat([i]);
|
|||
|
|
patches.push({
|
|||
|
|
op: REPLACE,
|
|||
|
|
path: path,
|
|||
|
|
// Need to maybe clone it, as it can in fact be the original value
|
|||
|
|
// due to the base/copy inversion at the start of this function
|
|||
|
|
value: clonePatchValueIfNeeded(copy_[i])
|
|||
|
|
});
|
|||
|
|
inversePatches.push({
|
|||
|
|
op: REPLACE,
|
|||
|
|
path: path,
|
|||
|
|
value: clonePatchValueIfNeeded(base_[i])
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
} // Process added indices.
|
|||
|
|
|
|||
|
|
|
|||
|
|
for (var _i = base_.length; _i < copy_.length; _i++) {
|
|||
|
|
var _path = basePath.concat([_i]);
|
|||
|
|
|
|||
|
|
patches.push({
|
|||
|
|
op: ADD,
|
|||
|
|
path: _path,
|
|||
|
|
// Need to maybe clone it, as it can in fact be the original value
|
|||
|
|
// due to the base/copy inversion at the start of this function
|
|||
|
|
value: clonePatchValueIfNeeded(copy_[_i])
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (base_.length < copy_.length) {
|
|||
|
|
inversePatches.push({
|
|||
|
|
op: REPLACE,
|
|||
|
|
path: basePath.concat(["length"]),
|
|||
|
|
value: base_.length
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
} // This is used for both Map objects and normal objects.
|
|||
|
|
|
|||
|
|
|
|||
|
|
function generatePatchesFromAssigned(state, basePath, patches, inversePatches) {
|
|||
|
|
var base_ = state.base_,
|
|||
|
|
copy_ = state.copy_;
|
|||
|
|
each$1(state.assigned_, function (key, assignedValue) {
|
|||
|
|
var origValue = get(base_, key);
|
|||
|
|
var value = get(copy_, key);
|
|||
|
|
var op = !assignedValue ? REMOVE : has(base_, key) ? REPLACE : ADD;
|
|||
|
|
if (origValue === value && op === REPLACE) return;
|
|||
|
|
var path = basePath.concat(key);
|
|||
|
|
patches.push(op === REMOVE ? {
|
|||
|
|
op: op,
|
|||
|
|
path: path
|
|||
|
|
} : {
|
|||
|
|
op: op,
|
|||
|
|
path: path,
|
|||
|
|
value: value
|
|||
|
|
});
|
|||
|
|
inversePatches.push(op === ADD ? {
|
|||
|
|
op: REMOVE,
|
|||
|
|
path: path
|
|||
|
|
} : op === REMOVE ? {
|
|||
|
|
op: ADD,
|
|||
|
|
path: path,
|
|||
|
|
value: clonePatchValueIfNeeded(origValue)
|
|||
|
|
} : {
|
|||
|
|
op: REPLACE,
|
|||
|
|
path: path,
|
|||
|
|
value: clonePatchValueIfNeeded(origValue)
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function generateSetPatches(state, basePath, patches, inversePatches) {
|
|||
|
|
var base_ = state.base_,
|
|||
|
|
copy_ = state.copy_;
|
|||
|
|
var i = 0;
|
|||
|
|
base_.forEach(function (value) {
|
|||
|
|
if (!copy_.has(value)) {
|
|||
|
|
var path = basePath.concat([i]);
|
|||
|
|
patches.push({
|
|||
|
|
op: REMOVE,
|
|||
|
|
path: path,
|
|||
|
|
value: value
|
|||
|
|
});
|
|||
|
|
inversePatches.unshift({
|
|||
|
|
op: ADD,
|
|||
|
|
path: path,
|
|||
|
|
value: value
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
i++;
|
|||
|
|
});
|
|||
|
|
i = 0;
|
|||
|
|
copy_.forEach(function (value) {
|
|||
|
|
if (!base_.has(value)) {
|
|||
|
|
var path = basePath.concat([i]);
|
|||
|
|
patches.push({
|
|||
|
|
op: ADD,
|
|||
|
|
path: path,
|
|||
|
|
value: value
|
|||
|
|
});
|
|||
|
|
inversePatches.unshift({
|
|||
|
|
op: REMOVE,
|
|||
|
|
path: path,
|
|||
|
|
value: value
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
i++;
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function generateReplacementPatches_(rootState, replacement, patches, inversePatches) {
|
|||
|
|
patches.push({
|
|||
|
|
op: REPLACE,
|
|||
|
|
path: [],
|
|||
|
|
value: replacement === NOTHING ? undefined : replacement
|
|||
|
|
});
|
|||
|
|
inversePatches.push({
|
|||
|
|
op: REPLACE,
|
|||
|
|
path: [],
|
|||
|
|
value: rootState.base_
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function applyPatches_(draft, patches) {
|
|||
|
|
patches.forEach(function (patch) {
|
|||
|
|
var path = patch.path,
|
|||
|
|
op = patch.op;
|
|||
|
|
var base = draft;
|
|||
|
|
|
|||
|
|
for (var i = 0; i < path.length - 1; i++) {
|
|||
|
|
var parentType = getArchtype(base);
|
|||
|
|
var p = "" + path[i]; // See #738, avoid prototype pollution
|
|||
|
|
|
|||
|
|
if ((parentType === 0
|
|||
|
|
/* Object */
|
|||
|
|
|| parentType === 1
|
|||
|
|
/* Array */
|
|||
|
|
) && (p === "__proto__" || p === "constructor")) die(24);
|
|||
|
|
if (typeof base === "function" && p === "prototype") die(24);
|
|||
|
|
base = get(base, p);
|
|||
|
|
if (typeof base !== "object") die(15, path.join("/"));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var type = getArchtype(base);
|
|||
|
|
var value = deepClonePatchValue(patch.value); // used to clone patch to ensure original patch is not modified, see #411
|
|||
|
|
|
|||
|
|
var key = path[path.length - 1];
|
|||
|
|
|
|||
|
|
switch (op) {
|
|||
|
|
case REPLACE:
|
|||
|
|
switch (type) {
|
|||
|
|
case 2
|
|||
|
|
/* Map */
|
|||
|
|
:
|
|||
|
|
return base.set(key, value);
|
|||
|
|
|
|||
|
|
/* istanbul ignore next */
|
|||
|
|
|
|||
|
|
case 3
|
|||
|
|
/* Set */
|
|||
|
|
:
|
|||
|
|
die(16);
|
|||
|
|
|
|||
|
|
default:
|
|||
|
|
// if value is an object, then it's assigned by reference
|
|||
|
|
// in the following add or remove ops, the value field inside the patch will also be modifyed
|
|||
|
|
// so we use value from the cloned patch
|
|||
|
|
// @ts-ignore
|
|||
|
|
return base[key] = value;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
case ADD:
|
|||
|
|
switch (type) {
|
|||
|
|
case 1
|
|||
|
|
/* Array */
|
|||
|
|
:
|
|||
|
|
return key === "-" ? base.push(value) : base.splice(key, 0, value);
|
|||
|
|
|
|||
|
|
case 2
|
|||
|
|
/* Map */
|
|||
|
|
:
|
|||
|
|
return base.set(key, value);
|
|||
|
|
|
|||
|
|
case 3
|
|||
|
|
/* Set */
|
|||
|
|
:
|
|||
|
|
return base.add(value);
|
|||
|
|
|
|||
|
|
default:
|
|||
|
|
return base[key] = value;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
case REMOVE:
|
|||
|
|
switch (type) {
|
|||
|
|
case 1
|
|||
|
|
/* Array */
|
|||
|
|
:
|
|||
|
|
return base.splice(key, 1);
|
|||
|
|
|
|||
|
|
case 2
|
|||
|
|
/* Map */
|
|||
|
|
:
|
|||
|
|
return base.delete(key);
|
|||
|
|
|
|||
|
|
case 3
|
|||
|
|
/* Set */
|
|||
|
|
:
|
|||
|
|
return base.delete(patch.value);
|
|||
|
|
|
|||
|
|
default:
|
|||
|
|
return delete base[key];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
default:
|
|||
|
|
die(17, op);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
return draft;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function deepClonePatchValue(obj) {
|
|||
|
|
if (!isDraftable(obj)) return obj;
|
|||
|
|
if (Array.isArray(obj)) return obj.map(deepClonePatchValue);
|
|||
|
|
if (isMap(obj)) return new Map(Array.from(obj.entries()).map(function (_ref3) {
|
|||
|
|
var k = _ref3[0],
|
|||
|
|
v = _ref3[1];
|
|||
|
|
return [k, deepClonePatchValue(v)];
|
|||
|
|
}));
|
|||
|
|
if (isSet(obj)) return new Set(Array.from(obj).map(deepClonePatchValue));
|
|||
|
|
var cloned = Object.create(Object.getPrototypeOf(obj));
|
|||
|
|
|
|||
|
|
for (var key in obj) {
|
|||
|
|
cloned[key] = deepClonePatchValue(obj[key]);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (has(obj, DRAFTABLE)) cloned[DRAFTABLE] = obj[DRAFTABLE];
|
|||
|
|
return cloned;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function clonePatchValueIfNeeded(obj) {
|
|||
|
|
if (isDraft(obj)) {
|
|||
|
|
return deepClonePatchValue(obj);
|
|||
|
|
} else return obj;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
loadPlugin("Patches", {
|
|||
|
|
applyPatches_: applyPatches_,
|
|||
|
|
generatePatches_: generatePatches_,
|
|||
|
|
generateReplacementPatches_: generateReplacementPatches_
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// types only!
|
|||
|
|
function enableMapSet() {
|
|||
|
|
/* istanbul ignore next */
|
|||
|
|
var _extendStatics = function extendStatics(d, b) {
|
|||
|
|
_extendStatics = Object.setPrototypeOf || {
|
|||
|
|
__proto__: []
|
|||
|
|
} instanceof Array && function (d, b) {
|
|||
|
|
d.__proto__ = b;
|
|||
|
|
} || function (d, b) {
|
|||
|
|
for (var p in b) {
|
|||
|
|
if (b.hasOwnProperty(p)) d[p] = b[p];
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
return _extendStatics(d, b);
|
|||
|
|
}; // Ugly hack to resolve #502 and inherit built in Map / Set
|
|||
|
|
|
|||
|
|
|
|||
|
|
function __extends(d, b) {
|
|||
|
|
_extendStatics(d, b);
|
|||
|
|
|
|||
|
|
function __() {
|
|||
|
|
this.constructor = d;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
d.prototype = ( // @ts-ignore
|
|||
|
|
__.prototype = b.prototype, new __());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var DraftMap = function (_super) {
|
|||
|
|
__extends(DraftMap, _super); // Create class manually, cause #502
|
|||
|
|
|
|||
|
|
|
|||
|
|
function DraftMap(target, parent) {
|
|||
|
|
this[DRAFT_STATE] = {
|
|||
|
|
type_: 2
|
|||
|
|
/* Map */
|
|||
|
|
,
|
|||
|
|
parent_: parent,
|
|||
|
|
scope_: parent ? parent.scope_ : getCurrentScope(),
|
|||
|
|
modified_: false,
|
|||
|
|
finalized_: false,
|
|||
|
|
copy_: undefined,
|
|||
|
|
assigned_: undefined,
|
|||
|
|
base_: target,
|
|||
|
|
draft_: this,
|
|||
|
|
isManual_: false,
|
|||
|
|
revoked_: false
|
|||
|
|
};
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var p = DraftMap.prototype;
|
|||
|
|
Object.defineProperty(p, "size", {
|
|||
|
|
get: function get() {
|
|||
|
|
return latest(this[DRAFT_STATE]).size;
|
|||
|
|
} // enumerable: false,
|
|||
|
|
// configurable: true
|
|||
|
|
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
p.has = function (key) {
|
|||
|
|
return latest(this[DRAFT_STATE]).has(key);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
p.set = function (key, value) {
|
|||
|
|
var state = this[DRAFT_STATE];
|
|||
|
|
assertUnrevoked(state);
|
|||
|
|
|
|||
|
|
if (!latest(state).has(key) || latest(state).get(key) !== value) {
|
|||
|
|
prepareMapCopy(state);
|
|||
|
|
markChanged(state);
|
|||
|
|
state.assigned_.set(key, true);
|
|||
|
|
state.copy_.set(key, value);
|
|||
|
|
state.assigned_.set(key, true);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return this;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
p.delete = function (key) {
|
|||
|
|
if (!this.has(key)) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var state = this[DRAFT_STATE];
|
|||
|
|
assertUnrevoked(state);
|
|||
|
|
prepareMapCopy(state);
|
|||
|
|
markChanged(state);
|
|||
|
|
state.assigned_.set(key, false);
|
|||
|
|
state.copy_.delete(key);
|
|||
|
|
return true;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
p.clear = function () {
|
|||
|
|
var state = this[DRAFT_STATE];
|
|||
|
|
assertUnrevoked(state);
|
|||
|
|
|
|||
|
|
if (latest(state).size) {
|
|||
|
|
prepareMapCopy(state);
|
|||
|
|
markChanged(state);
|
|||
|
|
state.assigned_ = new Map();
|
|||
|
|
each$1(state.base_, function (key) {
|
|||
|
|
state.assigned_.set(key, false);
|
|||
|
|
});
|
|||
|
|
state.copy_.clear();
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
p.forEach = function (cb, thisArg) {
|
|||
|
|
var _this = this;
|
|||
|
|
|
|||
|
|
var state = this[DRAFT_STATE];
|
|||
|
|
latest(state).forEach(function (_value, key, _map) {
|
|||
|
|
cb.call(thisArg, _this.get(key), key, _this);
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
p.get = function (key) {
|
|||
|
|
var state = this[DRAFT_STATE];
|
|||
|
|
assertUnrevoked(state);
|
|||
|
|
var value = latest(state).get(key);
|
|||
|
|
|
|||
|
|
if (state.finalized_ || !isDraftable(value)) {
|
|||
|
|
return value;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (value !== state.base_.get(key)) {
|
|||
|
|
return value; // either already drafted or reassigned
|
|||
|
|
} // despite what it looks, this creates a draft only once, see above condition
|
|||
|
|
|
|||
|
|
|
|||
|
|
var draft = createProxy(state.scope_.immer_, value, state);
|
|||
|
|
prepareMapCopy(state);
|
|||
|
|
state.copy_.set(key, draft);
|
|||
|
|
return draft;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
p.keys = function () {
|
|||
|
|
return latest(this[DRAFT_STATE]).keys();
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
p.values = function () {
|
|||
|
|
var _this2 = this,
|
|||
|
|
_ref;
|
|||
|
|
|
|||
|
|
var iterator = this.keys();
|
|||
|
|
return _ref = {}, _ref[iteratorSymbol$1] = function () {
|
|||
|
|
return _this2.values();
|
|||
|
|
}, _ref.next = function next() {
|
|||
|
|
var r = iterator.next();
|
|||
|
|
/* istanbul ignore next */
|
|||
|
|
|
|||
|
|
if (r.done) return r;
|
|||
|
|
|
|||
|
|
var value = _this2.get(r.value);
|
|||
|
|
|
|||
|
|
return {
|
|||
|
|
done: false,
|
|||
|
|
value: value
|
|||
|
|
};
|
|||
|
|
}, _ref;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
p.entries = function () {
|
|||
|
|
var _this3 = this,
|
|||
|
|
_ref2;
|
|||
|
|
|
|||
|
|
var iterator = this.keys();
|
|||
|
|
return _ref2 = {}, _ref2[iteratorSymbol$1] = function () {
|
|||
|
|
return _this3.entries();
|
|||
|
|
}, _ref2.next = function next() {
|
|||
|
|
var r = iterator.next();
|
|||
|
|
/* istanbul ignore next */
|
|||
|
|
|
|||
|
|
if (r.done) return r;
|
|||
|
|
|
|||
|
|
var value = _this3.get(r.value);
|
|||
|
|
|
|||
|
|
return {
|
|||
|
|
done: false,
|
|||
|
|
value: [r.value, value]
|
|||
|
|
};
|
|||
|
|
}, _ref2;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
p[iteratorSymbol$1] = function () {
|
|||
|
|
return this.entries();
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
return DraftMap;
|
|||
|
|
}(Map);
|
|||
|
|
|
|||
|
|
function proxyMap_(target, parent) {
|
|||
|
|
// @ts-ignore
|
|||
|
|
return new DraftMap(target, parent);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function prepareMapCopy(state) {
|
|||
|
|
if (!state.copy_) {
|
|||
|
|
state.assigned_ = new Map();
|
|||
|
|
state.copy_ = new Map(state.base_);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var DraftSet = function (_super) {
|
|||
|
|
__extends(DraftSet, _super); // Create class manually, cause #502
|
|||
|
|
|
|||
|
|
|
|||
|
|
function DraftSet(target, parent) {
|
|||
|
|
this[DRAFT_STATE] = {
|
|||
|
|
type_: 3
|
|||
|
|
/* Set */
|
|||
|
|
,
|
|||
|
|
parent_: parent,
|
|||
|
|
scope_: parent ? parent.scope_ : getCurrentScope(),
|
|||
|
|
modified_: false,
|
|||
|
|
finalized_: false,
|
|||
|
|
copy_: undefined,
|
|||
|
|
base_: target,
|
|||
|
|
draft_: this,
|
|||
|
|
drafts_: new Map(),
|
|||
|
|
revoked_: false,
|
|||
|
|
isManual_: false
|
|||
|
|
};
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var p = DraftSet.prototype;
|
|||
|
|
Object.defineProperty(p, "size", {
|
|||
|
|
get: function get() {
|
|||
|
|
return latest(this[DRAFT_STATE]).size;
|
|||
|
|
} // enumerable: true,
|
|||
|
|
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
p.has = function (value) {
|
|||
|
|
var state = this[DRAFT_STATE];
|
|||
|
|
assertUnrevoked(state); // bit of trickery here, to be able to recognize both the value, and the draft of its value
|
|||
|
|
|
|||
|
|
if (!state.copy_) {
|
|||
|
|
return state.base_.has(value);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (state.copy_.has(value)) return true;
|
|||
|
|
if (state.drafts_.has(value) && state.copy_.has(state.drafts_.get(value))) return true;
|
|||
|
|
return false;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
p.add = function (value) {
|
|||
|
|
var state = this[DRAFT_STATE];
|
|||
|
|
assertUnrevoked(state);
|
|||
|
|
|
|||
|
|
if (!this.has(value)) {
|
|||
|
|
prepareSetCopy(state);
|
|||
|
|
markChanged(state);
|
|||
|
|
state.copy_.add(value);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return this;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
p.delete = function (value) {
|
|||
|
|
if (!this.has(value)) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var state = this[DRAFT_STATE];
|
|||
|
|
assertUnrevoked(state);
|
|||
|
|
prepareSetCopy(state);
|
|||
|
|
markChanged(state);
|
|||
|
|
return state.copy_.delete(value) || (state.drafts_.has(value) ? state.copy_.delete(state.drafts_.get(value)) :
|
|||
|
|
/* istanbul ignore next */
|
|||
|
|
false);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
p.clear = function () {
|
|||
|
|
var state = this[DRAFT_STATE];
|
|||
|
|
assertUnrevoked(state);
|
|||
|
|
|
|||
|
|
if (latest(state).size) {
|
|||
|
|
prepareSetCopy(state);
|
|||
|
|
markChanged(state);
|
|||
|
|
state.copy_.clear();
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
p.values = function () {
|
|||
|
|
var state = this[DRAFT_STATE];
|
|||
|
|
assertUnrevoked(state);
|
|||
|
|
prepareSetCopy(state);
|
|||
|
|
return state.copy_.values();
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
p.entries = function entries() {
|
|||
|
|
var state = this[DRAFT_STATE];
|
|||
|
|
assertUnrevoked(state);
|
|||
|
|
prepareSetCopy(state);
|
|||
|
|
return state.copy_.entries();
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
p.keys = function () {
|
|||
|
|
return this.values();
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
p[iteratorSymbol$1] = function () {
|
|||
|
|
return this.values();
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
p.forEach = function forEach(cb, thisArg) {
|
|||
|
|
var iterator = this.values();
|
|||
|
|
var result = iterator.next();
|
|||
|
|
|
|||
|
|
while (!result.done) {
|
|||
|
|
cb.call(thisArg, result.value, result.value, this);
|
|||
|
|
result = iterator.next();
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
return DraftSet;
|
|||
|
|
}(Set);
|
|||
|
|
|
|||
|
|
function proxySet_(target, parent) {
|
|||
|
|
// @ts-ignore
|
|||
|
|
return new DraftSet(target, parent);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function prepareSetCopy(state) {
|
|||
|
|
if (!state.copy_) {
|
|||
|
|
// create drafts for all entries to preserve insertion order
|
|||
|
|
state.copy_ = new Set();
|
|||
|
|
state.base_.forEach(function (value) {
|
|||
|
|
if (isDraftable(value)) {
|
|||
|
|
var draft = createProxy(state.scope_.immer_, value, state);
|
|||
|
|
state.drafts_.set(value, draft);
|
|||
|
|
state.copy_.add(draft);
|
|||
|
|
} else {
|
|||
|
|
state.copy_.add(value);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function assertUnrevoked(state
|
|||
|
|
/*ES5State | MapState | SetState*/
|
|||
|
|
) {
|
|||
|
|
if (state.revoked_) die(3, JSON.stringify(latest(state)));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
loadPlugin("MapSet", {
|
|||
|
|
proxyMap_: proxyMap_,
|
|||
|
|
proxySet_: proxySet_
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function enableAllPlugins() {
|
|||
|
|
enableES5();
|
|||
|
|
enableMapSet();
|
|||
|
|
enablePatches();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var immer$1 =
|
|||
|
|
/*#__PURE__*/
|
|||
|
|
new Immer();
|
|||
|
|
/**
|
|||
|
|
* The `produce` function takes a value and a "recipe function" (whose
|
|||
|
|
* return value often depends on the base state). The recipe function is
|
|||
|
|
* free to mutate its first argument however it wants. All mutations are
|
|||
|
|
* only ever applied to a __copy__ of the base state.
|
|||
|
|
*
|
|||
|
|
* Pass only a function to create a "curried producer" which relieves you
|
|||
|
|
* from passing the recipe function every time.
|
|||
|
|
*
|
|||
|
|
* Only plain objects and arrays are made mutable. All other objects are
|
|||
|
|
* considered uncopyable.
|
|||
|
|
*
|
|||
|
|
* Note: This function is __bound__ to its `Immer` instance.
|
|||
|
|
*
|
|||
|
|
* @param {any} base - the initial state
|
|||
|
|
* @param {Function} producer - function that receives a proxy of the base state as first argument and which can be freely modified
|
|||
|
|
* @param {Function} patchListener - optional function that will be called with all the patches produced here
|
|||
|
|
* @returns {any} a new state, or the initial state if nothing was modified
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
var produce = immer$1.produce;
|
|||
|
|
/**
|
|||
|
|
* Like `produce`, but `produceWithPatches` always returns a tuple
|
|||
|
|
* [nextState, patches, inversePatches] (instead of just the next state)
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
var produceWithPatches =
|
|||
|
|
/*#__PURE__*/
|
|||
|
|
immer$1.produceWithPatches.bind(immer$1);
|
|||
|
|
/**
|
|||
|
|
* Pass true to automatically freeze all copies created by Immer.
|
|||
|
|
*
|
|||
|
|
* Always freeze by default, even in production mode
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
var setAutoFreeze =
|
|||
|
|
/*#__PURE__*/
|
|||
|
|
immer$1.setAutoFreeze.bind(immer$1);
|
|||
|
|
/**
|
|||
|
|
* Pass true to use the ES2015 `Proxy` class when creating drafts, which is
|
|||
|
|
* always faster than using ES5 proxies.
|
|||
|
|
*
|
|||
|
|
* By default, feature detection is used, so calling this is rarely necessary.
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
var setUseProxies =
|
|||
|
|
/*#__PURE__*/
|
|||
|
|
immer$1.setUseProxies.bind(immer$1);
|
|||
|
|
/**
|
|||
|
|
* Apply an array of Immer patches to the first argument.
|
|||
|
|
*
|
|||
|
|
* This function is a producer, which means copy-on-write is in effect.
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
var applyPatches =
|
|||
|
|
/*#__PURE__*/
|
|||
|
|
immer$1.applyPatches.bind(immer$1);
|
|||
|
|
/**
|
|||
|
|
* Create an Immer draft from the given base state, which may be a draft itself.
|
|||
|
|
* The draft can be modified until you finalize it with the `finishDraft` function.
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
var createDraft =
|
|||
|
|
/*#__PURE__*/
|
|||
|
|
immer$1.createDraft.bind(immer$1);
|
|||
|
|
/**
|
|||
|
|
* Finalize an Immer draft from a `createDraft` call, returning the base state
|
|||
|
|
* (if no changes were made) or a modified copy. The draft must *not* be
|
|||
|
|
* mutated afterwards.
|
|||
|
|
*
|
|||
|
|
* Pass a function as the 2nd argument to generate Immer patches based on the
|
|||
|
|
* changes that were made.
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
var finishDraft =
|
|||
|
|
/*#__PURE__*/
|
|||
|
|
immer$1.finishDraft.bind(immer$1);
|
|||
|
|
/**
|
|||
|
|
* This function is actually a no-op, but can be used to cast an immutable type
|
|||
|
|
* to an draft type and make TypeScript happy
|
|||
|
|
*
|
|||
|
|
* @param value
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
function castDraft(value) {
|
|||
|
|
return value;
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* This function is actually a no-op, but can be used to cast a mutable type
|
|||
|
|
* to an immutable type and make TypeScript happy
|
|||
|
|
* @param value
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
function castImmutable(value) {
|
|||
|
|
return value;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var Immer_1 = Immer;
|
|||
|
|
var applyPatches_1 = applyPatches;
|
|||
|
|
var castDraft_1 = castDraft;
|
|||
|
|
var castImmutable_1 = castImmutable;
|
|||
|
|
var createDraft_1 = createDraft;
|
|||
|
|
var current_1 = current;
|
|||
|
|
var _default$2 = produce;
|
|||
|
|
var enableAllPlugins_1 = enableAllPlugins;
|
|||
|
|
var enableES5_1 = enableES5;
|
|||
|
|
var enableMapSet_1 = enableMapSet;
|
|||
|
|
var enablePatches_1 = enablePatches;
|
|||
|
|
var finishDraft_1 = finishDraft;
|
|||
|
|
var freeze_1 = freeze;
|
|||
|
|
var immerable = DRAFTABLE;
|
|||
|
|
var isDraft_1 = isDraft;
|
|||
|
|
var isDraftable_1 = isDraftable;
|
|||
|
|
var nothing = NOTHING;
|
|||
|
|
var original_1 = original;
|
|||
|
|
var produce_1 = produce;
|
|||
|
|
var produceWithPatches_1 = produceWithPatches;
|
|||
|
|
var setAutoFreeze_1 = setAutoFreeze;
|
|||
|
|
var setUseProxies_1 = setUseProxies;
|
|||
|
|
|
|||
|
|
|
|||
|
|
var immer_cjs_development = /*#__PURE__*/Object.defineProperty({
|
|||
|
|
Immer: Immer_1,
|
|||
|
|
applyPatches: applyPatches_1,
|
|||
|
|
castDraft: castDraft_1,
|
|||
|
|
castImmutable: castImmutable_1,
|
|||
|
|
createDraft: createDraft_1,
|
|||
|
|
current: current_1,
|
|||
|
|
default: _default$2,
|
|||
|
|
enableAllPlugins: enableAllPlugins_1,
|
|||
|
|
enableES5: enableES5_1,
|
|||
|
|
enableMapSet: enableMapSet_1,
|
|||
|
|
enablePatches: enablePatches_1,
|
|||
|
|
finishDraft: finishDraft_1,
|
|||
|
|
freeze: freeze_1,
|
|||
|
|
immerable: immerable,
|
|||
|
|
isDraft: isDraft_1,
|
|||
|
|
isDraftable: isDraftable_1,
|
|||
|
|
nothing: nothing,
|
|||
|
|
original: original_1,
|
|||
|
|
produce: produce_1,
|
|||
|
|
produceWithPatches: produceWithPatches_1,
|
|||
|
|
setAutoFreeze: setAutoFreeze_1,
|
|||
|
|
setUseProxies: setUseProxies_1
|
|||
|
|
}, '__esModule', {value: true});
|
|||
|
|
|
|||
|
|
var require$$1$1 = immer_cjs_development;
|
|||
|
|
|
|||
|
|
var dist$8 = createCommonjsModule$1(function (module) {
|
|||
|
|
|
|||
|
|
{
|
|||
|
|
module.exports = require$$1$1;
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
var isPlainObject = isPlainObject_1;
|
|||
|
|
|
|||
|
|
var immer = dist$8;
|
|||
|
|
|
|||
|
|
function unwrapExports (x) {
|
|||
|
|
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function createCommonjsModule(fn, module) {
|
|||
|
|
return module = { exports: {} }, fn(module, module.exports), module.exports;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var arrayLikeToArray = createCommonjsModule(function (module) {
|
|||
|
|
function _arrayLikeToArray(arr, len) {
|
|||
|
|
if (len == null || len > arr.length) len = arr.length;
|
|||
|
|
|
|||
|
|
for (var i = 0, arr2 = new Array(len); i < len; i++) {
|
|||
|
|
arr2[i] = arr[i];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return arr2;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
module.exports = _arrayLikeToArray;
|
|||
|
|
module.exports["default"] = module.exports, module.exports.__esModule = true;
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
unwrapExports(arrayLikeToArray);
|
|||
|
|
|
|||
|
|
var arrayWithoutHoles = createCommonjsModule(function (module) {
|
|||
|
|
function _arrayWithoutHoles(arr) {
|
|||
|
|
if (Array.isArray(arr)) return arrayLikeToArray(arr);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
module.exports = _arrayWithoutHoles;
|
|||
|
|
module.exports["default"] = module.exports, module.exports.__esModule = true;
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
unwrapExports(arrayWithoutHoles);
|
|||
|
|
|
|||
|
|
var iterableToArray = createCommonjsModule(function (module) {
|
|||
|
|
function _iterableToArray(iter) {
|
|||
|
|
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
module.exports = _iterableToArray;
|
|||
|
|
module.exports["default"] = module.exports, module.exports.__esModule = true;
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
unwrapExports(iterableToArray);
|
|||
|
|
|
|||
|
|
var unsupportedIterableToArray = createCommonjsModule(function (module) {
|
|||
|
|
function _unsupportedIterableToArray(o, minLen) {
|
|||
|
|
if (!o) return;
|
|||
|
|
if (typeof o === "string") return arrayLikeToArray(o, minLen);
|
|||
|
|
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|||
|
|
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|||
|
|
if (n === "Map" || n === "Set") return Array.from(o);
|
|||
|
|
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return arrayLikeToArray(o, minLen);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
module.exports = _unsupportedIterableToArray;
|
|||
|
|
module.exports["default"] = module.exports, module.exports.__esModule = true;
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
unwrapExports(unsupportedIterableToArray);
|
|||
|
|
|
|||
|
|
var nonIterableSpread = createCommonjsModule(function (module) {
|
|||
|
|
function _nonIterableSpread() {
|
|||
|
|
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
module.exports = _nonIterableSpread;
|
|||
|
|
module.exports["default"] = module.exports, module.exports.__esModule = true;
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
unwrapExports(nonIterableSpread);
|
|||
|
|
|
|||
|
|
var toConsumableArray = createCommonjsModule(function (module) {
|
|||
|
|
function _toConsumableArray(arr) {
|
|||
|
|
return arrayWithoutHoles(arr) || iterableToArray(arr) || unsupportedIterableToArray(arr) || nonIterableSpread();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
module.exports = _toConsumableArray;
|
|||
|
|
module.exports["default"] = module.exports, module.exports.__esModule = true;
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
var _toConsumableArray = unwrapExports(toConsumableArray);
|
|||
|
|
|
|||
|
|
var arrayWithHoles = createCommonjsModule(function (module) {
|
|||
|
|
function _arrayWithHoles(arr) {
|
|||
|
|
if (Array.isArray(arr)) return arr;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
module.exports = _arrayWithHoles;
|
|||
|
|
module.exports["default"] = module.exports, module.exports.__esModule = true;
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
unwrapExports(arrayWithHoles);
|
|||
|
|
|
|||
|
|
var iterableToArrayLimit = createCommonjsModule(function (module) {
|
|||
|
|
function _iterableToArrayLimit(arr, i) {
|
|||
|
|
var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
|
|||
|
|
|
|||
|
|
if (_i == null) return;
|
|||
|
|
var _arr = [];
|
|||
|
|
var _n = true;
|
|||
|
|
var _d = false;
|
|||
|
|
|
|||
|
|
var _s, _e;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {
|
|||
|
|
_arr.push(_s.value);
|
|||
|
|
|
|||
|
|
if (i && _arr.length === i) break;
|
|||
|
|
}
|
|||
|
|
} catch (err) {
|
|||
|
|
_d = true;
|
|||
|
|
_e = err;
|
|||
|
|
} finally {
|
|||
|
|
try {
|
|||
|
|
if (!_n && _i["return"] != null) _i["return"]();
|
|||
|
|
} finally {
|
|||
|
|
if (_d) throw _e;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return _arr;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
module.exports = _iterableToArrayLimit;
|
|||
|
|
module.exports["default"] = module.exports, module.exports.__esModule = true;
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
unwrapExports(iterableToArrayLimit);
|
|||
|
|
|
|||
|
|
var nonIterableRest = createCommonjsModule(function (module) {
|
|||
|
|
function _nonIterableRest() {
|
|||
|
|
throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
module.exports = _nonIterableRest;
|
|||
|
|
module.exports["default"] = module.exports, module.exports.__esModule = true;
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
unwrapExports(nonIterableRest);
|
|||
|
|
|
|||
|
|
var slicedToArray = createCommonjsModule(function (module) {
|
|||
|
|
function _slicedToArray(arr, i) {
|
|||
|
|
return arrayWithHoles(arr) || iterableToArrayLimit(arr, i) || unsupportedIterableToArray(arr, i) || nonIterableRest();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
module.exports = _slicedToArray;
|
|||
|
|
module.exports["default"] = module.exports, module.exports.__esModule = true;
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
var _slicedToArray = unwrapExports(slicedToArray);
|
|||
|
|
|
|||
|
|
var defineProperty = createCommonjsModule(function (module) {
|
|||
|
|
function _defineProperty(obj, key, value) {
|
|||
|
|
if (key in obj) {
|
|||
|
|
Object.defineProperty(obj, key, {
|
|||
|
|
value: value,
|
|||
|
|
enumerable: true,
|
|||
|
|
configurable: true,
|
|||
|
|
writable: true
|
|||
|
|
});
|
|||
|
|
} else {
|
|||
|
|
obj[key] = value;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return obj;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
module.exports = _defineProperty;
|
|||
|
|
module.exports["default"] = module.exports, module.exports.__esModule = true;
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
var _defineProperty = unwrapExports(defineProperty);
|
|||
|
|
|
|||
|
|
var DIRTY_PATHS = new WeakMap();
|
|||
|
|
var FLUSHING = new WeakMap();
|
|||
|
|
var NORMALIZING = new WeakMap();
|
|||
|
|
var PATH_REFS = new WeakMap();
|
|||
|
|
var POINT_REFS = new WeakMap();
|
|||
|
|
var RANGE_REFS = new WeakMap();
|
|||
|
|
|
|||
|
|
function ownKeys$9(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
|
|||
|
|
|
|||
|
|
function _objectSpread$9(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$9(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$9(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
|||
|
|
|
|||
|
|
function _createForOfIteratorHelper$7(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$7(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
|
|||
|
|
|
|||
|
|
function _unsupportedIterableToArray$7(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$7(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray$7(o, minLen); }
|
|||
|
|
|
|||
|
|
function _arrayLikeToArray$7(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|||
|
|
/**
|
|||
|
|
* Create a new Slate `Editor` object.
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
var createEditor$1 = function createEditor() {
|
|||
|
|
var editor = {
|
|||
|
|
children: [],
|
|||
|
|
operations: [],
|
|||
|
|
selection: null,
|
|||
|
|
marks: null,
|
|||
|
|
isInline: function isInline() {
|
|||
|
|
return false;
|
|||
|
|
},
|
|||
|
|
isVoid: function isVoid() {
|
|||
|
|
return false;
|
|||
|
|
},
|
|||
|
|
onChange: function onChange() {},
|
|||
|
|
apply: function apply(op) {
|
|||
|
|
var _iterator = _createForOfIteratorHelper$7(Editor.pathRefs(editor)),
|
|||
|
|
_step;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|||
|
|
var ref = _step.value;
|
|||
|
|
PathRef.transform(ref, op);
|
|||
|
|
}
|
|||
|
|
} catch (err) {
|
|||
|
|
_iterator.e(err);
|
|||
|
|
} finally {
|
|||
|
|
_iterator.f();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var _iterator2 = _createForOfIteratorHelper$7(Editor.pointRefs(editor)),
|
|||
|
|
_step2;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|||
|
|
var _ref = _step2.value;
|
|||
|
|
PointRef.transform(_ref, op);
|
|||
|
|
}
|
|||
|
|
} catch (err) {
|
|||
|
|
_iterator2.e(err);
|
|||
|
|
} finally {
|
|||
|
|
_iterator2.f();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var _iterator3 = _createForOfIteratorHelper$7(Editor.rangeRefs(editor)),
|
|||
|
|
_step3;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|||
|
|
var _ref2 = _step3.value;
|
|||
|
|
RangeRef.transform(_ref2, op);
|
|||
|
|
}
|
|||
|
|
} catch (err) {
|
|||
|
|
_iterator3.e(err);
|
|||
|
|
} finally {
|
|||
|
|
_iterator3.f();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var set = new Set();
|
|||
|
|
var dirtyPaths = [];
|
|||
|
|
|
|||
|
|
var add = function add(path) {
|
|||
|
|
if (path) {
|
|||
|
|
var key = path.join(',');
|
|||
|
|
|
|||
|
|
if (!set.has(key)) {
|
|||
|
|
set.add(key);
|
|||
|
|
dirtyPaths.push(path);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var oldDirtyPaths = DIRTY_PATHS.get(editor) || [];
|
|||
|
|
var newDirtyPaths = getDirtyPaths(op);
|
|||
|
|
|
|||
|
|
var _iterator4 = _createForOfIteratorHelper$7(oldDirtyPaths),
|
|||
|
|
_step4;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
|
|||
|
|
var path = _step4.value;
|
|||
|
|
var newPath = Path.transform(path, op);
|
|||
|
|
add(newPath);
|
|||
|
|
}
|
|||
|
|
} catch (err) {
|
|||
|
|
_iterator4.e(err);
|
|||
|
|
} finally {
|
|||
|
|
_iterator4.f();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var _iterator5 = _createForOfIteratorHelper$7(newDirtyPaths),
|
|||
|
|
_step5;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
|
|||
|
|
var _path = _step5.value;
|
|||
|
|
add(_path);
|
|||
|
|
}
|
|||
|
|
} catch (err) {
|
|||
|
|
_iterator5.e(err);
|
|||
|
|
} finally {
|
|||
|
|
_iterator5.f();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
DIRTY_PATHS.set(editor, dirtyPaths);
|
|||
|
|
Transforms.transform(editor, op);
|
|||
|
|
editor.operations.push(op);
|
|||
|
|
Editor.normalize(editor); // Clear any formats applied to the cursor if the selection changes.
|
|||
|
|
|
|||
|
|
if (op.type === 'set_selection') {
|
|||
|
|
editor.marks = null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!FLUSHING.get(editor)) {
|
|||
|
|
FLUSHING.set(editor, true);
|
|||
|
|
Promise.resolve().then(function () {
|
|||
|
|
FLUSHING.set(editor, false);
|
|||
|
|
editor.onChange();
|
|||
|
|
editor.operations = [];
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
addMark: function addMark(key, value) {
|
|||
|
|
var selection = editor.selection;
|
|||
|
|
|
|||
|
|
if (selection) {
|
|||
|
|
if (Range.isExpanded(selection)) {
|
|||
|
|
Transforms.setNodes(editor, _defineProperty({}, key, value), {
|
|||
|
|
match: Text.isText,
|
|||
|
|
split: true
|
|||
|
|
});
|
|||
|
|
} else {
|
|||
|
|
var marks = _objectSpread$9(_objectSpread$9({}, Editor.marks(editor) || {}), {}, _defineProperty({}, key, value));
|
|||
|
|
|
|||
|
|
editor.marks = marks;
|
|||
|
|
|
|||
|
|
if (!FLUSHING.get(editor)) {
|
|||
|
|
editor.onChange();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
deleteBackward: function deleteBackward(unit) {
|
|||
|
|
var selection = editor.selection;
|
|||
|
|
|
|||
|
|
if (selection && Range.isCollapsed(selection)) {
|
|||
|
|
Transforms["delete"](editor, {
|
|||
|
|
unit: unit,
|
|||
|
|
reverse: true
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
deleteForward: function deleteForward(unit) {
|
|||
|
|
var selection = editor.selection;
|
|||
|
|
|
|||
|
|
if (selection && Range.isCollapsed(selection)) {
|
|||
|
|
Transforms["delete"](editor, {
|
|||
|
|
unit: unit
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
deleteFragment: function deleteFragment(direction) {
|
|||
|
|
var selection = editor.selection;
|
|||
|
|
|
|||
|
|
if (selection && Range.isExpanded(selection)) {
|
|||
|
|
Transforms["delete"](editor, {
|
|||
|
|
reverse: direction === 'backward'
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
getFragment: function getFragment() {
|
|||
|
|
var selection = editor.selection;
|
|||
|
|
|
|||
|
|
if (selection) {
|
|||
|
|
return Node$1.fragment(editor, selection);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return [];
|
|||
|
|
},
|
|||
|
|
insertBreak: function insertBreak() {
|
|||
|
|
Transforms.splitNodes(editor, {
|
|||
|
|
always: true
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
insertFragment: function insertFragment(fragment) {
|
|||
|
|
Transforms.insertFragment(editor, fragment);
|
|||
|
|
},
|
|||
|
|
insertNode: function insertNode(node) {
|
|||
|
|
Transforms.insertNodes(editor, node);
|
|||
|
|
},
|
|||
|
|
insertText: function insertText(text) {
|
|||
|
|
var selection = editor.selection,
|
|||
|
|
marks = editor.marks;
|
|||
|
|
|
|||
|
|
if (selection) {
|
|||
|
|
if (marks) {
|
|||
|
|
var node = _objectSpread$9({
|
|||
|
|
text: text
|
|||
|
|
}, marks);
|
|||
|
|
|
|||
|
|
Transforms.insertNodes(editor, node);
|
|||
|
|
} else {
|
|||
|
|
Transforms.insertText(editor, text);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
editor.marks = null;
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
normalizeNode: function normalizeNode(entry) {
|
|||
|
|
var _entry = _slicedToArray(entry, 2),
|
|||
|
|
node = _entry[0],
|
|||
|
|
path = _entry[1]; // There are no core normalizations for text nodes.
|
|||
|
|
|
|||
|
|
|
|||
|
|
if (Text.isText(node)) {
|
|||
|
|
return;
|
|||
|
|
} // Ensure that block and inline nodes have at least one text child.
|
|||
|
|
|
|||
|
|
|
|||
|
|
if (Element$1.isElement(node) && node.children.length === 0) {
|
|||
|
|
var child = {
|
|||
|
|
text: ''
|
|||
|
|
};
|
|||
|
|
Transforms.insertNodes(editor, child, {
|
|||
|
|
at: path.concat(0),
|
|||
|
|
voids: true
|
|||
|
|
});
|
|||
|
|
return;
|
|||
|
|
} // Determine whether the node should have block or inline children.
|
|||
|
|
|
|||
|
|
|
|||
|
|
var shouldHaveInlines = Editor.isEditor(node) ? false : Element$1.isElement(node) && (editor.isInline(node) || node.children.length === 0 || Text.isText(node.children[0]) || editor.isInline(node.children[0])); // Since we'll be applying operations while iterating, keep track of an
|
|||
|
|
// index that accounts for any added/removed nodes.
|
|||
|
|
|
|||
|
|
var n = 0;
|
|||
|
|
|
|||
|
|
for (var i = 0; i < node.children.length; i++, n++) {
|
|||
|
|
var currentNode = Node$1.get(editor, path);
|
|||
|
|
if (Text.isText(currentNode)) continue;
|
|||
|
|
var _child = node.children[i];
|
|||
|
|
var prev = currentNode.children[n - 1];
|
|||
|
|
var isLast = i === node.children.length - 1;
|
|||
|
|
var isInlineOrText = Text.isText(_child) || Element$1.isElement(_child) && editor.isInline(_child); // Only allow block nodes in the top-level children and parent blocks
|
|||
|
|
// that only contain block nodes. Similarly, only allow inline nodes in
|
|||
|
|
// other inline nodes, or parent blocks that only contain inlines and
|
|||
|
|
// text.
|
|||
|
|
|
|||
|
|
if (isInlineOrText !== shouldHaveInlines) {
|
|||
|
|
Transforms.removeNodes(editor, {
|
|||
|
|
at: path.concat(n),
|
|||
|
|
voids: true
|
|||
|
|
});
|
|||
|
|
n--;
|
|||
|
|
} else if (Element$1.isElement(_child)) {
|
|||
|
|
// Ensure that inline nodes are surrounded by text nodes.
|
|||
|
|
if (editor.isInline(_child)) {
|
|||
|
|
if (prev == null || !Text.isText(prev)) {
|
|||
|
|
var newChild = {
|
|||
|
|
text: ''
|
|||
|
|
};
|
|||
|
|
Transforms.insertNodes(editor, newChild, {
|
|||
|
|
at: path.concat(n),
|
|||
|
|
voids: true
|
|||
|
|
});
|
|||
|
|
n++;
|
|||
|
|
} else if (isLast) {
|
|||
|
|
var _newChild = {
|
|||
|
|
text: ''
|
|||
|
|
};
|
|||
|
|
Transforms.insertNodes(editor, _newChild, {
|
|||
|
|
at: path.concat(n + 1),
|
|||
|
|
voids: true
|
|||
|
|
});
|
|||
|
|
n++;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
// Merge adjacent text nodes that are empty or match.
|
|||
|
|
if (prev != null && Text.isText(prev)) {
|
|||
|
|
if (Text.equals(_child, prev, {
|
|||
|
|
loose: true
|
|||
|
|
})) {
|
|||
|
|
Transforms.mergeNodes(editor, {
|
|||
|
|
at: path.concat(n),
|
|||
|
|
voids: true
|
|||
|
|
});
|
|||
|
|
n--;
|
|||
|
|
} else if (prev.text === '') {
|
|||
|
|
Transforms.removeNodes(editor, {
|
|||
|
|
at: path.concat(n - 1),
|
|||
|
|
voids: true
|
|||
|
|
});
|
|||
|
|
n--;
|
|||
|
|
} else if (_child.text === '') {
|
|||
|
|
Transforms.removeNodes(editor, {
|
|||
|
|
at: path.concat(n),
|
|||
|
|
voids: true
|
|||
|
|
});
|
|||
|
|
n--;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
removeMark: function removeMark(key) {
|
|||
|
|
var selection = editor.selection;
|
|||
|
|
|
|||
|
|
if (selection) {
|
|||
|
|
if (Range.isExpanded(selection)) {
|
|||
|
|
Transforms.unsetNodes(editor, key, {
|
|||
|
|
match: Text.isText,
|
|||
|
|
split: true
|
|||
|
|
});
|
|||
|
|
} else {
|
|||
|
|
var marks = _objectSpread$9({}, Editor.marks(editor) || {});
|
|||
|
|
|
|||
|
|
delete marks[key];
|
|||
|
|
editor.marks = marks;
|
|||
|
|
|
|||
|
|
if (!FLUSHING.get(editor)) {
|
|||
|
|
editor.onChange();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
return editor;
|
|||
|
|
};
|
|||
|
|
/**
|
|||
|
|
* Get the "dirty" paths generated from an operation.
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
var getDirtyPaths = function getDirtyPaths(op) {
|
|||
|
|
switch (op.type) {
|
|||
|
|
case 'insert_text':
|
|||
|
|
case 'remove_text':
|
|||
|
|
case 'set_node':
|
|||
|
|
{
|
|||
|
|
var path = op.path;
|
|||
|
|
return Path.levels(path);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
case 'insert_node':
|
|||
|
|
{
|
|||
|
|
var node = op.node,
|
|||
|
|
_path2 = op.path;
|
|||
|
|
var levels = Path.levels(_path2);
|
|||
|
|
var descendants = Text.isText(node) ? [] : Array.from(Node$1.nodes(node), function (_ref3) {
|
|||
|
|
var _ref4 = _slicedToArray(_ref3, 2),
|
|||
|
|
p = _ref4[1];
|
|||
|
|
|
|||
|
|
return _path2.concat(p);
|
|||
|
|
});
|
|||
|
|
return [].concat(_toConsumableArray(levels), _toConsumableArray(descendants));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
case 'merge_node':
|
|||
|
|
{
|
|||
|
|
var _path3 = op.path;
|
|||
|
|
var ancestors = Path.ancestors(_path3);
|
|||
|
|
var previousPath = Path.previous(_path3);
|
|||
|
|
return [].concat(_toConsumableArray(ancestors), [previousPath]);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
case 'move_node':
|
|||
|
|
{
|
|||
|
|
var _path4 = op.path,
|
|||
|
|
newPath = op.newPath;
|
|||
|
|
|
|||
|
|
if (Path.equals(_path4, newPath)) {
|
|||
|
|
return [];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var oldAncestors = [];
|
|||
|
|
var newAncestors = [];
|
|||
|
|
|
|||
|
|
var _iterator6 = _createForOfIteratorHelper$7(Path.ancestors(_path4)),
|
|||
|
|
_step6;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
|
|||
|
|
var ancestor = _step6.value;
|
|||
|
|
var p = Path.transform(ancestor, op);
|
|||
|
|
oldAncestors.push(p);
|
|||
|
|
}
|
|||
|
|
} catch (err) {
|
|||
|
|
_iterator6.e(err);
|
|||
|
|
} finally {
|
|||
|
|
_iterator6.f();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var _iterator7 = _createForOfIteratorHelper$7(Path.ancestors(newPath)),
|
|||
|
|
_step7;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
|
|||
|
|
var _ancestor = _step7.value;
|
|||
|
|
|
|||
|
|
var _p = Path.transform(_ancestor, op);
|
|||
|
|
|
|||
|
|
newAncestors.push(_p);
|
|||
|
|
}
|
|||
|
|
} catch (err) {
|
|||
|
|
_iterator7.e(err);
|
|||
|
|
} finally {
|
|||
|
|
_iterator7.f();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var newParent = newAncestors[newAncestors.length - 1];
|
|||
|
|
var newIndex = newPath[newPath.length - 1];
|
|||
|
|
var resultPath = newParent.concat(newIndex);
|
|||
|
|
return [].concat(oldAncestors, newAncestors, [resultPath]);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
case 'remove_node':
|
|||
|
|
{
|
|||
|
|
var _path5 = op.path;
|
|||
|
|
|
|||
|
|
var _ancestors = Path.ancestors(_path5);
|
|||
|
|
|
|||
|
|
return _toConsumableArray(_ancestors);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
case 'split_node':
|
|||
|
|
{
|
|||
|
|
var _path6 = op.path;
|
|||
|
|
|
|||
|
|
var _levels = Path.levels(_path6);
|
|||
|
|
|
|||
|
|
var nextPath = Path.next(_path6);
|
|||
|
|
return [].concat(_toConsumableArray(_levels), [nextPath]);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
default:
|
|||
|
|
{
|
|||
|
|
return [];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var objectWithoutPropertiesLoose = createCommonjsModule(function (module) {
|
|||
|
|
function _objectWithoutPropertiesLoose(source, excluded) {
|
|||
|
|
if (source == null) return {};
|
|||
|
|
var target = {};
|
|||
|
|
var sourceKeys = Object.keys(source);
|
|||
|
|
var key, i;
|
|||
|
|
|
|||
|
|
for (i = 0; i < sourceKeys.length; i++) {
|
|||
|
|
key = sourceKeys[i];
|
|||
|
|
if (excluded.indexOf(key) >= 0) continue;
|
|||
|
|
target[key] = source[key];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return target;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
module.exports = _objectWithoutPropertiesLoose;
|
|||
|
|
module.exports["default"] = module.exports, module.exports.__esModule = true;
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
unwrapExports(objectWithoutPropertiesLoose);
|
|||
|
|
|
|||
|
|
var objectWithoutProperties = createCommonjsModule(function (module) {
|
|||
|
|
function _objectWithoutProperties(source, excluded) {
|
|||
|
|
if (source == null) return {};
|
|||
|
|
var target = objectWithoutPropertiesLoose(source, excluded);
|
|||
|
|
var key, i;
|
|||
|
|
|
|||
|
|
if (Object.getOwnPropertySymbols) {
|
|||
|
|
var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
|
|||
|
|
|
|||
|
|
for (i = 0; i < sourceSymbolKeys.length; i++) {
|
|||
|
|
key = sourceSymbolKeys[i];
|
|||
|
|
if (excluded.indexOf(key) >= 0) continue;
|
|||
|
|
if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
|
|||
|
|
target[key] = source[key];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return target;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
module.exports = _objectWithoutProperties;
|
|||
|
|
module.exports["default"] = module.exports, module.exports.__esModule = true;
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
var _objectWithoutProperties = unwrapExports(objectWithoutProperties);
|
|||
|
|
|
|||
|
|
function _createForOfIteratorHelper$6(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$6(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
|
|||
|
|
|
|||
|
|
function _unsupportedIterableToArray$6(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$6(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray$6(o, minLen); }
|
|||
|
|
|
|||
|
|
function _arrayLikeToArray$6(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|||
|
|
|
|||
|
|
// Character (grapheme cluster) boundaries are determined according to
|
|||
|
|
// the default grapheme cluster boundary specification, extended grapheme clusters variant[1].
|
|||
|
|
//
|
|||
|
|
// References:
|
|||
|
|
//
|
|||
|
|
// [1] https://www.unicode.org/reports/tr29/#Default_Grapheme_Cluster_Table
|
|||
|
|
// [2] https://www.unicode.org/Public/UCD/latest/ucd/auxiliary/GraphemeBreakProperty.txt
|
|||
|
|
// [3] https://www.unicode.org/Public/UCD/latest/ucd/auxiliary/GraphemeBreakTest.html
|
|||
|
|
// [4] https://www.unicode.org/Public/UCD/latest/ucd/auxiliary/GraphemeBreakTest.txt
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Get the distance to the end of the first character in a string of text.
|
|||
|
|
*/
|
|||
|
|
var getCharacterDistance = function getCharacterDistance(str) {
|
|||
|
|
var isRTL = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|||
|
|
var isLTR = !isRTL;
|
|||
|
|
var codepoints = isRTL ? codepointsIteratorRTL(str) : str;
|
|||
|
|
var left = CodepointType.None;
|
|||
|
|
var right = CodepointType.None;
|
|||
|
|
var distance = 0; // Evaluation of these conditions are deferred.
|
|||
|
|
|
|||
|
|
var gb11 = null; // Is GB11 applicable?
|
|||
|
|
|
|||
|
|
var gb12Or13 = null; // Is GB12 or GB13 applicable?
|
|||
|
|
|
|||
|
|
var _iterator = _createForOfIteratorHelper$6(codepoints),
|
|||
|
|
_step;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|||
|
|
var _char = _step.value;
|
|||
|
|
|
|||
|
|
var code = _char.codePointAt(0);
|
|||
|
|
|
|||
|
|
if (!code) break;
|
|||
|
|
var type = getCodepointType(_char, code);
|
|||
|
|
|
|||
|
|
var _ref = isLTR ? [right, type] : [type, left];
|
|||
|
|
|
|||
|
|
var _ref2 = _slicedToArray(_ref, 2);
|
|||
|
|
|
|||
|
|
left = _ref2[0];
|
|||
|
|
right = _ref2[1];
|
|||
|
|
|
|||
|
|
if (intersects(left, CodepointType.ZWJ) && intersects(right, CodepointType.ExtPict)) {
|
|||
|
|
if (isLTR) {
|
|||
|
|
gb11 = endsWithEmojiZWJ(str.substring(0, distance));
|
|||
|
|
} else {
|
|||
|
|
gb11 = endsWithEmojiZWJ(str.substring(0, str.length - distance));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!gb11) break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (intersects(left, CodepointType.RI) && intersects(right, CodepointType.RI)) {
|
|||
|
|
if (gb12Or13 !== null) {
|
|||
|
|
gb12Or13 = !gb12Or13;
|
|||
|
|
} else {
|
|||
|
|
if (isLTR) {
|
|||
|
|
gb12Or13 = true;
|
|||
|
|
} else {
|
|||
|
|
gb12Or13 = endsWithOddNumberOfRIs(str.substring(0, str.length - distance));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!gb12Or13) break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (left !== CodepointType.None && right !== CodepointType.None && isBoundaryPair(left, right)) {
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
distance += _char.length;
|
|||
|
|
}
|
|||
|
|
} catch (err) {
|
|||
|
|
_iterator.e(err);
|
|||
|
|
} finally {
|
|||
|
|
_iterator.f();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return distance || 1;
|
|||
|
|
};
|
|||
|
|
var SPACE = /\s/;
|
|||
|
|
var PUNCTUATION = /[\u0021-\u0023\u0025-\u002A\u002C-\u002F\u003A\u003B\u003F\u0040\u005B-\u005D\u005F\u007B\u007D\u00A1\u00A7\u00AB\u00B6\u00B7\u00BB\u00BF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061E\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u0AF0\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166D\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E3B\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]/;
|
|||
|
|
var CHAMELEON = /['\u2018\u2019]/;
|
|||
|
|
/**
|
|||
|
|
* Get the distance to the end of the first word in a string of text.
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
var getWordDistance = function getWordDistance(text) {
|
|||
|
|
var isRTL = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|||
|
|
var dist = 0;
|
|||
|
|
var started = false;
|
|||
|
|
|
|||
|
|
while (text.length > 0) {
|
|||
|
|
var charDist = getCharacterDistance(text, isRTL);
|
|||
|
|
|
|||
|
|
var _splitByCharacterDist = splitByCharacterDistance(text, charDist, isRTL),
|
|||
|
|
_splitByCharacterDist2 = _slicedToArray(_splitByCharacterDist, 2),
|
|||
|
|
_char2 = _splitByCharacterDist2[0],
|
|||
|
|
remaining = _splitByCharacterDist2[1];
|
|||
|
|
|
|||
|
|
if (isWordCharacter(_char2, remaining, isRTL)) {
|
|||
|
|
started = true;
|
|||
|
|
dist += charDist;
|
|||
|
|
} else if (!started) {
|
|||
|
|
dist += charDist;
|
|||
|
|
} else {
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
text = remaining;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return dist;
|
|||
|
|
};
|
|||
|
|
/**
|
|||
|
|
* Split a string in two parts at a given distance starting from the end when
|
|||
|
|
* `isRTL` is set to `true`.
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
var splitByCharacterDistance = function splitByCharacterDistance(str, dist, isRTL) {
|
|||
|
|
if (isRTL) {
|
|||
|
|
var at = str.length - dist;
|
|||
|
|
return [str.slice(at, str.length), str.slice(0, at)];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return [str.slice(0, dist), str.slice(dist)];
|
|||
|
|
};
|
|||
|
|
/**
|
|||
|
|
* Check if a character is a word character. The `remaining` argument is used
|
|||
|
|
* because sometimes you must read subsequent characters to truly determine it.
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
var isWordCharacter = function isWordCharacter(_char3, remaining) {
|
|||
|
|
var isRTL = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|||
|
|
|
|||
|
|
if (SPACE.test(_char3)) {
|
|||
|
|
return false;
|
|||
|
|
} // Chameleons count as word characters as long as they're in a word, so
|
|||
|
|
// recurse to see if the next one is a word character or not.
|
|||
|
|
|
|||
|
|
|
|||
|
|
if (CHAMELEON.test(_char3)) {
|
|||
|
|
var charDist = getCharacterDistance(remaining, isRTL);
|
|||
|
|
|
|||
|
|
var _splitByCharacterDist3 = splitByCharacterDistance(remaining, charDist, isRTL),
|
|||
|
|
_splitByCharacterDist4 = _slicedToArray(_splitByCharacterDist3, 2),
|
|||
|
|
nextChar = _splitByCharacterDist4[0],
|
|||
|
|
nextRemaining = _splitByCharacterDist4[1];
|
|||
|
|
|
|||
|
|
if (isWordCharacter(nextChar, nextRemaining, isRTL)) {
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (PUNCTUATION.test(_char3)) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
};
|
|||
|
|
/**
|
|||
|
|
* Iterate on codepoints from right to left.
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
var codepointsIteratorRTL = function* codepointsIteratorRTL(str) {
|
|||
|
|
var end = str.length - 1;
|
|||
|
|
|
|||
|
|
for (var i = 0; i < str.length; i++) {
|
|||
|
|
var char1 = str.charAt(end - i);
|
|||
|
|
|
|||
|
|
if (isLowSurrogate(char1.charCodeAt(0))) {
|
|||
|
|
var char2 = str.charAt(end - i - 1);
|
|||
|
|
|
|||
|
|
if (isHighSurrogate(char2.charCodeAt(0))) {
|
|||
|
|
yield char2 + char1;
|
|||
|
|
i++;
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
yield char1;
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
/**
|
|||
|
|
* Is `charCode` a high surrogate.
|
|||
|
|
*
|
|||
|
|
* https://en.wikipedia.org/wiki/Universal_Character_Set_characters#Surrogates
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
var isHighSurrogate = function isHighSurrogate(charCode) {
|
|||
|
|
return charCode >= 0xd800 && charCode <= 0xdbff;
|
|||
|
|
};
|
|||
|
|
/**
|
|||
|
|
* Is `charCode` a low surrogate.
|
|||
|
|
*
|
|||
|
|
* https://en.wikipedia.org/wiki/Universal_Character_Set_characters#Surrogates
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
var isLowSurrogate = function isLowSurrogate(charCode) {
|
|||
|
|
return charCode >= 0xdc00 && charCode <= 0xdfff;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var CodepointType;
|
|||
|
|
|
|||
|
|
(function (CodepointType) {
|
|||
|
|
CodepointType[CodepointType["None"] = 0] = "None";
|
|||
|
|
CodepointType[CodepointType["Extend"] = 1] = "Extend";
|
|||
|
|
CodepointType[CodepointType["ZWJ"] = 2] = "ZWJ";
|
|||
|
|
CodepointType[CodepointType["RI"] = 4] = "RI";
|
|||
|
|
CodepointType[CodepointType["Prepend"] = 8] = "Prepend";
|
|||
|
|
CodepointType[CodepointType["SpacingMark"] = 16] = "SpacingMark";
|
|||
|
|
CodepointType[CodepointType["L"] = 32] = "L";
|
|||
|
|
CodepointType[CodepointType["V"] = 64] = "V";
|
|||
|
|
CodepointType[CodepointType["T"] = 128] = "T";
|
|||
|
|
CodepointType[CodepointType["LV"] = 256] = "LV";
|
|||
|
|
CodepointType[CodepointType["LVT"] = 512] = "LVT";
|
|||
|
|
CodepointType[CodepointType["ExtPict"] = 1024] = "ExtPict";
|
|||
|
|
CodepointType[CodepointType["Any"] = 2048] = "Any";
|
|||
|
|
})(CodepointType || (CodepointType = {}));
|
|||
|
|
|
|||
|
|
var reExtend = /^(?:[\u0300-\u036F\u0483-\u0489\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u07FD\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08D3-\u08E1\u08E3-\u0902\u093A\u093C\u0941-\u0948\u094D\u0951-\u0957\u0962\u0963\u0981\u09BC\u09BE\u09C1-\u09C4\u09CD\u09D7\u09E2\u09E3\u09FE\u0A01\u0A02\u0A3C\u0A41\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A70\u0A71\u0A75\u0A81\u0A82\u0ABC\u0AC1-\u0AC5\u0AC7\u0AC8\u0ACD\u0AE2\u0AE3\u0AFA-\u0AFF\u0B01\u0B3C\u0B3E\u0B3F\u0B41-\u0B44\u0B4D\u0B55-\u0B57\u0B62\u0B63\u0B82\u0BBE\u0BC0\u0BCD\u0BD7\u0C00\u0C04\u0C3E-\u0C40\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C81\u0CBC\u0CBF\u0CC2\u0CC6\u0CCC\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0D00\u0D01\u0D3B\u0D3C\u0D3E\u0D41-\u0D44\u0D4D\u0D57\u0D62\u0D63\u0D81\u0DCA\u0DCF\u0DD2-\u0DD4\u0DD6\u0DDF\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EBC\u0EC8-\u0ECD\u0F18\u0F19\u0F35\u0F37\u0F39\u0F71-\u0F7E\u0F80-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102D-\u1030\u1032-\u1037\u1039\u103A\u103D\u103E\u1058\u1059\u105E-\u1060\u1071-\u1074\u1082\u1085\u1086\u108D\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4\u17B5\u17B7-\u17BD\u17C6\u17C9-\u17D3\u17DD\u180B-\u180D\u1885\u1886\u18A9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193B\u1A17\u1A18\u1A1B\u1A56\u1A58-\u1A5E\u1A60\u1A62\u1A65-\u1A6C\u1A73-\u1A7C\u1A7F\u1AB0-\u1AC0\u1B00-\u1B03\u1B34-\u1B3A\u1B3C\u1B42\u1B6B-\u1B73\u1B80\u1B81\u1BA2-\u1BA5\u1BA8\u1BA9\u1BAB-\u1BAD\u1BE6\u1BE8\u1BE9\u1BED\u1BEF-\u1BF1\u1C2C-\u1C33\u1C36\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE0\u1CE2-\u1CE8\u1CED\u1CF4\u1CF8\u1CF9\u1DC0-\u1DF9\u1DFB-\u1DFF\u200C\u20D0-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099\u309A\uA66F-\uA672\uA674-\uA67D\uA69E\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA825\uA826\uA82C\uA8C4\uA8C5\uA8E0-\uA8F1\uA8FF\uA926-\uA92D\uA947-\uA951\uA980-\uA982\uA9B3\uA9B6-\uA9B9\uA9BC\uA9BD\uA9E5\uAA29-\uAA2E\uAA31\uAA32\uAA35\uAA36\uAA43\uAA4C\uAA7C\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEC\uAAED\uAAF6\uABE5\uABE8\uABED\uFB1E\uFE00-\uFE0F\uFE20-\uFE2F\uFF9E\uFF9F]|\uD800[\uDDFD\uDEE0\uDF76-\uDF7A]|\uD802[\uDE01-\uDE03\uDE05\uDE06\uDE0C-\uDE0F\uDE38-\uDE3A\uDE3F\uDEE5\uDEE6]|\uD803[\uDD24-\uDD27\uDEAB\uDEAC\uDF46-\uDF50]|\uD804[\uDC01\uDC38-\uDC46\uDC7F-\uDC81\uDCB3-\uDCB6\uDCB9\uDCBA\uDD00-\uDD02\uDD27-\uDD2B\uDD2D-\uDD34\uDD73\uDD80\uDD81\uDDB6-\uDDBE\uDDC9-\uDDCC\uDDCF\uDE2F-\uDE31\uDE34\uDE36\uDE37\uDE3E\uDEDF\uDEE3-\uDEEA\uDF00\uDF01\uDF3B\uDF3C\uDF3E\uDF40\uDF57\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC38-\uDC3F\uDC42-\uDC44\uDC46\uDC5E\uDCB0\uDCB3-\uDCB8\uDCBA\uDCBD\uDCBF\uDCC0\uDCC2\uDCC3\uDDAF\uDDB2-\uDDB5\uDDBC\uDDBD\uDDBF\uDDC0\uDDDC\uDDDD\uDE33-\uDE3A\uDE3D\uDE3F\uDE40\uDEAB\uDEAD\uDEB0-\uDEB5\uDEB7\uDF1D-\uDF1F\uDF22-\uDF25\uDF27-\uDF2B]|\uD806[\uDC2F-\uDC37\uDC39\uDC3A\uDD30\uDD3B\uDD3C\uDD3E\uDD43\uDDD4-\uDDD7\uDDDA\uDDDB\uDDE0\uDE01-\uDE0A\uDE33-\uDE38\uDE3B-\uDE3E\uDE47\uDE51-\uDE56\uDE59-\uDE5B\uDE8A-\uDE96\uDE98\uDE99]|\uD807[\uDC30-\uDC36\uDC38-\uDC3D\uDC3F\uDC92-\uDCA7\uDCAA-\uDCB0\uDCB2\uDCB3\uDCB5\uDCB6\uDD31-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD45\uDD47\uDD90\uDD91\uDD95\uDD97\uDEF3\uDEF4]|\uD81A[\uDEF0-\uDEF4\uDF30-\uDF36]|\uD81B[\uDF4F\uDF8F-\uDF92\uDFE4]|\uD82F[\uDC9D\uDC9E]|\uD834[\uDD65\uDD67-\uDD69\uDD6E-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A\uDD30-\uDD36\uDEEC-\uDEEF]|\uD83A[\uDCD0-\uDCD6\uDD44-\uDD4A]|\uD83C[\uDFFB-\uDFFF]|\uDB40[\uDC20-\uDC7F\uDD00-\uDDEF])$/;
|
|||
|
|
var rePrepend = /^(?:[\u0600-\u0605\u06DD\u070F\u0890\u0891\u08E2\u0D4E]|\uD804[\uDCBD\uDCCD\uDDC2\uDDC3]|\uD806[\uDD3F\uDD41\uDE3A\uDE84-\uDE89]|\uD807\uDD46)$/;
|
|||
|
|
var reSpacingMark = /^(?:[\u0903\u093B\u093E-\u0940\u0949-\u094C\u094E\u094F\u0982\u0983\u09BF\u09C0\u09C7\u09C8\u09CB\u09CC\u0A03\u0A3E-\u0A40\u0A83\u0ABE-\u0AC0\u0AC9\u0ACB\u0ACC\u0B02\u0B03\u0B40\u0B47\u0B48\u0B4B\u0B4C\u0BBF\u0BC1\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCC\u0C01-\u0C03\u0C41-\u0C44\u0C82\u0C83\u0CBE\u0CC0\u0CC1\u0CC3\u0CC4\u0CC7\u0CC8\u0CCA\u0CCB\u0D02\u0D03\u0D3F\u0D40\u0D46-\u0D48\u0D4A-\u0D4C\u0D82\u0D83\u0DD0\u0DD1\u0DD8-\u0DDE\u0DF2\u0DF3\u0E33\u0EB3\u0F3E\u0F3F\u0F7F\u1031\u103B\u103C\u1056\u1057\u1084\u1715\u1734\u17B6\u17BE-\u17C5\u17C7\u17C8\u1923-\u1926\u1929-\u192B\u1930\u1931\u1933-\u1938\u1A19\u1A1A\u1A55\u1A57\u1A6D-\u1A72\u1B04\u1B3B\u1B3D-\u1B41\u1B43\u1B44\u1B82\u1BA1\u1BA6\u1BA7\u1BAA\u1BE7\u1BEA-\u1BEC\u1BEE\u1BF2\u1BF3\u1C24-\u1C2B\u1C34\u1C35\u1CE1\u1CF7\uA823\uA824\uA827\uA880\uA881\uA8B4-\uA8C3\uA952\uA953\uA983\uA9B4\uA9B5\uA9BA\uA9BB\uA9BE-\uA9C0\uAA2F\uAA30\uAA33\uAA34\uAA4D\uAAEB\uAAEE\uAAEF\uAAF5\uABE3\uABE4\uABE6\uABE7\uABE9\uABEA\uABEC]|\uD804[\uDC00\uDC02\uDC82\uDCB0-\uDCB2\uDCB7\uDCB8\uDD2C\uDD45\uDD46\uDD82\uDDB3-\uDDB5\uDDBF\uDDC0\uDDCE\uDE2C-\uDE2E\uDE32\uDE33\uDE35\uDEE0-\uDEE2\uDF02\uDF03\uDF3F\uDF41-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF62\uDF63]|\uD805[\uDC35-\uDC37\uDC40\uDC41\uDC45\uDCB1\uDCB2\uDCB9\uDCBB\uDCBC\uDCBE\uDCC1\uDDB0\uDDB1\uDDB8-\uDDBB\uDDBE\uDE30-\uDE32\uDE3B\uDE3C\uDE3E\uDEAC\uDEAE\uDEAF\uDEB6\uDF26]|\uD806[\uDC2C-\uDC2E\uDC38\uDD31-\uDD35\uDD37\uDD38\uDD3D\uDD40\uDD42\uDDD1-\uDDD3\uDDDC-\uDDDF\uDDE4\uDE39\uDE57\uDE58\uDE97]|\uD807[\uDC2F\uDC3E\uDCA9\uDCB1\uDCB4\uDD8A-\uDD8E\uDD93\uDD94\uDD96\uDEF5\uDEF6]|\uD81B[\uDF51-\uDF87\uDFF0\uDFF1]|\uD834[\uDD66\uDD6D])$/;
|
|||
|
|
var reL = /^[\u1100-\u115F\uA960-\uA97C]$/;
|
|||
|
|
var reV = /^[\u1160-\u11A7\uD7B0-\uD7C6]$/;
|
|||
|
|
var reT = /^[\u11A8-\u11FF\uD7CB-\uD7FB]$/;
|
|||
|
|
var reLV = /^[\uAC00\uAC1C\uAC38\uAC54\uAC70\uAC8C\uACA8\uACC4\uACE0\uACFC\uAD18\uAD34\uAD50\uAD6C\uAD88\uADA4\uADC0\uADDC\uADF8\uAE14\uAE30\uAE4C\uAE68\uAE84\uAEA0\uAEBC\uAED8\uAEF4\uAF10\uAF2C\uAF48\uAF64\uAF80\uAF9C\uAFB8\uAFD4\uAFF0\uB00C\uB028\uB044\uB060\uB07C\uB098\uB0B4\uB0D0\uB0EC\uB108\uB124\uB140\uB15C\uB178\uB194\uB1B0\uB1CC\uB1E8\uB204\uB220\uB23C\uB258\uB274\uB290\uB2AC\uB2C8\uB2E4\uB300\uB31C\uB338\uB354\uB370\uB38C\uB3A8\uB3C4\uB3E0\uB3FC\uB418\uB434\uB450\uB46C\uB488\uB4A4\uB4C0\uB4DC\uB4F8\uB514\uB530\uB54C\uB568\uB584\uB5A0\uB5BC\uB5D8\uB5F4\uB610\uB62C\uB648\uB664\uB680\uB69C\uB6B8\uB6D4\uB6F0\uB70C\uB728\uB744\uB760\uB77C\uB798\uB7B4\uB7D0\uB7EC\uB808\uB824\uB840\uB85C\uB878\uB894\uB8B0\uB8CC\uB8E8\uB904\uB920\uB93C\uB958\uB974\uB990\uB9AC\uB9C8\uB9E4\uBA00\uBA1C\uBA38\uBA54\uBA70\uBA8C\uBAA8\uBAC4\uBAE0\uBAFC\uBB18\uBB34\uBB50\uBB6C\uBB88\uBBA4\uBBC0\uBBDC\uBBF8\uBC14\uBC30\uBC4C\uBC68\uBC84\uBCA0\uBCBC\uBCD8\uBCF4\uBD10\uBD2C\uBD48\uBD64\uBD80\uBD9C\uBDB8\uBDD4\uBDF0\uBE0C\uBE28\uBE44\uBE60\uBE7C\uBE98\uBEB4\uBED0\uBEEC\uBF08\uBF24\uBF40\uBF5C\uBF78\uBF94\uBFB0\uBFCC\uBFE8\uC004\uC020\uC03C\uC058\uC074\uC090\uC0AC\uC0C8\uC0E4\uC100\uC11C\uC138\uC154\uC170\uC18C\uC1A8\uC1C4\uC1E0\uC1FC\uC218\uC234\uC250\uC26C\uC288\uC2A4\uC2C0\uC2DC\uC2F8\uC314\uC330\uC34C\uC368\uC384\uC3A0\uC3BC\uC3D8\uC3F4\uC410\uC42C\uC448\uC464\uC480\uC49C\uC4B8\uC4D4\uC4F0\uC50C\uC528\uC544\uC560\uC57C\uC598\uC5B4\uC5D0\uC5EC\uC608\uC624\uC640\uC65C\uC678\uC694\uC6B0\uC6CC\uC6E8\uC704\uC720\uC73C\uC758\uC774\uC790\uC7AC\uC7C8\uC7E4\uC800\uC81C\uC838\uC854\uC870\uC88C\uC8A8\uC8C4\uC8E0\uC8FC\uC918\uC934\uC950\uC96C\uC988\uC9A4\uC9C0\uC9DC\uC9F8\uCA14\uCA30\uCA4C\uCA68\uCA84\uCAA0\uCABC\uCAD8\uCAF4\uCB10\uCB2C\uCB48\uCB64\uCB80\uCB9C\uCBB8\uCBD4\uCBF0\uCC0C\uCC28\uCC44\uCC60\uCC7C\uCC98\uCCB4\uCCD0\uCCEC\uCD08\uCD24\uCD40\uCD5C\uCD78\uCD94\uCDB0\uCDCC\uCDE8\uCE04\uCE20\uCE3C\uCE58\uCE74\uCE90\uCEAC\uCEC8\uCEE4\uCF00\uCF1C\uCF38\uCF54\uCF70\uCF8C\uCFA8\uCFC4\uCFE0\uCFFC\uD018\uD034\uD050\uD06C\uD088\uD0A4\uD0C0\uD0DC\uD0F8\uD114\uD130\uD14C\uD168\uD184\uD1A0\uD1BC\uD1D8\uD1F4\uD210\uD22C\uD248\uD264\uD280\uD29C\uD2B8\uD2D4\uD2F0\uD30C\uD328\uD344\uD360\uD37C\uD398\uD3B4\uD3D0\uD3EC\uD408\uD424\uD440\uD45C\uD478\uD494\uD4B0\uD4CC\uD4E8\uD504\uD520\uD53C\uD558\uD574\uD590\uD5AC\uD5C8\uD5E4\uD600\uD61C\uD638\uD654\uD670\uD68C\uD6A8\uD6C4\uD6E0\uD6FC\uD718\uD734\uD750\uD76C\uD788]$/;
|
|||
|
|
var reLVT = /^[\uAC01-\uAC1B\uAC1D-\uAC37\uAC39-\uAC53\uAC55-\uAC6F\uAC71-\uAC8B\uAC8D-\uACA7\uACA9-\uACC3\uACC5-\uACDF\uACE1-\uACFB\uACFD-\uAD17\uAD19-\uAD33\uAD35-\uAD4F\uAD51-\uAD6B\uAD6D-\uAD87\uAD89-\uADA3\uADA5-\uADBF\uADC1-\uADDB\uADDD-\uADF7\uADF9-\uAE13\uAE15-\uAE2F\uAE31-\uAE4B\uAE4D-\uAE67\uAE69-\uAE83\uAE85-\uAE9F\uAEA1-\uAEBB\uAEBD-\uAED7\uAED9-\uAEF3\uAEF5-\uAF0F\uAF11-\uAF2B\uAF2D-\uAF47\uAF49-\uAF63\uAF65-\uAF7F\uAF81-\uAF9B\uAF9D-\uAFB7\uAFB9-\uAFD3\uAFD5-\uAFEF\uAFF1-\uB00B\uB00D-\uB027\uB029-\uB043\uB045-\uB05F\uB061-\uB07B\uB07D-\uB097\uB099-\uB0B3\uB0B5-\uB0CF\uB0D1-\uB0EB\uB0ED-\uB107\uB109-\uB123\uB125-\uB13F\uB141-\uB15B\uB15D-\uB177\uB179-\uB193\uB195-\uB1AF\uB1B1-\uB1CB\uB1CD-\uB1E7\uB1E9-\uB203\uB205-\uB21F\uB221-\uB23B\uB23D-\uB257\uB259-\uB273\uB275-\uB28F\uB291-\uB2AB\uB2AD-\uB2C7\uB2C9-\uB2E3\uB2E5-\uB2FF\uB301-\uB31B\uB31D-\uB337\uB339-\uB353\uB355-\uB36F\uB371-\uB38B\uB38D-\uB3A7\uB3A9-\uB3C3\uB3C5-\uB3DF\uB3E1-\uB3FB\uB3FD-\uB417\uB419-\uB433\uB435-\uB44F\uB451-\uB46B\uB46D-\uB487\uB489-\uB4A3\uB4A5-\uB4BF\uB4C1-\uB4DB\uB4DD-\uB4F7\uB4F9-\uB513\uB515-\uB52F\uB531-\uB54B\uB54D-\uB567\uB569-\uB583\uB585-\uB59F\uB5A1-\uB5BB\uB5BD-\uB5D7\uB5D9-\uB5F3\uB5F5-\uB60F\uB611-\uB62B\uB62D-\uB647\uB649-\uB663\uB665-\uB67F\uB681-\uB69B\uB69D-\uB6B7\uB6B9-\uB6D3\uB6D5-\uB6EF\uB6F1-\uB70B\uB70D-\uB727\uB729-\uB743\uB745-\uB75F\uB761-\uB77B\uB77D-\uB797\uB799-\uB7B3\uB7B5-\uB7CF\uB7D1-\uB7EB\uB7ED-\uB807\uB809-\uB823\uB825-\uB83F\uB841-\uB85B\uB85D-\uB877\uB879-\uB893\uB895-\uB8AF\uB8B1-\uB8CB\uB8CD-\uB8E7\uB8E9-\uB903\uB905-\uB91F\uB921-\uB93B\uB93D-\uB957\uB959-\uB973\uB975-\uB98F\uB991-\uB9AB\uB9AD-\uB9C7\uB9C9-\uB9E3\uB9E5-\uB9FF\uBA01-\uBA1B\uBA1D-\uBA37\uBA39-\uBA53\uBA55-\uBA6F\uBA71-\uBA8B\uBA8D-\uBAA7\uBAA9-\uBAC3\uBAC5-\uBADF\uBAE1-\uBAFB\uBAFD-\uBB17\uBB19-\uBB33\uBB35-\uBB4F\uBB51-\uBB6B\uBB6D-\uBB87\uBB89-\uBBA3\uBBA5-\uBBBF\uBBC1-\uBBDB\uBBDD-\uBBF7\uBBF9-\uBC13\uBC15-\uBC2F\uBC31-\uBC4B\uBC4D-\uBC67\uBC69-\uBC83\uBC85-\uBC9F\uBCA1-\uBCBB\uBCBD-\uBCD7\uBCD9-\uBCF3\uBCF5-\uBD0F\uBD11-\uBD2B\uBD2D-\uBD47\uBD49-\uBD63\uBD65-\uBD7F\uBD81-\uBD9B\uBD9D-\uBDB7\uBDB9-\uBDD3\uBDD5-\uBDEF\uBDF1-\uBE0B\uBE0D-\uBE27\uBE29-\uBE43\uBE45-\uBE5F\uBE61-\uBE7B\uBE7D-\uBE97\uBE99-\uBEB3\uBEB5-\uBECF\uBED1-\uBEEB\uBEED-\uBF07\uBF09-\uBF23\uBF25-\uBF3F\uBF41-\uBF5B\uBF5D-\uBF77\uBF79-\uBF93\uBF95-\uBFAF\uBFB1-\uBFCB\uBFCD-\uBFE7\uBFE9-\uC003\uC005-\uC01F\uC021-\uC03B\uC03D-\uC057\uC059-\uC073\uC075-\uC08F\uC091-\uC0AB\uC0AD-\uC0C7\uC0C9-\uC0E3\uC0E5-\uC0FF\uC101-\uC11B\uC11D-\uC137\uC139-\uC153\uC155-\uC16F\uC171-\uC18B\uC18D-\uC1A7\uC1A9-\uC1C3\uC1C5-\uC1DF\uC1E1-\uC1FB\uC1FD-\uC217\uC219-\uC233\uC235-\uC24F\uC251-\uC26B\uC26D-\uC287\uC289-\uC2A3\uC2A5-\uC2BF\uC2C1-\uC2DB\uC2DD-\uC2F7\uC2F9-\uC313\uC315-\uC32F\uC331-\uC34B\uC34D-\uC367\uC369-\uC383\uC385-\uC39F\uC3A1-\uC3BB\uC3BD-\uC3D7\uC3D9-\uC3F3\uC3F5-\uC40F\uC411-\uC42B\uC42D-\uC447\uC449-\uC463\uC465-\uC47F\uC481-\uC49B\uC49D-\uC4B7\uC4B9-\uC4D3\uC4D5-\uC4EF\uC4F1-\uC50B\uC50D-\uC527\uC529-\uC543\uC545-\uC55F\uC561-\uC57B\uC57D-\uC597\uC599-\uC5B3\uC5B5-\uC5CF\uC5D1-\uC5EB\uC5ED-\uC607\uC609-\uC623\uC625-\uC63F\uC641-\uC65B\uC65D-\uC677\uC679-\uC693\uC695-\uC6AF\uC6B1-\uC6CB\uC6CD-\uC6E7\uC6E9-\uC703\uC705-\uC71F\uC721-\uC73B\uC73D-\uC757\uC759-\uC773\uC775-\uC78F\uC791-\uC7AB\uC7AD-\uC7C7\uC7C9-\uC7E3\uC7E5-\uC7FF\uC801-\uC81B\uC81D-\uC837\uC839-\uC853\uC855-\uC86F\uC871-\uC88B\uC88D-\uC8A7\uC8A9-\uC8C3\uC8C5-\uC8DF\uC8E1-\uC8FB\uC8FD-\uC917\uC919-\uC933\uC935-\uC94F\uC951-\uC96B\uC96D-\uC987\uC989-\uC9A3\uC9A5-\uC9BF\uC9C1-\uC9DB\uC9DD-\uC9F7\uC9F9-\uCA13\uCA15-\uCA2F\uCA31-\uCA4B\uCA4D-\uCA67\uCA69-\uCA83\uCA85-\uCA9F\uCAA1-\uCABB\uCABD-\uCAD7\uCAD9-\uCAF3\uCAF5-\uCB0F\uCB11-\uCB2B\uCB2D-\uCB47\uCB49-\uCB63\uCB65-\uCB7F\uCB81-\uCB9B\uCB9D-\uCBB7\uCBB9-\uCBD3\uCBD5-\uCBEF\uCBF1-\uCC0B\uCC0D-\uCC27\uCC29-\uCC43\uCC45-\uCC5F\uCC61-\uCC7B\uCC7D-\uCC97\uCC99-\uCCB3\uCCB5-\uCCCF\uCCD1-\uCCEB\uCCED-\uCD07\uCD09-\uCD23\uCD25-\uCD3F\uCD41-\uCD5B\uCD5D-\uCD77\uCD79-\uCD93\uCD95-\uCDAF\uCDB1-\uCDCB\uCDCD-\uCDE7\uCDE9-\uCE03\uCE05-\uCE1F\uCE21-\uCE3B\uCE3D-\u
|
|||
|
|
var reExtPict = /^(?:[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u2388\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2605\u2607-\u2612\u2614-\u2685\u2690-\u2705\u2708-\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763-\u2767\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC00-\uDCFF\uDD0D-\uDD0F\uDD2F\uDD6C-\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDAD-\uDDE5\uDE01-\uDE0F\uDE1A\uDE2F\uDE32-\uDE3A\uDE3C-\uDE3F\uDE49-\uDFFA]|\uD83D[\uDC00-\uDD3D\uDD46-\uDE4F\uDE80-\uDEFF\uDF74-\uDF7F\uDFD5-\uDFFF]|\uD83E[\uDC0C-\uDC0F\uDC48-\uDC4F\uDC5A-\uDC5F\uDC88-\uDC8F\uDCAE-\uDCFF\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDEFF]|\uD83F[\uDC00-\uDFFD])$/;
|
|||
|
|
|
|||
|
|
var getCodepointType = function getCodepointType(_char4, code) {
|
|||
|
|
var type = CodepointType.Any;
|
|||
|
|
|
|||
|
|
if (_char4.search(reExtend) !== -1) {
|
|||
|
|
type |= CodepointType.Extend;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (code === 0x200d) {
|
|||
|
|
type |= CodepointType.ZWJ;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (code >= 0x1f1e6 && code <= 0x1f1ff) {
|
|||
|
|
type |= CodepointType.RI;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (_char4.search(rePrepend) !== -1) {
|
|||
|
|
type |= CodepointType.Prepend;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (_char4.search(reSpacingMark) !== -1) {
|
|||
|
|
type |= CodepointType.SpacingMark;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (_char4.search(reL) !== -1) {
|
|||
|
|
type |= CodepointType.L;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (_char4.search(reV) !== -1) {
|
|||
|
|
type |= CodepointType.V;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (_char4.search(reT) !== -1) {
|
|||
|
|
type |= CodepointType.T;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (_char4.search(reLV) !== -1) {
|
|||
|
|
type |= CodepointType.LV;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (_char4.search(reLVT) !== -1) {
|
|||
|
|
type |= CodepointType.LVT;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (_char4.search(reExtPict) !== -1) {
|
|||
|
|
type |= CodepointType.ExtPict;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return type;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
function intersects(x, y) {
|
|||
|
|
return (x & y) !== 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var NonBoundaryPairs = [// GB6
|
|||
|
|
[CodepointType.L, CodepointType.L | CodepointType.V | CodepointType.LV | CodepointType.LVT], // GB7
|
|||
|
|
[CodepointType.LV | CodepointType.V, CodepointType.V | CodepointType.T], // GB8
|
|||
|
|
[CodepointType.LVT | CodepointType.T, CodepointType.T], // GB9
|
|||
|
|
[CodepointType.Any, CodepointType.Extend | CodepointType.ZWJ], // GB9a
|
|||
|
|
[CodepointType.Any, CodepointType.SpacingMark], // GB9b
|
|||
|
|
[CodepointType.Prepend, CodepointType.Any], // GB11
|
|||
|
|
[CodepointType.ZWJ, CodepointType.ExtPict], // GB12 and GB13
|
|||
|
|
[CodepointType.RI, CodepointType.RI]];
|
|||
|
|
|
|||
|
|
function isBoundaryPair(left, right) {
|
|||
|
|
return NonBoundaryPairs.findIndex(function (r) {
|
|||
|
|
return intersects(left, r[0]) && intersects(right, r[1]);
|
|||
|
|
}) === -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var endingEmojiZWJ = /(?:[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u2388\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2605\u2607-\u2612\u2614-\u2685\u2690-\u2705\u2708-\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763-\u2767\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC00-\uDCFF\uDD0D-\uDD0F\uDD2F\uDD6C-\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDAD-\uDDE5\uDE01-\uDE0F\uDE1A\uDE2F\uDE32-\uDE3A\uDE3C-\uDE3F\uDE49-\uDFFA]|\uD83D[\uDC00-\uDD3D\uDD46-\uDE4F\uDE80-\uDEFF\uDF74-\uDF7F\uDFD5-\uDFFF]|\uD83E[\uDC0C-\uDC0F\uDC48-\uDC4F\uDC5A-\uDC5F\uDC88-\uDC8F\uDCAE-\uDCFF\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDEFF]|\uD83F[\uDC00-\uDFFD])(?:[\u0300-\u036F\u0483-\u0489\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u07FD\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08D3-\u08E1\u08E3-\u0902\u093A\u093C\u0941-\u0948\u094D\u0951-\u0957\u0962\u0963\u0981\u09BC\u09BE\u09C1-\u09C4\u09CD\u09D7\u09E2\u09E3\u09FE\u0A01\u0A02\u0A3C\u0A41\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A70\u0A71\u0A75\u0A81\u0A82\u0ABC\u0AC1-\u0AC5\u0AC7\u0AC8\u0ACD\u0AE2\u0AE3\u0AFA-\u0AFF\u0B01\u0B3C\u0B3E\u0B3F\u0B41-\u0B44\u0B4D\u0B55-\u0B57\u0B62\u0B63\u0B82\u0BBE\u0BC0\u0BCD\u0BD7\u0C00\u0C04\u0C3E-\u0C40\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C81\u0CBC\u0CBF\u0CC2\u0CC6\u0CCC\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0D00\u0D01\u0D3B\u0D3C\u0D3E\u0D41-\u0D44\u0D4D\u0D57\u0D62\u0D63\u0D81\u0DCA\u0DCF\u0DD2-\u0DD4\u0DD6\u0DDF\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EBC\u0EC8-\u0ECD\u0F18\u0F19\u0F35\u0F37\u0F39\u0F71-\u0F7E\u0F80-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102D-\u1030\u1032-\u1037\u1039\u103A\u103D\u103E\u1058\u1059\u105E-\u1060\u1071-\u1074\u1082\u1085\u1086\u108D\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4\u17B5\u17B7-\u17BD\u17C6\u17C9-\u17D3\u17DD\u180B-\u180D\u1885\u1886\u18A9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193B\u1A17\u1A18\u1A1B\u1A56\u1A58-\u1A5E\u1A60\u1A62\u1A65-\u1A6C\u1A73-\u1A7C\u1A7F\u1AB0-\u1AC0\u1B00-\u1B03\u1B34-\u1B3A\u1B3C\u1B42\u1B6B-\u1B73\u1B80\u1B81\u1BA2-\u1BA5\u1BA8\u1BA9\u1BAB-\u1BAD\u1BE6\u1BE8\u1BE9\u1BED\u1BEF-\u1BF1\u1C2C-\u1C33\u1C36\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE0\u1CE2-\u1CE8\u1CED\u1CF4\u1CF8\u1CF9\u1DC0-\u1DF9\u1DFB-\u1DFF\u200C\u20D0-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099\u309A\uA66F-\uA672\uA674-\uA67D\uA69E\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA825\uA826\uA82C\uA8C4\uA8C5\uA8E0-\uA8F1\uA8FF\uA926-\uA92D\uA947-\uA951\uA980-\uA982\uA9B3\uA9B6-\uA9B9\uA9BC\uA9BD\uA9E5\uAA29-\uAA2E\uAA31\uAA32\uAA35\uAA36\uAA43\uAA4C\uAA7C\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEC\uAAED\uAAF6\uABE5\uABE8\uABED\uFB1E\uFE00-\uFE0F\uFE20-\uFE2F\uFF9E\uFF9F]|\uD800[\uDDFD\uDEE0\uDF76-\uDF7A]|\uD802[\uDE01-\uDE03\uDE05\uDE06\uDE0C-\uDE0F\uDE38-\uDE3A\uDE3F\uDEE5\uDEE6]|\uD803[\uDD24-\uDD27\uDEAB\uDEAC\uDF46-\uDF50]|\uD804[\uDC01\uDC38-\uDC46\uDC7F-\uDC81\uDCB3-\uDCB6\uDCB9\uDCBA\uDD00-\uDD02\uDD27-\uDD2B\uDD2D-\uDD34\uDD73\uDD80\uDD81\uDDB6-\uDDBE\uDDC9-\uDDCC\uDDCF\uDE2F-\uDE31\uDE34\uDE36\uDE37\uDE3E\uDEDF\uDEE3-\uDEEA\uDF00\uDF01\uDF3B\uDF3C\uDF3E\uDF40\uDF57\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC38-\uDC3F\uDC42-\uDC44\uDC46\uDC5E\uDCB0\uDCB3-\uDCB8\uDCBA\uDCBD\uDCBF\uDCC0\uDCC2\uDCC3\uDDAF\uDDB2-\uDDB5\uDDBC\uDDBD\uDDBF\uDDC0\uDDDC\uDDDD\uDE33-\uDE3A\uDE3D\uDE3F\uDE40\uDEAB\uDEAD\uDEB0-\uDEB5\uDEB7\uDF1D-\uDF1F\uDF22-\uDF25\uDF27-\uDF2B]|\uD806[\uDC2F-\uDC37\uDC39\uDC3A\uDD30\uDD3B\uDD3C\uDD3E\uDD43\uDDD4-\uDDD7\uDDDA\uDDDB\uDDE0\uDE01-\uDE0A\uDE33-\uDE38\uDE3B-\uDE3E\uDE47\uDE51-\uDE56\uDE59-\uDE5B\uDE8A-\uDE96\uDE98\uDE99]|\uD807[\uDC30-\uDC36\uDC38-\uDC3D\uDC3F\uDC92-\uDCA7\uDCAA-\uDCB0\uDCB2\uDCB3\uDCB5\uDCB6\uDD31-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD45\uDD47\uDD90\uDD91\uDD95\uDD97\uDEF3\uDEF4]|\uD81A[\uDEF0
|
|||
|
|
|
|||
|
|
var endsWithEmojiZWJ = function endsWithEmojiZWJ(str) {
|
|||
|
|
return str.search(endingEmojiZWJ) !== -1;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var endingRIs = /(?:\uD83C[\uDDE6-\uDDFF])+$/g;
|
|||
|
|
|
|||
|
|
var endsWithOddNumberOfRIs = function endsWithOddNumberOfRIs(str) {
|
|||
|
|
var match = str.match(endingRIs);
|
|||
|
|
|
|||
|
|
if (match === null) {
|
|||
|
|
return false;
|
|||
|
|
} else {
|
|||
|
|
// A RI is represented by a surrogate pair.
|
|||
|
|
var numRIs = match[0].length / 2;
|
|||
|
|
return numRIs % 2 === 1;
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Shared the function with isElementType utility
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
var isElement = function isElement(value) {
|
|||
|
|
return isPlainObject.isPlainObject(value) && Node$1.isNodeList(value.children) && !Editor.isEditor(value);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var Element$1 = {
|
|||
|
|
/**
|
|||
|
|
* Check if a value implements the 'Ancestor' interface.
|
|||
|
|
*/
|
|||
|
|
isAncestor: function isAncestor(value) {
|
|||
|
|
return isPlainObject.isPlainObject(value) && Node$1.isNodeList(value.children);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if a value implements the `Element` interface.
|
|||
|
|
*/
|
|||
|
|
isElement: isElement,
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if a value is an array of `Element` objects.
|
|||
|
|
*/
|
|||
|
|
isElementList: function isElementList(value) {
|
|||
|
|
return Array.isArray(value) && value.every(function (val) {
|
|||
|
|
return Element$1.isElement(val);
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if a set of props is a partial of Element.
|
|||
|
|
*/
|
|||
|
|
isElementProps: function isElementProps(props) {
|
|||
|
|
return props.children !== undefined;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if a value implements the `Element` interface and has elementKey with selected value.
|
|||
|
|
* Default it check to `type` key value
|
|||
|
|
*/
|
|||
|
|
isElementType: function isElementType(value, elementVal) {
|
|||
|
|
var elementKey = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'type';
|
|||
|
|
return isElement(value) && value[elementKey] === elementVal;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if an element matches set of properties.
|
|||
|
|
*
|
|||
|
|
* Note: this checks custom properties, and it does not ensure that any
|
|||
|
|
* children are equivalent.
|
|||
|
|
*/
|
|||
|
|
matches: function matches(element, props) {
|
|||
|
|
for (var key in props) {
|
|||
|
|
if (key === 'children') {
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (element[key] !== props[key]) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var _excluded$4 = ["text"],
|
|||
|
|
_excluded2$3 = ["text"];
|
|||
|
|
|
|||
|
|
function ownKeys$8(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
|
|||
|
|
|
|||
|
|
function _objectSpread$8(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$8(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$8(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
|||
|
|
|
|||
|
|
function _createForOfIteratorHelper$5(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$5(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
|
|||
|
|
|
|||
|
|
function _unsupportedIterableToArray$5(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$5(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray$5(o, minLen); }
|
|||
|
|
|
|||
|
|
function _arrayLikeToArray$5(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|||
|
|
var IS_EDITOR_CACHE = new WeakMap();
|
|||
|
|
var Editor = {
|
|||
|
|
/**
|
|||
|
|
* Get the ancestor above a location in the document.
|
|||
|
|
*/
|
|||
|
|
above: function above(editor) {
|
|||
|
|
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|||
|
|
var _options$voids = options.voids,
|
|||
|
|
voids = _options$voids === void 0 ? false : _options$voids,
|
|||
|
|
_options$mode = options.mode,
|
|||
|
|
mode = _options$mode === void 0 ? 'lowest' : _options$mode,
|
|||
|
|
_options$at = options.at,
|
|||
|
|
at = _options$at === void 0 ? editor.selection : _options$at,
|
|||
|
|
match = options.match;
|
|||
|
|
|
|||
|
|
if (!at) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var path = Editor.path(editor, at);
|
|||
|
|
var reverse = mode === 'lowest';
|
|||
|
|
|
|||
|
|
var _iterator = _createForOfIteratorHelper$5(Editor.levels(editor, {
|
|||
|
|
at: path,
|
|||
|
|
voids: voids,
|
|||
|
|
match: match,
|
|||
|
|
reverse: reverse
|
|||
|
|
})),
|
|||
|
|
_step;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|||
|
|
var _step$value = _slicedToArray(_step.value, 2),
|
|||
|
|
n = _step$value[0],
|
|||
|
|
p = _step$value[1];
|
|||
|
|
|
|||
|
|
if (!Text.isText(n) && !Path.equals(path, p)) {
|
|||
|
|
return [n, p];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
} catch (err) {
|
|||
|
|
_iterator.e(err);
|
|||
|
|
} finally {
|
|||
|
|
_iterator.f();
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Add a custom property to the leaf text nodes in the current selection.
|
|||
|
|
*
|
|||
|
|
* If the selection is currently collapsed, the marks will be added to the
|
|||
|
|
* `editor.marks` property instead, and applied when text is inserted next.
|
|||
|
|
*/
|
|||
|
|
addMark: function addMark(editor, key, value) {
|
|||
|
|
editor.addMark(key, value);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Get the point after a location.
|
|||
|
|
*/
|
|||
|
|
after: function after(editor, at) {
|
|||
|
|
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|||
|
|
var anchor = Editor.point(editor, at, {
|
|||
|
|
edge: 'end'
|
|||
|
|
});
|
|||
|
|
var focus = Editor.end(editor, []);
|
|||
|
|
var range = {
|
|||
|
|
anchor: anchor,
|
|||
|
|
focus: focus
|
|||
|
|
};
|
|||
|
|
var _options$distance = options.distance,
|
|||
|
|
distance = _options$distance === void 0 ? 1 : _options$distance;
|
|||
|
|
var d = 0;
|
|||
|
|
var target;
|
|||
|
|
|
|||
|
|
var _iterator2 = _createForOfIteratorHelper$5(Editor.positions(editor, _objectSpread$8(_objectSpread$8({}, options), {}, {
|
|||
|
|
at: range
|
|||
|
|
}))),
|
|||
|
|
_step2;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|||
|
|
var p = _step2.value;
|
|||
|
|
|
|||
|
|
if (d > distance) {
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (d !== 0) {
|
|||
|
|
target = p;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
d++;
|
|||
|
|
}
|
|||
|
|
} catch (err) {
|
|||
|
|
_iterator2.e(err);
|
|||
|
|
} finally {
|
|||
|
|
_iterator2.f();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return target;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Get the point before a location.
|
|||
|
|
*/
|
|||
|
|
before: function before(editor, at) {
|
|||
|
|
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|||
|
|
var anchor = Editor.start(editor, []);
|
|||
|
|
var focus = Editor.point(editor, at, {
|
|||
|
|
edge: 'start'
|
|||
|
|
});
|
|||
|
|
var range = {
|
|||
|
|
anchor: anchor,
|
|||
|
|
focus: focus
|
|||
|
|
};
|
|||
|
|
var _options$distance2 = options.distance,
|
|||
|
|
distance = _options$distance2 === void 0 ? 1 : _options$distance2;
|
|||
|
|
var d = 0;
|
|||
|
|
var target;
|
|||
|
|
|
|||
|
|
var _iterator3 = _createForOfIteratorHelper$5(Editor.positions(editor, _objectSpread$8(_objectSpread$8({}, options), {}, {
|
|||
|
|
at: range,
|
|||
|
|
reverse: true
|
|||
|
|
}))),
|
|||
|
|
_step3;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|||
|
|
var p = _step3.value;
|
|||
|
|
|
|||
|
|
if (d > distance) {
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (d !== 0) {
|
|||
|
|
target = p;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
d++;
|
|||
|
|
}
|
|||
|
|
} catch (err) {
|
|||
|
|
_iterator3.e(err);
|
|||
|
|
} finally {
|
|||
|
|
_iterator3.f();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return target;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Delete content in the editor backward from the current selection.
|
|||
|
|
*/
|
|||
|
|
deleteBackward: function deleteBackward(editor) {
|
|||
|
|
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|||
|
|
var _options$unit = options.unit,
|
|||
|
|
unit = _options$unit === void 0 ? 'character' : _options$unit;
|
|||
|
|
editor.deleteBackward(unit);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Delete content in the editor forward from the current selection.
|
|||
|
|
*/
|
|||
|
|
deleteForward: function deleteForward(editor) {
|
|||
|
|
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|||
|
|
var _options$unit2 = options.unit,
|
|||
|
|
unit = _options$unit2 === void 0 ? 'character' : _options$unit2;
|
|||
|
|
editor.deleteForward(unit);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Delete the content in the current selection.
|
|||
|
|
*/
|
|||
|
|
deleteFragment: function deleteFragment(editor) {
|
|||
|
|
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|||
|
|
var _options$direction = options.direction,
|
|||
|
|
direction = _options$direction === void 0 ? 'forward' : _options$direction;
|
|||
|
|
editor.deleteFragment(direction);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Get the start and end points of a location.
|
|||
|
|
*/
|
|||
|
|
edges: function edges(editor, at) {
|
|||
|
|
return [Editor.start(editor, at), Editor.end(editor, at)];
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Get the end point of a location.
|
|||
|
|
*/
|
|||
|
|
end: function end(editor, at) {
|
|||
|
|
return Editor.point(editor, at, {
|
|||
|
|
edge: 'end'
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Get the first node at a location.
|
|||
|
|
*/
|
|||
|
|
first: function first(editor, at) {
|
|||
|
|
var path = Editor.path(editor, at, {
|
|||
|
|
edge: 'start'
|
|||
|
|
});
|
|||
|
|
return Editor.node(editor, path);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Get the fragment at a location.
|
|||
|
|
*/
|
|||
|
|
fragment: function fragment(editor, at) {
|
|||
|
|
var range = Editor.range(editor, at);
|
|||
|
|
var fragment = Node$1.fragment(editor, range);
|
|||
|
|
return fragment;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if a node has block children.
|
|||
|
|
*/
|
|||
|
|
hasBlocks: function hasBlocks(editor, element) {
|
|||
|
|
return element.children.some(function (n) {
|
|||
|
|
return Editor.isBlock(editor, n);
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if a node has inline and text children.
|
|||
|
|
*/
|
|||
|
|
hasInlines: function hasInlines(editor, element) {
|
|||
|
|
return element.children.some(function (n) {
|
|||
|
|
return Text.isText(n) || Editor.isInline(editor, n);
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if a node has text children.
|
|||
|
|
*/
|
|||
|
|
hasTexts: function hasTexts(editor, element) {
|
|||
|
|
return element.children.every(function (n) {
|
|||
|
|
return Text.isText(n);
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Insert a block break at the current selection.
|
|||
|
|
*
|
|||
|
|
* If the selection is currently expanded, it will be deleted first.
|
|||
|
|
*/
|
|||
|
|
insertBreak: function insertBreak(editor) {
|
|||
|
|
editor.insertBreak();
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Insert a fragment at the current selection.
|
|||
|
|
*
|
|||
|
|
* If the selection is currently expanded, it will be deleted first.
|
|||
|
|
*/
|
|||
|
|
insertFragment: function insertFragment(editor, fragment) {
|
|||
|
|
editor.insertFragment(fragment);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Insert a node at the current selection.
|
|||
|
|
*
|
|||
|
|
* If the selection is currently expanded, it will be deleted first.
|
|||
|
|
*/
|
|||
|
|
insertNode: function insertNode(editor, node) {
|
|||
|
|
editor.insertNode(node);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Insert text at the current selection.
|
|||
|
|
*
|
|||
|
|
* If the selection is currently expanded, it will be deleted first.
|
|||
|
|
*/
|
|||
|
|
insertText: function insertText(editor, text) {
|
|||
|
|
editor.insertText(text);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if a value is a block `Element` object.
|
|||
|
|
*/
|
|||
|
|
isBlock: function isBlock(editor, value) {
|
|||
|
|
return Element$1.isElement(value) && !editor.isInline(value);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if a value is an `Editor` object.
|
|||
|
|
*/
|
|||
|
|
isEditor: function isEditor(value) {
|
|||
|
|
if (!isPlainObject.isPlainObject(value)) return false;
|
|||
|
|
var cachedIsEditor = IS_EDITOR_CACHE.get(value);
|
|||
|
|
|
|||
|
|
if (cachedIsEditor !== undefined) {
|
|||
|
|
return cachedIsEditor;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var isEditor = typeof value.addMark === 'function' && typeof value.apply === 'function' && typeof value.deleteBackward === 'function' && typeof value.deleteForward === 'function' && typeof value.deleteFragment === 'function' && typeof value.insertBreak === 'function' && typeof value.insertFragment === 'function' && typeof value.insertNode === 'function' && typeof value.insertText === 'function' && typeof value.isInline === 'function' && typeof value.isVoid === 'function' && typeof value.normalizeNode === 'function' && typeof value.onChange === 'function' && typeof value.removeMark === 'function' && (value.marks === null || isPlainObject.isPlainObject(value.marks)) && (value.selection === null || Range.isRange(value.selection)) && Node$1.isNodeList(value.children) && Operation.isOperationList(value.operations);
|
|||
|
|
IS_EDITOR_CACHE.set(value, isEditor);
|
|||
|
|
return isEditor;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if a point is the end point of a location.
|
|||
|
|
*/
|
|||
|
|
isEnd: function isEnd(editor, point, at) {
|
|||
|
|
var end = Editor.end(editor, at);
|
|||
|
|
return Point.equals(point, end);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if a point is an edge of a location.
|
|||
|
|
*/
|
|||
|
|
isEdge: function isEdge(editor, point, at) {
|
|||
|
|
return Editor.isStart(editor, point, at) || Editor.isEnd(editor, point, at);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if an element is empty, accounting for void nodes.
|
|||
|
|
*/
|
|||
|
|
isEmpty: function isEmpty(editor, element) {
|
|||
|
|
var children = element.children;
|
|||
|
|
|
|||
|
|
var _children = _slicedToArray(children, 1),
|
|||
|
|
first = _children[0];
|
|||
|
|
|
|||
|
|
return children.length === 0 || children.length === 1 && Text.isText(first) && first.text === '' && !editor.isVoid(element);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if a value is an inline `Element` object.
|
|||
|
|
*/
|
|||
|
|
isInline: function isInline(editor, value) {
|
|||
|
|
return Element$1.isElement(value) && editor.isInline(value);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if the editor is currently normalizing after each operation.
|
|||
|
|
*/
|
|||
|
|
isNormalizing: function isNormalizing(editor) {
|
|||
|
|
var isNormalizing = NORMALIZING.get(editor);
|
|||
|
|
return isNormalizing === undefined ? true : isNormalizing;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if a point is the start point of a location.
|
|||
|
|
*/
|
|||
|
|
isStart: function isStart(editor, point, at) {
|
|||
|
|
// PERF: If the offset isn't `0` we know it's not the start.
|
|||
|
|
if (point.offset !== 0) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var start = Editor.start(editor, at);
|
|||
|
|
return Point.equals(point, start);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if a value is a void `Element` object.
|
|||
|
|
*/
|
|||
|
|
isVoid: function isVoid(editor, value) {
|
|||
|
|
return Element$1.isElement(value) && editor.isVoid(value);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Get the last node at a location.
|
|||
|
|
*/
|
|||
|
|
last: function last(editor, at) {
|
|||
|
|
var path = Editor.path(editor, at, {
|
|||
|
|
edge: 'end'
|
|||
|
|
});
|
|||
|
|
return Editor.node(editor, path);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Get the leaf text node at a location.
|
|||
|
|
*/
|
|||
|
|
leaf: function leaf(editor, at) {
|
|||
|
|
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|||
|
|
var path = Editor.path(editor, at, options);
|
|||
|
|
var node = Node$1.leaf(editor, path);
|
|||
|
|
return [node, path];
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Iterate through all of the levels at a location.
|
|||
|
|
*/
|
|||
|
|
levels: function* levels(editor) {
|
|||
|
|
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|||
|
|
var _options$at2 = options.at,
|
|||
|
|
at = _options$at2 === void 0 ? editor.selection : _options$at2,
|
|||
|
|
_options$reverse = options.reverse,
|
|||
|
|
reverse = _options$reverse === void 0 ? false : _options$reverse,
|
|||
|
|
_options$voids2 = options.voids,
|
|||
|
|
voids = _options$voids2 === void 0 ? false : _options$voids2;
|
|||
|
|
var match = options.match;
|
|||
|
|
|
|||
|
|
if (match == null) {
|
|||
|
|
match = function match() {
|
|||
|
|
return true;
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!at) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var levels = [];
|
|||
|
|
var path = Editor.path(editor, at);
|
|||
|
|
|
|||
|
|
var _iterator4 = _createForOfIteratorHelper$5(Node$1.levels(editor, path)),
|
|||
|
|
_step4;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
|
|||
|
|
var _step4$value = _slicedToArray(_step4.value, 2),
|
|||
|
|
n = _step4$value[0],
|
|||
|
|
p = _step4$value[1];
|
|||
|
|
|
|||
|
|
if (!match(n, p)) {
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
levels.push([n, p]);
|
|||
|
|
|
|||
|
|
if (!voids && Editor.isVoid(editor, n)) {
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
} catch (err) {
|
|||
|
|
_iterator4.e(err);
|
|||
|
|
} finally {
|
|||
|
|
_iterator4.f();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (reverse) {
|
|||
|
|
levels.reverse();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
yield* levels;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Get the marks that would be added to text at the current selection.
|
|||
|
|
*/
|
|||
|
|
marks: function marks(editor) {
|
|||
|
|
var marks = editor.marks,
|
|||
|
|
selection = editor.selection;
|
|||
|
|
|
|||
|
|
if (!selection) {
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (marks) {
|
|||
|
|
return marks;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (Range.isExpanded(selection)) {
|
|||
|
|
var _Editor$nodes = Editor.nodes(editor, {
|
|||
|
|
match: Text.isText
|
|||
|
|
}),
|
|||
|
|
_Editor$nodes2 = _slicedToArray(_Editor$nodes, 1),
|
|||
|
|
match = _Editor$nodes2[0];
|
|||
|
|
|
|||
|
|
if (match) {
|
|||
|
|
var _match = _slicedToArray(match, 1),
|
|||
|
|
_node = _match[0];
|
|||
|
|
|
|||
|
|
_node.text;
|
|||
|
|
var _rest = _objectWithoutProperties(_node, _excluded$4);
|
|||
|
|
|
|||
|
|
return _rest;
|
|||
|
|
} else {
|
|||
|
|
return {};
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var anchor = selection.anchor;
|
|||
|
|
var path = anchor.path;
|
|||
|
|
|
|||
|
|
var _Editor$leaf = Editor.leaf(editor, path),
|
|||
|
|
_Editor$leaf2 = _slicedToArray(_Editor$leaf, 1),
|
|||
|
|
node = _Editor$leaf2[0];
|
|||
|
|
|
|||
|
|
if (anchor.offset === 0) {
|
|||
|
|
var prev = Editor.previous(editor, {
|
|||
|
|
at: path,
|
|||
|
|
match: Text.isText
|
|||
|
|
});
|
|||
|
|
var block = Editor.above(editor, {
|
|||
|
|
match: function match(n) {
|
|||
|
|
return Editor.isBlock(editor, n);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
if (prev && block) {
|
|||
|
|
var _prev = _slicedToArray(prev, 2),
|
|||
|
|
prevNode = _prev[0],
|
|||
|
|
prevPath = _prev[1];
|
|||
|
|
|
|||
|
|
var _block = _slicedToArray(block, 2),
|
|||
|
|
blockPath = _block[1];
|
|||
|
|
|
|||
|
|
if (Path.isAncestor(blockPath, prevPath)) {
|
|||
|
|
node = prevNode;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var _node2 = node;
|
|||
|
|
_node2.text;
|
|||
|
|
var rest = _objectWithoutProperties(_node2, _excluded2$3);
|
|||
|
|
|
|||
|
|
return rest;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Get the matching node in the branch of the document after a location.
|
|||
|
|
*/
|
|||
|
|
next: function next(editor) {
|
|||
|
|
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|||
|
|
var _options$mode2 = options.mode,
|
|||
|
|
mode = _options$mode2 === void 0 ? 'lowest' : _options$mode2,
|
|||
|
|
_options$voids3 = options.voids,
|
|||
|
|
voids = _options$voids3 === void 0 ? false : _options$voids3;
|
|||
|
|
var match = options.match,
|
|||
|
|
_options$at3 = options.at,
|
|||
|
|
at = _options$at3 === void 0 ? editor.selection : _options$at3;
|
|||
|
|
|
|||
|
|
if (!at) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var pointAfterLocation = Editor.after(editor, at, {
|
|||
|
|
voids: voids
|
|||
|
|
});
|
|||
|
|
if (!pointAfterLocation) return;
|
|||
|
|
|
|||
|
|
var _Editor$last = Editor.last(editor, []),
|
|||
|
|
_Editor$last2 = _slicedToArray(_Editor$last, 2),
|
|||
|
|
to = _Editor$last2[1];
|
|||
|
|
|
|||
|
|
var span = [pointAfterLocation.path, to];
|
|||
|
|
|
|||
|
|
if (Path.isPath(at) && at.length === 0) {
|
|||
|
|
throw new Error("Cannot get the next node from the root node!");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (match == null) {
|
|||
|
|
if (Path.isPath(at)) {
|
|||
|
|
var _Editor$parent = Editor.parent(editor, at),
|
|||
|
|
_Editor$parent2 = _slicedToArray(_Editor$parent, 1),
|
|||
|
|
parent = _Editor$parent2[0];
|
|||
|
|
|
|||
|
|
match = function match(n) {
|
|||
|
|
return parent.children.includes(n);
|
|||
|
|
};
|
|||
|
|
} else {
|
|||
|
|
match = function match() {
|
|||
|
|
return true;
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var _Editor$nodes3 = Editor.nodes(editor, {
|
|||
|
|
at: span,
|
|||
|
|
match: match,
|
|||
|
|
mode: mode,
|
|||
|
|
voids: voids
|
|||
|
|
}),
|
|||
|
|
_Editor$nodes4 = _slicedToArray(_Editor$nodes3, 1),
|
|||
|
|
next = _Editor$nodes4[0];
|
|||
|
|
|
|||
|
|
return next;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Get the node at a location.
|
|||
|
|
*/
|
|||
|
|
node: function node(editor, at) {
|
|||
|
|
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|||
|
|
var path = Editor.path(editor, at, options);
|
|||
|
|
var node = Node$1.get(editor, path);
|
|||
|
|
return [node, path];
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Iterate through all of the nodes in the Editor.
|
|||
|
|
*/
|
|||
|
|
nodes: function* nodes(editor) {
|
|||
|
|
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|||
|
|
var _options$at4 = options.at,
|
|||
|
|
at = _options$at4 === void 0 ? editor.selection : _options$at4,
|
|||
|
|
_options$mode3 = options.mode,
|
|||
|
|
mode = _options$mode3 === void 0 ? 'all' : _options$mode3,
|
|||
|
|
_options$universal = options.universal,
|
|||
|
|
universal = _options$universal === void 0 ? false : _options$universal,
|
|||
|
|
_options$reverse2 = options.reverse,
|
|||
|
|
reverse = _options$reverse2 === void 0 ? false : _options$reverse2,
|
|||
|
|
_options$voids4 = options.voids,
|
|||
|
|
voids = _options$voids4 === void 0 ? false : _options$voids4;
|
|||
|
|
var match = options.match;
|
|||
|
|
|
|||
|
|
if (!match) {
|
|||
|
|
match = function match() {
|
|||
|
|
return true;
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!at) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var from;
|
|||
|
|
var to;
|
|||
|
|
|
|||
|
|
if (Span.isSpan(at)) {
|
|||
|
|
from = at[0];
|
|||
|
|
to = at[1];
|
|||
|
|
} else {
|
|||
|
|
var first = Editor.path(editor, at, {
|
|||
|
|
edge: 'start'
|
|||
|
|
});
|
|||
|
|
var last = Editor.path(editor, at, {
|
|||
|
|
edge: 'end'
|
|||
|
|
});
|
|||
|
|
from = reverse ? last : first;
|
|||
|
|
to = reverse ? first : last;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var nodeEntries = Node$1.nodes(editor, {
|
|||
|
|
reverse: reverse,
|
|||
|
|
from: from,
|
|||
|
|
to: to,
|
|||
|
|
pass: function pass(_ref) {
|
|||
|
|
var _ref2 = _slicedToArray(_ref, 1),
|
|||
|
|
n = _ref2[0];
|
|||
|
|
|
|||
|
|
return voids ? false : Editor.isVoid(editor, n);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
var matches = [];
|
|||
|
|
var hit;
|
|||
|
|
|
|||
|
|
var _iterator5 = _createForOfIteratorHelper$5(nodeEntries),
|
|||
|
|
_step5;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
|
|||
|
|
var _step5$value = _slicedToArray(_step5.value, 2),
|
|||
|
|
node = _step5$value[0],
|
|||
|
|
path = _step5$value[1];
|
|||
|
|
|
|||
|
|
var isLower = hit && Path.compare(path, hit[1]) === 0; // In highest mode any node lower than the last hit is not a match.
|
|||
|
|
|
|||
|
|
if (mode === 'highest' && isLower) {
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!match(node, path)) {
|
|||
|
|
// If we've arrived at a leaf text node that is not lower than the last
|
|||
|
|
// hit, then we've found a branch that doesn't include a match, which
|
|||
|
|
// means the match is not universal.
|
|||
|
|
if (universal && !isLower && Text.isText(node)) {
|
|||
|
|
return;
|
|||
|
|
} else {
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
} // If there's a match and it's lower than the last, update the hit.
|
|||
|
|
|
|||
|
|
|
|||
|
|
if (mode === 'lowest' && isLower) {
|
|||
|
|
hit = [node, path];
|
|||
|
|
continue;
|
|||
|
|
} // In lowest mode we emit the last hit, once it's guaranteed lowest.
|
|||
|
|
|
|||
|
|
|
|||
|
|
var emit = mode === 'lowest' ? hit : [node, path];
|
|||
|
|
|
|||
|
|
if (emit) {
|
|||
|
|
if (universal) {
|
|||
|
|
matches.push(emit);
|
|||
|
|
} else {
|
|||
|
|
yield emit;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
hit = [node, path];
|
|||
|
|
} // Since lowest is always emitting one behind, catch up at the end.
|
|||
|
|
|
|||
|
|
} catch (err) {
|
|||
|
|
_iterator5.e(err);
|
|||
|
|
} finally {
|
|||
|
|
_iterator5.f();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (mode === 'lowest' && hit) {
|
|||
|
|
if (universal) {
|
|||
|
|
matches.push(hit);
|
|||
|
|
} else {
|
|||
|
|
yield hit;
|
|||
|
|
}
|
|||
|
|
} // Universal defers to ensure that the match occurs in every branch, so we
|
|||
|
|
// yield all of the matches after iterating.
|
|||
|
|
|
|||
|
|
|
|||
|
|
if (universal) {
|
|||
|
|
yield* matches;
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Normalize any dirty objects in the editor.
|
|||
|
|
*/
|
|||
|
|
normalize: function normalize(editor) {
|
|||
|
|
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|||
|
|
var _options$force = options.force,
|
|||
|
|
force = _options$force === void 0 ? false : _options$force;
|
|||
|
|
|
|||
|
|
var getDirtyPaths = function getDirtyPaths(editor) {
|
|||
|
|
return DIRTY_PATHS.get(editor) || [];
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
if (!Editor.isNormalizing(editor)) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (force) {
|
|||
|
|
var allPaths = Array.from(Node$1.nodes(editor), function (_ref3) {
|
|||
|
|
var _ref4 = _slicedToArray(_ref3, 2),
|
|||
|
|
p = _ref4[1];
|
|||
|
|
|
|||
|
|
return p;
|
|||
|
|
});
|
|||
|
|
DIRTY_PATHS.set(editor, allPaths);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (getDirtyPaths(editor).length === 0) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Editor.withoutNormalizing(editor, function () {
|
|||
|
|
/*
|
|||
|
|
Fix dirty elements with no children.
|
|||
|
|
editor.normalizeNode() does fix this, but some normalization fixes also require it to work.
|
|||
|
|
Running an initial pass avoids the catch-22 race condition.
|
|||
|
|
*/
|
|||
|
|
var _iterator6 = _createForOfIteratorHelper$5(getDirtyPaths(editor)),
|
|||
|
|
_step6;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
|
|||
|
|
var _dirtyPath = _step6.value;
|
|||
|
|
|
|||
|
|
if (Node$1.has(editor, _dirtyPath)) {
|
|||
|
|
var _entry = Editor.node(editor, _dirtyPath);
|
|||
|
|
|
|||
|
|
var _entry2 = _slicedToArray(_entry, 2),
|
|||
|
|
node = _entry2[0],
|
|||
|
|
_ = _entry2[1];
|
|||
|
|
/*
|
|||
|
|
The default normalizer inserts an empty text node in this scenario, but it can be customised.
|
|||
|
|
So there is some risk here.
|
|||
|
|
As long as the normalizer only inserts child nodes for this case it is safe to do in any order;
|
|||
|
|
by definition adding children to an empty node can't cause other paths to change.
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
if (Element$1.isElement(node) && node.children.length === 0) {
|
|||
|
|
editor.normalizeNode(_entry);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
} catch (err) {
|
|||
|
|
_iterator6.e(err);
|
|||
|
|
} finally {
|
|||
|
|
_iterator6.f();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var max = getDirtyPaths(editor).length * 42; // HACK: better way?
|
|||
|
|
|
|||
|
|
var m = 0;
|
|||
|
|
|
|||
|
|
while (getDirtyPaths(editor).length !== 0) {
|
|||
|
|
if (m > max) {
|
|||
|
|
throw new Error("\n Could not completely normalize the editor after ".concat(max, " iterations! This is usually due to incorrect normalization logic that leaves a node in an invalid state.\n "));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var dirtyPath = getDirtyPaths(editor).pop(); // If the node doesn't exist in the tree, it does not need to be normalized.
|
|||
|
|
|
|||
|
|
if (Node$1.has(editor, dirtyPath)) {
|
|||
|
|
var entry = Editor.node(editor, dirtyPath);
|
|||
|
|
editor.normalizeNode(entry);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
m++;
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Get the parent node of a location.
|
|||
|
|
*/
|
|||
|
|
parent: function parent(editor, at) {
|
|||
|
|
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|||
|
|
var path = Editor.path(editor, at, options);
|
|||
|
|
var parentPath = Path.parent(path);
|
|||
|
|
var entry = Editor.node(editor, parentPath);
|
|||
|
|
return entry;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Get the path of a location.
|
|||
|
|
*/
|
|||
|
|
path: function path(editor, at) {
|
|||
|
|
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|||
|
|
var depth = options.depth,
|
|||
|
|
edge = options.edge;
|
|||
|
|
|
|||
|
|
if (Path.isPath(at)) {
|
|||
|
|
if (edge === 'start') {
|
|||
|
|
var _Node$first = Node$1.first(editor, at),
|
|||
|
|
_Node$first2 = _slicedToArray(_Node$first, 2),
|
|||
|
|
firstPath = _Node$first2[1];
|
|||
|
|
|
|||
|
|
at = firstPath;
|
|||
|
|
} else if (edge === 'end') {
|
|||
|
|
var _Node$last = Node$1.last(editor, at),
|
|||
|
|
_Node$last2 = _slicedToArray(_Node$last, 2),
|
|||
|
|
lastPath = _Node$last2[1];
|
|||
|
|
|
|||
|
|
at = lastPath;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (Range.isRange(at)) {
|
|||
|
|
if (edge === 'start') {
|
|||
|
|
at = Range.start(at);
|
|||
|
|
} else if (edge === 'end') {
|
|||
|
|
at = Range.end(at);
|
|||
|
|
} else {
|
|||
|
|
at = Path.common(at.anchor.path, at.focus.path);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (Point.isPoint(at)) {
|
|||
|
|
at = at.path;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (depth != null) {
|
|||
|
|
at = at.slice(0, depth);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return at;
|
|||
|
|
},
|
|||
|
|
hasPath: function hasPath(editor, path) {
|
|||
|
|
return Node$1.has(editor, path);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Create a mutable ref for a `Path` object, which will stay in sync as new
|
|||
|
|
* operations are applied to the editor.
|
|||
|
|
*/
|
|||
|
|
pathRef: function pathRef(editor, path) {
|
|||
|
|
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|||
|
|
var _options$affinity = options.affinity,
|
|||
|
|
affinity = _options$affinity === void 0 ? 'forward' : _options$affinity;
|
|||
|
|
var ref = {
|
|||
|
|
current: path,
|
|||
|
|
affinity: affinity,
|
|||
|
|
unref: function unref() {
|
|||
|
|
var current = ref.current;
|
|||
|
|
var pathRefs = Editor.pathRefs(editor);
|
|||
|
|
pathRefs["delete"](ref);
|
|||
|
|
ref.current = null;
|
|||
|
|
return current;
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
var refs = Editor.pathRefs(editor);
|
|||
|
|
refs.add(ref);
|
|||
|
|
return ref;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Get the set of currently tracked path refs of the editor.
|
|||
|
|
*/
|
|||
|
|
pathRefs: function pathRefs(editor) {
|
|||
|
|
var refs = PATH_REFS.get(editor);
|
|||
|
|
|
|||
|
|
if (!refs) {
|
|||
|
|
refs = new Set();
|
|||
|
|
PATH_REFS.set(editor, refs);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return refs;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Get the start or end point of a location.
|
|||
|
|
*/
|
|||
|
|
point: function point(editor, at) {
|
|||
|
|
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|||
|
|
var _options$edge = options.edge,
|
|||
|
|
edge = _options$edge === void 0 ? 'start' : _options$edge;
|
|||
|
|
|
|||
|
|
if (Path.isPath(at)) {
|
|||
|
|
var path;
|
|||
|
|
|
|||
|
|
if (edge === 'end') {
|
|||
|
|
var _Node$last3 = Node$1.last(editor, at),
|
|||
|
|
_Node$last4 = _slicedToArray(_Node$last3, 2),
|
|||
|
|
lastPath = _Node$last4[1];
|
|||
|
|
|
|||
|
|
path = lastPath;
|
|||
|
|
} else {
|
|||
|
|
var _Node$first3 = Node$1.first(editor, at),
|
|||
|
|
_Node$first4 = _slicedToArray(_Node$first3, 2),
|
|||
|
|
firstPath = _Node$first4[1];
|
|||
|
|
|
|||
|
|
path = firstPath;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var node = Node$1.get(editor, path);
|
|||
|
|
|
|||
|
|
if (!Text.isText(node)) {
|
|||
|
|
throw new Error("Cannot get the ".concat(edge, " point in the node at path [").concat(at, "] because it has no ").concat(edge, " text node."));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return {
|
|||
|
|
path: path,
|
|||
|
|
offset: edge === 'end' ? node.text.length : 0
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (Range.isRange(at)) {
|
|||
|
|
var _Range$edges = Range.edges(at),
|
|||
|
|
_Range$edges2 = _slicedToArray(_Range$edges, 2),
|
|||
|
|
start = _Range$edges2[0],
|
|||
|
|
end = _Range$edges2[1];
|
|||
|
|
|
|||
|
|
return edge === 'start' ? start : end;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return at;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Create a mutable ref for a `Point` object, which will stay in sync as new
|
|||
|
|
* operations are applied to the editor.
|
|||
|
|
*/
|
|||
|
|
pointRef: function pointRef(editor, point) {
|
|||
|
|
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|||
|
|
var _options$affinity2 = options.affinity,
|
|||
|
|
affinity = _options$affinity2 === void 0 ? 'forward' : _options$affinity2;
|
|||
|
|
var ref = {
|
|||
|
|
current: point,
|
|||
|
|
affinity: affinity,
|
|||
|
|
unref: function unref() {
|
|||
|
|
var current = ref.current;
|
|||
|
|
var pointRefs = Editor.pointRefs(editor);
|
|||
|
|
pointRefs["delete"](ref);
|
|||
|
|
ref.current = null;
|
|||
|
|
return current;
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
var refs = Editor.pointRefs(editor);
|
|||
|
|
refs.add(ref);
|
|||
|
|
return ref;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Get the set of currently tracked point refs of the editor.
|
|||
|
|
*/
|
|||
|
|
pointRefs: function pointRefs(editor) {
|
|||
|
|
var refs = POINT_REFS.get(editor);
|
|||
|
|
|
|||
|
|
if (!refs) {
|
|||
|
|
refs = new Set();
|
|||
|
|
POINT_REFS.set(editor, refs);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return refs;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Return all the positions in `at` range where a `Point` can be placed.
|
|||
|
|
*
|
|||
|
|
* By default, moves forward by individual offsets at a time, but
|
|||
|
|
* the `unit` option can be used to to move by character, word, line, or block.
|
|||
|
|
*
|
|||
|
|
* The `reverse` option can be used to change iteration direction.
|
|||
|
|
*
|
|||
|
|
* Note: By default void nodes are treated as a single point and iteration
|
|||
|
|
* will not happen inside their content unless you pass in true for the
|
|||
|
|
* `voids` option, then iteration will occur.
|
|||
|
|
*/
|
|||
|
|
positions: function* positions(editor) {
|
|||
|
|
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|||
|
|
var _options$at5 = options.at,
|
|||
|
|
at = _options$at5 === void 0 ? editor.selection : _options$at5,
|
|||
|
|
_options$unit3 = options.unit,
|
|||
|
|
unit = _options$unit3 === void 0 ? 'offset' : _options$unit3,
|
|||
|
|
_options$reverse3 = options.reverse,
|
|||
|
|
reverse = _options$reverse3 === void 0 ? false : _options$reverse3,
|
|||
|
|
_options$voids5 = options.voids,
|
|||
|
|
voids = _options$voids5 === void 0 ? false : _options$voids5;
|
|||
|
|
|
|||
|
|
if (!at) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Algorithm notes:
|
|||
|
|
*
|
|||
|
|
* Each step `distance` is dynamic depending on the underlying text
|
|||
|
|
* and the `unit` specified. Each step, e.g., a line or word, may
|
|||
|
|
* span multiple text nodes, so we iterate through the text both on
|
|||
|
|
* two levels in step-sync:
|
|||
|
|
*
|
|||
|
|
* `leafText` stores the text on a text leaf level, and is advanced
|
|||
|
|
* through using the counters `leafTextOffset` and `leafTextRemaining`.
|
|||
|
|
*
|
|||
|
|
* `blockText` stores the text on a block level, and is shortened
|
|||
|
|
* by `distance` every time it is advanced.
|
|||
|
|
*
|
|||
|
|
* We only maintain a window of one blockText and one leafText because
|
|||
|
|
* a block node always appears before all of its leaf nodes.
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
var range = Editor.range(editor, at);
|
|||
|
|
|
|||
|
|
var _Range$edges3 = Range.edges(range),
|
|||
|
|
_Range$edges4 = _slicedToArray(_Range$edges3, 2),
|
|||
|
|
start = _Range$edges4[0],
|
|||
|
|
end = _Range$edges4[1];
|
|||
|
|
|
|||
|
|
var first = reverse ? end : start;
|
|||
|
|
var isNewBlock = false;
|
|||
|
|
var blockText = '';
|
|||
|
|
var distance = 0; // Distance for leafText to catch up to blockText.
|
|||
|
|
|
|||
|
|
var leafTextRemaining = 0;
|
|||
|
|
var leafTextOffset = 0; // Iterate through all nodes in range, grabbing entire textual content
|
|||
|
|
// of block nodes in blockText, and text nodes in leafText.
|
|||
|
|
// Exploits the fact that nodes are sequenced in such a way that we first
|
|||
|
|
// encounter the block node, then all of its text nodes, so when iterating
|
|||
|
|
// through the blockText and leafText we just need to remember a window of
|
|||
|
|
// one block node and leaf node, respectively.
|
|||
|
|
|
|||
|
|
var _iterator7 = _createForOfIteratorHelper$5(Editor.nodes(editor, {
|
|||
|
|
at: at,
|
|||
|
|
reverse: reverse,
|
|||
|
|
voids: voids
|
|||
|
|
})),
|
|||
|
|
_step7;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
|
|||
|
|
var _step7$value = _slicedToArray(_step7.value, 2),
|
|||
|
|
node = _step7$value[0],
|
|||
|
|
path = _step7$value[1];
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
* ELEMENT NODE - Yield position(s) for voids, collect blockText for blocks
|
|||
|
|
*/
|
|||
|
|
if (Element$1.isElement(node)) {
|
|||
|
|
// Void nodes are a special case, so by default we will always
|
|||
|
|
// yield their first point. If the `voids` option is set to true,
|
|||
|
|
// then we will iterate over their content.
|
|||
|
|
if (!voids && editor.isVoid(node)) {
|
|||
|
|
yield Editor.start(editor, path);
|
|||
|
|
continue;
|
|||
|
|
} // Inline element nodes are ignored as they don't themselves
|
|||
|
|
// contribute to `blockText` or `leafText` - their parent and
|
|||
|
|
// children do.
|
|||
|
|
|
|||
|
|
|
|||
|
|
if (editor.isInline(node)) continue; // Block element node - set `blockText` to its text content.
|
|||
|
|
|
|||
|
|
if (Editor.hasInlines(editor, node)) {
|
|||
|
|
// We always exhaust block nodes before encountering a new one:
|
|||
|
|
// console.assert(blockText === '',
|
|||
|
|
// `blockText='${blockText}' - `+
|
|||
|
|
// `not exhausted before new block node`, path)
|
|||
|
|
// Ensure range considered is capped to `range`, in the
|
|||
|
|
// start/end edge cases where block extends beyond range.
|
|||
|
|
// Equivalent to this, but presumably more performant:
|
|||
|
|
// blockRange = Editor.range(editor, ...Editor.edges(editor, path))
|
|||
|
|
// blockRange = Range.intersection(range, blockRange) // intersect
|
|||
|
|
// blockText = Editor.string(editor, blockRange, { voids })
|
|||
|
|
var e = Path.isAncestor(path, end.path) ? end : Editor.end(editor, path);
|
|||
|
|
var s = Path.isAncestor(path, start.path) ? start : Editor.start(editor, path);
|
|||
|
|
blockText = Editor.string(editor, {
|
|||
|
|
anchor: s,
|
|||
|
|
focus: e
|
|||
|
|
}, {
|
|||
|
|
voids: voids
|
|||
|
|
});
|
|||
|
|
isNewBlock = true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
/*
|
|||
|
|
* TEXT LEAF NODE - Iterate through text content, yielding
|
|||
|
|
* positions every `distance` offset according to `unit`.
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
if (Text.isText(node)) {
|
|||
|
|
var isFirst = Path.equals(path, first.path); // Proof that we always exhaust text nodes before encountering a new one:
|
|||
|
|
// console.assert(leafTextRemaining <= 0,
|
|||
|
|
// `leafTextRemaining=${leafTextRemaining} - `+
|
|||
|
|
// `not exhausted before new leaf text node`, path)
|
|||
|
|
// Reset `leafText` counters for new text node.
|
|||
|
|
|
|||
|
|
if (isFirst) {
|
|||
|
|
leafTextRemaining = reverse ? first.offset : node.text.length - first.offset;
|
|||
|
|
leafTextOffset = first.offset; // Works for reverse too.
|
|||
|
|
} else {
|
|||
|
|
leafTextRemaining = node.text.length;
|
|||
|
|
leafTextOffset = reverse ? leafTextRemaining : 0;
|
|||
|
|
} // Yield position at the start of node (potentially).
|
|||
|
|
|
|||
|
|
|
|||
|
|
if (isFirst || isNewBlock || unit === 'offset') {
|
|||
|
|
yield {
|
|||
|
|
path: path,
|
|||
|
|
offset: leafTextOffset
|
|||
|
|
};
|
|||
|
|
isNewBlock = false;
|
|||
|
|
} // Yield positions every (dynamically calculated) `distance` offset.
|
|||
|
|
|
|||
|
|
|
|||
|
|
while (true) {
|
|||
|
|
// If `leafText` has caught up with `blockText` (distance=0),
|
|||
|
|
// and if blockText is exhausted, break to get another block node,
|
|||
|
|
// otherwise advance blockText forward by the new `distance`.
|
|||
|
|
if (distance === 0) {
|
|||
|
|
if (blockText === '') break;
|
|||
|
|
distance = calcDistance(blockText, unit, reverse); // Split the string at the previously found distance and use the
|
|||
|
|
// remaining string for the next iteration.
|
|||
|
|
|
|||
|
|
blockText = splitByCharacterDistance(blockText, distance, reverse)[1];
|
|||
|
|
} // Advance `leafText` by the current `distance`.
|
|||
|
|
|
|||
|
|
|
|||
|
|
leafTextOffset = reverse ? leafTextOffset - distance : leafTextOffset + distance;
|
|||
|
|
leafTextRemaining = leafTextRemaining - distance; // If `leafText` is exhausted, break to get a new leaf node
|
|||
|
|
// and set distance to the overflow amount, so we'll (maybe)
|
|||
|
|
// catch up to blockText in the next leaf text node.
|
|||
|
|
|
|||
|
|
if (leafTextRemaining < 0) {
|
|||
|
|
distance = -leafTextRemaining;
|
|||
|
|
break;
|
|||
|
|
} // Successfully walked `distance` offsets through `leafText`
|
|||
|
|
// to catch up with `blockText`, so we can reset `distance`
|
|||
|
|
// and yield this position in this node.
|
|||
|
|
|
|||
|
|
|
|||
|
|
distance = 0;
|
|||
|
|
yield {
|
|||
|
|
path: path,
|
|||
|
|
offset: leafTextOffset
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
} // Proof that upon completion, we've exahusted both leaf and block text:
|
|||
|
|
// console.assert(leafTextRemaining <= 0, "leafText wasn't exhausted")
|
|||
|
|
// console.assert(blockText === '', "blockText wasn't exhausted")
|
|||
|
|
// Helper:
|
|||
|
|
// Return the distance in offsets for a step of size `unit` on given string.
|
|||
|
|
|
|||
|
|
} catch (err) {
|
|||
|
|
_iterator7.e(err);
|
|||
|
|
} finally {
|
|||
|
|
_iterator7.f();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function calcDistance(text, unit, reverse) {
|
|||
|
|
if (unit === 'character') {
|
|||
|
|
return getCharacterDistance(text, reverse);
|
|||
|
|
} else if (unit === 'word') {
|
|||
|
|
return getWordDistance(text, reverse);
|
|||
|
|
} else if (unit === 'line' || unit === 'block') {
|
|||
|
|
return text.length;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Get the matching node in the branch of the document before a location.
|
|||
|
|
*/
|
|||
|
|
previous: function previous(editor) {
|
|||
|
|
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|||
|
|
var _options$mode4 = options.mode,
|
|||
|
|
mode = _options$mode4 === void 0 ? 'lowest' : _options$mode4,
|
|||
|
|
_options$voids6 = options.voids,
|
|||
|
|
voids = _options$voids6 === void 0 ? false : _options$voids6;
|
|||
|
|
var match = options.match,
|
|||
|
|
_options$at6 = options.at,
|
|||
|
|
at = _options$at6 === void 0 ? editor.selection : _options$at6;
|
|||
|
|
|
|||
|
|
if (!at) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var pointBeforeLocation = Editor.before(editor, at, {
|
|||
|
|
voids: voids
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
if (!pointBeforeLocation) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var _Editor$first = Editor.first(editor, []),
|
|||
|
|
_Editor$first2 = _slicedToArray(_Editor$first, 2),
|
|||
|
|
to = _Editor$first2[1]; // The search location is from the start of the document to the path of
|
|||
|
|
// the point before the location passed in
|
|||
|
|
|
|||
|
|
|
|||
|
|
var span = [pointBeforeLocation.path, to];
|
|||
|
|
|
|||
|
|
if (Path.isPath(at) && at.length === 0) {
|
|||
|
|
throw new Error("Cannot get the previous node from the root node!");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (match == null) {
|
|||
|
|
if (Path.isPath(at)) {
|
|||
|
|
var _Editor$parent3 = Editor.parent(editor, at),
|
|||
|
|
_Editor$parent4 = _slicedToArray(_Editor$parent3, 1),
|
|||
|
|
parent = _Editor$parent4[0];
|
|||
|
|
|
|||
|
|
match = function match(n) {
|
|||
|
|
return parent.children.includes(n);
|
|||
|
|
};
|
|||
|
|
} else {
|
|||
|
|
match = function match() {
|
|||
|
|
return true;
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var _Editor$nodes5 = Editor.nodes(editor, {
|
|||
|
|
reverse: true,
|
|||
|
|
at: span,
|
|||
|
|
match: match,
|
|||
|
|
mode: mode,
|
|||
|
|
voids: voids
|
|||
|
|
}),
|
|||
|
|
_Editor$nodes6 = _slicedToArray(_Editor$nodes5, 1),
|
|||
|
|
previous = _Editor$nodes6[0];
|
|||
|
|
|
|||
|
|
return previous;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Get a range of a location.
|
|||
|
|
*/
|
|||
|
|
range: function range(editor, at, to) {
|
|||
|
|
if (Range.isRange(at) && !to) {
|
|||
|
|
return at;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var start = Editor.start(editor, at);
|
|||
|
|
var end = Editor.end(editor, to || at);
|
|||
|
|
return {
|
|||
|
|
anchor: start,
|
|||
|
|
focus: end
|
|||
|
|
};
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Create a mutable ref for a `Range` object, which will stay in sync as new
|
|||
|
|
* operations are applied to the editor.
|
|||
|
|
*/
|
|||
|
|
rangeRef: function rangeRef(editor, range) {
|
|||
|
|
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|||
|
|
var _options$affinity3 = options.affinity,
|
|||
|
|
affinity = _options$affinity3 === void 0 ? 'forward' : _options$affinity3;
|
|||
|
|
var ref = {
|
|||
|
|
current: range,
|
|||
|
|
affinity: affinity,
|
|||
|
|
unref: function unref() {
|
|||
|
|
var current = ref.current;
|
|||
|
|
var rangeRefs = Editor.rangeRefs(editor);
|
|||
|
|
rangeRefs["delete"](ref);
|
|||
|
|
ref.current = null;
|
|||
|
|
return current;
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
var refs = Editor.rangeRefs(editor);
|
|||
|
|
refs.add(ref);
|
|||
|
|
return ref;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Get the set of currently tracked range refs of the editor.
|
|||
|
|
*/
|
|||
|
|
rangeRefs: function rangeRefs(editor) {
|
|||
|
|
var refs = RANGE_REFS.get(editor);
|
|||
|
|
|
|||
|
|
if (!refs) {
|
|||
|
|
refs = new Set();
|
|||
|
|
RANGE_REFS.set(editor, refs);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return refs;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Remove a custom property from all of the leaf text nodes in the current
|
|||
|
|
* selection.
|
|||
|
|
*
|
|||
|
|
* If the selection is currently collapsed, the removal will be stored on
|
|||
|
|
* `editor.marks` and applied to the text inserted next.
|
|||
|
|
*/
|
|||
|
|
removeMark: function removeMark(editor, key) {
|
|||
|
|
editor.removeMark(key);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Manually set if the editor should currently be normalizing.
|
|||
|
|
*
|
|||
|
|
* Note: Using this incorrectly can leave the editor in an invalid state.
|
|||
|
|
*
|
|||
|
|
*/
|
|||
|
|
setNormalizing: function setNormalizing(editor, isNormalizing) {
|
|||
|
|
NORMALIZING.set(editor, isNormalizing);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Get the start point of a location.
|
|||
|
|
*/
|
|||
|
|
start: function start(editor, at) {
|
|||
|
|
return Editor.point(editor, at, {
|
|||
|
|
edge: 'start'
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Get the text string content of a location.
|
|||
|
|
*
|
|||
|
|
* Note: by default the text of void nodes is considered to be an empty
|
|||
|
|
* string, regardless of content, unless you pass in true for the voids option
|
|||
|
|
*/
|
|||
|
|
string: function string(editor, at) {
|
|||
|
|
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|||
|
|
var _options$voids7 = options.voids,
|
|||
|
|
voids = _options$voids7 === void 0 ? false : _options$voids7;
|
|||
|
|
var range = Editor.range(editor, at);
|
|||
|
|
|
|||
|
|
var _Range$edges5 = Range.edges(range),
|
|||
|
|
_Range$edges6 = _slicedToArray(_Range$edges5, 2),
|
|||
|
|
start = _Range$edges6[0],
|
|||
|
|
end = _Range$edges6[1];
|
|||
|
|
|
|||
|
|
var text = '';
|
|||
|
|
|
|||
|
|
var _iterator8 = _createForOfIteratorHelper$5(Editor.nodes(editor, {
|
|||
|
|
at: range,
|
|||
|
|
match: Text.isText,
|
|||
|
|
voids: voids
|
|||
|
|
})),
|
|||
|
|
_step8;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
|
|||
|
|
var _step8$value = _slicedToArray(_step8.value, 2),
|
|||
|
|
node = _step8$value[0],
|
|||
|
|
path = _step8$value[1];
|
|||
|
|
|
|||
|
|
var t = node.text;
|
|||
|
|
|
|||
|
|
if (Path.equals(path, end.path)) {
|
|||
|
|
t = t.slice(0, end.offset);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (Path.equals(path, start.path)) {
|
|||
|
|
t = t.slice(start.offset);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
text += t;
|
|||
|
|
}
|
|||
|
|
} catch (err) {
|
|||
|
|
_iterator8.e(err);
|
|||
|
|
} finally {
|
|||
|
|
_iterator8.f();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return text;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Convert a range into a non-hanging one.
|
|||
|
|
*/
|
|||
|
|
unhangRange: function unhangRange(editor, range) {
|
|||
|
|
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|||
|
|
var _options$voids8 = options.voids,
|
|||
|
|
voids = _options$voids8 === void 0 ? false : _options$voids8;
|
|||
|
|
|
|||
|
|
var _Range$edges7 = Range.edges(range),
|
|||
|
|
_Range$edges8 = _slicedToArray(_Range$edges7, 2),
|
|||
|
|
start = _Range$edges8[0],
|
|||
|
|
end = _Range$edges8[1]; // PERF: exit early if we can guarantee that the range isn't hanging.
|
|||
|
|
|
|||
|
|
|
|||
|
|
if (start.offset !== 0 || end.offset !== 0 || Range.isCollapsed(range)) {
|
|||
|
|
return range;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var endBlock = Editor.above(editor, {
|
|||
|
|
at: end,
|
|||
|
|
match: function match(n) {
|
|||
|
|
return Editor.isBlock(editor, n);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
var blockPath = endBlock ? endBlock[1] : [];
|
|||
|
|
var first = Editor.start(editor, []);
|
|||
|
|
var before = {
|
|||
|
|
anchor: first,
|
|||
|
|
focus: end
|
|||
|
|
};
|
|||
|
|
var skip = true;
|
|||
|
|
|
|||
|
|
var _iterator9 = _createForOfIteratorHelper$5(Editor.nodes(editor, {
|
|||
|
|
at: before,
|
|||
|
|
match: Text.isText,
|
|||
|
|
reverse: true,
|
|||
|
|
voids: voids
|
|||
|
|
})),
|
|||
|
|
_step9;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
for (_iterator9.s(); !(_step9 = _iterator9.n()).done;) {
|
|||
|
|
var _step9$value = _slicedToArray(_step9.value, 2),
|
|||
|
|
node = _step9$value[0],
|
|||
|
|
path = _step9$value[1];
|
|||
|
|
|
|||
|
|
if (skip) {
|
|||
|
|
skip = false;
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (node.text !== '' || Path.isBefore(path, blockPath)) {
|
|||
|
|
end = {
|
|||
|
|
path: path,
|
|||
|
|
offset: node.text.length
|
|||
|
|
};
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
} catch (err) {
|
|||
|
|
_iterator9.e(err);
|
|||
|
|
} finally {
|
|||
|
|
_iterator9.f();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return {
|
|||
|
|
anchor: start,
|
|||
|
|
focus: end
|
|||
|
|
};
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Match a void node in the current branch of the editor.
|
|||
|
|
*/
|
|||
|
|
"void": function _void(editor) {
|
|||
|
|
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|||
|
|
return Editor.above(editor, _objectSpread$8(_objectSpread$8({}, options), {}, {
|
|||
|
|
match: function match(n) {
|
|||
|
|
return Editor.isVoid(editor, n);
|
|||
|
|
}
|
|||
|
|
}));
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Call a function, deferring normalization until after it completes.
|
|||
|
|
*/
|
|||
|
|
withoutNormalizing: function withoutNormalizing(editor, fn) {
|
|||
|
|
var value = Editor.isNormalizing(editor);
|
|||
|
|
Editor.setNormalizing(editor, false);
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
fn();
|
|||
|
|
} finally {
|
|||
|
|
Editor.setNormalizing(editor, value);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Editor.normalize(editor);
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var Location = {
|
|||
|
|
/**
|
|||
|
|
* Check if a value implements the `Location` interface.
|
|||
|
|
*/
|
|||
|
|
isLocation: function isLocation(value) {
|
|||
|
|
return Path.isPath(value) || Point.isPoint(value) || Range.isRange(value);
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
var Span = {
|
|||
|
|
/**
|
|||
|
|
* Check if a value implements the `Span` interface.
|
|||
|
|
*/
|
|||
|
|
isSpan: function isSpan(value) {
|
|||
|
|
return Array.isArray(value) && value.length === 2 && value.every(Path.isPath);
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var _excluded$3 = ["children"],
|
|||
|
|
_excluded2$2 = ["text"];
|
|||
|
|
|
|||
|
|
function _createForOfIteratorHelper$4(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$4(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
|
|||
|
|
|
|||
|
|
function _unsupportedIterableToArray$4(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$4(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray$4(o, minLen); }
|
|||
|
|
|
|||
|
|
function _arrayLikeToArray$4(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|||
|
|
var IS_NODE_LIST_CACHE = new WeakMap();
|
|||
|
|
var Node$1 = {
|
|||
|
|
/**
|
|||
|
|
* Get the node at a specific path, asserting that it's an ancestor node.
|
|||
|
|
*/
|
|||
|
|
ancestor: function ancestor(root, path) {
|
|||
|
|
var node = Node$1.get(root, path);
|
|||
|
|
|
|||
|
|
if (Text.isText(node)) {
|
|||
|
|
throw new Error("Cannot get the ancestor node at path [".concat(path, "] because it refers to a text node instead: ").concat(node));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return node;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Return a generator of all the ancestor nodes above a specific path.
|
|||
|
|
*
|
|||
|
|
* By default the order is bottom-up, from lowest to highest ancestor in
|
|||
|
|
* the tree, but you can pass the `reverse: true` option to go top-down.
|
|||
|
|
*/
|
|||
|
|
ancestors: function* ancestors(root, path) {
|
|||
|
|
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|||
|
|
|
|||
|
|
var _iterator = _createForOfIteratorHelper$4(Path.ancestors(path, options)),
|
|||
|
|
_step;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|||
|
|
var p = _step.value;
|
|||
|
|
var n = Node$1.ancestor(root, p);
|
|||
|
|
var entry = [n, p];
|
|||
|
|
yield entry;
|
|||
|
|
}
|
|||
|
|
} catch (err) {
|
|||
|
|
_iterator.e(err);
|
|||
|
|
} finally {
|
|||
|
|
_iterator.f();
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Get the child of a node at a specific index.
|
|||
|
|
*/
|
|||
|
|
child: function child(root, index) {
|
|||
|
|
if (Text.isText(root)) {
|
|||
|
|
throw new Error("Cannot get the child of a text node: ".concat(JSON.stringify(root)));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var c = root.children[index];
|
|||
|
|
|
|||
|
|
if (c == null) {
|
|||
|
|
throw new Error("Cannot get child at index `".concat(index, "` in node: ").concat(JSON.stringify(root)));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return c;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Iterate over the children of a node at a specific path.
|
|||
|
|
*/
|
|||
|
|
children: function* children(root, path) {
|
|||
|
|
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|||
|
|
var _options$reverse = options.reverse,
|
|||
|
|
reverse = _options$reverse === void 0 ? false : _options$reverse;
|
|||
|
|
var ancestor = Node$1.ancestor(root, path);
|
|||
|
|
var children = ancestor.children;
|
|||
|
|
var index = reverse ? children.length - 1 : 0;
|
|||
|
|
|
|||
|
|
while (reverse ? index >= 0 : index < children.length) {
|
|||
|
|
var child = Node$1.child(ancestor, index);
|
|||
|
|
var childPath = path.concat(index);
|
|||
|
|
yield [child, childPath];
|
|||
|
|
index = reverse ? index - 1 : index + 1;
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Get an entry for the common ancesetor node of two paths.
|
|||
|
|
*/
|
|||
|
|
common: function common(root, path, another) {
|
|||
|
|
var p = Path.common(path, another);
|
|||
|
|
var n = Node$1.get(root, p);
|
|||
|
|
return [n, p];
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Get the node at a specific path, asserting that it's a descendant node.
|
|||
|
|
*/
|
|||
|
|
descendant: function descendant(root, path) {
|
|||
|
|
var node = Node$1.get(root, path);
|
|||
|
|
|
|||
|
|
if (Editor.isEditor(node)) {
|
|||
|
|
throw new Error("Cannot get the descendant node at path [".concat(path, "] because it refers to the root editor node instead: ").concat(node));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return node;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Return a generator of all the descendant node entries inside a root node.
|
|||
|
|
*/
|
|||
|
|
descendants: function* descendants(root) {
|
|||
|
|
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|||
|
|
|
|||
|
|
var _iterator2 = _createForOfIteratorHelper$4(Node$1.nodes(root, options)),
|
|||
|
|
_step2;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|||
|
|
var _step2$value = _slicedToArray(_step2.value, 2),
|
|||
|
|
node = _step2$value[0],
|
|||
|
|
path = _step2$value[1];
|
|||
|
|
|
|||
|
|
if (path.length !== 0) {
|
|||
|
|
// NOTE: we have to coerce here because checking the path's length does
|
|||
|
|
// guarantee that `node` is not a `Editor`, but TypeScript doesn't know.
|
|||
|
|
yield [node, path];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
} catch (err) {
|
|||
|
|
_iterator2.e(err);
|
|||
|
|
} finally {
|
|||
|
|
_iterator2.f();
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Return a generator of all the element nodes inside a root node. Each iteration
|
|||
|
|
* will return an `ElementEntry` tuple consisting of `[Element, Path]`. If the
|
|||
|
|
* root node is an element it will be included in the iteration as well.
|
|||
|
|
*/
|
|||
|
|
elements: function* elements(root) {
|
|||
|
|
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|||
|
|
|
|||
|
|
var _iterator3 = _createForOfIteratorHelper$4(Node$1.nodes(root, options)),
|
|||
|
|
_step3;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|||
|
|
var _step3$value = _slicedToArray(_step3.value, 2),
|
|||
|
|
node = _step3$value[0],
|
|||
|
|
path = _step3$value[1];
|
|||
|
|
|
|||
|
|
if (Element$1.isElement(node)) {
|
|||
|
|
yield [node, path];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
} catch (err) {
|
|||
|
|
_iterator3.e(err);
|
|||
|
|
} finally {
|
|||
|
|
_iterator3.f();
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Extract props from a Node.
|
|||
|
|
*/
|
|||
|
|
extractProps: function extractProps(node) {
|
|||
|
|
if (Element$1.isAncestor(node)) {
|
|||
|
|
node.children;
|
|||
|
|
var properties = _objectWithoutProperties(node, _excluded$3);
|
|||
|
|
|
|||
|
|
return properties;
|
|||
|
|
} else {
|
|||
|
|
node.text;
|
|||
|
|
var _properties = _objectWithoutProperties(node, _excluded2$2);
|
|||
|
|
|
|||
|
|
return _properties;
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Get the first node entry in a root node from a path.
|
|||
|
|
*/
|
|||
|
|
first: function first(root, path) {
|
|||
|
|
var p = path.slice();
|
|||
|
|
var n = Node$1.get(root, p);
|
|||
|
|
|
|||
|
|
while (n) {
|
|||
|
|
if (Text.isText(n) || n.children.length === 0) {
|
|||
|
|
break;
|
|||
|
|
} else {
|
|||
|
|
n = n.children[0];
|
|||
|
|
p.push(0);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return [n, p];
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Get the sliced fragment represented by a range inside a root node.
|
|||
|
|
*/
|
|||
|
|
fragment: function fragment(root, range) {
|
|||
|
|
if (Text.isText(root)) {
|
|||
|
|
throw new Error("Cannot get a fragment starting from a root text node: ".concat(JSON.stringify(root)));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var newRoot = immer.produce({
|
|||
|
|
children: root.children
|
|||
|
|
}, function (r) {
|
|||
|
|
var _Range$edges = Range.edges(range),
|
|||
|
|
_Range$edges2 = _slicedToArray(_Range$edges, 2),
|
|||
|
|
start = _Range$edges2[0],
|
|||
|
|
end = _Range$edges2[1];
|
|||
|
|
|
|||
|
|
var nodeEntries = Node$1.nodes(r, {
|
|||
|
|
reverse: true,
|
|||
|
|
pass: function pass(_ref) {
|
|||
|
|
var _ref2 = _slicedToArray(_ref, 2),
|
|||
|
|
path = _ref2[1];
|
|||
|
|
|
|||
|
|
return !Range.includes(range, path);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
var _iterator4 = _createForOfIteratorHelper$4(nodeEntries),
|
|||
|
|
_step4;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
|
|||
|
|
var _step4$value = _slicedToArray(_step4.value, 2),
|
|||
|
|
path = _step4$value[1];
|
|||
|
|
|
|||
|
|
if (!Range.includes(range, path)) {
|
|||
|
|
var parent = Node$1.parent(r, path);
|
|||
|
|
var index = path[path.length - 1];
|
|||
|
|
parent.children.splice(index, 1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (Path.equals(path, end.path)) {
|
|||
|
|
var leaf = Node$1.leaf(r, path);
|
|||
|
|
leaf.text = leaf.text.slice(0, end.offset);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (Path.equals(path, start.path)) {
|
|||
|
|
var _leaf = Node$1.leaf(r, path);
|
|||
|
|
|
|||
|
|
_leaf.text = _leaf.text.slice(start.offset);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
} catch (err) {
|
|||
|
|
_iterator4.e(err);
|
|||
|
|
} finally {
|
|||
|
|
_iterator4.f();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (Editor.isEditor(r)) {
|
|||
|
|
r.selection = null;
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
return newRoot.children;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Get the descendant node referred to by a specific path. If the path is an
|
|||
|
|
* empty array, it refers to the root node itself.
|
|||
|
|
*/
|
|||
|
|
get: function get(root, path) {
|
|||
|
|
var node = root;
|
|||
|
|
|
|||
|
|
for (var i = 0; i < path.length; i++) {
|
|||
|
|
var p = path[i];
|
|||
|
|
|
|||
|
|
if (Text.isText(node) || !node.children[p]) {
|
|||
|
|
throw new Error("Cannot find a descendant at path [".concat(path, "] in node: ").concat(JSON.stringify(root)));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
node = node.children[p];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return node;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if a descendant node exists at a specific path.
|
|||
|
|
*/
|
|||
|
|
has: function has(root, path) {
|
|||
|
|
var node = root;
|
|||
|
|
|
|||
|
|
for (var i = 0; i < path.length; i++) {
|
|||
|
|
var p = path[i];
|
|||
|
|
|
|||
|
|
if (Text.isText(node) || !node.children[p]) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
node = node.children[p];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if a value implements the `Node` interface.
|
|||
|
|
*/
|
|||
|
|
isNode: function isNode(value) {
|
|||
|
|
return Text.isText(value) || Element$1.isElement(value) || Editor.isEditor(value);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if a value is a list of `Node` objects.
|
|||
|
|
*/
|
|||
|
|
isNodeList: function isNodeList(value) {
|
|||
|
|
if (!Array.isArray(value)) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var cachedResult = IS_NODE_LIST_CACHE.get(value);
|
|||
|
|
|
|||
|
|
if (cachedResult !== undefined) {
|
|||
|
|
return cachedResult;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var isNodeList = value.every(function (val) {
|
|||
|
|
return Node$1.isNode(val);
|
|||
|
|
});
|
|||
|
|
IS_NODE_LIST_CACHE.set(value, isNodeList);
|
|||
|
|
return isNodeList;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Get the last node entry in a root node from a path.
|
|||
|
|
*/
|
|||
|
|
last: function last(root, path) {
|
|||
|
|
var p = path.slice();
|
|||
|
|
var n = Node$1.get(root, p);
|
|||
|
|
|
|||
|
|
while (n) {
|
|||
|
|
if (Text.isText(n) || n.children.length === 0) {
|
|||
|
|
break;
|
|||
|
|
} else {
|
|||
|
|
var i = n.children.length - 1;
|
|||
|
|
n = n.children[i];
|
|||
|
|
p.push(i);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return [n, p];
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Get the node at a specific path, ensuring it's a leaf text node.
|
|||
|
|
*/
|
|||
|
|
leaf: function leaf(root, path) {
|
|||
|
|
var node = Node$1.get(root, path);
|
|||
|
|
|
|||
|
|
if (!Text.isText(node)) {
|
|||
|
|
throw new Error("Cannot get the leaf node at path [".concat(path, "] because it refers to a non-leaf node: ").concat(node));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return node;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Return a generator of the in a branch of the tree, from a specific path.
|
|||
|
|
*
|
|||
|
|
* By default the order is top-down, from lowest to highest node in the tree,
|
|||
|
|
* but you can pass the `reverse: true` option to go bottom-up.
|
|||
|
|
*/
|
|||
|
|
levels: function* levels(root, path) {
|
|||
|
|
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|||
|
|
|
|||
|
|
var _iterator5 = _createForOfIteratorHelper$4(Path.levels(path, options)),
|
|||
|
|
_step5;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
|
|||
|
|
var p = _step5.value;
|
|||
|
|
var n = Node$1.get(root, p);
|
|||
|
|
yield [n, p];
|
|||
|
|
}
|
|||
|
|
} catch (err) {
|
|||
|
|
_iterator5.e(err);
|
|||
|
|
} finally {
|
|||
|
|
_iterator5.f();
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if a node matches a set of props.
|
|||
|
|
*/
|
|||
|
|
matches: function matches(node, props) {
|
|||
|
|
return Element$1.isElement(node) && Element$1.isElementProps(props) && Element$1.matches(node, props) || Text.isText(node) && Text.isTextProps(props) && Text.matches(node, props);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Return a generator of all the node entries of a root node. Each entry is
|
|||
|
|
* returned as a `[Node, Path]` tuple, with the path referring to the node's
|
|||
|
|
* position inside the root node.
|
|||
|
|
*/
|
|||
|
|
nodes: function* nodes(root) {
|
|||
|
|
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|||
|
|
var pass = options.pass,
|
|||
|
|
_options$reverse2 = options.reverse,
|
|||
|
|
reverse = _options$reverse2 === void 0 ? false : _options$reverse2;
|
|||
|
|
var _options$from = options.from,
|
|||
|
|
from = _options$from === void 0 ? [] : _options$from,
|
|||
|
|
to = options.to;
|
|||
|
|
var visited = new Set();
|
|||
|
|
var p = [];
|
|||
|
|
var n = root;
|
|||
|
|
|
|||
|
|
while (true) {
|
|||
|
|
if (to && (reverse ? Path.isBefore(p, to) : Path.isAfter(p, to))) {
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!visited.has(n)) {
|
|||
|
|
yield [n, p];
|
|||
|
|
} // If we're allowed to go downward and we haven't descended yet, do.
|
|||
|
|
|
|||
|
|
|
|||
|
|
if (!visited.has(n) && !Text.isText(n) && n.children.length !== 0 && (pass == null || pass([n, p]) === false)) {
|
|||
|
|
visited.add(n);
|
|||
|
|
var nextIndex = reverse ? n.children.length - 1 : 0;
|
|||
|
|
|
|||
|
|
if (Path.isAncestor(p, from)) {
|
|||
|
|
nextIndex = from[p.length];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
p = p.concat(nextIndex);
|
|||
|
|
n = Node$1.get(root, p);
|
|||
|
|
continue;
|
|||
|
|
} // If we're at the root and we can't go down, we're done.
|
|||
|
|
|
|||
|
|
|
|||
|
|
if (p.length === 0) {
|
|||
|
|
break;
|
|||
|
|
} // If we're going forward...
|
|||
|
|
|
|||
|
|
|
|||
|
|
if (!reverse) {
|
|||
|
|
var newPath = Path.next(p);
|
|||
|
|
|
|||
|
|
if (Node$1.has(root, newPath)) {
|
|||
|
|
p = newPath;
|
|||
|
|
n = Node$1.get(root, p);
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
} // If we're going backward...
|
|||
|
|
|
|||
|
|
|
|||
|
|
if (reverse && p[p.length - 1] !== 0) {
|
|||
|
|
var _newPath = Path.previous(p);
|
|||
|
|
|
|||
|
|
p = _newPath;
|
|||
|
|
n = Node$1.get(root, p);
|
|||
|
|
continue;
|
|||
|
|
} // Otherwise we're going upward...
|
|||
|
|
|
|||
|
|
|
|||
|
|
p = Path.parent(p);
|
|||
|
|
n = Node$1.get(root, p);
|
|||
|
|
visited.add(n);
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Get the parent of a node at a specific path.
|
|||
|
|
*/
|
|||
|
|
parent: function parent(root, path) {
|
|||
|
|
var parentPath = Path.parent(path);
|
|||
|
|
var p = Node$1.get(root, parentPath);
|
|||
|
|
|
|||
|
|
if (Text.isText(p)) {
|
|||
|
|
throw new Error("Cannot get the parent of path [".concat(path, "] because it does not exist in the root."));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return p;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Get the concatenated text string of a node's content.
|
|||
|
|
*
|
|||
|
|
* Note that this will not include spaces or line breaks between block nodes.
|
|||
|
|
* It is not a user-facing string, but a string for performing offset-related
|
|||
|
|
* computations for a node.
|
|||
|
|
*/
|
|||
|
|
string: function string(node) {
|
|||
|
|
if (Text.isText(node)) {
|
|||
|
|
return node.text;
|
|||
|
|
} else {
|
|||
|
|
return node.children.map(Node$1.string).join('');
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Return a generator of all leaf text nodes in a root node.
|
|||
|
|
*/
|
|||
|
|
texts: function* texts(root) {
|
|||
|
|
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|||
|
|
|
|||
|
|
var _iterator6 = _createForOfIteratorHelper$4(Node$1.nodes(root, options)),
|
|||
|
|
_step6;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
|
|||
|
|
var _step6$value = _slicedToArray(_step6.value, 2),
|
|||
|
|
node = _step6$value[0],
|
|||
|
|
path = _step6$value[1];
|
|||
|
|
|
|||
|
|
if (Text.isText(node)) {
|
|||
|
|
yield [node, path];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
} catch (err) {
|
|||
|
|
_iterator6.e(err);
|
|||
|
|
} finally {
|
|||
|
|
_iterator6.f();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
function ownKeys$7(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
|
|||
|
|
|
|||
|
|
function _objectSpread$7(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$7(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$7(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
|||
|
|
var Operation = {
|
|||
|
|
/**
|
|||
|
|
* Check of a value is a `NodeOperation` object.
|
|||
|
|
*/
|
|||
|
|
isNodeOperation: function isNodeOperation(value) {
|
|||
|
|
return Operation.isOperation(value) && value.type.endsWith('_node');
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check of a value is an `Operation` object.
|
|||
|
|
*/
|
|||
|
|
isOperation: function isOperation(value) {
|
|||
|
|
if (!isPlainObject.isPlainObject(value)) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
switch (value.type) {
|
|||
|
|
case 'insert_node':
|
|||
|
|
return Path.isPath(value.path) && Node$1.isNode(value.node);
|
|||
|
|
|
|||
|
|
case 'insert_text':
|
|||
|
|
return typeof value.offset === 'number' && typeof value.text === 'string' && Path.isPath(value.path);
|
|||
|
|
|
|||
|
|
case 'merge_node':
|
|||
|
|
return typeof value.position === 'number' && Path.isPath(value.path) && isPlainObject.isPlainObject(value.properties);
|
|||
|
|
|
|||
|
|
case 'move_node':
|
|||
|
|
return Path.isPath(value.path) && Path.isPath(value.newPath);
|
|||
|
|
|
|||
|
|
case 'remove_node':
|
|||
|
|
return Path.isPath(value.path) && Node$1.isNode(value.node);
|
|||
|
|
|
|||
|
|
case 'remove_text':
|
|||
|
|
return typeof value.offset === 'number' && typeof value.text === 'string' && Path.isPath(value.path);
|
|||
|
|
|
|||
|
|
case 'set_node':
|
|||
|
|
return Path.isPath(value.path) && isPlainObject.isPlainObject(value.properties) && isPlainObject.isPlainObject(value.newProperties);
|
|||
|
|
|
|||
|
|
case 'set_selection':
|
|||
|
|
return value.properties === null && Range.isRange(value.newProperties) || value.newProperties === null && Range.isRange(value.properties) || isPlainObject.isPlainObject(value.properties) && isPlainObject.isPlainObject(value.newProperties);
|
|||
|
|
|
|||
|
|
case 'split_node':
|
|||
|
|
return Path.isPath(value.path) && typeof value.position === 'number' && isPlainObject.isPlainObject(value.properties);
|
|||
|
|
|
|||
|
|
default:
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if a value is a list of `Operation` objects.
|
|||
|
|
*/
|
|||
|
|
isOperationList: function isOperationList(value) {
|
|||
|
|
return Array.isArray(value) && value.every(function (val) {
|
|||
|
|
return Operation.isOperation(val);
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check of a value is a `SelectionOperation` object.
|
|||
|
|
*/
|
|||
|
|
isSelectionOperation: function isSelectionOperation(value) {
|
|||
|
|
return Operation.isOperation(value) && value.type.endsWith('_selection');
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check of a value is a `TextOperation` object.
|
|||
|
|
*/
|
|||
|
|
isTextOperation: function isTextOperation(value) {
|
|||
|
|
return Operation.isOperation(value) && value.type.endsWith('_text');
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Invert an operation, returning a new operation that will exactly undo the
|
|||
|
|
* original when applied.
|
|||
|
|
*/
|
|||
|
|
inverse: function inverse(op) {
|
|||
|
|
switch (op.type) {
|
|||
|
|
case 'insert_node':
|
|||
|
|
{
|
|||
|
|
return _objectSpread$7(_objectSpread$7({}, op), {}, {
|
|||
|
|
type: 'remove_node'
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
case 'insert_text':
|
|||
|
|
{
|
|||
|
|
return _objectSpread$7(_objectSpread$7({}, op), {}, {
|
|||
|
|
type: 'remove_text'
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
case 'merge_node':
|
|||
|
|
{
|
|||
|
|
return _objectSpread$7(_objectSpread$7({}, op), {}, {
|
|||
|
|
type: 'split_node',
|
|||
|
|
path: Path.previous(op.path)
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
case 'move_node':
|
|||
|
|
{
|
|||
|
|
var newPath = op.newPath,
|
|||
|
|
path = op.path; // PERF: in this case the move operation is a no-op anyways.
|
|||
|
|
|
|||
|
|
if (Path.equals(newPath, path)) {
|
|||
|
|
return op;
|
|||
|
|
} // If the move happens completely within a single parent the path and
|
|||
|
|
// newPath are stable with respect to each other.
|
|||
|
|
|
|||
|
|
|
|||
|
|
if (Path.isSibling(path, newPath)) {
|
|||
|
|
return _objectSpread$7(_objectSpread$7({}, op), {}, {
|
|||
|
|
path: newPath,
|
|||
|
|
newPath: path
|
|||
|
|
});
|
|||
|
|
} // If the move does not happen within a single parent it is possible
|
|||
|
|
// for the move to impact the true path to the location where the node
|
|||
|
|
// was removed from and where it was inserted. We have to adjust for this
|
|||
|
|
// and find the original path. We can accomplish this (only in non-sibling)
|
|||
|
|
// moves by looking at the impact of the move operation on the node
|
|||
|
|
// after the original move path.
|
|||
|
|
|
|||
|
|
|
|||
|
|
var inversePath = Path.transform(path, op);
|
|||
|
|
var inverseNewPath = Path.transform(Path.next(path), op);
|
|||
|
|
return _objectSpread$7(_objectSpread$7({}, op), {}, {
|
|||
|
|
path: inversePath,
|
|||
|
|
newPath: inverseNewPath
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
case 'remove_node':
|
|||
|
|
{
|
|||
|
|
return _objectSpread$7(_objectSpread$7({}, op), {}, {
|
|||
|
|
type: 'insert_node'
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
case 'remove_text':
|
|||
|
|
{
|
|||
|
|
return _objectSpread$7(_objectSpread$7({}, op), {}, {
|
|||
|
|
type: 'insert_text'
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
case 'set_node':
|
|||
|
|
{
|
|||
|
|
var properties = op.properties,
|
|||
|
|
newProperties = op.newProperties;
|
|||
|
|
return _objectSpread$7(_objectSpread$7({}, op), {}, {
|
|||
|
|
properties: newProperties,
|
|||
|
|
newProperties: properties
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
case 'set_selection':
|
|||
|
|
{
|
|||
|
|
var _properties = op.properties,
|
|||
|
|
_newProperties = op.newProperties;
|
|||
|
|
|
|||
|
|
if (_properties == null) {
|
|||
|
|
return _objectSpread$7(_objectSpread$7({}, op), {}, {
|
|||
|
|
properties: _newProperties,
|
|||
|
|
newProperties: null
|
|||
|
|
});
|
|||
|
|
} else if (_newProperties == null) {
|
|||
|
|
return _objectSpread$7(_objectSpread$7({}, op), {}, {
|
|||
|
|
properties: null,
|
|||
|
|
newProperties: _properties
|
|||
|
|
});
|
|||
|
|
} else {
|
|||
|
|
return _objectSpread$7(_objectSpread$7({}, op), {}, {
|
|||
|
|
properties: _newProperties,
|
|||
|
|
newProperties: _properties
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
case 'split_node':
|
|||
|
|
{
|
|||
|
|
return _objectSpread$7(_objectSpread$7({}, op), {}, {
|
|||
|
|
type: 'merge_node',
|
|||
|
|
path: Path.next(op.path)
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var Path = {
|
|||
|
|
/**
|
|||
|
|
* Get a list of ancestor paths for a given path.
|
|||
|
|
*
|
|||
|
|
* The paths are sorted from deepest to shallowest ancestor. However, if the
|
|||
|
|
* `reverse: true` option is passed, they are reversed.
|
|||
|
|
*/
|
|||
|
|
ancestors: function ancestors(path) {
|
|||
|
|
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|||
|
|
var _options$reverse = options.reverse,
|
|||
|
|
reverse = _options$reverse === void 0 ? false : _options$reverse;
|
|||
|
|
var paths = Path.levels(path, options);
|
|||
|
|
|
|||
|
|
if (reverse) {
|
|||
|
|
paths = paths.slice(1);
|
|||
|
|
} else {
|
|||
|
|
paths = paths.slice(0, -1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return paths;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Get the common ancestor path of two paths.
|
|||
|
|
*/
|
|||
|
|
common: function common(path, another) {
|
|||
|
|
var common = [];
|
|||
|
|
|
|||
|
|
for (var i = 0; i < path.length && i < another.length; i++) {
|
|||
|
|
var av = path[i];
|
|||
|
|
var bv = another[i];
|
|||
|
|
|
|||
|
|
if (av !== bv) {
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
common.push(av);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return common;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Compare a path to another, returning an integer indicating whether the path
|
|||
|
|
* was before, at, or after the other.
|
|||
|
|
*
|
|||
|
|
* Note: Two paths of unequal length can still receive a `0` result if one is
|
|||
|
|
* directly above or below the other. If you want exact matching, use
|
|||
|
|
* [[Path.equals]] instead.
|
|||
|
|
*/
|
|||
|
|
compare: function compare(path, another) {
|
|||
|
|
var min = Math.min(path.length, another.length);
|
|||
|
|
|
|||
|
|
for (var i = 0; i < min; i++) {
|
|||
|
|
if (path[i] < another[i]) return -1;
|
|||
|
|
if (path[i] > another[i]) return 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return 0;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if a path ends after one of the indexes in another.
|
|||
|
|
*/
|
|||
|
|
endsAfter: function endsAfter(path, another) {
|
|||
|
|
var i = path.length - 1;
|
|||
|
|
var as = path.slice(0, i);
|
|||
|
|
var bs = another.slice(0, i);
|
|||
|
|
var av = path[i];
|
|||
|
|
var bv = another[i];
|
|||
|
|
return Path.equals(as, bs) && av > bv;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if a path ends at one of the indexes in another.
|
|||
|
|
*/
|
|||
|
|
endsAt: function endsAt(path, another) {
|
|||
|
|
var i = path.length;
|
|||
|
|
var as = path.slice(0, i);
|
|||
|
|
var bs = another.slice(0, i);
|
|||
|
|
return Path.equals(as, bs);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if a path ends before one of the indexes in another.
|
|||
|
|
*/
|
|||
|
|
endsBefore: function endsBefore(path, another) {
|
|||
|
|
var i = path.length - 1;
|
|||
|
|
var as = path.slice(0, i);
|
|||
|
|
var bs = another.slice(0, i);
|
|||
|
|
var av = path[i];
|
|||
|
|
var bv = another[i];
|
|||
|
|
return Path.equals(as, bs) && av < bv;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if a path is exactly equal to another.
|
|||
|
|
*/
|
|||
|
|
equals: function equals(path, another) {
|
|||
|
|
return path.length === another.length && path.every(function (n, i) {
|
|||
|
|
return n === another[i];
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if the path of previous sibling node exists
|
|||
|
|
*/
|
|||
|
|
hasPrevious: function hasPrevious(path) {
|
|||
|
|
return path[path.length - 1] > 0;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if a path is after another.
|
|||
|
|
*/
|
|||
|
|
isAfter: function isAfter(path, another) {
|
|||
|
|
return Path.compare(path, another) === 1;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if a path is an ancestor of another.
|
|||
|
|
*/
|
|||
|
|
isAncestor: function isAncestor(path, another) {
|
|||
|
|
return path.length < another.length && Path.compare(path, another) === 0;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if a path is before another.
|
|||
|
|
*/
|
|||
|
|
isBefore: function isBefore(path, another) {
|
|||
|
|
return Path.compare(path, another) === -1;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if a path is a child of another.
|
|||
|
|
*/
|
|||
|
|
isChild: function isChild(path, another) {
|
|||
|
|
return path.length === another.length + 1 && Path.compare(path, another) === 0;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if a path is equal to or an ancestor of another.
|
|||
|
|
*/
|
|||
|
|
isCommon: function isCommon(path, another) {
|
|||
|
|
return path.length <= another.length && Path.compare(path, another) === 0;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if a path is a descendant of another.
|
|||
|
|
*/
|
|||
|
|
isDescendant: function isDescendant(path, another) {
|
|||
|
|
return path.length > another.length && Path.compare(path, another) === 0;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if a path is the parent of another.
|
|||
|
|
*/
|
|||
|
|
isParent: function isParent(path, another) {
|
|||
|
|
return path.length + 1 === another.length && Path.compare(path, another) === 0;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check is a value implements the `Path` interface.
|
|||
|
|
*/
|
|||
|
|
isPath: function isPath(value) {
|
|||
|
|
return Array.isArray(value) && (value.length === 0 || typeof value[0] === 'number');
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if a path is a sibling of another.
|
|||
|
|
*/
|
|||
|
|
isSibling: function isSibling(path, another) {
|
|||
|
|
if (path.length !== another.length) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var as = path.slice(0, -1);
|
|||
|
|
var bs = another.slice(0, -1);
|
|||
|
|
var al = path[path.length - 1];
|
|||
|
|
var bl = another[another.length - 1];
|
|||
|
|
return al !== bl && Path.equals(as, bs);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Get a list of paths at every level down to a path. Note: this is the same
|
|||
|
|
* as `Path.ancestors`, but including the path itself.
|
|||
|
|
*
|
|||
|
|
* The paths are sorted from shallowest to deepest. However, if the `reverse:
|
|||
|
|
* true` option is passed, they are reversed.
|
|||
|
|
*/
|
|||
|
|
levels: function levels(path) {
|
|||
|
|
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|||
|
|
var _options$reverse2 = options.reverse,
|
|||
|
|
reverse = _options$reverse2 === void 0 ? false : _options$reverse2;
|
|||
|
|
var list = [];
|
|||
|
|
|
|||
|
|
for (var i = 0; i <= path.length; i++) {
|
|||
|
|
list.push(path.slice(0, i));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (reverse) {
|
|||
|
|
list.reverse();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return list;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Given a path, get the path to the next sibling node.
|
|||
|
|
*/
|
|||
|
|
next: function next(path) {
|
|||
|
|
if (path.length === 0) {
|
|||
|
|
throw new Error("Cannot get the next path of a root path [".concat(path, "], because it has no next index."));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var last = path[path.length - 1];
|
|||
|
|
return path.slice(0, -1).concat(last + 1);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Given a path, return a new path referring to the parent node above it.
|
|||
|
|
*/
|
|||
|
|
parent: function parent(path) {
|
|||
|
|
if (path.length === 0) {
|
|||
|
|
throw new Error("Cannot get the parent path of the root path [".concat(path, "]."));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return path.slice(0, -1);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Given a path, get the path to the previous sibling node.
|
|||
|
|
*/
|
|||
|
|
previous: function previous(path) {
|
|||
|
|
if (path.length === 0) {
|
|||
|
|
throw new Error("Cannot get the previous path of a root path [".concat(path, "], because it has no previous index."));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var last = path[path.length - 1];
|
|||
|
|
|
|||
|
|
if (last <= 0) {
|
|||
|
|
throw new Error("Cannot get the previous path of a first child path [".concat(path, "] because it would result in a negative index."));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return path.slice(0, -1).concat(last - 1);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Get a path relative to an ancestor.
|
|||
|
|
*/
|
|||
|
|
relative: function relative(path, ancestor) {
|
|||
|
|
if (!Path.isAncestor(ancestor, path) && !Path.equals(path, ancestor)) {
|
|||
|
|
throw new Error("Cannot get the relative path of [".concat(path, "] inside ancestor [").concat(ancestor, "], because it is not above or equal to the path."));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return path.slice(ancestor.length);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Transform a path by an operation.
|
|||
|
|
*/
|
|||
|
|
transform: function transform(path, operation) {
|
|||
|
|
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|||
|
|
return immer.produce(path, function (p) {
|
|||
|
|
var _options$affinity = options.affinity,
|
|||
|
|
affinity = _options$affinity === void 0 ? 'forward' : _options$affinity; // PERF: Exit early if the operation is guaranteed not to have an effect.
|
|||
|
|
|
|||
|
|
if (!path || (path === null || path === void 0 ? void 0 : path.length) === 0) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (p === null) {
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
switch (operation.type) {
|
|||
|
|
case 'insert_node':
|
|||
|
|
{
|
|||
|
|
var op = operation.path;
|
|||
|
|
|
|||
|
|
if (Path.equals(op, p) || Path.endsBefore(op, p) || Path.isAncestor(op, p)) {
|
|||
|
|
p[op.length - 1] += 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
case 'remove_node':
|
|||
|
|
{
|
|||
|
|
var _op = operation.path;
|
|||
|
|
|
|||
|
|
if (Path.equals(_op, p) || Path.isAncestor(_op, p)) {
|
|||
|
|
return null;
|
|||
|
|
} else if (Path.endsBefore(_op, p)) {
|
|||
|
|
p[_op.length - 1] -= 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
case 'merge_node':
|
|||
|
|
{
|
|||
|
|
var _op2 = operation.path,
|
|||
|
|
position = operation.position;
|
|||
|
|
|
|||
|
|
if (Path.equals(_op2, p) || Path.endsBefore(_op2, p)) {
|
|||
|
|
p[_op2.length - 1] -= 1;
|
|||
|
|
} else if (Path.isAncestor(_op2, p)) {
|
|||
|
|
p[_op2.length - 1] -= 1;
|
|||
|
|
p[_op2.length] += position;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
case 'split_node':
|
|||
|
|
{
|
|||
|
|
var _op3 = operation.path,
|
|||
|
|
_position = operation.position;
|
|||
|
|
|
|||
|
|
if (Path.equals(_op3, p)) {
|
|||
|
|
if (affinity === 'forward') {
|
|||
|
|
p[p.length - 1] += 1;
|
|||
|
|
} else if (affinity === 'backward') ; else {
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
} else if (Path.endsBefore(_op3, p)) {
|
|||
|
|
p[_op3.length - 1] += 1;
|
|||
|
|
} else if (Path.isAncestor(_op3, p) && path[_op3.length] >= _position) {
|
|||
|
|
p[_op3.length - 1] += 1;
|
|||
|
|
p[_op3.length] -= _position;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
case 'move_node':
|
|||
|
|
{
|
|||
|
|
var _op4 = operation.path,
|
|||
|
|
onp = operation.newPath; // If the old and new path are the same, it's a no-op.
|
|||
|
|
|
|||
|
|
if (Path.equals(_op4, onp)) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (Path.isAncestor(_op4, p) || Path.equals(_op4, p)) {
|
|||
|
|
var copy = onp.slice();
|
|||
|
|
|
|||
|
|
if (Path.endsBefore(_op4, onp) && _op4.length < onp.length) {
|
|||
|
|
copy[_op4.length - 1] -= 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return copy.concat(p.slice(_op4.length));
|
|||
|
|
} else if (Path.isSibling(_op4, onp) && (Path.isAncestor(onp, p) || Path.equals(onp, p))) {
|
|||
|
|
if (Path.endsBefore(_op4, p)) {
|
|||
|
|
p[_op4.length - 1] -= 1;
|
|||
|
|
} else {
|
|||
|
|
p[_op4.length - 1] += 1;
|
|||
|
|
}
|
|||
|
|
} else if (Path.endsBefore(onp, p) || Path.equals(onp, p) || Path.isAncestor(onp, p)) {
|
|||
|
|
if (Path.endsBefore(_op4, p)) {
|
|||
|
|
p[_op4.length - 1] -= 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
p[onp.length - 1] += 1;
|
|||
|
|
} else if (Path.endsBefore(_op4, p)) {
|
|||
|
|
if (Path.equals(onp, p)) {
|
|||
|
|
p[onp.length - 1] += 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
p[_op4.length - 1] -= 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var PathRef = {
|
|||
|
|
/**
|
|||
|
|
* Transform the path ref's current value by an operation.
|
|||
|
|
*/
|
|||
|
|
transform: function transform(ref, op) {
|
|||
|
|
var current = ref.current,
|
|||
|
|
affinity = ref.affinity;
|
|||
|
|
|
|||
|
|
if (current == null) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var path = Path.transform(current, op, {
|
|||
|
|
affinity: affinity
|
|||
|
|
});
|
|||
|
|
ref.current = path;
|
|||
|
|
|
|||
|
|
if (path == null) {
|
|||
|
|
ref.unref();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
function ownKeys$6(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
|
|||
|
|
|
|||
|
|
function _objectSpread$6(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$6(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$6(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
|||
|
|
var Point = {
|
|||
|
|
/**
|
|||
|
|
* Compare a point to another, returning an integer indicating whether the
|
|||
|
|
* point was before, at, or after the other.
|
|||
|
|
*/
|
|||
|
|
compare: function compare(point, another) {
|
|||
|
|
var result = Path.compare(point.path, another.path);
|
|||
|
|
|
|||
|
|
if (result === 0) {
|
|||
|
|
if (point.offset < another.offset) return -1;
|
|||
|
|
if (point.offset > another.offset) return 1;
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return result;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if a point is after another.
|
|||
|
|
*/
|
|||
|
|
isAfter: function isAfter(point, another) {
|
|||
|
|
return Point.compare(point, another) === 1;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if a point is before another.
|
|||
|
|
*/
|
|||
|
|
isBefore: function isBefore(point, another) {
|
|||
|
|
return Point.compare(point, another) === -1;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if a point is exactly equal to another.
|
|||
|
|
*/
|
|||
|
|
equals: function equals(point, another) {
|
|||
|
|
// PERF: ensure the offsets are equal first since they are cheaper to check.
|
|||
|
|
return point.offset === another.offset && Path.equals(point.path, another.path);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if a value implements the `Point` interface.
|
|||
|
|
*/
|
|||
|
|
isPoint: function isPoint(value) {
|
|||
|
|
return isPlainObject.isPlainObject(value) && typeof value.offset === 'number' && Path.isPath(value.path);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Transform a point by an operation.
|
|||
|
|
*/
|
|||
|
|
transform: function transform(point, op) {
|
|||
|
|
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|||
|
|
return immer.produce(point, function (p) {
|
|||
|
|
if (p === null) {
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var _options$affinity = options.affinity,
|
|||
|
|
affinity = _options$affinity === void 0 ? 'forward' : _options$affinity;
|
|||
|
|
var path = p.path,
|
|||
|
|
offset = p.offset;
|
|||
|
|
|
|||
|
|
switch (op.type) {
|
|||
|
|
case 'insert_node':
|
|||
|
|
case 'move_node':
|
|||
|
|
{
|
|||
|
|
p.path = Path.transform(path, op, options);
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
case 'insert_text':
|
|||
|
|
{
|
|||
|
|
if (Path.equals(op.path, path) && op.offset <= offset) {
|
|||
|
|
p.offset += op.text.length;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
case 'merge_node':
|
|||
|
|
{
|
|||
|
|
if (Path.equals(op.path, path)) {
|
|||
|
|
p.offset += op.position;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
p.path = Path.transform(path, op, options);
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
case 'remove_text':
|
|||
|
|
{
|
|||
|
|
if (Path.equals(op.path, path) && op.offset <= offset) {
|
|||
|
|
p.offset -= Math.min(offset - op.offset, op.text.length);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
case 'remove_node':
|
|||
|
|
{
|
|||
|
|
if (Path.equals(op.path, path) || Path.isAncestor(op.path, path)) {
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
p.path = Path.transform(path, op, options);
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
case 'split_node':
|
|||
|
|
{
|
|||
|
|
if (Path.equals(op.path, path)) {
|
|||
|
|
if (op.position === offset && affinity == null) {
|
|||
|
|
return null;
|
|||
|
|
} else if (op.position < offset || op.position === offset && affinity === 'forward') {
|
|||
|
|
p.offset -= op.position;
|
|||
|
|
p.path = Path.transform(path, op, _objectSpread$6(_objectSpread$6({}, options), {}, {
|
|||
|
|
affinity: 'forward'
|
|||
|
|
}));
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
p.path = Path.transform(path, op, options);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var PointRef = {
|
|||
|
|
/**
|
|||
|
|
* Transform the point ref's current value by an operation.
|
|||
|
|
*/
|
|||
|
|
transform: function transform(ref, op) {
|
|||
|
|
var current = ref.current,
|
|||
|
|
affinity = ref.affinity;
|
|||
|
|
|
|||
|
|
if (current == null) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var point = Point.transform(current, op, {
|
|||
|
|
affinity: affinity
|
|||
|
|
});
|
|||
|
|
ref.current = point;
|
|||
|
|
|
|||
|
|
if (point == null) {
|
|||
|
|
ref.unref();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var _excluded$2 = ["anchor", "focus"];
|
|||
|
|
|
|||
|
|
function ownKeys$5(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
|
|||
|
|
|
|||
|
|
function _objectSpread$5(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$5(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$5(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
|||
|
|
var Range = {
|
|||
|
|
/**
|
|||
|
|
* Get the start and end points of a range, in the order in which they appear
|
|||
|
|
* in the document.
|
|||
|
|
*/
|
|||
|
|
edges: function edges(range) {
|
|||
|
|
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|||
|
|
var _options$reverse = options.reverse,
|
|||
|
|
reverse = _options$reverse === void 0 ? false : _options$reverse;
|
|||
|
|
var anchor = range.anchor,
|
|||
|
|
focus = range.focus;
|
|||
|
|
return Range.isBackward(range) === reverse ? [anchor, focus] : [focus, anchor];
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Get the end point of a range.
|
|||
|
|
*/
|
|||
|
|
end: function end(range) {
|
|||
|
|
var _Range$edges = Range.edges(range),
|
|||
|
|
_Range$edges2 = _slicedToArray(_Range$edges, 2),
|
|||
|
|
end = _Range$edges2[1];
|
|||
|
|
|
|||
|
|
return end;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if a range is exactly equal to another.
|
|||
|
|
*/
|
|||
|
|
equals: function equals(range, another) {
|
|||
|
|
return Point.equals(range.anchor, another.anchor) && Point.equals(range.focus, another.focus);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if a range includes a path, a point or part of another range.
|
|||
|
|
*/
|
|||
|
|
includes: function includes(range, target) {
|
|||
|
|
if (Range.isRange(target)) {
|
|||
|
|
if (Range.includes(range, target.anchor) || Range.includes(range, target.focus)) {
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var _Range$edges3 = Range.edges(range),
|
|||
|
|
_Range$edges4 = _slicedToArray(_Range$edges3, 2),
|
|||
|
|
rs = _Range$edges4[0],
|
|||
|
|
re = _Range$edges4[1];
|
|||
|
|
|
|||
|
|
var _Range$edges5 = Range.edges(target),
|
|||
|
|
_Range$edges6 = _slicedToArray(_Range$edges5, 2),
|
|||
|
|
ts = _Range$edges6[0],
|
|||
|
|
te = _Range$edges6[1];
|
|||
|
|
|
|||
|
|
return Point.isBefore(rs, ts) && Point.isAfter(re, te);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var _Range$edges7 = Range.edges(range),
|
|||
|
|
_Range$edges8 = _slicedToArray(_Range$edges7, 2),
|
|||
|
|
start = _Range$edges8[0],
|
|||
|
|
end = _Range$edges8[1];
|
|||
|
|
|
|||
|
|
var isAfterStart = false;
|
|||
|
|
var isBeforeEnd = false;
|
|||
|
|
|
|||
|
|
if (Point.isPoint(target)) {
|
|||
|
|
isAfterStart = Point.compare(target, start) >= 0;
|
|||
|
|
isBeforeEnd = Point.compare(target, end) <= 0;
|
|||
|
|
} else {
|
|||
|
|
isAfterStart = Path.compare(target, start.path) >= 0;
|
|||
|
|
isBeforeEnd = Path.compare(target, end.path) <= 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return isAfterStart && isBeforeEnd;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Get the intersection of a range with another.
|
|||
|
|
*/
|
|||
|
|
intersection: function intersection(range, another) {
|
|||
|
|
range.anchor;
|
|||
|
|
range.focus;
|
|||
|
|
var rest = _objectWithoutProperties(range, _excluded$2);
|
|||
|
|
|
|||
|
|
var _Range$edges9 = Range.edges(range),
|
|||
|
|
_Range$edges10 = _slicedToArray(_Range$edges9, 2),
|
|||
|
|
s1 = _Range$edges10[0],
|
|||
|
|
e1 = _Range$edges10[1];
|
|||
|
|
|
|||
|
|
var _Range$edges11 = Range.edges(another),
|
|||
|
|
_Range$edges12 = _slicedToArray(_Range$edges11, 2),
|
|||
|
|
s2 = _Range$edges12[0],
|
|||
|
|
e2 = _Range$edges12[1];
|
|||
|
|
|
|||
|
|
var start = Point.isBefore(s1, s2) ? s2 : s1;
|
|||
|
|
var end = Point.isBefore(e1, e2) ? e1 : e2;
|
|||
|
|
|
|||
|
|
if (Point.isBefore(end, start)) {
|
|||
|
|
return null;
|
|||
|
|
} else {
|
|||
|
|
return _objectSpread$5({
|
|||
|
|
anchor: start,
|
|||
|
|
focus: end
|
|||
|
|
}, rest);
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if a range is backward, meaning that its anchor point appears in the
|
|||
|
|
* document _after_ its focus point.
|
|||
|
|
*/
|
|||
|
|
isBackward: function isBackward(range) {
|
|||
|
|
var anchor = range.anchor,
|
|||
|
|
focus = range.focus;
|
|||
|
|
return Point.isAfter(anchor, focus);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if a range is collapsed, meaning that both its anchor and focus
|
|||
|
|
* points refer to the exact same position in the document.
|
|||
|
|
*/
|
|||
|
|
isCollapsed: function isCollapsed(range) {
|
|||
|
|
var anchor = range.anchor,
|
|||
|
|
focus = range.focus;
|
|||
|
|
return Point.equals(anchor, focus);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if a range is expanded.
|
|||
|
|
*
|
|||
|
|
* This is the opposite of [[Range.isCollapsed]] and is provided for legibility.
|
|||
|
|
*/
|
|||
|
|
isExpanded: function isExpanded(range) {
|
|||
|
|
return !Range.isCollapsed(range);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if a range is forward.
|
|||
|
|
*
|
|||
|
|
* This is the opposite of [[Range.isBackward]] and is provided for legibility.
|
|||
|
|
*/
|
|||
|
|
isForward: function isForward(range) {
|
|||
|
|
return !Range.isBackward(range);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if a value implements the [[Range]] interface.
|
|||
|
|
*/
|
|||
|
|
isRange: function isRange(value) {
|
|||
|
|
return isPlainObject.isPlainObject(value) && Point.isPoint(value.anchor) && Point.isPoint(value.focus);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Iterate through all of the point entries in a range.
|
|||
|
|
*/
|
|||
|
|
points: function* points(range) {
|
|||
|
|
yield [range.anchor, 'anchor'];
|
|||
|
|
yield [range.focus, 'focus'];
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Get the start point of a range.
|
|||
|
|
*/
|
|||
|
|
start: function start(range) {
|
|||
|
|
var _Range$edges13 = Range.edges(range),
|
|||
|
|
_Range$edges14 = _slicedToArray(_Range$edges13, 1),
|
|||
|
|
start = _Range$edges14[0];
|
|||
|
|
|
|||
|
|
return start;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Transform a range by an operation.
|
|||
|
|
*/
|
|||
|
|
transform: function transform(range, op) {
|
|||
|
|
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|||
|
|
return immer.produce(range, function (r) {
|
|||
|
|
if (r === null) {
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var _options$affinity = options.affinity,
|
|||
|
|
affinity = _options$affinity === void 0 ? 'inward' : _options$affinity;
|
|||
|
|
var affinityAnchor;
|
|||
|
|
var affinityFocus;
|
|||
|
|
|
|||
|
|
if (affinity === 'inward') {
|
|||
|
|
// If the range is collapsed, make sure to use the same affinity to
|
|||
|
|
// avoid the two points passing each other and expanding in the opposite
|
|||
|
|
// direction
|
|||
|
|
var isCollapsed = Range.isCollapsed(r);
|
|||
|
|
|
|||
|
|
if (Range.isForward(r)) {
|
|||
|
|
affinityAnchor = 'forward';
|
|||
|
|
affinityFocus = isCollapsed ? affinityAnchor : 'backward';
|
|||
|
|
} else {
|
|||
|
|
affinityAnchor = 'backward';
|
|||
|
|
affinityFocus = isCollapsed ? affinityAnchor : 'forward';
|
|||
|
|
}
|
|||
|
|
} else if (affinity === 'outward') {
|
|||
|
|
if (Range.isForward(r)) {
|
|||
|
|
affinityAnchor = 'backward';
|
|||
|
|
affinityFocus = 'forward';
|
|||
|
|
} else {
|
|||
|
|
affinityAnchor = 'forward';
|
|||
|
|
affinityFocus = 'backward';
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
affinityAnchor = affinity;
|
|||
|
|
affinityFocus = affinity;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var anchor = Point.transform(r.anchor, op, {
|
|||
|
|
affinity: affinityAnchor
|
|||
|
|
});
|
|||
|
|
var focus = Point.transform(r.focus, op, {
|
|||
|
|
affinity: affinityFocus
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
if (!anchor || !focus) {
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
r.anchor = anchor;
|
|||
|
|
r.focus = focus;
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var RangeRef = {
|
|||
|
|
/**
|
|||
|
|
* Transform the range ref's current value by an operation.
|
|||
|
|
*/
|
|||
|
|
transform: function transform(ref, op) {
|
|||
|
|
var current = ref.current,
|
|||
|
|
affinity = ref.affinity;
|
|||
|
|
|
|||
|
|
if (current == null) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var path = Range.transform(current, op, {
|
|||
|
|
affinity: affinity
|
|||
|
|
});
|
|||
|
|
ref.current = path;
|
|||
|
|
|
|||
|
|
if (path == null) {
|
|||
|
|
ref.unref();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
Custom deep equal comparison for Slate nodes.
|
|||
|
|
|
|||
|
|
We don't need general purpose deep equality;
|
|||
|
|
Slate only supports plain values, Arrays, and nested objects.
|
|||
|
|
Complex values nested inside Arrays are not supported.
|
|||
|
|
|
|||
|
|
Slate objects are designed to be serialised, so
|
|||
|
|
missing keys are deliberately normalised to undefined.
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
var isDeepEqual = function isDeepEqual(node, another) {
|
|||
|
|
for (var key in node) {
|
|||
|
|
var a = node[key];
|
|||
|
|
var b = another[key];
|
|||
|
|
|
|||
|
|
if (isPlainObject.isPlainObject(a) && isPlainObject.isPlainObject(b)) {
|
|||
|
|
if (!isDeepEqual(a, b)) return false;
|
|||
|
|
} else if (Array.isArray(a) && Array.isArray(b)) {
|
|||
|
|
if (a.length !== b.length) return false;
|
|||
|
|
|
|||
|
|
for (var i = 0; i < a.length; i++) {
|
|||
|
|
if (a[i] !== b[i]) return false;
|
|||
|
|
}
|
|||
|
|
} else if (a !== b) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
/*
|
|||
|
|
Deep object equality is only necessary in one direction; in the reverse direction
|
|||
|
|
we are only looking for keys that are missing.
|
|||
|
|
As above, undefined keys are normalised to missing.
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
for (var _key in another) {
|
|||
|
|
if (node[_key] === undefined && another[_key] !== undefined) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var _excluded$1 = ["text"],
|
|||
|
|
_excluded2$1 = ["anchor", "focus"];
|
|||
|
|
|
|||
|
|
function _createForOfIteratorHelper$3(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$3(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
|
|||
|
|
|
|||
|
|
function _unsupportedIterableToArray$3(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$3(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray$3(o, minLen); }
|
|||
|
|
|
|||
|
|
function _arrayLikeToArray$3(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|||
|
|
|
|||
|
|
function ownKeys$4(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
|
|||
|
|
|
|||
|
|
function _objectSpread$4(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$4(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$4(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
|||
|
|
var Text = {
|
|||
|
|
/**
|
|||
|
|
* Check if two text nodes are equal.
|
|||
|
|
*
|
|||
|
|
* When loose is set, the text is not compared. This is
|
|||
|
|
* used to check whether sibling text nodes can be merged.
|
|||
|
|
*/
|
|||
|
|
equals: function equals(text, another) {
|
|||
|
|
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|||
|
|
var _options$loose = options.loose,
|
|||
|
|
loose = _options$loose === void 0 ? false : _options$loose;
|
|||
|
|
|
|||
|
|
function omitText(obj) {
|
|||
|
|
obj.text;
|
|||
|
|
var rest = _objectWithoutProperties(obj, _excluded$1);
|
|||
|
|
|
|||
|
|
return rest;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return isDeepEqual(loose ? omitText(text) : text, loose ? omitText(another) : another);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if a value implements the `Text` interface.
|
|||
|
|
*/
|
|||
|
|
isText: function isText(value) {
|
|||
|
|
return isPlainObject.isPlainObject(value) && typeof value.text === 'string';
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if a value is a list of `Text` objects.
|
|||
|
|
*/
|
|||
|
|
isTextList: function isTextList(value) {
|
|||
|
|
return Array.isArray(value) && value.every(function (val) {
|
|||
|
|
return Text.isText(val);
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if some props are a partial of Text.
|
|||
|
|
*/
|
|||
|
|
isTextProps: function isTextProps(props) {
|
|||
|
|
return props.text !== undefined;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if an text matches set of properties.
|
|||
|
|
*
|
|||
|
|
* Note: this is for matching custom properties, and it does not ensure that
|
|||
|
|
* the `text` property are two nodes equal.
|
|||
|
|
*/
|
|||
|
|
matches: function matches(text, props) {
|
|||
|
|
for (var key in props) {
|
|||
|
|
if (key === 'text') {
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!text.hasOwnProperty(key) || text[key] !== props[key]) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Get the leaves for a text node given decorations.
|
|||
|
|
*/
|
|||
|
|
decorations: function decorations(node, _decorations) {
|
|||
|
|
var leaves = [_objectSpread$4({}, node)];
|
|||
|
|
|
|||
|
|
var _iterator = _createForOfIteratorHelper$3(_decorations),
|
|||
|
|
_step;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|||
|
|
var dec = _step.value;
|
|||
|
|
|
|||
|
|
var anchor = dec.anchor,
|
|||
|
|
focus = dec.focus,
|
|||
|
|
rest = _objectWithoutProperties(dec, _excluded2$1);
|
|||
|
|
|
|||
|
|
var _Range$edges = Range.edges(dec),
|
|||
|
|
_Range$edges2 = _slicedToArray(_Range$edges, 2),
|
|||
|
|
start = _Range$edges2[0],
|
|||
|
|
end = _Range$edges2[1];
|
|||
|
|
|
|||
|
|
var next = [];
|
|||
|
|
var o = 0;
|
|||
|
|
|
|||
|
|
var _iterator2 = _createForOfIteratorHelper$3(leaves),
|
|||
|
|
_step2;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|||
|
|
var leaf = _step2.value;
|
|||
|
|
var length = leaf.text.length;
|
|||
|
|
var offset = o;
|
|||
|
|
o += length; // If the range encompases the entire leaf, add the range.
|
|||
|
|
|
|||
|
|
if (start.offset <= offset && end.offset >= o) {
|
|||
|
|
Object.assign(leaf, rest);
|
|||
|
|
next.push(leaf);
|
|||
|
|
continue;
|
|||
|
|
} // If the range expanded and match the leaf, or starts after, or ends before it, continue.
|
|||
|
|
|
|||
|
|
|
|||
|
|
if (start.offset !== end.offset && (start.offset === o || end.offset === offset) || start.offset > o || end.offset < offset || end.offset === offset && offset !== 0) {
|
|||
|
|
next.push(leaf);
|
|||
|
|
continue;
|
|||
|
|
} // Otherwise we need to split the leaf, at the start, end, or both,
|
|||
|
|
// and add the range to the middle intersecting section. Do the end
|
|||
|
|
// split first since we don't need to update the offset that way.
|
|||
|
|
|
|||
|
|
|
|||
|
|
var middle = leaf;
|
|||
|
|
var before = void 0;
|
|||
|
|
var after = void 0;
|
|||
|
|
|
|||
|
|
if (end.offset < o) {
|
|||
|
|
var off = end.offset - offset;
|
|||
|
|
after = _objectSpread$4(_objectSpread$4({}, middle), {}, {
|
|||
|
|
text: middle.text.slice(off)
|
|||
|
|
});
|
|||
|
|
middle = _objectSpread$4(_objectSpread$4({}, middle), {}, {
|
|||
|
|
text: middle.text.slice(0, off)
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (start.offset > offset) {
|
|||
|
|
var _off = start.offset - offset;
|
|||
|
|
|
|||
|
|
before = _objectSpread$4(_objectSpread$4({}, middle), {}, {
|
|||
|
|
text: middle.text.slice(0, _off)
|
|||
|
|
});
|
|||
|
|
middle = _objectSpread$4(_objectSpread$4({}, middle), {}, {
|
|||
|
|
text: middle.text.slice(_off)
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Object.assign(middle, rest);
|
|||
|
|
|
|||
|
|
if (before) {
|
|||
|
|
next.push(before);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
next.push(middle);
|
|||
|
|
|
|||
|
|
if (after) {
|
|||
|
|
next.push(after);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
} catch (err) {
|
|||
|
|
_iterator2.e(err);
|
|||
|
|
} finally {
|
|||
|
|
_iterator2.f();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
leaves = next;
|
|||
|
|
}
|
|||
|
|
} catch (err) {
|
|||
|
|
_iterator.e(err);
|
|||
|
|
} finally {
|
|||
|
|
_iterator.f();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return leaves;
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
function ownKeys$3(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
|
|||
|
|
|
|||
|
|
function _objectSpread$3(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$3(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$3(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
|||
|
|
|
|||
|
|
function _createForOfIteratorHelper$2(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$2(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
|
|||
|
|
|
|||
|
|
function _unsupportedIterableToArray$2(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$2(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray$2(o, minLen); }
|
|||
|
|
|
|||
|
|
function _arrayLikeToArray$2(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|||
|
|
|
|||
|
|
var applyToDraft = function applyToDraft(editor, selection, op) {
|
|||
|
|
switch (op.type) {
|
|||
|
|
case 'insert_node':
|
|||
|
|
{
|
|||
|
|
var path = op.path,
|
|||
|
|
node = op.node;
|
|||
|
|
var parent = Node$1.parent(editor, path);
|
|||
|
|
var index = path[path.length - 1];
|
|||
|
|
|
|||
|
|
if (index > parent.children.length) {
|
|||
|
|
throw new Error("Cannot apply an \"insert_node\" operation at path [".concat(path, "] because the destination is past the end of the node."));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
parent.children.splice(index, 0, node);
|
|||
|
|
|
|||
|
|
if (selection) {
|
|||
|
|
var _iterator = _createForOfIteratorHelper$2(Range.points(selection)),
|
|||
|
|
_step;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|||
|
|
var _step$value = _slicedToArray(_step.value, 2),
|
|||
|
|
point = _step$value[0],
|
|||
|
|
key = _step$value[1];
|
|||
|
|
|
|||
|
|
selection[key] = Point.transform(point, op);
|
|||
|
|
}
|
|||
|
|
} catch (err) {
|
|||
|
|
_iterator.e(err);
|
|||
|
|
} finally {
|
|||
|
|
_iterator.f();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
case 'insert_text':
|
|||
|
|
{
|
|||
|
|
var _path = op.path,
|
|||
|
|
offset = op.offset,
|
|||
|
|
text = op.text;
|
|||
|
|
if (text.length === 0) break;
|
|||
|
|
|
|||
|
|
var _node = Node$1.leaf(editor, _path);
|
|||
|
|
|
|||
|
|
var before = _node.text.slice(0, offset);
|
|||
|
|
|
|||
|
|
var after = _node.text.slice(offset);
|
|||
|
|
|
|||
|
|
_node.text = before + text + after;
|
|||
|
|
|
|||
|
|
if (selection) {
|
|||
|
|
var _iterator2 = _createForOfIteratorHelper$2(Range.points(selection)),
|
|||
|
|
_step2;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|||
|
|
var _step2$value = _slicedToArray(_step2.value, 2),
|
|||
|
|
_point = _step2$value[0],
|
|||
|
|
_key = _step2$value[1];
|
|||
|
|
|
|||
|
|
selection[_key] = Point.transform(_point, op);
|
|||
|
|
}
|
|||
|
|
} catch (err) {
|
|||
|
|
_iterator2.e(err);
|
|||
|
|
} finally {
|
|||
|
|
_iterator2.f();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
case 'merge_node':
|
|||
|
|
{
|
|||
|
|
var _path2 = op.path;
|
|||
|
|
|
|||
|
|
var _node2 = Node$1.get(editor, _path2);
|
|||
|
|
|
|||
|
|
var prevPath = Path.previous(_path2);
|
|||
|
|
var prev = Node$1.get(editor, prevPath);
|
|||
|
|
|
|||
|
|
var _parent = Node$1.parent(editor, _path2);
|
|||
|
|
|
|||
|
|
var _index = _path2[_path2.length - 1];
|
|||
|
|
|
|||
|
|
if (Text.isText(_node2) && Text.isText(prev)) {
|
|||
|
|
prev.text += _node2.text;
|
|||
|
|
} else if (!Text.isText(_node2) && !Text.isText(prev)) {
|
|||
|
|
var _prev$children;
|
|||
|
|
|
|||
|
|
(_prev$children = prev.children).push.apply(_prev$children, _toConsumableArray(_node2.children));
|
|||
|
|
} else {
|
|||
|
|
throw new Error("Cannot apply a \"merge_node\" operation at path [".concat(_path2, "] to nodes of different interfaces: ").concat(_node2, " ").concat(prev));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
_parent.children.splice(_index, 1);
|
|||
|
|
|
|||
|
|
if (selection) {
|
|||
|
|
var _iterator3 = _createForOfIteratorHelper$2(Range.points(selection)),
|
|||
|
|
_step3;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|||
|
|
var _step3$value = _slicedToArray(_step3.value, 2),
|
|||
|
|
_point2 = _step3$value[0],
|
|||
|
|
_key2 = _step3$value[1];
|
|||
|
|
|
|||
|
|
selection[_key2] = Point.transform(_point2, op);
|
|||
|
|
}
|
|||
|
|
} catch (err) {
|
|||
|
|
_iterator3.e(err);
|
|||
|
|
} finally {
|
|||
|
|
_iterator3.f();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
case 'move_node':
|
|||
|
|
{
|
|||
|
|
var _path3 = op.path,
|
|||
|
|
newPath = op.newPath;
|
|||
|
|
|
|||
|
|
if (Path.isAncestor(_path3, newPath)) {
|
|||
|
|
throw new Error("Cannot move a path [".concat(_path3, "] to new path [").concat(newPath, "] because the destination is inside itself."));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var _node3 = Node$1.get(editor, _path3);
|
|||
|
|
|
|||
|
|
var _parent2 = Node$1.parent(editor, _path3);
|
|||
|
|
|
|||
|
|
var _index2 = _path3[_path3.length - 1]; // This is tricky, but since the `path` and `newPath` both refer to
|
|||
|
|
// the same snapshot in time, there's a mismatch. After either
|
|||
|
|
// removing the original position, the second step's path can be out
|
|||
|
|
// of date. So instead of using the `op.newPath` directly, we
|
|||
|
|
// transform `op.path` to ascertain what the `newPath` would be after
|
|||
|
|
// the operation was applied.
|
|||
|
|
|
|||
|
|
_parent2.children.splice(_index2, 1);
|
|||
|
|
|
|||
|
|
var truePath = Path.transform(_path3, op);
|
|||
|
|
var newParent = Node$1.get(editor, Path.parent(truePath));
|
|||
|
|
var newIndex = truePath[truePath.length - 1];
|
|||
|
|
newParent.children.splice(newIndex, 0, _node3);
|
|||
|
|
|
|||
|
|
if (selection) {
|
|||
|
|
var _iterator4 = _createForOfIteratorHelper$2(Range.points(selection)),
|
|||
|
|
_step4;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
|
|||
|
|
var _step4$value = _slicedToArray(_step4.value, 2),
|
|||
|
|
_point3 = _step4$value[0],
|
|||
|
|
_key3 = _step4$value[1];
|
|||
|
|
|
|||
|
|
selection[_key3] = Point.transform(_point3, op);
|
|||
|
|
}
|
|||
|
|
} catch (err) {
|
|||
|
|
_iterator4.e(err);
|
|||
|
|
} finally {
|
|||
|
|
_iterator4.f();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
case 'remove_node':
|
|||
|
|
{
|
|||
|
|
var _path4 = op.path;
|
|||
|
|
var _index3 = _path4[_path4.length - 1];
|
|||
|
|
|
|||
|
|
var _parent3 = Node$1.parent(editor, _path4);
|
|||
|
|
|
|||
|
|
_parent3.children.splice(_index3, 1); // Transform all of the points in the value, but if the point was in the
|
|||
|
|
// node that was removed we need to update the range or remove it.
|
|||
|
|
|
|||
|
|
|
|||
|
|
if (selection) {
|
|||
|
|
var _iterator5 = _createForOfIteratorHelper$2(Range.points(selection)),
|
|||
|
|
_step5;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
|
|||
|
|
var _step5$value = _slicedToArray(_step5.value, 2),
|
|||
|
|
_point4 = _step5$value[0],
|
|||
|
|
_key4 = _step5$value[1];
|
|||
|
|
|
|||
|
|
var result = Point.transform(_point4, op);
|
|||
|
|
|
|||
|
|
if (selection != null && result != null) {
|
|||
|
|
selection[_key4] = result;
|
|||
|
|
} else {
|
|||
|
|
var _prev = void 0;
|
|||
|
|
|
|||
|
|
var next = void 0;
|
|||
|
|
|
|||
|
|
var _iterator6 = _createForOfIteratorHelper$2(Node$1.texts(editor)),
|
|||
|
|
_step6;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
|
|||
|
|
var _step6$value = _slicedToArray(_step6.value, 2),
|
|||
|
|
n = _step6$value[0],
|
|||
|
|
p = _step6$value[1];
|
|||
|
|
|
|||
|
|
if (Path.compare(p, _path4) === -1) {
|
|||
|
|
_prev = [n, p];
|
|||
|
|
} else {
|
|||
|
|
next = [n, p];
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
} catch (err) {
|
|||
|
|
_iterator6.e(err);
|
|||
|
|
} finally {
|
|||
|
|
_iterator6.f();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var preferNext = false;
|
|||
|
|
|
|||
|
|
if (_prev && next) {
|
|||
|
|
if (Path.equals(next[1], _path4)) {
|
|||
|
|
preferNext = !Path.hasPrevious(next[1]);
|
|||
|
|
} else {
|
|||
|
|
preferNext = Path.common(_prev[1], _path4).length < Path.common(next[1], _path4).length;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (_prev && !preferNext) {
|
|||
|
|
_point4.path = _prev[1];
|
|||
|
|
_point4.offset = _prev[0].text.length;
|
|||
|
|
} else if (next) {
|
|||
|
|
_point4.path = next[1];
|
|||
|
|
_point4.offset = 0;
|
|||
|
|
} else {
|
|||
|
|
selection = null;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
} catch (err) {
|
|||
|
|
_iterator5.e(err);
|
|||
|
|
} finally {
|
|||
|
|
_iterator5.f();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
case 'remove_text':
|
|||
|
|
{
|
|||
|
|
var _path5 = op.path,
|
|||
|
|
_offset = op.offset,
|
|||
|
|
_text = op.text;
|
|||
|
|
if (_text.length === 0) break;
|
|||
|
|
|
|||
|
|
var _node4 = Node$1.leaf(editor, _path5);
|
|||
|
|
|
|||
|
|
var _before = _node4.text.slice(0, _offset);
|
|||
|
|
|
|||
|
|
var _after = _node4.text.slice(_offset + _text.length);
|
|||
|
|
|
|||
|
|
_node4.text = _before + _after;
|
|||
|
|
|
|||
|
|
if (selection) {
|
|||
|
|
var _iterator7 = _createForOfIteratorHelper$2(Range.points(selection)),
|
|||
|
|
_step7;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
|
|||
|
|
var _step7$value = _slicedToArray(_step7.value, 2),
|
|||
|
|
_point5 = _step7$value[0],
|
|||
|
|
_key5 = _step7$value[1];
|
|||
|
|
|
|||
|
|
selection[_key5] = Point.transform(_point5, op);
|
|||
|
|
}
|
|||
|
|
} catch (err) {
|
|||
|
|
_iterator7.e(err);
|
|||
|
|
} finally {
|
|||
|
|
_iterator7.f();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
case 'set_node':
|
|||
|
|
{
|
|||
|
|
var _path6 = op.path,
|
|||
|
|
properties = op.properties,
|
|||
|
|
newProperties = op.newProperties;
|
|||
|
|
|
|||
|
|
if (_path6.length === 0) {
|
|||
|
|
throw new Error("Cannot set properties on the root node!");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var _node5 = Node$1.get(editor, _path6);
|
|||
|
|
|
|||
|
|
for (var _key6 in newProperties) {
|
|||
|
|
if (_key6 === 'children' || _key6 === 'text') {
|
|||
|
|
throw new Error("Cannot set the \"".concat(_key6, "\" property of nodes!"));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var value = newProperties[_key6];
|
|||
|
|
|
|||
|
|
if (value == null) {
|
|||
|
|
delete _node5[_key6];
|
|||
|
|
} else {
|
|||
|
|
_node5[_key6] = value;
|
|||
|
|
}
|
|||
|
|
} // properties that were previously defined, but are now missing, must be deleted
|
|||
|
|
|
|||
|
|
|
|||
|
|
for (var _key7 in properties) {
|
|||
|
|
if (!newProperties.hasOwnProperty(_key7)) {
|
|||
|
|
delete _node5[_key7];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
case 'set_selection':
|
|||
|
|
{
|
|||
|
|
var _newProperties = op.newProperties;
|
|||
|
|
|
|||
|
|
if (_newProperties == null) {
|
|||
|
|
selection = _newProperties;
|
|||
|
|
} else {
|
|||
|
|
if (selection == null) {
|
|||
|
|
if (!Range.isRange(_newProperties)) {
|
|||
|
|
throw new Error("Cannot apply an incomplete \"set_selection\" operation properties ".concat(JSON.stringify(_newProperties), " when there is no current selection."));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
selection = _objectSpread$3({}, _newProperties);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
for (var _key8 in _newProperties) {
|
|||
|
|
var _value = _newProperties[_key8];
|
|||
|
|
|
|||
|
|
if (_value == null) {
|
|||
|
|
if (_key8 === 'anchor' || _key8 === 'focus') {
|
|||
|
|
throw new Error("Cannot remove the \"".concat(_key8, "\" selection property"));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
delete selection[_key8];
|
|||
|
|
} else {
|
|||
|
|
selection[_key8] = _value;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
case 'split_node':
|
|||
|
|
{
|
|||
|
|
var _path7 = op.path,
|
|||
|
|
position = op.position,
|
|||
|
|
_properties = op.properties;
|
|||
|
|
|
|||
|
|
if (_path7.length === 0) {
|
|||
|
|
throw new Error("Cannot apply a \"split_node\" operation at path [".concat(_path7, "] because the root node cannot be split."));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var _node6 = Node$1.get(editor, _path7);
|
|||
|
|
|
|||
|
|
var _parent4 = Node$1.parent(editor, _path7);
|
|||
|
|
|
|||
|
|
var _index4 = _path7[_path7.length - 1];
|
|||
|
|
var newNode;
|
|||
|
|
|
|||
|
|
if (Text.isText(_node6)) {
|
|||
|
|
var _before2 = _node6.text.slice(0, position);
|
|||
|
|
|
|||
|
|
var _after2 = _node6.text.slice(position);
|
|||
|
|
|
|||
|
|
_node6.text = _before2;
|
|||
|
|
newNode = _objectSpread$3(_objectSpread$3({}, _properties), {}, {
|
|||
|
|
text: _after2
|
|||
|
|
});
|
|||
|
|
} else {
|
|||
|
|
var _before3 = _node6.children.slice(0, position);
|
|||
|
|
|
|||
|
|
var _after3 = _node6.children.slice(position);
|
|||
|
|
|
|||
|
|
_node6.children = _before3;
|
|||
|
|
newNode = _objectSpread$3(_objectSpread$3({}, _properties), {}, {
|
|||
|
|
children: _after3
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
_parent4.children.splice(_index4 + 1, 0, newNode);
|
|||
|
|
|
|||
|
|
if (selection) {
|
|||
|
|
var _iterator8 = _createForOfIteratorHelper$2(Range.points(selection)),
|
|||
|
|
_step8;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
|
|||
|
|
var _step8$value = _slicedToArray(_step8.value, 2),
|
|||
|
|
_point6 = _step8$value[0],
|
|||
|
|
_key9 = _step8$value[1];
|
|||
|
|
|
|||
|
|
selection[_key9] = Point.transform(_point6, op);
|
|||
|
|
}
|
|||
|
|
} catch (err) {
|
|||
|
|
_iterator8.e(err);
|
|||
|
|
} finally {
|
|||
|
|
_iterator8.f();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return selection;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var GeneralTransforms = {
|
|||
|
|
/**
|
|||
|
|
* Transform the editor by an operation.
|
|||
|
|
*/
|
|||
|
|
transform: function transform(editor, op) {
|
|||
|
|
editor.children = immer.createDraft(editor.children);
|
|||
|
|
var selection = editor.selection && immer.createDraft(editor.selection);
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
selection = applyToDraft(editor, selection, op);
|
|||
|
|
} finally {
|
|||
|
|
editor.children = immer.finishDraft(editor.children);
|
|||
|
|
|
|||
|
|
if (selection) {
|
|||
|
|
editor.selection = immer.isDraft(selection) ? immer.finishDraft(selection) : selection;
|
|||
|
|
} else {
|
|||
|
|
editor.selection = null;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var _excluded = ["text"],
|
|||
|
|
_excluded2 = ["children"];
|
|||
|
|
|
|||
|
|
function ownKeys$2(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
|
|||
|
|
|
|||
|
|
function _objectSpread$2(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$2(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$2(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
|||
|
|
|
|||
|
|
function _createForOfIteratorHelper$1(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$1(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
|
|||
|
|
|
|||
|
|
function _unsupportedIterableToArray$1(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$1(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray$1(o, minLen); }
|
|||
|
|
|
|||
|
|
function _arrayLikeToArray$1(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|||
|
|
var NodeTransforms = {
|
|||
|
|
/**
|
|||
|
|
* Insert nodes at a specific location in the Editor.
|
|||
|
|
*/
|
|||
|
|
insertNodes: function insertNodes(editor, nodes) {
|
|||
|
|
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|||
|
|
Editor.withoutNormalizing(editor, function () {
|
|||
|
|
var _options$hanging = options.hanging,
|
|||
|
|
hanging = _options$hanging === void 0 ? false : _options$hanging,
|
|||
|
|
_options$voids = options.voids,
|
|||
|
|
voids = _options$voids === void 0 ? false : _options$voids,
|
|||
|
|
_options$mode = options.mode,
|
|||
|
|
mode = _options$mode === void 0 ? 'lowest' : _options$mode;
|
|||
|
|
var at = options.at,
|
|||
|
|
match = options.match,
|
|||
|
|
select = options.select;
|
|||
|
|
|
|||
|
|
if (Node$1.isNode(nodes)) {
|
|||
|
|
nodes = [nodes];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (nodes.length === 0) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var _nodes = nodes,
|
|||
|
|
_nodes2 = _slicedToArray(_nodes, 1),
|
|||
|
|
node = _nodes2[0]; // By default, use the selection as the target location. But if there is
|
|||
|
|
// no selection, insert at the end of the document since that is such a
|
|||
|
|
// common use case when inserting from a non-selected state.
|
|||
|
|
|
|||
|
|
|
|||
|
|
if (!at) {
|
|||
|
|
if (editor.selection) {
|
|||
|
|
at = editor.selection;
|
|||
|
|
} else if (editor.children.length > 0) {
|
|||
|
|
at = Editor.end(editor, []);
|
|||
|
|
} else {
|
|||
|
|
at = [0];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
select = true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (select == null) {
|
|||
|
|
select = false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (Range.isRange(at)) {
|
|||
|
|
if (!hanging) {
|
|||
|
|
at = Editor.unhangRange(editor, at);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (Range.isCollapsed(at)) {
|
|||
|
|
at = at.anchor;
|
|||
|
|
} else {
|
|||
|
|
var _Range$edges = Range.edges(at),
|
|||
|
|
_Range$edges2 = _slicedToArray(_Range$edges, 2),
|
|||
|
|
end = _Range$edges2[1];
|
|||
|
|
|
|||
|
|
var pointRef = Editor.pointRef(editor, end);
|
|||
|
|
Transforms["delete"](editor, {
|
|||
|
|
at: at
|
|||
|
|
});
|
|||
|
|
at = pointRef.unref();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (Point.isPoint(at)) {
|
|||
|
|
if (match == null) {
|
|||
|
|
if (Text.isText(node)) {
|
|||
|
|
match = function match(n) {
|
|||
|
|
return Text.isText(n);
|
|||
|
|
};
|
|||
|
|
} else if (editor.isInline(node)) {
|
|||
|
|
match = function match(n) {
|
|||
|
|
return Text.isText(n) || Editor.isInline(editor, n);
|
|||
|
|
};
|
|||
|
|
} else {
|
|||
|
|
match = function match(n) {
|
|||
|
|
return Editor.isBlock(editor, n);
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var _Editor$nodes = Editor.nodes(editor, {
|
|||
|
|
at: at.path,
|
|||
|
|
match: match,
|
|||
|
|
mode: mode,
|
|||
|
|
voids: voids
|
|||
|
|
}),
|
|||
|
|
_Editor$nodes2 = _slicedToArray(_Editor$nodes, 1),
|
|||
|
|
entry = _Editor$nodes2[0];
|
|||
|
|
|
|||
|
|
if (entry) {
|
|||
|
|
var _entry = _slicedToArray(entry, 2),
|
|||
|
|
_matchPath = _entry[1];
|
|||
|
|
|
|||
|
|
var pathRef = Editor.pathRef(editor, _matchPath);
|
|||
|
|
var isAtEnd = Editor.isEnd(editor, at, _matchPath);
|
|||
|
|
Transforms.splitNodes(editor, {
|
|||
|
|
at: at,
|
|||
|
|
match: match,
|
|||
|
|
mode: mode,
|
|||
|
|
voids: voids
|
|||
|
|
});
|
|||
|
|
var path = pathRef.unref();
|
|||
|
|
at = isAtEnd ? Path.next(path) : path;
|
|||
|
|
} else {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var parentPath = Path.parent(at);
|
|||
|
|
var index = at[at.length - 1];
|
|||
|
|
|
|||
|
|
if (!voids && Editor["void"](editor, {
|
|||
|
|
at: parentPath
|
|||
|
|
})) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var _iterator = _createForOfIteratorHelper$1(nodes),
|
|||
|
|
_step;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|||
|
|
var _node = _step.value;
|
|||
|
|
|
|||
|
|
var _path = parentPath.concat(index);
|
|||
|
|
|
|||
|
|
index++;
|
|||
|
|
editor.apply({
|
|||
|
|
type: 'insert_node',
|
|||
|
|
path: _path,
|
|||
|
|
node: _node
|
|||
|
|
});
|
|||
|
|
at = Path.next(at);
|
|||
|
|
}
|
|||
|
|
} catch (err) {
|
|||
|
|
_iterator.e(err);
|
|||
|
|
} finally {
|
|||
|
|
_iterator.f();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
at = Path.previous(at);
|
|||
|
|
|
|||
|
|
if (select) {
|
|||
|
|
var point = Editor.end(editor, at);
|
|||
|
|
|
|||
|
|
if (point) {
|
|||
|
|
Transforms.select(editor, point);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Lift nodes at a specific location upwards in the document tree, splitting
|
|||
|
|
* their parent in two if necessary.
|
|||
|
|
*/
|
|||
|
|
liftNodes: function liftNodes(editor) {
|
|||
|
|
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|||
|
|
Editor.withoutNormalizing(editor, function () {
|
|||
|
|
var _options$at = options.at,
|
|||
|
|
at = _options$at === void 0 ? editor.selection : _options$at,
|
|||
|
|
_options$mode2 = options.mode,
|
|||
|
|
mode = _options$mode2 === void 0 ? 'lowest' : _options$mode2,
|
|||
|
|
_options$voids2 = options.voids,
|
|||
|
|
voids = _options$voids2 === void 0 ? false : _options$voids2;
|
|||
|
|
var match = options.match;
|
|||
|
|
|
|||
|
|
if (match == null) {
|
|||
|
|
match = Path.isPath(at) ? matchPath(editor, at) : function (n) {
|
|||
|
|
return Editor.isBlock(editor, n);
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!at) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var matches = Editor.nodes(editor, {
|
|||
|
|
at: at,
|
|||
|
|
match: match,
|
|||
|
|
mode: mode,
|
|||
|
|
voids: voids
|
|||
|
|
});
|
|||
|
|
var pathRefs = Array.from(matches, function (_ref) {
|
|||
|
|
var _ref2 = _slicedToArray(_ref, 2),
|
|||
|
|
p = _ref2[1];
|
|||
|
|
|
|||
|
|
return Editor.pathRef(editor, p);
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
for (var _i = 0, _pathRefs = pathRefs; _i < _pathRefs.length; _i++) {
|
|||
|
|
var pathRef = _pathRefs[_i];
|
|||
|
|
var path = pathRef.unref();
|
|||
|
|
|
|||
|
|
if (path.length < 2) {
|
|||
|
|
throw new Error("Cannot lift node at a path [".concat(path, "] because it has a depth of less than `2`."));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var parentNodeEntry = Editor.node(editor, Path.parent(path));
|
|||
|
|
|
|||
|
|
var _parentNodeEntry = _slicedToArray(parentNodeEntry, 2),
|
|||
|
|
parent = _parentNodeEntry[0],
|
|||
|
|
parentPath = _parentNodeEntry[1];
|
|||
|
|
|
|||
|
|
var index = path[path.length - 1];
|
|||
|
|
var length = parent.children.length;
|
|||
|
|
|
|||
|
|
if (length === 1) {
|
|||
|
|
var toPath = Path.next(parentPath);
|
|||
|
|
Transforms.moveNodes(editor, {
|
|||
|
|
at: path,
|
|||
|
|
to: toPath,
|
|||
|
|
voids: voids
|
|||
|
|
});
|
|||
|
|
Transforms.removeNodes(editor, {
|
|||
|
|
at: parentPath,
|
|||
|
|
voids: voids
|
|||
|
|
});
|
|||
|
|
} else if (index === 0) {
|
|||
|
|
Transforms.moveNodes(editor, {
|
|||
|
|
at: path,
|
|||
|
|
to: parentPath,
|
|||
|
|
voids: voids
|
|||
|
|
});
|
|||
|
|
} else if (index === length - 1) {
|
|||
|
|
var _toPath = Path.next(parentPath);
|
|||
|
|
|
|||
|
|
Transforms.moveNodes(editor, {
|
|||
|
|
at: path,
|
|||
|
|
to: _toPath,
|
|||
|
|
voids: voids
|
|||
|
|
});
|
|||
|
|
} else {
|
|||
|
|
var splitPath = Path.next(path);
|
|||
|
|
|
|||
|
|
var _toPath2 = Path.next(parentPath);
|
|||
|
|
|
|||
|
|
Transforms.splitNodes(editor, {
|
|||
|
|
at: splitPath,
|
|||
|
|
voids: voids
|
|||
|
|
});
|
|||
|
|
Transforms.moveNodes(editor, {
|
|||
|
|
at: path,
|
|||
|
|
to: _toPath2,
|
|||
|
|
voids: voids
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Merge a node at a location with the previous node of the same depth,
|
|||
|
|
* removing any empty containing nodes after the merge if necessary.
|
|||
|
|
*/
|
|||
|
|
mergeNodes: function mergeNodes(editor) {
|
|||
|
|
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|||
|
|
Editor.withoutNormalizing(editor, function () {
|
|||
|
|
var match = options.match,
|
|||
|
|
_options$at2 = options.at,
|
|||
|
|
at = _options$at2 === void 0 ? editor.selection : _options$at2;
|
|||
|
|
var _options$hanging2 = options.hanging,
|
|||
|
|
hanging = _options$hanging2 === void 0 ? false : _options$hanging2,
|
|||
|
|
_options$voids3 = options.voids,
|
|||
|
|
voids = _options$voids3 === void 0 ? false : _options$voids3,
|
|||
|
|
_options$mode3 = options.mode,
|
|||
|
|
mode = _options$mode3 === void 0 ? 'lowest' : _options$mode3;
|
|||
|
|
|
|||
|
|
if (!at) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (match == null) {
|
|||
|
|
if (Path.isPath(at)) {
|
|||
|
|
var _Editor$parent = Editor.parent(editor, at),
|
|||
|
|
_Editor$parent2 = _slicedToArray(_Editor$parent, 1),
|
|||
|
|
parent = _Editor$parent2[0];
|
|||
|
|
|
|||
|
|
match = function match(n) {
|
|||
|
|
return parent.children.includes(n);
|
|||
|
|
};
|
|||
|
|
} else {
|
|||
|
|
match = function match(n) {
|
|||
|
|
return Editor.isBlock(editor, n);
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!hanging && Range.isRange(at)) {
|
|||
|
|
at = Editor.unhangRange(editor, at);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (Range.isRange(at)) {
|
|||
|
|
if (Range.isCollapsed(at)) {
|
|||
|
|
at = at.anchor;
|
|||
|
|
} else {
|
|||
|
|
var _Range$edges3 = Range.edges(at),
|
|||
|
|
_Range$edges4 = _slicedToArray(_Range$edges3, 2),
|
|||
|
|
end = _Range$edges4[1];
|
|||
|
|
|
|||
|
|
var pointRef = Editor.pointRef(editor, end);
|
|||
|
|
Transforms["delete"](editor, {
|
|||
|
|
at: at
|
|||
|
|
});
|
|||
|
|
at = pointRef.unref();
|
|||
|
|
|
|||
|
|
if (options.at == null) {
|
|||
|
|
Transforms.select(editor, at);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var _Editor$nodes3 = Editor.nodes(editor, {
|
|||
|
|
at: at,
|
|||
|
|
match: match,
|
|||
|
|
voids: voids,
|
|||
|
|
mode: mode
|
|||
|
|
}),
|
|||
|
|
_Editor$nodes4 = _slicedToArray(_Editor$nodes3, 1),
|
|||
|
|
current = _Editor$nodes4[0];
|
|||
|
|
|
|||
|
|
var prev = Editor.previous(editor, {
|
|||
|
|
at: at,
|
|||
|
|
match: match,
|
|||
|
|
voids: voids,
|
|||
|
|
mode: mode
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
if (!current || !prev) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var _current = _slicedToArray(current, 2),
|
|||
|
|
node = _current[0],
|
|||
|
|
path = _current[1];
|
|||
|
|
|
|||
|
|
var _prev = _slicedToArray(prev, 2),
|
|||
|
|
prevNode = _prev[0],
|
|||
|
|
prevPath = _prev[1];
|
|||
|
|
|
|||
|
|
if (path.length === 0 || prevPath.length === 0) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var newPath = Path.next(prevPath);
|
|||
|
|
var commonPath = Path.common(path, prevPath);
|
|||
|
|
var isPreviousSibling = Path.isSibling(path, prevPath);
|
|||
|
|
var levels = Array.from(Editor.levels(editor, {
|
|||
|
|
at: path
|
|||
|
|
}), function (_ref3) {
|
|||
|
|
var _ref4 = _slicedToArray(_ref3, 1),
|
|||
|
|
n = _ref4[0];
|
|||
|
|
|
|||
|
|
return n;
|
|||
|
|
}).slice(commonPath.length).slice(0, -1); // Determine if the merge will leave an ancestor of the path empty as a
|
|||
|
|
// result, in which case we'll want to remove it after merging.
|
|||
|
|
|
|||
|
|
var emptyAncestor = Editor.above(editor, {
|
|||
|
|
at: path,
|
|||
|
|
mode: 'highest',
|
|||
|
|
match: function match(n) {
|
|||
|
|
return levels.includes(n) && hasSingleChildNest(editor, n);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
var emptyRef = emptyAncestor && Editor.pathRef(editor, emptyAncestor[1]);
|
|||
|
|
var properties;
|
|||
|
|
var position; // Ensure that the nodes are equivalent, and figure out what the position
|
|||
|
|
// and extra properties of the merge will be.
|
|||
|
|
|
|||
|
|
if (Text.isText(node) && Text.isText(prevNode)) {
|
|||
|
|
node.text;
|
|||
|
|
var rest = _objectWithoutProperties(node, _excluded);
|
|||
|
|
|
|||
|
|
position = prevNode.text.length;
|
|||
|
|
properties = rest;
|
|||
|
|
} else if (Element$1.isElement(node) && Element$1.isElement(prevNode)) {
|
|||
|
|
node.children;
|
|||
|
|
var _rest = _objectWithoutProperties(node, _excluded2);
|
|||
|
|
|
|||
|
|
position = prevNode.children.length;
|
|||
|
|
properties = _rest;
|
|||
|
|
} else {
|
|||
|
|
throw new Error("Cannot merge the node at path [".concat(path, "] with the previous sibling because it is not the same kind: ").concat(JSON.stringify(node), " ").concat(JSON.stringify(prevNode)));
|
|||
|
|
} // If the node isn't already the next sibling of the previous node, move
|
|||
|
|
// it so that it is before merging.
|
|||
|
|
|
|||
|
|
|
|||
|
|
if (!isPreviousSibling) {
|
|||
|
|
Transforms.moveNodes(editor, {
|
|||
|
|
at: path,
|
|||
|
|
to: newPath,
|
|||
|
|
voids: voids
|
|||
|
|
});
|
|||
|
|
} // If there was going to be an empty ancestor of the node that was merged,
|
|||
|
|
// we remove it from the tree.
|
|||
|
|
|
|||
|
|
|
|||
|
|
if (emptyRef) {
|
|||
|
|
Transforms.removeNodes(editor, {
|
|||
|
|
at: emptyRef.current,
|
|||
|
|
voids: voids
|
|||
|
|
});
|
|||
|
|
} // If the target node that we're merging with is empty, remove it instead
|
|||
|
|
// of merging the two. This is a common rich text editor behavior to
|
|||
|
|
// prevent losing formatting when deleting entire nodes when you have a
|
|||
|
|
// hanging selection.
|
|||
|
|
// if prevNode is first child in parent,don't remove it.
|
|||
|
|
|
|||
|
|
|
|||
|
|
if (Element$1.isElement(prevNode) && Editor.isEmpty(editor, prevNode) || Text.isText(prevNode) && prevNode.text === '' && prevPath[prevPath.length - 1] !== 0) {
|
|||
|
|
Transforms.removeNodes(editor, {
|
|||
|
|
at: prevPath,
|
|||
|
|
voids: voids
|
|||
|
|
});
|
|||
|
|
} else {
|
|||
|
|
editor.apply({
|
|||
|
|
type: 'merge_node',
|
|||
|
|
path: newPath,
|
|||
|
|
position: position,
|
|||
|
|
properties: properties
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (emptyRef) {
|
|||
|
|
emptyRef.unref();
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Move the nodes at a location to a new location.
|
|||
|
|
*/
|
|||
|
|
moveNodes: function moveNodes(editor, options) {
|
|||
|
|
Editor.withoutNormalizing(editor, function () {
|
|||
|
|
var to = options.to,
|
|||
|
|
_options$at3 = options.at,
|
|||
|
|
at = _options$at3 === void 0 ? editor.selection : _options$at3,
|
|||
|
|
_options$mode4 = options.mode,
|
|||
|
|
mode = _options$mode4 === void 0 ? 'lowest' : _options$mode4,
|
|||
|
|
_options$voids4 = options.voids,
|
|||
|
|
voids = _options$voids4 === void 0 ? false : _options$voids4;
|
|||
|
|
var match = options.match;
|
|||
|
|
|
|||
|
|
if (!at) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (match == null) {
|
|||
|
|
match = Path.isPath(at) ? matchPath(editor, at) : function (n) {
|
|||
|
|
return Editor.isBlock(editor, n);
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var toRef = Editor.pathRef(editor, to);
|
|||
|
|
var targets = Editor.nodes(editor, {
|
|||
|
|
at: at,
|
|||
|
|
match: match,
|
|||
|
|
mode: mode,
|
|||
|
|
voids: voids
|
|||
|
|
});
|
|||
|
|
var pathRefs = Array.from(targets, function (_ref5) {
|
|||
|
|
var _ref6 = _slicedToArray(_ref5, 2),
|
|||
|
|
p = _ref6[1];
|
|||
|
|
|
|||
|
|
return Editor.pathRef(editor, p);
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
for (var _i2 = 0, _pathRefs2 = pathRefs; _i2 < _pathRefs2.length; _i2++) {
|
|||
|
|
var pathRef = _pathRefs2[_i2];
|
|||
|
|
var path = pathRef.unref();
|
|||
|
|
var newPath = toRef.current;
|
|||
|
|
|
|||
|
|
if (path.length !== 0) {
|
|||
|
|
editor.apply({
|
|||
|
|
type: 'move_node',
|
|||
|
|
path: path,
|
|||
|
|
newPath: newPath
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (toRef.current && Path.isSibling(newPath, path) && Path.isAfter(newPath, path)) {
|
|||
|
|
// When performing a sibling move to a later index, the path at the destination is shifted
|
|||
|
|
// to before the insertion point instead of after. To ensure our group of nodes are inserted
|
|||
|
|
// in the correct order we increment toRef to account for that
|
|||
|
|
toRef.current = Path.next(toRef.current);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
toRef.unref();
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Remove the nodes at a specific location in the document.
|
|||
|
|
*/
|
|||
|
|
removeNodes: function removeNodes(editor) {
|
|||
|
|
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|||
|
|
Editor.withoutNormalizing(editor, function () {
|
|||
|
|
var _options$hanging3 = options.hanging,
|
|||
|
|
hanging = _options$hanging3 === void 0 ? false : _options$hanging3,
|
|||
|
|
_options$voids5 = options.voids,
|
|||
|
|
voids = _options$voids5 === void 0 ? false : _options$voids5,
|
|||
|
|
_options$mode5 = options.mode,
|
|||
|
|
mode = _options$mode5 === void 0 ? 'lowest' : _options$mode5;
|
|||
|
|
var _options$at4 = options.at,
|
|||
|
|
at = _options$at4 === void 0 ? editor.selection : _options$at4,
|
|||
|
|
match = options.match;
|
|||
|
|
|
|||
|
|
if (!at) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (match == null) {
|
|||
|
|
match = Path.isPath(at) ? matchPath(editor, at) : function (n) {
|
|||
|
|
return Editor.isBlock(editor, n);
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!hanging && Range.isRange(at)) {
|
|||
|
|
at = Editor.unhangRange(editor, at);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var depths = Editor.nodes(editor, {
|
|||
|
|
at: at,
|
|||
|
|
match: match,
|
|||
|
|
mode: mode,
|
|||
|
|
voids: voids
|
|||
|
|
});
|
|||
|
|
var pathRefs = Array.from(depths, function (_ref7) {
|
|||
|
|
var _ref8 = _slicedToArray(_ref7, 2),
|
|||
|
|
p = _ref8[1];
|
|||
|
|
|
|||
|
|
return Editor.pathRef(editor, p);
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
for (var _i3 = 0, _pathRefs3 = pathRefs; _i3 < _pathRefs3.length; _i3++) {
|
|||
|
|
var pathRef = _pathRefs3[_i3];
|
|||
|
|
var path = pathRef.unref();
|
|||
|
|
|
|||
|
|
if (path) {
|
|||
|
|
var _Editor$node = Editor.node(editor, path),
|
|||
|
|
_Editor$node2 = _slicedToArray(_Editor$node, 1),
|
|||
|
|
node = _Editor$node2[0];
|
|||
|
|
|
|||
|
|
editor.apply({
|
|||
|
|
type: 'remove_node',
|
|||
|
|
path: path,
|
|||
|
|
node: node
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Set new properties on the nodes at a location.
|
|||
|
|
*/
|
|||
|
|
setNodes: function setNodes(editor, props) {
|
|||
|
|
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|||
|
|
Editor.withoutNormalizing(editor, function () {
|
|||
|
|
var match = options.match,
|
|||
|
|
_options$at5 = options.at,
|
|||
|
|
at = _options$at5 === void 0 ? editor.selection : _options$at5;
|
|||
|
|
var _options$hanging4 = options.hanging,
|
|||
|
|
hanging = _options$hanging4 === void 0 ? false : _options$hanging4,
|
|||
|
|
_options$mode6 = options.mode,
|
|||
|
|
mode = _options$mode6 === void 0 ? 'lowest' : _options$mode6,
|
|||
|
|
_options$split = options.split,
|
|||
|
|
split = _options$split === void 0 ? false : _options$split,
|
|||
|
|
_options$voids6 = options.voids,
|
|||
|
|
voids = _options$voids6 === void 0 ? false : _options$voids6;
|
|||
|
|
|
|||
|
|
if (!at) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (match == null) {
|
|||
|
|
match = Path.isPath(at) ? matchPath(editor, at) : function (n) {
|
|||
|
|
return Editor.isBlock(editor, n);
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!hanging && Range.isRange(at)) {
|
|||
|
|
at = Editor.unhangRange(editor, at);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (split && Range.isRange(at)) {
|
|||
|
|
if (Range.isCollapsed(at) && Editor.leaf(editor, at.anchor)[0].text.length > 0) {
|
|||
|
|
// If the range is collapsed in a non-empty node and 'split' is true, there's nothing to
|
|||
|
|
// set that won't get normalized away
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var rangeRef = Editor.rangeRef(editor, at, {
|
|||
|
|
affinity: 'inward'
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
var _Range$edges5 = Range.edges(at),
|
|||
|
|
_Range$edges6 = _slicedToArray(_Range$edges5, 2),
|
|||
|
|
start = _Range$edges6[0],
|
|||
|
|
end = _Range$edges6[1];
|
|||
|
|
|
|||
|
|
var splitMode = mode === 'lowest' ? 'lowest' : 'highest';
|
|||
|
|
var endAtEndOfNode = Editor.isEnd(editor, end, end.path);
|
|||
|
|
Transforms.splitNodes(editor, {
|
|||
|
|
at: end,
|
|||
|
|
match: match,
|
|||
|
|
mode: splitMode,
|
|||
|
|
voids: voids,
|
|||
|
|
always: !endAtEndOfNode
|
|||
|
|
});
|
|||
|
|
var startAtStartOfNode = Editor.isStart(editor, start, start.path);
|
|||
|
|
Transforms.splitNodes(editor, {
|
|||
|
|
at: start,
|
|||
|
|
match: match,
|
|||
|
|
mode: splitMode,
|
|||
|
|
voids: voids,
|
|||
|
|
always: !startAtStartOfNode
|
|||
|
|
});
|
|||
|
|
at = rangeRef.unref();
|
|||
|
|
|
|||
|
|
if (options.at == null) {
|
|||
|
|
Transforms.select(editor, at);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var _iterator2 = _createForOfIteratorHelper$1(Editor.nodes(editor, {
|
|||
|
|
at: at,
|
|||
|
|
match: match,
|
|||
|
|
mode: mode,
|
|||
|
|
voids: voids
|
|||
|
|
})),
|
|||
|
|
_step2;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|||
|
|
var _step2$value = _slicedToArray(_step2.value, 2),
|
|||
|
|
node = _step2$value[0],
|
|||
|
|
path = _step2$value[1];
|
|||
|
|
|
|||
|
|
var properties = {};
|
|||
|
|
var newProperties = {}; // You can't set properties on the editor node.
|
|||
|
|
|
|||
|
|
if (path.length === 0) {
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var hasChanges = false;
|
|||
|
|
|
|||
|
|
for (var k in props) {
|
|||
|
|
if (k === 'children' || k === 'text') {
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (props[k] !== node[k]) {
|
|||
|
|
hasChanges = true; // Omit new properties from the old properties list
|
|||
|
|
|
|||
|
|
if (node.hasOwnProperty(k)) properties[k] = node[k]; // Omit properties that have been removed from the new properties list
|
|||
|
|
|
|||
|
|
if (props[k] != null) newProperties[k] = props[k];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (hasChanges) {
|
|||
|
|
editor.apply({
|
|||
|
|
type: 'set_node',
|
|||
|
|
path: path,
|
|||
|
|
properties: properties,
|
|||
|
|
newProperties: newProperties
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
} catch (err) {
|
|||
|
|
_iterator2.e(err);
|
|||
|
|
} finally {
|
|||
|
|
_iterator2.f();
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Split the nodes at a specific location.
|
|||
|
|
*/
|
|||
|
|
splitNodes: function splitNodes(editor) {
|
|||
|
|
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|||
|
|
Editor.withoutNormalizing(editor, function () {
|
|||
|
|
var _options$mode7 = options.mode,
|
|||
|
|
mode = _options$mode7 === void 0 ? 'lowest' : _options$mode7,
|
|||
|
|
_options$voids7 = options.voids,
|
|||
|
|
voids = _options$voids7 === void 0 ? false : _options$voids7;
|
|||
|
|
var match = options.match,
|
|||
|
|
_options$at6 = options.at,
|
|||
|
|
at = _options$at6 === void 0 ? editor.selection : _options$at6,
|
|||
|
|
_options$height = options.height,
|
|||
|
|
height = _options$height === void 0 ? 0 : _options$height,
|
|||
|
|
_options$always = options.always,
|
|||
|
|
always = _options$always === void 0 ? false : _options$always;
|
|||
|
|
|
|||
|
|
if (match == null) {
|
|||
|
|
match = function match(n) {
|
|||
|
|
return Editor.isBlock(editor, n);
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (Range.isRange(at)) {
|
|||
|
|
at = deleteRange(editor, at);
|
|||
|
|
} // If the target is a path, the default height-skipping and position
|
|||
|
|
// counters need to account for us potentially splitting at a non-leaf.
|
|||
|
|
|
|||
|
|
|
|||
|
|
if (Path.isPath(at)) {
|
|||
|
|
var path = at;
|
|||
|
|
var point = Editor.point(editor, path);
|
|||
|
|
|
|||
|
|
var _Editor$parent3 = Editor.parent(editor, path),
|
|||
|
|
_Editor$parent4 = _slicedToArray(_Editor$parent3, 1),
|
|||
|
|
parent = _Editor$parent4[0];
|
|||
|
|
|
|||
|
|
match = function match(n) {
|
|||
|
|
return n === parent;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
height = point.path.length - path.length + 1;
|
|||
|
|
at = point;
|
|||
|
|
always = true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!at) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var beforeRef = Editor.pointRef(editor, at, {
|
|||
|
|
affinity: 'backward'
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
var _Editor$nodes5 = Editor.nodes(editor, {
|
|||
|
|
at: at,
|
|||
|
|
match: match,
|
|||
|
|
mode: mode,
|
|||
|
|
voids: voids
|
|||
|
|
}),
|
|||
|
|
_Editor$nodes6 = _slicedToArray(_Editor$nodes5, 1),
|
|||
|
|
highest = _Editor$nodes6[0];
|
|||
|
|
|
|||
|
|
if (!highest) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var voidMatch = Editor["void"](editor, {
|
|||
|
|
at: at,
|
|||
|
|
mode: 'highest'
|
|||
|
|
});
|
|||
|
|
var nudge = 0;
|
|||
|
|
|
|||
|
|
if (!voids && voidMatch) {
|
|||
|
|
var _voidMatch = _slicedToArray(voidMatch, 2),
|
|||
|
|
voidNode = _voidMatch[0],
|
|||
|
|
voidPath = _voidMatch[1];
|
|||
|
|
|
|||
|
|
if (Element$1.isElement(voidNode) && editor.isInline(voidNode)) {
|
|||
|
|
var after = Editor.after(editor, voidPath);
|
|||
|
|
|
|||
|
|
if (!after) {
|
|||
|
|
var text = {
|
|||
|
|
text: ''
|
|||
|
|
};
|
|||
|
|
var afterPath = Path.next(voidPath);
|
|||
|
|
Transforms.insertNodes(editor, text, {
|
|||
|
|
at: afterPath,
|
|||
|
|
voids: voids
|
|||
|
|
});
|
|||
|
|
after = Editor.point(editor, afterPath);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
at = after;
|
|||
|
|
always = true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var siblingHeight = at.path.length - voidPath.length;
|
|||
|
|
height = siblingHeight + 1;
|
|||
|
|
always = true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var afterRef = Editor.pointRef(editor, at);
|
|||
|
|
var depth = at.path.length - height;
|
|||
|
|
|
|||
|
|
var _highest = _slicedToArray(highest, 2),
|
|||
|
|
highestPath = _highest[1];
|
|||
|
|
|
|||
|
|
var lowestPath = at.path.slice(0, depth);
|
|||
|
|
var position = height === 0 ? at.offset : at.path[depth] + nudge;
|
|||
|
|
|
|||
|
|
var _iterator3 = _createForOfIteratorHelper$1(Editor.levels(editor, {
|
|||
|
|
at: lowestPath,
|
|||
|
|
reverse: true,
|
|||
|
|
voids: voids
|
|||
|
|
})),
|
|||
|
|
_step3;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|||
|
|
var _step3$value = _slicedToArray(_step3.value, 2),
|
|||
|
|
node = _step3$value[0],
|
|||
|
|
_path2 = _step3$value[1];
|
|||
|
|
|
|||
|
|
var split = false;
|
|||
|
|
|
|||
|
|
if (_path2.length < highestPath.length || _path2.length === 0 || !voids && Editor.isVoid(editor, node)) {
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var _point2 = beforeRef.current;
|
|||
|
|
var isEnd = Editor.isEnd(editor, _point2, _path2);
|
|||
|
|
|
|||
|
|
if (always || !beforeRef || !Editor.isEdge(editor, _point2, _path2)) {
|
|||
|
|
split = true;
|
|||
|
|
var properties = Node$1.extractProps(node);
|
|||
|
|
editor.apply({
|
|||
|
|
type: 'split_node',
|
|||
|
|
path: _path2,
|
|||
|
|
position: position,
|
|||
|
|
properties: properties
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
position = _path2[_path2.length - 1] + (split || isEnd ? 1 : 0);
|
|||
|
|
}
|
|||
|
|
} catch (err) {
|
|||
|
|
_iterator3.e(err);
|
|||
|
|
} finally {
|
|||
|
|
_iterator3.f();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (options.at == null) {
|
|||
|
|
var _point = afterRef.current || Editor.end(editor, []);
|
|||
|
|
|
|||
|
|
Transforms.select(editor, _point);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
beforeRef.unref();
|
|||
|
|
afterRef.unref();
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Unset properties on the nodes at a location.
|
|||
|
|
*/
|
|||
|
|
unsetNodes: function unsetNodes(editor, props) {
|
|||
|
|
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|||
|
|
|
|||
|
|
if (!Array.isArray(props)) {
|
|||
|
|
props = [props];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var obj = {};
|
|||
|
|
|
|||
|
|
var _iterator4 = _createForOfIteratorHelper$1(props),
|
|||
|
|
_step4;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
|
|||
|
|
var key = _step4.value;
|
|||
|
|
obj[key] = null;
|
|||
|
|
}
|
|||
|
|
} catch (err) {
|
|||
|
|
_iterator4.e(err);
|
|||
|
|
} finally {
|
|||
|
|
_iterator4.f();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Transforms.setNodes(editor, obj, options);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Unwrap the nodes at a location from a parent node, splitting the parent if
|
|||
|
|
* necessary to ensure that only the content in the range is unwrapped.
|
|||
|
|
*/
|
|||
|
|
unwrapNodes: function unwrapNodes(editor) {
|
|||
|
|
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|||
|
|
Editor.withoutNormalizing(editor, function () {
|
|||
|
|
var _options$mode8 = options.mode,
|
|||
|
|
mode = _options$mode8 === void 0 ? 'lowest' : _options$mode8,
|
|||
|
|
_options$split2 = options.split,
|
|||
|
|
split = _options$split2 === void 0 ? false : _options$split2,
|
|||
|
|
_options$voids8 = options.voids,
|
|||
|
|
voids = _options$voids8 === void 0 ? false : _options$voids8;
|
|||
|
|
var _options$at7 = options.at,
|
|||
|
|
at = _options$at7 === void 0 ? editor.selection : _options$at7,
|
|||
|
|
match = options.match;
|
|||
|
|
|
|||
|
|
if (!at) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (match == null) {
|
|||
|
|
match = Path.isPath(at) ? matchPath(editor, at) : function (n) {
|
|||
|
|
return Editor.isBlock(editor, n);
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (Path.isPath(at)) {
|
|||
|
|
at = Editor.range(editor, at);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var rangeRef = Range.isRange(at) ? Editor.rangeRef(editor, at) : null;
|
|||
|
|
var matches = Editor.nodes(editor, {
|
|||
|
|
at: at,
|
|||
|
|
match: match,
|
|||
|
|
mode: mode,
|
|||
|
|
voids: voids
|
|||
|
|
});
|
|||
|
|
var pathRefs = Array.from(matches, function (_ref9) {
|
|||
|
|
var _ref10 = _slicedToArray(_ref9, 2),
|
|||
|
|
p = _ref10[1];
|
|||
|
|
|
|||
|
|
return Editor.pathRef(editor, p);
|
|||
|
|
} // unwrapNode will call liftNode which does not support splitting the node when nested.
|
|||
|
|
// If we do not reverse the order and call it from top to the bottom, it will remove all blocks
|
|||
|
|
// that wrap target node. So we reverse the order.
|
|||
|
|
).reverse();
|
|||
|
|
|
|||
|
|
var _iterator5 = _createForOfIteratorHelper$1(pathRefs),
|
|||
|
|
_step5;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
var _loop = function _loop() {
|
|||
|
|
var pathRef = _step5.value;
|
|||
|
|
var path = pathRef.unref();
|
|||
|
|
|
|||
|
|
var _Editor$node3 = Editor.node(editor, path),
|
|||
|
|
_Editor$node4 = _slicedToArray(_Editor$node3, 1),
|
|||
|
|
node = _Editor$node4[0];
|
|||
|
|
|
|||
|
|
var range = Editor.range(editor, path);
|
|||
|
|
|
|||
|
|
if (split && rangeRef) {
|
|||
|
|
range = Range.intersection(rangeRef.current, range);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Transforms.liftNodes(editor, {
|
|||
|
|
at: range,
|
|||
|
|
match: function match(n) {
|
|||
|
|
return Element$1.isAncestor(node) && node.children.includes(n);
|
|||
|
|
},
|
|||
|
|
voids: voids
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
|
|||
|
|
_loop();
|
|||
|
|
}
|
|||
|
|
} catch (err) {
|
|||
|
|
_iterator5.e(err);
|
|||
|
|
} finally {
|
|||
|
|
_iterator5.f();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (rangeRef) {
|
|||
|
|
rangeRef.unref();
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Wrap the nodes at a location in a new container node, splitting the edges
|
|||
|
|
* of the range first to ensure that only the content in the range is wrapped.
|
|||
|
|
*/
|
|||
|
|
wrapNodes: function wrapNodes(editor, element) {
|
|||
|
|
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|||
|
|
Editor.withoutNormalizing(editor, function () {
|
|||
|
|
var _options$mode9 = options.mode,
|
|||
|
|
mode = _options$mode9 === void 0 ? 'lowest' : _options$mode9,
|
|||
|
|
_options$split3 = options.split,
|
|||
|
|
split = _options$split3 === void 0 ? false : _options$split3,
|
|||
|
|
_options$voids9 = options.voids,
|
|||
|
|
voids = _options$voids9 === void 0 ? false : _options$voids9;
|
|||
|
|
var match = options.match,
|
|||
|
|
_options$at8 = options.at,
|
|||
|
|
at = _options$at8 === void 0 ? editor.selection : _options$at8;
|
|||
|
|
|
|||
|
|
if (!at) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (match == null) {
|
|||
|
|
if (Path.isPath(at)) {
|
|||
|
|
match = matchPath(editor, at);
|
|||
|
|
} else if (editor.isInline(element)) {
|
|||
|
|
match = function match(n) {
|
|||
|
|
return Editor.isInline(editor, n) || Text.isText(n);
|
|||
|
|
};
|
|||
|
|
} else {
|
|||
|
|
match = function match(n) {
|
|||
|
|
return Editor.isBlock(editor, n);
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (split && Range.isRange(at)) {
|
|||
|
|
var _Range$edges7 = Range.edges(at),
|
|||
|
|
_Range$edges8 = _slicedToArray(_Range$edges7, 2),
|
|||
|
|
start = _Range$edges8[0],
|
|||
|
|
end = _Range$edges8[1];
|
|||
|
|
|
|||
|
|
var rangeRef = Editor.rangeRef(editor, at, {
|
|||
|
|
affinity: 'inward'
|
|||
|
|
});
|
|||
|
|
Transforms.splitNodes(editor, {
|
|||
|
|
at: end,
|
|||
|
|
match: match,
|
|||
|
|
voids: voids
|
|||
|
|
});
|
|||
|
|
Transforms.splitNodes(editor, {
|
|||
|
|
at: start,
|
|||
|
|
match: match,
|
|||
|
|
voids: voids
|
|||
|
|
});
|
|||
|
|
at = rangeRef.unref();
|
|||
|
|
|
|||
|
|
if (options.at == null) {
|
|||
|
|
Transforms.select(editor, at);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var roots = Array.from(Editor.nodes(editor, {
|
|||
|
|
at: at,
|
|||
|
|
match: editor.isInline(element) ? function (n) {
|
|||
|
|
return Editor.isBlock(editor, n);
|
|||
|
|
} : function (n) {
|
|||
|
|
return Editor.isEditor(n);
|
|||
|
|
},
|
|||
|
|
mode: 'lowest',
|
|||
|
|
voids: voids
|
|||
|
|
}));
|
|||
|
|
|
|||
|
|
for (var _i4 = 0, _roots = roots; _i4 < _roots.length; _i4++) {
|
|||
|
|
var _roots$_i = _slicedToArray(_roots[_i4], 2),
|
|||
|
|
rootPath = _roots$_i[1];
|
|||
|
|
|
|||
|
|
var a = Range.isRange(at) ? Range.intersection(at, Editor.range(editor, rootPath)) : at;
|
|||
|
|
|
|||
|
|
if (!a) {
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var matches = Array.from(Editor.nodes(editor, {
|
|||
|
|
at: a,
|
|||
|
|
match: match,
|
|||
|
|
mode: mode,
|
|||
|
|
voids: voids
|
|||
|
|
}));
|
|||
|
|
|
|||
|
|
if (matches.length > 0) {
|
|||
|
|
var _ret = function () {
|
|||
|
|
var _matches = _slicedToArray(matches, 1),
|
|||
|
|
first = _matches[0];
|
|||
|
|
|
|||
|
|
var last = matches[matches.length - 1];
|
|||
|
|
|
|||
|
|
var _first = _slicedToArray(first, 2),
|
|||
|
|
firstPath = _first[1];
|
|||
|
|
|
|||
|
|
var _last = _slicedToArray(last, 2),
|
|||
|
|
lastPath = _last[1];
|
|||
|
|
|
|||
|
|
if (firstPath.length === 0 && lastPath.length === 0) {
|
|||
|
|
// if there's no matching parent - usually means the node is an editor - don't do anything
|
|||
|
|
return "continue";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var commonPath = Path.equals(firstPath, lastPath) ? Path.parent(firstPath) : Path.common(firstPath, lastPath);
|
|||
|
|
var range = Editor.range(editor, firstPath, lastPath);
|
|||
|
|
var commonNodeEntry = Editor.node(editor, commonPath);
|
|||
|
|
|
|||
|
|
var _commonNodeEntry = _slicedToArray(commonNodeEntry, 1),
|
|||
|
|
commonNode = _commonNodeEntry[0];
|
|||
|
|
|
|||
|
|
var depth = commonPath.length + 1;
|
|||
|
|
var wrapperPath = Path.next(lastPath.slice(0, depth));
|
|||
|
|
|
|||
|
|
var wrapper = _objectSpread$2(_objectSpread$2({}, element), {}, {
|
|||
|
|
children: []
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
Transforms.insertNodes(editor, wrapper, {
|
|||
|
|
at: wrapperPath,
|
|||
|
|
voids: voids
|
|||
|
|
});
|
|||
|
|
Transforms.moveNodes(editor, {
|
|||
|
|
at: range,
|
|||
|
|
match: function match(n) {
|
|||
|
|
return Element$1.isAncestor(commonNode) && commonNode.children.includes(n);
|
|||
|
|
},
|
|||
|
|
to: wrapperPath.concat(0),
|
|||
|
|
voids: voids
|
|||
|
|
});
|
|||
|
|
}();
|
|||
|
|
|
|||
|
|
if (_ret === "continue") continue;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var hasSingleChildNest = function hasSingleChildNest(editor, node) {
|
|||
|
|
if (Element$1.isElement(node)) {
|
|||
|
|
var element = node;
|
|||
|
|
|
|||
|
|
if (Editor.isVoid(editor, node)) {
|
|||
|
|
return true;
|
|||
|
|
} else if (element.children.length === 1) {
|
|||
|
|
return hasSingleChildNest(editor, element.children[0]);
|
|||
|
|
} else {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
} else if (Editor.isEditor(node)) {
|
|||
|
|
return false;
|
|||
|
|
} else {
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
/**
|
|||
|
|
* Convert a range into a point by deleting it's content.
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
var deleteRange = function deleteRange(editor, range) {
|
|||
|
|
if (Range.isCollapsed(range)) {
|
|||
|
|
return range.anchor;
|
|||
|
|
} else {
|
|||
|
|
var _Range$edges9 = Range.edges(range),
|
|||
|
|
_Range$edges10 = _slicedToArray(_Range$edges9, 2),
|
|||
|
|
end = _Range$edges10[1];
|
|||
|
|
|
|||
|
|
var pointRef = Editor.pointRef(editor, end);
|
|||
|
|
Transforms["delete"](editor, {
|
|||
|
|
at: range
|
|||
|
|
});
|
|||
|
|
return pointRef.unref();
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var matchPath = function matchPath(editor, path) {
|
|||
|
|
var _Editor$node5 = Editor.node(editor, path),
|
|||
|
|
_Editor$node6 = _slicedToArray(_Editor$node5, 1),
|
|||
|
|
node = _Editor$node6[0];
|
|||
|
|
|
|||
|
|
return function (n) {
|
|||
|
|
return n === node;
|
|||
|
|
};
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
function ownKeys$1(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
|
|||
|
|
|
|||
|
|
function _objectSpread$1(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$1(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$1(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
|||
|
|
var SelectionTransforms = {
|
|||
|
|
/**
|
|||
|
|
* Collapse the selection.
|
|||
|
|
*/
|
|||
|
|
collapse: function collapse(editor) {
|
|||
|
|
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|||
|
|
var _options$edge = options.edge,
|
|||
|
|
edge = _options$edge === void 0 ? 'anchor' : _options$edge;
|
|||
|
|
var selection = editor.selection;
|
|||
|
|
|
|||
|
|
if (!selection) {
|
|||
|
|
return;
|
|||
|
|
} else if (edge === 'anchor') {
|
|||
|
|
Transforms.select(editor, selection.anchor);
|
|||
|
|
} else if (edge === 'focus') {
|
|||
|
|
Transforms.select(editor, selection.focus);
|
|||
|
|
} else if (edge === 'start') {
|
|||
|
|
var _Range$edges = Range.edges(selection),
|
|||
|
|
_Range$edges2 = _slicedToArray(_Range$edges, 1),
|
|||
|
|
start = _Range$edges2[0];
|
|||
|
|
|
|||
|
|
Transforms.select(editor, start);
|
|||
|
|
} else if (edge === 'end') {
|
|||
|
|
var _Range$edges3 = Range.edges(selection),
|
|||
|
|
_Range$edges4 = _slicedToArray(_Range$edges3, 2),
|
|||
|
|
end = _Range$edges4[1];
|
|||
|
|
|
|||
|
|
Transforms.select(editor, end);
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Unset the selection.
|
|||
|
|
*/
|
|||
|
|
deselect: function deselect(editor) {
|
|||
|
|
var selection = editor.selection;
|
|||
|
|
|
|||
|
|
if (selection) {
|
|||
|
|
editor.apply({
|
|||
|
|
type: 'set_selection',
|
|||
|
|
properties: selection,
|
|||
|
|
newProperties: null
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Move the selection's point forward or backward.
|
|||
|
|
*/
|
|||
|
|
move: function move(editor) {
|
|||
|
|
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|||
|
|
var selection = editor.selection;
|
|||
|
|
var _options$distance = options.distance,
|
|||
|
|
distance = _options$distance === void 0 ? 1 : _options$distance,
|
|||
|
|
_options$unit = options.unit,
|
|||
|
|
unit = _options$unit === void 0 ? 'character' : _options$unit,
|
|||
|
|
_options$reverse = options.reverse,
|
|||
|
|
reverse = _options$reverse === void 0 ? false : _options$reverse;
|
|||
|
|
var _options$edge2 = options.edge,
|
|||
|
|
edge = _options$edge2 === void 0 ? null : _options$edge2;
|
|||
|
|
|
|||
|
|
if (!selection) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (edge === 'start') {
|
|||
|
|
edge = Range.isBackward(selection) ? 'focus' : 'anchor';
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (edge === 'end') {
|
|||
|
|
edge = Range.isBackward(selection) ? 'anchor' : 'focus';
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var anchor = selection.anchor,
|
|||
|
|
focus = selection.focus;
|
|||
|
|
var opts = {
|
|||
|
|
distance: distance,
|
|||
|
|
unit: unit
|
|||
|
|
};
|
|||
|
|
var props = {};
|
|||
|
|
|
|||
|
|
if (edge == null || edge === 'anchor') {
|
|||
|
|
var point = reverse ? Editor.before(editor, anchor, opts) : Editor.after(editor, anchor, opts);
|
|||
|
|
|
|||
|
|
if (point) {
|
|||
|
|
props.anchor = point;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (edge == null || edge === 'focus') {
|
|||
|
|
var _point = reverse ? Editor.before(editor, focus, opts) : Editor.after(editor, focus, opts);
|
|||
|
|
|
|||
|
|
if (_point) {
|
|||
|
|
props.focus = _point;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Transforms.setSelection(editor, props);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Set the selection to a new value.
|
|||
|
|
*/
|
|||
|
|
select: function select(editor, target) {
|
|||
|
|
var selection = editor.selection;
|
|||
|
|
target = Editor.range(editor, target);
|
|||
|
|
|
|||
|
|
if (selection) {
|
|||
|
|
Transforms.setSelection(editor, target);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!Range.isRange(target)) {
|
|||
|
|
throw new Error("When setting the selection and the current selection is `null` you must provide at least an `anchor` and `focus`, but you passed: ".concat(JSON.stringify(target)));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
editor.apply({
|
|||
|
|
type: 'set_selection',
|
|||
|
|
properties: selection,
|
|||
|
|
newProperties: target
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Set new properties on one of the selection's points.
|
|||
|
|
*/
|
|||
|
|
setPoint: function setPoint(editor, props) {
|
|||
|
|
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|||
|
|
var selection = editor.selection;
|
|||
|
|
var _options$edge3 = options.edge,
|
|||
|
|
edge = _options$edge3 === void 0 ? 'both' : _options$edge3;
|
|||
|
|
|
|||
|
|
if (!selection) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (edge === 'start') {
|
|||
|
|
edge = Range.isBackward(selection) ? 'focus' : 'anchor';
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (edge === 'end') {
|
|||
|
|
edge = Range.isBackward(selection) ? 'anchor' : 'focus';
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var anchor = selection.anchor,
|
|||
|
|
focus = selection.focus;
|
|||
|
|
var point = edge === 'anchor' ? anchor : focus;
|
|||
|
|
Transforms.setSelection(editor, _defineProperty({}, edge === 'anchor' ? 'anchor' : 'focus', _objectSpread$1(_objectSpread$1({}, point), props)));
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Set new properties on the selection.
|
|||
|
|
*/
|
|||
|
|
setSelection: function setSelection(editor, props) {
|
|||
|
|
var selection = editor.selection;
|
|||
|
|
var oldProps = {};
|
|||
|
|
var newProps = {};
|
|||
|
|
|
|||
|
|
if (!selection) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
for (var k in props) {
|
|||
|
|
if (k === 'anchor' && props.anchor != null && !Point.equals(props.anchor, selection.anchor) || k === 'focus' && props.focus != null && !Point.equals(props.focus, selection.focus) || k !== 'anchor' && k !== 'focus' && props[k] !== selection[k]) {
|
|||
|
|
oldProps[k] = selection[k];
|
|||
|
|
newProps[k] = props[k];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (Object.keys(oldProps).length > 0) {
|
|||
|
|
editor.apply({
|
|||
|
|
type: 'set_selection',
|
|||
|
|
properties: oldProps,
|
|||
|
|
newProperties: newProps
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
|
|||
|
|
|
|||
|
|
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|||
|
|
|
|||
|
|
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|||
|
|
var TextTransforms = {
|
|||
|
|
/**
|
|||
|
|
* Delete content in the editor.
|
|||
|
|
*/
|
|||
|
|
"delete": function _delete(editor) {
|
|||
|
|
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|||
|
|
Editor.withoutNormalizing(editor, function () {
|
|||
|
|
var _options$reverse = options.reverse,
|
|||
|
|
reverse = _options$reverse === void 0 ? false : _options$reverse,
|
|||
|
|
_options$unit = options.unit,
|
|||
|
|
unit = _options$unit === void 0 ? 'character' : _options$unit,
|
|||
|
|
_options$distance = options.distance,
|
|||
|
|
distance = _options$distance === void 0 ? 1 : _options$distance,
|
|||
|
|
_options$voids = options.voids,
|
|||
|
|
voids = _options$voids === void 0 ? false : _options$voids;
|
|||
|
|
var _options$at = options.at,
|
|||
|
|
at = _options$at === void 0 ? editor.selection : _options$at,
|
|||
|
|
_options$hanging = options.hanging,
|
|||
|
|
hanging = _options$hanging === void 0 ? false : _options$hanging;
|
|||
|
|
|
|||
|
|
if (!at) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (Range.isRange(at) && Range.isCollapsed(at)) {
|
|||
|
|
at = at.anchor;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (Point.isPoint(at)) {
|
|||
|
|
var furthestVoid = Editor["void"](editor, {
|
|||
|
|
at: at,
|
|||
|
|
mode: 'highest'
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
if (!voids && furthestVoid) {
|
|||
|
|
var _furthestVoid = _slicedToArray(furthestVoid, 2),
|
|||
|
|
voidPath = _furthestVoid[1];
|
|||
|
|
|
|||
|
|
at = voidPath;
|
|||
|
|
} else {
|
|||
|
|
var opts = {
|
|||
|
|
unit: unit,
|
|||
|
|
distance: distance
|
|||
|
|
};
|
|||
|
|
var target = reverse ? Editor.before(editor, at, opts) || Editor.start(editor, []) : Editor.after(editor, at, opts) || Editor.end(editor, []);
|
|||
|
|
at = {
|
|||
|
|
anchor: at,
|
|||
|
|
focus: target
|
|||
|
|
};
|
|||
|
|
hanging = true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (Path.isPath(at)) {
|
|||
|
|
Transforms.removeNodes(editor, {
|
|||
|
|
at: at,
|
|||
|
|
voids: voids
|
|||
|
|
});
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (Range.isCollapsed(at)) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!hanging) {
|
|||
|
|
var _Range$edges = Range.edges(at),
|
|||
|
|
_Range$edges2 = _slicedToArray(_Range$edges, 2),
|
|||
|
|
_end = _Range$edges2[1];
|
|||
|
|
|
|||
|
|
var endOfDoc = Editor.end(editor, []);
|
|||
|
|
|
|||
|
|
if (!Point.equals(_end, endOfDoc)) {
|
|||
|
|
at = Editor.unhangRange(editor, at, {
|
|||
|
|
voids: voids
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var _Range$edges3 = Range.edges(at),
|
|||
|
|
_Range$edges4 = _slicedToArray(_Range$edges3, 2),
|
|||
|
|
start = _Range$edges4[0],
|
|||
|
|
end = _Range$edges4[1];
|
|||
|
|
|
|||
|
|
var startBlock = Editor.above(editor, {
|
|||
|
|
match: function match(n) {
|
|||
|
|
return Editor.isBlock(editor, n);
|
|||
|
|
},
|
|||
|
|
at: start,
|
|||
|
|
voids: voids
|
|||
|
|
});
|
|||
|
|
var endBlock = Editor.above(editor, {
|
|||
|
|
match: function match(n) {
|
|||
|
|
return Editor.isBlock(editor, n);
|
|||
|
|
},
|
|||
|
|
at: end,
|
|||
|
|
voids: voids
|
|||
|
|
});
|
|||
|
|
var isAcrossBlocks = startBlock && endBlock && !Path.equals(startBlock[1], endBlock[1]);
|
|||
|
|
var isSingleText = Path.equals(start.path, end.path);
|
|||
|
|
var startVoid = voids ? null : Editor["void"](editor, {
|
|||
|
|
at: start,
|
|||
|
|
mode: 'highest'
|
|||
|
|
});
|
|||
|
|
var endVoid = voids ? null : Editor["void"](editor, {
|
|||
|
|
at: end,
|
|||
|
|
mode: 'highest'
|
|||
|
|
}); // If the start or end points are inside an inline void, nudge them out.
|
|||
|
|
|
|||
|
|
if (startVoid) {
|
|||
|
|
var before = Editor.before(editor, start);
|
|||
|
|
|
|||
|
|
if (before && startBlock && Path.isAncestor(startBlock[1], before.path)) {
|
|||
|
|
start = before;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (endVoid) {
|
|||
|
|
var after = Editor.after(editor, end);
|
|||
|
|
|
|||
|
|
if (after && endBlock && Path.isAncestor(endBlock[1], after.path)) {
|
|||
|
|
end = after;
|
|||
|
|
}
|
|||
|
|
} // Get the highest nodes that are completely inside the range, as well as
|
|||
|
|
// the start and end nodes.
|
|||
|
|
|
|||
|
|
|
|||
|
|
var matches = [];
|
|||
|
|
var lastPath;
|
|||
|
|
|
|||
|
|
var _iterator = _createForOfIteratorHelper(Editor.nodes(editor, {
|
|||
|
|
at: at,
|
|||
|
|
voids: voids
|
|||
|
|
})),
|
|||
|
|
_step;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|||
|
|
var entry = _step.value;
|
|||
|
|
|
|||
|
|
var _entry = _slicedToArray(entry, 2),
|
|||
|
|
_node2 = _entry[0],
|
|||
|
|
_path3 = _entry[1];
|
|||
|
|
|
|||
|
|
if (lastPath && Path.compare(_path3, lastPath) === 0) {
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!voids && Editor.isVoid(editor, _node2) || !Path.isCommon(_path3, start.path) && !Path.isCommon(_path3, end.path)) {
|
|||
|
|
matches.push(entry);
|
|||
|
|
lastPath = _path3;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
} catch (err) {
|
|||
|
|
_iterator.e(err);
|
|||
|
|
} finally {
|
|||
|
|
_iterator.f();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var pathRefs = Array.from(matches, function (_ref) {
|
|||
|
|
var _ref2 = _slicedToArray(_ref, 2),
|
|||
|
|
p = _ref2[1];
|
|||
|
|
|
|||
|
|
return Editor.pathRef(editor, p);
|
|||
|
|
});
|
|||
|
|
var startRef = Editor.pointRef(editor, start);
|
|||
|
|
var endRef = Editor.pointRef(editor, end);
|
|||
|
|
|
|||
|
|
if (!isSingleText && !startVoid) {
|
|||
|
|
var _point = startRef.current;
|
|||
|
|
|
|||
|
|
var _Editor$leaf = Editor.leaf(editor, _point),
|
|||
|
|
_Editor$leaf2 = _slicedToArray(_Editor$leaf, 1),
|
|||
|
|
node = _Editor$leaf2[0];
|
|||
|
|
|
|||
|
|
var path = _point.path;
|
|||
|
|
var _start = start,
|
|||
|
|
offset = _start.offset;
|
|||
|
|
var text = node.text.slice(offset);
|
|||
|
|
if (text.length > 0) editor.apply({
|
|||
|
|
type: 'remove_text',
|
|||
|
|
path: path,
|
|||
|
|
offset: offset,
|
|||
|
|
text: text
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
for (var _i = 0, _pathRefs = pathRefs; _i < _pathRefs.length; _i++) {
|
|||
|
|
var pathRef = _pathRefs[_i];
|
|||
|
|
|
|||
|
|
var _path = pathRef.unref();
|
|||
|
|
|
|||
|
|
Transforms.removeNodes(editor, {
|
|||
|
|
at: _path,
|
|||
|
|
voids: voids
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!endVoid) {
|
|||
|
|
var _point2 = endRef.current;
|
|||
|
|
|
|||
|
|
var _Editor$leaf3 = Editor.leaf(editor, _point2),
|
|||
|
|
_Editor$leaf4 = _slicedToArray(_Editor$leaf3, 1),
|
|||
|
|
_node = _Editor$leaf4[0];
|
|||
|
|
|
|||
|
|
var _path2 = _point2.path;
|
|||
|
|
|
|||
|
|
var _offset = isSingleText ? start.offset : 0;
|
|||
|
|
|
|||
|
|
var _text = _node.text.slice(_offset, end.offset);
|
|||
|
|
|
|||
|
|
if (_text.length > 0) editor.apply({
|
|||
|
|
type: 'remove_text',
|
|||
|
|
path: _path2,
|
|||
|
|
offset: _offset,
|
|||
|
|
text: _text
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!isSingleText && isAcrossBlocks && endRef.current && startRef.current) {
|
|||
|
|
Transforms.mergeNodes(editor, {
|
|||
|
|
at: endRef.current,
|
|||
|
|
hanging: true,
|
|||
|
|
voids: voids
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var point = reverse ? startRef.unref() || endRef.unref() : endRef.unref() || startRef.unref();
|
|||
|
|
|
|||
|
|
if (options.at == null && point) {
|
|||
|
|
Transforms.select(editor, point);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Insert a fragment at a specific location in the editor.
|
|||
|
|
*/
|
|||
|
|
insertFragment: function insertFragment(editor, fragment) {
|
|||
|
|
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|||
|
|
Editor.withoutNormalizing(editor, function () {
|
|||
|
|
var _options$hanging2 = options.hanging,
|
|||
|
|
hanging = _options$hanging2 === void 0 ? false : _options$hanging2,
|
|||
|
|
_options$voids2 = options.voids,
|
|||
|
|
voids = _options$voids2 === void 0 ? false : _options$voids2;
|
|||
|
|
var _options$at2 = options.at,
|
|||
|
|
at = _options$at2 === void 0 ? editor.selection : _options$at2;
|
|||
|
|
|
|||
|
|
if (!fragment.length) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!at) {
|
|||
|
|
return;
|
|||
|
|
} else if (Range.isRange(at)) {
|
|||
|
|
if (!hanging) {
|
|||
|
|
at = Editor.unhangRange(editor, at);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (Range.isCollapsed(at)) {
|
|||
|
|
at = at.anchor;
|
|||
|
|
} else {
|
|||
|
|
var _Range$edges5 = Range.edges(at),
|
|||
|
|
_Range$edges6 = _slicedToArray(_Range$edges5, 2),
|
|||
|
|
end = _Range$edges6[1];
|
|||
|
|
|
|||
|
|
if (!voids && Editor["void"](editor, {
|
|||
|
|
at: end
|
|||
|
|
})) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var pointRef = Editor.pointRef(editor, end);
|
|||
|
|
Transforms["delete"](editor, {
|
|||
|
|
at: at
|
|||
|
|
});
|
|||
|
|
at = pointRef.unref();
|
|||
|
|
}
|
|||
|
|
} else if (Path.isPath(at)) {
|
|||
|
|
at = Editor.start(editor, at);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!voids && Editor["void"](editor, {
|
|||
|
|
at: at
|
|||
|
|
})) {
|
|||
|
|
return;
|
|||
|
|
} // If the insert point is at the edge of an inline node, move it outside
|
|||
|
|
// instead since it will need to be split otherwise.
|
|||
|
|
|
|||
|
|
|
|||
|
|
var inlineElementMatch = Editor.above(editor, {
|
|||
|
|
at: at,
|
|||
|
|
match: function match(n) {
|
|||
|
|
return Editor.isInline(editor, n);
|
|||
|
|
},
|
|||
|
|
mode: 'highest',
|
|||
|
|
voids: voids
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
if (inlineElementMatch) {
|
|||
|
|
var _inlineElementMatch = _slicedToArray(inlineElementMatch, 2),
|
|||
|
|
_inlinePath = _inlineElementMatch[1];
|
|||
|
|
|
|||
|
|
if (Editor.isEnd(editor, at, _inlinePath)) {
|
|||
|
|
var after = Editor.after(editor, _inlinePath);
|
|||
|
|
at = after;
|
|||
|
|
} else if (Editor.isStart(editor, at, _inlinePath)) {
|
|||
|
|
var before = Editor.before(editor, _inlinePath);
|
|||
|
|
at = before;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var blockMatch = Editor.above(editor, {
|
|||
|
|
match: function match(n) {
|
|||
|
|
return Editor.isBlock(editor, n);
|
|||
|
|
},
|
|||
|
|
at: at,
|
|||
|
|
voids: voids
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
var _blockMatch = _slicedToArray(blockMatch, 2),
|
|||
|
|
blockPath = _blockMatch[1];
|
|||
|
|
|
|||
|
|
var isBlockStart = Editor.isStart(editor, at, blockPath);
|
|||
|
|
var isBlockEnd = Editor.isEnd(editor, at, blockPath);
|
|||
|
|
var isBlockEmpty = isBlockStart && isBlockEnd;
|
|||
|
|
var mergeStart = !isBlockStart || isBlockStart && isBlockEnd;
|
|||
|
|
var mergeEnd = !isBlockEnd;
|
|||
|
|
|
|||
|
|
var _Node$first = Node$1.first({
|
|||
|
|
children: fragment
|
|||
|
|
}, []),
|
|||
|
|
_Node$first2 = _slicedToArray(_Node$first, 2),
|
|||
|
|
firstPath = _Node$first2[1];
|
|||
|
|
|
|||
|
|
var _Node$last = Node$1.last({
|
|||
|
|
children: fragment
|
|||
|
|
}, []),
|
|||
|
|
_Node$last2 = _slicedToArray(_Node$last, 2),
|
|||
|
|
lastPath = _Node$last2[1];
|
|||
|
|
|
|||
|
|
var matches = [];
|
|||
|
|
|
|||
|
|
var matcher = function matcher(_ref3) {
|
|||
|
|
var _ref4 = _slicedToArray(_ref3, 2),
|
|||
|
|
n = _ref4[0],
|
|||
|
|
p = _ref4[1];
|
|||
|
|
|
|||
|
|
var isRoot = p.length === 0;
|
|||
|
|
|
|||
|
|
if (isRoot) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (isBlockEmpty) {
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (mergeStart && Path.isAncestor(p, firstPath) && Element$1.isElement(n) && !editor.isVoid(n) && !editor.isInline(n)) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (mergeEnd && Path.isAncestor(p, lastPath) && Element$1.isElement(n) && !editor.isVoid(n) && !editor.isInline(n)) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var _iterator2 = _createForOfIteratorHelper(Node$1.nodes({
|
|||
|
|
children: fragment
|
|||
|
|
}, {
|
|||
|
|
pass: matcher
|
|||
|
|
})),
|
|||
|
|
_step2;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|||
|
|
var entry = _step2.value;
|
|||
|
|
|
|||
|
|
if (matcher(entry)) {
|
|||
|
|
matches.push(entry);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
} catch (err) {
|
|||
|
|
_iterator2.e(err);
|
|||
|
|
} finally {
|
|||
|
|
_iterator2.f();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var starts = [];
|
|||
|
|
var middles = [];
|
|||
|
|
var ends = [];
|
|||
|
|
var starting = true;
|
|||
|
|
var hasBlocks = false;
|
|||
|
|
|
|||
|
|
for (var _i2 = 0, _matches = matches; _i2 < _matches.length; _i2++) {
|
|||
|
|
var _matches$_i = _slicedToArray(_matches[_i2], 1),
|
|||
|
|
node = _matches$_i[0];
|
|||
|
|
|
|||
|
|
if (Element$1.isElement(node) && !editor.isInline(node)) {
|
|||
|
|
starting = false;
|
|||
|
|
hasBlocks = true;
|
|||
|
|
middles.push(node);
|
|||
|
|
} else if (starting) {
|
|||
|
|
starts.push(node);
|
|||
|
|
} else {
|
|||
|
|
ends.push(node);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var _Editor$nodes = Editor.nodes(editor, {
|
|||
|
|
at: at,
|
|||
|
|
match: function match(n) {
|
|||
|
|
return Text.isText(n) || Editor.isInline(editor, n);
|
|||
|
|
},
|
|||
|
|
mode: 'highest',
|
|||
|
|
voids: voids
|
|||
|
|
}),
|
|||
|
|
_Editor$nodes2 = _slicedToArray(_Editor$nodes, 1),
|
|||
|
|
inlineMatch = _Editor$nodes2[0];
|
|||
|
|
|
|||
|
|
var _inlineMatch = _slicedToArray(inlineMatch, 2),
|
|||
|
|
inlinePath = _inlineMatch[1];
|
|||
|
|
|
|||
|
|
var isInlineStart = Editor.isStart(editor, at, inlinePath);
|
|||
|
|
var isInlineEnd = Editor.isEnd(editor, at, inlinePath);
|
|||
|
|
var middleRef = Editor.pathRef(editor, isBlockEnd ? Path.next(blockPath) : blockPath);
|
|||
|
|
var endRef = Editor.pathRef(editor, isInlineEnd ? Path.next(inlinePath) : inlinePath);
|
|||
|
|
var blockPathRef = Editor.pathRef(editor, blockPath);
|
|||
|
|
Transforms.splitNodes(editor, {
|
|||
|
|
at: at,
|
|||
|
|
match: function match(n) {
|
|||
|
|
return hasBlocks ? Editor.isBlock(editor, n) : Text.isText(n) || Editor.isInline(editor, n);
|
|||
|
|
},
|
|||
|
|
mode: hasBlocks ? 'lowest' : 'highest',
|
|||
|
|
voids: voids
|
|||
|
|
});
|
|||
|
|
var startRef = Editor.pathRef(editor, !isInlineStart || isInlineStart && isInlineEnd ? Path.next(inlinePath) : inlinePath);
|
|||
|
|
Transforms.insertNodes(editor, starts, {
|
|||
|
|
at: startRef.current,
|
|||
|
|
match: function match(n) {
|
|||
|
|
return Text.isText(n) || Editor.isInline(editor, n);
|
|||
|
|
},
|
|||
|
|
mode: 'highest',
|
|||
|
|
voids: voids
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
if (isBlockEmpty && middles.length) {
|
|||
|
|
Transforms["delete"](editor, {
|
|||
|
|
at: blockPathRef.unref(),
|
|||
|
|
voids: voids
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Transforms.insertNodes(editor, middles, {
|
|||
|
|
at: middleRef.current,
|
|||
|
|
match: function match(n) {
|
|||
|
|
return Editor.isBlock(editor, n);
|
|||
|
|
},
|
|||
|
|
mode: 'lowest',
|
|||
|
|
voids: voids
|
|||
|
|
});
|
|||
|
|
Transforms.insertNodes(editor, ends, {
|
|||
|
|
at: endRef.current,
|
|||
|
|
match: function match(n) {
|
|||
|
|
return Text.isText(n) || Editor.isInline(editor, n);
|
|||
|
|
},
|
|||
|
|
mode: 'highest',
|
|||
|
|
voids: voids
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
if (!options.at) {
|
|||
|
|
var path;
|
|||
|
|
|
|||
|
|
if (ends.length > 0) {
|
|||
|
|
path = Path.previous(endRef.current);
|
|||
|
|
} else if (middles.length > 0) {
|
|||
|
|
path = Path.previous(middleRef.current);
|
|||
|
|
} else {
|
|||
|
|
path = Path.previous(startRef.current);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var _end2 = Editor.end(editor, path);
|
|||
|
|
|
|||
|
|
Transforms.select(editor, _end2);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
startRef.unref();
|
|||
|
|
middleRef.unref();
|
|||
|
|
endRef.unref();
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Insert a string of text in the Editor.
|
|||
|
|
*/
|
|||
|
|
insertText: function insertText(editor, text) {
|
|||
|
|
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|||
|
|
Editor.withoutNormalizing(editor, function () {
|
|||
|
|
var _options$voids3 = options.voids,
|
|||
|
|
voids = _options$voids3 === void 0 ? false : _options$voids3;
|
|||
|
|
var _options$at3 = options.at,
|
|||
|
|
at = _options$at3 === void 0 ? editor.selection : _options$at3;
|
|||
|
|
|
|||
|
|
if (!at) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (Path.isPath(at)) {
|
|||
|
|
at = Editor.range(editor, at);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (Range.isRange(at)) {
|
|||
|
|
if (Range.isCollapsed(at)) {
|
|||
|
|
at = at.anchor;
|
|||
|
|
} else {
|
|||
|
|
var end = Range.end(at);
|
|||
|
|
|
|||
|
|
if (!voids && Editor["void"](editor, {
|
|||
|
|
at: end
|
|||
|
|
})) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var pointRef = Editor.pointRef(editor, end);
|
|||
|
|
Transforms["delete"](editor, {
|
|||
|
|
at: at,
|
|||
|
|
voids: voids
|
|||
|
|
});
|
|||
|
|
at = pointRef.unref();
|
|||
|
|
Transforms.setSelection(editor, {
|
|||
|
|
anchor: at,
|
|||
|
|
focus: at
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!voids && Editor["void"](editor, {
|
|||
|
|
at: at
|
|||
|
|
})) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var _at = at,
|
|||
|
|
path = _at.path,
|
|||
|
|
offset = _at.offset;
|
|||
|
|
if (text.length > 0) editor.apply({
|
|||
|
|
type: 'insert_text',
|
|||
|
|
path: path,
|
|||
|
|
offset: offset,
|
|||
|
|
text: text
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
|
|||
|
|
|
|||
|
|
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
|||
|
|
var Transforms = _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, GeneralTransforms), NodeTransforms), SelectionTransforms), TextTransforms);
|
|||
|
|
|
|||
|
|
var Editor_1 = Editor;
|
|||
|
|
var Element_1 = Element$1;
|
|||
|
|
var Location_1 = Location;
|
|||
|
|
var Node_1 = Node$1;
|
|||
|
|
var Operation_1 = Operation;
|
|||
|
|
var Path_1 = Path;
|
|||
|
|
var PathRef_1 = PathRef;
|
|||
|
|
var Point_1 = Point;
|
|||
|
|
var PointRef_1 = PointRef;
|
|||
|
|
var Range_1 = Range;
|
|||
|
|
var RangeRef_1 = RangeRef;
|
|||
|
|
var Span_1 = Span;
|
|||
|
|
var Text_1 = Text;
|
|||
|
|
var Transforms_1 = Transforms;
|
|||
|
|
var createEditor_1 = createEditor$1;
|
|||
|
|
|
|||
|
|
|
|||
|
|
var dist$7 = /*#__PURE__*/Object.defineProperty({
|
|||
|
|
Editor: Editor_1,
|
|||
|
|
Element: Element_1,
|
|||
|
|
Location: Location_1,
|
|||
|
|
Node: Node_1,
|
|||
|
|
Operation: Operation_1,
|
|||
|
|
Path: Path_1,
|
|||
|
|
PathRef: PathRef_1,
|
|||
|
|
Point: Point_1,
|
|||
|
|
PointRef: PointRef_1,
|
|||
|
|
Range: Range_1,
|
|||
|
|
RangeRef: RangeRef_1,
|
|||
|
|
Span: Span_1,
|
|||
|
|
Text: Text_1,
|
|||
|
|
Transforms: Transforms_1,
|
|||
|
|
createEditor: createEditor_1
|
|||
|
|
}, '__esModule', {value: true});
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* lodash (Custom Build) <https://lodash.com/>
|
|||
|
|
* Build: `lodash modularize exports="npm" -o ./`
|
|||
|
|
* Copyright jQuery Foundation and other contributors <https://jquery.org/>
|
|||
|
|
* Released under MIT license <https://lodash.com/license>
|
|||
|
|
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
|
|||
|
|
* Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
/** Used as references for various `Number` constants. */
|
|||
|
|
var MAX_SAFE_INTEGER$1 = 9007199254740991;
|
|||
|
|
|
|||
|
|
/** `Object#toString` result references. */
|
|||
|
|
var argsTag$1 = '[object Arguments]',
|
|||
|
|
funcTag$1 = '[object Function]',
|
|||
|
|
genTag$1 = '[object GeneratorFunction]',
|
|||
|
|
mapTag = '[object Map]',
|
|||
|
|
objectTag = '[object Object]',
|
|||
|
|
promiseTag = '[object Promise]',
|
|||
|
|
setTag = '[object Set]',
|
|||
|
|
stringTag = '[object String]',
|
|||
|
|
weakMapTag = '[object WeakMap]';
|
|||
|
|
|
|||
|
|
var dataViewTag = '[object DataView]';
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Used to match `RegExp`
|
|||
|
|
* [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
|
|||
|
|
*/
|
|||
|
|
var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
|
|||
|
|
|
|||
|
|
/** Used to detect host constructors (Safari). */
|
|||
|
|
var reIsHostCtor = /^\[object .+?Constructor\]$/;
|
|||
|
|
|
|||
|
|
/** Used to detect unsigned integer values. */
|
|||
|
|
var reIsUint$1 = /^(?:0|[1-9]\d*)$/;
|
|||
|
|
|
|||
|
|
/** Used to compose unicode character classes. */
|
|||
|
|
var rsAstralRange$1 = '\\ud800-\\udfff',
|
|||
|
|
rsComboMarksRange$1 = '\\u0300-\\u036f\\ufe20-\\ufe23',
|
|||
|
|
rsComboSymbolsRange$1 = '\\u20d0-\\u20f0',
|
|||
|
|
rsVarRange$1 = '\\ufe0e\\ufe0f';
|
|||
|
|
|
|||
|
|
/** Used to compose unicode capture groups. */
|
|||
|
|
var rsAstral$1 = '[' + rsAstralRange$1 + ']',
|
|||
|
|
rsCombo$1 = '[' + rsComboMarksRange$1 + rsComboSymbolsRange$1 + ']',
|
|||
|
|
rsFitz$1 = '\\ud83c[\\udffb-\\udfff]',
|
|||
|
|
rsModifier$1 = '(?:' + rsCombo$1 + '|' + rsFitz$1 + ')',
|
|||
|
|
rsNonAstral$1 = '[^' + rsAstralRange$1 + ']',
|
|||
|
|
rsRegional$1 = '(?:\\ud83c[\\udde6-\\uddff]){2}',
|
|||
|
|
rsSurrPair$1 = '[\\ud800-\\udbff][\\udc00-\\udfff]',
|
|||
|
|
rsZWJ$1 = '\\u200d';
|
|||
|
|
|
|||
|
|
/** Used to compose unicode regexes. */
|
|||
|
|
var reOptMod$1 = rsModifier$1 + '?',
|
|||
|
|
rsOptVar$1 = '[' + rsVarRange$1 + ']?',
|
|||
|
|
rsOptJoin$1 = '(?:' + rsZWJ$1 + '(?:' + [rsNonAstral$1, rsRegional$1, rsSurrPair$1].join('|') + ')' + rsOptVar$1 + reOptMod$1 + ')*',
|
|||
|
|
rsSeq$1 = rsOptVar$1 + reOptMod$1 + rsOptJoin$1,
|
|||
|
|
rsSymbol$1 = '(?:' + [rsNonAstral$1 + rsCombo$1 + '?', rsCombo$1, rsRegional$1, rsSurrPair$1, rsAstral$1].join('|') + ')';
|
|||
|
|
|
|||
|
|
/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
|
|||
|
|
var reUnicode$1 = RegExp(rsFitz$1 + '(?=' + rsFitz$1 + ')|' + rsSymbol$1 + rsSeq$1, 'g');
|
|||
|
|
|
|||
|
|
/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */
|
|||
|
|
var reHasUnicode$1 = RegExp('[' + rsZWJ$1 + rsAstralRange$1 + rsComboMarksRange$1 + rsComboSymbolsRange$1 + rsVarRange$1 + ']');
|
|||
|
|
|
|||
|
|
/** Detect free variable `global` from Node.js. */
|
|||
|
|
var freeGlobal$3 = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;
|
|||
|
|
|
|||
|
|
/** Detect free variable `self`. */
|
|||
|
|
var freeSelf$3 = typeof self == 'object' && self && self.Object === Object && self;
|
|||
|
|
|
|||
|
|
/** Used as a reference to the global object. */
|
|||
|
|
var root$3 = freeGlobal$3 || freeSelf$3 || Function('return this')();
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* A specialized version of `_.map` for arrays without support for iteratee
|
|||
|
|
* shorthands.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Array} [array] The array to iterate over.
|
|||
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|||
|
|
* @returns {Array} Returns the new mapped array.
|
|||
|
|
*/
|
|||
|
|
function arrayMap(array, iteratee) {
|
|||
|
|
var index = -1,
|
|||
|
|
length = array ? array.length : 0,
|
|||
|
|
result = Array(length);
|
|||
|
|
|
|||
|
|
while (++index < length) {
|
|||
|
|
result[index] = iteratee(array[index], index, array);
|
|||
|
|
}
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Converts an ASCII `string` to an array.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {string} string The string to convert.
|
|||
|
|
* @returns {Array} Returns the converted array.
|
|||
|
|
*/
|
|||
|
|
function asciiToArray$1(string) {
|
|||
|
|
return string.split('');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* The base implementation of `_.times` without support for iteratee shorthands
|
|||
|
|
* or max array length checks.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {number} n The number of times to invoke `iteratee`.
|
|||
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|||
|
|
* @returns {Array} Returns the array of results.
|
|||
|
|
*/
|
|||
|
|
function baseTimes$1(n, iteratee) {
|
|||
|
|
var index = -1,
|
|||
|
|
result = Array(n);
|
|||
|
|
|
|||
|
|
while (++index < n) {
|
|||
|
|
result[index] = iteratee(index);
|
|||
|
|
}
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* The base implementation of `_.values` and `_.valuesIn` which creates an
|
|||
|
|
* array of `object` property values corresponding to the property names
|
|||
|
|
* of `props`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Object} object The object to query.
|
|||
|
|
* @param {Array} props The property names to get values for.
|
|||
|
|
* @returns {Object} Returns the array of property values.
|
|||
|
|
*/
|
|||
|
|
function baseValues(object, props) {
|
|||
|
|
return arrayMap(props, function(key) {
|
|||
|
|
return object[key];
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Gets the value at `key` of `object`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Object} [object] The object to query.
|
|||
|
|
* @param {string} key The key of the property to get.
|
|||
|
|
* @returns {*} Returns the property value.
|
|||
|
|
*/
|
|||
|
|
function getValue(object, key) {
|
|||
|
|
return object == null ? undefined : object[key];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `string` contains Unicode symbols.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {string} string The string to inspect.
|
|||
|
|
* @returns {boolean} Returns `true` if a symbol is found, else `false`.
|
|||
|
|
*/
|
|||
|
|
function hasUnicode$1(string) {
|
|||
|
|
return reHasUnicode$1.test(string);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is a host object in IE < 9.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is a host object, else `false`.
|
|||
|
|
*/
|
|||
|
|
function isHostObject(value) {
|
|||
|
|
// Many host objects are `Object` objects that can coerce to strings
|
|||
|
|
// despite having improperly defined `toString` methods.
|
|||
|
|
var result = false;
|
|||
|
|
if (value != null && typeof value.toString != 'function') {
|
|||
|
|
try {
|
|||
|
|
result = !!(value + '');
|
|||
|
|
} catch (e) {}
|
|||
|
|
}
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Converts `iterator` to an array.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Object} iterator The iterator to convert.
|
|||
|
|
* @returns {Array} Returns the converted array.
|
|||
|
|
*/
|
|||
|
|
function iteratorToArray(iterator) {
|
|||
|
|
var data,
|
|||
|
|
result = [];
|
|||
|
|
|
|||
|
|
while (!(data = iterator.next()).done) {
|
|||
|
|
result.push(data.value);
|
|||
|
|
}
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Converts `map` to its key-value pairs.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Object} map The map to convert.
|
|||
|
|
* @returns {Array} Returns the key-value pairs.
|
|||
|
|
*/
|
|||
|
|
function mapToArray(map) {
|
|||
|
|
var index = -1,
|
|||
|
|
result = Array(map.size);
|
|||
|
|
|
|||
|
|
map.forEach(function(value, key) {
|
|||
|
|
result[++index] = [key, value];
|
|||
|
|
});
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Creates a unary function that invokes `func` with its argument transformed.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Function} func The function to wrap.
|
|||
|
|
* @param {Function} transform The argument transform.
|
|||
|
|
* @returns {Function} Returns the new function.
|
|||
|
|
*/
|
|||
|
|
function overArg$1(func, transform) {
|
|||
|
|
return function(arg) {
|
|||
|
|
return func(transform(arg));
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Converts `set` to an array of its values.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Object} set The set to convert.
|
|||
|
|
* @returns {Array} Returns the values.
|
|||
|
|
*/
|
|||
|
|
function setToArray(set) {
|
|||
|
|
var index = -1,
|
|||
|
|
result = Array(set.size);
|
|||
|
|
|
|||
|
|
set.forEach(function(value) {
|
|||
|
|
result[++index] = value;
|
|||
|
|
});
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Converts `string` to an array.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {string} string The string to convert.
|
|||
|
|
* @returns {Array} Returns the converted array.
|
|||
|
|
*/
|
|||
|
|
function stringToArray$1(string) {
|
|||
|
|
return hasUnicode$1(string)
|
|||
|
|
? unicodeToArray$1(string)
|
|||
|
|
: asciiToArray$1(string);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Converts a Unicode `string` to an array.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {string} string The string to convert.
|
|||
|
|
* @returns {Array} Returns the converted array.
|
|||
|
|
*/
|
|||
|
|
function unicodeToArray$1(string) {
|
|||
|
|
return string.match(reUnicode$1) || [];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/** Used for built-in method references. */
|
|||
|
|
var funcProto = Function.prototype,
|
|||
|
|
objectProto$4 = Object.prototype;
|
|||
|
|
|
|||
|
|
/** Used to detect overreaching core-js shims. */
|
|||
|
|
var coreJsData = root$3['__core-js_shared__'];
|
|||
|
|
|
|||
|
|
/** Used to detect methods masquerading as native. */
|
|||
|
|
var maskSrcKey = (function() {
|
|||
|
|
var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
|
|||
|
|
return uid ? ('Symbol(src)_1.' + uid) : '';
|
|||
|
|
}());
|
|||
|
|
|
|||
|
|
/** Used to resolve the decompiled source of functions. */
|
|||
|
|
var funcToString = funcProto.toString;
|
|||
|
|
|
|||
|
|
/** Used to check objects for own properties. */
|
|||
|
|
var hasOwnProperty$2 = objectProto$4.hasOwnProperty;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Used to resolve the
|
|||
|
|
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
|
|||
|
|
* of values.
|
|||
|
|
*/
|
|||
|
|
var objectToString$4 = objectProto$4.toString;
|
|||
|
|
|
|||
|
|
/** Used to detect if a method is native. */
|
|||
|
|
var reIsNative = RegExp('^' +
|
|||
|
|
funcToString.call(hasOwnProperty$2).replace(reRegExpChar, '\\$&')
|
|||
|
|
.replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
/** Built-in value references. */
|
|||
|
|
var Symbol$2 = root$3.Symbol,
|
|||
|
|
iteratorSymbol = Symbol$2 ? Symbol$2.iterator : undefined,
|
|||
|
|
propertyIsEnumerable$1 = objectProto$4.propertyIsEnumerable;
|
|||
|
|
|
|||
|
|
/* Built-in method references for those with the same name as other `lodash` methods. */
|
|||
|
|
var nativeKeys$1 = overArg$1(Object.keys, Object);
|
|||
|
|
|
|||
|
|
/* Built-in method references that are verified to be native. */
|
|||
|
|
var DataView = getNative(root$3, 'DataView'),
|
|||
|
|
Map$1 = getNative(root$3, 'Map'),
|
|||
|
|
Promise$1 = getNative(root$3, 'Promise'),
|
|||
|
|
Set$1 = getNative(root$3, 'Set'),
|
|||
|
|
WeakMap$1 = getNative(root$3, 'WeakMap');
|
|||
|
|
|
|||
|
|
/** Used to detect maps, sets, and weakmaps. */
|
|||
|
|
var dataViewCtorString = toSource(DataView),
|
|||
|
|
mapCtorString = toSource(Map$1),
|
|||
|
|
promiseCtorString = toSource(Promise$1),
|
|||
|
|
setCtorString = toSource(Set$1),
|
|||
|
|
weakMapCtorString = toSource(WeakMap$1);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Creates an array of the enumerable property names of the array-like `value`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {*} value The value to query.
|
|||
|
|
* @param {boolean} inherited Specify returning inherited property names.
|
|||
|
|
* @returns {Array} Returns the array of property names.
|
|||
|
|
*/
|
|||
|
|
function arrayLikeKeys$1(value, inherited) {
|
|||
|
|
// Safari 8.1 makes `arguments.callee` enumerable in strict mode.
|
|||
|
|
// Safari 9 makes `arguments.length` enumerable in strict mode.
|
|||
|
|
var result = (isArray$1(value) || isArguments$1(value))
|
|||
|
|
? baseTimes$1(value.length, String)
|
|||
|
|
: [];
|
|||
|
|
|
|||
|
|
var length = result.length,
|
|||
|
|
skipIndexes = !!length;
|
|||
|
|
|
|||
|
|
for (var key in value) {
|
|||
|
|
if ((inherited || hasOwnProperty$2.call(value, key)) &&
|
|||
|
|
!(skipIndexes && (key == 'length' || isIndex$1(key, length)))) {
|
|||
|
|
result.push(key);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* The base implementation of `getTag`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {*} value The value to query.
|
|||
|
|
* @returns {string} Returns the `toStringTag`.
|
|||
|
|
*/
|
|||
|
|
function baseGetTag(value) {
|
|||
|
|
return objectToString$4.call(value);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* The base implementation of `_.isNative` without bad shim checks.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is a native function,
|
|||
|
|
* else `false`.
|
|||
|
|
*/
|
|||
|
|
function baseIsNative(value) {
|
|||
|
|
if (!isObject$3(value) || isMasked(value)) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
var pattern = (isFunction$1(value) || isHostObject(value)) ? reIsNative : reIsHostCtor;
|
|||
|
|
return pattern.test(toSource(value));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Object} object The object to query.
|
|||
|
|
* @returns {Array} Returns the array of property names.
|
|||
|
|
*/
|
|||
|
|
function baseKeys$1(object) {
|
|||
|
|
if (!isPrototype$1(object)) {
|
|||
|
|
return nativeKeys$1(object);
|
|||
|
|
}
|
|||
|
|
var result = [];
|
|||
|
|
for (var key in Object(object)) {
|
|||
|
|
if (hasOwnProperty$2.call(object, key) && key != 'constructor') {
|
|||
|
|
result.push(key);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Copies the values of `source` to `array`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Array} source The array to copy values from.
|
|||
|
|
* @param {Array} [array=[]] The array to copy values to.
|
|||
|
|
* @returns {Array} Returns `array`.
|
|||
|
|
*/
|
|||
|
|
function copyArray(source, array) {
|
|||
|
|
var index = -1,
|
|||
|
|
length = source.length;
|
|||
|
|
|
|||
|
|
array || (array = Array(length));
|
|||
|
|
while (++index < length) {
|
|||
|
|
array[index] = source[index];
|
|||
|
|
}
|
|||
|
|
return array;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Gets the native function at `key` of `object`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Object} object The object to query.
|
|||
|
|
* @param {string} key The key of the method to get.
|
|||
|
|
* @returns {*} Returns the function if it's native, else `undefined`.
|
|||
|
|
*/
|
|||
|
|
function getNative(object, key) {
|
|||
|
|
var value = getValue(object, key);
|
|||
|
|
return baseIsNative(value) ? value : undefined;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Gets the `toStringTag` of `value`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {*} value The value to query.
|
|||
|
|
* @returns {string} Returns the `toStringTag`.
|
|||
|
|
*/
|
|||
|
|
var getTag = baseGetTag;
|
|||
|
|
|
|||
|
|
// Fallback for data views, maps, sets, and weak maps in IE 11,
|
|||
|
|
// for data views in Edge < 14, and promises in Node.js.
|
|||
|
|
if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||
|
|||
|
|
(Map$1 && getTag(new Map$1) != mapTag) ||
|
|||
|
|
(Promise$1 && getTag(Promise$1.resolve()) != promiseTag) ||
|
|||
|
|
(Set$1 && getTag(new Set$1) != setTag) ||
|
|||
|
|
(WeakMap$1 && getTag(new WeakMap$1) != weakMapTag)) {
|
|||
|
|
getTag = function(value) {
|
|||
|
|
var result = objectToString$4.call(value),
|
|||
|
|
Ctor = result == objectTag ? value.constructor : undefined,
|
|||
|
|
ctorString = Ctor ? toSource(Ctor) : undefined;
|
|||
|
|
|
|||
|
|
if (ctorString) {
|
|||
|
|
switch (ctorString) {
|
|||
|
|
case dataViewCtorString: return dataViewTag;
|
|||
|
|
case mapCtorString: return mapTag;
|
|||
|
|
case promiseCtorString: return promiseTag;
|
|||
|
|
case setCtorString: return setTag;
|
|||
|
|
case weakMapCtorString: return weakMapTag;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return result;
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is a valid array-like index.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
|
|||
|
|
*/
|
|||
|
|
function isIndex$1(value, length) {
|
|||
|
|
length = length == null ? MAX_SAFE_INTEGER$1 : length;
|
|||
|
|
return !!length &&
|
|||
|
|
(typeof value == 'number' || reIsUint$1.test(value)) &&
|
|||
|
|
(value > -1 && value % 1 == 0 && value < length);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `func` has its source masked.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Function} func The function to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `func` is masked, else `false`.
|
|||
|
|
*/
|
|||
|
|
function isMasked(func) {
|
|||
|
|
return !!maskSrcKey && (maskSrcKey in func);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is likely a prototype object.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
|
|||
|
|
*/
|
|||
|
|
function isPrototype$1(value) {
|
|||
|
|
var Ctor = value && value.constructor,
|
|||
|
|
proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto$4;
|
|||
|
|
|
|||
|
|
return value === proto;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Converts `func` to its source code.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Function} func The function to process.
|
|||
|
|
* @returns {string} Returns the source code.
|
|||
|
|
*/
|
|||
|
|
function toSource(func) {
|
|||
|
|
if (func != null) {
|
|||
|
|
try {
|
|||
|
|
return funcToString.call(func);
|
|||
|
|
} catch (e) {}
|
|||
|
|
try {
|
|||
|
|
return (func + '');
|
|||
|
|
} catch (e) {}
|
|||
|
|
}
|
|||
|
|
return '';
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is likely an `arguments` object.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 0.1.0
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is an `arguments` object,
|
|||
|
|
* else `false`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.isArguments(function() { return arguments; }());
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isArguments([1, 2, 3]);
|
|||
|
|
* // => false
|
|||
|
|
*/
|
|||
|
|
function isArguments$1(value) {
|
|||
|
|
// Safari 8.1 makes `arguments.callee` enumerable in strict mode.
|
|||
|
|
return isArrayLikeObject$1(value) && hasOwnProperty$2.call(value, 'callee') &&
|
|||
|
|
(!propertyIsEnumerable$1.call(value, 'callee') || objectToString$4.call(value) == argsTag$1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is classified as an `Array` object.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 0.1.0
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is an array, else `false`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.isArray([1, 2, 3]);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isArray(document.body.children);
|
|||
|
|
* // => false
|
|||
|
|
*
|
|||
|
|
* _.isArray('abc');
|
|||
|
|
* // => false
|
|||
|
|
*
|
|||
|
|
* _.isArray(_.noop);
|
|||
|
|
* // => false
|
|||
|
|
*/
|
|||
|
|
var isArray$1 = Array.isArray;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is array-like. A value is considered array-like if it's
|
|||
|
|
* not a function and has a `value.length` that's an integer greater than or
|
|||
|
|
* equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 4.0.0
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is array-like, else `false`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.isArrayLike([1, 2, 3]);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isArrayLike(document.body.children);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isArrayLike('abc');
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isArrayLike(_.noop);
|
|||
|
|
* // => false
|
|||
|
|
*/
|
|||
|
|
function isArrayLike$1(value) {
|
|||
|
|
return value != null && isLength$1(value.length) && !isFunction$1(value);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* This method is like `_.isArrayLike` except that it also checks if `value`
|
|||
|
|
* is an object.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 4.0.0
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is an array-like object,
|
|||
|
|
* else `false`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.isArrayLikeObject([1, 2, 3]);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isArrayLikeObject(document.body.children);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isArrayLikeObject('abc');
|
|||
|
|
* // => false
|
|||
|
|
*
|
|||
|
|
* _.isArrayLikeObject(_.noop);
|
|||
|
|
* // => false
|
|||
|
|
*/
|
|||
|
|
function isArrayLikeObject$1(value) {
|
|||
|
|
return isObjectLike$4(value) && isArrayLike$1(value);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is classified as a `Function` object.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 0.1.0
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is a function, else `false`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.isFunction(_);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isFunction(/abc/);
|
|||
|
|
* // => false
|
|||
|
|
*/
|
|||
|
|
function isFunction$1(value) {
|
|||
|
|
// The use of `Object#toString` avoids issues with the `typeof` operator
|
|||
|
|
// in Safari 8-9 which returns 'object' for typed array and other constructors.
|
|||
|
|
var tag = isObject$3(value) ? objectToString$4.call(value) : '';
|
|||
|
|
return tag == funcTag$1 || tag == genTag$1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is a valid array-like length.
|
|||
|
|
*
|
|||
|
|
* **Note:** This method is loosely based on
|
|||
|
|
* [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 4.0.0
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.isLength(3);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isLength(Number.MIN_VALUE);
|
|||
|
|
* // => false
|
|||
|
|
*
|
|||
|
|
* _.isLength(Infinity);
|
|||
|
|
* // => false
|
|||
|
|
*
|
|||
|
|
* _.isLength('3');
|
|||
|
|
* // => false
|
|||
|
|
*/
|
|||
|
|
function isLength$1(value) {
|
|||
|
|
return typeof value == 'number' &&
|
|||
|
|
value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER$1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is the
|
|||
|
|
* [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
|
|||
|
|
* of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 0.1.0
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is an object, else `false`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.isObject({});
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isObject([1, 2, 3]);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isObject(_.noop);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isObject(null);
|
|||
|
|
* // => false
|
|||
|
|
*/
|
|||
|
|
function isObject$3(value) {
|
|||
|
|
var type = typeof value;
|
|||
|
|
return !!value && (type == 'object' || type == 'function');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is object-like. A value is object-like if it's not `null`
|
|||
|
|
* and has a `typeof` result of "object".
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 4.0.0
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.isObjectLike({});
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isObjectLike([1, 2, 3]);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isObjectLike(_.noop);
|
|||
|
|
* // => false
|
|||
|
|
*
|
|||
|
|
* _.isObjectLike(null);
|
|||
|
|
* // => false
|
|||
|
|
*/
|
|||
|
|
function isObjectLike$4(value) {
|
|||
|
|
return !!value && typeof value == 'object';
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is classified as a `String` primitive or object.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @since 0.1.0
|
|||
|
|
* @memberOf _
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is a string, else `false`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.isString('abc');
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isString(1);
|
|||
|
|
* // => false
|
|||
|
|
*/
|
|||
|
|
function isString(value) {
|
|||
|
|
return typeof value == 'string' ||
|
|||
|
|
(!isArray$1(value) && isObjectLike$4(value) && objectToString$4.call(value) == stringTag);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Converts `value` to an array.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @since 0.1.0
|
|||
|
|
* @memberOf _
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to convert.
|
|||
|
|
* @returns {Array} Returns the converted array.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.toArray({ 'a': 1, 'b': 2 });
|
|||
|
|
* // => [1, 2]
|
|||
|
|
*
|
|||
|
|
* _.toArray('abc');
|
|||
|
|
* // => ['a', 'b', 'c']
|
|||
|
|
*
|
|||
|
|
* _.toArray(1);
|
|||
|
|
* // => []
|
|||
|
|
*
|
|||
|
|
* _.toArray(null);
|
|||
|
|
* // => []
|
|||
|
|
*/
|
|||
|
|
function toArray(value) {
|
|||
|
|
if (!value) {
|
|||
|
|
return [];
|
|||
|
|
}
|
|||
|
|
if (isArrayLike$1(value)) {
|
|||
|
|
return isString(value) ? stringToArray$1(value) : copyArray(value);
|
|||
|
|
}
|
|||
|
|
if (iteratorSymbol && value[iteratorSymbol]) {
|
|||
|
|
return iteratorToArray(value[iteratorSymbol]());
|
|||
|
|
}
|
|||
|
|
var tag = getTag(value),
|
|||
|
|
func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values);
|
|||
|
|
|
|||
|
|
return func(value);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Creates an array of the own enumerable property names of `object`.
|
|||
|
|
*
|
|||
|
|
* **Note:** Non-object values are coerced to objects. See the
|
|||
|
|
* [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
|
|||
|
|
* for more details.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @since 0.1.0
|
|||
|
|
* @memberOf _
|
|||
|
|
* @category Object
|
|||
|
|
* @param {Object} object The object to query.
|
|||
|
|
* @returns {Array} Returns the array of property names.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* function Foo() {
|
|||
|
|
* this.a = 1;
|
|||
|
|
* this.b = 2;
|
|||
|
|
* }
|
|||
|
|
*
|
|||
|
|
* Foo.prototype.c = 3;
|
|||
|
|
*
|
|||
|
|
* _.keys(new Foo);
|
|||
|
|
* // => ['a', 'b'] (iteration order is not guaranteed)
|
|||
|
|
*
|
|||
|
|
* _.keys('hi');
|
|||
|
|
* // => ['0', '1']
|
|||
|
|
*/
|
|||
|
|
function keys$1(object) {
|
|||
|
|
return isArrayLike$1(object) ? arrayLikeKeys$1(object) : baseKeys$1(object);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Creates an array of the own enumerable string keyed property values of `object`.
|
|||
|
|
*
|
|||
|
|
* **Note:** Non-object values are coerced to objects.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @since 0.1.0
|
|||
|
|
* @memberOf _
|
|||
|
|
* @category Object
|
|||
|
|
* @param {Object} object The object to query.
|
|||
|
|
* @returns {Array} Returns the array of property values.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* function Foo() {
|
|||
|
|
* this.a = 1;
|
|||
|
|
* this.b = 2;
|
|||
|
|
* }
|
|||
|
|
*
|
|||
|
|
* Foo.prototype.c = 3;
|
|||
|
|
*
|
|||
|
|
* _.values(new Foo);
|
|||
|
|
* // => [1, 2] (iteration order is not guaranteed)
|
|||
|
|
*
|
|||
|
|
* _.values('hi');
|
|||
|
|
* // => ['h', 'i']
|
|||
|
|
*/
|
|||
|
|
function values(object) {
|
|||
|
|
return object ? baseValues(object, keys$1(object)) : [];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var lodash_toarray = toArray;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* SSR Window 3.0.0
|
|||
|
|
* Better handling for window object in SSR environment
|
|||
|
|
* https://github.com/nolimits4web/ssr-window
|
|||
|
|
*
|
|||
|
|
* Copyright 2020, Vladimir Kharlampidi
|
|||
|
|
*
|
|||
|
|
* Licensed under MIT
|
|||
|
|
*
|
|||
|
|
* Released on: November 9, 2020
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
var ssrWindow_umd = createCommonjsModule$1(function (module, exports) {
|
|||
|
|
(function (global, factory) {
|
|||
|
|
factory(exports) ;
|
|||
|
|
}(commonjsGlobal, (function (exports) {
|
|||
|
|
/* eslint-disable no-param-reassign */
|
|||
|
|
function isObject(obj) {
|
|||
|
|
return (obj !== null &&
|
|||
|
|
typeof obj === 'object' &&
|
|||
|
|
'constructor' in obj &&
|
|||
|
|
obj.constructor === Object);
|
|||
|
|
}
|
|||
|
|
function extend(target, src) {
|
|||
|
|
if (target === void 0) { target = {}; }
|
|||
|
|
if (src === void 0) { src = {}; }
|
|||
|
|
Object.keys(src).forEach(function (key) {
|
|||
|
|
if (typeof target[key] === 'undefined')
|
|||
|
|
target[key] = src[key];
|
|||
|
|
else if (isObject(src[key]) &&
|
|||
|
|
isObject(target[key]) &&
|
|||
|
|
Object.keys(src[key]).length > 0) {
|
|||
|
|
extend(target[key], src[key]);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var ssrDocument = {
|
|||
|
|
body: {},
|
|||
|
|
addEventListener: function () { },
|
|||
|
|
removeEventListener: function () { },
|
|||
|
|
activeElement: {
|
|||
|
|
blur: function () { },
|
|||
|
|
nodeName: '',
|
|||
|
|
},
|
|||
|
|
querySelector: function () {
|
|||
|
|
return null;
|
|||
|
|
},
|
|||
|
|
querySelectorAll: function () {
|
|||
|
|
return [];
|
|||
|
|
},
|
|||
|
|
getElementById: function () {
|
|||
|
|
return null;
|
|||
|
|
},
|
|||
|
|
createEvent: function () {
|
|||
|
|
return {
|
|||
|
|
initEvent: function () { },
|
|||
|
|
};
|
|||
|
|
},
|
|||
|
|
createElement: function () {
|
|||
|
|
return {
|
|||
|
|
children: [],
|
|||
|
|
childNodes: [],
|
|||
|
|
style: {},
|
|||
|
|
setAttribute: function () { },
|
|||
|
|
getElementsByTagName: function () {
|
|||
|
|
return [];
|
|||
|
|
},
|
|||
|
|
};
|
|||
|
|
},
|
|||
|
|
createElementNS: function () {
|
|||
|
|
return {};
|
|||
|
|
},
|
|||
|
|
importNode: function () {
|
|||
|
|
return null;
|
|||
|
|
},
|
|||
|
|
location: {
|
|||
|
|
hash: '',
|
|||
|
|
host: '',
|
|||
|
|
hostname: '',
|
|||
|
|
href: '',
|
|||
|
|
origin: '',
|
|||
|
|
pathname: '',
|
|||
|
|
protocol: '',
|
|||
|
|
search: '',
|
|||
|
|
},
|
|||
|
|
};
|
|||
|
|
function getDocument() {
|
|||
|
|
var doc = typeof document !== 'undefined' ? document : {};
|
|||
|
|
extend(doc, ssrDocument);
|
|||
|
|
return doc;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var ssrWindow = {
|
|||
|
|
document: ssrDocument,
|
|||
|
|
navigator: {
|
|||
|
|
userAgent: '',
|
|||
|
|
},
|
|||
|
|
location: {
|
|||
|
|
hash: '',
|
|||
|
|
host: '',
|
|||
|
|
hostname: '',
|
|||
|
|
href: '',
|
|||
|
|
origin: '',
|
|||
|
|
pathname: '',
|
|||
|
|
protocol: '',
|
|||
|
|
search: '',
|
|||
|
|
},
|
|||
|
|
history: {
|
|||
|
|
replaceState: function () { },
|
|||
|
|
pushState: function () { },
|
|||
|
|
go: function () { },
|
|||
|
|
back: function () { },
|
|||
|
|
},
|
|||
|
|
CustomEvent: function CustomEvent() {
|
|||
|
|
return this;
|
|||
|
|
},
|
|||
|
|
addEventListener: function () { },
|
|||
|
|
removeEventListener: function () { },
|
|||
|
|
getComputedStyle: function () {
|
|||
|
|
return {
|
|||
|
|
getPropertyValue: function () {
|
|||
|
|
return '';
|
|||
|
|
},
|
|||
|
|
};
|
|||
|
|
},
|
|||
|
|
Image: function () { },
|
|||
|
|
Date: function () { },
|
|||
|
|
screen: {},
|
|||
|
|
setTimeout: function () { },
|
|||
|
|
clearTimeout: function () { },
|
|||
|
|
matchMedia: function () {
|
|||
|
|
return {};
|
|||
|
|
},
|
|||
|
|
requestAnimationFrame: function (callback) {
|
|||
|
|
if (typeof setTimeout === 'undefined') {
|
|||
|
|
callback();
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
return setTimeout(callback, 0);
|
|||
|
|
},
|
|||
|
|
cancelAnimationFrame: function (id) {
|
|||
|
|
if (typeof setTimeout === 'undefined') {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
clearTimeout(id);
|
|||
|
|
},
|
|||
|
|
};
|
|||
|
|
function getWindow() {
|
|||
|
|
var win = typeof window !== 'undefined' ? window : {};
|
|||
|
|
extend(win, ssrWindow);
|
|||
|
|
return win;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
exports.extend = extend;
|
|||
|
|
exports.getDocument = getDocument;
|
|||
|
|
exports.getWindow = getWindow;
|
|||
|
|
exports.ssrDocument = ssrDocument;
|
|||
|
|
exports.ssrWindow = ssrWindow;
|
|||
|
|
|
|||
|
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|||
|
|
|
|||
|
|
})));
|
|||
|
|
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Dom7 3.0.0
|
|||
|
|
* Minimalistic JavaScript library for DOM manipulation, with a jQuery-compatible API
|
|||
|
|
* https://framework7.io/docs/dom7.html
|
|||
|
|
*
|
|||
|
|
* Copyright 2020, Vladimir Kharlampidi
|
|||
|
|
*
|
|||
|
|
* Licensed under MIT
|
|||
|
|
*
|
|||
|
|
* Released on: November 9, 2020
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
function _inheritsLoose(subClass, superClass) {
|
|||
|
|
subClass.prototype = Object.create(superClass.prototype);
|
|||
|
|
subClass.prototype.constructor = subClass;
|
|||
|
|
subClass.__proto__ = superClass;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function _getPrototypeOf(o) {
|
|||
|
|
_getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
|
|||
|
|
return o.__proto__ || Object.getPrototypeOf(o);
|
|||
|
|
};
|
|||
|
|
return _getPrototypeOf(o);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function _setPrototypeOf(o, p) {
|
|||
|
|
_setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
|
|||
|
|
o.__proto__ = p;
|
|||
|
|
return o;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
return _setPrototypeOf(o, p);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function _isNativeReflectConstruct() {
|
|||
|
|
if (typeof Reflect === "undefined" || !Reflect.construct) return false;
|
|||
|
|
if (Reflect.construct.sham) return false;
|
|||
|
|
if (typeof Proxy === "function") return true;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
Date.prototype.toString.call(Reflect.construct(Date, [], function () {}));
|
|||
|
|
return true;
|
|||
|
|
} catch (e) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function _construct(Parent, args, Class) {
|
|||
|
|
if (_isNativeReflectConstruct()) {
|
|||
|
|
_construct = Reflect.construct;
|
|||
|
|
} else {
|
|||
|
|
_construct = function _construct(Parent, args, Class) {
|
|||
|
|
var a = [null];
|
|||
|
|
a.push.apply(a, args);
|
|||
|
|
var Constructor = Function.bind.apply(Parent, a);
|
|||
|
|
var instance = new Constructor();
|
|||
|
|
if (Class) _setPrototypeOf(instance, Class.prototype);
|
|||
|
|
return instance;
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return _construct.apply(null, arguments);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function _isNativeFunction(fn) {
|
|||
|
|
return Function.toString.call(fn).indexOf("[native code]") !== -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function _wrapNativeSuper(Class) {
|
|||
|
|
var _cache = typeof Map === "function" ? new Map() : undefined;
|
|||
|
|
|
|||
|
|
_wrapNativeSuper = function _wrapNativeSuper(Class) {
|
|||
|
|
if (Class === null || !_isNativeFunction(Class)) return Class;
|
|||
|
|
|
|||
|
|
if (typeof Class !== "function") {
|
|||
|
|
throw new TypeError("Super expression must either be null or a function");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (typeof _cache !== "undefined") {
|
|||
|
|
if (_cache.has(Class)) return _cache.get(Class);
|
|||
|
|
|
|||
|
|
_cache.set(Class, Wrapper);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function Wrapper() {
|
|||
|
|
return _construct(Class, arguments, _getPrototypeOf(this).constructor);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Wrapper.prototype = Object.create(Class.prototype, {
|
|||
|
|
constructor: {
|
|||
|
|
value: Wrapper,
|
|||
|
|
enumerable: false,
|
|||
|
|
writable: true,
|
|||
|
|
configurable: true
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
return _setPrototypeOf(Wrapper, Class);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
return _wrapNativeSuper(Class);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function _assertThisInitialized(self) {
|
|||
|
|
if (self === void 0) {
|
|||
|
|
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return self;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* eslint-disable no-proto */
|
|||
|
|
function makeReactive(obj) {
|
|||
|
|
var proto = obj.__proto__;
|
|||
|
|
Object.defineProperty(obj, '__proto__', {
|
|||
|
|
get: function get() {
|
|||
|
|
return proto;
|
|||
|
|
},
|
|||
|
|
set: function set(value) {
|
|||
|
|
proto.__proto__ = value;
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var Dom7 = /*#__PURE__*/function (_Array) {
|
|||
|
|
_inheritsLoose(Dom7, _Array);
|
|||
|
|
|
|||
|
|
function Dom7(items) {
|
|||
|
|
var _this;
|
|||
|
|
|
|||
|
|
_this = _Array.call.apply(_Array, [this].concat(items)) || this;
|
|||
|
|
makeReactive(_assertThisInitialized(_this));
|
|||
|
|
return _this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return Dom7;
|
|||
|
|
}( /*#__PURE__*/_wrapNativeSuper(Array));
|
|||
|
|
|
|||
|
|
function arrayFlat(arr) {
|
|||
|
|
if (arr === void 0) {
|
|||
|
|
arr = [];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var res = [];
|
|||
|
|
arr.forEach(function (el) {
|
|||
|
|
if (Array.isArray(el)) {
|
|||
|
|
res.push.apply(res, arrayFlat(el));
|
|||
|
|
} else {
|
|||
|
|
res.push(el);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
return res;
|
|||
|
|
}
|
|||
|
|
function arrayFilter(arr, callback) {
|
|||
|
|
return Array.prototype.filter.call(arr, callback);
|
|||
|
|
}
|
|||
|
|
function arrayUnique(arr) {
|
|||
|
|
var uniqueArray = [];
|
|||
|
|
|
|||
|
|
for (var i = 0; i < arr.length; i += 1) {
|
|||
|
|
if (uniqueArray.indexOf(arr[i]) === -1) uniqueArray.push(arr[i]);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return uniqueArray;
|
|||
|
|
}
|
|||
|
|
function toCamelCase(string) {
|
|||
|
|
return string.toLowerCase().replace(/-(.)/g, function (match, group) {
|
|||
|
|
return group.toUpperCase();
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function qsa(selector, context) {
|
|||
|
|
if (typeof selector !== 'string') {
|
|||
|
|
return [selector];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var a = [];
|
|||
|
|
var res = context.querySelectorAll(selector);
|
|||
|
|
|
|||
|
|
for (var i = 0; i < res.length; i += 1) {
|
|||
|
|
a.push(res[i]);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return a;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function $(selector, context) {
|
|||
|
|
var window = ssrWindow_umd.getWindow();
|
|||
|
|
var document = ssrWindow_umd.getDocument();
|
|||
|
|
var arr = [];
|
|||
|
|
|
|||
|
|
if (!context && selector instanceof Dom7) {
|
|||
|
|
return selector;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!selector) {
|
|||
|
|
return new Dom7(arr);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (typeof selector === 'string') {
|
|||
|
|
var html = selector.trim();
|
|||
|
|
|
|||
|
|
if (html.indexOf('<') >= 0 && html.indexOf('>') >= 0) {
|
|||
|
|
var toCreate = 'div';
|
|||
|
|
if (html.indexOf('<li') === 0) toCreate = 'ul';
|
|||
|
|
if (html.indexOf('<tr') === 0) toCreate = 'tbody';
|
|||
|
|
if (html.indexOf('<td') === 0 || html.indexOf('<th') === 0) toCreate = 'tr';
|
|||
|
|
if (html.indexOf('<tbody') === 0) toCreate = 'table';
|
|||
|
|
if (html.indexOf('<option') === 0) toCreate = 'select';
|
|||
|
|
var tempParent = document.createElement(toCreate);
|
|||
|
|
tempParent.innerHTML = html;
|
|||
|
|
|
|||
|
|
for (var i = 0; i < tempParent.childNodes.length; i += 1) {
|
|||
|
|
arr.push(tempParent.childNodes[i]);
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
arr = qsa(selector.trim(), context || document);
|
|||
|
|
} // arr = qsa(selector, document);
|
|||
|
|
|
|||
|
|
} else if (selector.nodeType || selector === window || selector === document) {
|
|||
|
|
arr.push(selector);
|
|||
|
|
} else if (Array.isArray(selector)) {
|
|||
|
|
if (selector instanceof Dom7) return selector;
|
|||
|
|
arr = selector;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return new Dom7(arrayUnique(arr));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
$.fn = Dom7.prototype;
|
|||
|
|
|
|||
|
|
function addClass() {
|
|||
|
|
for (var _len = arguments.length, classes = new Array(_len), _key = 0; _key < _len; _key++) {
|
|||
|
|
classes[_key] = arguments[_key];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var classNames = arrayFlat(classes.map(function (c) {
|
|||
|
|
return c.split(' ');
|
|||
|
|
}));
|
|||
|
|
this.forEach(function (el) {
|
|||
|
|
var _el$classList;
|
|||
|
|
|
|||
|
|
(_el$classList = el.classList).add.apply(_el$classList, classNames);
|
|||
|
|
});
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function removeClass() {
|
|||
|
|
for (var _len2 = arguments.length, classes = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
|||
|
|
classes[_key2] = arguments[_key2];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var classNames = arrayFlat(classes.map(function (c) {
|
|||
|
|
return c.split(' ');
|
|||
|
|
}));
|
|||
|
|
this.forEach(function (el) {
|
|||
|
|
var _el$classList2;
|
|||
|
|
|
|||
|
|
(_el$classList2 = el.classList).remove.apply(_el$classList2, classNames);
|
|||
|
|
});
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function toggleClass() {
|
|||
|
|
for (var _len3 = arguments.length, classes = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
|
|||
|
|
classes[_key3] = arguments[_key3];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var classNames = arrayFlat(classes.map(function (c) {
|
|||
|
|
return c.split(' ');
|
|||
|
|
}));
|
|||
|
|
this.forEach(function (el) {
|
|||
|
|
classNames.forEach(function (className) {
|
|||
|
|
el.classList.toggle(className);
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function hasClass() {
|
|||
|
|
for (var _len4 = arguments.length, classes = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
|
|||
|
|
classes[_key4] = arguments[_key4];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var classNames = arrayFlat(classes.map(function (c) {
|
|||
|
|
return c.split(' ');
|
|||
|
|
}));
|
|||
|
|
return arrayFilter(this, function (el) {
|
|||
|
|
return classNames.filter(function (className) {
|
|||
|
|
return el.classList.contains(className);
|
|||
|
|
}).length > 0;
|
|||
|
|
}).length > 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function attr(attrs, value) {
|
|||
|
|
if (arguments.length === 1 && typeof attrs === 'string') {
|
|||
|
|
// Get attr
|
|||
|
|
if (this[0]) return this[0].getAttribute(attrs);
|
|||
|
|
return undefined;
|
|||
|
|
} // Set attrs
|
|||
|
|
|
|||
|
|
|
|||
|
|
for (var i = 0; i < this.length; i += 1) {
|
|||
|
|
if (arguments.length === 2) {
|
|||
|
|
// String
|
|||
|
|
this[i].setAttribute(attrs, value);
|
|||
|
|
} else {
|
|||
|
|
// Object
|
|||
|
|
for (var attrName in attrs) {
|
|||
|
|
this[i][attrName] = attrs[attrName];
|
|||
|
|
this[i].setAttribute(attrName, attrs[attrName]);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function removeAttr(attr) {
|
|||
|
|
for (var i = 0; i < this.length; i += 1) {
|
|||
|
|
this[i].removeAttribute(attr);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function prop(props, value) {
|
|||
|
|
if (arguments.length === 1 && typeof props === 'string') {
|
|||
|
|
// Get prop
|
|||
|
|
if (this[0]) return this[0][props];
|
|||
|
|
} else {
|
|||
|
|
// Set props
|
|||
|
|
for (var i = 0; i < this.length; i += 1) {
|
|||
|
|
if (arguments.length === 2) {
|
|||
|
|
// String
|
|||
|
|
this[i][props] = value;
|
|||
|
|
} else {
|
|||
|
|
// Object
|
|||
|
|
for (var propName in props) {
|
|||
|
|
this[i][propName] = props[propName];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function data(key, value) {
|
|||
|
|
var el;
|
|||
|
|
|
|||
|
|
if (typeof value === 'undefined') {
|
|||
|
|
el = this[0];
|
|||
|
|
if (!el) return undefined; // Get value
|
|||
|
|
|
|||
|
|
if (el.dom7ElementDataStorage && key in el.dom7ElementDataStorage) {
|
|||
|
|
return el.dom7ElementDataStorage[key];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var dataKey = el.getAttribute("data-" + key);
|
|||
|
|
|
|||
|
|
if (dataKey) {
|
|||
|
|
return dataKey;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return undefined;
|
|||
|
|
} // Set value
|
|||
|
|
|
|||
|
|
|
|||
|
|
for (var i = 0; i < this.length; i += 1) {
|
|||
|
|
el = this[i];
|
|||
|
|
if (!el.dom7ElementDataStorage) el.dom7ElementDataStorage = {};
|
|||
|
|
el.dom7ElementDataStorage[key] = value;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function removeData(key) {
|
|||
|
|
for (var i = 0; i < this.length; i += 1) {
|
|||
|
|
var el = this[i];
|
|||
|
|
|
|||
|
|
if (el.dom7ElementDataStorage && el.dom7ElementDataStorage[key]) {
|
|||
|
|
el.dom7ElementDataStorage[key] = null;
|
|||
|
|
delete el.dom7ElementDataStorage[key];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function dataset() {
|
|||
|
|
var el = this[0];
|
|||
|
|
if (!el) return undefined;
|
|||
|
|
var dataset = {}; // eslint-disable-line
|
|||
|
|
|
|||
|
|
if (el.dataset) {
|
|||
|
|
for (var dataKey in el.dataset) {
|
|||
|
|
dataset[dataKey] = el.dataset[dataKey];
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
for (var i = 0; i < el.attributes.length; i += 1) {
|
|||
|
|
var _attr = el.attributes[i];
|
|||
|
|
|
|||
|
|
if (_attr.name.indexOf('data-') >= 0) {
|
|||
|
|
dataset[toCamelCase(_attr.name.split('data-')[1])] = _attr.value;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
for (var key in dataset) {
|
|||
|
|
if (dataset[key] === 'false') dataset[key] = false;else if (dataset[key] === 'true') dataset[key] = true;else if (parseFloat(dataset[key]) === dataset[key] * 1) dataset[key] *= 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return dataset;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function val(value) {
|
|||
|
|
if (typeof value === 'undefined') {
|
|||
|
|
// get value
|
|||
|
|
var el = this[0];
|
|||
|
|
if (!el) return undefined;
|
|||
|
|
|
|||
|
|
if (el.multiple && el.nodeName.toLowerCase() === 'select') {
|
|||
|
|
var values = [];
|
|||
|
|
|
|||
|
|
for (var i = 0; i < el.selectedOptions.length; i += 1) {
|
|||
|
|
values.push(el.selectedOptions[i].value);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return values;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return el.value;
|
|||
|
|
} // set value
|
|||
|
|
|
|||
|
|
|
|||
|
|
for (var _i = 0; _i < this.length; _i += 1) {
|
|||
|
|
var _el = this[_i];
|
|||
|
|
|
|||
|
|
if (Array.isArray(value) && _el.multiple && _el.nodeName.toLowerCase() === 'select') {
|
|||
|
|
for (var j = 0; j < _el.options.length; j += 1) {
|
|||
|
|
_el.options[j].selected = value.indexOf(_el.options[j].value) >= 0;
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
_el.value = value;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function value(value) {
|
|||
|
|
return this.val(value);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function transform(transform) {
|
|||
|
|
for (var i = 0; i < this.length; i += 1) {
|
|||
|
|
this[i].style.transform = transform;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function transition(duration) {
|
|||
|
|
for (var i = 0; i < this.length; i += 1) {
|
|||
|
|
this[i].style.transitionDuration = typeof duration !== 'string' ? duration + "ms" : duration;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function on() {
|
|||
|
|
for (var _len5 = arguments.length, args = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {
|
|||
|
|
args[_key5] = arguments[_key5];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var eventType = args[0],
|
|||
|
|
targetSelector = args[1],
|
|||
|
|
listener = args[2],
|
|||
|
|
capture = args[3];
|
|||
|
|
|
|||
|
|
if (typeof args[1] === 'function') {
|
|||
|
|
eventType = args[0];
|
|||
|
|
listener = args[1];
|
|||
|
|
capture = args[2];
|
|||
|
|
targetSelector = undefined;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!capture) capture = false;
|
|||
|
|
|
|||
|
|
function handleLiveEvent(e) {
|
|||
|
|
var target = e.target;
|
|||
|
|
if (!target) return;
|
|||
|
|
var eventData = e.target.dom7EventData || [];
|
|||
|
|
|
|||
|
|
if (eventData.indexOf(e) < 0) {
|
|||
|
|
eventData.unshift(e);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if ($(target).is(targetSelector)) listener.apply(target, eventData);else {
|
|||
|
|
var _parents = $(target).parents(); // eslint-disable-line
|
|||
|
|
|
|||
|
|
|
|||
|
|
for (var k = 0; k < _parents.length; k += 1) {
|
|||
|
|
if ($(_parents[k]).is(targetSelector)) listener.apply(_parents[k], eventData);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function handleEvent(e) {
|
|||
|
|
var eventData = e && e.target ? e.target.dom7EventData || [] : [];
|
|||
|
|
|
|||
|
|
if (eventData.indexOf(e) < 0) {
|
|||
|
|
eventData.unshift(e);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
listener.apply(this, eventData);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var events = eventType.split(' ');
|
|||
|
|
var j;
|
|||
|
|
|
|||
|
|
for (var i = 0; i < this.length; i += 1) {
|
|||
|
|
var el = this[i];
|
|||
|
|
|
|||
|
|
if (!targetSelector) {
|
|||
|
|
for (j = 0; j < events.length; j += 1) {
|
|||
|
|
var event = events[j];
|
|||
|
|
if (!el.dom7Listeners) el.dom7Listeners = {};
|
|||
|
|
if (!el.dom7Listeners[event]) el.dom7Listeners[event] = [];
|
|||
|
|
el.dom7Listeners[event].push({
|
|||
|
|
listener: listener,
|
|||
|
|
proxyListener: handleEvent
|
|||
|
|
});
|
|||
|
|
el.addEventListener(event, handleEvent, capture);
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
// Live events
|
|||
|
|
for (j = 0; j < events.length; j += 1) {
|
|||
|
|
var _event = events[j];
|
|||
|
|
if (!el.dom7LiveListeners) el.dom7LiveListeners = {};
|
|||
|
|
if (!el.dom7LiveListeners[_event]) el.dom7LiveListeners[_event] = [];
|
|||
|
|
|
|||
|
|
el.dom7LiveListeners[_event].push({
|
|||
|
|
listener: listener,
|
|||
|
|
proxyListener: handleLiveEvent
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
el.addEventListener(_event, handleLiveEvent, capture);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function off() {
|
|||
|
|
for (var _len6 = arguments.length, args = new Array(_len6), _key6 = 0; _key6 < _len6; _key6++) {
|
|||
|
|
args[_key6] = arguments[_key6];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var eventType = args[0],
|
|||
|
|
targetSelector = args[1],
|
|||
|
|
listener = args[2],
|
|||
|
|
capture = args[3];
|
|||
|
|
|
|||
|
|
if (typeof args[1] === 'function') {
|
|||
|
|
eventType = args[0];
|
|||
|
|
listener = args[1];
|
|||
|
|
capture = args[2];
|
|||
|
|
targetSelector = undefined;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!capture) capture = false;
|
|||
|
|
var events = eventType.split(' ');
|
|||
|
|
|
|||
|
|
for (var i = 0; i < events.length; i += 1) {
|
|||
|
|
var event = events[i];
|
|||
|
|
|
|||
|
|
for (var j = 0; j < this.length; j += 1) {
|
|||
|
|
var el = this[j];
|
|||
|
|
var handlers = void 0;
|
|||
|
|
|
|||
|
|
if (!targetSelector && el.dom7Listeners) {
|
|||
|
|
handlers = el.dom7Listeners[event];
|
|||
|
|
} else if (targetSelector && el.dom7LiveListeners) {
|
|||
|
|
handlers = el.dom7LiveListeners[event];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (handlers && handlers.length) {
|
|||
|
|
for (var k = handlers.length - 1; k >= 0; k -= 1) {
|
|||
|
|
var handler = handlers[k];
|
|||
|
|
|
|||
|
|
if (listener && handler.listener === listener) {
|
|||
|
|
el.removeEventListener(event, handler.proxyListener, capture);
|
|||
|
|
handlers.splice(k, 1);
|
|||
|
|
} else if (listener && handler.listener && handler.listener.dom7proxy && handler.listener.dom7proxy === listener) {
|
|||
|
|
el.removeEventListener(event, handler.proxyListener, capture);
|
|||
|
|
handlers.splice(k, 1);
|
|||
|
|
} else if (!listener) {
|
|||
|
|
el.removeEventListener(event, handler.proxyListener, capture);
|
|||
|
|
handlers.splice(k, 1);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function once() {
|
|||
|
|
var dom = this;
|
|||
|
|
|
|||
|
|
for (var _len7 = arguments.length, args = new Array(_len7), _key7 = 0; _key7 < _len7; _key7++) {
|
|||
|
|
args[_key7] = arguments[_key7];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var eventName = args[0],
|
|||
|
|
targetSelector = args[1],
|
|||
|
|
listener = args[2],
|
|||
|
|
capture = args[3];
|
|||
|
|
|
|||
|
|
if (typeof args[1] === 'function') {
|
|||
|
|
eventName = args[0];
|
|||
|
|
listener = args[1];
|
|||
|
|
capture = args[2];
|
|||
|
|
targetSelector = undefined;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function onceHandler() {
|
|||
|
|
for (var _len8 = arguments.length, eventArgs = new Array(_len8), _key8 = 0; _key8 < _len8; _key8++) {
|
|||
|
|
eventArgs[_key8] = arguments[_key8];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
listener.apply(this, eventArgs);
|
|||
|
|
dom.off(eventName, targetSelector, onceHandler, capture);
|
|||
|
|
|
|||
|
|
if (onceHandler.dom7proxy) {
|
|||
|
|
delete onceHandler.dom7proxy;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
onceHandler.dom7proxy = listener;
|
|||
|
|
return dom.on(eventName, targetSelector, onceHandler, capture);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function trigger() {
|
|||
|
|
var window = ssrWindow_umd.getWindow();
|
|||
|
|
|
|||
|
|
for (var _len9 = arguments.length, args = new Array(_len9), _key9 = 0; _key9 < _len9; _key9++) {
|
|||
|
|
args[_key9] = arguments[_key9];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var events = args[0].split(' ');
|
|||
|
|
var eventData = args[1];
|
|||
|
|
|
|||
|
|
for (var i = 0; i < events.length; i += 1) {
|
|||
|
|
var event = events[i];
|
|||
|
|
|
|||
|
|
for (var j = 0; j < this.length; j += 1) {
|
|||
|
|
var el = this[j];
|
|||
|
|
|
|||
|
|
if (window.CustomEvent) {
|
|||
|
|
var evt = new window.CustomEvent(event, {
|
|||
|
|
detail: eventData,
|
|||
|
|
bubbles: true,
|
|||
|
|
cancelable: true
|
|||
|
|
});
|
|||
|
|
el.dom7EventData = args.filter(function (data, dataIndex) {
|
|||
|
|
return dataIndex > 0;
|
|||
|
|
});
|
|||
|
|
el.dispatchEvent(evt);
|
|||
|
|
el.dom7EventData = [];
|
|||
|
|
delete el.dom7EventData;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function transitionEnd(callback) {
|
|||
|
|
var dom = this;
|
|||
|
|
|
|||
|
|
function fireCallBack(e) {
|
|||
|
|
if (e.target !== this) return;
|
|||
|
|
callback.call(this, e);
|
|||
|
|
dom.off('transitionend', fireCallBack);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (callback) {
|
|||
|
|
dom.on('transitionend', fireCallBack);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function animationEnd(callback) {
|
|||
|
|
var dom = this;
|
|||
|
|
|
|||
|
|
function fireCallBack(e) {
|
|||
|
|
if (e.target !== this) return;
|
|||
|
|
callback.call(this, e);
|
|||
|
|
dom.off('animationend', fireCallBack);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (callback) {
|
|||
|
|
dom.on('animationend', fireCallBack);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function width() {
|
|||
|
|
var window = ssrWindow_umd.getWindow();
|
|||
|
|
|
|||
|
|
if (this[0] === window) {
|
|||
|
|
return window.innerWidth;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (this.length > 0) {
|
|||
|
|
return parseFloat(this.css('width'));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function outerWidth(includeMargins) {
|
|||
|
|
if (this.length > 0) {
|
|||
|
|
if (includeMargins) {
|
|||
|
|
var _styles = this.styles();
|
|||
|
|
|
|||
|
|
return this[0].offsetWidth + parseFloat(_styles.getPropertyValue('margin-right')) + parseFloat(_styles.getPropertyValue('margin-left'));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return this[0].offsetWidth;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function height() {
|
|||
|
|
var window = ssrWindow_umd.getWindow();
|
|||
|
|
|
|||
|
|
if (this[0] === window) {
|
|||
|
|
return window.innerHeight;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (this.length > 0) {
|
|||
|
|
return parseFloat(this.css('height'));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function outerHeight(includeMargins) {
|
|||
|
|
if (this.length > 0) {
|
|||
|
|
if (includeMargins) {
|
|||
|
|
var _styles2 = this.styles();
|
|||
|
|
|
|||
|
|
return this[0].offsetHeight + parseFloat(_styles2.getPropertyValue('margin-top')) + parseFloat(_styles2.getPropertyValue('margin-bottom'));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return this[0].offsetHeight;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function offset() {
|
|||
|
|
if (this.length > 0) {
|
|||
|
|
var window = ssrWindow_umd.getWindow();
|
|||
|
|
var document = ssrWindow_umd.getDocument();
|
|||
|
|
var el = this[0];
|
|||
|
|
var box = el.getBoundingClientRect();
|
|||
|
|
var body = document.body;
|
|||
|
|
var clientTop = el.clientTop || body.clientTop || 0;
|
|||
|
|
var clientLeft = el.clientLeft || body.clientLeft || 0;
|
|||
|
|
var scrollTop = el === window ? window.scrollY : el.scrollTop;
|
|||
|
|
var scrollLeft = el === window ? window.scrollX : el.scrollLeft;
|
|||
|
|
return {
|
|||
|
|
top: box.top + scrollTop - clientTop,
|
|||
|
|
left: box.left + scrollLeft - clientLeft
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function hide() {
|
|||
|
|
for (var i = 0; i < this.length; i += 1) {
|
|||
|
|
this[i].style.display = 'none';
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function show() {
|
|||
|
|
var window = ssrWindow_umd.getWindow();
|
|||
|
|
|
|||
|
|
for (var i = 0; i < this.length; i += 1) {
|
|||
|
|
var el = this[i];
|
|||
|
|
|
|||
|
|
if (el.style.display === 'none') {
|
|||
|
|
el.style.display = '';
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (window.getComputedStyle(el, null).getPropertyValue('display') === 'none') {
|
|||
|
|
// Still not visible
|
|||
|
|
el.style.display = 'block';
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function styles() {
|
|||
|
|
var window = ssrWindow_umd.getWindow();
|
|||
|
|
if (this[0]) return window.getComputedStyle(this[0], null);
|
|||
|
|
return {};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function css(props, value) {
|
|||
|
|
var window = ssrWindow_umd.getWindow();
|
|||
|
|
var i;
|
|||
|
|
|
|||
|
|
if (arguments.length === 1) {
|
|||
|
|
if (typeof props === 'string') {
|
|||
|
|
// .css('width')
|
|||
|
|
if (this[0]) return window.getComputedStyle(this[0], null).getPropertyValue(props);
|
|||
|
|
} else {
|
|||
|
|
// .css({ width: '100px' })
|
|||
|
|
for (i = 0; i < this.length; i += 1) {
|
|||
|
|
for (var _prop in props) {
|
|||
|
|
this[i].style[_prop] = props[_prop];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (arguments.length === 2 && typeof props === 'string') {
|
|||
|
|
// .css('width', '100px')
|
|||
|
|
for (i = 0; i < this.length; i += 1) {
|
|||
|
|
this[i].style[props] = value;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function each(callback) {
|
|||
|
|
if (!callback) return this;
|
|||
|
|
this.forEach(function (el, index) {
|
|||
|
|
callback.apply(el, [el, index]);
|
|||
|
|
});
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function filter(callback) {
|
|||
|
|
var result = arrayFilter(this, callback);
|
|||
|
|
return $(result);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function html(html) {
|
|||
|
|
if (typeof html === 'undefined') {
|
|||
|
|
return this[0] ? this[0].innerHTML : null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
for (var i = 0; i < this.length; i += 1) {
|
|||
|
|
this[i].innerHTML = html;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function text(text) {
|
|||
|
|
if (typeof text === 'undefined') {
|
|||
|
|
return this[0] ? this[0].textContent.trim() : null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
for (var i = 0; i < this.length; i += 1) {
|
|||
|
|
this[i].textContent = text;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function is(selector) {
|
|||
|
|
var window = ssrWindow_umd.getWindow();
|
|||
|
|
var document = ssrWindow_umd.getDocument();
|
|||
|
|
var el = this[0];
|
|||
|
|
var compareWith;
|
|||
|
|
var i;
|
|||
|
|
if (!el || typeof selector === 'undefined') return false;
|
|||
|
|
|
|||
|
|
if (typeof selector === 'string') {
|
|||
|
|
if (el.matches) return el.matches(selector);
|
|||
|
|
if (el.webkitMatchesSelector) return el.webkitMatchesSelector(selector);
|
|||
|
|
if (el.msMatchesSelector) return el.msMatchesSelector(selector);
|
|||
|
|
compareWith = $(selector);
|
|||
|
|
|
|||
|
|
for (i = 0; i < compareWith.length; i += 1) {
|
|||
|
|
if (compareWith[i] === el) return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (selector === document) {
|
|||
|
|
return el === document;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (selector === window) {
|
|||
|
|
return el === window;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (selector.nodeType || selector instanceof Dom7) {
|
|||
|
|
compareWith = selector.nodeType ? [selector] : selector;
|
|||
|
|
|
|||
|
|
for (i = 0; i < compareWith.length; i += 1) {
|
|||
|
|
if (compareWith[i] === el) return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function index$1() {
|
|||
|
|
var child = this[0];
|
|||
|
|
var i;
|
|||
|
|
|
|||
|
|
if (child) {
|
|||
|
|
i = 0; // eslint-disable-next-line
|
|||
|
|
|
|||
|
|
while ((child = child.previousSibling) !== null) {
|
|||
|
|
if (child.nodeType === 1) i += 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return i;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return undefined;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function eq(index) {
|
|||
|
|
if (typeof index === 'undefined') return this;
|
|||
|
|
var length = this.length;
|
|||
|
|
|
|||
|
|
if (index > length - 1) {
|
|||
|
|
return $([]);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (index < 0) {
|
|||
|
|
var returnIndex = length + index;
|
|||
|
|
if (returnIndex < 0) return $([]);
|
|||
|
|
return $([this[returnIndex]]);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return $([this[index]]);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function append() {
|
|||
|
|
var newChild;
|
|||
|
|
var document = ssrWindow_umd.getDocument();
|
|||
|
|
|
|||
|
|
for (var k = 0; k < arguments.length; k += 1) {
|
|||
|
|
newChild = k < 0 || arguments.length <= k ? undefined : arguments[k];
|
|||
|
|
|
|||
|
|
for (var i = 0; i < this.length; i += 1) {
|
|||
|
|
if (typeof newChild === 'string') {
|
|||
|
|
var tempDiv = document.createElement('div');
|
|||
|
|
tempDiv.innerHTML = newChild;
|
|||
|
|
|
|||
|
|
while (tempDiv.firstChild) {
|
|||
|
|
this[i].appendChild(tempDiv.firstChild);
|
|||
|
|
}
|
|||
|
|
} else if (newChild instanceof Dom7) {
|
|||
|
|
for (var j = 0; j < newChild.length; j += 1) {
|
|||
|
|
this[i].appendChild(newChild[j]);
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
this[i].appendChild(newChild);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function appendTo(parent) {
|
|||
|
|
$(parent).append(this);
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function prepend(newChild) {
|
|||
|
|
var document = ssrWindow_umd.getDocument();
|
|||
|
|
var i;
|
|||
|
|
var j;
|
|||
|
|
|
|||
|
|
for (i = 0; i < this.length; i += 1) {
|
|||
|
|
if (typeof newChild === 'string') {
|
|||
|
|
var tempDiv = document.createElement('div');
|
|||
|
|
tempDiv.innerHTML = newChild;
|
|||
|
|
|
|||
|
|
for (j = tempDiv.childNodes.length - 1; j >= 0; j -= 1) {
|
|||
|
|
this[i].insertBefore(tempDiv.childNodes[j], this[i].childNodes[0]);
|
|||
|
|
}
|
|||
|
|
} else if (newChild instanceof Dom7) {
|
|||
|
|
for (j = 0; j < newChild.length; j += 1) {
|
|||
|
|
this[i].insertBefore(newChild[j], this[i].childNodes[0]);
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
this[i].insertBefore(newChild, this[i].childNodes[0]);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function prependTo(parent) {
|
|||
|
|
$(parent).prepend(this);
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function insertBefore(selector) {
|
|||
|
|
var before = $(selector);
|
|||
|
|
|
|||
|
|
for (var i = 0; i < this.length; i += 1) {
|
|||
|
|
if (before.length === 1) {
|
|||
|
|
before[0].parentNode.insertBefore(this[i], before[0]);
|
|||
|
|
} else if (before.length > 1) {
|
|||
|
|
for (var j = 0; j < before.length; j += 1) {
|
|||
|
|
before[j].parentNode.insertBefore(this[i].cloneNode(true), before[j]);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function insertAfter(selector) {
|
|||
|
|
var after = $(selector);
|
|||
|
|
|
|||
|
|
for (var i = 0; i < this.length; i += 1) {
|
|||
|
|
if (after.length === 1) {
|
|||
|
|
after[0].parentNode.insertBefore(this[i], after[0].nextSibling);
|
|||
|
|
} else if (after.length > 1) {
|
|||
|
|
for (var j = 0; j < after.length; j += 1) {
|
|||
|
|
after[j].parentNode.insertBefore(this[i].cloneNode(true), after[j].nextSibling);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function next(selector) {
|
|||
|
|
if (this.length > 0) {
|
|||
|
|
if (selector) {
|
|||
|
|
if (this[0].nextElementSibling && $(this[0].nextElementSibling).is(selector)) {
|
|||
|
|
return $([this[0].nextElementSibling]);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return $([]);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (this[0].nextElementSibling) return $([this[0].nextElementSibling]);
|
|||
|
|
return $([]);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return $([]);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function nextAll(selector) {
|
|||
|
|
var nextEls = [];
|
|||
|
|
var el = this[0];
|
|||
|
|
if (!el) return $([]);
|
|||
|
|
|
|||
|
|
while (el.nextElementSibling) {
|
|||
|
|
var _next = el.nextElementSibling; // eslint-disable-line
|
|||
|
|
|
|||
|
|
if (selector) {
|
|||
|
|
if ($(_next).is(selector)) nextEls.push(_next);
|
|||
|
|
} else nextEls.push(_next);
|
|||
|
|
|
|||
|
|
el = _next;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return $(nextEls);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function prev(selector) {
|
|||
|
|
if (this.length > 0) {
|
|||
|
|
var el = this[0];
|
|||
|
|
|
|||
|
|
if (selector) {
|
|||
|
|
if (el.previousElementSibling && $(el.previousElementSibling).is(selector)) {
|
|||
|
|
return $([el.previousElementSibling]);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return $([]);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (el.previousElementSibling) return $([el.previousElementSibling]);
|
|||
|
|
return $([]);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return $([]);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function prevAll(selector) {
|
|||
|
|
var prevEls = [];
|
|||
|
|
var el = this[0];
|
|||
|
|
if (!el) return $([]);
|
|||
|
|
|
|||
|
|
while (el.previousElementSibling) {
|
|||
|
|
var _prev = el.previousElementSibling; // eslint-disable-line
|
|||
|
|
|
|||
|
|
if (selector) {
|
|||
|
|
if ($(_prev).is(selector)) prevEls.push(_prev);
|
|||
|
|
} else prevEls.push(_prev);
|
|||
|
|
|
|||
|
|
el = _prev;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return $(prevEls);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function siblings(selector) {
|
|||
|
|
return this.nextAll(selector).add(this.prevAll(selector));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function parent(selector) {
|
|||
|
|
var parents = []; // eslint-disable-line
|
|||
|
|
|
|||
|
|
for (var i = 0; i < this.length; i += 1) {
|
|||
|
|
if (this[i].parentNode !== null) {
|
|||
|
|
if (selector) {
|
|||
|
|
if ($(this[i].parentNode).is(selector)) parents.push(this[i].parentNode);
|
|||
|
|
} else {
|
|||
|
|
parents.push(this[i].parentNode);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return $(parents);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function parents(selector) {
|
|||
|
|
var parents = []; // eslint-disable-line
|
|||
|
|
|
|||
|
|
for (var i = 0; i < this.length; i += 1) {
|
|||
|
|
var _parent = this[i].parentNode; // eslint-disable-line
|
|||
|
|
|
|||
|
|
while (_parent) {
|
|||
|
|
if (selector) {
|
|||
|
|
if ($(_parent).is(selector)) parents.push(_parent);
|
|||
|
|
} else {
|
|||
|
|
parents.push(_parent);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
_parent = _parent.parentNode;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return $(parents);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function closest(selector) {
|
|||
|
|
var closest = this; // eslint-disable-line
|
|||
|
|
|
|||
|
|
if (typeof selector === 'undefined') {
|
|||
|
|
return $([]);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!closest.is(selector)) {
|
|||
|
|
closest = closest.parents(selector).eq(0);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return closest;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function find(selector) {
|
|||
|
|
var foundElements = [];
|
|||
|
|
|
|||
|
|
for (var i = 0; i < this.length; i += 1) {
|
|||
|
|
var found = this[i].querySelectorAll(selector);
|
|||
|
|
|
|||
|
|
for (var j = 0; j < found.length; j += 1) {
|
|||
|
|
foundElements.push(found[j]);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return $(foundElements);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function children(selector) {
|
|||
|
|
var children = []; // eslint-disable-line
|
|||
|
|
|
|||
|
|
for (var i = 0; i < this.length; i += 1) {
|
|||
|
|
var childNodes = this[i].children;
|
|||
|
|
|
|||
|
|
for (var j = 0; j < childNodes.length; j += 1) {
|
|||
|
|
if (!selector || $(childNodes[j]).is(selector)) {
|
|||
|
|
children.push(childNodes[j]);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return $(children);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function remove() {
|
|||
|
|
for (var i = 0; i < this.length; i += 1) {
|
|||
|
|
if (this[i].parentNode) this[i].parentNode.removeChild(this[i]);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function detach() {
|
|||
|
|
return this.remove();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function add() {
|
|||
|
|
var dom = this;
|
|||
|
|
var i;
|
|||
|
|
var j;
|
|||
|
|
|
|||
|
|
for (var _len10 = arguments.length, els = new Array(_len10), _key10 = 0; _key10 < _len10; _key10++) {
|
|||
|
|
els[_key10] = arguments[_key10];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
for (i = 0; i < els.length; i += 1) {
|
|||
|
|
var toAdd = $(els[i]);
|
|||
|
|
|
|||
|
|
for (j = 0; j < toAdd.length; j += 1) {
|
|||
|
|
dom.push(toAdd[j]);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return dom;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function empty() {
|
|||
|
|
for (var i = 0; i < this.length; i += 1) {
|
|||
|
|
var el = this[i];
|
|||
|
|
|
|||
|
|
if (el.nodeType === 1) {
|
|||
|
|
for (var j = 0; j < el.childNodes.length; j += 1) {
|
|||
|
|
if (el.childNodes[j].parentNode) {
|
|||
|
|
el.childNodes[j].parentNode.removeChild(el.childNodes[j]);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
el.textContent = '';
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function scrollTo() {
|
|||
|
|
var window = ssrWindow_umd.getWindow();
|
|||
|
|
|
|||
|
|
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|||
|
|
args[_key] = arguments[_key];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var left = args[0],
|
|||
|
|
top = args[1],
|
|||
|
|
duration = args[2],
|
|||
|
|
easing = args[3],
|
|||
|
|
callback = args[4];
|
|||
|
|
|
|||
|
|
if (args.length === 4 && typeof easing === 'function') {
|
|||
|
|
callback = easing;
|
|||
|
|
left = args[0];
|
|||
|
|
top = args[1];
|
|||
|
|
duration = args[2];
|
|||
|
|
callback = args[3];
|
|||
|
|
easing = args[4];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (typeof easing === 'undefined') easing = 'swing';
|
|||
|
|
return this.each(function animate() {
|
|||
|
|
var el = this;
|
|||
|
|
var currentTop;
|
|||
|
|
var currentLeft;
|
|||
|
|
var maxTop;
|
|||
|
|
var maxLeft;
|
|||
|
|
var newTop;
|
|||
|
|
var newLeft;
|
|||
|
|
var scrollTop; // eslint-disable-line
|
|||
|
|
|
|||
|
|
var scrollLeft; // eslint-disable-line
|
|||
|
|
|
|||
|
|
var animateTop = top > 0 || top === 0;
|
|||
|
|
var animateLeft = left > 0 || left === 0;
|
|||
|
|
|
|||
|
|
if (typeof easing === 'undefined') {
|
|||
|
|
easing = 'swing';
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (animateTop) {
|
|||
|
|
currentTop = el.scrollTop;
|
|||
|
|
|
|||
|
|
if (!duration) {
|
|||
|
|
el.scrollTop = top;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (animateLeft) {
|
|||
|
|
currentLeft = el.scrollLeft;
|
|||
|
|
|
|||
|
|
if (!duration) {
|
|||
|
|
el.scrollLeft = left;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!duration) return;
|
|||
|
|
|
|||
|
|
if (animateTop) {
|
|||
|
|
maxTop = el.scrollHeight - el.offsetHeight;
|
|||
|
|
newTop = Math.max(Math.min(top, maxTop), 0);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (animateLeft) {
|
|||
|
|
maxLeft = el.scrollWidth - el.offsetWidth;
|
|||
|
|
newLeft = Math.max(Math.min(left, maxLeft), 0);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var startTime = null;
|
|||
|
|
if (animateTop && newTop === currentTop) animateTop = false;
|
|||
|
|
if (animateLeft && newLeft === currentLeft) animateLeft = false;
|
|||
|
|
|
|||
|
|
function render(time) {
|
|||
|
|
if (time === void 0) {
|
|||
|
|
time = new Date().getTime();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (startTime === null) {
|
|||
|
|
startTime = time;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var progress = Math.max(Math.min((time - startTime) / duration, 1), 0);
|
|||
|
|
var easeProgress = easing === 'linear' ? progress : 0.5 - Math.cos(progress * Math.PI) / 2;
|
|||
|
|
var done;
|
|||
|
|
if (animateTop) scrollTop = currentTop + easeProgress * (newTop - currentTop);
|
|||
|
|
if (animateLeft) scrollLeft = currentLeft + easeProgress * (newLeft - currentLeft);
|
|||
|
|
|
|||
|
|
if (animateTop && newTop > currentTop && scrollTop >= newTop) {
|
|||
|
|
el.scrollTop = newTop;
|
|||
|
|
done = true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (animateTop && newTop < currentTop && scrollTop <= newTop) {
|
|||
|
|
el.scrollTop = newTop;
|
|||
|
|
done = true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (animateLeft && newLeft > currentLeft && scrollLeft >= newLeft) {
|
|||
|
|
el.scrollLeft = newLeft;
|
|||
|
|
done = true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (animateLeft && newLeft < currentLeft && scrollLeft <= newLeft) {
|
|||
|
|
el.scrollLeft = newLeft;
|
|||
|
|
done = true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (done) {
|
|||
|
|
if (callback) callback();
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (animateTop) el.scrollTop = scrollTop;
|
|||
|
|
if (animateLeft) el.scrollLeft = scrollLeft;
|
|||
|
|
window.requestAnimationFrame(render);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
window.requestAnimationFrame(render);
|
|||
|
|
});
|
|||
|
|
} // scrollTop(top, duration, easing, callback) {
|
|||
|
|
|
|||
|
|
|
|||
|
|
function scrollTop() {
|
|||
|
|
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
|||
|
|
args[_key2] = arguments[_key2];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var top = args[0],
|
|||
|
|
duration = args[1],
|
|||
|
|
easing = args[2],
|
|||
|
|
callback = args[3];
|
|||
|
|
|
|||
|
|
if (args.length === 3 && typeof easing === 'function') {
|
|||
|
|
top = args[0];
|
|||
|
|
duration = args[1];
|
|||
|
|
callback = args[2];
|
|||
|
|
easing = args[3];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var dom = this;
|
|||
|
|
|
|||
|
|
if (typeof top === 'undefined') {
|
|||
|
|
if (dom.length > 0) return dom[0].scrollTop;
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return dom.scrollTo(undefined, top, duration, easing, callback);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function scrollLeft() {
|
|||
|
|
for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
|
|||
|
|
args[_key3] = arguments[_key3];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var left = args[0],
|
|||
|
|
duration = args[1],
|
|||
|
|
easing = args[2],
|
|||
|
|
callback = args[3];
|
|||
|
|
|
|||
|
|
if (args.length === 3 && typeof easing === 'function') {
|
|||
|
|
left = args[0];
|
|||
|
|
duration = args[1];
|
|||
|
|
callback = args[2];
|
|||
|
|
easing = args[3];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var dom = this;
|
|||
|
|
|
|||
|
|
if (typeof left === 'undefined') {
|
|||
|
|
if (dom.length > 0) return dom[0].scrollLeft;
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return dom.scrollTo(left, undefined, duration, easing, callback);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function animate(initialProps, initialParams) {
|
|||
|
|
var window = ssrWindow_umd.getWindow();
|
|||
|
|
var els = this;
|
|||
|
|
var a = {
|
|||
|
|
props: Object.assign({}, initialProps),
|
|||
|
|
params: Object.assign({
|
|||
|
|
duration: 300,
|
|||
|
|
easing: 'swing' // or 'linear'
|
|||
|
|
|
|||
|
|
/* Callbacks
|
|||
|
|
begin(elements)
|
|||
|
|
complete(elements)
|
|||
|
|
progress(elements, complete, remaining, start, tweenValue)
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
}, initialParams),
|
|||
|
|
elements: els,
|
|||
|
|
animating: false,
|
|||
|
|
que: [],
|
|||
|
|
easingProgress: function easingProgress(easing, progress) {
|
|||
|
|
if (easing === 'swing') {
|
|||
|
|
return 0.5 - Math.cos(progress * Math.PI) / 2;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (typeof easing === 'function') {
|
|||
|
|
return easing(progress);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return progress;
|
|||
|
|
},
|
|||
|
|
stop: function stop() {
|
|||
|
|
if (a.frameId) {
|
|||
|
|
window.cancelAnimationFrame(a.frameId);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
a.animating = false;
|
|||
|
|
a.elements.each(function (el) {
|
|||
|
|
var element = el;
|
|||
|
|
delete element.dom7AnimateInstance;
|
|||
|
|
});
|
|||
|
|
a.que = [];
|
|||
|
|
},
|
|||
|
|
done: function done(complete) {
|
|||
|
|
a.animating = false;
|
|||
|
|
a.elements.each(function (el) {
|
|||
|
|
var element = el;
|
|||
|
|
delete element.dom7AnimateInstance;
|
|||
|
|
});
|
|||
|
|
if (complete) complete(els);
|
|||
|
|
|
|||
|
|
if (a.que.length > 0) {
|
|||
|
|
var que = a.que.shift();
|
|||
|
|
a.animate(que[0], que[1]);
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
animate: function animate(props, params) {
|
|||
|
|
if (a.animating) {
|
|||
|
|
a.que.push([props, params]);
|
|||
|
|
return a;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var elements = []; // Define & Cache Initials & Units
|
|||
|
|
|
|||
|
|
a.elements.each(function (el, index) {
|
|||
|
|
var initialFullValue;
|
|||
|
|
var initialValue;
|
|||
|
|
var unit;
|
|||
|
|
var finalValue;
|
|||
|
|
var finalFullValue;
|
|||
|
|
if (!el.dom7AnimateInstance) a.elements[index].dom7AnimateInstance = a;
|
|||
|
|
elements[index] = {
|
|||
|
|
container: el
|
|||
|
|
};
|
|||
|
|
Object.keys(props).forEach(function (prop) {
|
|||
|
|
initialFullValue = window.getComputedStyle(el, null).getPropertyValue(prop).replace(',', '.');
|
|||
|
|
initialValue = parseFloat(initialFullValue);
|
|||
|
|
unit = initialFullValue.replace(initialValue, '');
|
|||
|
|
finalValue = parseFloat(props[prop]);
|
|||
|
|
finalFullValue = props[prop] + unit;
|
|||
|
|
elements[index][prop] = {
|
|||
|
|
initialFullValue: initialFullValue,
|
|||
|
|
initialValue: initialValue,
|
|||
|
|
unit: unit,
|
|||
|
|
finalValue: finalValue,
|
|||
|
|
finalFullValue: finalFullValue,
|
|||
|
|
currentValue: initialValue
|
|||
|
|
};
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
var startTime = null;
|
|||
|
|
var time;
|
|||
|
|
var elementsDone = 0;
|
|||
|
|
var propsDone = 0;
|
|||
|
|
var done;
|
|||
|
|
var began = false;
|
|||
|
|
a.animating = true;
|
|||
|
|
|
|||
|
|
function render() {
|
|||
|
|
time = new Date().getTime();
|
|||
|
|
var progress;
|
|||
|
|
var easeProgress; // let el;
|
|||
|
|
|
|||
|
|
if (!began) {
|
|||
|
|
began = true;
|
|||
|
|
if (params.begin) params.begin(els);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (startTime === null) {
|
|||
|
|
startTime = time;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (params.progress) {
|
|||
|
|
// eslint-disable-next-line
|
|||
|
|
params.progress(els, Math.max(Math.min((time - startTime) / params.duration, 1), 0), startTime + params.duration - time < 0 ? 0 : startTime + params.duration - time, startTime);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
elements.forEach(function (element) {
|
|||
|
|
var el = element;
|
|||
|
|
if (done || el.done) return;
|
|||
|
|
Object.keys(props).forEach(function (prop) {
|
|||
|
|
if (done || el.done) return;
|
|||
|
|
progress = Math.max(Math.min((time - startTime) / params.duration, 1), 0);
|
|||
|
|
easeProgress = a.easingProgress(params.easing, progress);
|
|||
|
|
var _el$prop = el[prop],
|
|||
|
|
initialValue = _el$prop.initialValue,
|
|||
|
|
finalValue = _el$prop.finalValue,
|
|||
|
|
unit = _el$prop.unit;
|
|||
|
|
el[prop].currentValue = initialValue + easeProgress * (finalValue - initialValue);
|
|||
|
|
var currentValue = el[prop].currentValue;
|
|||
|
|
|
|||
|
|
if (finalValue > initialValue && currentValue >= finalValue || finalValue < initialValue && currentValue <= finalValue) {
|
|||
|
|
el.container.style[prop] = finalValue + unit;
|
|||
|
|
propsDone += 1;
|
|||
|
|
|
|||
|
|
if (propsDone === Object.keys(props).length) {
|
|||
|
|
el.done = true;
|
|||
|
|
elementsDone += 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (elementsDone === elements.length) {
|
|||
|
|
done = true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (done) {
|
|||
|
|
a.done(params.complete);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
el.container.style[prop] = currentValue + unit;
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
if (done) return; // Then call
|
|||
|
|
|
|||
|
|
a.frameId = window.requestAnimationFrame(render);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
a.frameId = window.requestAnimationFrame(render);
|
|||
|
|
return a;
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
if (a.elements.length === 0) {
|
|||
|
|
return els;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var animateInstance;
|
|||
|
|
|
|||
|
|
for (var i = 0; i < a.elements.length; i += 1) {
|
|||
|
|
if (a.elements[i].dom7AnimateInstance) {
|
|||
|
|
animateInstance = a.elements[i].dom7AnimateInstance;
|
|||
|
|
} else a.elements[i].dom7AnimateInstance = a;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!animateInstance) {
|
|||
|
|
animateInstance = a;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (initialProps === 'stop') {
|
|||
|
|
animateInstance.stop();
|
|||
|
|
} else {
|
|||
|
|
animateInstance.animate(a.props, a.params);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return els;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function stop() {
|
|||
|
|
var els = this;
|
|||
|
|
|
|||
|
|
for (var i = 0; i < els.length; i += 1) {
|
|||
|
|
if (els[i].dom7AnimateInstance) {
|
|||
|
|
els[i].dom7AnimateInstance.stop();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var noTrigger = 'resize scroll'.split(' ');
|
|||
|
|
|
|||
|
|
function shortcut(name) {
|
|||
|
|
function eventHandler() {
|
|||
|
|
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|||
|
|
args[_key] = arguments[_key];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (typeof args[0] === 'undefined') {
|
|||
|
|
for (var i = 0; i < this.length; i += 1) {
|
|||
|
|
if (noTrigger.indexOf(name) < 0) {
|
|||
|
|
if (name in this[i]) this[i][name]();else {
|
|||
|
|
$(this[i]).trigger(name);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return this.on.apply(this, [name].concat(args));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return eventHandler;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var click = shortcut('click');
|
|||
|
|
var blur = shortcut('blur');
|
|||
|
|
var focus = shortcut('focus');
|
|||
|
|
var focusin = shortcut('focusin');
|
|||
|
|
var focusout = shortcut('focusout');
|
|||
|
|
var keyup = shortcut('keyup');
|
|||
|
|
var keydown = shortcut('keydown');
|
|||
|
|
var keypress = shortcut('keypress');
|
|||
|
|
var submit = shortcut('submit');
|
|||
|
|
var change = shortcut('change');
|
|||
|
|
var mousedown = shortcut('mousedown');
|
|||
|
|
var mousemove = shortcut('mousemove');
|
|||
|
|
var mouseup = shortcut('mouseup');
|
|||
|
|
var mouseenter = shortcut('mouseenter');
|
|||
|
|
var mouseleave = shortcut('mouseleave');
|
|||
|
|
var mouseout = shortcut('mouseout');
|
|||
|
|
var mouseover = shortcut('mouseover');
|
|||
|
|
var touchstart = shortcut('touchstart');
|
|||
|
|
var touchend = shortcut('touchend');
|
|||
|
|
var touchmove = shortcut('touchmove');
|
|||
|
|
var resize = shortcut('resize');
|
|||
|
|
var scroll = shortcut('scroll');
|
|||
|
|
|
|||
|
|
var $_1 = $;
|
|||
|
|
var add_1 = add;
|
|||
|
|
var addClass_1 = addClass;
|
|||
|
|
var animate_1 = animate;
|
|||
|
|
var animationEnd_1 = animationEnd;
|
|||
|
|
var append_1 = append;
|
|||
|
|
var appendTo_1 = appendTo;
|
|||
|
|
var attr_1 = attr;
|
|||
|
|
var blur_1 = blur;
|
|||
|
|
var change_1 = change;
|
|||
|
|
var children_1 = children;
|
|||
|
|
var click_1 = click;
|
|||
|
|
var closest_1 = closest;
|
|||
|
|
var css_1 = css;
|
|||
|
|
var data_1 = data;
|
|||
|
|
var dataset_1 = dataset;
|
|||
|
|
var _default$1 = $;
|
|||
|
|
var detach_1 = detach;
|
|||
|
|
var each_1 = each;
|
|||
|
|
var empty_1 = empty;
|
|||
|
|
var eq_1 = eq;
|
|||
|
|
var filter_1 = filter;
|
|||
|
|
var find_1 = find;
|
|||
|
|
var focus_1 = focus;
|
|||
|
|
var focusin_1 = focusin;
|
|||
|
|
var focusout_1 = focusout;
|
|||
|
|
var hasClass_1 = hasClass;
|
|||
|
|
var height_1 = height;
|
|||
|
|
var hide_1 = hide;
|
|||
|
|
var html_1 = html;
|
|||
|
|
var index_1 = index$1;
|
|||
|
|
var insertAfter_1 = insertAfter;
|
|||
|
|
var insertBefore_1 = insertBefore;
|
|||
|
|
var is_1 = is;
|
|||
|
|
var keydown_1 = keydown;
|
|||
|
|
var keypress_1 = keypress;
|
|||
|
|
var keyup_1 = keyup;
|
|||
|
|
var mousedown_1 = mousedown;
|
|||
|
|
var mouseenter_1 = mouseenter;
|
|||
|
|
var mouseleave_1 = mouseleave;
|
|||
|
|
var mousemove_1 = mousemove;
|
|||
|
|
var mouseout_1 = mouseout;
|
|||
|
|
var mouseover_1 = mouseover;
|
|||
|
|
var mouseup_1 = mouseup;
|
|||
|
|
var next_1 = next;
|
|||
|
|
var nextAll_1 = nextAll;
|
|||
|
|
var off_1 = off;
|
|||
|
|
var offset_1 = offset;
|
|||
|
|
var on_1 = on;
|
|||
|
|
var once_1 = once;
|
|||
|
|
var outerHeight_1 = outerHeight;
|
|||
|
|
var outerWidth_1 = outerWidth;
|
|||
|
|
var parent_1 = parent;
|
|||
|
|
var parents_1 = parents;
|
|||
|
|
var prepend_1 = prepend;
|
|||
|
|
var prependTo_1 = prependTo;
|
|||
|
|
var prev_1 = prev;
|
|||
|
|
var prevAll_1 = prevAll;
|
|||
|
|
var prop_1 = prop;
|
|||
|
|
var remove_1 = remove;
|
|||
|
|
var removeAttr_1 = removeAttr;
|
|||
|
|
var removeClass_1 = removeClass;
|
|||
|
|
var removeData_1 = removeData;
|
|||
|
|
var resize_1 = resize;
|
|||
|
|
var scroll_1 = scroll;
|
|||
|
|
var scrollLeft_1 = scrollLeft;
|
|||
|
|
var scrollTo_1 = scrollTo;
|
|||
|
|
var scrollTop_1 = scrollTop;
|
|||
|
|
var show_1 = show;
|
|||
|
|
var siblings_1 = siblings;
|
|||
|
|
var stop_1 = stop;
|
|||
|
|
var styles_1 = styles;
|
|||
|
|
var submit_1 = submit;
|
|||
|
|
var text_1 = text;
|
|||
|
|
var toggleClass_1 = toggleClass;
|
|||
|
|
var touchend_1 = touchend;
|
|||
|
|
var touchmove_1 = touchmove;
|
|||
|
|
var touchstart_1 = touchstart;
|
|||
|
|
var transform_1 = transform;
|
|||
|
|
var transition_1 = transition;
|
|||
|
|
var transitionEnd_1 = transitionEnd;
|
|||
|
|
var trigger_1 = trigger;
|
|||
|
|
var val_1 = val;
|
|||
|
|
var value_1 = value;
|
|||
|
|
var width_1 = width;
|
|||
|
|
|
|||
|
|
var dom7_cjs = /*#__PURE__*/Object.defineProperty({
|
|||
|
|
$: $_1,
|
|||
|
|
add: add_1,
|
|||
|
|
addClass: addClass_1,
|
|||
|
|
animate: animate_1,
|
|||
|
|
animationEnd: animationEnd_1,
|
|||
|
|
append: append_1,
|
|||
|
|
appendTo: appendTo_1,
|
|||
|
|
attr: attr_1,
|
|||
|
|
blur: blur_1,
|
|||
|
|
change: change_1,
|
|||
|
|
children: children_1,
|
|||
|
|
click: click_1,
|
|||
|
|
closest: closest_1,
|
|||
|
|
css: css_1,
|
|||
|
|
data: data_1,
|
|||
|
|
dataset: dataset_1,
|
|||
|
|
default: _default$1,
|
|||
|
|
detach: detach_1,
|
|||
|
|
each: each_1,
|
|||
|
|
empty: empty_1,
|
|||
|
|
eq: eq_1,
|
|||
|
|
filter: filter_1,
|
|||
|
|
find: find_1,
|
|||
|
|
focus: focus_1,
|
|||
|
|
focusin: focusin_1,
|
|||
|
|
focusout: focusout_1,
|
|||
|
|
hasClass: hasClass_1,
|
|||
|
|
height: height_1,
|
|||
|
|
hide: hide_1,
|
|||
|
|
html: html_1,
|
|||
|
|
index: index_1,
|
|||
|
|
insertAfter: insertAfter_1,
|
|||
|
|
insertBefore: insertBefore_1,
|
|||
|
|
is: is_1,
|
|||
|
|
keydown: keydown_1,
|
|||
|
|
keypress: keypress_1,
|
|||
|
|
keyup: keyup_1,
|
|||
|
|
mousedown: mousedown_1,
|
|||
|
|
mouseenter: mouseenter_1,
|
|||
|
|
mouseleave: mouseleave_1,
|
|||
|
|
mousemove: mousemove_1,
|
|||
|
|
mouseout: mouseout_1,
|
|||
|
|
mouseover: mouseover_1,
|
|||
|
|
mouseup: mouseup_1,
|
|||
|
|
next: next_1,
|
|||
|
|
nextAll: nextAll_1,
|
|||
|
|
off: off_1,
|
|||
|
|
offset: offset_1,
|
|||
|
|
on: on_1,
|
|||
|
|
once: once_1,
|
|||
|
|
outerHeight: outerHeight_1,
|
|||
|
|
outerWidth: outerWidth_1,
|
|||
|
|
parent: parent_1,
|
|||
|
|
parents: parents_1,
|
|||
|
|
prepend: prepend_1,
|
|||
|
|
prependTo: prependTo_1,
|
|||
|
|
prev: prev_1,
|
|||
|
|
prevAll: prevAll_1,
|
|||
|
|
prop: prop_1,
|
|||
|
|
remove: remove_1,
|
|||
|
|
removeAttr: removeAttr_1,
|
|||
|
|
removeClass: removeClass_1,
|
|||
|
|
removeData: removeData_1,
|
|||
|
|
resize: resize_1,
|
|||
|
|
scroll: scroll_1,
|
|||
|
|
scrollLeft: scrollLeft_1,
|
|||
|
|
scrollTo: scrollTo_1,
|
|||
|
|
scrollTop: scrollTop_1,
|
|||
|
|
show: show_1,
|
|||
|
|
siblings: siblings_1,
|
|||
|
|
stop: stop_1,
|
|||
|
|
styles: styles_1,
|
|||
|
|
submit: submit_1,
|
|||
|
|
text: text_1,
|
|||
|
|
toggleClass: toggleClass_1,
|
|||
|
|
touchend: touchend_1,
|
|||
|
|
touchmove: touchmove_1,
|
|||
|
|
touchstart: touchstart_1,
|
|||
|
|
transform: transform_1,
|
|||
|
|
transition: transition_1,
|
|||
|
|
transitionEnd: transitionEnd_1,
|
|||
|
|
trigger: trigger_1,
|
|||
|
|
val: val_1,
|
|||
|
|
value: value_1,
|
|||
|
|
width: width_1
|
|||
|
|
}, '__esModule', {value: true});
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* lodash (Custom Build) <https://lodash.com/>
|
|||
|
|
* Build: `lodash modularize exports="npm" -o ./`
|
|||
|
|
* Copyright jQuery Foundation and other contributors <https://jquery.org/>
|
|||
|
|
* Released under MIT license <https://lodash.com/license>
|
|||
|
|
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
|
|||
|
|
* Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
|||
|
|
*/
|
|||
|
|
/** Used as references for various `Number` constants. */
|
|||
|
|
var MAX_SAFE_INTEGER = 9007199254740991;
|
|||
|
|
|
|||
|
|
/** `Object#toString` result references. */
|
|||
|
|
var argsTag = '[object Arguments]',
|
|||
|
|
funcTag = '[object Function]',
|
|||
|
|
genTag = '[object GeneratorFunction]';
|
|||
|
|
|
|||
|
|
/** Used to detect unsigned integer values. */
|
|||
|
|
var reIsUint = /^(?:0|[1-9]\d*)$/;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* A specialized version of `_.forEach` for arrays without support for
|
|||
|
|
* iteratee shorthands.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Array} [array] The array to iterate over.
|
|||
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|||
|
|
* @returns {Array} Returns `array`.
|
|||
|
|
*/
|
|||
|
|
function arrayEach(array, iteratee) {
|
|||
|
|
var index = -1,
|
|||
|
|
length = array ? array.length : 0;
|
|||
|
|
|
|||
|
|
while (++index < length) {
|
|||
|
|
if (iteratee(array[index], index, array) === false) {
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return array;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* The base implementation of `_.times` without support for iteratee shorthands
|
|||
|
|
* or max array length checks.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {number} n The number of times to invoke `iteratee`.
|
|||
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|||
|
|
* @returns {Array} Returns the array of results.
|
|||
|
|
*/
|
|||
|
|
function baseTimes(n, iteratee) {
|
|||
|
|
var index = -1,
|
|||
|
|
result = Array(n);
|
|||
|
|
|
|||
|
|
while (++index < n) {
|
|||
|
|
result[index] = iteratee(index);
|
|||
|
|
}
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Creates a unary function that invokes `func` with its argument transformed.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Function} func The function to wrap.
|
|||
|
|
* @param {Function} transform The argument transform.
|
|||
|
|
* @returns {Function} Returns the new function.
|
|||
|
|
*/
|
|||
|
|
function overArg(func, transform) {
|
|||
|
|
return function(arg) {
|
|||
|
|
return func(transform(arg));
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/** Used for built-in method references. */
|
|||
|
|
var objectProto$3 = Object.prototype;
|
|||
|
|
|
|||
|
|
/** Used to check objects for own properties. */
|
|||
|
|
var hasOwnProperty$1 = objectProto$3.hasOwnProperty;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Used to resolve the
|
|||
|
|
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
|
|||
|
|
* of values.
|
|||
|
|
*/
|
|||
|
|
var objectToString$3 = objectProto$3.toString;
|
|||
|
|
|
|||
|
|
/** Built-in value references. */
|
|||
|
|
var propertyIsEnumerable = objectProto$3.propertyIsEnumerable;
|
|||
|
|
|
|||
|
|
/* Built-in method references for those with the same name as other `lodash` methods. */
|
|||
|
|
var nativeKeys = overArg(Object.keys, Object);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Creates an array of the enumerable property names of the array-like `value`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {*} value The value to query.
|
|||
|
|
* @param {boolean} inherited Specify returning inherited property names.
|
|||
|
|
* @returns {Array} Returns the array of property names.
|
|||
|
|
*/
|
|||
|
|
function arrayLikeKeys(value, inherited) {
|
|||
|
|
// Safari 8.1 makes `arguments.callee` enumerable in strict mode.
|
|||
|
|
// Safari 9 makes `arguments.length` enumerable in strict mode.
|
|||
|
|
var result = (isArray(value) || isArguments(value))
|
|||
|
|
? baseTimes(value.length, String)
|
|||
|
|
: [];
|
|||
|
|
|
|||
|
|
var length = result.length,
|
|||
|
|
skipIndexes = !!length;
|
|||
|
|
|
|||
|
|
for (var key in value) {
|
|||
|
|
if ((inherited || hasOwnProperty$1.call(value, key)) &&
|
|||
|
|
!(skipIndexes && (key == 'length' || isIndex(key, length)))) {
|
|||
|
|
result.push(key);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* The base implementation of `_.forEach` without support for iteratee shorthands.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|||
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|||
|
|
* @returns {Array|Object} Returns `collection`.
|
|||
|
|
*/
|
|||
|
|
var baseEach = createBaseEach(baseForOwn);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* The base implementation of `baseForOwn` which iterates over `object`
|
|||
|
|
* properties returned by `keysFunc` and invokes `iteratee` for each property.
|
|||
|
|
* Iteratee functions may exit iteration early by explicitly returning `false`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Object} object The object to iterate over.
|
|||
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|||
|
|
* @param {Function} keysFunc The function to get the keys of `object`.
|
|||
|
|
* @returns {Object} Returns `object`.
|
|||
|
|
*/
|
|||
|
|
var baseFor = createBaseFor();
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* The base implementation of `_.forOwn` without support for iteratee shorthands.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Object} object The object to iterate over.
|
|||
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|||
|
|
* @returns {Object} Returns `object`.
|
|||
|
|
*/
|
|||
|
|
function baseForOwn(object, iteratee) {
|
|||
|
|
return object && baseFor(object, iteratee, keys);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Object} object The object to query.
|
|||
|
|
* @returns {Array} Returns the array of property names.
|
|||
|
|
*/
|
|||
|
|
function baseKeys(object) {
|
|||
|
|
if (!isPrototype(object)) {
|
|||
|
|
return nativeKeys(object);
|
|||
|
|
}
|
|||
|
|
var result = [];
|
|||
|
|
for (var key in Object(object)) {
|
|||
|
|
if (hasOwnProperty$1.call(object, key) && key != 'constructor') {
|
|||
|
|
result.push(key);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Creates a `baseEach` or `baseEachRight` function.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Function} eachFunc The function to iterate over a collection.
|
|||
|
|
* @param {boolean} [fromRight] Specify iterating from right to left.
|
|||
|
|
* @returns {Function} Returns the new base function.
|
|||
|
|
*/
|
|||
|
|
function createBaseEach(eachFunc, fromRight) {
|
|||
|
|
return function(collection, iteratee) {
|
|||
|
|
if (collection == null) {
|
|||
|
|
return collection;
|
|||
|
|
}
|
|||
|
|
if (!isArrayLike(collection)) {
|
|||
|
|
return eachFunc(collection, iteratee);
|
|||
|
|
}
|
|||
|
|
var length = collection.length,
|
|||
|
|
index = fromRight ? length : -1,
|
|||
|
|
iterable = Object(collection);
|
|||
|
|
|
|||
|
|
while ((fromRight ? index-- : ++index < length)) {
|
|||
|
|
if (iteratee(iterable[index], index, iterable) === false) {
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return collection;
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Creates a base function for methods like `_.forIn` and `_.forOwn`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {boolean} [fromRight] Specify iterating from right to left.
|
|||
|
|
* @returns {Function} Returns the new base function.
|
|||
|
|
*/
|
|||
|
|
function createBaseFor(fromRight) {
|
|||
|
|
return function(object, iteratee, keysFunc) {
|
|||
|
|
var index = -1,
|
|||
|
|
iterable = Object(object),
|
|||
|
|
props = keysFunc(object),
|
|||
|
|
length = props.length;
|
|||
|
|
|
|||
|
|
while (length--) {
|
|||
|
|
var key = props[fromRight ? length : ++index];
|
|||
|
|
if (iteratee(iterable[key], key, iterable) === false) {
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return object;
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is a valid array-like index.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
|
|||
|
|
*/
|
|||
|
|
function isIndex(value, length) {
|
|||
|
|
length = length == null ? MAX_SAFE_INTEGER : length;
|
|||
|
|
return !!length &&
|
|||
|
|
(typeof value == 'number' || reIsUint.test(value)) &&
|
|||
|
|
(value > -1 && value % 1 == 0 && value < length);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is likely a prototype object.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
|
|||
|
|
*/
|
|||
|
|
function isPrototype(value) {
|
|||
|
|
var Ctor = value && value.constructor,
|
|||
|
|
proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto$3;
|
|||
|
|
|
|||
|
|
return value === proto;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Iterates over elements of `collection` and invokes `iteratee` for each element.
|
|||
|
|
* The iteratee is invoked with three arguments: (value, index|key, collection).
|
|||
|
|
* Iteratee functions may exit iteration early by explicitly returning `false`.
|
|||
|
|
*
|
|||
|
|
* **Note:** As with other "Collections" methods, objects with a "length"
|
|||
|
|
* property are iterated like arrays. To avoid this behavior use `_.forIn`
|
|||
|
|
* or `_.forOwn` for object iteration.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 0.1.0
|
|||
|
|
* @alias each
|
|||
|
|
* @category Collection
|
|||
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|||
|
|
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
|||
|
|
* @returns {Array|Object} Returns `collection`.
|
|||
|
|
* @see _.forEachRight
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _([1, 2]).forEach(function(value) {
|
|||
|
|
* console.log(value);
|
|||
|
|
* });
|
|||
|
|
* // => Logs `1` then `2`.
|
|||
|
|
*
|
|||
|
|
* _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
|
|||
|
|
* console.log(key);
|
|||
|
|
* });
|
|||
|
|
* // => Logs 'a' then 'b' (iteration order is not guaranteed).
|
|||
|
|
*/
|
|||
|
|
function forEach(collection, iteratee) {
|
|||
|
|
var func = isArray(collection) ? arrayEach : baseEach;
|
|||
|
|
return func(collection, typeof iteratee == 'function' ? iteratee : identity);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is likely an `arguments` object.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 0.1.0
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is an `arguments` object,
|
|||
|
|
* else `false`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.isArguments(function() { return arguments; }());
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isArguments([1, 2, 3]);
|
|||
|
|
* // => false
|
|||
|
|
*/
|
|||
|
|
function isArguments(value) {
|
|||
|
|
// Safari 8.1 makes `arguments.callee` enumerable in strict mode.
|
|||
|
|
return isArrayLikeObject(value) && hasOwnProperty$1.call(value, 'callee') &&
|
|||
|
|
(!propertyIsEnumerable.call(value, 'callee') || objectToString$3.call(value) == argsTag);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is classified as an `Array` object.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 0.1.0
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is an array, else `false`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.isArray([1, 2, 3]);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isArray(document.body.children);
|
|||
|
|
* // => false
|
|||
|
|
*
|
|||
|
|
* _.isArray('abc');
|
|||
|
|
* // => false
|
|||
|
|
*
|
|||
|
|
* _.isArray(_.noop);
|
|||
|
|
* // => false
|
|||
|
|
*/
|
|||
|
|
var isArray = Array.isArray;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is array-like. A value is considered array-like if it's
|
|||
|
|
* not a function and has a `value.length` that's an integer greater than or
|
|||
|
|
* equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 4.0.0
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is array-like, else `false`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.isArrayLike([1, 2, 3]);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isArrayLike(document.body.children);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isArrayLike('abc');
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isArrayLike(_.noop);
|
|||
|
|
* // => false
|
|||
|
|
*/
|
|||
|
|
function isArrayLike(value) {
|
|||
|
|
return value != null && isLength(value.length) && !isFunction(value);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* This method is like `_.isArrayLike` except that it also checks if `value`
|
|||
|
|
* is an object.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 4.0.0
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is an array-like object,
|
|||
|
|
* else `false`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.isArrayLikeObject([1, 2, 3]);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isArrayLikeObject(document.body.children);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isArrayLikeObject('abc');
|
|||
|
|
* // => false
|
|||
|
|
*
|
|||
|
|
* _.isArrayLikeObject(_.noop);
|
|||
|
|
* // => false
|
|||
|
|
*/
|
|||
|
|
function isArrayLikeObject(value) {
|
|||
|
|
return isObjectLike$3(value) && isArrayLike(value);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is classified as a `Function` object.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 0.1.0
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is a function, else `false`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.isFunction(_);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isFunction(/abc/);
|
|||
|
|
* // => false
|
|||
|
|
*/
|
|||
|
|
function isFunction(value) {
|
|||
|
|
// The use of `Object#toString` avoids issues with the `typeof` operator
|
|||
|
|
// in Safari 8-9 which returns 'object' for typed array and other constructors.
|
|||
|
|
var tag = isObject$2(value) ? objectToString$3.call(value) : '';
|
|||
|
|
return tag == funcTag || tag == genTag;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is a valid array-like length.
|
|||
|
|
*
|
|||
|
|
* **Note:** This method is loosely based on
|
|||
|
|
* [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 4.0.0
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.isLength(3);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isLength(Number.MIN_VALUE);
|
|||
|
|
* // => false
|
|||
|
|
*
|
|||
|
|
* _.isLength(Infinity);
|
|||
|
|
* // => false
|
|||
|
|
*
|
|||
|
|
* _.isLength('3');
|
|||
|
|
* // => false
|
|||
|
|
*/
|
|||
|
|
function isLength(value) {
|
|||
|
|
return typeof value == 'number' &&
|
|||
|
|
value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is the
|
|||
|
|
* [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
|
|||
|
|
* of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 0.1.0
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is an object, else `false`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.isObject({});
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isObject([1, 2, 3]);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isObject(_.noop);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isObject(null);
|
|||
|
|
* // => false
|
|||
|
|
*/
|
|||
|
|
function isObject$2(value) {
|
|||
|
|
var type = typeof value;
|
|||
|
|
return !!value && (type == 'object' || type == 'function');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is object-like. A value is object-like if it's not `null`
|
|||
|
|
* and has a `typeof` result of "object".
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 4.0.0
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.isObjectLike({});
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isObjectLike([1, 2, 3]);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isObjectLike(_.noop);
|
|||
|
|
* // => false
|
|||
|
|
*
|
|||
|
|
* _.isObjectLike(null);
|
|||
|
|
* // => false
|
|||
|
|
*/
|
|||
|
|
function isObjectLike$3(value) {
|
|||
|
|
return !!value && typeof value == 'object';
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Creates an array of the own enumerable property names of `object`.
|
|||
|
|
*
|
|||
|
|
* **Note:** Non-object values are coerced to objects. See the
|
|||
|
|
* [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
|
|||
|
|
* for more details.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @since 0.1.0
|
|||
|
|
* @memberOf _
|
|||
|
|
* @category Object
|
|||
|
|
* @param {Object} object The object to query.
|
|||
|
|
* @returns {Array} Returns the array of property names.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* function Foo() {
|
|||
|
|
* this.a = 1;
|
|||
|
|
* this.b = 2;
|
|||
|
|
* }
|
|||
|
|
*
|
|||
|
|
* Foo.prototype.c = 3;
|
|||
|
|
*
|
|||
|
|
* _.keys(new Foo);
|
|||
|
|
* // => ['a', 'b'] (iteration order is not guaranteed)
|
|||
|
|
*
|
|||
|
|
* _.keys('hi');
|
|||
|
|
* // => ['0', '1']
|
|||
|
|
*/
|
|||
|
|
function keys(object) {
|
|||
|
|
return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* This method returns the first argument it receives.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @since 0.1.0
|
|||
|
|
* @memberOf _
|
|||
|
|
* @category Util
|
|||
|
|
* @param {*} value Any value.
|
|||
|
|
* @returns {*} Returns `value`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* var object = { 'a': 1 };
|
|||
|
|
*
|
|||
|
|
* console.log(_.identity(object) === object);
|
|||
|
|
* // => true
|
|||
|
|
*/
|
|||
|
|
function identity(value) {
|
|||
|
|
return value;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var lodash_foreach = forEach;
|
|||
|
|
|
|||
|
|
let urlAlphabet$1 =
|
|||
|
|
'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict';
|
|||
|
|
var urlAlphabet_1 = { urlAlphabet: urlAlphabet$1 };
|
|||
|
|
|
|||
|
|
let { urlAlphabet } = urlAlphabet_1;
|
|||
|
|
{
|
|||
|
|
if (
|
|||
|
|
typeof navigator !== 'undefined' &&
|
|||
|
|
navigator.product === 'ReactNative' &&
|
|||
|
|
typeof crypto === 'undefined'
|
|||
|
|
) {
|
|||
|
|
throw new Error(
|
|||
|
|
'React Native does not have a built-in secure random generator. ' +
|
|||
|
|
'If you don’t need unpredictable IDs use `nanoid/non-secure`. ' +
|
|||
|
|
'For secure IDs, import `react-native-get-random-values` ' +
|
|||
|
|
'before Nano ID.'
|
|||
|
|
)
|
|||
|
|
}
|
|||
|
|
if (typeof msCrypto !== 'undefined' && typeof crypto === 'undefined') {
|
|||
|
|
throw new Error(
|
|||
|
|
'Import file with `if (!window.crypto) window.crypto = window.msCrypto`' +
|
|||
|
|
' before importing Nano ID to fix IE 11 support'
|
|||
|
|
)
|
|||
|
|
}
|
|||
|
|
if (typeof crypto === 'undefined') {
|
|||
|
|
throw new Error(
|
|||
|
|
'Your browser does not have secure random generator. ' +
|
|||
|
|
'If you don’t need unpredictable IDs, you can use nanoid/non-secure.'
|
|||
|
|
)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
let random = bytes => crypto.getRandomValues(new Uint8Array(bytes));
|
|||
|
|
let customRandom = (alphabet, size, getRandom) => {
|
|||
|
|
let mask = (2 << (Math.log(alphabet.length - 1) / Math.LN2)) - 1;
|
|||
|
|
let step = -~((1.6 * mask * size) / alphabet.length);
|
|||
|
|
return () => {
|
|||
|
|
let id = '';
|
|||
|
|
while (true) {
|
|||
|
|
let bytes = getRandom(step);
|
|||
|
|
let j = step;
|
|||
|
|
while (j--) {
|
|||
|
|
id += alphabet[bytes[j] & mask] || '';
|
|||
|
|
if (id.length === size) return id
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
let customAlphabet = (alphabet, size) => customRandom(alphabet, size, random);
|
|||
|
|
let nanoid$2 = (size = 21) => {
|
|||
|
|
let id = '';
|
|||
|
|
let bytes = crypto.getRandomValues(new Uint8Array(size));
|
|||
|
|
while (size--) {
|
|||
|
|
let byte = bytes[size] & 63;
|
|||
|
|
if (byte < 36) {
|
|||
|
|
id += byte.toString(36);
|
|||
|
|
} else if (byte < 62) {
|
|||
|
|
id += (byte - 26).toString(36).toUpperCase();
|
|||
|
|
} else if (byte < 63) {
|
|||
|
|
id += '_';
|
|||
|
|
} else {
|
|||
|
|
id += '-';
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return id
|
|||
|
|
};
|
|||
|
|
var index_browser = { nanoid: nanoid$2, customAlphabet, customRandom, urlAlphabet, random };
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* lodash (Custom Build) <https://lodash.com/>
|
|||
|
|
* Build: `lodash modularize exports="npm" -o ./`
|
|||
|
|
* Copyright jQuery Foundation and other contributors <https://jquery.org/>
|
|||
|
|
* Released under MIT license <https://lodash.com/license>
|
|||
|
|
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
|
|||
|
|
* Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
/** Used as the `TypeError` message for "Functions" methods. */
|
|||
|
|
var FUNC_ERROR_TEXT$1 = 'Expected a function';
|
|||
|
|
|
|||
|
|
/** Used as references for various `Number` constants. */
|
|||
|
|
var NAN$1 = 0 / 0;
|
|||
|
|
|
|||
|
|
/** `Object#toString` result references. */
|
|||
|
|
var symbolTag$2 = '[object Symbol]';
|
|||
|
|
|
|||
|
|
/** Used to match leading and trailing whitespace. */
|
|||
|
|
var reTrim$1 = /^\s+|\s+$/g;
|
|||
|
|
|
|||
|
|
/** Used to detect bad signed hexadecimal string values. */
|
|||
|
|
var reIsBadHex$1 = /^[-+]0x[0-9a-f]+$/i;
|
|||
|
|
|
|||
|
|
/** Used to detect binary string values. */
|
|||
|
|
var reIsBinary$1 = /^0b[01]+$/i;
|
|||
|
|
|
|||
|
|
/** Used to detect octal string values. */
|
|||
|
|
var reIsOctal$1 = /^0o[0-7]+$/i;
|
|||
|
|
|
|||
|
|
/** Built-in method references without a dependency on `root`. */
|
|||
|
|
var freeParseInt$1 = parseInt;
|
|||
|
|
|
|||
|
|
/** Detect free variable `global` from Node.js. */
|
|||
|
|
var freeGlobal$2 = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;
|
|||
|
|
|
|||
|
|
/** Detect free variable `self`. */
|
|||
|
|
var freeSelf$2 = typeof self == 'object' && self && self.Object === Object && self;
|
|||
|
|
|
|||
|
|
/** Used as a reference to the global object. */
|
|||
|
|
var root$2 = freeGlobal$2 || freeSelf$2 || Function('return this')();
|
|||
|
|
|
|||
|
|
/** Used for built-in method references. */
|
|||
|
|
var objectProto$2 = Object.prototype;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Used to resolve the
|
|||
|
|
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
|
|||
|
|
* of values.
|
|||
|
|
*/
|
|||
|
|
var objectToString$2 = objectProto$2.toString;
|
|||
|
|
|
|||
|
|
/* Built-in method references for those with the same name as other `lodash` methods. */
|
|||
|
|
var nativeMax$1 = Math.max,
|
|||
|
|
nativeMin$1 = Math.min;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Gets the timestamp of the number of milliseconds that have elapsed since
|
|||
|
|
* the Unix epoch (1 January 1970 00:00:00 UTC).
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 2.4.0
|
|||
|
|
* @category Date
|
|||
|
|
* @returns {number} Returns the timestamp.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.defer(function(stamp) {
|
|||
|
|
* console.log(_.now() - stamp);
|
|||
|
|
* }, _.now());
|
|||
|
|
* // => Logs the number of milliseconds it took for the deferred invocation.
|
|||
|
|
*/
|
|||
|
|
var now$1 = function() {
|
|||
|
|
return root$2.Date.now();
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Creates a debounced function that delays invoking `func` until after `wait`
|
|||
|
|
* milliseconds have elapsed since the last time the debounced function was
|
|||
|
|
* invoked. The debounced function comes with a `cancel` method to cancel
|
|||
|
|
* delayed `func` invocations and a `flush` method to immediately invoke them.
|
|||
|
|
* Provide `options` to indicate whether `func` should be invoked on the
|
|||
|
|
* leading and/or trailing edge of the `wait` timeout. The `func` is invoked
|
|||
|
|
* with the last arguments provided to the debounced function. Subsequent
|
|||
|
|
* calls to the debounced function return the result of the last `func`
|
|||
|
|
* invocation.
|
|||
|
|
*
|
|||
|
|
* **Note:** If `leading` and `trailing` options are `true`, `func` is
|
|||
|
|
* invoked on the trailing edge of the timeout only if the debounced function
|
|||
|
|
* is invoked more than once during the `wait` timeout.
|
|||
|
|
*
|
|||
|
|
* If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
|
|||
|
|
* until to the next tick, similar to `setTimeout` with a timeout of `0`.
|
|||
|
|
*
|
|||
|
|
* See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
|
|||
|
|
* for details over the differences between `_.debounce` and `_.throttle`.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 0.1.0
|
|||
|
|
* @category Function
|
|||
|
|
* @param {Function} func The function to debounce.
|
|||
|
|
* @param {number} [wait=0] The number of milliseconds to delay.
|
|||
|
|
* @param {Object} [options={}] The options object.
|
|||
|
|
* @param {boolean} [options.leading=false]
|
|||
|
|
* Specify invoking on the leading edge of the timeout.
|
|||
|
|
* @param {number} [options.maxWait]
|
|||
|
|
* The maximum time `func` is allowed to be delayed before it's invoked.
|
|||
|
|
* @param {boolean} [options.trailing=true]
|
|||
|
|
* Specify invoking on the trailing edge of the timeout.
|
|||
|
|
* @returns {Function} Returns the new debounced function.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* // Avoid costly calculations while the window size is in flux.
|
|||
|
|
* jQuery(window).on('resize', _.debounce(calculateLayout, 150));
|
|||
|
|
*
|
|||
|
|
* // Invoke `sendMail` when clicked, debouncing subsequent calls.
|
|||
|
|
* jQuery(element).on('click', _.debounce(sendMail, 300, {
|
|||
|
|
* 'leading': true,
|
|||
|
|
* 'trailing': false
|
|||
|
|
* }));
|
|||
|
|
*
|
|||
|
|
* // Ensure `batchLog` is invoked once after 1 second of debounced calls.
|
|||
|
|
* var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
|
|||
|
|
* var source = new EventSource('/stream');
|
|||
|
|
* jQuery(source).on('message', debounced);
|
|||
|
|
*
|
|||
|
|
* // Cancel the trailing debounced invocation.
|
|||
|
|
* jQuery(window).on('popstate', debounced.cancel);
|
|||
|
|
*/
|
|||
|
|
function debounce$2(func, wait, options) {
|
|||
|
|
var lastArgs,
|
|||
|
|
lastThis,
|
|||
|
|
maxWait,
|
|||
|
|
result,
|
|||
|
|
timerId,
|
|||
|
|
lastCallTime,
|
|||
|
|
lastInvokeTime = 0,
|
|||
|
|
leading = false,
|
|||
|
|
maxing = false,
|
|||
|
|
trailing = true;
|
|||
|
|
|
|||
|
|
if (typeof func != 'function') {
|
|||
|
|
throw new TypeError(FUNC_ERROR_TEXT$1);
|
|||
|
|
}
|
|||
|
|
wait = toNumber$1(wait) || 0;
|
|||
|
|
if (isObject$1(options)) {
|
|||
|
|
leading = !!options.leading;
|
|||
|
|
maxing = 'maxWait' in options;
|
|||
|
|
maxWait = maxing ? nativeMax$1(toNumber$1(options.maxWait) || 0, wait) : maxWait;
|
|||
|
|
trailing = 'trailing' in options ? !!options.trailing : trailing;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function invokeFunc(time) {
|
|||
|
|
var args = lastArgs,
|
|||
|
|
thisArg = lastThis;
|
|||
|
|
|
|||
|
|
lastArgs = lastThis = undefined;
|
|||
|
|
lastInvokeTime = time;
|
|||
|
|
result = func.apply(thisArg, args);
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function leadingEdge(time) {
|
|||
|
|
// Reset any `maxWait` timer.
|
|||
|
|
lastInvokeTime = time;
|
|||
|
|
// Start the timer for the trailing edge.
|
|||
|
|
timerId = setTimeout(timerExpired, wait);
|
|||
|
|
// Invoke the leading edge.
|
|||
|
|
return leading ? invokeFunc(time) : result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function remainingWait(time) {
|
|||
|
|
var timeSinceLastCall = time - lastCallTime,
|
|||
|
|
timeSinceLastInvoke = time - lastInvokeTime,
|
|||
|
|
result = wait - timeSinceLastCall;
|
|||
|
|
|
|||
|
|
return maxing ? nativeMin$1(result, maxWait - timeSinceLastInvoke) : result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function shouldInvoke(time) {
|
|||
|
|
var timeSinceLastCall = time - lastCallTime,
|
|||
|
|
timeSinceLastInvoke = time - lastInvokeTime;
|
|||
|
|
|
|||
|
|
// Either this is the first call, activity has stopped and we're at the
|
|||
|
|
// trailing edge, the system time has gone backwards and we're treating
|
|||
|
|
// it as the trailing edge, or we've hit the `maxWait` limit.
|
|||
|
|
return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
|
|||
|
|
(timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function timerExpired() {
|
|||
|
|
var time = now$1();
|
|||
|
|
if (shouldInvoke(time)) {
|
|||
|
|
return trailingEdge(time);
|
|||
|
|
}
|
|||
|
|
// Restart the timer.
|
|||
|
|
timerId = setTimeout(timerExpired, remainingWait(time));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function trailingEdge(time) {
|
|||
|
|
timerId = undefined;
|
|||
|
|
|
|||
|
|
// Only invoke if we have `lastArgs` which means `func` has been
|
|||
|
|
// debounced at least once.
|
|||
|
|
if (trailing && lastArgs) {
|
|||
|
|
return invokeFunc(time);
|
|||
|
|
}
|
|||
|
|
lastArgs = lastThis = undefined;
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function cancel() {
|
|||
|
|
if (timerId !== undefined) {
|
|||
|
|
clearTimeout(timerId);
|
|||
|
|
}
|
|||
|
|
lastInvokeTime = 0;
|
|||
|
|
lastArgs = lastCallTime = lastThis = timerId = undefined;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function flush() {
|
|||
|
|
return timerId === undefined ? result : trailingEdge(now$1());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function debounced() {
|
|||
|
|
var time = now$1(),
|
|||
|
|
isInvoking = shouldInvoke(time);
|
|||
|
|
|
|||
|
|
lastArgs = arguments;
|
|||
|
|
lastThis = this;
|
|||
|
|
lastCallTime = time;
|
|||
|
|
|
|||
|
|
if (isInvoking) {
|
|||
|
|
if (timerId === undefined) {
|
|||
|
|
return leadingEdge(lastCallTime);
|
|||
|
|
}
|
|||
|
|
if (maxing) {
|
|||
|
|
// Handle invocations in a tight loop.
|
|||
|
|
timerId = setTimeout(timerExpired, wait);
|
|||
|
|
return invokeFunc(lastCallTime);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if (timerId === undefined) {
|
|||
|
|
timerId = setTimeout(timerExpired, wait);
|
|||
|
|
}
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
debounced.cancel = cancel;
|
|||
|
|
debounced.flush = flush;
|
|||
|
|
return debounced;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Creates a throttled function that only invokes `func` at most once per
|
|||
|
|
* every `wait` milliseconds. The throttled function comes with a `cancel`
|
|||
|
|
* method to cancel delayed `func` invocations and a `flush` method to
|
|||
|
|
* immediately invoke them. Provide `options` to indicate whether `func`
|
|||
|
|
* should be invoked on the leading and/or trailing edge of the `wait`
|
|||
|
|
* timeout. The `func` is invoked with the last arguments provided to the
|
|||
|
|
* throttled function. Subsequent calls to the throttled function return the
|
|||
|
|
* result of the last `func` invocation.
|
|||
|
|
*
|
|||
|
|
* **Note:** If `leading` and `trailing` options are `true`, `func` is
|
|||
|
|
* invoked on the trailing edge of the timeout only if the throttled function
|
|||
|
|
* is invoked more than once during the `wait` timeout.
|
|||
|
|
*
|
|||
|
|
* If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
|
|||
|
|
* until to the next tick, similar to `setTimeout` with a timeout of `0`.
|
|||
|
|
*
|
|||
|
|
* See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
|
|||
|
|
* for details over the differences between `_.throttle` and `_.debounce`.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 0.1.0
|
|||
|
|
* @category Function
|
|||
|
|
* @param {Function} func The function to throttle.
|
|||
|
|
* @param {number} [wait=0] The number of milliseconds to throttle invocations to.
|
|||
|
|
* @param {Object} [options={}] The options object.
|
|||
|
|
* @param {boolean} [options.leading=true]
|
|||
|
|
* Specify invoking on the leading edge of the timeout.
|
|||
|
|
* @param {boolean} [options.trailing=true]
|
|||
|
|
* Specify invoking on the trailing edge of the timeout.
|
|||
|
|
* @returns {Function} Returns the new throttled function.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* // Avoid excessively updating the position while scrolling.
|
|||
|
|
* jQuery(window).on('scroll', _.throttle(updatePosition, 100));
|
|||
|
|
*
|
|||
|
|
* // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
|
|||
|
|
* var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
|
|||
|
|
* jQuery(element).on('click', throttled);
|
|||
|
|
*
|
|||
|
|
* // Cancel the trailing throttled invocation.
|
|||
|
|
* jQuery(window).on('popstate', throttled.cancel);
|
|||
|
|
*/
|
|||
|
|
function throttle(func, wait, options) {
|
|||
|
|
var leading = true,
|
|||
|
|
trailing = true;
|
|||
|
|
|
|||
|
|
if (typeof func != 'function') {
|
|||
|
|
throw new TypeError(FUNC_ERROR_TEXT$1);
|
|||
|
|
}
|
|||
|
|
if (isObject$1(options)) {
|
|||
|
|
leading = 'leading' in options ? !!options.leading : leading;
|
|||
|
|
trailing = 'trailing' in options ? !!options.trailing : trailing;
|
|||
|
|
}
|
|||
|
|
return debounce$2(func, wait, {
|
|||
|
|
'leading': leading,
|
|||
|
|
'maxWait': wait,
|
|||
|
|
'trailing': trailing
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is the
|
|||
|
|
* [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
|
|||
|
|
* of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 0.1.0
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is an object, else `false`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.isObject({});
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isObject([1, 2, 3]);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isObject(_.noop);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isObject(null);
|
|||
|
|
* // => false
|
|||
|
|
*/
|
|||
|
|
function isObject$1(value) {
|
|||
|
|
var type = typeof value;
|
|||
|
|
return !!value && (type == 'object' || type == 'function');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is object-like. A value is object-like if it's not `null`
|
|||
|
|
* and has a `typeof` result of "object".
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 4.0.0
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.isObjectLike({});
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isObjectLike([1, 2, 3]);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isObjectLike(_.noop);
|
|||
|
|
* // => false
|
|||
|
|
*
|
|||
|
|
* _.isObjectLike(null);
|
|||
|
|
* // => false
|
|||
|
|
*/
|
|||
|
|
function isObjectLike$2(value) {
|
|||
|
|
return !!value && typeof value == 'object';
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is classified as a `Symbol` primitive or object.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 4.0.0
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.isSymbol(Symbol.iterator);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isSymbol('abc');
|
|||
|
|
* // => false
|
|||
|
|
*/
|
|||
|
|
function isSymbol$2(value) {
|
|||
|
|
return typeof value == 'symbol' ||
|
|||
|
|
(isObjectLike$2(value) && objectToString$2.call(value) == symbolTag$2);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Converts `value` to a number.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 4.0.0
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to process.
|
|||
|
|
* @returns {number} Returns the number.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.toNumber(3.2);
|
|||
|
|
* // => 3.2
|
|||
|
|
*
|
|||
|
|
* _.toNumber(Number.MIN_VALUE);
|
|||
|
|
* // => 5e-324
|
|||
|
|
*
|
|||
|
|
* _.toNumber(Infinity);
|
|||
|
|
* // => Infinity
|
|||
|
|
*
|
|||
|
|
* _.toNumber('3.2');
|
|||
|
|
* // => 3.2
|
|||
|
|
*/
|
|||
|
|
function toNumber$1(value) {
|
|||
|
|
if (typeof value == 'number') {
|
|||
|
|
return value;
|
|||
|
|
}
|
|||
|
|
if (isSymbol$2(value)) {
|
|||
|
|
return NAN$1;
|
|||
|
|
}
|
|||
|
|
if (isObject$1(value)) {
|
|||
|
|
var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
|
|||
|
|
value = isObject$1(other) ? (other + '') : other;
|
|||
|
|
}
|
|||
|
|
if (typeof value != 'string') {
|
|||
|
|
return value === 0 ? value : +value;
|
|||
|
|
}
|
|||
|
|
value = value.replace(reTrim$1, '');
|
|||
|
|
var isBinary = reIsBinary$1.test(value);
|
|||
|
|
return (isBinary || reIsOctal$1.test(value))
|
|||
|
|
? freeParseInt$1(value.slice(2), isBinary ? 2 : 8)
|
|||
|
|
: (reIsBadHex$1.test(value) ? NAN$1 : +value);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var lodash_throttle = throttle;
|
|||
|
|
|
|||
|
|
var snabbdom_cjs = createCommonjsModule$1(function (module, exports) {
|
|||
|
|
|
|||
|
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|||
|
|
|
|||
|
|
function createElement(tagName, options) {
|
|||
|
|
return document.createElement(tagName, options);
|
|||
|
|
}
|
|||
|
|
function createElementNS(namespaceURI, qualifiedName, options) {
|
|||
|
|
return document.createElementNS(namespaceURI, qualifiedName, options);
|
|||
|
|
}
|
|||
|
|
function createTextNode(text) {
|
|||
|
|
return document.createTextNode(text);
|
|||
|
|
}
|
|||
|
|
function createComment(text) {
|
|||
|
|
return document.createComment(text);
|
|||
|
|
}
|
|||
|
|
function insertBefore(parentNode, newNode, referenceNode) {
|
|||
|
|
parentNode.insertBefore(newNode, referenceNode);
|
|||
|
|
}
|
|||
|
|
function removeChild(node, child) {
|
|||
|
|
node.removeChild(child);
|
|||
|
|
}
|
|||
|
|
function appendChild(node, child) {
|
|||
|
|
node.appendChild(child);
|
|||
|
|
}
|
|||
|
|
function parentNode(node) {
|
|||
|
|
return node.parentNode;
|
|||
|
|
}
|
|||
|
|
function nextSibling(node) {
|
|||
|
|
return node.nextSibling;
|
|||
|
|
}
|
|||
|
|
function tagName(elm) {
|
|||
|
|
return elm.tagName;
|
|||
|
|
}
|
|||
|
|
function setTextContent(node, text) {
|
|||
|
|
node.textContent = text;
|
|||
|
|
}
|
|||
|
|
function getTextContent(node) {
|
|||
|
|
return node.textContent;
|
|||
|
|
}
|
|||
|
|
function isElement(node) {
|
|||
|
|
return node.nodeType === 1;
|
|||
|
|
}
|
|||
|
|
function isText(node) {
|
|||
|
|
return node.nodeType === 3;
|
|||
|
|
}
|
|||
|
|
function isComment(node) {
|
|||
|
|
return node.nodeType === 8;
|
|||
|
|
}
|
|||
|
|
const htmlDomApi = {
|
|||
|
|
createElement,
|
|||
|
|
createElementNS,
|
|||
|
|
createTextNode,
|
|||
|
|
createComment,
|
|||
|
|
insertBefore,
|
|||
|
|
removeChild,
|
|||
|
|
appendChild,
|
|||
|
|
parentNode,
|
|||
|
|
nextSibling,
|
|||
|
|
tagName,
|
|||
|
|
setTextContent,
|
|||
|
|
getTextContent,
|
|||
|
|
isElement,
|
|||
|
|
isText,
|
|||
|
|
isComment,
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
function vnode(sel, data, children, text, elm) {
|
|||
|
|
const key = data === undefined ? undefined : data.key;
|
|||
|
|
return { sel, data, children, text, elm, key };
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const array = Array.isArray;
|
|||
|
|
function primitive(s) {
|
|||
|
|
return typeof s === "string" ||
|
|||
|
|
typeof s === "number" ||
|
|||
|
|
s instanceof String ||
|
|||
|
|
s instanceof Number;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function isUndef(s) {
|
|||
|
|
return s === undefined;
|
|||
|
|
}
|
|||
|
|
function isDef(s) {
|
|||
|
|
return s !== undefined;
|
|||
|
|
}
|
|||
|
|
const emptyNode = vnode("", {}, [], undefined, undefined);
|
|||
|
|
function sameVnode(vnode1, vnode2) {
|
|||
|
|
var _a, _b;
|
|||
|
|
const isSameKey = vnode1.key === vnode2.key;
|
|||
|
|
const isSameIs = ((_a = vnode1.data) === null || _a === void 0 ? void 0 : _a.is) === ((_b = vnode2.data) === null || _b === void 0 ? void 0 : _b.is);
|
|||
|
|
const isSameSel = vnode1.sel === vnode2.sel;
|
|||
|
|
return isSameSel && isSameKey && isSameIs;
|
|||
|
|
}
|
|||
|
|
function isVnode(vnode) {
|
|||
|
|
return vnode.sel !== undefined;
|
|||
|
|
}
|
|||
|
|
function createKeyToOldIdx(children, beginIdx, endIdx) {
|
|||
|
|
var _a;
|
|||
|
|
const map = {};
|
|||
|
|
for (let i = beginIdx; i <= endIdx; ++i) {
|
|||
|
|
const key = (_a = children[i]) === null || _a === void 0 ? void 0 : _a.key;
|
|||
|
|
if (key !== undefined) {
|
|||
|
|
map[key] = i;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return map;
|
|||
|
|
}
|
|||
|
|
const hooks = [
|
|||
|
|
"create",
|
|||
|
|
"update",
|
|||
|
|
"remove",
|
|||
|
|
"destroy",
|
|||
|
|
"pre",
|
|||
|
|
"post",
|
|||
|
|
];
|
|||
|
|
function init$1(modules, domApi) {
|
|||
|
|
const cbs = {
|
|||
|
|
create: [],
|
|||
|
|
update: [],
|
|||
|
|
remove: [],
|
|||
|
|
destroy: [],
|
|||
|
|
pre: [],
|
|||
|
|
post: [],
|
|||
|
|
};
|
|||
|
|
const api = domApi !== undefined ? domApi : htmlDomApi;
|
|||
|
|
for (const hook of hooks) {
|
|||
|
|
for (const module of modules) {
|
|||
|
|
const currentHook = module[hook];
|
|||
|
|
if (currentHook !== undefined) {
|
|||
|
|
cbs[hook].push(currentHook);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function emptyNodeAt(elm) {
|
|||
|
|
const id = elm.id ? "#" + elm.id : "";
|
|||
|
|
// elm.className doesn't return a string when elm is an SVG element inside a shadowRoot.
|
|||
|
|
// https://stackoverflow.com/questions/29454340/detecting-classname-of-svganimatedstring
|
|||
|
|
const classes = elm.getAttribute("class");
|
|||
|
|
const c = classes ? "." + classes.split(" ").join(".") : "";
|
|||
|
|
return vnode(api.tagName(elm).toLowerCase() + id + c, {}, [], undefined, elm);
|
|||
|
|
}
|
|||
|
|
function createRmCb(childElm, listeners) {
|
|||
|
|
return function rmCb() {
|
|||
|
|
if (--listeners === 0) {
|
|||
|
|
const parent = api.parentNode(childElm);
|
|||
|
|
api.removeChild(parent, childElm);
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
function createElm(vnode, insertedVnodeQueue) {
|
|||
|
|
var _a, _b;
|
|||
|
|
let i;
|
|||
|
|
let data = vnode.data;
|
|||
|
|
if (data !== undefined) {
|
|||
|
|
const init = (_a = data.hook) === null || _a === void 0 ? void 0 : _a.init;
|
|||
|
|
if (isDef(init)) {
|
|||
|
|
init(vnode);
|
|||
|
|
data = vnode.data;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
const children = vnode.children;
|
|||
|
|
const sel = vnode.sel;
|
|||
|
|
if (sel === "!") {
|
|||
|
|
if (isUndef(vnode.text)) {
|
|||
|
|
vnode.text = "";
|
|||
|
|
}
|
|||
|
|
vnode.elm = api.createComment(vnode.text);
|
|||
|
|
}
|
|||
|
|
else if (sel !== undefined) {
|
|||
|
|
// Parse selector
|
|||
|
|
const hashIdx = sel.indexOf("#");
|
|||
|
|
const dotIdx = sel.indexOf(".", hashIdx);
|
|||
|
|
const hash = hashIdx > 0 ? hashIdx : sel.length;
|
|||
|
|
const dot = dotIdx > 0 ? dotIdx : sel.length;
|
|||
|
|
const tag = hashIdx !== -1 || dotIdx !== -1
|
|||
|
|
? sel.slice(0, Math.min(hash, dot))
|
|||
|
|
: sel;
|
|||
|
|
const elm = (vnode.elm =
|
|||
|
|
isDef(data) && isDef((i = data.ns))
|
|||
|
|
? api.createElementNS(i, tag, data)
|
|||
|
|
: api.createElement(tag, data));
|
|||
|
|
if (hash < dot)
|
|||
|
|
elm.setAttribute("id", sel.slice(hash + 1, dot));
|
|||
|
|
if (dotIdx > 0)
|
|||
|
|
elm.setAttribute("class", sel.slice(dot + 1).replace(/\./g, " "));
|
|||
|
|
for (i = 0; i < cbs.create.length; ++i)
|
|||
|
|
cbs.create[i](emptyNode, vnode);
|
|||
|
|
if (array(children)) {
|
|||
|
|
for (i = 0; i < children.length; ++i) {
|
|||
|
|
const ch = children[i];
|
|||
|
|
if (ch != null) {
|
|||
|
|
api.appendChild(elm, createElm(ch, insertedVnodeQueue));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else if (primitive(vnode.text)) {
|
|||
|
|
api.appendChild(elm, api.createTextNode(vnode.text));
|
|||
|
|
}
|
|||
|
|
const hook = vnode.data.hook;
|
|||
|
|
if (isDef(hook)) {
|
|||
|
|
(_b = hook.create) === null || _b === void 0 ? void 0 : _b.call(hook, emptyNode, vnode);
|
|||
|
|
if (hook.insert) {
|
|||
|
|
insertedVnodeQueue.push(vnode);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
vnode.elm = api.createTextNode(vnode.text);
|
|||
|
|
}
|
|||
|
|
return vnode.elm;
|
|||
|
|
}
|
|||
|
|
function addVnodes(parentElm, before, vnodes, startIdx, endIdx, insertedVnodeQueue) {
|
|||
|
|
for (; startIdx <= endIdx; ++startIdx) {
|
|||
|
|
const ch = vnodes[startIdx];
|
|||
|
|
if (ch != null) {
|
|||
|
|
api.insertBefore(parentElm, createElm(ch, insertedVnodeQueue), before);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function invokeDestroyHook(vnode) {
|
|||
|
|
var _a, _b;
|
|||
|
|
const data = vnode.data;
|
|||
|
|
if (data !== undefined) {
|
|||
|
|
(_b = (_a = data === null || data === void 0 ? void 0 : data.hook) === null || _a === void 0 ? void 0 : _a.destroy) === null || _b === void 0 ? void 0 : _b.call(_a, vnode);
|
|||
|
|
for (let i = 0; i < cbs.destroy.length; ++i)
|
|||
|
|
cbs.destroy[i](vnode);
|
|||
|
|
if (vnode.children !== undefined) {
|
|||
|
|
for (let j = 0; j < vnode.children.length; ++j) {
|
|||
|
|
const child = vnode.children[j];
|
|||
|
|
if (child != null && typeof child !== "string") {
|
|||
|
|
invokeDestroyHook(child);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function removeVnodes(parentElm, vnodes, startIdx, endIdx) {
|
|||
|
|
var _a, _b;
|
|||
|
|
for (; startIdx <= endIdx; ++startIdx) {
|
|||
|
|
let listeners;
|
|||
|
|
let rm;
|
|||
|
|
const ch = vnodes[startIdx];
|
|||
|
|
if (ch != null) {
|
|||
|
|
if (isDef(ch.sel)) {
|
|||
|
|
invokeDestroyHook(ch);
|
|||
|
|
listeners = cbs.remove.length + 1;
|
|||
|
|
rm = createRmCb(ch.elm, listeners);
|
|||
|
|
for (let i = 0; i < cbs.remove.length; ++i)
|
|||
|
|
cbs.remove[i](ch, rm);
|
|||
|
|
const removeHook = (_b = (_a = ch === null || ch === void 0 ? void 0 : ch.data) === null || _a === void 0 ? void 0 : _a.hook) === null || _b === void 0 ? void 0 : _b.remove;
|
|||
|
|
if (isDef(removeHook)) {
|
|||
|
|
removeHook(ch, rm);
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
rm();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
// Text node
|
|||
|
|
api.removeChild(parentElm, ch.elm);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function updateChildren(parentElm, oldCh, newCh, insertedVnodeQueue) {
|
|||
|
|
let oldStartIdx = 0;
|
|||
|
|
let newStartIdx = 0;
|
|||
|
|
let oldEndIdx = oldCh.length - 1;
|
|||
|
|
let oldStartVnode = oldCh[0];
|
|||
|
|
let oldEndVnode = oldCh[oldEndIdx];
|
|||
|
|
let newEndIdx = newCh.length - 1;
|
|||
|
|
let newStartVnode = newCh[0];
|
|||
|
|
let newEndVnode = newCh[newEndIdx];
|
|||
|
|
let oldKeyToIdx;
|
|||
|
|
let idxInOld;
|
|||
|
|
let elmToMove;
|
|||
|
|
let before;
|
|||
|
|
while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {
|
|||
|
|
if (oldStartVnode == null) {
|
|||
|
|
oldStartVnode = oldCh[++oldStartIdx]; // Vnode might have been moved left
|
|||
|
|
}
|
|||
|
|
else if (oldEndVnode == null) {
|
|||
|
|
oldEndVnode = oldCh[--oldEndIdx];
|
|||
|
|
}
|
|||
|
|
else if (newStartVnode == null) {
|
|||
|
|
newStartVnode = newCh[++newStartIdx];
|
|||
|
|
}
|
|||
|
|
else if (newEndVnode == null) {
|
|||
|
|
newEndVnode = newCh[--newEndIdx];
|
|||
|
|
}
|
|||
|
|
else if (sameVnode(oldStartVnode, newStartVnode)) {
|
|||
|
|
patchVnode(oldStartVnode, newStartVnode, insertedVnodeQueue);
|
|||
|
|
oldStartVnode = oldCh[++oldStartIdx];
|
|||
|
|
newStartVnode = newCh[++newStartIdx];
|
|||
|
|
}
|
|||
|
|
else if (sameVnode(oldEndVnode, newEndVnode)) {
|
|||
|
|
patchVnode(oldEndVnode, newEndVnode, insertedVnodeQueue);
|
|||
|
|
oldEndVnode = oldCh[--oldEndIdx];
|
|||
|
|
newEndVnode = newCh[--newEndIdx];
|
|||
|
|
}
|
|||
|
|
else if (sameVnode(oldStartVnode, newEndVnode)) {
|
|||
|
|
// Vnode moved right
|
|||
|
|
patchVnode(oldStartVnode, newEndVnode, insertedVnodeQueue);
|
|||
|
|
api.insertBefore(parentElm, oldStartVnode.elm, api.nextSibling(oldEndVnode.elm));
|
|||
|
|
oldStartVnode = oldCh[++oldStartIdx];
|
|||
|
|
newEndVnode = newCh[--newEndIdx];
|
|||
|
|
}
|
|||
|
|
else if (sameVnode(oldEndVnode, newStartVnode)) {
|
|||
|
|
// Vnode moved left
|
|||
|
|
patchVnode(oldEndVnode, newStartVnode, insertedVnodeQueue);
|
|||
|
|
api.insertBefore(parentElm, oldEndVnode.elm, oldStartVnode.elm);
|
|||
|
|
oldEndVnode = oldCh[--oldEndIdx];
|
|||
|
|
newStartVnode = newCh[++newStartIdx];
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
if (oldKeyToIdx === undefined) {
|
|||
|
|
oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx);
|
|||
|
|
}
|
|||
|
|
idxInOld = oldKeyToIdx[newStartVnode.key];
|
|||
|
|
if (isUndef(idxInOld)) {
|
|||
|
|
// New element
|
|||
|
|
api.insertBefore(parentElm, createElm(newStartVnode, insertedVnodeQueue), oldStartVnode.elm);
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
elmToMove = oldCh[idxInOld];
|
|||
|
|
if (elmToMove.sel !== newStartVnode.sel) {
|
|||
|
|
api.insertBefore(parentElm, createElm(newStartVnode, insertedVnodeQueue), oldStartVnode.elm);
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
patchVnode(elmToMove, newStartVnode, insertedVnodeQueue);
|
|||
|
|
oldCh[idxInOld] = undefined;
|
|||
|
|
api.insertBefore(parentElm, elmToMove.elm, oldStartVnode.elm);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
newStartVnode = newCh[++newStartIdx];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if (oldStartIdx <= oldEndIdx || newStartIdx <= newEndIdx) {
|
|||
|
|
if (oldStartIdx > oldEndIdx) {
|
|||
|
|
before = newCh[newEndIdx + 1] == null ? null : newCh[newEndIdx + 1].elm;
|
|||
|
|
addVnodes(parentElm, before, newCh, newStartIdx, newEndIdx, insertedVnodeQueue);
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
removeVnodes(parentElm, oldCh, oldStartIdx, oldEndIdx);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function patchVnode(oldVnode, vnode, insertedVnodeQueue) {
|
|||
|
|
var _a, _b, _c, _d, _e;
|
|||
|
|
const hook = (_a = vnode.data) === null || _a === void 0 ? void 0 : _a.hook;
|
|||
|
|
(_b = hook === null || hook === void 0 ? void 0 : hook.prepatch) === null || _b === void 0 ? void 0 : _b.call(hook, oldVnode, vnode);
|
|||
|
|
const elm = (vnode.elm = oldVnode.elm);
|
|||
|
|
const oldCh = oldVnode.children;
|
|||
|
|
const ch = vnode.children;
|
|||
|
|
if (oldVnode === vnode)
|
|||
|
|
return;
|
|||
|
|
if (vnode.data !== undefined) {
|
|||
|
|
for (let i = 0; i < cbs.update.length; ++i)
|
|||
|
|
cbs.update[i](oldVnode, vnode);
|
|||
|
|
(_d = (_c = vnode.data.hook) === null || _c === void 0 ? void 0 : _c.update) === null || _d === void 0 ? void 0 : _d.call(_c, oldVnode, vnode);
|
|||
|
|
}
|
|||
|
|
if (isUndef(vnode.text)) {
|
|||
|
|
if (isDef(oldCh) && isDef(ch)) {
|
|||
|
|
if (oldCh !== ch)
|
|||
|
|
updateChildren(elm, oldCh, ch, insertedVnodeQueue);
|
|||
|
|
}
|
|||
|
|
else if (isDef(ch)) {
|
|||
|
|
if (isDef(oldVnode.text))
|
|||
|
|
api.setTextContent(elm, "");
|
|||
|
|
addVnodes(elm, null, ch, 0, ch.length - 1, insertedVnodeQueue);
|
|||
|
|
}
|
|||
|
|
else if (isDef(oldCh)) {
|
|||
|
|
removeVnodes(elm, oldCh, 0, oldCh.length - 1);
|
|||
|
|
}
|
|||
|
|
else if (isDef(oldVnode.text)) {
|
|||
|
|
api.setTextContent(elm, "");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else if (oldVnode.text !== vnode.text) {
|
|||
|
|
if (isDef(oldCh)) {
|
|||
|
|
removeVnodes(elm, oldCh, 0, oldCh.length - 1);
|
|||
|
|
}
|
|||
|
|
api.setTextContent(elm, vnode.text);
|
|||
|
|
}
|
|||
|
|
(_e = hook === null || hook === void 0 ? void 0 : hook.postpatch) === null || _e === void 0 ? void 0 : _e.call(hook, oldVnode, vnode);
|
|||
|
|
}
|
|||
|
|
return function patch(oldVnode, vnode) {
|
|||
|
|
let i, elm, parent;
|
|||
|
|
const insertedVnodeQueue = [];
|
|||
|
|
for (i = 0; i < cbs.pre.length; ++i)
|
|||
|
|
cbs.pre[i]();
|
|||
|
|
if (!isVnode(oldVnode)) {
|
|||
|
|
oldVnode = emptyNodeAt(oldVnode);
|
|||
|
|
}
|
|||
|
|
if (sameVnode(oldVnode, vnode)) {
|
|||
|
|
patchVnode(oldVnode, vnode, insertedVnodeQueue);
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
elm = oldVnode.elm;
|
|||
|
|
parent = api.parentNode(elm);
|
|||
|
|
createElm(vnode, insertedVnodeQueue);
|
|||
|
|
if (parent !== null) {
|
|||
|
|
api.insertBefore(parent, vnode.elm, api.nextSibling(elm));
|
|||
|
|
removeVnodes(parent, [oldVnode], 0, 0);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
for (i = 0; i < insertedVnodeQueue.length; ++i) {
|
|||
|
|
insertedVnodeQueue[i].data.hook.insert(insertedVnodeQueue[i]);
|
|||
|
|
}
|
|||
|
|
for (i = 0; i < cbs.post.length; ++i)
|
|||
|
|
cbs.post[i]();
|
|||
|
|
return vnode;
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function addNS(data, children, sel) {
|
|||
|
|
data.ns = "http://www.w3.org/2000/svg";
|
|||
|
|
if (sel !== "foreignObject" && children !== undefined) {
|
|||
|
|
for (let i = 0; i < children.length; ++i) {
|
|||
|
|
const childData = children[i].data;
|
|||
|
|
if (childData !== undefined) {
|
|||
|
|
addNS(childData, children[i].children, children[i].sel);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function h(sel, b, c) {
|
|||
|
|
let data = {};
|
|||
|
|
let children;
|
|||
|
|
let text;
|
|||
|
|
let i;
|
|||
|
|
if (c !== undefined) {
|
|||
|
|
if (b !== null) {
|
|||
|
|
data = b;
|
|||
|
|
}
|
|||
|
|
if (array(c)) {
|
|||
|
|
children = c;
|
|||
|
|
}
|
|||
|
|
else if (primitive(c)) {
|
|||
|
|
text = c.toString();
|
|||
|
|
}
|
|||
|
|
else if (c && c.sel) {
|
|||
|
|
children = [c];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else if (b !== undefined && b !== null) {
|
|||
|
|
if (array(b)) {
|
|||
|
|
children = b;
|
|||
|
|
}
|
|||
|
|
else if (primitive(b)) {
|
|||
|
|
text = b.toString();
|
|||
|
|
}
|
|||
|
|
else if (b && b.sel) {
|
|||
|
|
children = [b];
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
data = b;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if (children !== undefined) {
|
|||
|
|
for (i = 0; i < children.length; ++i) {
|
|||
|
|
if (primitive(children[i]))
|
|||
|
|
children[i] = vnode(undefined, undefined, undefined, children[i], undefined);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if (sel[0] === "s" &&
|
|||
|
|
sel[1] === "v" &&
|
|||
|
|
sel[2] === "g" &&
|
|||
|
|
(sel.length === 3 || sel[3] === "." || sel[3] === "#")) {
|
|||
|
|
addNS(data, children, sel);
|
|||
|
|
}
|
|||
|
|
return vnode(sel, data, children, text, undefined);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function copyToThunk(vnode, thunk) {
|
|||
|
|
vnode.data.fn = thunk.data.fn;
|
|||
|
|
vnode.data.args = thunk.data.args;
|
|||
|
|
thunk.data = vnode.data;
|
|||
|
|
thunk.children = vnode.children;
|
|||
|
|
thunk.text = vnode.text;
|
|||
|
|
thunk.elm = vnode.elm;
|
|||
|
|
}
|
|||
|
|
function init(thunk) {
|
|||
|
|
const cur = thunk.data;
|
|||
|
|
const vnode = cur.fn(...cur.args);
|
|||
|
|
copyToThunk(vnode, thunk);
|
|||
|
|
}
|
|||
|
|
function prepatch(oldVnode, thunk) {
|
|||
|
|
let i;
|
|||
|
|
const old = oldVnode.data;
|
|||
|
|
const cur = thunk.data;
|
|||
|
|
const oldArgs = old.args;
|
|||
|
|
const args = cur.args;
|
|||
|
|
if (old.fn !== cur.fn || oldArgs.length !== args.length) {
|
|||
|
|
copyToThunk(cur.fn(...args), thunk);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
for (i = 0; i < args.length; ++i) {
|
|||
|
|
if (oldArgs[i] !== args[i]) {
|
|||
|
|
copyToThunk(cur.fn(...args), thunk);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
copyToThunk(oldVnode, thunk);
|
|||
|
|
}
|
|||
|
|
const thunk = function thunk(sel, key, fn, args) {
|
|||
|
|
if (args === undefined) {
|
|||
|
|
args = fn;
|
|||
|
|
fn = key;
|
|||
|
|
key = undefined;
|
|||
|
|
}
|
|||
|
|
return h(sel, {
|
|||
|
|
key: key,
|
|||
|
|
hook: { init, prepatch },
|
|||
|
|
fn: fn,
|
|||
|
|
args: args,
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
function pre(vnode, newVnode) {
|
|||
|
|
const attachData = vnode.data.attachData;
|
|||
|
|
// Copy created placeholder and real element from old vnode
|
|||
|
|
newVnode.data.attachData.placeholder = attachData.placeholder;
|
|||
|
|
newVnode.data.attachData.real = attachData.real;
|
|||
|
|
// Mount real element in vnode so the patch process operates on it
|
|||
|
|
vnode.elm = vnode.data.attachData.real;
|
|||
|
|
}
|
|||
|
|
function post(_, vnode) {
|
|||
|
|
// Mount dummy placeholder in vnode so potential reorders use it
|
|||
|
|
vnode.elm = vnode.data.attachData.placeholder;
|
|||
|
|
}
|
|||
|
|
function destroy(vnode) {
|
|||
|
|
// Remove placeholder
|
|||
|
|
if (vnode.elm !== undefined) {
|
|||
|
|
vnode.elm.parentNode.removeChild(vnode.elm);
|
|||
|
|
}
|
|||
|
|
// Remove real element from where it was inserted
|
|||
|
|
vnode.elm = vnode.data.attachData.real;
|
|||
|
|
}
|
|||
|
|
function create(_, vnode) {
|
|||
|
|
const real = vnode.elm;
|
|||
|
|
const attachData = vnode.data.attachData;
|
|||
|
|
const placeholder = document.createElement("span");
|
|||
|
|
// Replace actual element with dummy placeholder
|
|||
|
|
// Snabbdom will then insert placeholder instead
|
|||
|
|
vnode.elm = placeholder;
|
|||
|
|
attachData.target.appendChild(real);
|
|||
|
|
attachData.real = real;
|
|||
|
|
attachData.placeholder = placeholder;
|
|||
|
|
}
|
|||
|
|
function attachTo(target, vnode) {
|
|||
|
|
if (vnode.data === undefined)
|
|||
|
|
vnode.data = {};
|
|||
|
|
if (vnode.data.hook === undefined)
|
|||
|
|
vnode.data.hook = {};
|
|||
|
|
const data = vnode.data;
|
|||
|
|
const hook = vnode.data.hook;
|
|||
|
|
data.attachData = { target: target, placeholder: undefined, real: undefined };
|
|||
|
|
hook.create = create;
|
|||
|
|
hook.prepatch = pre;
|
|||
|
|
hook.postpatch = post;
|
|||
|
|
hook.destroy = destroy;
|
|||
|
|
return vnode;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function toVNode(node, domApi) {
|
|||
|
|
const api = domApi !== undefined ? domApi : htmlDomApi;
|
|||
|
|
let text;
|
|||
|
|
if (api.isElement(node)) {
|
|||
|
|
const id = node.id ? "#" + node.id : "";
|
|||
|
|
const cn = node.getAttribute("class");
|
|||
|
|
const c = cn ? "." + cn.split(" ").join(".") : "";
|
|||
|
|
const sel = api.tagName(node).toLowerCase() + id + c;
|
|||
|
|
const attrs = {};
|
|||
|
|
const children = [];
|
|||
|
|
let name;
|
|||
|
|
let i, n;
|
|||
|
|
const elmAttrs = node.attributes;
|
|||
|
|
const elmChildren = node.childNodes;
|
|||
|
|
for (i = 0, n = elmAttrs.length; i < n; i++) {
|
|||
|
|
name = elmAttrs[i].nodeName;
|
|||
|
|
if (name !== "id" && name !== "class") {
|
|||
|
|
attrs[name] = elmAttrs[i].nodeValue;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
for (i = 0, n = elmChildren.length; i < n; i++) {
|
|||
|
|
children.push(toVNode(elmChildren[i], domApi));
|
|||
|
|
}
|
|||
|
|
return vnode(sel, { attrs }, children, undefined, node);
|
|||
|
|
}
|
|||
|
|
else if (api.isText(node)) {
|
|||
|
|
text = api.getTextContent(node);
|
|||
|
|
return vnode(undefined, undefined, undefined, text, node);
|
|||
|
|
}
|
|||
|
|
else if (api.isComment(node)) {
|
|||
|
|
text = api.getTextContent(node);
|
|||
|
|
return vnode("!", {}, [], text, node);
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
return vnode("", {}, [], undefined, node);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const xlinkNS = "http://www.w3.org/1999/xlink";
|
|||
|
|
const xmlNS = "http://www.w3.org/XML/1998/namespace";
|
|||
|
|
const colonChar = 58;
|
|||
|
|
const xChar = 120;
|
|||
|
|
function updateAttrs(oldVnode, vnode) {
|
|||
|
|
let key;
|
|||
|
|
const elm = vnode.elm;
|
|||
|
|
let oldAttrs = oldVnode.data.attrs;
|
|||
|
|
let attrs = vnode.data.attrs;
|
|||
|
|
if (!oldAttrs && !attrs)
|
|||
|
|
return;
|
|||
|
|
if (oldAttrs === attrs)
|
|||
|
|
return;
|
|||
|
|
oldAttrs = oldAttrs || {};
|
|||
|
|
attrs = attrs || {};
|
|||
|
|
// update modified attributes, add new attributes
|
|||
|
|
for (key in attrs) {
|
|||
|
|
const cur = attrs[key];
|
|||
|
|
const old = oldAttrs[key];
|
|||
|
|
if (old !== cur) {
|
|||
|
|
if (cur === true) {
|
|||
|
|
elm.setAttribute(key, "");
|
|||
|
|
}
|
|||
|
|
else if (cur === false) {
|
|||
|
|
elm.removeAttribute(key);
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
if (key.charCodeAt(0) !== xChar) {
|
|||
|
|
elm.setAttribute(key, cur);
|
|||
|
|
}
|
|||
|
|
else if (key.charCodeAt(3) === colonChar) {
|
|||
|
|
// Assume xml namespace
|
|||
|
|
elm.setAttributeNS(xmlNS, key, cur);
|
|||
|
|
}
|
|||
|
|
else if (key.charCodeAt(5) === colonChar) {
|
|||
|
|
// Assume xlink namespace
|
|||
|
|
elm.setAttributeNS(xlinkNS, key, cur);
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
elm.setAttribute(key, cur);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
// remove removed attributes
|
|||
|
|
// use `in` operator since the previous `for` iteration uses it (.i.e. add even attributes with undefined value)
|
|||
|
|
// the other option is to remove all attributes with value == undefined
|
|||
|
|
for (key in oldAttrs) {
|
|||
|
|
if (!(key in attrs)) {
|
|||
|
|
elm.removeAttribute(key);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
const attributesModule = {
|
|||
|
|
create: updateAttrs,
|
|||
|
|
update: updateAttrs,
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
function updateClass(oldVnode, vnode) {
|
|||
|
|
let cur;
|
|||
|
|
let name;
|
|||
|
|
const elm = vnode.elm;
|
|||
|
|
let oldClass = oldVnode.data.class;
|
|||
|
|
let klass = vnode.data.class;
|
|||
|
|
if (!oldClass && !klass)
|
|||
|
|
return;
|
|||
|
|
if (oldClass === klass)
|
|||
|
|
return;
|
|||
|
|
oldClass = oldClass || {};
|
|||
|
|
klass = klass || {};
|
|||
|
|
for (name in oldClass) {
|
|||
|
|
if (oldClass[name] && !Object.prototype.hasOwnProperty.call(klass, name)) {
|
|||
|
|
// was `true` and now not provided
|
|||
|
|
elm.classList.remove(name);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
for (name in klass) {
|
|||
|
|
cur = klass[name];
|
|||
|
|
if (cur !== oldClass[name]) {
|
|||
|
|
elm.classList[cur ? "add" : "remove"](name);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
const classModule = { create: updateClass, update: updateClass };
|
|||
|
|
|
|||
|
|
const CAPS_REGEX = /[A-Z]/g;
|
|||
|
|
function updateDataset(oldVnode, vnode) {
|
|||
|
|
const elm = vnode.elm;
|
|||
|
|
let oldDataset = oldVnode.data.dataset;
|
|||
|
|
let dataset = vnode.data.dataset;
|
|||
|
|
let key;
|
|||
|
|
if (!oldDataset && !dataset)
|
|||
|
|
return;
|
|||
|
|
if (oldDataset === dataset)
|
|||
|
|
return;
|
|||
|
|
oldDataset = oldDataset || {};
|
|||
|
|
dataset = dataset || {};
|
|||
|
|
const d = elm.dataset;
|
|||
|
|
for (key in oldDataset) {
|
|||
|
|
if (!dataset[key]) {
|
|||
|
|
if (d) {
|
|||
|
|
if (key in d) {
|
|||
|
|
delete d[key];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
elm.removeAttribute("data-" + key.replace(CAPS_REGEX, "-$&").toLowerCase());
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
for (key in dataset) {
|
|||
|
|
if (oldDataset[key] !== dataset[key]) {
|
|||
|
|
if (d) {
|
|||
|
|
d[key] = dataset[key];
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
elm.setAttribute("data-" + key.replace(CAPS_REGEX, "-$&").toLowerCase(), dataset[key]);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
const datasetModule = {
|
|||
|
|
create: updateDataset,
|
|||
|
|
update: updateDataset,
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
function invokeHandler(handler, vnode, event) {
|
|||
|
|
if (typeof handler === "function") {
|
|||
|
|
// call function handler
|
|||
|
|
handler.call(vnode, event, vnode);
|
|||
|
|
}
|
|||
|
|
else if (typeof handler === "object") {
|
|||
|
|
// call multiple handlers
|
|||
|
|
for (let i = 0; i < handler.length; i++) {
|
|||
|
|
invokeHandler(handler[i], vnode, event);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function handleEvent(event, vnode) {
|
|||
|
|
const name = event.type;
|
|||
|
|
const on = vnode.data.on;
|
|||
|
|
// call event handler(s) if exists
|
|||
|
|
if (on && on[name]) {
|
|||
|
|
invokeHandler(on[name], vnode, event);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function createListener() {
|
|||
|
|
return function handler(event) {
|
|||
|
|
handleEvent(event, handler.vnode);
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
function updateEventListeners(oldVnode, vnode) {
|
|||
|
|
const oldOn = oldVnode.data.on;
|
|||
|
|
const oldListener = oldVnode.listener;
|
|||
|
|
const oldElm = oldVnode.elm;
|
|||
|
|
const on = vnode && vnode.data.on;
|
|||
|
|
const elm = (vnode && vnode.elm);
|
|||
|
|
let name;
|
|||
|
|
// optimization for reused immutable handlers
|
|||
|
|
if (oldOn === on) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
// remove existing listeners which no longer used
|
|||
|
|
if (oldOn && oldListener) {
|
|||
|
|
// if element changed or deleted we remove all existing listeners unconditionally
|
|||
|
|
if (!on) {
|
|||
|
|
for (name in oldOn) {
|
|||
|
|
// remove listener if element was changed or existing listeners removed
|
|||
|
|
oldElm.removeEventListener(name, oldListener, false);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
for (name in oldOn) {
|
|||
|
|
// remove listener if existing listener removed
|
|||
|
|
if (!on[name]) {
|
|||
|
|
oldElm.removeEventListener(name, oldListener, false);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
// add new listeners which has not already attached
|
|||
|
|
if (on) {
|
|||
|
|
// reuse existing listener or create new
|
|||
|
|
const listener = (vnode.listener =
|
|||
|
|
oldVnode.listener || createListener());
|
|||
|
|
// update vnode for listener
|
|||
|
|
listener.vnode = vnode;
|
|||
|
|
// if element changed or added we add all needed listeners unconditionally
|
|||
|
|
if (!oldOn) {
|
|||
|
|
for (name in on) {
|
|||
|
|
// add listener if element was changed or new listeners added
|
|||
|
|
elm.addEventListener(name, listener, false);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
for (name in on) {
|
|||
|
|
// add listener if new listener added
|
|||
|
|
if (!oldOn[name]) {
|
|||
|
|
elm.addEventListener(name, listener, false);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
const eventListenersModule = {
|
|||
|
|
create: updateEventListeners,
|
|||
|
|
update: updateEventListeners,
|
|||
|
|
destroy: updateEventListeners,
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
function updateProps(oldVnode, vnode) {
|
|||
|
|
let key;
|
|||
|
|
let cur;
|
|||
|
|
let old;
|
|||
|
|
const elm = vnode.elm;
|
|||
|
|
let oldProps = oldVnode.data.props;
|
|||
|
|
let props = vnode.data.props;
|
|||
|
|
if (!oldProps && !props)
|
|||
|
|
return;
|
|||
|
|
if (oldProps === props)
|
|||
|
|
return;
|
|||
|
|
oldProps = oldProps || {};
|
|||
|
|
props = props || {};
|
|||
|
|
for (key in props) {
|
|||
|
|
cur = props[key];
|
|||
|
|
old = oldProps[key];
|
|||
|
|
if (old !== cur && (key !== "value" || elm[key] !== cur)) {
|
|||
|
|
elm[key] = cur;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
const propsModule = { create: updateProps, update: updateProps };
|
|||
|
|
|
|||
|
|
// Bindig `requestAnimationFrame` like this fixes a bug in IE/Edge. See #360 and #409.
|
|||
|
|
const raf = (typeof window !== "undefined" &&
|
|||
|
|
window.requestAnimationFrame.bind(window)) ||
|
|||
|
|
setTimeout;
|
|||
|
|
const nextFrame = function (fn) {
|
|||
|
|
raf(function () {
|
|||
|
|
raf(fn);
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
let reflowForced = false;
|
|||
|
|
function setNextFrame(obj, prop, val) {
|
|||
|
|
nextFrame(function () {
|
|||
|
|
obj[prop] = val;
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
function updateStyle(oldVnode, vnode) {
|
|||
|
|
let cur;
|
|||
|
|
let name;
|
|||
|
|
const elm = vnode.elm;
|
|||
|
|
let oldStyle = oldVnode.data.style;
|
|||
|
|
let style = vnode.data.style;
|
|||
|
|
if (!oldStyle && !style)
|
|||
|
|
return;
|
|||
|
|
if (oldStyle === style)
|
|||
|
|
return;
|
|||
|
|
oldStyle = oldStyle || {};
|
|||
|
|
style = style || {};
|
|||
|
|
const oldHasDel = "delayed" in oldStyle;
|
|||
|
|
for (name in oldStyle) {
|
|||
|
|
if (!style[name]) {
|
|||
|
|
if (name[0] === "-" && name[1] === "-") {
|
|||
|
|
elm.style.removeProperty(name);
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
elm.style[name] = "";
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
for (name in style) {
|
|||
|
|
cur = style[name];
|
|||
|
|
if (name === "delayed" && style.delayed) {
|
|||
|
|
for (const name2 in style.delayed) {
|
|||
|
|
cur = style.delayed[name2];
|
|||
|
|
if (!oldHasDel || cur !== oldStyle.delayed[name2]) {
|
|||
|
|
setNextFrame(elm.style, name2, cur);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else if (name !== "remove" && cur !== oldStyle[name]) {
|
|||
|
|
if (name[0] === "-" && name[1] === "-") {
|
|||
|
|
elm.style.setProperty(name, cur);
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
elm.style[name] = cur;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function applyDestroyStyle(vnode) {
|
|||
|
|
let style;
|
|||
|
|
let name;
|
|||
|
|
const elm = vnode.elm;
|
|||
|
|
const s = vnode.data.style;
|
|||
|
|
if (!s || !(style = s.destroy))
|
|||
|
|
return;
|
|||
|
|
for (name in style) {
|
|||
|
|
elm.style[name] = style[name];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
function applyRemoveStyle(vnode, rm) {
|
|||
|
|
const s = vnode.data.style;
|
|||
|
|
if (!s || !s.remove) {
|
|||
|
|
rm();
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
if (!reflowForced) {
|
|||
|
|
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|||
|
|
vnode.elm.offsetLeft;
|
|||
|
|
reflowForced = true;
|
|||
|
|
}
|
|||
|
|
let name;
|
|||
|
|
const elm = vnode.elm;
|
|||
|
|
let i = 0;
|
|||
|
|
const style = s.remove;
|
|||
|
|
let amount = 0;
|
|||
|
|
const applied = [];
|
|||
|
|
for (name in style) {
|
|||
|
|
applied.push(name);
|
|||
|
|
elm.style[name] = style[name];
|
|||
|
|
}
|
|||
|
|
const compStyle = getComputedStyle(elm);
|
|||
|
|
const props = compStyle["transition-property"].split(", ");
|
|||
|
|
for (; i < props.length; ++i) {
|
|||
|
|
if (applied.indexOf(props[i]) !== -1)
|
|||
|
|
amount++;
|
|||
|
|
}
|
|||
|
|
elm.addEventListener("transitionend", function (ev) {
|
|||
|
|
if (ev.target === elm)
|
|||
|
|
--amount;
|
|||
|
|
if (amount === 0)
|
|||
|
|
rm();
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
function forceReflow() {
|
|||
|
|
reflowForced = false;
|
|||
|
|
}
|
|||
|
|
const styleModule = {
|
|||
|
|
pre: forceReflow,
|
|||
|
|
create: updateStyle,
|
|||
|
|
update: updateStyle,
|
|||
|
|
destroy: applyDestroyStyle,
|
|||
|
|
remove: applyRemoveStyle,
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/* eslint-disable @typescript-eslint/no-namespace, import/export */
|
|||
|
|
function flattenAndFilter(children, flattened) {
|
|||
|
|
for (const child of children) {
|
|||
|
|
// filter out falsey children, except 0 since zero can be a valid value e.g inside a chart
|
|||
|
|
if (child !== undefined &&
|
|||
|
|
child !== null &&
|
|||
|
|
child !== false &&
|
|||
|
|
child !== "") {
|
|||
|
|
if (Array.isArray(child)) {
|
|||
|
|
flattenAndFilter(child, flattened);
|
|||
|
|
}
|
|||
|
|
else if (typeof child === "string" ||
|
|||
|
|
typeof child === "number" ||
|
|||
|
|
typeof child === "boolean") {
|
|||
|
|
flattened.push(vnode(undefined, undefined, undefined, String(child), undefined));
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
flattened.push(child);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return flattened;
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* jsx/tsx compatible factory function
|
|||
|
|
* see: https://www.typescriptlang.org/docs/handbook/jsx.html#factory-functions
|
|||
|
|
*/
|
|||
|
|
function jsx(tag, data, ...children) {
|
|||
|
|
const flatChildren = flattenAndFilter(children, []);
|
|||
|
|
if (typeof tag === "function") {
|
|||
|
|
// tag is a function component
|
|||
|
|
return tag(data, flatChildren);
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
if (flatChildren.length === 1 &&
|
|||
|
|
!flatChildren[0].sel &&
|
|||
|
|
flatChildren[0].text) {
|
|||
|
|
// only child is a simple text node, pass as text for a simpler vtree
|
|||
|
|
return h(tag, data, flatChildren[0].text);
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
return h(tag, data, flatChildren);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
(function (jsx) {
|
|||
|
|
})(jsx || (jsx = {}));
|
|||
|
|
|
|||
|
|
exports.array = array;
|
|||
|
|
exports.attachTo = attachTo;
|
|||
|
|
exports.attributesModule = attributesModule;
|
|||
|
|
exports.classModule = classModule;
|
|||
|
|
exports.datasetModule = datasetModule;
|
|||
|
|
exports.eventListenersModule = eventListenersModule;
|
|||
|
|
exports.h = h;
|
|||
|
|
exports.htmlDomApi = htmlDomApi;
|
|||
|
|
exports.init = init$1;
|
|||
|
|
exports.jsx = jsx;
|
|||
|
|
exports.primitive = primitive;
|
|||
|
|
exports.propsModule = propsModule;
|
|||
|
|
exports.styleModule = styleModule;
|
|||
|
|
exports.thunk = thunk;
|
|||
|
|
exports.toVNode = toVNode;
|
|||
|
|
exports.vnode = vnode;
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* lodash (Custom Build) <https://lodash.com/>
|
|||
|
|
* Build: `lodash modularize exports="npm" -o ./`
|
|||
|
|
* Copyright jQuery Foundation and other contributors <https://jquery.org/>
|
|||
|
|
* Released under MIT license <https://lodash.com/license>
|
|||
|
|
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
|
|||
|
|
* Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
/** Used as references for various `Number` constants. */
|
|||
|
|
var INFINITY = 1 / 0;
|
|||
|
|
|
|||
|
|
/** `Object#toString` result references. */
|
|||
|
|
var symbolTag$1 = '[object Symbol]';
|
|||
|
|
|
|||
|
|
/** Used to match words composed of alphanumeric characters. */
|
|||
|
|
var reAsciiWord = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
|
|||
|
|
|
|||
|
|
/** Used to match Latin Unicode letters (excluding mathematical operators). */
|
|||
|
|
var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g;
|
|||
|
|
|
|||
|
|
/** Used to compose unicode character classes. */
|
|||
|
|
var rsAstralRange = '\\ud800-\\udfff',
|
|||
|
|
rsComboMarksRange = '\\u0300-\\u036f\\ufe20-\\ufe23',
|
|||
|
|
rsComboSymbolsRange = '\\u20d0-\\u20f0',
|
|||
|
|
rsDingbatRange = '\\u2700-\\u27bf',
|
|||
|
|
rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff',
|
|||
|
|
rsMathOpRange = '\\xac\\xb1\\xd7\\xf7',
|
|||
|
|
rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf',
|
|||
|
|
rsPunctuationRange = '\\u2000-\\u206f',
|
|||
|
|
rsSpaceRange = ' \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000',
|
|||
|
|
rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde',
|
|||
|
|
rsVarRange = '\\ufe0e\\ufe0f',
|
|||
|
|
rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange;
|
|||
|
|
|
|||
|
|
/** Used to compose unicode capture groups. */
|
|||
|
|
var rsApos = "['\u2019]",
|
|||
|
|
rsAstral = '[' + rsAstralRange + ']',
|
|||
|
|
rsBreak = '[' + rsBreakRange + ']',
|
|||
|
|
rsCombo = '[' + rsComboMarksRange + rsComboSymbolsRange + ']',
|
|||
|
|
rsDigits = '\\d+',
|
|||
|
|
rsDingbat = '[' + rsDingbatRange + ']',
|
|||
|
|
rsLower = '[' + rsLowerRange + ']',
|
|||
|
|
rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']',
|
|||
|
|
rsFitz = '\\ud83c[\\udffb-\\udfff]',
|
|||
|
|
rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',
|
|||
|
|
rsNonAstral = '[^' + rsAstralRange + ']',
|
|||
|
|
rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}',
|
|||
|
|
rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]',
|
|||
|
|
rsUpper = '[' + rsUpperRange + ']',
|
|||
|
|
rsZWJ = '\\u200d';
|
|||
|
|
|
|||
|
|
/** Used to compose unicode regexes. */
|
|||
|
|
var rsLowerMisc = '(?:' + rsLower + '|' + rsMisc + ')',
|
|||
|
|
rsUpperMisc = '(?:' + rsUpper + '|' + rsMisc + ')',
|
|||
|
|
rsOptLowerContr = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?',
|
|||
|
|
rsOptUpperContr = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?',
|
|||
|
|
reOptMod = rsModifier + '?',
|
|||
|
|
rsOptVar = '[' + rsVarRange + ']?',
|
|||
|
|
rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',
|
|||
|
|
rsSeq = rsOptVar + reOptMod + rsOptJoin,
|
|||
|
|
rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq,
|
|||
|
|
rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';
|
|||
|
|
|
|||
|
|
/** Used to match apostrophes. */
|
|||
|
|
var reApos = RegExp(rsApos, 'g');
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and
|
|||
|
|
* [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).
|
|||
|
|
*/
|
|||
|
|
var reComboMark = RegExp(rsCombo, 'g');
|
|||
|
|
|
|||
|
|
/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
|
|||
|
|
var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');
|
|||
|
|
|
|||
|
|
/** Used to match complex or compound words. */
|
|||
|
|
var reUnicodeWord = RegExp([
|
|||
|
|
rsUpper + '?' + rsLower + '+' + rsOptLowerContr + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',
|
|||
|
|
rsUpperMisc + '+' + rsOptUpperContr + '(?=' + [rsBreak, rsUpper + rsLowerMisc, '$'].join('|') + ')',
|
|||
|
|
rsUpper + '?' + rsLowerMisc + '+' + rsOptLowerContr,
|
|||
|
|
rsUpper + '+' + rsOptUpperContr,
|
|||
|
|
rsDigits,
|
|||
|
|
rsEmoji
|
|||
|
|
].join('|'), 'g');
|
|||
|
|
|
|||
|
|
/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */
|
|||
|
|
var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboMarksRange + rsComboSymbolsRange + rsVarRange + ']');
|
|||
|
|
|
|||
|
|
/** Used to detect strings that need a more robust regexp to match words. */
|
|||
|
|
var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;
|
|||
|
|
|
|||
|
|
/** Used to map Latin Unicode letters to basic Latin letters. */
|
|||
|
|
var deburredLetters = {
|
|||
|
|
// Latin-1 Supplement block.
|
|||
|
|
'\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A',
|
|||
|
|
'\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a',
|
|||
|
|
'\xc7': 'C', '\xe7': 'c',
|
|||
|
|
'\xd0': 'D', '\xf0': 'd',
|
|||
|
|
'\xc8': 'E', '\xc9': 'E', '\xca': 'E', '\xcb': 'E',
|
|||
|
|
'\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e',
|
|||
|
|
'\xcc': 'I', '\xcd': 'I', '\xce': 'I', '\xcf': 'I',
|
|||
|
|
'\xec': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i',
|
|||
|
|
'\xd1': 'N', '\xf1': 'n',
|
|||
|
|
'\xd2': 'O', '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O',
|
|||
|
|
'\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o',
|
|||
|
|
'\xd9': 'U', '\xda': 'U', '\xdb': 'U', '\xdc': 'U',
|
|||
|
|
'\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u',
|
|||
|
|
'\xdd': 'Y', '\xfd': 'y', '\xff': 'y',
|
|||
|
|
'\xc6': 'Ae', '\xe6': 'ae',
|
|||
|
|
'\xde': 'Th', '\xfe': 'th',
|
|||
|
|
'\xdf': 'ss',
|
|||
|
|
// Latin Extended-A block.
|
|||
|
|
'\u0100': 'A', '\u0102': 'A', '\u0104': 'A',
|
|||
|
|
'\u0101': 'a', '\u0103': 'a', '\u0105': 'a',
|
|||
|
|
'\u0106': 'C', '\u0108': 'C', '\u010a': 'C', '\u010c': 'C',
|
|||
|
|
'\u0107': 'c', '\u0109': 'c', '\u010b': 'c', '\u010d': 'c',
|
|||
|
|
'\u010e': 'D', '\u0110': 'D', '\u010f': 'd', '\u0111': 'd',
|
|||
|
|
'\u0112': 'E', '\u0114': 'E', '\u0116': 'E', '\u0118': 'E', '\u011a': 'E',
|
|||
|
|
'\u0113': 'e', '\u0115': 'e', '\u0117': 'e', '\u0119': 'e', '\u011b': 'e',
|
|||
|
|
'\u011c': 'G', '\u011e': 'G', '\u0120': 'G', '\u0122': 'G',
|
|||
|
|
'\u011d': 'g', '\u011f': 'g', '\u0121': 'g', '\u0123': 'g',
|
|||
|
|
'\u0124': 'H', '\u0126': 'H', '\u0125': 'h', '\u0127': 'h',
|
|||
|
|
'\u0128': 'I', '\u012a': 'I', '\u012c': 'I', '\u012e': 'I', '\u0130': 'I',
|
|||
|
|
'\u0129': 'i', '\u012b': 'i', '\u012d': 'i', '\u012f': 'i', '\u0131': 'i',
|
|||
|
|
'\u0134': 'J', '\u0135': 'j',
|
|||
|
|
'\u0136': 'K', '\u0137': 'k', '\u0138': 'k',
|
|||
|
|
'\u0139': 'L', '\u013b': 'L', '\u013d': 'L', '\u013f': 'L', '\u0141': 'L',
|
|||
|
|
'\u013a': 'l', '\u013c': 'l', '\u013e': 'l', '\u0140': 'l', '\u0142': 'l',
|
|||
|
|
'\u0143': 'N', '\u0145': 'N', '\u0147': 'N', '\u014a': 'N',
|
|||
|
|
'\u0144': 'n', '\u0146': 'n', '\u0148': 'n', '\u014b': 'n',
|
|||
|
|
'\u014c': 'O', '\u014e': 'O', '\u0150': 'O',
|
|||
|
|
'\u014d': 'o', '\u014f': 'o', '\u0151': 'o',
|
|||
|
|
'\u0154': 'R', '\u0156': 'R', '\u0158': 'R',
|
|||
|
|
'\u0155': 'r', '\u0157': 'r', '\u0159': 'r',
|
|||
|
|
'\u015a': 'S', '\u015c': 'S', '\u015e': 'S', '\u0160': 'S',
|
|||
|
|
'\u015b': 's', '\u015d': 's', '\u015f': 's', '\u0161': 's',
|
|||
|
|
'\u0162': 'T', '\u0164': 'T', '\u0166': 'T',
|
|||
|
|
'\u0163': 't', '\u0165': 't', '\u0167': 't',
|
|||
|
|
'\u0168': 'U', '\u016a': 'U', '\u016c': 'U', '\u016e': 'U', '\u0170': 'U', '\u0172': 'U',
|
|||
|
|
'\u0169': 'u', '\u016b': 'u', '\u016d': 'u', '\u016f': 'u', '\u0171': 'u', '\u0173': 'u',
|
|||
|
|
'\u0174': 'W', '\u0175': 'w',
|
|||
|
|
'\u0176': 'Y', '\u0177': 'y', '\u0178': 'Y',
|
|||
|
|
'\u0179': 'Z', '\u017b': 'Z', '\u017d': 'Z',
|
|||
|
|
'\u017a': 'z', '\u017c': 'z', '\u017e': 'z',
|
|||
|
|
'\u0132': 'IJ', '\u0133': 'ij',
|
|||
|
|
'\u0152': 'Oe', '\u0153': 'oe',
|
|||
|
|
'\u0149': "'n", '\u017f': 'ss'
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/** Detect free variable `global` from Node.js. */
|
|||
|
|
var freeGlobal$1 = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;
|
|||
|
|
|
|||
|
|
/** Detect free variable `self`. */
|
|||
|
|
var freeSelf$1 = typeof self == 'object' && self && self.Object === Object && self;
|
|||
|
|
|
|||
|
|
/** Used as a reference to the global object. */
|
|||
|
|
var root$1 = freeGlobal$1 || freeSelf$1 || Function('return this')();
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* A specialized version of `_.reduce` for arrays without support for
|
|||
|
|
* iteratee shorthands.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Array} [array] The array to iterate over.
|
|||
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|||
|
|
* @param {*} [accumulator] The initial value.
|
|||
|
|
* @param {boolean} [initAccum] Specify using the first element of `array` as
|
|||
|
|
* the initial value.
|
|||
|
|
* @returns {*} Returns the accumulated value.
|
|||
|
|
*/
|
|||
|
|
function arrayReduce(array, iteratee, accumulator, initAccum) {
|
|||
|
|
var index = -1,
|
|||
|
|
length = array ? array.length : 0;
|
|||
|
|
|
|||
|
|
if (initAccum && length) {
|
|||
|
|
accumulator = array[++index];
|
|||
|
|
}
|
|||
|
|
while (++index < length) {
|
|||
|
|
accumulator = iteratee(accumulator, array[index], index, array);
|
|||
|
|
}
|
|||
|
|
return accumulator;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Converts an ASCII `string` to an array.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {string} string The string to convert.
|
|||
|
|
* @returns {Array} Returns the converted array.
|
|||
|
|
*/
|
|||
|
|
function asciiToArray(string) {
|
|||
|
|
return string.split('');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Splits an ASCII `string` into an array of its words.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {string} The string to inspect.
|
|||
|
|
* @returns {Array} Returns the words of `string`.
|
|||
|
|
*/
|
|||
|
|
function asciiWords(string) {
|
|||
|
|
return string.match(reAsciiWord) || [];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* The base implementation of `_.propertyOf` without support for deep paths.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Object} object The object to query.
|
|||
|
|
* @returns {Function} Returns the new accessor function.
|
|||
|
|
*/
|
|||
|
|
function basePropertyOf(object) {
|
|||
|
|
return function(key) {
|
|||
|
|
return object == null ? undefined : object[key];
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A
|
|||
|
|
* letters to basic Latin letters.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {string} letter The matched letter to deburr.
|
|||
|
|
* @returns {string} Returns the deburred letter.
|
|||
|
|
*/
|
|||
|
|
var deburrLetter = basePropertyOf(deburredLetters);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `string` contains Unicode symbols.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {string} string The string to inspect.
|
|||
|
|
* @returns {boolean} Returns `true` if a symbol is found, else `false`.
|
|||
|
|
*/
|
|||
|
|
function hasUnicode(string) {
|
|||
|
|
return reHasUnicode.test(string);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `string` contains a word composed of Unicode symbols.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {string} string The string to inspect.
|
|||
|
|
* @returns {boolean} Returns `true` if a word is found, else `false`.
|
|||
|
|
*/
|
|||
|
|
function hasUnicodeWord(string) {
|
|||
|
|
return reHasUnicodeWord.test(string);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Converts `string` to an array.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {string} string The string to convert.
|
|||
|
|
* @returns {Array} Returns the converted array.
|
|||
|
|
*/
|
|||
|
|
function stringToArray(string) {
|
|||
|
|
return hasUnicode(string)
|
|||
|
|
? unicodeToArray(string)
|
|||
|
|
: asciiToArray(string);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Converts a Unicode `string` to an array.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {string} string The string to convert.
|
|||
|
|
* @returns {Array} Returns the converted array.
|
|||
|
|
*/
|
|||
|
|
function unicodeToArray(string) {
|
|||
|
|
return string.match(reUnicode) || [];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Splits a Unicode `string` into an array of its words.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {string} The string to inspect.
|
|||
|
|
* @returns {Array} Returns the words of `string`.
|
|||
|
|
*/
|
|||
|
|
function unicodeWords(string) {
|
|||
|
|
return string.match(reUnicodeWord) || [];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/** Used for built-in method references. */
|
|||
|
|
var objectProto$1 = Object.prototype;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Used to resolve the
|
|||
|
|
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
|
|||
|
|
* of values.
|
|||
|
|
*/
|
|||
|
|
var objectToString$1 = objectProto$1.toString;
|
|||
|
|
|
|||
|
|
/** Built-in value references. */
|
|||
|
|
var Symbol$1 = root$1.Symbol;
|
|||
|
|
|
|||
|
|
/** Used to convert symbols to primitives and strings. */
|
|||
|
|
var symbolProto = Symbol$1 ? Symbol$1.prototype : undefined,
|
|||
|
|
symbolToString = symbolProto ? symbolProto.toString : undefined;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* The base implementation of `_.slice` without an iteratee call guard.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Array} array The array to slice.
|
|||
|
|
* @param {number} [start=0] The start position.
|
|||
|
|
* @param {number} [end=array.length] The end position.
|
|||
|
|
* @returns {Array} Returns the slice of `array`.
|
|||
|
|
*/
|
|||
|
|
function baseSlice(array, start, end) {
|
|||
|
|
var index = -1,
|
|||
|
|
length = array.length;
|
|||
|
|
|
|||
|
|
if (start < 0) {
|
|||
|
|
start = -start > length ? 0 : (length + start);
|
|||
|
|
}
|
|||
|
|
end = end > length ? length : end;
|
|||
|
|
if (end < 0) {
|
|||
|
|
end += length;
|
|||
|
|
}
|
|||
|
|
length = start > end ? 0 : ((end - start) >>> 0);
|
|||
|
|
start >>>= 0;
|
|||
|
|
|
|||
|
|
var result = Array(length);
|
|||
|
|
while (++index < length) {
|
|||
|
|
result[index] = array[index + start];
|
|||
|
|
}
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* The base implementation of `_.toString` which doesn't convert nullish
|
|||
|
|
* values to empty strings.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {*} value The value to process.
|
|||
|
|
* @returns {string} Returns the string.
|
|||
|
|
*/
|
|||
|
|
function baseToString(value) {
|
|||
|
|
// Exit early for strings to avoid a performance hit in some environments.
|
|||
|
|
if (typeof value == 'string') {
|
|||
|
|
return value;
|
|||
|
|
}
|
|||
|
|
if (isSymbol$1(value)) {
|
|||
|
|
return symbolToString ? symbolToString.call(value) : '';
|
|||
|
|
}
|
|||
|
|
var result = (value + '');
|
|||
|
|
return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Casts `array` to a slice if it's needed.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Array} array The array to inspect.
|
|||
|
|
* @param {number} start The start position.
|
|||
|
|
* @param {number} [end=array.length] The end position.
|
|||
|
|
* @returns {Array} Returns the cast slice.
|
|||
|
|
*/
|
|||
|
|
function castSlice(array, start, end) {
|
|||
|
|
var length = array.length;
|
|||
|
|
end = end === undefined ? length : end;
|
|||
|
|
return (!start && end >= length) ? array : baseSlice(array, start, end);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Creates a function like `_.lowerFirst`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {string} methodName The name of the `String` case method to use.
|
|||
|
|
* @returns {Function} Returns the new case function.
|
|||
|
|
*/
|
|||
|
|
function createCaseFirst(methodName) {
|
|||
|
|
return function(string) {
|
|||
|
|
string = toString(string);
|
|||
|
|
|
|||
|
|
var strSymbols = hasUnicode(string)
|
|||
|
|
? stringToArray(string)
|
|||
|
|
: undefined;
|
|||
|
|
|
|||
|
|
var chr = strSymbols
|
|||
|
|
? strSymbols[0]
|
|||
|
|
: string.charAt(0);
|
|||
|
|
|
|||
|
|
var trailing = strSymbols
|
|||
|
|
? castSlice(strSymbols, 1).join('')
|
|||
|
|
: string.slice(1);
|
|||
|
|
|
|||
|
|
return chr[methodName]() + trailing;
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Creates a function like `_.camelCase`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Function} callback The function to combine each word.
|
|||
|
|
* @returns {Function} Returns the new compounder function.
|
|||
|
|
*/
|
|||
|
|
function createCompounder(callback) {
|
|||
|
|
return function(string) {
|
|||
|
|
return arrayReduce(words(deburr(string).replace(reApos, '')), callback, '');
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is object-like. A value is object-like if it's not `null`
|
|||
|
|
* and has a `typeof` result of "object".
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 4.0.0
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.isObjectLike({});
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isObjectLike([1, 2, 3]);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isObjectLike(_.noop);
|
|||
|
|
* // => false
|
|||
|
|
*
|
|||
|
|
* _.isObjectLike(null);
|
|||
|
|
* // => false
|
|||
|
|
*/
|
|||
|
|
function isObjectLike$1(value) {
|
|||
|
|
return !!value && typeof value == 'object';
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is classified as a `Symbol` primitive or object.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 4.0.0
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.isSymbol(Symbol.iterator);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isSymbol('abc');
|
|||
|
|
* // => false
|
|||
|
|
*/
|
|||
|
|
function isSymbol$1(value) {
|
|||
|
|
return typeof value == 'symbol' ||
|
|||
|
|
(isObjectLike$1(value) && objectToString$1.call(value) == symbolTag$1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Converts `value` to a string. An empty string is returned for `null`
|
|||
|
|
* and `undefined` values. The sign of `-0` is preserved.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 4.0.0
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to process.
|
|||
|
|
* @returns {string} Returns the string.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.toString(null);
|
|||
|
|
* // => ''
|
|||
|
|
*
|
|||
|
|
* _.toString(-0);
|
|||
|
|
* // => '-0'
|
|||
|
|
*
|
|||
|
|
* _.toString([1, 2, 3]);
|
|||
|
|
* // => '1,2,3'
|
|||
|
|
*/
|
|||
|
|
function toString(value) {
|
|||
|
|
return value == null ? '' : baseToString(value);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 3.0.0
|
|||
|
|
* @category String
|
|||
|
|
* @param {string} [string=''] The string to convert.
|
|||
|
|
* @returns {string} Returns the camel cased string.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.camelCase('Foo Bar');
|
|||
|
|
* // => 'fooBar'
|
|||
|
|
*
|
|||
|
|
* _.camelCase('--foo-bar--');
|
|||
|
|
* // => 'fooBar'
|
|||
|
|
*
|
|||
|
|
* _.camelCase('__FOO_BAR__');
|
|||
|
|
* // => 'fooBar'
|
|||
|
|
*/
|
|||
|
|
var camelCase = createCompounder(function(result, word, index) {
|
|||
|
|
word = word.toLowerCase();
|
|||
|
|
return result + (index ? capitalize(word) : word);
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Converts the first character of `string` to upper case and the remaining
|
|||
|
|
* to lower case.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 3.0.0
|
|||
|
|
* @category String
|
|||
|
|
* @param {string} [string=''] The string to capitalize.
|
|||
|
|
* @returns {string} Returns the capitalized string.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.capitalize('FRED');
|
|||
|
|
* // => 'Fred'
|
|||
|
|
*/
|
|||
|
|
function capitalize(string) {
|
|||
|
|
return upperFirst(toString(string).toLowerCase());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Deburrs `string` by converting
|
|||
|
|
* [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)
|
|||
|
|
* and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A)
|
|||
|
|
* letters to basic Latin letters and removing
|
|||
|
|
* [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 3.0.0
|
|||
|
|
* @category String
|
|||
|
|
* @param {string} [string=''] The string to deburr.
|
|||
|
|
* @returns {string} Returns the deburred string.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.deburr('déjà vu');
|
|||
|
|
* // => 'deja vu'
|
|||
|
|
*/
|
|||
|
|
function deburr(string) {
|
|||
|
|
string = toString(string);
|
|||
|
|
return string && string.replace(reLatin, deburrLetter).replace(reComboMark, '');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Converts the first character of `string` to upper case.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 4.0.0
|
|||
|
|
* @category String
|
|||
|
|
* @param {string} [string=''] The string to convert.
|
|||
|
|
* @returns {string} Returns the converted string.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.upperFirst('fred');
|
|||
|
|
* // => 'Fred'
|
|||
|
|
*
|
|||
|
|
* _.upperFirst('FRED');
|
|||
|
|
* // => 'FRED'
|
|||
|
|
*/
|
|||
|
|
var upperFirst = createCaseFirst('toUpperCase');
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Splits `string` into an array of its words.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 3.0.0
|
|||
|
|
* @category String
|
|||
|
|
* @param {string} [string=''] The string to inspect.
|
|||
|
|
* @param {RegExp|string} [pattern] The pattern to match words.
|
|||
|
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
|||
|
|
* @returns {Array} Returns the words of `string`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.words('fred, barney, & pebbles');
|
|||
|
|
* // => ['fred', 'barney', 'pebbles']
|
|||
|
|
*
|
|||
|
|
* _.words('fred, barney, & pebbles', /[^, ]+/g);
|
|||
|
|
* // => ['fred', 'barney', '&', 'pebbles']
|
|||
|
|
*/
|
|||
|
|
function words(string, pattern, guard) {
|
|||
|
|
string = toString(string);
|
|||
|
|
pattern = guard ? undefined : pattern;
|
|||
|
|
|
|||
|
|
if (pattern === undefined) {
|
|||
|
|
return hasUnicodeWord(string) ? unicodeWords(string) : asciiWords(string);
|
|||
|
|
}
|
|||
|
|
return string.match(pattern) || [];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var lodash_camelcase = camelCase;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Constants.
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
var IS_MAC = typeof window != 'undefined' && /Mac|iPod|iPhone|iPad/.test(window.navigator.platform);
|
|||
|
|
|
|||
|
|
var MODIFIERS = {
|
|||
|
|
alt: 'altKey',
|
|||
|
|
control: 'ctrlKey',
|
|||
|
|
meta: 'metaKey',
|
|||
|
|
shift: 'shiftKey'
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var ALIASES = {
|
|||
|
|
add: '+',
|
|||
|
|
break: 'pause',
|
|||
|
|
cmd: 'meta',
|
|||
|
|
command: 'meta',
|
|||
|
|
ctl: 'control',
|
|||
|
|
ctrl: 'control',
|
|||
|
|
del: 'delete',
|
|||
|
|
down: 'arrowdown',
|
|||
|
|
esc: 'escape',
|
|||
|
|
ins: 'insert',
|
|||
|
|
left: 'arrowleft',
|
|||
|
|
mod: IS_MAC ? 'meta' : 'control',
|
|||
|
|
opt: 'alt',
|
|||
|
|
option: 'alt',
|
|||
|
|
return: 'enter',
|
|||
|
|
right: 'arrowright',
|
|||
|
|
space: ' ',
|
|||
|
|
spacebar: ' ',
|
|||
|
|
up: 'arrowup',
|
|||
|
|
win: 'meta',
|
|||
|
|
windows: 'meta'
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var CODES = {
|
|||
|
|
backspace: 8,
|
|||
|
|
tab: 9,
|
|||
|
|
enter: 13,
|
|||
|
|
shift: 16,
|
|||
|
|
control: 17,
|
|||
|
|
alt: 18,
|
|||
|
|
pause: 19,
|
|||
|
|
capslock: 20,
|
|||
|
|
escape: 27,
|
|||
|
|
' ': 32,
|
|||
|
|
pageup: 33,
|
|||
|
|
pagedown: 34,
|
|||
|
|
end: 35,
|
|||
|
|
home: 36,
|
|||
|
|
arrowleft: 37,
|
|||
|
|
arrowup: 38,
|
|||
|
|
arrowright: 39,
|
|||
|
|
arrowdown: 40,
|
|||
|
|
insert: 45,
|
|||
|
|
delete: 46,
|
|||
|
|
meta: 91,
|
|||
|
|
numlock: 144,
|
|||
|
|
scrolllock: 145,
|
|||
|
|
';': 186,
|
|||
|
|
'=': 187,
|
|||
|
|
',': 188,
|
|||
|
|
'-': 189,
|
|||
|
|
'.': 190,
|
|||
|
|
'/': 191,
|
|||
|
|
'`': 192,
|
|||
|
|
'[': 219,
|
|||
|
|
'\\': 220,
|
|||
|
|
']': 221,
|
|||
|
|
'\'': 222
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
for (var f = 1; f < 20; f++) {
|
|||
|
|
CODES['f' + f] = 111 + f;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Is hotkey?
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
function isHotkey(hotkey, options, event) {
|
|||
|
|
if (options && !('byKey' in options)) {
|
|||
|
|
event = options;
|
|||
|
|
options = null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!Array.isArray(hotkey)) {
|
|||
|
|
hotkey = [hotkey];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var array = hotkey.map(function (string) {
|
|||
|
|
return parseHotkey(string, options);
|
|||
|
|
});
|
|||
|
|
var check = function check(e) {
|
|||
|
|
return array.some(function (object) {
|
|||
|
|
return compareHotkey(object, e);
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
var ret = event == null ? check : check(event);
|
|||
|
|
return ret;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function isCodeHotkey(hotkey, event) {
|
|||
|
|
return isHotkey(hotkey, event);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function isKeyHotkey(hotkey, event) {
|
|||
|
|
return isHotkey(hotkey, { byKey: true }, event);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Parse.
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
function parseHotkey(hotkey, options) {
|
|||
|
|
var byKey = options && options.byKey;
|
|||
|
|
var ret = {};
|
|||
|
|
|
|||
|
|
// Special case to handle the `+` key since we use it as a separator.
|
|||
|
|
hotkey = hotkey.replace('++', '+add');
|
|||
|
|
var values = hotkey.split('+');
|
|||
|
|
var length = values.length;
|
|||
|
|
|
|||
|
|
// Ensure that all the modifiers are set to false unless the hotkey has them.
|
|||
|
|
|
|||
|
|
for (var k in MODIFIERS) {
|
|||
|
|
ret[MODIFIERS[k]] = false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var _iteratorNormalCompletion = true;
|
|||
|
|
var _didIteratorError = false;
|
|||
|
|
var _iteratorError = undefined;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
for (var _iterator = values[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
|||
|
|
var value = _step.value;
|
|||
|
|
|
|||
|
|
var optional = value.endsWith('?') && value.length > 1;
|
|||
|
|
|
|||
|
|
if (optional) {
|
|||
|
|
value = value.slice(0, -1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var name = toKeyName(value);
|
|||
|
|
var modifier = MODIFIERS[name];
|
|||
|
|
|
|||
|
|
if (value.length > 1 && !modifier && !ALIASES[value] && !CODES[name]) {
|
|||
|
|
throw new TypeError('Unknown modifier: "' + value + '"');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (length === 1 || !modifier) {
|
|||
|
|
if (byKey) {
|
|||
|
|
ret.key = name;
|
|||
|
|
} else {
|
|||
|
|
ret.which = toKeyCode(value);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (modifier) {
|
|||
|
|
ret[modifier] = optional ? null : true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
} catch (err) {
|
|||
|
|
_didIteratorError = true;
|
|||
|
|
_iteratorError = err;
|
|||
|
|
} finally {
|
|||
|
|
try {
|
|||
|
|
if (!_iteratorNormalCompletion && _iterator.return) {
|
|||
|
|
_iterator.return();
|
|||
|
|
}
|
|||
|
|
} finally {
|
|||
|
|
if (_didIteratorError) {
|
|||
|
|
throw _iteratorError;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return ret;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Compare.
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
function compareHotkey(object, event) {
|
|||
|
|
for (var key in object) {
|
|||
|
|
var expected = object[key];
|
|||
|
|
var actual = void 0;
|
|||
|
|
|
|||
|
|
if (expected == null) {
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (key === 'key' && event.key != null) {
|
|||
|
|
actual = event.key.toLowerCase();
|
|||
|
|
} else if (key === 'which') {
|
|||
|
|
actual = expected === 91 && event.which === 93 ? 91 : event.which;
|
|||
|
|
} else {
|
|||
|
|
actual = event[key];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (actual == null && expected === false) {
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (actual !== expected) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Utils.
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
function toKeyCode(name) {
|
|||
|
|
name = toKeyName(name);
|
|||
|
|
var code = CODES[name] || name.toUpperCase().charCodeAt(0);
|
|||
|
|
return code;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function toKeyName(name) {
|
|||
|
|
name = name.toLowerCase();
|
|||
|
|
name = ALIASES[name] || name;
|
|||
|
|
return name;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Export.
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
var _default = isHotkey;
|
|||
|
|
var isHotkey_1 = isHotkey;
|
|||
|
|
var isCodeHotkey_1 = isCodeHotkey;
|
|||
|
|
var isKeyHotkey_1 = isKeyHotkey;
|
|||
|
|
var parseHotkey_1 = parseHotkey;
|
|||
|
|
var compareHotkey_1 = compareHotkey;
|
|||
|
|
var toKeyCode_1 = toKeyCode;
|
|||
|
|
var toKeyName_1 = toKeyName;
|
|||
|
|
|
|||
|
|
var lib$4 = /*#__PURE__*/Object.defineProperty({
|
|||
|
|
default: _default,
|
|||
|
|
isHotkey: isHotkey_1,
|
|||
|
|
isCodeHotkey: isCodeHotkey_1,
|
|||
|
|
isKeyHotkey: isKeyHotkey_1,
|
|||
|
|
parseHotkey: parseHotkey_1,
|
|||
|
|
compareHotkey: compareHotkey_1,
|
|||
|
|
toKeyCode: toKeyCode_1,
|
|||
|
|
toKeyName: toKeyName_1
|
|||
|
|
}, '__esModule', {value: true});
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* lodash (Custom Build) <https://lodash.com/>
|
|||
|
|
* Build: `lodash modularize exports="npm" -o ./`
|
|||
|
|
* Copyright jQuery Foundation and other contributors <https://jquery.org/>
|
|||
|
|
* Released under MIT license <https://lodash.com/license>
|
|||
|
|
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
|
|||
|
|
* Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
/** Used as the `TypeError` message for "Functions" methods. */
|
|||
|
|
var FUNC_ERROR_TEXT = 'Expected a function';
|
|||
|
|
|
|||
|
|
/** Used as references for various `Number` constants. */
|
|||
|
|
var NAN = 0 / 0;
|
|||
|
|
|
|||
|
|
/** `Object#toString` result references. */
|
|||
|
|
var symbolTag = '[object Symbol]';
|
|||
|
|
|
|||
|
|
/** Used to match leading and trailing whitespace. */
|
|||
|
|
var reTrim = /^\s+|\s+$/g;
|
|||
|
|
|
|||
|
|
/** Used to detect bad signed hexadecimal string values. */
|
|||
|
|
var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
|
|||
|
|
|
|||
|
|
/** Used to detect binary string values. */
|
|||
|
|
var reIsBinary = /^0b[01]+$/i;
|
|||
|
|
|
|||
|
|
/** Used to detect octal string values. */
|
|||
|
|
var reIsOctal = /^0o[0-7]+$/i;
|
|||
|
|
|
|||
|
|
/** Built-in method references without a dependency on `root`. */
|
|||
|
|
var freeParseInt = parseInt;
|
|||
|
|
|
|||
|
|
/** Detect free variable `global` from Node.js. */
|
|||
|
|
var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;
|
|||
|
|
|
|||
|
|
/** Detect free variable `self`. */
|
|||
|
|
var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
|
|||
|
|
|
|||
|
|
/** Used as a reference to the global object. */
|
|||
|
|
var root = freeGlobal || freeSelf || Function('return this')();
|
|||
|
|
|
|||
|
|
/** Used for built-in method references. */
|
|||
|
|
var objectProto = Object.prototype;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Used to resolve the
|
|||
|
|
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
|
|||
|
|
* of values.
|
|||
|
|
*/
|
|||
|
|
var objectToString = objectProto.toString;
|
|||
|
|
|
|||
|
|
/* Built-in method references for those with the same name as other `lodash` methods. */
|
|||
|
|
var nativeMax = Math.max,
|
|||
|
|
nativeMin = Math.min;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Gets the timestamp of the number of milliseconds that have elapsed since
|
|||
|
|
* the Unix epoch (1 January 1970 00:00:00 UTC).
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 2.4.0
|
|||
|
|
* @category Date
|
|||
|
|
* @returns {number} Returns the timestamp.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.defer(function(stamp) {
|
|||
|
|
* console.log(_.now() - stamp);
|
|||
|
|
* }, _.now());
|
|||
|
|
* // => Logs the number of milliseconds it took for the deferred invocation.
|
|||
|
|
*/
|
|||
|
|
var now = function() {
|
|||
|
|
return root.Date.now();
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Creates a debounced function that delays invoking `func` until after `wait`
|
|||
|
|
* milliseconds have elapsed since the last time the debounced function was
|
|||
|
|
* invoked. The debounced function comes with a `cancel` method to cancel
|
|||
|
|
* delayed `func` invocations and a `flush` method to immediately invoke them.
|
|||
|
|
* Provide `options` to indicate whether `func` should be invoked on the
|
|||
|
|
* leading and/or trailing edge of the `wait` timeout. The `func` is invoked
|
|||
|
|
* with the last arguments provided to the debounced function. Subsequent
|
|||
|
|
* calls to the debounced function return the result of the last `func`
|
|||
|
|
* invocation.
|
|||
|
|
*
|
|||
|
|
* **Note:** If `leading` and `trailing` options are `true`, `func` is
|
|||
|
|
* invoked on the trailing edge of the timeout only if the debounced function
|
|||
|
|
* is invoked more than once during the `wait` timeout.
|
|||
|
|
*
|
|||
|
|
* If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
|
|||
|
|
* until to the next tick, similar to `setTimeout` with a timeout of `0`.
|
|||
|
|
*
|
|||
|
|
* See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
|
|||
|
|
* for details over the differences between `_.debounce` and `_.throttle`.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 0.1.0
|
|||
|
|
* @category Function
|
|||
|
|
* @param {Function} func The function to debounce.
|
|||
|
|
* @param {number} [wait=0] The number of milliseconds to delay.
|
|||
|
|
* @param {Object} [options={}] The options object.
|
|||
|
|
* @param {boolean} [options.leading=false]
|
|||
|
|
* Specify invoking on the leading edge of the timeout.
|
|||
|
|
* @param {number} [options.maxWait]
|
|||
|
|
* The maximum time `func` is allowed to be delayed before it's invoked.
|
|||
|
|
* @param {boolean} [options.trailing=true]
|
|||
|
|
* Specify invoking on the trailing edge of the timeout.
|
|||
|
|
* @returns {Function} Returns the new debounced function.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* // Avoid costly calculations while the window size is in flux.
|
|||
|
|
* jQuery(window).on('resize', _.debounce(calculateLayout, 150));
|
|||
|
|
*
|
|||
|
|
* // Invoke `sendMail` when clicked, debouncing subsequent calls.
|
|||
|
|
* jQuery(element).on('click', _.debounce(sendMail, 300, {
|
|||
|
|
* 'leading': true,
|
|||
|
|
* 'trailing': false
|
|||
|
|
* }));
|
|||
|
|
*
|
|||
|
|
* // Ensure `batchLog` is invoked once after 1 second of debounced calls.
|
|||
|
|
* var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
|
|||
|
|
* var source = new EventSource('/stream');
|
|||
|
|
* jQuery(source).on('message', debounced);
|
|||
|
|
*
|
|||
|
|
* // Cancel the trailing debounced invocation.
|
|||
|
|
* jQuery(window).on('popstate', debounced.cancel);
|
|||
|
|
*/
|
|||
|
|
function debounce$1(func, wait, options) {
|
|||
|
|
var lastArgs,
|
|||
|
|
lastThis,
|
|||
|
|
maxWait,
|
|||
|
|
result,
|
|||
|
|
timerId,
|
|||
|
|
lastCallTime,
|
|||
|
|
lastInvokeTime = 0,
|
|||
|
|
leading = false,
|
|||
|
|
maxing = false,
|
|||
|
|
trailing = true;
|
|||
|
|
|
|||
|
|
if (typeof func != 'function') {
|
|||
|
|
throw new TypeError(FUNC_ERROR_TEXT);
|
|||
|
|
}
|
|||
|
|
wait = toNumber(wait) || 0;
|
|||
|
|
if (isObject(options)) {
|
|||
|
|
leading = !!options.leading;
|
|||
|
|
maxing = 'maxWait' in options;
|
|||
|
|
maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
|
|||
|
|
trailing = 'trailing' in options ? !!options.trailing : trailing;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function invokeFunc(time) {
|
|||
|
|
var args = lastArgs,
|
|||
|
|
thisArg = lastThis;
|
|||
|
|
|
|||
|
|
lastArgs = lastThis = undefined;
|
|||
|
|
lastInvokeTime = time;
|
|||
|
|
result = func.apply(thisArg, args);
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function leadingEdge(time) {
|
|||
|
|
// Reset any `maxWait` timer.
|
|||
|
|
lastInvokeTime = time;
|
|||
|
|
// Start the timer for the trailing edge.
|
|||
|
|
timerId = setTimeout(timerExpired, wait);
|
|||
|
|
// Invoke the leading edge.
|
|||
|
|
return leading ? invokeFunc(time) : result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function remainingWait(time) {
|
|||
|
|
var timeSinceLastCall = time - lastCallTime,
|
|||
|
|
timeSinceLastInvoke = time - lastInvokeTime,
|
|||
|
|
result = wait - timeSinceLastCall;
|
|||
|
|
|
|||
|
|
return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function shouldInvoke(time) {
|
|||
|
|
var timeSinceLastCall = time - lastCallTime,
|
|||
|
|
timeSinceLastInvoke = time - lastInvokeTime;
|
|||
|
|
|
|||
|
|
// Either this is the first call, activity has stopped and we're at the
|
|||
|
|
// trailing edge, the system time has gone backwards and we're treating
|
|||
|
|
// it as the trailing edge, or we've hit the `maxWait` limit.
|
|||
|
|
return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
|
|||
|
|
(timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function timerExpired() {
|
|||
|
|
var time = now();
|
|||
|
|
if (shouldInvoke(time)) {
|
|||
|
|
return trailingEdge(time);
|
|||
|
|
}
|
|||
|
|
// Restart the timer.
|
|||
|
|
timerId = setTimeout(timerExpired, remainingWait(time));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function trailingEdge(time) {
|
|||
|
|
timerId = undefined;
|
|||
|
|
|
|||
|
|
// Only invoke if we have `lastArgs` which means `func` has been
|
|||
|
|
// debounced at least once.
|
|||
|
|
if (trailing && lastArgs) {
|
|||
|
|
return invokeFunc(time);
|
|||
|
|
}
|
|||
|
|
lastArgs = lastThis = undefined;
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function cancel() {
|
|||
|
|
if (timerId !== undefined) {
|
|||
|
|
clearTimeout(timerId);
|
|||
|
|
}
|
|||
|
|
lastInvokeTime = 0;
|
|||
|
|
lastArgs = lastCallTime = lastThis = timerId = undefined;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function flush() {
|
|||
|
|
return timerId === undefined ? result : trailingEdge(now());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function debounced() {
|
|||
|
|
var time = now(),
|
|||
|
|
isInvoking = shouldInvoke(time);
|
|||
|
|
|
|||
|
|
lastArgs = arguments;
|
|||
|
|
lastThis = this;
|
|||
|
|
lastCallTime = time;
|
|||
|
|
|
|||
|
|
if (isInvoking) {
|
|||
|
|
if (timerId === undefined) {
|
|||
|
|
return leadingEdge(lastCallTime);
|
|||
|
|
}
|
|||
|
|
if (maxing) {
|
|||
|
|
// Handle invocations in a tight loop.
|
|||
|
|
timerId = setTimeout(timerExpired, wait);
|
|||
|
|
return invokeFunc(lastCallTime);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if (timerId === undefined) {
|
|||
|
|
timerId = setTimeout(timerExpired, wait);
|
|||
|
|
}
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
debounced.cancel = cancel;
|
|||
|
|
debounced.flush = flush;
|
|||
|
|
return debounced;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is the
|
|||
|
|
* [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
|
|||
|
|
* of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 0.1.0
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is an object, else `false`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.isObject({});
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isObject([1, 2, 3]);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isObject(_.noop);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isObject(null);
|
|||
|
|
* // => false
|
|||
|
|
*/
|
|||
|
|
function isObject(value) {
|
|||
|
|
var type = typeof value;
|
|||
|
|
return !!value && (type == 'object' || type == 'function');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is object-like. A value is object-like if it's not `null`
|
|||
|
|
* and has a `typeof` result of "object".
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 4.0.0
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.isObjectLike({});
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isObjectLike([1, 2, 3]);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isObjectLike(_.noop);
|
|||
|
|
* // => false
|
|||
|
|
*
|
|||
|
|
* _.isObjectLike(null);
|
|||
|
|
* // => false
|
|||
|
|
*/
|
|||
|
|
function isObjectLike(value) {
|
|||
|
|
return !!value && typeof value == 'object';
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is classified as a `Symbol` primitive or object.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 4.0.0
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.isSymbol(Symbol.iterator);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isSymbol('abc');
|
|||
|
|
* // => false
|
|||
|
|
*/
|
|||
|
|
function isSymbol(value) {
|
|||
|
|
return typeof value == 'symbol' ||
|
|||
|
|
(isObjectLike(value) && objectToString.call(value) == symbolTag);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Converts `value` to a number.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 4.0.0
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to process.
|
|||
|
|
* @returns {number} Returns the number.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.toNumber(3.2);
|
|||
|
|
* // => 3.2
|
|||
|
|
*
|
|||
|
|
* _.toNumber(Number.MIN_VALUE);
|
|||
|
|
* // => 5e-324
|
|||
|
|
*
|
|||
|
|
* _.toNumber(Infinity);
|
|||
|
|
* // => Infinity
|
|||
|
|
*
|
|||
|
|
* _.toNumber('3.2');
|
|||
|
|
* // => 3.2
|
|||
|
|
*/
|
|||
|
|
function toNumber(value) {
|
|||
|
|
if (typeof value == 'number') {
|
|||
|
|
return value;
|
|||
|
|
}
|
|||
|
|
if (isSymbol(value)) {
|
|||
|
|
return NAN;
|
|||
|
|
}
|
|||
|
|
if (isObject(value)) {
|
|||
|
|
var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
|
|||
|
|
value = isObject(other) ? (other + '') : other;
|
|||
|
|
}
|
|||
|
|
if (typeof value != 'string') {
|
|||
|
|
return value === 0 ? value : +value;
|
|||
|
|
}
|
|||
|
|
value = value.replace(reTrim, '');
|
|||
|
|
var isBinary = reIsBinary.test(value);
|
|||
|
|
return (isBinary || reIsOctal.test(value))
|
|||
|
|
? freeParseInt(value.slice(2), isBinary ? 2 : 8)
|
|||
|
|
: (reIsBadHex.test(value) ? NAN : +value);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var lodash_debounce = debounce$1;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* lodash (Custom Build) <https://lodash.com/>
|
|||
|
|
* Build: `lodash modularize exports="npm" -o ./`
|
|||
|
|
* Copyright jQuery Foundation and other contributors <https://jquery.org/>
|
|||
|
|
* Released under MIT license <https://lodash.com/license>
|
|||
|
|
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
|
|||
|
|
* Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
var lodash_clonedeep = createCommonjsModule$1(function (module, exports) {
|
|||
|
|
/** Used as the size to enable large array optimizations. */
|
|||
|
|
var LARGE_ARRAY_SIZE = 200;
|
|||
|
|
|
|||
|
|
/** Used to stand-in for `undefined` hash values. */
|
|||
|
|
var HASH_UNDEFINED = '__lodash_hash_undefined__';
|
|||
|
|
|
|||
|
|
/** Used as references for various `Number` constants. */
|
|||
|
|
var MAX_SAFE_INTEGER = 9007199254740991;
|
|||
|
|
|
|||
|
|
/** `Object#toString` result references. */
|
|||
|
|
var argsTag = '[object Arguments]',
|
|||
|
|
arrayTag = '[object Array]',
|
|||
|
|
boolTag = '[object Boolean]',
|
|||
|
|
dateTag = '[object Date]',
|
|||
|
|
errorTag = '[object Error]',
|
|||
|
|
funcTag = '[object Function]',
|
|||
|
|
genTag = '[object GeneratorFunction]',
|
|||
|
|
mapTag = '[object Map]',
|
|||
|
|
numberTag = '[object Number]',
|
|||
|
|
objectTag = '[object Object]',
|
|||
|
|
promiseTag = '[object Promise]',
|
|||
|
|
regexpTag = '[object RegExp]',
|
|||
|
|
setTag = '[object Set]',
|
|||
|
|
stringTag = '[object String]',
|
|||
|
|
symbolTag = '[object Symbol]',
|
|||
|
|
weakMapTag = '[object WeakMap]';
|
|||
|
|
|
|||
|
|
var arrayBufferTag = '[object ArrayBuffer]',
|
|||
|
|
dataViewTag = '[object DataView]',
|
|||
|
|
float32Tag = '[object Float32Array]',
|
|||
|
|
float64Tag = '[object Float64Array]',
|
|||
|
|
int8Tag = '[object Int8Array]',
|
|||
|
|
int16Tag = '[object Int16Array]',
|
|||
|
|
int32Tag = '[object Int32Array]',
|
|||
|
|
uint8Tag = '[object Uint8Array]',
|
|||
|
|
uint8ClampedTag = '[object Uint8ClampedArray]',
|
|||
|
|
uint16Tag = '[object Uint16Array]',
|
|||
|
|
uint32Tag = '[object Uint32Array]';
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Used to match `RegExp`
|
|||
|
|
* [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
|
|||
|
|
*/
|
|||
|
|
var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
|
|||
|
|
|
|||
|
|
/** Used to match `RegExp` flags from their coerced string values. */
|
|||
|
|
var reFlags = /\w*$/;
|
|||
|
|
|
|||
|
|
/** Used to detect host constructors (Safari). */
|
|||
|
|
var reIsHostCtor = /^\[object .+?Constructor\]$/;
|
|||
|
|
|
|||
|
|
/** Used to detect unsigned integer values. */
|
|||
|
|
var reIsUint = /^(?:0|[1-9]\d*)$/;
|
|||
|
|
|
|||
|
|
/** Used to identify `toStringTag` values supported by `_.clone`. */
|
|||
|
|
var cloneableTags = {};
|
|||
|
|
cloneableTags[argsTag] = cloneableTags[arrayTag] =
|
|||
|
|
cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =
|
|||
|
|
cloneableTags[boolTag] = cloneableTags[dateTag] =
|
|||
|
|
cloneableTags[float32Tag] = cloneableTags[float64Tag] =
|
|||
|
|
cloneableTags[int8Tag] = cloneableTags[int16Tag] =
|
|||
|
|
cloneableTags[int32Tag] = cloneableTags[mapTag] =
|
|||
|
|
cloneableTags[numberTag] = cloneableTags[objectTag] =
|
|||
|
|
cloneableTags[regexpTag] = cloneableTags[setTag] =
|
|||
|
|
cloneableTags[stringTag] = cloneableTags[symbolTag] =
|
|||
|
|
cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
|
|||
|
|
cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
|
|||
|
|
cloneableTags[errorTag] = cloneableTags[funcTag] =
|
|||
|
|
cloneableTags[weakMapTag] = false;
|
|||
|
|
|
|||
|
|
/** Detect free variable `global` from Node.js. */
|
|||
|
|
var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;
|
|||
|
|
|
|||
|
|
/** Detect free variable `self`. */
|
|||
|
|
var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
|
|||
|
|
|
|||
|
|
/** Used as a reference to the global object. */
|
|||
|
|
var root = freeGlobal || freeSelf || Function('return this')();
|
|||
|
|
|
|||
|
|
/** Detect free variable `exports`. */
|
|||
|
|
var freeExports = exports && !exports.nodeType && exports;
|
|||
|
|
|
|||
|
|
/** Detect free variable `module`. */
|
|||
|
|
var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module;
|
|||
|
|
|
|||
|
|
/** Detect the popular CommonJS extension `module.exports`. */
|
|||
|
|
var moduleExports = freeModule && freeModule.exports === freeExports;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Adds the key-value `pair` to `map`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Object} map The map to modify.
|
|||
|
|
* @param {Array} pair The key-value pair to add.
|
|||
|
|
* @returns {Object} Returns `map`.
|
|||
|
|
*/
|
|||
|
|
function addMapEntry(map, pair) {
|
|||
|
|
// Don't return `map.set` because it's not chainable in IE 11.
|
|||
|
|
map.set(pair[0], pair[1]);
|
|||
|
|
return map;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Adds `value` to `set`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Object} set The set to modify.
|
|||
|
|
* @param {*} value The value to add.
|
|||
|
|
* @returns {Object} Returns `set`.
|
|||
|
|
*/
|
|||
|
|
function addSetEntry(set, value) {
|
|||
|
|
// Don't return `set.add` because it's not chainable in IE 11.
|
|||
|
|
set.add(value);
|
|||
|
|
return set;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* A specialized version of `_.forEach` for arrays without support for
|
|||
|
|
* iteratee shorthands.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Array} [array] The array to iterate over.
|
|||
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|||
|
|
* @returns {Array} Returns `array`.
|
|||
|
|
*/
|
|||
|
|
function arrayEach(array, iteratee) {
|
|||
|
|
var index = -1,
|
|||
|
|
length = array ? array.length : 0;
|
|||
|
|
|
|||
|
|
while (++index < length) {
|
|||
|
|
if (iteratee(array[index], index, array) === false) {
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return array;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Appends the elements of `values` to `array`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Array} array The array to modify.
|
|||
|
|
* @param {Array} values The values to append.
|
|||
|
|
* @returns {Array} Returns `array`.
|
|||
|
|
*/
|
|||
|
|
function arrayPush(array, values) {
|
|||
|
|
var index = -1,
|
|||
|
|
length = values.length,
|
|||
|
|
offset = array.length;
|
|||
|
|
|
|||
|
|
while (++index < length) {
|
|||
|
|
array[offset + index] = values[index];
|
|||
|
|
}
|
|||
|
|
return array;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* A specialized version of `_.reduce` for arrays without support for
|
|||
|
|
* iteratee shorthands.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Array} [array] The array to iterate over.
|
|||
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|||
|
|
* @param {*} [accumulator] The initial value.
|
|||
|
|
* @param {boolean} [initAccum] Specify using the first element of `array` as
|
|||
|
|
* the initial value.
|
|||
|
|
* @returns {*} Returns the accumulated value.
|
|||
|
|
*/
|
|||
|
|
function arrayReduce(array, iteratee, accumulator, initAccum) {
|
|||
|
|
var index = -1,
|
|||
|
|
length = array ? array.length : 0;
|
|||
|
|
|
|||
|
|
if (initAccum && length) {
|
|||
|
|
accumulator = array[++index];
|
|||
|
|
}
|
|||
|
|
while (++index < length) {
|
|||
|
|
accumulator = iteratee(accumulator, array[index], index, array);
|
|||
|
|
}
|
|||
|
|
return accumulator;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* The base implementation of `_.times` without support for iteratee shorthands
|
|||
|
|
* or max array length checks.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {number} n The number of times to invoke `iteratee`.
|
|||
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|||
|
|
* @returns {Array} Returns the array of results.
|
|||
|
|
*/
|
|||
|
|
function baseTimes(n, iteratee) {
|
|||
|
|
var index = -1,
|
|||
|
|
result = Array(n);
|
|||
|
|
|
|||
|
|
while (++index < n) {
|
|||
|
|
result[index] = iteratee(index);
|
|||
|
|
}
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Gets the value at `key` of `object`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Object} [object] The object to query.
|
|||
|
|
* @param {string} key The key of the property to get.
|
|||
|
|
* @returns {*} Returns the property value.
|
|||
|
|
*/
|
|||
|
|
function getValue(object, key) {
|
|||
|
|
return object == null ? undefined : object[key];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is a host object in IE < 9.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is a host object, else `false`.
|
|||
|
|
*/
|
|||
|
|
function isHostObject(value) {
|
|||
|
|
// Many host objects are `Object` objects that can coerce to strings
|
|||
|
|
// despite having improperly defined `toString` methods.
|
|||
|
|
var result = false;
|
|||
|
|
if (value != null && typeof value.toString != 'function') {
|
|||
|
|
try {
|
|||
|
|
result = !!(value + '');
|
|||
|
|
} catch (e) {}
|
|||
|
|
}
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Converts `map` to its key-value pairs.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Object} map The map to convert.
|
|||
|
|
* @returns {Array} Returns the key-value pairs.
|
|||
|
|
*/
|
|||
|
|
function mapToArray(map) {
|
|||
|
|
var index = -1,
|
|||
|
|
result = Array(map.size);
|
|||
|
|
|
|||
|
|
map.forEach(function(value, key) {
|
|||
|
|
result[++index] = [key, value];
|
|||
|
|
});
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Creates a unary function that invokes `func` with its argument transformed.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Function} func The function to wrap.
|
|||
|
|
* @param {Function} transform The argument transform.
|
|||
|
|
* @returns {Function} Returns the new function.
|
|||
|
|
*/
|
|||
|
|
function overArg(func, transform) {
|
|||
|
|
return function(arg) {
|
|||
|
|
return func(transform(arg));
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Converts `set` to an array of its values.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Object} set The set to convert.
|
|||
|
|
* @returns {Array} Returns the values.
|
|||
|
|
*/
|
|||
|
|
function setToArray(set) {
|
|||
|
|
var index = -1,
|
|||
|
|
result = Array(set.size);
|
|||
|
|
|
|||
|
|
set.forEach(function(value) {
|
|||
|
|
result[++index] = value;
|
|||
|
|
});
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/** Used for built-in method references. */
|
|||
|
|
var arrayProto = Array.prototype,
|
|||
|
|
funcProto = Function.prototype,
|
|||
|
|
objectProto = Object.prototype;
|
|||
|
|
|
|||
|
|
/** Used to detect overreaching core-js shims. */
|
|||
|
|
var coreJsData = root['__core-js_shared__'];
|
|||
|
|
|
|||
|
|
/** Used to detect methods masquerading as native. */
|
|||
|
|
var maskSrcKey = (function() {
|
|||
|
|
var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
|
|||
|
|
return uid ? ('Symbol(src)_1.' + uid) : '';
|
|||
|
|
}());
|
|||
|
|
|
|||
|
|
/** Used to resolve the decompiled source of functions. */
|
|||
|
|
var funcToString = funcProto.toString;
|
|||
|
|
|
|||
|
|
/** Used to check objects for own properties. */
|
|||
|
|
var hasOwnProperty = objectProto.hasOwnProperty;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Used to resolve the
|
|||
|
|
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
|
|||
|
|
* of values.
|
|||
|
|
*/
|
|||
|
|
var objectToString = objectProto.toString;
|
|||
|
|
|
|||
|
|
/** Used to detect if a method is native. */
|
|||
|
|
var reIsNative = RegExp('^' +
|
|||
|
|
funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
|
|||
|
|
.replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
/** Built-in value references. */
|
|||
|
|
var Buffer = moduleExports ? root.Buffer : undefined,
|
|||
|
|
Symbol = root.Symbol,
|
|||
|
|
Uint8Array = root.Uint8Array,
|
|||
|
|
getPrototype = overArg(Object.getPrototypeOf, Object),
|
|||
|
|
objectCreate = Object.create,
|
|||
|
|
propertyIsEnumerable = objectProto.propertyIsEnumerable,
|
|||
|
|
splice = arrayProto.splice;
|
|||
|
|
|
|||
|
|
/* Built-in method references for those with the same name as other `lodash` methods. */
|
|||
|
|
var nativeGetSymbols = Object.getOwnPropertySymbols,
|
|||
|
|
nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined,
|
|||
|
|
nativeKeys = overArg(Object.keys, Object);
|
|||
|
|
|
|||
|
|
/* Built-in method references that are verified to be native. */
|
|||
|
|
var DataView = getNative(root, 'DataView'),
|
|||
|
|
Map = getNative(root, 'Map'),
|
|||
|
|
Promise = getNative(root, 'Promise'),
|
|||
|
|
Set = getNative(root, 'Set'),
|
|||
|
|
WeakMap = getNative(root, 'WeakMap'),
|
|||
|
|
nativeCreate = getNative(Object, 'create');
|
|||
|
|
|
|||
|
|
/** Used to detect maps, sets, and weakmaps. */
|
|||
|
|
var dataViewCtorString = toSource(DataView),
|
|||
|
|
mapCtorString = toSource(Map),
|
|||
|
|
promiseCtorString = toSource(Promise),
|
|||
|
|
setCtorString = toSource(Set),
|
|||
|
|
weakMapCtorString = toSource(WeakMap);
|
|||
|
|
|
|||
|
|
/** Used to convert symbols to primitives and strings. */
|
|||
|
|
var symbolProto = Symbol ? Symbol.prototype : undefined,
|
|||
|
|
symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Creates a hash object.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @constructor
|
|||
|
|
* @param {Array} [entries] The key-value pairs to cache.
|
|||
|
|
*/
|
|||
|
|
function Hash(entries) {
|
|||
|
|
var index = -1,
|
|||
|
|
length = entries ? entries.length : 0;
|
|||
|
|
|
|||
|
|
this.clear();
|
|||
|
|
while (++index < length) {
|
|||
|
|
var entry = entries[index];
|
|||
|
|
this.set(entry[0], entry[1]);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Removes all key-value entries from the hash.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @name clear
|
|||
|
|
* @memberOf Hash
|
|||
|
|
*/
|
|||
|
|
function hashClear() {
|
|||
|
|
this.__data__ = nativeCreate ? nativeCreate(null) : {};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Removes `key` and its value from the hash.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @name delete
|
|||
|
|
* @memberOf Hash
|
|||
|
|
* @param {Object} hash The hash to modify.
|
|||
|
|
* @param {string} key The key of the value to remove.
|
|||
|
|
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
|
|||
|
|
*/
|
|||
|
|
function hashDelete(key) {
|
|||
|
|
return this.has(key) && delete this.__data__[key];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Gets the hash value for `key`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @name get
|
|||
|
|
* @memberOf Hash
|
|||
|
|
* @param {string} key The key of the value to get.
|
|||
|
|
* @returns {*} Returns the entry value.
|
|||
|
|
*/
|
|||
|
|
function hashGet(key) {
|
|||
|
|
var data = this.__data__;
|
|||
|
|
if (nativeCreate) {
|
|||
|
|
var result = data[key];
|
|||
|
|
return result === HASH_UNDEFINED ? undefined : result;
|
|||
|
|
}
|
|||
|
|
return hasOwnProperty.call(data, key) ? data[key] : undefined;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if a hash value for `key` exists.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @name has
|
|||
|
|
* @memberOf Hash
|
|||
|
|
* @param {string} key The key of the entry to check.
|
|||
|
|
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
|
|||
|
|
*/
|
|||
|
|
function hashHas(key) {
|
|||
|
|
var data = this.__data__;
|
|||
|
|
return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Sets the hash `key` to `value`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @name set
|
|||
|
|
* @memberOf Hash
|
|||
|
|
* @param {string} key The key of the value to set.
|
|||
|
|
* @param {*} value The value to set.
|
|||
|
|
* @returns {Object} Returns the hash instance.
|
|||
|
|
*/
|
|||
|
|
function hashSet(key, value) {
|
|||
|
|
var data = this.__data__;
|
|||
|
|
data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Add methods to `Hash`.
|
|||
|
|
Hash.prototype.clear = hashClear;
|
|||
|
|
Hash.prototype['delete'] = hashDelete;
|
|||
|
|
Hash.prototype.get = hashGet;
|
|||
|
|
Hash.prototype.has = hashHas;
|
|||
|
|
Hash.prototype.set = hashSet;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Creates an list cache object.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @constructor
|
|||
|
|
* @param {Array} [entries] The key-value pairs to cache.
|
|||
|
|
*/
|
|||
|
|
function ListCache(entries) {
|
|||
|
|
var index = -1,
|
|||
|
|
length = entries ? entries.length : 0;
|
|||
|
|
|
|||
|
|
this.clear();
|
|||
|
|
while (++index < length) {
|
|||
|
|
var entry = entries[index];
|
|||
|
|
this.set(entry[0], entry[1]);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Removes all key-value entries from the list cache.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @name clear
|
|||
|
|
* @memberOf ListCache
|
|||
|
|
*/
|
|||
|
|
function listCacheClear() {
|
|||
|
|
this.__data__ = [];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Removes `key` and its value from the list cache.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @name delete
|
|||
|
|
* @memberOf ListCache
|
|||
|
|
* @param {string} key The key of the value to remove.
|
|||
|
|
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
|
|||
|
|
*/
|
|||
|
|
function listCacheDelete(key) {
|
|||
|
|
var data = this.__data__,
|
|||
|
|
index = assocIndexOf(data, key);
|
|||
|
|
|
|||
|
|
if (index < 0) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
var lastIndex = data.length - 1;
|
|||
|
|
if (index == lastIndex) {
|
|||
|
|
data.pop();
|
|||
|
|
} else {
|
|||
|
|
splice.call(data, index, 1);
|
|||
|
|
}
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Gets the list cache value for `key`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @name get
|
|||
|
|
* @memberOf ListCache
|
|||
|
|
* @param {string} key The key of the value to get.
|
|||
|
|
* @returns {*} Returns the entry value.
|
|||
|
|
*/
|
|||
|
|
function listCacheGet(key) {
|
|||
|
|
var data = this.__data__,
|
|||
|
|
index = assocIndexOf(data, key);
|
|||
|
|
|
|||
|
|
return index < 0 ? undefined : data[index][1];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if a list cache value for `key` exists.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @name has
|
|||
|
|
* @memberOf ListCache
|
|||
|
|
* @param {string} key The key of the entry to check.
|
|||
|
|
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
|
|||
|
|
*/
|
|||
|
|
function listCacheHas(key) {
|
|||
|
|
return assocIndexOf(this.__data__, key) > -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Sets the list cache `key` to `value`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @name set
|
|||
|
|
* @memberOf ListCache
|
|||
|
|
* @param {string} key The key of the value to set.
|
|||
|
|
* @param {*} value The value to set.
|
|||
|
|
* @returns {Object} Returns the list cache instance.
|
|||
|
|
*/
|
|||
|
|
function listCacheSet(key, value) {
|
|||
|
|
var data = this.__data__,
|
|||
|
|
index = assocIndexOf(data, key);
|
|||
|
|
|
|||
|
|
if (index < 0) {
|
|||
|
|
data.push([key, value]);
|
|||
|
|
} else {
|
|||
|
|
data[index][1] = value;
|
|||
|
|
}
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Add methods to `ListCache`.
|
|||
|
|
ListCache.prototype.clear = listCacheClear;
|
|||
|
|
ListCache.prototype['delete'] = listCacheDelete;
|
|||
|
|
ListCache.prototype.get = listCacheGet;
|
|||
|
|
ListCache.prototype.has = listCacheHas;
|
|||
|
|
ListCache.prototype.set = listCacheSet;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Creates a map cache object to store key-value pairs.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @constructor
|
|||
|
|
* @param {Array} [entries] The key-value pairs to cache.
|
|||
|
|
*/
|
|||
|
|
function MapCache(entries) {
|
|||
|
|
var index = -1,
|
|||
|
|
length = entries ? entries.length : 0;
|
|||
|
|
|
|||
|
|
this.clear();
|
|||
|
|
while (++index < length) {
|
|||
|
|
var entry = entries[index];
|
|||
|
|
this.set(entry[0], entry[1]);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Removes all key-value entries from the map.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @name clear
|
|||
|
|
* @memberOf MapCache
|
|||
|
|
*/
|
|||
|
|
function mapCacheClear() {
|
|||
|
|
this.__data__ = {
|
|||
|
|
'hash': new Hash,
|
|||
|
|
'map': new (Map || ListCache),
|
|||
|
|
'string': new Hash
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Removes `key` and its value from the map.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @name delete
|
|||
|
|
* @memberOf MapCache
|
|||
|
|
* @param {string} key The key of the value to remove.
|
|||
|
|
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
|
|||
|
|
*/
|
|||
|
|
function mapCacheDelete(key) {
|
|||
|
|
return getMapData(this, key)['delete'](key);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Gets the map value for `key`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @name get
|
|||
|
|
* @memberOf MapCache
|
|||
|
|
* @param {string} key The key of the value to get.
|
|||
|
|
* @returns {*} Returns the entry value.
|
|||
|
|
*/
|
|||
|
|
function mapCacheGet(key) {
|
|||
|
|
return getMapData(this, key).get(key);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if a map value for `key` exists.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @name has
|
|||
|
|
* @memberOf MapCache
|
|||
|
|
* @param {string} key The key of the entry to check.
|
|||
|
|
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
|
|||
|
|
*/
|
|||
|
|
function mapCacheHas(key) {
|
|||
|
|
return getMapData(this, key).has(key);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Sets the map `key` to `value`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @name set
|
|||
|
|
* @memberOf MapCache
|
|||
|
|
* @param {string} key The key of the value to set.
|
|||
|
|
* @param {*} value The value to set.
|
|||
|
|
* @returns {Object} Returns the map cache instance.
|
|||
|
|
*/
|
|||
|
|
function mapCacheSet(key, value) {
|
|||
|
|
getMapData(this, key).set(key, value);
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Add methods to `MapCache`.
|
|||
|
|
MapCache.prototype.clear = mapCacheClear;
|
|||
|
|
MapCache.prototype['delete'] = mapCacheDelete;
|
|||
|
|
MapCache.prototype.get = mapCacheGet;
|
|||
|
|
MapCache.prototype.has = mapCacheHas;
|
|||
|
|
MapCache.prototype.set = mapCacheSet;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Creates a stack cache object to store key-value pairs.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @constructor
|
|||
|
|
* @param {Array} [entries] The key-value pairs to cache.
|
|||
|
|
*/
|
|||
|
|
function Stack(entries) {
|
|||
|
|
this.__data__ = new ListCache(entries);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Removes all key-value entries from the stack.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @name clear
|
|||
|
|
* @memberOf Stack
|
|||
|
|
*/
|
|||
|
|
function stackClear() {
|
|||
|
|
this.__data__ = new ListCache;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Removes `key` and its value from the stack.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @name delete
|
|||
|
|
* @memberOf Stack
|
|||
|
|
* @param {string} key The key of the value to remove.
|
|||
|
|
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
|
|||
|
|
*/
|
|||
|
|
function stackDelete(key) {
|
|||
|
|
return this.__data__['delete'](key);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Gets the stack value for `key`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @name get
|
|||
|
|
* @memberOf Stack
|
|||
|
|
* @param {string} key The key of the value to get.
|
|||
|
|
* @returns {*} Returns the entry value.
|
|||
|
|
*/
|
|||
|
|
function stackGet(key) {
|
|||
|
|
return this.__data__.get(key);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if a stack value for `key` exists.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @name has
|
|||
|
|
* @memberOf Stack
|
|||
|
|
* @param {string} key The key of the entry to check.
|
|||
|
|
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
|
|||
|
|
*/
|
|||
|
|
function stackHas(key) {
|
|||
|
|
return this.__data__.has(key);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Sets the stack `key` to `value`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @name set
|
|||
|
|
* @memberOf Stack
|
|||
|
|
* @param {string} key The key of the value to set.
|
|||
|
|
* @param {*} value The value to set.
|
|||
|
|
* @returns {Object} Returns the stack cache instance.
|
|||
|
|
*/
|
|||
|
|
function stackSet(key, value) {
|
|||
|
|
var cache = this.__data__;
|
|||
|
|
if (cache instanceof ListCache) {
|
|||
|
|
var pairs = cache.__data__;
|
|||
|
|
if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
|
|||
|
|
pairs.push([key, value]);
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
cache = this.__data__ = new MapCache(pairs);
|
|||
|
|
}
|
|||
|
|
cache.set(key, value);
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Add methods to `Stack`.
|
|||
|
|
Stack.prototype.clear = stackClear;
|
|||
|
|
Stack.prototype['delete'] = stackDelete;
|
|||
|
|
Stack.prototype.get = stackGet;
|
|||
|
|
Stack.prototype.has = stackHas;
|
|||
|
|
Stack.prototype.set = stackSet;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Creates an array of the enumerable property names of the array-like `value`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {*} value The value to query.
|
|||
|
|
* @param {boolean} inherited Specify returning inherited property names.
|
|||
|
|
* @returns {Array} Returns the array of property names.
|
|||
|
|
*/
|
|||
|
|
function arrayLikeKeys(value, inherited) {
|
|||
|
|
// Safari 8.1 makes `arguments.callee` enumerable in strict mode.
|
|||
|
|
// Safari 9 makes `arguments.length` enumerable in strict mode.
|
|||
|
|
var result = (isArray(value) || isArguments(value))
|
|||
|
|
? baseTimes(value.length, String)
|
|||
|
|
: [];
|
|||
|
|
|
|||
|
|
var length = result.length,
|
|||
|
|
skipIndexes = !!length;
|
|||
|
|
|
|||
|
|
for (var key in value) {
|
|||
|
|
if ((inherited || hasOwnProperty.call(value, key)) &&
|
|||
|
|
!(skipIndexes && (key == 'length' || isIndex(key, length)))) {
|
|||
|
|
result.push(key);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Assigns `value` to `key` of `object` if the existing value is not equivalent
|
|||
|
|
* using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
|
|||
|
|
* for equality comparisons.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Object} object The object to modify.
|
|||
|
|
* @param {string} key The key of the property to assign.
|
|||
|
|
* @param {*} value The value to assign.
|
|||
|
|
*/
|
|||
|
|
function assignValue(object, key, value) {
|
|||
|
|
var objValue = object[key];
|
|||
|
|
if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||
|
|||
|
|
(value === undefined && !(key in object))) {
|
|||
|
|
object[key] = value;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Gets the index at which the `key` is found in `array` of key-value pairs.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Array} array The array to inspect.
|
|||
|
|
* @param {*} key The key to search for.
|
|||
|
|
* @returns {number} Returns the index of the matched value, else `-1`.
|
|||
|
|
*/
|
|||
|
|
function assocIndexOf(array, key) {
|
|||
|
|
var length = array.length;
|
|||
|
|
while (length--) {
|
|||
|
|
if (eq(array[length][0], key)) {
|
|||
|
|
return length;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* The base implementation of `_.assign` without support for multiple sources
|
|||
|
|
* or `customizer` functions.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Object} object The destination object.
|
|||
|
|
* @param {Object} source The source object.
|
|||
|
|
* @returns {Object} Returns `object`.
|
|||
|
|
*/
|
|||
|
|
function baseAssign(object, source) {
|
|||
|
|
return object && copyObject(source, keys(source), object);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* The base implementation of `_.clone` and `_.cloneDeep` which tracks
|
|||
|
|
* traversed objects.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {*} value The value to clone.
|
|||
|
|
* @param {boolean} [isDeep] Specify a deep clone.
|
|||
|
|
* @param {boolean} [isFull] Specify a clone including symbols.
|
|||
|
|
* @param {Function} [customizer] The function to customize cloning.
|
|||
|
|
* @param {string} [key] The key of `value`.
|
|||
|
|
* @param {Object} [object] The parent object of `value`.
|
|||
|
|
* @param {Object} [stack] Tracks traversed objects and their clone counterparts.
|
|||
|
|
* @returns {*} Returns the cloned value.
|
|||
|
|
*/
|
|||
|
|
function baseClone(value, isDeep, isFull, customizer, key, object, stack) {
|
|||
|
|
var result;
|
|||
|
|
if (customizer) {
|
|||
|
|
result = object ? customizer(value, key, object, stack) : customizer(value);
|
|||
|
|
}
|
|||
|
|
if (result !== undefined) {
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
if (!isObject(value)) {
|
|||
|
|
return value;
|
|||
|
|
}
|
|||
|
|
var isArr = isArray(value);
|
|||
|
|
if (isArr) {
|
|||
|
|
result = initCloneArray(value);
|
|||
|
|
if (!isDeep) {
|
|||
|
|
return copyArray(value, result);
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
var tag = getTag(value),
|
|||
|
|
isFunc = tag == funcTag || tag == genTag;
|
|||
|
|
|
|||
|
|
if (isBuffer(value)) {
|
|||
|
|
return cloneBuffer(value, isDeep);
|
|||
|
|
}
|
|||
|
|
if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
|
|||
|
|
if (isHostObject(value)) {
|
|||
|
|
return object ? value : {};
|
|||
|
|
}
|
|||
|
|
result = initCloneObject(isFunc ? {} : value);
|
|||
|
|
if (!isDeep) {
|
|||
|
|
return copySymbols(value, baseAssign(result, value));
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
if (!cloneableTags[tag]) {
|
|||
|
|
return object ? value : {};
|
|||
|
|
}
|
|||
|
|
result = initCloneByTag(value, tag, baseClone, isDeep);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
// Check for circular references and return its corresponding clone.
|
|||
|
|
stack || (stack = new Stack);
|
|||
|
|
var stacked = stack.get(value);
|
|||
|
|
if (stacked) {
|
|||
|
|
return stacked;
|
|||
|
|
}
|
|||
|
|
stack.set(value, result);
|
|||
|
|
|
|||
|
|
if (!isArr) {
|
|||
|
|
var props = isFull ? getAllKeys(value) : keys(value);
|
|||
|
|
}
|
|||
|
|
arrayEach(props || value, function(subValue, key) {
|
|||
|
|
if (props) {
|
|||
|
|
key = subValue;
|
|||
|
|
subValue = value[key];
|
|||
|
|
}
|
|||
|
|
// Recursively populate clone (susceptible to call stack limits).
|
|||
|
|
assignValue(result, key, baseClone(subValue, isDeep, isFull, customizer, key, value, stack));
|
|||
|
|
});
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* The base implementation of `_.create` without support for assigning
|
|||
|
|
* properties to the created object.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Object} prototype The object to inherit from.
|
|||
|
|
* @returns {Object} Returns the new object.
|
|||
|
|
*/
|
|||
|
|
function baseCreate(proto) {
|
|||
|
|
return isObject(proto) ? objectCreate(proto) : {};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* The base implementation of `getAllKeys` and `getAllKeysIn` which uses
|
|||
|
|
* `keysFunc` and `symbolsFunc` to get the enumerable property names and
|
|||
|
|
* symbols of `object`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Object} object The object to query.
|
|||
|
|
* @param {Function} keysFunc The function to get the keys of `object`.
|
|||
|
|
* @param {Function} symbolsFunc The function to get the symbols of `object`.
|
|||
|
|
* @returns {Array} Returns the array of property names and symbols.
|
|||
|
|
*/
|
|||
|
|
function baseGetAllKeys(object, keysFunc, symbolsFunc) {
|
|||
|
|
var result = keysFunc(object);
|
|||
|
|
return isArray(object) ? result : arrayPush(result, symbolsFunc(object));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* The base implementation of `getTag`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {*} value The value to query.
|
|||
|
|
* @returns {string} Returns the `toStringTag`.
|
|||
|
|
*/
|
|||
|
|
function baseGetTag(value) {
|
|||
|
|
return objectToString.call(value);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* The base implementation of `_.isNative` without bad shim checks.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is a native function,
|
|||
|
|
* else `false`.
|
|||
|
|
*/
|
|||
|
|
function baseIsNative(value) {
|
|||
|
|
if (!isObject(value) || isMasked(value)) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor;
|
|||
|
|
return pattern.test(toSource(value));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Object} object The object to query.
|
|||
|
|
* @returns {Array} Returns the array of property names.
|
|||
|
|
*/
|
|||
|
|
function baseKeys(object) {
|
|||
|
|
if (!isPrototype(object)) {
|
|||
|
|
return nativeKeys(object);
|
|||
|
|
}
|
|||
|
|
var result = [];
|
|||
|
|
for (var key in Object(object)) {
|
|||
|
|
if (hasOwnProperty.call(object, key) && key != 'constructor') {
|
|||
|
|
result.push(key);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Creates a clone of `buffer`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Buffer} buffer The buffer to clone.
|
|||
|
|
* @param {boolean} [isDeep] Specify a deep clone.
|
|||
|
|
* @returns {Buffer} Returns the cloned buffer.
|
|||
|
|
*/
|
|||
|
|
function cloneBuffer(buffer, isDeep) {
|
|||
|
|
if (isDeep) {
|
|||
|
|
return buffer.slice();
|
|||
|
|
}
|
|||
|
|
var result = new buffer.constructor(buffer.length);
|
|||
|
|
buffer.copy(result);
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Creates a clone of `arrayBuffer`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {ArrayBuffer} arrayBuffer The array buffer to clone.
|
|||
|
|
* @returns {ArrayBuffer} Returns the cloned array buffer.
|
|||
|
|
*/
|
|||
|
|
function cloneArrayBuffer(arrayBuffer) {
|
|||
|
|
var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
|
|||
|
|
new Uint8Array(result).set(new Uint8Array(arrayBuffer));
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Creates a clone of `dataView`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Object} dataView The data view to clone.
|
|||
|
|
* @param {boolean} [isDeep] Specify a deep clone.
|
|||
|
|
* @returns {Object} Returns the cloned data view.
|
|||
|
|
*/
|
|||
|
|
function cloneDataView(dataView, isDeep) {
|
|||
|
|
var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;
|
|||
|
|
return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Creates a clone of `map`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Object} map The map to clone.
|
|||
|
|
* @param {Function} cloneFunc The function to clone values.
|
|||
|
|
* @param {boolean} [isDeep] Specify a deep clone.
|
|||
|
|
* @returns {Object} Returns the cloned map.
|
|||
|
|
*/
|
|||
|
|
function cloneMap(map, isDeep, cloneFunc) {
|
|||
|
|
var array = isDeep ? cloneFunc(mapToArray(map), true) : mapToArray(map);
|
|||
|
|
return arrayReduce(array, addMapEntry, new map.constructor);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Creates a clone of `regexp`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Object} regexp The regexp to clone.
|
|||
|
|
* @returns {Object} Returns the cloned regexp.
|
|||
|
|
*/
|
|||
|
|
function cloneRegExp(regexp) {
|
|||
|
|
var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));
|
|||
|
|
result.lastIndex = regexp.lastIndex;
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Creates a clone of `set`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Object} set The set to clone.
|
|||
|
|
* @param {Function} cloneFunc The function to clone values.
|
|||
|
|
* @param {boolean} [isDeep] Specify a deep clone.
|
|||
|
|
* @returns {Object} Returns the cloned set.
|
|||
|
|
*/
|
|||
|
|
function cloneSet(set, isDeep, cloneFunc) {
|
|||
|
|
var array = isDeep ? cloneFunc(setToArray(set), true) : setToArray(set);
|
|||
|
|
return arrayReduce(array, addSetEntry, new set.constructor);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Creates a clone of the `symbol` object.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Object} symbol The symbol object to clone.
|
|||
|
|
* @returns {Object} Returns the cloned symbol object.
|
|||
|
|
*/
|
|||
|
|
function cloneSymbol(symbol) {
|
|||
|
|
return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Creates a clone of `typedArray`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Object} typedArray The typed array to clone.
|
|||
|
|
* @param {boolean} [isDeep] Specify a deep clone.
|
|||
|
|
* @returns {Object} Returns the cloned typed array.
|
|||
|
|
*/
|
|||
|
|
function cloneTypedArray(typedArray, isDeep) {
|
|||
|
|
var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;
|
|||
|
|
return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Copies the values of `source` to `array`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Array} source The array to copy values from.
|
|||
|
|
* @param {Array} [array=[]] The array to copy values to.
|
|||
|
|
* @returns {Array} Returns `array`.
|
|||
|
|
*/
|
|||
|
|
function copyArray(source, array) {
|
|||
|
|
var index = -1,
|
|||
|
|
length = source.length;
|
|||
|
|
|
|||
|
|
array || (array = Array(length));
|
|||
|
|
while (++index < length) {
|
|||
|
|
array[index] = source[index];
|
|||
|
|
}
|
|||
|
|
return array;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Copies properties of `source` to `object`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Object} source The object to copy properties from.
|
|||
|
|
* @param {Array} props The property identifiers to copy.
|
|||
|
|
* @param {Object} [object={}] The object to copy properties to.
|
|||
|
|
* @param {Function} [customizer] The function to customize copied values.
|
|||
|
|
* @returns {Object} Returns `object`.
|
|||
|
|
*/
|
|||
|
|
function copyObject(source, props, object, customizer) {
|
|||
|
|
object || (object = {});
|
|||
|
|
|
|||
|
|
var index = -1,
|
|||
|
|
length = props.length;
|
|||
|
|
|
|||
|
|
while (++index < length) {
|
|||
|
|
var key = props[index];
|
|||
|
|
|
|||
|
|
var newValue = customizer
|
|||
|
|
? customizer(object[key], source[key], key, object, source)
|
|||
|
|
: undefined;
|
|||
|
|
|
|||
|
|
assignValue(object, key, newValue === undefined ? source[key] : newValue);
|
|||
|
|
}
|
|||
|
|
return object;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Copies own symbol properties of `source` to `object`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Object} source The object to copy symbols from.
|
|||
|
|
* @param {Object} [object={}] The object to copy symbols to.
|
|||
|
|
* @returns {Object} Returns `object`.
|
|||
|
|
*/
|
|||
|
|
function copySymbols(source, object) {
|
|||
|
|
return copyObject(source, getSymbols(source), object);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Creates an array of own enumerable property names and symbols of `object`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Object} object The object to query.
|
|||
|
|
* @returns {Array} Returns the array of property names and symbols.
|
|||
|
|
*/
|
|||
|
|
function getAllKeys(object) {
|
|||
|
|
return baseGetAllKeys(object, keys, getSymbols);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Gets the data for `map`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Object} map The map to query.
|
|||
|
|
* @param {string} key The reference key.
|
|||
|
|
* @returns {*} Returns the map data.
|
|||
|
|
*/
|
|||
|
|
function getMapData(map, key) {
|
|||
|
|
var data = map.__data__;
|
|||
|
|
return isKeyable(key)
|
|||
|
|
? data[typeof key == 'string' ? 'string' : 'hash']
|
|||
|
|
: data.map;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Gets the native function at `key` of `object`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Object} object The object to query.
|
|||
|
|
* @param {string} key The key of the method to get.
|
|||
|
|
* @returns {*} Returns the function if it's native, else `undefined`.
|
|||
|
|
*/
|
|||
|
|
function getNative(object, key) {
|
|||
|
|
var value = getValue(object, key);
|
|||
|
|
return baseIsNative(value) ? value : undefined;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Creates an array of the own enumerable symbol properties of `object`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Object} object The object to query.
|
|||
|
|
* @returns {Array} Returns the array of symbols.
|
|||
|
|
*/
|
|||
|
|
var getSymbols = nativeGetSymbols ? overArg(nativeGetSymbols, Object) : stubArray;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Gets the `toStringTag` of `value`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {*} value The value to query.
|
|||
|
|
* @returns {string} Returns the `toStringTag`.
|
|||
|
|
*/
|
|||
|
|
var getTag = baseGetTag;
|
|||
|
|
|
|||
|
|
// Fallback for data views, maps, sets, and weak maps in IE 11,
|
|||
|
|
// for data views in Edge < 14, and promises in Node.js.
|
|||
|
|
if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||
|
|||
|
|
(Map && getTag(new Map) != mapTag) ||
|
|||
|
|
(Promise && getTag(Promise.resolve()) != promiseTag) ||
|
|||
|
|
(Set && getTag(new Set) != setTag) ||
|
|||
|
|
(WeakMap && getTag(new WeakMap) != weakMapTag)) {
|
|||
|
|
getTag = function(value) {
|
|||
|
|
var result = objectToString.call(value),
|
|||
|
|
Ctor = result == objectTag ? value.constructor : undefined,
|
|||
|
|
ctorString = Ctor ? toSource(Ctor) : undefined;
|
|||
|
|
|
|||
|
|
if (ctorString) {
|
|||
|
|
switch (ctorString) {
|
|||
|
|
case dataViewCtorString: return dataViewTag;
|
|||
|
|
case mapCtorString: return mapTag;
|
|||
|
|
case promiseCtorString: return promiseTag;
|
|||
|
|
case setCtorString: return setTag;
|
|||
|
|
case weakMapCtorString: return weakMapTag;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return result;
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Initializes an array clone.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Array} array The array to clone.
|
|||
|
|
* @returns {Array} Returns the initialized clone.
|
|||
|
|
*/
|
|||
|
|
function initCloneArray(array) {
|
|||
|
|
var length = array.length,
|
|||
|
|
result = array.constructor(length);
|
|||
|
|
|
|||
|
|
// Add properties assigned by `RegExp#exec`.
|
|||
|
|
if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
|
|||
|
|
result.index = array.index;
|
|||
|
|
result.input = array.input;
|
|||
|
|
}
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Initializes an object clone.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Object} object The object to clone.
|
|||
|
|
* @returns {Object} Returns the initialized clone.
|
|||
|
|
*/
|
|||
|
|
function initCloneObject(object) {
|
|||
|
|
return (typeof object.constructor == 'function' && !isPrototype(object))
|
|||
|
|
? baseCreate(getPrototype(object))
|
|||
|
|
: {};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Initializes an object clone based on its `toStringTag`.
|
|||
|
|
*
|
|||
|
|
* **Note:** This function only supports cloning values with tags of
|
|||
|
|
* `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Object} object The object to clone.
|
|||
|
|
* @param {string} tag The `toStringTag` of the object to clone.
|
|||
|
|
* @param {Function} cloneFunc The function to clone values.
|
|||
|
|
* @param {boolean} [isDeep] Specify a deep clone.
|
|||
|
|
* @returns {Object} Returns the initialized clone.
|
|||
|
|
*/
|
|||
|
|
function initCloneByTag(object, tag, cloneFunc, isDeep) {
|
|||
|
|
var Ctor = object.constructor;
|
|||
|
|
switch (tag) {
|
|||
|
|
case arrayBufferTag:
|
|||
|
|
return cloneArrayBuffer(object);
|
|||
|
|
|
|||
|
|
case boolTag:
|
|||
|
|
case dateTag:
|
|||
|
|
return new Ctor(+object);
|
|||
|
|
|
|||
|
|
case dataViewTag:
|
|||
|
|
return cloneDataView(object, isDeep);
|
|||
|
|
|
|||
|
|
case float32Tag: case float64Tag:
|
|||
|
|
case int8Tag: case int16Tag: case int32Tag:
|
|||
|
|
case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
|
|||
|
|
return cloneTypedArray(object, isDeep);
|
|||
|
|
|
|||
|
|
case mapTag:
|
|||
|
|
return cloneMap(object, isDeep, cloneFunc);
|
|||
|
|
|
|||
|
|
case numberTag:
|
|||
|
|
case stringTag:
|
|||
|
|
return new Ctor(object);
|
|||
|
|
|
|||
|
|
case regexpTag:
|
|||
|
|
return cloneRegExp(object);
|
|||
|
|
|
|||
|
|
case setTag:
|
|||
|
|
return cloneSet(object, isDeep, cloneFunc);
|
|||
|
|
|
|||
|
|
case symbolTag:
|
|||
|
|
return cloneSymbol(object);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is a valid array-like index.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
|
|||
|
|
*/
|
|||
|
|
function isIndex(value, length) {
|
|||
|
|
length = length == null ? MAX_SAFE_INTEGER : length;
|
|||
|
|
return !!length &&
|
|||
|
|
(typeof value == 'number' || reIsUint.test(value)) &&
|
|||
|
|
(value > -1 && value % 1 == 0 && value < length);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is suitable for use as unique object key.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is suitable, else `false`.
|
|||
|
|
*/
|
|||
|
|
function isKeyable(value) {
|
|||
|
|
var type = typeof value;
|
|||
|
|
return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
|
|||
|
|
? (value !== '__proto__')
|
|||
|
|
: (value === null);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `func` has its source masked.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Function} func The function to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `func` is masked, else `false`.
|
|||
|
|
*/
|
|||
|
|
function isMasked(func) {
|
|||
|
|
return !!maskSrcKey && (maskSrcKey in func);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is likely a prototype object.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
|
|||
|
|
*/
|
|||
|
|
function isPrototype(value) {
|
|||
|
|
var Ctor = value && value.constructor,
|
|||
|
|
proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
|
|||
|
|
|
|||
|
|
return value === proto;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Converts `func` to its source code.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Function} func The function to process.
|
|||
|
|
* @returns {string} Returns the source code.
|
|||
|
|
*/
|
|||
|
|
function toSource(func) {
|
|||
|
|
if (func != null) {
|
|||
|
|
try {
|
|||
|
|
return funcToString.call(func);
|
|||
|
|
} catch (e) {}
|
|||
|
|
try {
|
|||
|
|
return (func + '');
|
|||
|
|
} catch (e) {}
|
|||
|
|
}
|
|||
|
|
return '';
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* This method is like `_.clone` except that it recursively clones `value`.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 1.0.0
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to recursively clone.
|
|||
|
|
* @returns {*} Returns the deep cloned value.
|
|||
|
|
* @see _.clone
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* var objects = [{ 'a': 1 }, { 'b': 2 }];
|
|||
|
|
*
|
|||
|
|
* var deep = _.cloneDeep(objects);
|
|||
|
|
* console.log(deep[0] === objects[0]);
|
|||
|
|
* // => false
|
|||
|
|
*/
|
|||
|
|
function cloneDeep(value) {
|
|||
|
|
return baseClone(value, true, true);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Performs a
|
|||
|
|
* [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
|
|||
|
|
* comparison between two values to determine if they are equivalent.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 4.0.0
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to compare.
|
|||
|
|
* @param {*} other The other value to compare.
|
|||
|
|
* @returns {boolean} Returns `true` if the values are equivalent, else `false`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* var object = { 'a': 1 };
|
|||
|
|
* var other = { 'a': 1 };
|
|||
|
|
*
|
|||
|
|
* _.eq(object, object);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.eq(object, other);
|
|||
|
|
* // => false
|
|||
|
|
*
|
|||
|
|
* _.eq('a', 'a');
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.eq('a', Object('a'));
|
|||
|
|
* // => false
|
|||
|
|
*
|
|||
|
|
* _.eq(NaN, NaN);
|
|||
|
|
* // => true
|
|||
|
|
*/
|
|||
|
|
function eq(value, other) {
|
|||
|
|
return value === other || (value !== value && other !== other);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is likely an `arguments` object.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 0.1.0
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is an `arguments` object,
|
|||
|
|
* else `false`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.isArguments(function() { return arguments; }());
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isArguments([1, 2, 3]);
|
|||
|
|
* // => false
|
|||
|
|
*/
|
|||
|
|
function isArguments(value) {
|
|||
|
|
// Safari 8.1 makes `arguments.callee` enumerable in strict mode.
|
|||
|
|
return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&
|
|||
|
|
(!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is classified as an `Array` object.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 0.1.0
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is an array, else `false`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.isArray([1, 2, 3]);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isArray(document.body.children);
|
|||
|
|
* // => false
|
|||
|
|
*
|
|||
|
|
* _.isArray('abc');
|
|||
|
|
* // => false
|
|||
|
|
*
|
|||
|
|
* _.isArray(_.noop);
|
|||
|
|
* // => false
|
|||
|
|
*/
|
|||
|
|
var isArray = Array.isArray;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is array-like. A value is considered array-like if it's
|
|||
|
|
* not a function and has a `value.length` that's an integer greater than or
|
|||
|
|
* equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 4.0.0
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is array-like, else `false`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.isArrayLike([1, 2, 3]);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isArrayLike(document.body.children);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isArrayLike('abc');
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isArrayLike(_.noop);
|
|||
|
|
* // => false
|
|||
|
|
*/
|
|||
|
|
function isArrayLike(value) {
|
|||
|
|
return value != null && isLength(value.length) && !isFunction(value);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* This method is like `_.isArrayLike` except that it also checks if `value`
|
|||
|
|
* is an object.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 4.0.0
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is an array-like object,
|
|||
|
|
* else `false`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.isArrayLikeObject([1, 2, 3]);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isArrayLikeObject(document.body.children);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isArrayLikeObject('abc');
|
|||
|
|
* // => false
|
|||
|
|
*
|
|||
|
|
* _.isArrayLikeObject(_.noop);
|
|||
|
|
* // => false
|
|||
|
|
*/
|
|||
|
|
function isArrayLikeObject(value) {
|
|||
|
|
return isObjectLike(value) && isArrayLike(value);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is a buffer.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 4.3.0
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.isBuffer(new Buffer(2));
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isBuffer(new Uint8Array(2));
|
|||
|
|
* // => false
|
|||
|
|
*/
|
|||
|
|
var isBuffer = nativeIsBuffer || stubFalse;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is classified as a `Function` object.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 0.1.0
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is a function, else `false`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.isFunction(_);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isFunction(/abc/);
|
|||
|
|
* // => false
|
|||
|
|
*/
|
|||
|
|
function isFunction(value) {
|
|||
|
|
// The use of `Object#toString` avoids issues with the `typeof` operator
|
|||
|
|
// in Safari 8-9 which returns 'object' for typed array and other constructors.
|
|||
|
|
var tag = isObject(value) ? objectToString.call(value) : '';
|
|||
|
|
return tag == funcTag || tag == genTag;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is a valid array-like length.
|
|||
|
|
*
|
|||
|
|
* **Note:** This method is loosely based on
|
|||
|
|
* [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 4.0.0
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.isLength(3);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isLength(Number.MIN_VALUE);
|
|||
|
|
* // => false
|
|||
|
|
*
|
|||
|
|
* _.isLength(Infinity);
|
|||
|
|
* // => false
|
|||
|
|
*
|
|||
|
|
* _.isLength('3');
|
|||
|
|
* // => false
|
|||
|
|
*/
|
|||
|
|
function isLength(value) {
|
|||
|
|
return typeof value == 'number' &&
|
|||
|
|
value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is the
|
|||
|
|
* [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
|
|||
|
|
* of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 0.1.0
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is an object, else `false`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.isObject({});
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isObject([1, 2, 3]);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isObject(_.noop);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isObject(null);
|
|||
|
|
* // => false
|
|||
|
|
*/
|
|||
|
|
function isObject(value) {
|
|||
|
|
var type = typeof value;
|
|||
|
|
return !!value && (type == 'object' || type == 'function');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is object-like. A value is object-like if it's not `null`
|
|||
|
|
* and has a `typeof` result of "object".
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 4.0.0
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.isObjectLike({});
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isObjectLike([1, 2, 3]);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isObjectLike(_.noop);
|
|||
|
|
* // => false
|
|||
|
|
*
|
|||
|
|
* _.isObjectLike(null);
|
|||
|
|
* // => false
|
|||
|
|
*/
|
|||
|
|
function isObjectLike(value) {
|
|||
|
|
return !!value && typeof value == 'object';
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Creates an array of the own enumerable property names of `object`.
|
|||
|
|
*
|
|||
|
|
* **Note:** Non-object values are coerced to objects. See the
|
|||
|
|
* [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
|
|||
|
|
* for more details.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @since 0.1.0
|
|||
|
|
* @memberOf _
|
|||
|
|
* @category Object
|
|||
|
|
* @param {Object} object The object to query.
|
|||
|
|
* @returns {Array} Returns the array of property names.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* function Foo() {
|
|||
|
|
* this.a = 1;
|
|||
|
|
* this.b = 2;
|
|||
|
|
* }
|
|||
|
|
*
|
|||
|
|
* Foo.prototype.c = 3;
|
|||
|
|
*
|
|||
|
|
* _.keys(new Foo);
|
|||
|
|
* // => ['a', 'b'] (iteration order is not guaranteed)
|
|||
|
|
*
|
|||
|
|
* _.keys('hi');
|
|||
|
|
* // => ['0', '1']
|
|||
|
|
*/
|
|||
|
|
function keys(object) {
|
|||
|
|
return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* This method returns a new empty array.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 4.13.0
|
|||
|
|
* @category Util
|
|||
|
|
* @returns {Array} Returns the new empty array.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* var arrays = _.times(2, _.stubArray);
|
|||
|
|
*
|
|||
|
|
* console.log(arrays);
|
|||
|
|
* // => [[], []]
|
|||
|
|
*
|
|||
|
|
* console.log(arrays[0] === arrays[1]);
|
|||
|
|
* // => false
|
|||
|
|
*/
|
|||
|
|
function stubArray() {
|
|||
|
|
return [];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* This method returns `false`.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 4.13.0
|
|||
|
|
* @category Util
|
|||
|
|
* @returns {boolean} Returns `false`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.times(2, _.stubFalse);
|
|||
|
|
* // => [false, false]
|
|||
|
|
*/
|
|||
|
|
function stubFalse() {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
module.exports = cloneDeep;
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
var hasProperty = function has(object, key) {
|
|||
|
|
return Object.prototype.hasOwnProperty.call(object, key);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var _apply;
|
|||
|
|
|
|||
|
|
function _classPrivateFieldLooseBase$8(receiver, privateKey) { if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) { throw new TypeError("attempted to use private field on non-instance"); } return receiver; }
|
|||
|
|
|
|||
|
|
var id$8 = 0;
|
|||
|
|
|
|||
|
|
function _classPrivateFieldLooseKey$8(name) { return "__private_" + id$8++ + "_" + name; }
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
function insertReplacement(source, rx, replacement) {
|
|||
|
|
const newParts = [];
|
|||
|
|
source.forEach(chunk => {
|
|||
|
|
// When the source contains multiple placeholders for interpolation,
|
|||
|
|
// we should ignore chunks that are not strings, because those
|
|||
|
|
// can be JSX objects and will be otherwise incorrectly turned into strings.
|
|||
|
|
// Without this condition we’d get this: [object Object] hello [object Object] my <button>
|
|||
|
|
if (typeof chunk !== 'string') {
|
|||
|
|
return newParts.push(chunk);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return rx[Symbol.split](chunk).forEach((raw, i, list) => {
|
|||
|
|
if (raw !== '') {
|
|||
|
|
newParts.push(raw);
|
|||
|
|
} // Interlace with the `replacement` value
|
|||
|
|
|
|||
|
|
|
|||
|
|
if (i < list.length - 1) {
|
|||
|
|
newParts.push(replacement);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
return newParts;
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Takes a string with placeholder variables like `%{smart_count} file selected`
|
|||
|
|
* and replaces it with values from options `{smart_count: 5}`
|
|||
|
|
*
|
|||
|
|
* @license https://github.com/airbnb/polyglot.js/blob/master/LICENSE
|
|||
|
|
* taken from https://github.com/airbnb/polyglot.js/blob/master/lib/polyglot.js#L299
|
|||
|
|
*
|
|||
|
|
* @param {string} phrase that needs interpolation, with placeholders
|
|||
|
|
* @param {object} options with values that will be used to replace placeholders
|
|||
|
|
* @returns {any[]} interpolated
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
function interpolate(phrase, options) {
|
|||
|
|
const dollarRegex = /\$/g;
|
|||
|
|
const dollarBillsYall = '$$$$';
|
|||
|
|
let interpolated = [phrase];
|
|||
|
|
if (options == null) return interpolated;
|
|||
|
|
|
|||
|
|
for (const arg of Object.keys(options)) {
|
|||
|
|
if (arg !== '_') {
|
|||
|
|
// Ensure replacement value is escaped to prevent special $-prefixed
|
|||
|
|
// regex replace tokens. the "$$$$" is needed because each "$" needs to
|
|||
|
|
// be escaped with "$" itself, and we need two in the resulting output.
|
|||
|
|
let replacement = options[arg];
|
|||
|
|
|
|||
|
|
if (typeof replacement === 'string') {
|
|||
|
|
replacement = dollarRegex[Symbol.replace](replacement, dollarBillsYall);
|
|||
|
|
} // We create a new `RegExp` each time instead of using a more-efficient
|
|||
|
|
// string replace so that the same argument can be replaced multiple times
|
|||
|
|
// in the same phrase.
|
|||
|
|
|
|||
|
|
|
|||
|
|
interpolated = insertReplacement(interpolated, new RegExp(`%\\{${arg}\\}`, 'g'), replacement);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return interpolated;
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Translates strings with interpolation & pluralization support.
|
|||
|
|
* Extensible with custom dictionaries and pluralization functions.
|
|||
|
|
*
|
|||
|
|
* Borrows heavily from and inspired by Polyglot https://github.com/airbnb/polyglot.js,
|
|||
|
|
* basically a stripped-down version of it. Differences: pluralization functions are not hardcoded
|
|||
|
|
* and can be easily added among with dictionaries, nested objects are used for pluralization
|
|||
|
|
* as opposed to `||||` delimeter
|
|||
|
|
*
|
|||
|
|
* Usage example: `translator.translate('files_chosen', {smart_count: 3})`
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
var Translator_1 = (_apply = /*#__PURE__*/_classPrivateFieldLooseKey$8("apply"), class Translator {
|
|||
|
|
/**
|
|||
|
|
* @param {object|Array<object>} locales - locale or list of locales.
|
|||
|
|
*/
|
|||
|
|
constructor(locales) {
|
|||
|
|
Object.defineProperty(this, _apply, {
|
|||
|
|
value: _apply2
|
|||
|
|
});
|
|||
|
|
this.locale = {
|
|||
|
|
strings: {},
|
|||
|
|
|
|||
|
|
pluralize(n) {
|
|||
|
|
if (n === 1) {
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
if (Array.isArray(locales)) {
|
|||
|
|
locales.forEach(_classPrivateFieldLooseBase$8(this, _apply)[_apply], this);
|
|||
|
|
} else {
|
|||
|
|
_classPrivateFieldLooseBase$8(this, _apply)[_apply](locales);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Public translate method
|
|||
|
|
*
|
|||
|
|
* @param {string} key
|
|||
|
|
* @param {object} options with values that will be used later to replace placeholders in string
|
|||
|
|
* @returns {string} translated (and interpolated)
|
|||
|
|
*/
|
|||
|
|
translate(key, options) {
|
|||
|
|
return this.translateArray(key, options).join('');
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Get a translation and return the translated and interpolated parts as an array.
|
|||
|
|
*
|
|||
|
|
* @param {string} key
|
|||
|
|
* @param {object} options with values that will be used to replace placeholders
|
|||
|
|
* @returns {Array} The translated and interpolated parts, in order.
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
translateArray(key, options) {
|
|||
|
|
if (!hasProperty(this.locale.strings, key)) {
|
|||
|
|
throw new Error(`missing string: ${key}`);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const string = this.locale.strings[key];
|
|||
|
|
const hasPluralForms = typeof string === 'object';
|
|||
|
|
|
|||
|
|
if (hasPluralForms) {
|
|||
|
|
if (options && typeof options.smart_count !== 'undefined') {
|
|||
|
|
const plural = this.locale.pluralize(options.smart_count);
|
|||
|
|
return interpolate(string[plural], options);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
throw new Error('Attempted to use a string with plural forms, but no value was given for %{smart_count}');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return interpolate(string, options);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
function _apply2(locale) {
|
|||
|
|
if (!(locale != null && locale.strings)) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const prevLocale = this.locale;
|
|||
|
|
this.locale = { ...prevLocale,
|
|||
|
|
strings: { ...prevLocale.strings,
|
|||
|
|
...locale.strings
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
this.locale.pluralize = locale.pluralize || prevLocale.pluralize;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Create an event emitter with namespaces
|
|||
|
|
* @name createNamespaceEmitter
|
|||
|
|
* @example
|
|||
|
|
* var emitter = require('./index')()
|
|||
|
|
*
|
|||
|
|
* emitter.on('*', function () {
|
|||
|
|
* console.log('all events emitted', this.event)
|
|||
|
|
* })
|
|||
|
|
*
|
|||
|
|
* emitter.on('example', function () {
|
|||
|
|
* console.log('example event emitted')
|
|||
|
|
* })
|
|||
|
|
*/
|
|||
|
|
var namespaceEmitter = function createNamespaceEmitter () {
|
|||
|
|
var emitter = {};
|
|||
|
|
var _fns = emitter._fns = {};
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Emit an event. Optionally namespace the event. Handlers are fired in the order in which they were added with exact matches taking precedence. Separate the namespace and event with a `:`
|
|||
|
|
* @name emit
|
|||
|
|
* @param {String} event – the name of the event, with optional namespace
|
|||
|
|
* @param {...*} data – up to 6 arguments that are passed to the event listener
|
|||
|
|
* @example
|
|||
|
|
* emitter.emit('example')
|
|||
|
|
* emitter.emit('demo:test')
|
|||
|
|
* emitter.emit('data', { example: true}, 'a string', 1)
|
|||
|
|
*/
|
|||
|
|
emitter.emit = function emit (event, arg1, arg2, arg3, arg4, arg5, arg6) {
|
|||
|
|
var toEmit = getListeners(event);
|
|||
|
|
|
|||
|
|
if (toEmit.length) {
|
|||
|
|
emitAll(event, toEmit, [arg1, arg2, arg3, arg4, arg5, arg6]);
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Create en event listener.
|
|||
|
|
* @name on
|
|||
|
|
* @param {String} event
|
|||
|
|
* @param {Function} fn
|
|||
|
|
* @example
|
|||
|
|
* emitter.on('example', function () {})
|
|||
|
|
* emitter.on('demo', function () {})
|
|||
|
|
*/
|
|||
|
|
emitter.on = function on (event, fn) {
|
|||
|
|
if (!_fns[event]) {
|
|||
|
|
_fns[event] = [];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
_fns[event].push(fn);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Create en event listener that fires once.
|
|||
|
|
* @name once
|
|||
|
|
* @param {String} event
|
|||
|
|
* @param {Function} fn
|
|||
|
|
* @example
|
|||
|
|
* emitter.once('example', function () {})
|
|||
|
|
* emitter.once('demo', function () {})
|
|||
|
|
*/
|
|||
|
|
emitter.once = function once (event, fn) {
|
|||
|
|
function one () {
|
|||
|
|
fn.apply(this, arguments);
|
|||
|
|
emitter.off(event, one);
|
|||
|
|
}
|
|||
|
|
this.on(event, one);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Stop listening to an event. Stop all listeners on an event by only passing the event name. Stop a single listener by passing that event handler as a callback.
|
|||
|
|
* You must be explicit about what will be unsubscribed: `emitter.off('demo')` will unsubscribe an `emitter.on('demo')` listener,
|
|||
|
|
* `emitter.off('demo:example')` will unsubscribe an `emitter.on('demo:example')` listener
|
|||
|
|
* @name off
|
|||
|
|
* @param {String} event
|
|||
|
|
* @param {Function} [fn] – the specific handler
|
|||
|
|
* @example
|
|||
|
|
* emitter.off('example')
|
|||
|
|
* emitter.off('demo', function () {})
|
|||
|
|
*/
|
|||
|
|
emitter.off = function off (event, fn) {
|
|||
|
|
var keep = [];
|
|||
|
|
|
|||
|
|
if (event && fn) {
|
|||
|
|
var fns = this._fns[event];
|
|||
|
|
var i = 0;
|
|||
|
|
var l = fns ? fns.length : 0;
|
|||
|
|
|
|||
|
|
for (i; i < l; i++) {
|
|||
|
|
if (fns[i] !== fn) {
|
|||
|
|
keep.push(fns[i]);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
keep.length ? this._fns[event] = keep : delete this._fns[event];
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
function getListeners (e) {
|
|||
|
|
var out = _fns[e] ? _fns[e] : [];
|
|||
|
|
var idx = e.indexOf(':');
|
|||
|
|
var args = (idx === -1) ? [e] : [e.substring(0, idx), e.substring(idx + 1)];
|
|||
|
|
|
|||
|
|
var keys = Object.keys(_fns);
|
|||
|
|
var i = 0;
|
|||
|
|
var l = keys.length;
|
|||
|
|
|
|||
|
|
for (i; i < l; i++) {
|
|||
|
|
var key = keys[i];
|
|||
|
|
if (key === '*') {
|
|||
|
|
out = out.concat(_fns[key]);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (args.length === 2 && args[0] === key) {
|
|||
|
|
out = out.concat(_fns[key]);
|
|||
|
|
break
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return out
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function emitAll (e, fns, args) {
|
|||
|
|
var i = 0;
|
|||
|
|
var l = fns.length;
|
|||
|
|
|
|||
|
|
for (i; i < l; i++) {
|
|||
|
|
if (!fns[i]) break
|
|||
|
|
fns[i].event = e;
|
|||
|
|
fns[i].apply(fns[i], args);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return emitter
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// Adapted from https://github.com/Flet/prettier-bytes/
|
|||
|
|
// Changing 1000 bytes to 1024, so we can keep uppercase KB vs kB
|
|||
|
|
// ISC License (c) Dan Flettre https://github.com/Flet/prettier-bytes/blob/master/LICENSE
|
|||
|
|
var prettierBytes = function prettierBytes (num) {
|
|||
|
|
if (typeof num !== 'number' || isNaN(num)) {
|
|||
|
|
throw new TypeError('Expected a number, got ' + typeof num)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var neg = num < 0;
|
|||
|
|
var units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
|||
|
|
|
|||
|
|
if (neg) {
|
|||
|
|
num = -num;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (num < 1) {
|
|||
|
|
return (neg ? '-' : '') + num + ' B'
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var exponent = Math.min(Math.floor(Math.log(num) / Math.log(1024)), units.length - 1);
|
|||
|
|
num = Number(num / Math.pow(1024, exponent));
|
|||
|
|
var unit = units[exponent];
|
|||
|
|
|
|||
|
|
if (num >= 10 || num % 1 === 0) {
|
|||
|
|
// Do not show decimals when the number is two-digit, or if the number has no
|
|||
|
|
// decimal component.
|
|||
|
|
return (neg ? '-' : '') + num.toFixed(0) + ' ' + unit
|
|||
|
|
} else {
|
|||
|
|
return (neg ? '-' : '') + num.toFixed(1) + ' ' + unit
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/* jshint node: true */
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
# wildcard
|
|||
|
|
|
|||
|
|
Very simple wildcard matching, which is designed to provide the same
|
|||
|
|
functionality that is found in the
|
|||
|
|
[eve](https://github.com/adobe-webplatform/eve) eventing library.
|
|||
|
|
|
|||
|
|
## Usage
|
|||
|
|
|
|||
|
|
It works with strings:
|
|||
|
|
|
|||
|
|
<<< examples/strings.js
|
|||
|
|
|
|||
|
|
Arrays:
|
|||
|
|
|
|||
|
|
<<< examples/arrays.js
|
|||
|
|
|
|||
|
|
Objects (matching against keys):
|
|||
|
|
|
|||
|
|
<<< examples/objects.js
|
|||
|
|
|
|||
|
|
While the library works in Node, if you are are looking for file-based
|
|||
|
|
wildcard matching then you should have a look at:
|
|||
|
|
|
|||
|
|
<https://github.com/isaacs/node-glob>
|
|||
|
|
**/
|
|||
|
|
|
|||
|
|
function WildcardMatcher(text, separator) {
|
|||
|
|
this.text = text = text || '';
|
|||
|
|
this.hasWild = ~text.indexOf('*');
|
|||
|
|
this.separator = separator;
|
|||
|
|
this.parts = text.split(separator);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
WildcardMatcher.prototype.match = function(input) {
|
|||
|
|
var matches = true;
|
|||
|
|
var parts = this.parts;
|
|||
|
|
var ii;
|
|||
|
|
var partsCount = parts.length;
|
|||
|
|
var testParts;
|
|||
|
|
|
|||
|
|
if (typeof input == 'string' || input instanceof String) {
|
|||
|
|
if (!this.hasWild && this.text != input) {
|
|||
|
|
matches = false;
|
|||
|
|
} else {
|
|||
|
|
testParts = (input || '').split(this.separator);
|
|||
|
|
for (ii = 0; matches && ii < partsCount; ii++) {
|
|||
|
|
if (parts[ii] === '*') {
|
|||
|
|
continue;
|
|||
|
|
} else if (ii < testParts.length) {
|
|||
|
|
matches = parts[ii] === testParts[ii];
|
|||
|
|
} else {
|
|||
|
|
matches = false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// If matches, then return the component parts
|
|||
|
|
matches = matches && testParts;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else if (typeof input.splice == 'function') {
|
|||
|
|
matches = [];
|
|||
|
|
|
|||
|
|
for (ii = input.length; ii--; ) {
|
|||
|
|
if (this.match(input[ii])) {
|
|||
|
|
matches[matches.length] = input[ii];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else if (typeof input == 'object') {
|
|||
|
|
matches = {};
|
|||
|
|
|
|||
|
|
for (var key in input) {
|
|||
|
|
if (this.match(key)) {
|
|||
|
|
matches[key] = input[key];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return matches;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var wildcard = function(text, test, separator) {
|
|||
|
|
var matcher = new WildcardMatcher(text, separator || /[\/\.]/);
|
|||
|
|
if (typeof test != 'undefined') {
|
|||
|
|
return matcher.match(test);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return matcher;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var reMimePartSplit = /[\/\+\.]/;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
# mime-match
|
|||
|
|
|
|||
|
|
A simple function to checker whether a target mime type matches a mime-type
|
|||
|
|
pattern (e.g. image/jpeg matches image/jpeg OR image/*).
|
|||
|
|
|
|||
|
|
## Example Usage
|
|||
|
|
|
|||
|
|
<<< example.js
|
|||
|
|
|
|||
|
|
**/
|
|||
|
|
var mimeMatch = function(target, pattern) {
|
|||
|
|
function test(pattern) {
|
|||
|
|
var result = wildcard(pattern, target, reMimePartSplit);
|
|||
|
|
|
|||
|
|
// ensure that we have a valid mime type (should have two parts)
|
|||
|
|
return result && result.length >= 2;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return pattern ? test(pattern.split(';')[0]) : test;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
function _classPrivateFieldLooseBase$7(receiver, privateKey) { if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) { throw new TypeError("attempted to use private field on non-instance"); } return receiver; }
|
|||
|
|
|
|||
|
|
var id$7 = 0;
|
|||
|
|
|
|||
|
|
function _classPrivateFieldLooseKey$7(name) { return "__private_" + id$7++ + "_" + name; }
|
|||
|
|
|
|||
|
|
var _publish = /*#__PURE__*/_classPrivateFieldLooseKey$7("publish");
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Default store that keeps state in a simple object.
|
|||
|
|
*/
|
|||
|
|
class DefaultStore {
|
|||
|
|
constructor() {
|
|||
|
|
Object.defineProperty(this, _publish, {
|
|||
|
|
value: _publish2
|
|||
|
|
});
|
|||
|
|
this.state = {};
|
|||
|
|
this.callbacks = [];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
getState() {
|
|||
|
|
return this.state;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
setState(patch) {
|
|||
|
|
const prevState = { ...this.state
|
|||
|
|
};
|
|||
|
|
const nextState = { ...this.state,
|
|||
|
|
...patch
|
|||
|
|
};
|
|||
|
|
this.state = nextState;
|
|||
|
|
|
|||
|
|
_classPrivateFieldLooseBase$7(this, _publish)[_publish](prevState, nextState, patch);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
subscribe(listener) {
|
|||
|
|
this.callbacks.push(listener);
|
|||
|
|
return () => {
|
|||
|
|
// Remove the listener.
|
|||
|
|
this.callbacks.splice(this.callbacks.indexOf(listener), 1);
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function _publish2() {
|
|||
|
|
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|||
|
|
args[_key] = arguments[_key];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
this.callbacks.forEach(listener => {
|
|||
|
|
listener(...args);
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
DefaultStore.VERSION = "2.0.3";
|
|||
|
|
|
|||
|
|
var lib$3 = function defaultStore() {
|
|||
|
|
return new DefaultStore();
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Takes a full filename string and returns an object {name, extension}
|
|||
|
|
*
|
|||
|
|
* @param {string} fullFileName
|
|||
|
|
* @returns {object} {name, extension}
|
|||
|
|
*/
|
|||
|
|
var getFileNameAndExtension = function getFileNameAndExtension(fullFileName) {
|
|||
|
|
const lastDot = fullFileName.lastIndexOf('.'); // these count as no extension: "no-dot", "trailing-dot."
|
|||
|
|
|
|||
|
|
if (lastDot === -1 || lastDot === fullFileName.length - 1) {
|
|||
|
|
return {
|
|||
|
|
name: fullFileName,
|
|||
|
|
extension: undefined
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return {
|
|||
|
|
name: fullFileName.slice(0, lastDot),
|
|||
|
|
extension: fullFileName.slice(lastDot + 1)
|
|||
|
|
};
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// ___Why not add the mime-types package?
|
|||
|
|
// It's 19.7kB gzipped, and we only need mime types for well-known extensions (for file previews).
|
|||
|
|
// ___Where to take new extensions from?
|
|||
|
|
// https://github.com/jshttp/mime-db/blob/master/db.json
|
|||
|
|
var mimeTypes = {
|
|||
|
|
md: 'text/markdown',
|
|||
|
|
markdown: 'text/markdown',
|
|||
|
|
mp4: 'video/mp4',
|
|||
|
|
mp3: 'audio/mp3',
|
|||
|
|
svg: 'image/svg+xml',
|
|||
|
|
jpg: 'image/jpeg',
|
|||
|
|
png: 'image/png',
|
|||
|
|
gif: 'image/gif',
|
|||
|
|
heic: 'image/heic',
|
|||
|
|
heif: 'image/heif',
|
|||
|
|
yaml: 'text/yaml',
|
|||
|
|
yml: 'text/yaml',
|
|||
|
|
csv: 'text/csv',
|
|||
|
|
tsv: 'text/tab-separated-values',
|
|||
|
|
tab: 'text/tab-separated-values',
|
|||
|
|
avi: 'video/x-msvideo',
|
|||
|
|
mks: 'video/x-matroska',
|
|||
|
|
mkv: 'video/x-matroska',
|
|||
|
|
mov: 'video/quicktime',
|
|||
|
|
doc: 'application/msword',
|
|||
|
|
docm: 'application/vnd.ms-word.document.macroenabled.12',
|
|||
|
|
docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|||
|
|
dot: 'application/msword',
|
|||
|
|
dotm: 'application/vnd.ms-word.template.macroenabled.12',
|
|||
|
|
dotx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
|
|||
|
|
xla: 'application/vnd.ms-excel',
|
|||
|
|
xlam: 'application/vnd.ms-excel.addin.macroenabled.12',
|
|||
|
|
xlc: 'application/vnd.ms-excel',
|
|||
|
|
xlf: 'application/x-xliff+xml',
|
|||
|
|
xlm: 'application/vnd.ms-excel',
|
|||
|
|
xls: 'application/vnd.ms-excel',
|
|||
|
|
xlsb: 'application/vnd.ms-excel.sheet.binary.macroenabled.12',
|
|||
|
|
xlsm: 'application/vnd.ms-excel.sheet.macroenabled.12',
|
|||
|
|
xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|||
|
|
xlt: 'application/vnd.ms-excel',
|
|||
|
|
xltm: 'application/vnd.ms-excel.template.macroenabled.12',
|
|||
|
|
xltx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
|
|||
|
|
xlw: 'application/vnd.ms-excel',
|
|||
|
|
txt: 'text/plain',
|
|||
|
|
text: 'text/plain',
|
|||
|
|
conf: 'text/plain',
|
|||
|
|
log: 'text/plain',
|
|||
|
|
pdf: 'application/pdf',
|
|||
|
|
zip: 'application/zip',
|
|||
|
|
'7z': 'application/x-7z-compressed',
|
|||
|
|
rar: 'application/x-rar-compressed',
|
|||
|
|
tar: 'application/x-tar',
|
|||
|
|
gz: 'application/gzip',
|
|||
|
|
dmg: 'application/x-apple-diskimage'
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var getFileType = function getFileType(file) {
|
|||
|
|
var _getFileNameAndExtens;
|
|||
|
|
|
|||
|
|
if (file.type) return file.type;
|
|||
|
|
const fileExtension = file.name ? (_getFileNameAndExtens = getFileNameAndExtension(file.name).extension) == null ? void 0 : _getFileNameAndExtens.toLowerCase() : null;
|
|||
|
|
|
|||
|
|
if (fileExtension && fileExtension in mimeTypes) {
|
|||
|
|
// else, see if we can map extension to a mime type
|
|||
|
|
return mimeTypes[fileExtension];
|
|||
|
|
} // if all fails, fall back to a generic byte stream type
|
|||
|
|
|
|||
|
|
|
|||
|
|
return 'application/octet-stream';
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
function encodeCharacter(character) {
|
|||
|
|
return character.charCodeAt(0).toString(32);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function encodeFilename(name) {
|
|||
|
|
let suffix = '';
|
|||
|
|
return name.replace(/[^A-Z0-9]/ig, character => {
|
|||
|
|
suffix += `-${encodeCharacter(character)}`;
|
|||
|
|
return '/';
|
|||
|
|
}) + suffix;
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Takes a file object and turns it into fileID, by converting file.name to lowercase,
|
|||
|
|
* removing extra characters and adding type, size and lastModified
|
|||
|
|
*
|
|||
|
|
* @param {object} file
|
|||
|
|
* @returns {string} the fileID
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
var generateFileID = function generateFileID(file) {
|
|||
|
|
// It's tempting to do `[items].filter(Boolean).join('-')` here, but that
|
|||
|
|
// is slower! simple string concatenation is fast
|
|||
|
|
let id = 'uppy';
|
|||
|
|
|
|||
|
|
if (typeof file.name === 'string') {
|
|||
|
|
id += `-${encodeFilename(file.name.toLowerCase())}`;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (file.type !== undefined) {
|
|||
|
|
id += `-${file.type}`;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (file.meta && typeof file.meta.relativePath === 'string') {
|
|||
|
|
id += `-${encodeFilename(file.meta.relativePath.toLowerCase())}`;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (file.data.size !== undefined) {
|
|||
|
|
id += `-${file.data.size}`;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (file.data.lastModified !== undefined) {
|
|||
|
|
id += `-${file.data.lastModified}`;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return id;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// Edge 15.x does not fire 'progress' events on uploads.
|
|||
|
|
// See https://github.com/transloadit/uppy/issues/945
|
|||
|
|
// And https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/12224510/
|
|||
|
|
var supportsUploadProgress = function supportsUploadProgress(userAgent) {
|
|||
|
|
// Allow passing in userAgent for tests
|
|||
|
|
if (userAgent == null) {
|
|||
|
|
userAgent = typeof navigator !== 'undefined' ? navigator.userAgent : null;
|
|||
|
|
} // Assume it works because basically everything supports progress events.
|
|||
|
|
|
|||
|
|
|
|||
|
|
if (!userAgent) return true;
|
|||
|
|
const m = /Edge\/(\d+\.\d+)/.exec(userAgent);
|
|||
|
|
if (!m) return true;
|
|||
|
|
const edgeVersion = m[1];
|
|||
|
|
let [major, minor] = edgeVersion.split('.');
|
|||
|
|
major = parseInt(major, 10);
|
|||
|
|
minor = parseInt(minor, 10); // Worked before:
|
|||
|
|
// Edge 40.15063.0.0
|
|||
|
|
// Microsoft EdgeHTML 15.15063
|
|||
|
|
|
|||
|
|
if (major < 15 || major === 15 && minor < 15063) {
|
|||
|
|
return true;
|
|||
|
|
} // Fixed in:
|
|||
|
|
// Microsoft EdgeHTML 18.18218
|
|||
|
|
|
|||
|
|
|
|||
|
|
if (major > 18 || major === 18 && minor >= 18218) {
|
|||
|
|
return true;
|
|||
|
|
} // other versions don't work.
|
|||
|
|
|
|||
|
|
|
|||
|
|
return false;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var getFileName = function getFileName(fileType, fileDescriptor) {
|
|||
|
|
if (fileDescriptor.name) {
|
|||
|
|
return fileDescriptor.name;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (fileType.split('/')[0] === 'image') {
|
|||
|
|
return `${fileType.split('/')[0]}.${fileType.split('/')[1]}`;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return 'noname';
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Adds zero to strings shorter than two characters.
|
|||
|
|
*
|
|||
|
|
* @param {number} number
|
|||
|
|
* @returns {string}
|
|||
|
|
*/
|
|||
|
|
function pad(number) {
|
|||
|
|
return number < 10 ? `0${number}` : number.toString();
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Returns a timestamp in the format of `hours:minutes:seconds`
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
var getTimeStamp = function getTimeStamp() {
|
|||
|
|
const date = new Date();
|
|||
|
|
const hours = pad(date.getHours());
|
|||
|
|
const minutes = pad(date.getMinutes());
|
|||
|
|
const seconds = pad(date.getSeconds());
|
|||
|
|
return `${hours}:${minutes}:${seconds}`;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/* eslint-disable no-console */
|
|||
|
|
// Swallow all logs, except errors.
|
|||
|
|
// default if logger is not set or debug: false
|
|||
|
|
|
|||
|
|
|
|||
|
|
const justErrorsLogger$1 = {
|
|||
|
|
debug: () => {},
|
|||
|
|
warn: () => {},
|
|||
|
|
error: function () {
|
|||
|
|
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|||
|
|
args[_key] = arguments[_key];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return console.error(`[Uppy] [${getTimeStamp()}]`, ...args);
|
|||
|
|
}
|
|||
|
|
}; // Print logs to console with namespace + timestamp,
|
|||
|
|
// set by logger: Uppy.debugLogger or debug: true
|
|||
|
|
|
|||
|
|
const debugLogger$2 = {
|
|||
|
|
debug: function () {
|
|||
|
|
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
|||
|
|
args[_key2] = arguments[_key2];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return console.debug(`[Uppy] [${getTimeStamp()}]`, ...args);
|
|||
|
|
},
|
|||
|
|
warn: function () {
|
|||
|
|
for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
|
|||
|
|
args[_key3] = arguments[_key3];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return console.warn(`[Uppy] [${getTimeStamp()}]`, ...args);
|
|||
|
|
},
|
|||
|
|
error: function () {
|
|||
|
|
for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
|
|||
|
|
args[_key4] = arguments[_key4];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return console.error(`[Uppy] [${getTimeStamp()}]`, ...args);
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
var loggers = {
|
|||
|
|
justErrorsLogger: justErrorsLogger$1,
|
|||
|
|
debugLogger: debugLogger$2
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var locale$1 = {
|
|||
|
|
strings: {
|
|||
|
|
addBulkFilesFailed: {
|
|||
|
|
0: 'Failed to add %{smart_count} file due to an internal error',
|
|||
|
|
1: 'Failed to add %{smart_count} files due to internal errors'
|
|||
|
|
},
|
|||
|
|
youCanOnlyUploadX: {
|
|||
|
|
0: 'You can only upload %{smart_count} file',
|
|||
|
|
1: 'You can only upload %{smart_count} files'
|
|||
|
|
},
|
|||
|
|
youHaveToAtLeastSelectX: {
|
|||
|
|
0: 'You have to select at least %{smart_count} file',
|
|||
|
|
1: 'You have to select at least %{smart_count} files'
|
|||
|
|
},
|
|||
|
|
exceedsSize: '%{file} exceeds maximum allowed size of %{size}',
|
|||
|
|
missingRequiredMetaField: 'Missing required meta fields',
|
|||
|
|
missingRequiredMetaFieldOnFile: 'Missing required meta fields in %{fileName}',
|
|||
|
|
inferiorSize: 'This file is smaller than the allowed size of %{size}',
|
|||
|
|
youCanOnlyUploadFileTypes: 'You can only upload: %{types}',
|
|||
|
|
noMoreFilesAllowed: 'Cannot add more files',
|
|||
|
|
noDuplicates: "Cannot add the duplicate file '%{fileName}', it already exists",
|
|||
|
|
companionError: 'Connection with Companion failed',
|
|||
|
|
authAborted: 'Authentication aborted',
|
|||
|
|
companionUnauthorizeHint: 'To unauthorize to your %{provider} account, please go to %{url}',
|
|||
|
|
failedToUpload: 'Failed to upload %{file}',
|
|||
|
|
noInternetConnection: 'No Internet connection',
|
|||
|
|
connectedToInternet: 'Connected to the Internet',
|
|||
|
|
// Strings for remote providers
|
|||
|
|
noFilesFound: 'You have no files or folders here',
|
|||
|
|
selectX: {
|
|||
|
|
0: 'Select %{smart_count}',
|
|||
|
|
1: 'Select %{smart_count}'
|
|||
|
|
},
|
|||
|
|
allFilesFromFolderNamed: 'All files from folder %{name}',
|
|||
|
|
openFolderNamed: 'Open folder %{name}',
|
|||
|
|
cancel: 'Cancel',
|
|||
|
|
logOut: 'Log out',
|
|||
|
|
filter: 'Filter',
|
|||
|
|
resetFilter: 'Reset filter',
|
|||
|
|
loading: 'Loading...',
|
|||
|
|
authenticateWithTitle: 'Please authenticate with %{pluginName} to select files',
|
|||
|
|
authenticateWith: 'Connect to %{pluginName}',
|
|||
|
|
signInWithGoogle: 'Sign in with Google',
|
|||
|
|
searchImages: 'Search for images',
|
|||
|
|
enterTextToSearch: 'Enter text to search for images',
|
|||
|
|
backToSearch: 'Back to Search',
|
|||
|
|
emptyFolderAdded: 'No files were added from empty folder',
|
|||
|
|
folderAlreadyAdded: 'The folder "%{folder}" was already added',
|
|||
|
|
folderAdded: {
|
|||
|
|
0: 'Added %{smart_count} file from %{folder}',
|
|||
|
|
1: 'Added %{smart_count} files from %{folder}'
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var require$$4 = index_browser;
|
|||
|
|
|
|||
|
|
/* global AggregateError */
|
|||
|
|
|
|||
|
|
let _Symbol$for$1, _Symbol$for2$1;
|
|||
|
|
|
|||
|
|
function _classPrivateFieldLooseBase$6(receiver, privateKey) { if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) { throw new TypeError("attempted to use private field on non-instance"); } return receiver; }
|
|||
|
|
|
|||
|
|
var id$6 = 0;
|
|||
|
|
|
|||
|
|
function _classPrivateFieldLooseKey$6(name) { return "__private_" + id$6++ + "_" + name; }
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
const {
|
|||
|
|
nanoid: nanoid$1
|
|||
|
|
} = require$$4;
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
const {
|
|||
|
|
justErrorsLogger,
|
|||
|
|
debugLogger: debugLogger$1
|
|||
|
|
} = loggers;
|
|||
|
|
|
|||
|
|
// Exported from here.
|
|||
|
|
|
|||
|
|
|
|||
|
|
class RestrictionError extends Error {
|
|||
|
|
constructor() {
|
|||
|
|
super(...arguments);
|
|||
|
|
this.isRestriction = true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (typeof AggregateError === 'undefined') {
|
|||
|
|
// eslint-disable-next-line no-global-assign
|
|||
|
|
globalThis.AggregateError = class AggregateError extends Error {
|
|||
|
|
constructor(errors, message) {
|
|||
|
|
super(message);
|
|||
|
|
this.errors = errors;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
class AggregateRestrictionError extends AggregateError {
|
|||
|
|
constructor() {
|
|||
|
|
super(...arguments);
|
|||
|
|
this.isRestriction = true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Uppy Core module.
|
|||
|
|
* Manages plugins, state updates, acts as an event bus,
|
|||
|
|
* adds/removes files and metadata.
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
var _plugins = /*#__PURE__*/_classPrivateFieldLooseKey$6("plugins");
|
|||
|
|
|
|||
|
|
var _storeUnsubscribe = /*#__PURE__*/_classPrivateFieldLooseKey$6("storeUnsubscribe");
|
|||
|
|
|
|||
|
|
var _emitter$2 = /*#__PURE__*/_classPrivateFieldLooseKey$6("emitter");
|
|||
|
|
|
|||
|
|
var _preProcessors = /*#__PURE__*/_classPrivateFieldLooseKey$6("preProcessors");
|
|||
|
|
|
|||
|
|
var _uploaders = /*#__PURE__*/_classPrivateFieldLooseKey$6("uploaders");
|
|||
|
|
|
|||
|
|
var _postProcessors = /*#__PURE__*/_classPrivateFieldLooseKey$6("postProcessors");
|
|||
|
|
|
|||
|
|
var _checkRestrictions = /*#__PURE__*/_classPrivateFieldLooseKey$6("checkRestrictions");
|
|||
|
|
|
|||
|
|
var _checkMinNumberOfFiles = /*#__PURE__*/_classPrivateFieldLooseKey$6("checkMinNumberOfFiles");
|
|||
|
|
|
|||
|
|
var _checkRequiredMetaFieldsOnFile = /*#__PURE__*/_classPrivateFieldLooseKey$6("checkRequiredMetaFieldsOnFile");
|
|||
|
|
|
|||
|
|
var _checkRequiredMetaFields = /*#__PURE__*/_classPrivateFieldLooseKey$6("checkRequiredMetaFields");
|
|||
|
|
|
|||
|
|
var _showOrLogErrorAndThrow = /*#__PURE__*/_classPrivateFieldLooseKey$6("showOrLogErrorAndThrow");
|
|||
|
|
|
|||
|
|
var _assertNewUploadAllowed = /*#__PURE__*/_classPrivateFieldLooseKey$6("assertNewUploadAllowed");
|
|||
|
|
|
|||
|
|
var _checkAndCreateFileStateObject = /*#__PURE__*/_classPrivateFieldLooseKey$6("checkAndCreateFileStateObject");
|
|||
|
|
|
|||
|
|
var _startIfAutoProceed = /*#__PURE__*/_classPrivateFieldLooseKey$6("startIfAutoProceed");
|
|||
|
|
|
|||
|
|
var _addListeners = /*#__PURE__*/_classPrivateFieldLooseKey$6("addListeners");
|
|||
|
|
|
|||
|
|
var _updateOnlineStatus = /*#__PURE__*/_classPrivateFieldLooseKey$6("updateOnlineStatus");
|
|||
|
|
|
|||
|
|
var _createUpload = /*#__PURE__*/_classPrivateFieldLooseKey$6("createUpload");
|
|||
|
|
|
|||
|
|
var _getUpload = /*#__PURE__*/_classPrivateFieldLooseKey$6("getUpload");
|
|||
|
|
|
|||
|
|
var _removeUpload = /*#__PURE__*/_classPrivateFieldLooseKey$6("removeUpload");
|
|||
|
|
|
|||
|
|
var _runUpload = /*#__PURE__*/_classPrivateFieldLooseKey$6("runUpload");
|
|||
|
|
|
|||
|
|
_Symbol$for$1 = Symbol.for('uppy test: getPlugins');
|
|||
|
|
_Symbol$for2$1 = Symbol.for('uppy test: createUpload');
|
|||
|
|
|
|||
|
|
class Uppy {
|
|||
|
|
// eslint-disable-next-line global-require
|
|||
|
|
|
|||
|
|
/** @type {Record<string, BasePlugin[]>} */
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Instantiate Uppy
|
|||
|
|
*
|
|||
|
|
* @param {object} opts — Uppy options
|
|||
|
|
*/
|
|||
|
|
constructor(_opts) {
|
|||
|
|
Object.defineProperty(this, _runUpload, {
|
|||
|
|
value: _runUpload2
|
|||
|
|
});
|
|||
|
|
Object.defineProperty(this, _removeUpload, {
|
|||
|
|
value: _removeUpload2
|
|||
|
|
});
|
|||
|
|
Object.defineProperty(this, _getUpload, {
|
|||
|
|
value: _getUpload2
|
|||
|
|
});
|
|||
|
|
Object.defineProperty(this, _createUpload, {
|
|||
|
|
value: _createUpload2
|
|||
|
|
});
|
|||
|
|
Object.defineProperty(this, _addListeners, {
|
|||
|
|
value: _addListeners2
|
|||
|
|
});
|
|||
|
|
Object.defineProperty(this, _startIfAutoProceed, {
|
|||
|
|
value: _startIfAutoProceed2
|
|||
|
|
});
|
|||
|
|
Object.defineProperty(this, _checkAndCreateFileStateObject, {
|
|||
|
|
value: _checkAndCreateFileStateObject2
|
|||
|
|
});
|
|||
|
|
Object.defineProperty(this, _assertNewUploadAllowed, {
|
|||
|
|
value: _assertNewUploadAllowed2
|
|||
|
|
});
|
|||
|
|
Object.defineProperty(this, _showOrLogErrorAndThrow, {
|
|||
|
|
value: _showOrLogErrorAndThrow2
|
|||
|
|
});
|
|||
|
|
Object.defineProperty(this, _checkRequiredMetaFields, {
|
|||
|
|
value: _checkRequiredMetaFields2
|
|||
|
|
});
|
|||
|
|
Object.defineProperty(this, _checkRequiredMetaFieldsOnFile, {
|
|||
|
|
value: _checkRequiredMetaFieldsOnFile2
|
|||
|
|
});
|
|||
|
|
Object.defineProperty(this, _checkMinNumberOfFiles, {
|
|||
|
|
value: _checkMinNumberOfFiles2
|
|||
|
|
});
|
|||
|
|
Object.defineProperty(this, _checkRestrictions, {
|
|||
|
|
value: _checkRestrictions2
|
|||
|
|
});
|
|||
|
|
Object.defineProperty(this, _plugins, {
|
|||
|
|
writable: true,
|
|||
|
|
value: Object.create(null)
|
|||
|
|
});
|
|||
|
|
Object.defineProperty(this, _storeUnsubscribe, {
|
|||
|
|
writable: true,
|
|||
|
|
value: void 0
|
|||
|
|
});
|
|||
|
|
Object.defineProperty(this, _emitter$2, {
|
|||
|
|
writable: true,
|
|||
|
|
value: namespaceEmitter()
|
|||
|
|
});
|
|||
|
|
Object.defineProperty(this, _preProcessors, {
|
|||
|
|
writable: true,
|
|||
|
|
value: new Set()
|
|||
|
|
});
|
|||
|
|
Object.defineProperty(this, _uploaders, {
|
|||
|
|
writable: true,
|
|||
|
|
value: new Set()
|
|||
|
|
});
|
|||
|
|
Object.defineProperty(this, _postProcessors, {
|
|||
|
|
writable: true,
|
|||
|
|
value: new Set()
|
|||
|
|
});
|
|||
|
|
Object.defineProperty(this, _updateOnlineStatus, {
|
|||
|
|
writable: true,
|
|||
|
|
value: this.updateOnlineStatus.bind(this)
|
|||
|
|
});
|
|||
|
|
this.defaultLocale = locale$1;
|
|||
|
|
const defaultOptions = {
|
|||
|
|
id: 'uppy',
|
|||
|
|
autoProceed: false,
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @deprecated The method should not be used
|
|||
|
|
*/
|
|||
|
|
allowMultipleUploads: true,
|
|||
|
|
allowMultipleUploadBatches: true,
|
|||
|
|
debug: false,
|
|||
|
|
restrictions: {
|
|||
|
|
maxFileSize: null,
|
|||
|
|
minFileSize: null,
|
|||
|
|
maxTotalFileSize: null,
|
|||
|
|
maxNumberOfFiles: null,
|
|||
|
|
minNumberOfFiles: null,
|
|||
|
|
allowedFileTypes: null,
|
|||
|
|
requiredMetaFields: []
|
|||
|
|
},
|
|||
|
|
meta: {},
|
|||
|
|
onBeforeFileAdded: currentFile => currentFile,
|
|||
|
|
onBeforeUpload: files => files,
|
|||
|
|
store: lib$3(),
|
|||
|
|
logger: justErrorsLogger,
|
|||
|
|
infoTimeout: 5000
|
|||
|
|
}; // Merge default options with the ones set by user,
|
|||
|
|
// making sure to merge restrictions too
|
|||
|
|
|
|||
|
|
this.opts = { ...defaultOptions,
|
|||
|
|
..._opts,
|
|||
|
|
restrictions: { ...defaultOptions.restrictions,
|
|||
|
|
...(_opts && _opts.restrictions)
|
|||
|
|
}
|
|||
|
|
}; // Support debug: true for backwards-compatability, unless logger is set in opts
|
|||
|
|
// opts instead of this.opts to avoid comparing objects — we set logger: justErrorsLogger in defaultOptions
|
|||
|
|
|
|||
|
|
if (_opts && _opts.logger && _opts.debug) {
|
|||
|
|
this.log('You are using a custom `logger`, but also set `debug: true`, which uses built-in logger to output logs to console. Ignoring `debug: true` and using your custom `logger`.', 'warning');
|
|||
|
|
} else if (_opts && _opts.debug) {
|
|||
|
|
this.opts.logger = debugLogger$1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
this.log(`Using Core v${this.constructor.VERSION}`);
|
|||
|
|
|
|||
|
|
if (this.opts.restrictions.allowedFileTypes && this.opts.restrictions.allowedFileTypes !== null && !Array.isArray(this.opts.restrictions.allowedFileTypes)) {
|
|||
|
|
throw new TypeError('`restrictions.allowedFileTypes` must be an array');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
this.i18nInit(); // ___Why throttle at 500ms?
|
|||
|
|
// - We must throttle at >250ms for superfocus in Dashboard to work well
|
|||
|
|
// (because animation takes 0.25s, and we want to wait for all animations to be over before refocusing).
|
|||
|
|
// [Practical Check]: if thottle is at 100ms, then if you are uploading a file,
|
|||
|
|
// and click 'ADD MORE FILES', - focus won't activate in Firefox.
|
|||
|
|
// - We must throttle at around >500ms to avoid performance lags.
|
|||
|
|
// [Practical Check] Firefox, try to upload a big file for a prolonged period of time. Laptop will start to heat up.
|
|||
|
|
|
|||
|
|
this.calculateProgress = lodash_throttle(this.calculateProgress.bind(this), 500, {
|
|||
|
|
leading: true,
|
|||
|
|
trailing: true
|
|||
|
|
});
|
|||
|
|
this.store = this.opts.store;
|
|||
|
|
this.setState({
|
|||
|
|
plugins: {},
|
|||
|
|
files: {},
|
|||
|
|
currentUploads: {},
|
|||
|
|
allowNewUpload: true,
|
|||
|
|
capabilities: {
|
|||
|
|
uploadProgress: supportsUploadProgress(),
|
|||
|
|
individualCancellation: true,
|
|||
|
|
resumableUploads: false
|
|||
|
|
},
|
|||
|
|
totalProgress: 0,
|
|||
|
|
meta: { ...this.opts.meta
|
|||
|
|
},
|
|||
|
|
info: [],
|
|||
|
|
recoveredState: null
|
|||
|
|
});
|
|||
|
|
_classPrivateFieldLooseBase$6(this, _storeUnsubscribe)[_storeUnsubscribe] = this.store.subscribe((prevState, nextState, patch) => {
|
|||
|
|
this.emit('state-update', prevState, nextState, patch);
|
|||
|
|
this.updateAll(nextState);
|
|||
|
|
}); // Exposing uppy object on window for debugging and testing
|
|||
|
|
|
|||
|
|
if (this.opts.debug && typeof window !== 'undefined') {
|
|||
|
|
window[this.opts.id] = this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
_classPrivateFieldLooseBase$6(this, _addListeners)[_addListeners]();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
emit(event) {
|
|||
|
|
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|||
|
|
args[_key - 1] = arguments[_key];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
_classPrivateFieldLooseBase$6(this, _emitter$2)[_emitter$2].emit(event, ...args);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
on(event, callback) {
|
|||
|
|
_classPrivateFieldLooseBase$6(this, _emitter$2)[_emitter$2].on(event, callback);
|
|||
|
|
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
once(event, callback) {
|
|||
|
|
_classPrivateFieldLooseBase$6(this, _emitter$2)[_emitter$2].once(event, callback);
|
|||
|
|
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
off(event, callback) {
|
|||
|
|
_classPrivateFieldLooseBase$6(this, _emitter$2)[_emitter$2].off(event, callback);
|
|||
|
|
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Iterate on all plugins and run `update` on them.
|
|||
|
|
* Called each time state changes.
|
|||
|
|
*
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
updateAll(state) {
|
|||
|
|
this.iteratePlugins(plugin => {
|
|||
|
|
plugin.update(state);
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Updates state with a patch
|
|||
|
|
*
|
|||
|
|
* @param {object} patch {foo: 'bar'}
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
setState(patch) {
|
|||
|
|
this.store.setState(patch);
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Returns current state.
|
|||
|
|
*
|
|||
|
|
* @returns {object}
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
getState() {
|
|||
|
|
return this.store.getState();
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Back compat for when uppy.state is used instead of uppy.getState().
|
|||
|
|
*
|
|||
|
|
* @deprecated
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
get state() {
|
|||
|
|
// Here, state is a non-enumerable property.
|
|||
|
|
return this.getState();
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Shorthand to set state for a specific file.
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
setFileState(fileID, state) {
|
|||
|
|
if (!this.getState().files[fileID]) {
|
|||
|
|
throw new Error(`Can’t set state for ${fileID} (the file could have been removed)`);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
this.setState({
|
|||
|
|
files: { ...this.getState().files,
|
|||
|
|
[fileID]: { ...this.getState().files[fileID],
|
|||
|
|
...state
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
i18nInit() {
|
|||
|
|
const translator = new Translator_1([this.defaultLocale, this.opts.locale]);
|
|||
|
|
this.i18n = translator.translate.bind(translator);
|
|||
|
|
this.i18nArray = translator.translateArray.bind(translator);
|
|||
|
|
this.locale = translator.locale;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
setOptions(newOpts) {
|
|||
|
|
this.opts = { ...this.opts,
|
|||
|
|
...newOpts,
|
|||
|
|
restrictions: { ...this.opts.restrictions,
|
|||
|
|
...(newOpts && newOpts.restrictions)
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
if (newOpts.meta) {
|
|||
|
|
this.setMeta(newOpts.meta);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
this.i18nInit();
|
|||
|
|
|
|||
|
|
if (newOpts.locale) {
|
|||
|
|
this.iteratePlugins(plugin => {
|
|||
|
|
plugin.setOptions();
|
|||
|
|
});
|
|||
|
|
} // Note: this is not the preact `setState`, it's an internal function that has the same name.
|
|||
|
|
|
|||
|
|
|
|||
|
|
this.setState(); // so that UI re-renders with new options
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
resetProgress() {
|
|||
|
|
const defaultProgress = {
|
|||
|
|
percentage: 0,
|
|||
|
|
bytesUploaded: 0,
|
|||
|
|
uploadComplete: false,
|
|||
|
|
uploadStarted: null
|
|||
|
|
};
|
|||
|
|
const files = { ...this.getState().files
|
|||
|
|
};
|
|||
|
|
const updatedFiles = {};
|
|||
|
|
Object.keys(files).forEach(fileID => {
|
|||
|
|
const updatedFile = { ...files[fileID]
|
|||
|
|
};
|
|||
|
|
updatedFile.progress = { ...updatedFile.progress,
|
|||
|
|
...defaultProgress
|
|||
|
|
};
|
|||
|
|
updatedFiles[fileID] = updatedFile;
|
|||
|
|
});
|
|||
|
|
this.setState({
|
|||
|
|
files: updatedFiles,
|
|||
|
|
totalProgress: 0
|
|||
|
|
});
|
|||
|
|
this.emit('reset-progress');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
addPreProcessor(fn) {
|
|||
|
|
_classPrivateFieldLooseBase$6(this, _preProcessors)[_preProcessors].add(fn);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
removePreProcessor(fn) {
|
|||
|
|
return _classPrivateFieldLooseBase$6(this, _preProcessors)[_preProcessors].delete(fn);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
addPostProcessor(fn) {
|
|||
|
|
_classPrivateFieldLooseBase$6(this, _postProcessors)[_postProcessors].add(fn);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
removePostProcessor(fn) {
|
|||
|
|
return _classPrivateFieldLooseBase$6(this, _postProcessors)[_postProcessors].delete(fn);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
addUploader(fn) {
|
|||
|
|
_classPrivateFieldLooseBase$6(this, _uploaders)[_uploaders].add(fn);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
removeUploader(fn) {
|
|||
|
|
return _classPrivateFieldLooseBase$6(this, _uploaders)[_uploaders].delete(fn);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
setMeta(data) {
|
|||
|
|
const updatedMeta = { ...this.getState().meta,
|
|||
|
|
...data
|
|||
|
|
};
|
|||
|
|
const updatedFiles = { ...this.getState().files
|
|||
|
|
};
|
|||
|
|
Object.keys(updatedFiles).forEach(fileID => {
|
|||
|
|
updatedFiles[fileID] = { ...updatedFiles[fileID],
|
|||
|
|
meta: { ...updatedFiles[fileID].meta,
|
|||
|
|
...data
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
});
|
|||
|
|
this.log('Adding metadata:');
|
|||
|
|
this.log(data);
|
|||
|
|
this.setState({
|
|||
|
|
meta: updatedMeta,
|
|||
|
|
files: updatedFiles
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
setFileMeta(fileID, data) {
|
|||
|
|
const updatedFiles = { ...this.getState().files
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
if (!updatedFiles[fileID]) {
|
|||
|
|
this.log('Was trying to set metadata for a file that has been removed: ', fileID);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const newMeta = { ...updatedFiles[fileID].meta,
|
|||
|
|
...data
|
|||
|
|
};
|
|||
|
|
updatedFiles[fileID] = { ...updatedFiles[fileID],
|
|||
|
|
meta: newMeta
|
|||
|
|
};
|
|||
|
|
this.setState({
|
|||
|
|
files: updatedFiles
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Get a file object.
|
|||
|
|
*
|
|||
|
|
* @param {string} fileID The ID of the file object to return.
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
getFile(fileID) {
|
|||
|
|
return this.getState().files[fileID];
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Get all files in an array.
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
getFiles() {
|
|||
|
|
const {
|
|||
|
|
files
|
|||
|
|
} = this.getState();
|
|||
|
|
return Object.values(files);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
getObjectOfFilesPerState() {
|
|||
|
|
const {
|
|||
|
|
files: filesObject,
|
|||
|
|
totalProgress,
|
|||
|
|
error
|
|||
|
|
} = this.getState();
|
|||
|
|
const files = Object.values(filesObject);
|
|||
|
|
const inProgressFiles = files.filter(_ref => {
|
|||
|
|
let {
|
|||
|
|
progress
|
|||
|
|
} = _ref;
|
|||
|
|
return !progress.uploadComplete && progress.uploadStarted;
|
|||
|
|
});
|
|||
|
|
const newFiles = files.filter(file => !file.progress.uploadStarted);
|
|||
|
|
const startedFiles = files.filter(file => file.progress.uploadStarted || file.progress.preprocess || file.progress.postprocess);
|
|||
|
|
const uploadStartedFiles = files.filter(file => file.progress.uploadStarted);
|
|||
|
|
const pausedFiles = files.filter(file => file.isPaused);
|
|||
|
|
const completeFiles = files.filter(file => file.progress.uploadComplete);
|
|||
|
|
const erroredFiles = files.filter(file => file.error);
|
|||
|
|
const inProgressNotPausedFiles = inProgressFiles.filter(file => !file.isPaused);
|
|||
|
|
const processingFiles = files.filter(file => file.progress.preprocess || file.progress.postprocess);
|
|||
|
|
return {
|
|||
|
|
newFiles,
|
|||
|
|
startedFiles,
|
|||
|
|
uploadStartedFiles,
|
|||
|
|
pausedFiles,
|
|||
|
|
completeFiles,
|
|||
|
|
erroredFiles,
|
|||
|
|
inProgressFiles,
|
|||
|
|
inProgressNotPausedFiles,
|
|||
|
|
processingFiles,
|
|||
|
|
isUploadStarted: uploadStartedFiles.length > 0,
|
|||
|
|
isAllComplete: totalProgress === 100 && completeFiles.length === files.length && processingFiles.length === 0,
|
|||
|
|
isAllErrored: !!error && erroredFiles.length === files.length,
|
|||
|
|
isAllPaused: inProgressFiles.length !== 0 && pausedFiles.length === inProgressFiles.length,
|
|||
|
|
isUploadInProgress: inProgressFiles.length > 0,
|
|||
|
|
isSomeGhost: files.some(file => file.isGhost)
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* A public wrapper for _checkRestrictions — checks if a file passes a set of restrictions.
|
|||
|
|
* For use in UI pluigins (like Providers), to disallow selecting files that won’t pass restrictions.
|
|||
|
|
*
|
|||
|
|
* @param {object} file object to check
|
|||
|
|
* @param {Array} [files] array to check maxNumberOfFiles and maxTotalFileSize
|
|||
|
|
* @returns {object} { result: true/false, reason: why file didn’t pass restrictions }
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
validateRestrictions(file, files) {
|
|||
|
|
try {
|
|||
|
|
_classPrivateFieldLooseBase$6(this, _checkRestrictions)[_checkRestrictions](file, files);
|
|||
|
|
|
|||
|
|
return {
|
|||
|
|
result: true
|
|||
|
|
};
|
|||
|
|
} catch (err) {
|
|||
|
|
return {
|
|||
|
|
result: false,
|
|||
|
|
reason: err.message
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Check if file passes a set of restrictions set in options: maxFileSize, minFileSize,
|
|||
|
|
* maxNumberOfFiles and allowedFileTypes.
|
|||
|
|
*
|
|||
|
|
* @param {object} file object to check
|
|||
|
|
* @param {Array} [files] array to check maxNumberOfFiles and maxTotalFileSize
|
|||
|
|
* @private
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
checkIfFileAlreadyExists(fileID) {
|
|||
|
|
const {
|
|||
|
|
files
|
|||
|
|
} = this.getState();
|
|||
|
|
|
|||
|
|
if (files[fileID] && !files[fileID].isGhost) {
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Create a file state object based on user-provided `addFile()` options.
|
|||
|
|
*
|
|||
|
|
* Note this is extremely side-effectful and should only be done when a file state object
|
|||
|
|
* will be added to state immediately afterward!
|
|||
|
|
*
|
|||
|
|
* The `files` value is passed in because it may be updated by the caller without updating the store.
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Add a new file to `state.files`. This will run `onBeforeFileAdded`,
|
|||
|
|
* try to guess file type in a clever way, check file against restrictions,
|
|||
|
|
* and start an upload if `autoProceed === true`.
|
|||
|
|
*
|
|||
|
|
* @param {object} file object to add
|
|||
|
|
* @returns {string} id for the added file
|
|||
|
|
*/
|
|||
|
|
addFile(file) {
|
|||
|
|
_classPrivateFieldLooseBase$6(this, _assertNewUploadAllowed)[_assertNewUploadAllowed](file);
|
|||
|
|
|
|||
|
|
const {
|
|||
|
|
files
|
|||
|
|
} = this.getState();
|
|||
|
|
|
|||
|
|
let newFile = _classPrivateFieldLooseBase$6(this, _checkAndCreateFileStateObject)[_checkAndCreateFileStateObject](files, file); // Users are asked to re-select recovered files without data,
|
|||
|
|
// and to keep the progress, meta and everthing else, we only replace said data
|
|||
|
|
|
|||
|
|
|
|||
|
|
if (files[newFile.id] && files[newFile.id].isGhost) {
|
|||
|
|
newFile = { ...files[newFile.id],
|
|||
|
|
data: file.data,
|
|||
|
|
isGhost: false
|
|||
|
|
};
|
|||
|
|
this.log(`Replaced the blob in the restored ghost file: ${newFile.name}, ${newFile.id}`);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
this.setState({
|
|||
|
|
files: { ...files,
|
|||
|
|
[newFile.id]: newFile
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
this.emit('file-added', newFile);
|
|||
|
|
this.emit('files-added', [newFile]);
|
|||
|
|
this.log(`Added file: ${newFile.name}, ${newFile.id}, mime type: ${newFile.type}`);
|
|||
|
|
|
|||
|
|
_classPrivateFieldLooseBase$6(this, _startIfAutoProceed)[_startIfAutoProceed]();
|
|||
|
|
|
|||
|
|
return newFile.id;
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Add multiple files to `state.files`. See the `addFile()` documentation.
|
|||
|
|
*
|
|||
|
|
* If an error occurs while adding a file, it is logged and the user is notified.
|
|||
|
|
* This is good for UI plugins, but not for programmatic use.
|
|||
|
|
* Programmatic users should usually still use `addFile()` on individual files.
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
addFiles(fileDescriptors) {
|
|||
|
|
_classPrivateFieldLooseBase$6(this, _assertNewUploadAllowed)[_assertNewUploadAllowed](); // create a copy of the files object only once
|
|||
|
|
|
|||
|
|
|
|||
|
|
const files = { ...this.getState().files
|
|||
|
|
};
|
|||
|
|
const newFiles = [];
|
|||
|
|
const errors = [];
|
|||
|
|
|
|||
|
|
for (let i = 0; i < fileDescriptors.length; i++) {
|
|||
|
|
try {
|
|||
|
|
let newFile = _classPrivateFieldLooseBase$6(this, _checkAndCreateFileStateObject)[_checkAndCreateFileStateObject](files, fileDescriptors[i]); // Users are asked to re-select recovered files without data,
|
|||
|
|
// and to keep the progress, meta and everthing else, we only replace said data
|
|||
|
|
|
|||
|
|
|
|||
|
|
if (files[newFile.id] && files[newFile.id].isGhost) {
|
|||
|
|
newFile = { ...files[newFile.id],
|
|||
|
|
data: fileDescriptors[i].data,
|
|||
|
|
isGhost: false
|
|||
|
|
};
|
|||
|
|
this.log(`Replaced blob in a ghost file: ${newFile.name}, ${newFile.id}`);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
files[newFile.id] = newFile;
|
|||
|
|
newFiles.push(newFile);
|
|||
|
|
} catch (err) {
|
|||
|
|
if (!err.isRestriction) {
|
|||
|
|
errors.push(err);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
this.setState({
|
|||
|
|
files
|
|||
|
|
});
|
|||
|
|
newFiles.forEach(newFile => {
|
|||
|
|
this.emit('file-added', newFile);
|
|||
|
|
});
|
|||
|
|
this.emit('files-added', newFiles);
|
|||
|
|
|
|||
|
|
if (newFiles.length > 5) {
|
|||
|
|
this.log(`Added batch of ${newFiles.length} files`);
|
|||
|
|
} else {
|
|||
|
|
Object.keys(newFiles).forEach(fileID => {
|
|||
|
|
this.log(`Added file: ${newFiles[fileID].name}\n id: ${newFiles[fileID].id}\n type: ${newFiles[fileID].type}`);
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (newFiles.length > 0) {
|
|||
|
|
_classPrivateFieldLooseBase$6(this, _startIfAutoProceed)[_startIfAutoProceed]();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (errors.length > 0) {
|
|||
|
|
let message = 'Multiple errors occurred while adding files:\n';
|
|||
|
|
errors.forEach(subError => {
|
|||
|
|
message += `\n * ${subError.message}`;
|
|||
|
|
});
|
|||
|
|
this.info({
|
|||
|
|
message: this.i18n('addBulkFilesFailed', {
|
|||
|
|
smart_count: errors.length
|
|||
|
|
}),
|
|||
|
|
details: message
|
|||
|
|
}, 'error', this.opts.infoTimeout);
|
|||
|
|
|
|||
|
|
if (typeof AggregateError === 'function') {
|
|||
|
|
throw new AggregateError(errors, message);
|
|||
|
|
} else {
|
|||
|
|
const err = new Error(message);
|
|||
|
|
err.errors = errors;
|
|||
|
|
throw err;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
removeFiles(fileIDs, reason) {
|
|||
|
|
const {
|
|||
|
|
files,
|
|||
|
|
currentUploads
|
|||
|
|
} = this.getState();
|
|||
|
|
const updatedFiles = { ...files
|
|||
|
|
};
|
|||
|
|
const updatedUploads = { ...currentUploads
|
|||
|
|
};
|
|||
|
|
const removedFiles = Object.create(null);
|
|||
|
|
fileIDs.forEach(fileID => {
|
|||
|
|
if (files[fileID]) {
|
|||
|
|
removedFiles[fileID] = files[fileID];
|
|||
|
|
delete updatedFiles[fileID];
|
|||
|
|
}
|
|||
|
|
}); // Remove files from the `fileIDs` list in each upload.
|
|||
|
|
|
|||
|
|
function fileIsNotRemoved(uploadFileID) {
|
|||
|
|
return removedFiles[uploadFileID] === undefined;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Object.keys(updatedUploads).forEach(uploadID => {
|
|||
|
|
const newFileIDs = currentUploads[uploadID].fileIDs.filter(fileIsNotRemoved); // Remove the upload if no files are associated with it anymore.
|
|||
|
|
|
|||
|
|
if (newFileIDs.length === 0) {
|
|||
|
|
delete updatedUploads[uploadID];
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
updatedUploads[uploadID] = { ...currentUploads[uploadID],
|
|||
|
|
fileIDs: newFileIDs
|
|||
|
|
};
|
|||
|
|
});
|
|||
|
|
const stateUpdate = {
|
|||
|
|
currentUploads: updatedUploads,
|
|||
|
|
files: updatedFiles
|
|||
|
|
}; // If all files were removed - allow new uploads,
|
|||
|
|
// and clear recoveredState
|
|||
|
|
|
|||
|
|
if (Object.keys(updatedFiles).length === 0) {
|
|||
|
|
stateUpdate.allowNewUpload = true;
|
|||
|
|
stateUpdate.error = null;
|
|||
|
|
stateUpdate.recoveredState = null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
this.setState(stateUpdate);
|
|||
|
|
this.calculateTotalProgress();
|
|||
|
|
const removedFileIDs = Object.keys(removedFiles);
|
|||
|
|
removedFileIDs.forEach(fileID => {
|
|||
|
|
this.emit('file-removed', removedFiles[fileID], reason);
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
if (removedFileIDs.length > 5) {
|
|||
|
|
this.log(`Removed ${removedFileIDs.length} files`);
|
|||
|
|
} else {
|
|||
|
|
this.log(`Removed files: ${removedFileIDs.join(', ')}`);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
removeFile(fileID, reason) {
|
|||
|
|
if (reason === void 0) {
|
|||
|
|
reason = null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
this.removeFiles([fileID], reason);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
pauseResume(fileID) {
|
|||
|
|
if (!this.getState().capabilities.resumableUploads || this.getFile(fileID).uploadComplete) {
|
|||
|
|
return undefined;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const wasPaused = this.getFile(fileID).isPaused || false;
|
|||
|
|
const isPaused = !wasPaused;
|
|||
|
|
this.setFileState(fileID, {
|
|||
|
|
isPaused
|
|||
|
|
});
|
|||
|
|
this.emit('upload-pause', fileID, isPaused);
|
|||
|
|
return isPaused;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
pauseAll() {
|
|||
|
|
const updatedFiles = { ...this.getState().files
|
|||
|
|
};
|
|||
|
|
const inProgressUpdatedFiles = Object.keys(updatedFiles).filter(file => {
|
|||
|
|
return !updatedFiles[file].progress.uploadComplete && updatedFiles[file].progress.uploadStarted;
|
|||
|
|
});
|
|||
|
|
inProgressUpdatedFiles.forEach(file => {
|
|||
|
|
const updatedFile = { ...updatedFiles[file],
|
|||
|
|
isPaused: true
|
|||
|
|
};
|
|||
|
|
updatedFiles[file] = updatedFile;
|
|||
|
|
});
|
|||
|
|
this.setState({
|
|||
|
|
files: updatedFiles
|
|||
|
|
});
|
|||
|
|
this.emit('pause-all');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
resumeAll() {
|
|||
|
|
const updatedFiles = { ...this.getState().files
|
|||
|
|
};
|
|||
|
|
const inProgressUpdatedFiles = Object.keys(updatedFiles).filter(file => {
|
|||
|
|
return !updatedFiles[file].progress.uploadComplete && updatedFiles[file].progress.uploadStarted;
|
|||
|
|
});
|
|||
|
|
inProgressUpdatedFiles.forEach(file => {
|
|||
|
|
const updatedFile = { ...updatedFiles[file],
|
|||
|
|
isPaused: false,
|
|||
|
|
error: null
|
|||
|
|
};
|
|||
|
|
updatedFiles[file] = updatedFile;
|
|||
|
|
});
|
|||
|
|
this.setState({
|
|||
|
|
files: updatedFiles
|
|||
|
|
});
|
|||
|
|
this.emit('resume-all');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
retryAll() {
|
|||
|
|
const updatedFiles = { ...this.getState().files
|
|||
|
|
};
|
|||
|
|
const filesToRetry = Object.keys(updatedFiles).filter(file => {
|
|||
|
|
return updatedFiles[file].error;
|
|||
|
|
});
|
|||
|
|
filesToRetry.forEach(file => {
|
|||
|
|
const updatedFile = { ...updatedFiles[file],
|
|||
|
|
isPaused: false,
|
|||
|
|
error: null
|
|||
|
|
};
|
|||
|
|
updatedFiles[file] = updatedFile;
|
|||
|
|
});
|
|||
|
|
this.setState({
|
|||
|
|
files: updatedFiles,
|
|||
|
|
error: null
|
|||
|
|
});
|
|||
|
|
this.emit('retry-all', filesToRetry);
|
|||
|
|
|
|||
|
|
if (filesToRetry.length === 0) {
|
|||
|
|
return Promise.resolve({
|
|||
|
|
successful: [],
|
|||
|
|
failed: []
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const uploadID = _classPrivateFieldLooseBase$6(this, _createUpload)[_createUpload](filesToRetry, {
|
|||
|
|
forceAllowNewUpload: true // create new upload even if allowNewUpload: false
|
|||
|
|
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
return _classPrivateFieldLooseBase$6(this, _runUpload)[_runUpload](uploadID);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
cancelAll() {
|
|||
|
|
this.emit('cancel-all');
|
|||
|
|
const {
|
|||
|
|
files
|
|||
|
|
} = this.getState();
|
|||
|
|
const fileIDs = Object.keys(files);
|
|||
|
|
|
|||
|
|
if (fileIDs.length) {
|
|||
|
|
this.removeFiles(fileIDs, 'cancel-all');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
this.setState({
|
|||
|
|
totalProgress: 0,
|
|||
|
|
error: null,
|
|||
|
|
recoveredState: null
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
retryUpload(fileID) {
|
|||
|
|
this.setFileState(fileID, {
|
|||
|
|
error: null,
|
|||
|
|
isPaused: false
|
|||
|
|
});
|
|||
|
|
this.emit('upload-retry', fileID);
|
|||
|
|
|
|||
|
|
const uploadID = _classPrivateFieldLooseBase$6(this, _createUpload)[_createUpload]([fileID], {
|
|||
|
|
forceAllowNewUpload: true // create new upload even if allowNewUpload: false
|
|||
|
|
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
return _classPrivateFieldLooseBase$6(this, _runUpload)[_runUpload](uploadID);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
reset() {
|
|||
|
|
this.cancelAll();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
logout() {
|
|||
|
|
this.iteratePlugins(plugin => {
|
|||
|
|
if (plugin.provider && plugin.provider.logout) {
|
|||
|
|
plugin.provider.logout();
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
calculateProgress(file, data) {
|
|||
|
|
if (!this.getFile(file.id)) {
|
|||
|
|
this.log(`Not setting progress for a file that has been removed: ${file.id}`);
|
|||
|
|
return;
|
|||
|
|
} // bytesTotal may be null or zero; in that case we can't divide by it
|
|||
|
|
|
|||
|
|
|
|||
|
|
const canHavePercentage = Number.isFinite(data.bytesTotal) && data.bytesTotal > 0;
|
|||
|
|
this.setFileState(file.id, {
|
|||
|
|
progress: { ...this.getFile(file.id).progress,
|
|||
|
|
bytesUploaded: data.bytesUploaded,
|
|||
|
|
bytesTotal: data.bytesTotal,
|
|||
|
|
percentage: canHavePercentage ? Math.round(data.bytesUploaded / data.bytesTotal * 100) : 0
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
this.calculateTotalProgress();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
calculateTotalProgress() {
|
|||
|
|
// calculate total progress, using the number of files currently uploading,
|
|||
|
|
// multiplied by 100 and the summ of individual progress of each file
|
|||
|
|
const files = this.getFiles();
|
|||
|
|
const inProgress = files.filter(file => {
|
|||
|
|
return file.progress.uploadStarted || file.progress.preprocess || file.progress.postprocess;
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
if (inProgress.length === 0) {
|
|||
|
|
this.emit('progress', 0);
|
|||
|
|
this.setState({
|
|||
|
|
totalProgress: 0
|
|||
|
|
});
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const sizedFiles = inProgress.filter(file => file.progress.bytesTotal != null);
|
|||
|
|
const unsizedFiles = inProgress.filter(file => file.progress.bytesTotal == null);
|
|||
|
|
|
|||
|
|
if (sizedFiles.length === 0) {
|
|||
|
|
const progressMax = inProgress.length * 100;
|
|||
|
|
const currentProgress = unsizedFiles.reduce((acc, file) => {
|
|||
|
|
return acc + file.progress.percentage;
|
|||
|
|
}, 0);
|
|||
|
|
const totalProgress = Math.round(currentProgress / progressMax * 100);
|
|||
|
|
this.setState({
|
|||
|
|
totalProgress
|
|||
|
|
});
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
let totalSize = sizedFiles.reduce((acc, file) => {
|
|||
|
|
return acc + file.progress.bytesTotal;
|
|||
|
|
}, 0);
|
|||
|
|
const averageSize = totalSize / sizedFiles.length;
|
|||
|
|
totalSize += averageSize * unsizedFiles.length;
|
|||
|
|
let uploadedSize = 0;
|
|||
|
|
sizedFiles.forEach(file => {
|
|||
|
|
uploadedSize += file.progress.bytesUploaded;
|
|||
|
|
});
|
|||
|
|
unsizedFiles.forEach(file => {
|
|||
|
|
uploadedSize += averageSize * (file.progress.percentage || 0) / 100;
|
|||
|
|
});
|
|||
|
|
let totalProgress = totalSize === 0 ? 0 : Math.round(uploadedSize / totalSize * 100); // hot fix, because:
|
|||
|
|
// uploadedSize ended up larger than totalSize, resulting in 1325% total
|
|||
|
|
|
|||
|
|
if (totalProgress > 100) {
|
|||
|
|
totalProgress = 100;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
this.setState({
|
|||
|
|
totalProgress
|
|||
|
|
});
|
|||
|
|
this.emit('progress', totalProgress);
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Registers listeners for all global actions, like:
|
|||
|
|
* `error`, `file-removed`, `upload-progress`
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
updateOnlineStatus() {
|
|||
|
|
const online = typeof window.navigator.onLine !== 'undefined' ? window.navigator.onLine : true;
|
|||
|
|
|
|||
|
|
if (!online) {
|
|||
|
|
this.emit('is-offline');
|
|||
|
|
this.info(this.i18n('noInternetConnection'), 'error', 0);
|
|||
|
|
this.wasOffline = true;
|
|||
|
|
} else {
|
|||
|
|
this.emit('is-online');
|
|||
|
|
|
|||
|
|
if (this.wasOffline) {
|
|||
|
|
this.emit('back-online');
|
|||
|
|
this.info(this.i18n('connectedToInternet'), 'success', 3000);
|
|||
|
|
this.wasOffline = false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
getID() {
|
|||
|
|
return this.opts.id;
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Registers a plugin with Core.
|
|||
|
|
*
|
|||
|
|
* @param {object} Plugin object
|
|||
|
|
* @param {object} [opts] object with options to be passed to Plugin
|
|||
|
|
* @returns {object} self for chaining
|
|||
|
|
*/
|
|||
|
|
// eslint-disable-next-line no-shadow
|
|||
|
|
|
|||
|
|
|
|||
|
|
use(Plugin, opts) {
|
|||
|
|
if (typeof Plugin !== 'function') {
|
|||
|
|
const msg = `Expected a plugin class, but got ${Plugin === null ? 'null' : typeof Plugin}.` + ' Please verify that the plugin was imported and spelled correctly.';
|
|||
|
|
throw new TypeError(msg);
|
|||
|
|
} // Instantiate
|
|||
|
|
|
|||
|
|
|
|||
|
|
const plugin = new Plugin(this, opts);
|
|||
|
|
const pluginId = plugin.id;
|
|||
|
|
|
|||
|
|
if (!pluginId) {
|
|||
|
|
throw new Error('Your plugin must have an id');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!plugin.type) {
|
|||
|
|
throw new Error('Your plugin must have a type');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const existsPluginAlready = this.getPlugin(pluginId);
|
|||
|
|
|
|||
|
|
if (existsPluginAlready) {
|
|||
|
|
const msg = `Already found a plugin named '${existsPluginAlready.id}'. ` + `Tried to use: '${pluginId}'.\n` + 'Uppy plugins must have unique `id` options. See https://uppy.io/docs/plugins/#id.';
|
|||
|
|
throw new Error(msg);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (Plugin.VERSION) {
|
|||
|
|
this.log(`Using ${pluginId} v${Plugin.VERSION}`);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (plugin.type in _classPrivateFieldLooseBase$6(this, _plugins)[_plugins]) {
|
|||
|
|
_classPrivateFieldLooseBase$6(this, _plugins)[_plugins][plugin.type].push(plugin);
|
|||
|
|
} else {
|
|||
|
|
_classPrivateFieldLooseBase$6(this, _plugins)[_plugins][plugin.type] = [plugin];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
plugin.install();
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Find one Plugin by name.
|
|||
|
|
*
|
|||
|
|
* @param {string} id plugin id
|
|||
|
|
* @returns {BasePlugin|undefined}
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
getPlugin(id) {
|
|||
|
|
for (const plugins of Object.values(_classPrivateFieldLooseBase$6(this, _plugins)[_plugins])) {
|
|||
|
|
const foundPlugin = plugins.find(plugin => plugin.id === id);
|
|||
|
|
if (foundPlugin != null) return foundPlugin;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return undefined;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
[_Symbol$for$1](type) {
|
|||
|
|
return _classPrivateFieldLooseBase$6(this, _plugins)[_plugins][type];
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Iterate through all `use`d plugins.
|
|||
|
|
*
|
|||
|
|
* @param {Function} method that will be run on each plugin
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
iteratePlugins(method) {
|
|||
|
|
Object.values(_classPrivateFieldLooseBase$6(this, _plugins)[_plugins]).flat(1).forEach(method);
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Uninstall and remove a plugin.
|
|||
|
|
*
|
|||
|
|
* @param {object} instance The plugin instance to remove.
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
removePlugin(instance) {
|
|||
|
|
this.log(`Removing plugin ${instance.id}`);
|
|||
|
|
this.emit('plugin-remove', instance);
|
|||
|
|
|
|||
|
|
if (instance.uninstall) {
|
|||
|
|
instance.uninstall();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const list = _classPrivateFieldLooseBase$6(this, _plugins)[_plugins][instance.type]; // list.indexOf failed here, because Vue3 converted the plugin instance
|
|||
|
|
// to a Proxy object, which failed the strict comparison test:
|
|||
|
|
// obj !== objProxy
|
|||
|
|
|
|||
|
|
|
|||
|
|
const index = list.findIndex(item => item.id === instance.id);
|
|||
|
|
|
|||
|
|
if (index !== -1) {
|
|||
|
|
list.splice(index, 1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const state = this.getState();
|
|||
|
|
const updatedState = {
|
|||
|
|
plugins: { ...state.plugins,
|
|||
|
|
[instance.id]: undefined
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
this.setState(updatedState);
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Uninstall all plugins and close down this Uppy instance.
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
close() {
|
|||
|
|
this.log(`Closing Uppy instance ${this.opts.id}: removing all files and uninstalling plugins`);
|
|||
|
|
this.reset();
|
|||
|
|
|
|||
|
|
_classPrivateFieldLooseBase$6(this, _storeUnsubscribe)[_storeUnsubscribe]();
|
|||
|
|
|
|||
|
|
this.iteratePlugins(plugin => {
|
|||
|
|
this.removePlugin(plugin);
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
if (typeof window !== 'undefined' && window.removeEventListener) {
|
|||
|
|
window.removeEventListener('online', _classPrivateFieldLooseBase$6(this, _updateOnlineStatus)[_updateOnlineStatus]);
|
|||
|
|
window.removeEventListener('offline', _classPrivateFieldLooseBase$6(this, _updateOnlineStatus)[_updateOnlineStatus]);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
hideInfo() {
|
|||
|
|
const {
|
|||
|
|
info
|
|||
|
|
} = this.getState();
|
|||
|
|
this.setState({
|
|||
|
|
info: info.slice(1)
|
|||
|
|
});
|
|||
|
|
this.emit('info-hidden');
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Set info message in `state.info`, so that UI plugins like `Informer`
|
|||
|
|
* can display the message.
|
|||
|
|
*
|
|||
|
|
* @param {string | object} message Message to be displayed by the informer
|
|||
|
|
* @param {string} [type]
|
|||
|
|
* @param {number} [duration]
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
info(message, type, duration) {
|
|||
|
|
if (type === void 0) {
|
|||
|
|
type = 'info';
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (duration === void 0) {
|
|||
|
|
duration = 3000;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const isComplexMessage = typeof message === 'object';
|
|||
|
|
this.setState({
|
|||
|
|
info: [...this.getState().info, {
|
|||
|
|
type,
|
|||
|
|
message: isComplexMessage ? message.message : message,
|
|||
|
|
details: isComplexMessage ? message.details : null
|
|||
|
|
}]
|
|||
|
|
});
|
|||
|
|
setTimeout(() => this.hideInfo(), duration);
|
|||
|
|
this.emit('info-visible');
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Passes messages to a function, provided in `opts.logger`.
|
|||
|
|
* If `opts.logger: Uppy.debugLogger` or `opts.debug: true`, logs to the browser console.
|
|||
|
|
*
|
|||
|
|
* @param {string|object} message to log
|
|||
|
|
* @param {string} [type] optional `error` or `warning`
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
log(message, type) {
|
|||
|
|
const {
|
|||
|
|
logger
|
|||
|
|
} = this.opts;
|
|||
|
|
|
|||
|
|
switch (type) {
|
|||
|
|
case 'error':
|
|||
|
|
logger.error(message);
|
|||
|
|
break;
|
|||
|
|
|
|||
|
|
case 'warning':
|
|||
|
|
logger.warn(message);
|
|||
|
|
break;
|
|||
|
|
|
|||
|
|
default:
|
|||
|
|
logger.debug(message);
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Restore an upload by its ID.
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
restore(uploadID) {
|
|||
|
|
this.log(`Core: attempting to restore upload "${uploadID}"`);
|
|||
|
|
|
|||
|
|
if (!this.getState().currentUploads[uploadID]) {
|
|||
|
|
_classPrivateFieldLooseBase$6(this, _removeUpload)[_removeUpload](uploadID);
|
|||
|
|
|
|||
|
|
return Promise.reject(new Error('Nonexistent upload'));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return _classPrivateFieldLooseBase$6(this, _runUpload)[_runUpload](uploadID);
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Create an upload for a bunch of files.
|
|||
|
|
*
|
|||
|
|
* @param {Array<string>} fileIDs File IDs to include in this upload.
|
|||
|
|
* @returns {string} ID of this upload.
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
[_Symbol$for2$1]() {
|
|||
|
|
return _classPrivateFieldLooseBase$6(this, _createUpload)[_createUpload](...arguments);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Add data to an upload's result object.
|
|||
|
|
*
|
|||
|
|
* @param {string} uploadID The ID of the upload.
|
|||
|
|
* @param {object} data Data properties to add to the result object.
|
|||
|
|
*/
|
|||
|
|
addResultData(uploadID, data) {
|
|||
|
|
if (!_classPrivateFieldLooseBase$6(this, _getUpload)[_getUpload](uploadID)) {
|
|||
|
|
this.log(`Not setting result for an upload that has been removed: ${uploadID}`);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const {
|
|||
|
|
currentUploads
|
|||
|
|
} = this.getState();
|
|||
|
|
const currentUpload = { ...currentUploads[uploadID],
|
|||
|
|
result: { ...currentUploads[uploadID].result,
|
|||
|
|
...data
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
this.setState({
|
|||
|
|
currentUploads: { ...currentUploads,
|
|||
|
|
[uploadID]: currentUpload
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Remove an upload, eg. if it has been canceled or completed.
|
|||
|
|
*
|
|||
|
|
* @param {string} uploadID The ID of the upload.
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Start an upload for all the files that are not currently being uploaded.
|
|||
|
|
*
|
|||
|
|
* @returns {Promise}
|
|||
|
|
*/
|
|||
|
|
upload() {
|
|||
|
|
var _classPrivateFieldLoo;
|
|||
|
|
|
|||
|
|
if (!((_classPrivateFieldLoo = _classPrivateFieldLooseBase$6(this, _plugins)[_plugins].uploader) != null && _classPrivateFieldLoo.length)) {
|
|||
|
|
this.log('No uploader type plugins are used', 'warning');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
let {
|
|||
|
|
files
|
|||
|
|
} = this.getState();
|
|||
|
|
const onBeforeUploadResult = this.opts.onBeforeUpload(files);
|
|||
|
|
|
|||
|
|
if (onBeforeUploadResult === false) {
|
|||
|
|
return Promise.reject(new Error('Not starting the upload because onBeforeUpload returned false'));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (onBeforeUploadResult && typeof onBeforeUploadResult === 'object') {
|
|||
|
|
files = onBeforeUploadResult; // Updating files in state, because uploader plugins receive file IDs,
|
|||
|
|
// and then fetch the actual file object from state
|
|||
|
|
|
|||
|
|
this.setState({
|
|||
|
|
files
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return Promise.resolve().then(() => {
|
|||
|
|
_classPrivateFieldLooseBase$6(this, _checkMinNumberOfFiles)[_checkMinNumberOfFiles](files);
|
|||
|
|
|
|||
|
|
_classPrivateFieldLooseBase$6(this, _checkRequiredMetaFields)[_checkRequiredMetaFields](files);
|
|||
|
|
}).catch(err => {
|
|||
|
|
_classPrivateFieldLooseBase$6(this, _showOrLogErrorAndThrow)[_showOrLogErrorAndThrow](err);
|
|||
|
|
}).then(() => {
|
|||
|
|
const {
|
|||
|
|
currentUploads
|
|||
|
|
} = this.getState(); // get a list of files that are currently assigned to uploads
|
|||
|
|
|
|||
|
|
const currentlyUploadingFiles = Object.values(currentUploads).flatMap(curr => curr.fileIDs);
|
|||
|
|
const waitingFileIDs = [];
|
|||
|
|
Object.keys(files).forEach(fileID => {
|
|||
|
|
const file = this.getFile(fileID); // if the file hasn't started uploading and hasn't already been assigned to an upload..
|
|||
|
|
|
|||
|
|
if (!file.progress.uploadStarted && currentlyUploadingFiles.indexOf(fileID) === -1) {
|
|||
|
|
waitingFileIDs.push(file.id);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
const uploadID = _classPrivateFieldLooseBase$6(this, _createUpload)[_createUpload](waitingFileIDs);
|
|||
|
|
|
|||
|
|
return _classPrivateFieldLooseBase$6(this, _runUpload)[_runUpload](uploadID);
|
|||
|
|
}).catch(err => {
|
|||
|
|
_classPrivateFieldLooseBase$6(this, _showOrLogErrorAndThrow)[_showOrLogErrorAndThrow](err, {
|
|||
|
|
showInformer: false
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function _checkRestrictions2(file, files) {
|
|||
|
|
if (files === void 0) {
|
|||
|
|
files = this.getFiles();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const {
|
|||
|
|
maxFileSize,
|
|||
|
|
minFileSize,
|
|||
|
|
maxTotalFileSize,
|
|||
|
|
maxNumberOfFiles,
|
|||
|
|
allowedFileTypes
|
|||
|
|
} = this.opts.restrictions;
|
|||
|
|
|
|||
|
|
if (maxNumberOfFiles) {
|
|||
|
|
if (files.length + 1 > maxNumberOfFiles) {
|
|||
|
|
throw new RestrictionError(`${this.i18n('youCanOnlyUploadX', {
|
|||
|
|
smart_count: maxNumberOfFiles
|
|||
|
|
})}`);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (allowedFileTypes) {
|
|||
|
|
const isCorrectFileType = allowedFileTypes.some(type => {
|
|||
|
|
// check if this is a mime-type
|
|||
|
|
if (type.indexOf('/') > -1) {
|
|||
|
|
if (!file.type) return false;
|
|||
|
|
return mimeMatch(file.type.replace(/;.*?$/, ''), type);
|
|||
|
|
} // otherwise this is likely an extension
|
|||
|
|
|
|||
|
|
|
|||
|
|
if (type[0] === '.' && file.extension) {
|
|||
|
|
return file.extension.toLowerCase() === type.substr(1).toLowerCase();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return false;
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
if (!isCorrectFileType) {
|
|||
|
|
const allowedFileTypesString = allowedFileTypes.join(', ');
|
|||
|
|
throw new RestrictionError(this.i18n('youCanOnlyUploadFileTypes', {
|
|||
|
|
types: allowedFileTypesString
|
|||
|
|
}));
|
|||
|
|
}
|
|||
|
|
} // We can't check maxTotalFileSize if the size is unknown.
|
|||
|
|
|
|||
|
|
|
|||
|
|
if (maxTotalFileSize && file.size != null) {
|
|||
|
|
let totalFilesSize = 0;
|
|||
|
|
totalFilesSize += file.size;
|
|||
|
|
files.forEach(f => {
|
|||
|
|
totalFilesSize += f.size;
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
if (totalFilesSize > maxTotalFileSize) {
|
|||
|
|
throw new RestrictionError(this.i18n('exceedsSize', {
|
|||
|
|
size: prettierBytes(maxTotalFileSize),
|
|||
|
|
file: file.name
|
|||
|
|
}));
|
|||
|
|
}
|
|||
|
|
} // We can't check maxFileSize if the size is unknown.
|
|||
|
|
|
|||
|
|
|
|||
|
|
if (maxFileSize && file.size != null) {
|
|||
|
|
if (file.size > maxFileSize) {
|
|||
|
|
throw new RestrictionError(this.i18n('exceedsSize', {
|
|||
|
|
size: prettierBytes(maxFileSize),
|
|||
|
|
file: file.name
|
|||
|
|
}));
|
|||
|
|
}
|
|||
|
|
} // We can't check minFileSize if the size is unknown.
|
|||
|
|
|
|||
|
|
|
|||
|
|
if (minFileSize && file.size != null) {
|
|||
|
|
if (file.size < minFileSize) {
|
|||
|
|
throw new RestrictionError(this.i18n('inferiorSize', {
|
|||
|
|
size: prettierBytes(minFileSize)
|
|||
|
|
}));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function _checkMinNumberOfFiles2(files) {
|
|||
|
|
const {
|
|||
|
|
minNumberOfFiles
|
|||
|
|
} = this.opts.restrictions;
|
|||
|
|
|
|||
|
|
if (Object.keys(files).length < minNumberOfFiles) {
|
|||
|
|
throw new RestrictionError(`${this.i18n('youHaveToAtLeastSelectX', {
|
|||
|
|
smart_count: minNumberOfFiles
|
|||
|
|
})}`);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function _checkRequiredMetaFieldsOnFile2(file) {
|
|||
|
|
const {
|
|||
|
|
requiredMetaFields
|
|||
|
|
} = this.opts.restrictions;
|
|||
|
|
const {
|
|||
|
|
hasOwnProperty
|
|||
|
|
} = Object.prototype;
|
|||
|
|
const errors = [];
|
|||
|
|
const missingFields = [];
|
|||
|
|
|
|||
|
|
for (let i = 0; i < requiredMetaFields.length; i++) {
|
|||
|
|
if (!hasOwnProperty.call(file.meta, requiredMetaFields[i]) || file.meta[requiredMetaFields[i]] === '') {
|
|||
|
|
const err = new RestrictionError(`${this.i18n('missingRequiredMetaFieldOnFile', {
|
|||
|
|
fileName: file.name
|
|||
|
|
})}`);
|
|||
|
|
errors.push(err);
|
|||
|
|
missingFields.push(requiredMetaFields[i]);
|
|||
|
|
|
|||
|
|
_classPrivateFieldLooseBase$6(this, _showOrLogErrorAndThrow)[_showOrLogErrorAndThrow](err, {
|
|||
|
|
file,
|
|||
|
|
showInformer: false,
|
|||
|
|
throwErr: false
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
this.setFileState(file.id, {
|
|||
|
|
missingRequiredMetaFields: missingFields
|
|||
|
|
});
|
|||
|
|
return errors;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function _checkRequiredMetaFields2(files) {
|
|||
|
|
const errors = Object.keys(files).flatMap(fileID => {
|
|||
|
|
const file = this.getFile(fileID);
|
|||
|
|
return _classPrivateFieldLooseBase$6(this, _checkRequiredMetaFieldsOnFile)[_checkRequiredMetaFieldsOnFile](file);
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
if (errors.length) {
|
|||
|
|
throw new AggregateRestrictionError(errors, `${this.i18n('missingRequiredMetaField')}`);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function _showOrLogErrorAndThrow2(err, _temp) {
|
|||
|
|
let {
|
|||
|
|
showInformer = true,
|
|||
|
|
file = null,
|
|||
|
|
throwErr = true
|
|||
|
|
} = _temp === void 0 ? {} : _temp;
|
|||
|
|
const message = typeof err === 'object' ? err.message : err;
|
|||
|
|
const details = typeof err === 'object' && err.details ? err.details : ''; // Restriction errors should be logged, but not as errors,
|
|||
|
|
// as they are expected and shown in the UI.
|
|||
|
|
|
|||
|
|
let logMessageWithDetails = message;
|
|||
|
|
|
|||
|
|
if (details) {
|
|||
|
|
logMessageWithDetails += ` ${details}`;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (err.isRestriction) {
|
|||
|
|
this.log(logMessageWithDetails);
|
|||
|
|
this.emit('restriction-failed', file, err);
|
|||
|
|
} else {
|
|||
|
|
this.log(logMessageWithDetails, 'error');
|
|||
|
|
} // Sometimes informer has to be shown manually by the developer,
|
|||
|
|
// for example, in `onBeforeFileAdded`.
|
|||
|
|
|
|||
|
|
|
|||
|
|
if (showInformer) {
|
|||
|
|
this.info({
|
|||
|
|
message,
|
|||
|
|
details
|
|||
|
|
}, 'error', this.opts.infoTimeout);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (throwErr) {
|
|||
|
|
throw typeof err === 'object' ? err : new Error(err);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function _assertNewUploadAllowed2(file) {
|
|||
|
|
const {
|
|||
|
|
allowNewUpload
|
|||
|
|
} = this.getState();
|
|||
|
|
|
|||
|
|
if (allowNewUpload === false) {
|
|||
|
|
_classPrivateFieldLooseBase$6(this, _showOrLogErrorAndThrow)[_showOrLogErrorAndThrow](new RestrictionError(this.i18n('noMoreFilesAllowed')), {
|
|||
|
|
file
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function _checkAndCreateFileStateObject2(files, fileDescriptor) {
|
|||
|
|
const fileType = getFileType(fileDescriptor);
|
|||
|
|
const fileName = getFileName(fileType, fileDescriptor);
|
|||
|
|
const fileExtension = getFileNameAndExtension(fileName).extension;
|
|||
|
|
const isRemote = Boolean(fileDescriptor.isRemote);
|
|||
|
|
const fileID = generateFileID({ ...fileDescriptor,
|
|||
|
|
type: fileType
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
if (this.checkIfFileAlreadyExists(fileID)) {
|
|||
|
|
const error = new RestrictionError(this.i18n('noDuplicates', {
|
|||
|
|
fileName
|
|||
|
|
}));
|
|||
|
|
|
|||
|
|
_classPrivateFieldLooseBase$6(this, _showOrLogErrorAndThrow)[_showOrLogErrorAndThrow](error, {
|
|||
|
|
file: fileDescriptor
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const meta = fileDescriptor.meta || {};
|
|||
|
|
meta.name = fileName;
|
|||
|
|
meta.type = fileType; // `null` means the size is unknown.
|
|||
|
|
|
|||
|
|
const size = Number.isFinite(fileDescriptor.data.size) ? fileDescriptor.data.size : null;
|
|||
|
|
let newFile = {
|
|||
|
|
source: fileDescriptor.source || '',
|
|||
|
|
id: fileID,
|
|||
|
|
name: fileName,
|
|||
|
|
extension: fileExtension || '',
|
|||
|
|
meta: { ...this.getState().meta,
|
|||
|
|
...meta
|
|||
|
|
},
|
|||
|
|
type: fileType,
|
|||
|
|
data: fileDescriptor.data,
|
|||
|
|
progress: {
|
|||
|
|
percentage: 0,
|
|||
|
|
bytesUploaded: 0,
|
|||
|
|
bytesTotal: size,
|
|||
|
|
uploadComplete: false,
|
|||
|
|
uploadStarted: null
|
|||
|
|
},
|
|||
|
|
size,
|
|||
|
|
isRemote,
|
|||
|
|
remote: fileDescriptor.remote || '',
|
|||
|
|
preview: fileDescriptor.preview
|
|||
|
|
};
|
|||
|
|
const onBeforeFileAddedResult = this.opts.onBeforeFileAdded(newFile, files);
|
|||
|
|
|
|||
|
|
if (onBeforeFileAddedResult === false) {
|
|||
|
|
// Don’t show UI info for this error, as it should be done by the developer
|
|||
|
|
_classPrivateFieldLooseBase$6(this, _showOrLogErrorAndThrow)[_showOrLogErrorAndThrow](new RestrictionError('Cannot add the file because onBeforeFileAdded returned false.'), {
|
|||
|
|
showInformer: false,
|
|||
|
|
fileDescriptor
|
|||
|
|
});
|
|||
|
|
} else if (typeof onBeforeFileAddedResult === 'object' && onBeforeFileAddedResult !== null) {
|
|||
|
|
newFile = onBeforeFileAddedResult;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
const filesArray = Object.keys(files).map(i => files[i]);
|
|||
|
|
|
|||
|
|
_classPrivateFieldLooseBase$6(this, _checkRestrictions)[_checkRestrictions](newFile, filesArray);
|
|||
|
|
} catch (err) {
|
|||
|
|
_classPrivateFieldLooseBase$6(this, _showOrLogErrorAndThrow)[_showOrLogErrorAndThrow](err, {
|
|||
|
|
file: newFile
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return newFile;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function _startIfAutoProceed2() {
|
|||
|
|
if (this.opts.autoProceed && !this.scheduledAutoProceed) {
|
|||
|
|
this.scheduledAutoProceed = setTimeout(() => {
|
|||
|
|
this.scheduledAutoProceed = null;
|
|||
|
|
this.upload().catch(err => {
|
|||
|
|
if (!err.isRestriction) {
|
|||
|
|
this.log(err.stack || err.message || err);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}, 4);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function _addListeners2() {
|
|||
|
|
/**
|
|||
|
|
* @param {Error} error
|
|||
|
|
* @param {object} [file]
|
|||
|
|
* @param {object} [response]
|
|||
|
|
*/
|
|||
|
|
const errorHandler = (error, file, response) => {
|
|||
|
|
let errorMsg = error.message || 'Unknown error';
|
|||
|
|
|
|||
|
|
if (error.details) {
|
|||
|
|
errorMsg += ` ${error.details}`;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
this.setState({
|
|||
|
|
error: errorMsg
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
if (file != null && file.id in this.getState().files) {
|
|||
|
|
this.setFileState(file.id, {
|
|||
|
|
error: errorMsg,
|
|||
|
|
response
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
this.on('error', errorHandler);
|
|||
|
|
this.on('upload-error', (file, error, response) => {
|
|||
|
|
errorHandler(error, file, response);
|
|||
|
|
|
|||
|
|
if (typeof error === 'object' && error.message) {
|
|||
|
|
const newError = new Error(error.message);
|
|||
|
|
newError.details = error.message;
|
|||
|
|
|
|||
|
|
if (error.details) {
|
|||
|
|
newError.details += ` ${error.details}`;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
newError.message = this.i18n('failedToUpload', {
|
|||
|
|
file: file.name
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
_classPrivateFieldLooseBase$6(this, _showOrLogErrorAndThrow)[_showOrLogErrorAndThrow](newError, {
|
|||
|
|
throwErr: false
|
|||
|
|
});
|
|||
|
|
} else {
|
|||
|
|
_classPrivateFieldLooseBase$6(this, _showOrLogErrorAndThrow)[_showOrLogErrorAndThrow](error, {
|
|||
|
|
throwErr: false
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
this.on('upload', () => {
|
|||
|
|
this.setState({
|
|||
|
|
error: null
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
this.on('upload-started', file => {
|
|||
|
|
if (!this.getFile(file.id)) {
|
|||
|
|
this.log(`Not setting progress for a file that has been removed: ${file.id}`);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
this.setFileState(file.id, {
|
|||
|
|
progress: {
|
|||
|
|
uploadStarted: Date.now(),
|
|||
|
|
uploadComplete: false,
|
|||
|
|
percentage: 0,
|
|||
|
|
bytesUploaded: 0,
|
|||
|
|
bytesTotal: file.size
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
this.on('upload-progress', this.calculateProgress);
|
|||
|
|
this.on('upload-success', (file, uploadResp) => {
|
|||
|
|
if (!this.getFile(file.id)) {
|
|||
|
|
this.log(`Not setting progress for a file that has been removed: ${file.id}`);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const currentProgress = this.getFile(file.id).progress;
|
|||
|
|
this.setFileState(file.id, {
|
|||
|
|
progress: { ...currentProgress,
|
|||
|
|
postprocess: _classPrivateFieldLooseBase$6(this, _postProcessors)[_postProcessors].size > 0 ? {
|
|||
|
|
mode: 'indeterminate'
|
|||
|
|
} : null,
|
|||
|
|
uploadComplete: true,
|
|||
|
|
percentage: 100,
|
|||
|
|
bytesUploaded: currentProgress.bytesTotal
|
|||
|
|
},
|
|||
|
|
response: uploadResp,
|
|||
|
|
uploadURL: uploadResp.uploadURL,
|
|||
|
|
isPaused: false
|
|||
|
|
}); // Remote providers sometimes don't tell us the file size,
|
|||
|
|
// but we can know how many bytes we uploaded once the upload is complete.
|
|||
|
|
|
|||
|
|
if (file.size == null) {
|
|||
|
|
this.setFileState(file.id, {
|
|||
|
|
size: uploadResp.bytesUploaded || currentProgress.bytesTotal
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
this.calculateTotalProgress();
|
|||
|
|
});
|
|||
|
|
this.on('preprocess-progress', (file, progress) => {
|
|||
|
|
if (!this.getFile(file.id)) {
|
|||
|
|
this.log(`Not setting progress for a file that has been removed: ${file.id}`);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
this.setFileState(file.id, {
|
|||
|
|
progress: { ...this.getFile(file.id).progress,
|
|||
|
|
preprocess: progress
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
this.on('preprocess-complete', file => {
|
|||
|
|
if (!this.getFile(file.id)) {
|
|||
|
|
this.log(`Not setting progress for a file that has been removed: ${file.id}`);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const files = { ...this.getState().files
|
|||
|
|
};
|
|||
|
|
files[file.id] = { ...files[file.id],
|
|||
|
|
progress: { ...files[file.id].progress
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
delete files[file.id].progress.preprocess;
|
|||
|
|
this.setState({
|
|||
|
|
files
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
this.on('postprocess-progress', (file, progress) => {
|
|||
|
|
if (!this.getFile(file.id)) {
|
|||
|
|
this.log(`Not setting progress for a file that has been removed: ${file.id}`);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
this.setFileState(file.id, {
|
|||
|
|
progress: { ...this.getState().files[file.id].progress,
|
|||
|
|
postprocess: progress
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
this.on('postprocess-complete', file => {
|
|||
|
|
if (!this.getFile(file.id)) {
|
|||
|
|
this.log(`Not setting progress for a file that has been removed: ${file.id}`);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const files = { ...this.getState().files
|
|||
|
|
};
|
|||
|
|
files[file.id] = { ...files[file.id],
|
|||
|
|
progress: { ...files[file.id].progress
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
delete files[file.id].progress.postprocess;
|
|||
|
|
this.setState({
|
|||
|
|
files
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
this.on('restored', () => {
|
|||
|
|
// Files may have changed--ensure progress is still accurate.
|
|||
|
|
this.calculateTotalProgress();
|
|||
|
|
});
|
|||
|
|
this.on('dashboard:file-edit-complete', file => {
|
|||
|
|
if (file) {
|
|||
|
|
_classPrivateFieldLooseBase$6(this, _checkRequiredMetaFieldsOnFile)[_checkRequiredMetaFieldsOnFile](file);
|
|||
|
|
}
|
|||
|
|
}); // show informer if offline
|
|||
|
|
|
|||
|
|
if (typeof window !== 'undefined' && window.addEventListener) {
|
|||
|
|
window.addEventListener('online', _classPrivateFieldLooseBase$6(this, _updateOnlineStatus)[_updateOnlineStatus]);
|
|||
|
|
window.addEventListener('offline', _classPrivateFieldLooseBase$6(this, _updateOnlineStatus)[_updateOnlineStatus]);
|
|||
|
|
setTimeout(_classPrivateFieldLooseBase$6(this, _updateOnlineStatus)[_updateOnlineStatus], 3000);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function _createUpload2(fileIDs, opts) {
|
|||
|
|
if (opts === void 0) {
|
|||
|
|
opts = {};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// uppy.retryAll sets this to true — when retrying we want to ignore `allowNewUpload: false`
|
|||
|
|
const {
|
|||
|
|
forceAllowNewUpload = false
|
|||
|
|
} = opts;
|
|||
|
|
const {
|
|||
|
|
allowNewUpload,
|
|||
|
|
currentUploads
|
|||
|
|
} = this.getState();
|
|||
|
|
|
|||
|
|
if (!allowNewUpload && !forceAllowNewUpload) {
|
|||
|
|
throw new Error('Cannot create a new upload: already uploading.');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const uploadID = nanoid$1();
|
|||
|
|
this.emit('upload', {
|
|||
|
|
id: uploadID,
|
|||
|
|
fileIDs
|
|||
|
|
});
|
|||
|
|
this.setState({
|
|||
|
|
allowNewUpload: this.opts.allowMultipleUploadBatches !== false && this.opts.allowMultipleUploads !== false,
|
|||
|
|
currentUploads: { ...currentUploads,
|
|||
|
|
[uploadID]: {
|
|||
|
|
fileIDs,
|
|||
|
|
step: 0,
|
|||
|
|
result: {}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
return uploadID;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function _getUpload2(uploadID) {
|
|||
|
|
const {
|
|||
|
|
currentUploads
|
|||
|
|
} = this.getState();
|
|||
|
|
return currentUploads[uploadID];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function _removeUpload2(uploadID) {
|
|||
|
|
const currentUploads = { ...this.getState().currentUploads
|
|||
|
|
};
|
|||
|
|
delete currentUploads[uploadID];
|
|||
|
|
this.setState({
|
|||
|
|
currentUploads
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
async function _runUpload2(uploadID) {
|
|||
|
|
let {
|
|||
|
|
currentUploads
|
|||
|
|
} = this.getState();
|
|||
|
|
let currentUpload = currentUploads[uploadID];
|
|||
|
|
const restoreStep = currentUpload.step || 0;
|
|||
|
|
const steps = [..._classPrivateFieldLooseBase$6(this, _preProcessors)[_preProcessors], ..._classPrivateFieldLooseBase$6(this, _uploaders)[_uploaders], ..._classPrivateFieldLooseBase$6(this, _postProcessors)[_postProcessors]];
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
for (let step = restoreStep; step < steps.length; step++) {
|
|||
|
|
if (!currentUpload) {
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const fn = steps[step];
|
|||
|
|
const updatedUpload = { ...currentUpload,
|
|||
|
|
step
|
|||
|
|
};
|
|||
|
|
this.setState({
|
|||
|
|
currentUploads: { ...currentUploads,
|
|||
|
|
[uploadID]: updatedUpload
|
|||
|
|
}
|
|||
|
|
}); // TODO give this the `updatedUpload` object as its only parameter maybe?
|
|||
|
|
// Otherwise when more metadata may be added to the upload this would keep getting more parameters
|
|||
|
|
|
|||
|
|
await fn(updatedUpload.fileIDs, uploadID); // Update currentUpload value in case it was modified asynchronously.
|
|||
|
|
|
|||
|
|
currentUploads = this.getState().currentUploads;
|
|||
|
|
currentUpload = currentUploads[uploadID];
|
|||
|
|
}
|
|||
|
|
} catch (err) {
|
|||
|
|
this.emit('error', err);
|
|||
|
|
|
|||
|
|
_classPrivateFieldLooseBase$6(this, _removeUpload)[_removeUpload](uploadID);
|
|||
|
|
|
|||
|
|
throw err;
|
|||
|
|
} // Set result data.
|
|||
|
|
|
|||
|
|
|
|||
|
|
if (currentUpload) {
|
|||
|
|
// Mark postprocessing step as complete if necessary; this addresses a case where we might get
|
|||
|
|
// stuck in the postprocessing UI while the upload is fully complete.
|
|||
|
|
// If the postprocessing steps do not do any work, they may not emit postprocessing events at
|
|||
|
|
// all, and never mark the postprocessing as complete. This is fine on its own but we
|
|||
|
|
// introduced code in the @uppy/core upload-success handler to prepare postprocessing progress
|
|||
|
|
// state if any postprocessors are registered. That is to avoid a "flash of completed state"
|
|||
|
|
// before the postprocessing plugins can emit events.
|
|||
|
|
//
|
|||
|
|
// So, just in case an upload with postprocessing plugins *has* completed *without* emitting
|
|||
|
|
// postprocessing completion, we do it instead.
|
|||
|
|
currentUpload.fileIDs.forEach(fileID => {
|
|||
|
|
const file = this.getFile(fileID);
|
|||
|
|
|
|||
|
|
if (file && file.progress.postprocess) {
|
|||
|
|
this.emit('postprocess-complete', file);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
const files = currentUpload.fileIDs.map(fileID => this.getFile(fileID));
|
|||
|
|
const successful = files.filter(file => !file.error);
|
|||
|
|
const failed = files.filter(file => file.error);
|
|||
|
|
await this.addResultData(uploadID, {
|
|||
|
|
successful,
|
|||
|
|
failed,
|
|||
|
|
uploadID
|
|||
|
|
}); // Update currentUpload value in case it was modified asynchronously.
|
|||
|
|
|
|||
|
|
currentUploads = this.getState().currentUploads;
|
|||
|
|
currentUpload = currentUploads[uploadID];
|
|||
|
|
} // Emit completion events.
|
|||
|
|
// This is in a separate function so that the `currentUploads` variable
|
|||
|
|
// always refers to the latest state. In the handler right above it refers
|
|||
|
|
// to an outdated object without the `.result` property.
|
|||
|
|
|
|||
|
|
|
|||
|
|
let result;
|
|||
|
|
|
|||
|
|
if (currentUpload) {
|
|||
|
|
result = currentUpload.result;
|
|||
|
|
this.emit('complete', result);
|
|||
|
|
|
|||
|
|
_classPrivateFieldLooseBase$6(this, _removeUpload)[_removeUpload](uploadID);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (result == null) {
|
|||
|
|
this.log(`Not setting result for an upload that has been removed: ${uploadID}`);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Uppy.VERSION = "2.1.3";
|
|||
|
|
var Uppy_1$1 = Uppy;
|
|||
|
|
|
|||
|
|
var preact = createCommonjsModule$1(function (module, exports) {
|
|||
|
|
var n,l,u,t,i,r,o,f,e={},c=[],s=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;function a(n,l){for(var u in l)n[u]=l[u];return n}function v(n){var l=n.parentNode;l&&l.removeChild(n);}function h(l,u,t){var i,r,o,f={};for(o in u)"key"==o?i=u[o]:"ref"==o?r=u[o]:f[o]=u[o];if(arguments.length>2&&(f.children=arguments.length>3?n.call(arguments,2):t),"function"==typeof l&&null!=l.defaultProps)for(o in l.defaultProps)void 0===f[o]&&(f[o]=l.defaultProps[o]);return p(l,f,i,r,null)}function p(n,t,i,r,o){var f={type:n,props:t,key:i,ref:r,__k:null,__:null,__b:0,__e:null,__d:void 0,__c:null,__h:null,constructor:void 0,__v:null==o?++u:o};return null==o&&null!=l.vnode&&l.vnode(f),f}function y(n){return n.children}function d(n,l){this.props=n,this.context=l;}function _(n,l){if(null==l)return n.__?_(n.__,n.__.__k.indexOf(n)+1):null;for(var u;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e)return u.__e;return "function"==typeof n.type?_(n):null}function k(n){var l,u;if(null!=(n=n.__)&&null!=n.__c){for(n.__e=n.__c.base=null,l=0;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e){n.__e=n.__c.base=u.__e;break}return k(n)}}function x(n){(!n.__d&&(n.__d=!0)&&i.push(n)&&!b.__r++||o!==l.debounceRendering)&&((o=l.debounceRendering)||r)(b);}function b(){for(var n;b.__r=i.length;)n=i.sort(function(n,l){return n.__v.__b-l.__v.__b}),i=[],n.some(function(n){var l,u,t,i,r,o;n.__d&&(r=(i=(l=n).__v).__e,(o=l.__P)&&(u=[],(t=a({},i)).__v=i.__v+1,I(o,i,t,l.__n,void 0!==o.ownerSVGElement,null!=i.__h?[r]:null,u,null==r?_(i):r,i.__h),T(u,i),i.__e!=r&&k(i)));});}function m(n,l,u,t,i,r,o,f,s,a){var v,h,d,k,x,b,m,A=t&&t.__k||c,P=A.length;for(u.__k=[],v=0;v<l.length;v++)if(null!=(k=u.__k[v]=null==(k=l[v])||"boolean"==typeof k?null:"string"==typeof k||"number"==typeof k||"bigint"==typeof k?p(null,k,null,null,k):Array.isArray(k)?p(y,{children:k},null,null,null):k.__b>0?p(k.type,k.props,k.key,null,k.__v):k)){if(k.__=u,k.__b=u.__b+1,null===(d=A[v])||d&&k.key==d.key&&k.type===d.type)A[v]=void 0;else for(h=0;h<P;h++){if((d=A[h])&&k.key==d.key&&k.type===d.type){A[h]=void 0;break}d=null;}I(n,k,d=d||e,i,r,o,f,s,a),x=k.__e,(h=k.ref)&&d.ref!=h&&(m||(m=[]),d.ref&&m.push(d.ref,null,k),m.push(h,k.__c||x,k)),null!=x?(null==b&&(b=x),"function"==typeof k.type&&k.__k===d.__k?k.__d=s=g(k,s,n):s=w(n,k,d,A,x,s),"function"==typeof u.type&&(u.__d=s)):s&&d.__e==s&&s.parentNode!=n&&(s=_(d));}for(u.__e=b,v=P;v--;)null!=A[v]&&("function"==typeof u.type&&null!=A[v].__e&&A[v].__e==u.__d&&(u.__d=_(t,v+1)),L(A[v],A[v]));if(m)for(v=0;v<m.length;v++)z(m[v],m[++v],m[++v]);}function g(n,l,u){for(var t,i=n.__k,r=0;i&&r<i.length;r++)(t=i[r])&&(t.__=n,l="function"==typeof t.type?g(t,l,u):w(u,t,t,i,t.__e,l));return l}function w(n,l,u,t,i,r){var o,f,e;if(void 0!==l.__d)o=l.__d,l.__d=void 0;else if(null==u||i!=r||null==i.parentNode)n:if(null==r||r.parentNode!==n)n.appendChild(i),o=null;else {for(f=r,e=0;(f=f.nextSibling)&&e<t.length;e+=2)if(f==i)break n;n.insertBefore(i,r),o=r;}return void 0!==o?o:i.nextSibling}function A(n,l,u,t,i){var r;for(r in u)"children"===r||"key"===r||r in l||C(n,r,null,u[r],t);for(r in l)i&&"function"!=typeof l[r]||"children"===r||"key"===r||"value"===r||"checked"===r||u[r]===l[r]||C(n,r,l[r],u[r],t);}function P(n,l,u){"-"===l[0]?n.setProperty(l,u):n[l]=null==u?"":"number"!=typeof u||s.test(l)?u:u+"px";}function C(n,l,u,t,i){var r;n:if("style"===l)if("string"==typeof u)n.style.cssText=u;else {if("string"==typeof t&&(n.style.cssText=t=""),t)for(l in t)u&&l in u||P(n.style,l,"");if(u)for(l in u)t&&u[l]===t[l]||P(n.style,l,u[l]);}else if("o"===l[0]&&"n"===l[1])r=l!==(l=l.replace(/Capture$/,"")),l=l.toLowerCase()in n?l.toLowerCase().slice(2):l.slice(2),n.l||(n.l={}),n.l[l+r]=u,u?t||n.addEventListener(l,r?H:$,r):n.removeEventListener(l,r?H:$,r);else if("dangerouslySetInnerHTML"!==l){if(i)l=l.replace(/xlink[H:h]/,"h").replace(/sName$/,"s");else if("href"!==l&&"list"!==l&&"form"!==l&&"tabIndex"!==l&&"download"!==l&&l in n)try{n[l]=null==u?"":u;break n}catch(n){}"function"==typeof u||(null!=u&&(!1!==u||"a"===l[0]&&"r"===l[1])?n.setAttribute(l,u):n.removeA
|
|||
|
|
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if an object is a DOM element. Duck-typing based on `nodeType`.
|
|||
|
|
*
|
|||
|
|
* @param {*} obj
|
|||
|
|
*/
|
|||
|
|
var isDOMElement = function isDOMElement(obj) {
|
|||
|
|
return (obj == null ? void 0 : obj.nodeType) === Node.ELEMENT_NODE;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Find a DOM element.
|
|||
|
|
*
|
|||
|
|
* @param {Node|string} element
|
|||
|
|
* @returns {Node|null}
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
var findDOMElement = function findDOMElement(element, context) {
|
|||
|
|
if (context === void 0) {
|
|||
|
|
context = document;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (typeof element === 'string') {
|
|||
|
|
return context.querySelector(element);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (isDOMElement(element)) {
|
|||
|
|
return element;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return null;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Core plugin logic that all plugins share.
|
|||
|
|
*
|
|||
|
|
* BasePlugin does not contain DOM rendering so it can be used for plugins
|
|||
|
|
* without a user interface.
|
|||
|
|
*
|
|||
|
|
* See `Plugin` for the extended version with Preact rendering for interfaces.
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
var BasePlugin_1$1 = class BasePlugin {
|
|||
|
|
constructor(uppy, opts) {
|
|||
|
|
if (opts === void 0) {
|
|||
|
|
opts = {};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
this.uppy = uppy;
|
|||
|
|
this.opts = opts;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
getPluginState() {
|
|||
|
|
const {
|
|||
|
|
plugins
|
|||
|
|
} = this.uppy.getState();
|
|||
|
|
return plugins[this.id] || {};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
setPluginState(update) {
|
|||
|
|
const {
|
|||
|
|
plugins
|
|||
|
|
} = this.uppy.getState();
|
|||
|
|
this.uppy.setState({
|
|||
|
|
plugins: { ...plugins,
|
|||
|
|
[this.id]: { ...plugins[this.id],
|
|||
|
|
...update
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
setOptions(newOpts) {
|
|||
|
|
this.opts = { ...this.opts,
|
|||
|
|
...newOpts
|
|||
|
|
};
|
|||
|
|
this.setPluginState(); // so that UI re-renders with new options
|
|||
|
|
|
|||
|
|
this.i18nInit();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
i18nInit() {
|
|||
|
|
const translator = new Translator_1([this.defaultLocale, this.uppy.locale, this.opts.locale]);
|
|||
|
|
this.i18n = translator.translate.bind(translator);
|
|||
|
|
this.i18nArray = translator.translateArray.bind(translator);
|
|||
|
|
this.setPluginState(); // so that UI re-renders and we see the updated locale
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Extendable methods
|
|||
|
|
* ==================
|
|||
|
|
* These methods are here to serve as an overview of the extendable methods as well as
|
|||
|
|
* making them not conditional in use, such as `if (this.afterUpdate)`.
|
|||
|
|
*/
|
|||
|
|
// eslint-disable-next-line class-methods-use-this
|
|||
|
|
|
|||
|
|
|
|||
|
|
addTarget() {
|
|||
|
|
throw new Error('Extend the addTarget method to add your plugin to another plugin\'s target');
|
|||
|
|
} // eslint-disable-next-line class-methods-use-this
|
|||
|
|
|
|||
|
|
|
|||
|
|
install() {} // eslint-disable-next-line class-methods-use-this
|
|||
|
|
|
|||
|
|
|
|||
|
|
uninstall() {}
|
|||
|
|
/**
|
|||
|
|
* Called when plugin is mounted, whether in DOM or into another plugin.
|
|||
|
|
* Needed because sometimes plugins are mounted separately/after `install`,
|
|||
|
|
* so this.el and this.parent might not be available in `install`.
|
|||
|
|
* This is the case with @uppy/react plugins, for example.
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
render() {
|
|||
|
|
throw new Error('Extend the render method to add your plugin to a DOM element');
|
|||
|
|
} // eslint-disable-next-line class-methods-use-this
|
|||
|
|
|
|||
|
|
|
|||
|
|
update() {} // Called after every state update, after everything's mounted. Debounced.
|
|||
|
|
// eslint-disable-next-line class-methods-use-this
|
|||
|
|
|
|||
|
|
|
|||
|
|
afterUpdate() {}
|
|||
|
|
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
function _classPrivateFieldLooseBase$5(receiver, privateKey) { if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) { throw new TypeError("attempted to use private field on non-instance"); } return receiver; }
|
|||
|
|
|
|||
|
|
var id$5 = 0;
|
|||
|
|
|
|||
|
|
function _classPrivateFieldLooseKey$5(name) { return "__private_" + id$5++ + "_" + name; }
|
|||
|
|
|
|||
|
|
const {
|
|||
|
|
render
|
|||
|
|
} = preact;
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Defer a frequent call to the microtask queue.
|
|||
|
|
*
|
|||
|
|
* @param {() => T} fn
|
|||
|
|
* @returns {Promise<T>}
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
function debounce(fn) {
|
|||
|
|
let calling = null;
|
|||
|
|
let latestArgs = null;
|
|||
|
|
return function () {
|
|||
|
|
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|||
|
|
args[_key] = arguments[_key];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
latestArgs = args;
|
|||
|
|
|
|||
|
|
if (!calling) {
|
|||
|
|
calling = Promise.resolve().then(() => {
|
|||
|
|
calling = null; // At this point `args` may be different from the most
|
|||
|
|
// recent state, if multiple calls happened since this task
|
|||
|
|
// was queued. So we use the `latestArgs`, which definitely
|
|||
|
|
// is the most recent call.
|
|||
|
|
|
|||
|
|
return fn(...latestArgs);
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return calling;
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* UIPlugin is the extended version of BasePlugin to incorporate rendering with Preact.
|
|||
|
|
* Use this for plugins that need a user interface.
|
|||
|
|
*
|
|||
|
|
* For plugins without an user interface, see BasePlugin.
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
var _updateUI = /*#__PURE__*/_classPrivateFieldLooseKey$5("updateUI");
|
|||
|
|
|
|||
|
|
class UIPlugin extends BasePlugin_1$1 {
|
|||
|
|
constructor() {
|
|||
|
|
super(...arguments);
|
|||
|
|
Object.defineProperty(this, _updateUI, {
|
|||
|
|
writable: true,
|
|||
|
|
value: void 0
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if supplied `target` is a DOM element or an `object`.
|
|||
|
|
* If it’s an object — target is a plugin, and we search `plugins`
|
|||
|
|
* for a plugin with same name and return its target.
|
|||
|
|
*/
|
|||
|
|
mount(target, plugin) {
|
|||
|
|
const callerPluginName = plugin.id;
|
|||
|
|
const targetElement = findDOMElement(target);
|
|||
|
|
|
|||
|
|
if (targetElement) {
|
|||
|
|
this.isTargetDOMEl = true; // When target is <body> with a single <div> element,
|
|||
|
|
// Preact thinks it’s the Uppy root element in there when doing a diff,
|
|||
|
|
// and destroys it. So we are creating a fragment (could be empty div)
|
|||
|
|
|
|||
|
|
const uppyRootElement = document.createDocumentFragment(); // API for plugins that require a synchronous rerender.
|
|||
|
|
|
|||
|
|
_classPrivateFieldLooseBase$5(this, _updateUI)[_updateUI] = debounce(state => {
|
|||
|
|
// plugin could be removed, but this.rerender is debounced below,
|
|||
|
|
// so it could still be called even after uppy.removePlugin or uppy.close
|
|||
|
|
// hence the check
|
|||
|
|
if (!this.uppy.getPlugin(this.id)) return;
|
|||
|
|
render(this.render(state), uppyRootElement);
|
|||
|
|
this.afterUpdate();
|
|||
|
|
});
|
|||
|
|
this.uppy.log(`Installing ${callerPluginName} to a DOM element '${target}'`);
|
|||
|
|
|
|||
|
|
if (this.opts.replaceTargetContent) {
|
|||
|
|
// Doing render(h(null), targetElement), which should have been
|
|||
|
|
// a better way, since because the component might need to do additional cleanup when it is removed,
|
|||
|
|
// stopped working — Preact just adds null into target, not replacing
|
|||
|
|
targetElement.innerHTML = '';
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
render(this.render(this.uppy.getState()), uppyRootElement);
|
|||
|
|
this.el = uppyRootElement.firstElementChild;
|
|||
|
|
targetElement.appendChild(uppyRootElement);
|
|||
|
|
this.onMount();
|
|||
|
|
return this.el;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
let targetPlugin;
|
|||
|
|
|
|||
|
|
if (typeof target === 'object' && target instanceof UIPlugin) {
|
|||
|
|
// Targeting a plugin *instance*
|
|||
|
|
targetPlugin = target;
|
|||
|
|
} else if (typeof target === 'function') {
|
|||
|
|
// Targeting a plugin type
|
|||
|
|
const Target = target; // Find the target plugin instance.
|
|||
|
|
|
|||
|
|
this.uppy.iteratePlugins(p => {
|
|||
|
|
if (p instanceof Target) {
|
|||
|
|
targetPlugin = p;
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (targetPlugin) {
|
|||
|
|
this.uppy.log(`Installing ${callerPluginName} to ${targetPlugin.id}`);
|
|||
|
|
this.parent = targetPlugin;
|
|||
|
|
this.el = targetPlugin.addTarget(plugin);
|
|||
|
|
this.onMount();
|
|||
|
|
return this.el;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
this.uppy.log(`Not installing ${callerPluginName}`);
|
|||
|
|
let message = `Invalid target option given to ${callerPluginName}.`;
|
|||
|
|
|
|||
|
|
if (typeof target === 'function') {
|
|||
|
|
message += ' The given target is not a Plugin class. ' + 'Please check that you\'re not specifying a React Component instead of a plugin. ' + 'If you are using @uppy/* packages directly, make sure you have only 1 version of @uppy/core installed: ' + 'run `npm ls @uppy/core` on the command line and verify that all the versions match and are deduped correctly.';
|
|||
|
|
} else {
|
|||
|
|
message += 'If you meant to target an HTML element, please make sure that the element exists. ' + 'Check that the <script> tag initializing Uppy is right before the closing </body> tag at the end of the page. ' + '(see https://github.com/transloadit/uppy/issues/1042)\n\n' + 'If you meant to target a plugin, please confirm that your `import` statements or `require` calls are correct.';
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
throw new Error(message);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
update(state) {
|
|||
|
|
if (this.el != null) {
|
|||
|
|
var _classPrivateFieldLoo, _classPrivateFieldLoo2;
|
|||
|
|
|
|||
|
|
(_classPrivateFieldLoo = (_classPrivateFieldLoo2 = _classPrivateFieldLooseBase$5(this, _updateUI))[_updateUI]) == null ? void 0 : _classPrivateFieldLoo.call(_classPrivateFieldLoo2, state);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
unmount() {
|
|||
|
|
if (this.isTargetDOMEl) {
|
|||
|
|
var _this$el;
|
|||
|
|
|
|||
|
|
(_this$el = this.el) == null ? void 0 : _this$el.remove();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
this.onUnmount();
|
|||
|
|
} // eslint-disable-next-line class-methods-use-this
|
|||
|
|
|
|||
|
|
|
|||
|
|
onMount() {} // eslint-disable-next-line class-methods-use-this
|
|||
|
|
|
|||
|
|
|
|||
|
|
onUnmount() {}
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var UIPlugin_1$1 = UIPlugin;
|
|||
|
|
|
|||
|
|
const {
|
|||
|
|
debugLogger
|
|||
|
|
} = loggers;
|
|||
|
|
|
|||
|
|
var lib$2 = Uppy_1$1;
|
|||
|
|
var Uppy_1 = Uppy_1$1;
|
|||
|
|
var UIPlugin_1 = UIPlugin_1$1;
|
|||
|
|
var BasePlugin_1 = BasePlugin_1$1;
|
|||
|
|
var debugLogger_1 = debugLogger;
|
|||
|
|
lib$2.Uppy = Uppy_1;
|
|||
|
|
lib$2.UIPlugin = UIPlugin_1;
|
|||
|
|
lib$2.BasePlugin = BasePlugin_1;
|
|||
|
|
lib$2.debugLogger = debugLogger_1;
|
|||
|
|
|
|||
|
|
class NetworkError extends Error {
|
|||
|
|
constructor(error, xhr) {
|
|||
|
|
if (xhr === void 0) {
|
|||
|
|
xhr = null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
super(`This looks like a network error, the endpoint might be blocked by an internet provider or a firewall.`);
|
|||
|
|
this.cause = error;
|
|||
|
|
this.isNetworkError = true;
|
|||
|
|
this.request = xhr;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var NetworkError_1 = NetworkError;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Wrapper around window.fetch that throws a NetworkError when appropriate
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
var fetchWithNetworkError = function fetchWithNetworkError() {
|
|||
|
|
return fetch(...arguments).catch(err => {
|
|||
|
|
if (err.name === 'AbortError') {
|
|||
|
|
throw err;
|
|||
|
|
} else {
|
|||
|
|
throw new NetworkError_1(err);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
class AuthError extends Error {
|
|||
|
|
constructor() {
|
|||
|
|
super('Authorization required');
|
|||
|
|
this.name = 'AuthError';
|
|||
|
|
this.isAuthError = true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var AuthError_1 = AuthError;
|
|||
|
|
|
|||
|
|
var _class$1, _getPostResponseFunc, _getUrl, _errorHandler, _temp$1;
|
|||
|
|
|
|||
|
|
function _classPrivateFieldLooseBase$4(receiver, privateKey) { if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) { throw new TypeError("attempted to use private field on non-instance"); } return receiver; }
|
|||
|
|
|
|||
|
|
var id$4 = 0;
|
|||
|
|
|
|||
|
|
function _classPrivateFieldLooseKey$4(name) { return "__private_" + id$4++ + "_" + name; }
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
// Remove the trailing slash so we can always safely append /xyz.
|
|||
|
|
|
|||
|
|
|
|||
|
|
function stripSlash(url) {
|
|||
|
|
return url.replace(/\/$/, '');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
async function handleJSONResponse(res) {
|
|||
|
|
if (res.status === 401) {
|
|||
|
|
throw new AuthError_1();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const jsonPromise = res.json();
|
|||
|
|
|
|||
|
|
if (res.status < 200 || res.status > 300) {
|
|||
|
|
let errMsg = `Failed request with status: ${res.status}. ${res.statusText}`;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
const errData = await jsonPromise;
|
|||
|
|
errMsg = errData.message ? `${errMsg} message: ${errData.message}` : errMsg;
|
|||
|
|
errMsg = errData.requestId ? `${errMsg} request-Id: ${errData.requestId}` : errMsg;
|
|||
|
|
} finally {
|
|||
|
|
// eslint-disable-next-line no-unsafe-finally
|
|||
|
|
throw new Error(errMsg);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return jsonPromise;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var RequestClient_1 = (_temp$1 = (_getPostResponseFunc = /*#__PURE__*/_classPrivateFieldLooseKey$4("getPostResponseFunc"), _getUrl = /*#__PURE__*/_classPrivateFieldLooseKey$4("getUrl"), _errorHandler = /*#__PURE__*/_classPrivateFieldLooseKey$4("errorHandler"), _class$1 = class RequestClient {
|
|||
|
|
// eslint-disable-next-line global-require
|
|||
|
|
constructor(uppy, opts) {
|
|||
|
|
Object.defineProperty(this, _errorHandler, {
|
|||
|
|
value: _errorHandler2
|
|||
|
|
});
|
|||
|
|
Object.defineProperty(this, _getUrl, {
|
|||
|
|
value: _getUrl2
|
|||
|
|
});
|
|||
|
|
Object.defineProperty(this, _getPostResponseFunc, {
|
|||
|
|
writable: true,
|
|||
|
|
value: skip => response => skip ? response : this.onReceiveResponse(response)
|
|||
|
|
});
|
|||
|
|
this.uppy = uppy;
|
|||
|
|
this.opts = opts;
|
|||
|
|
this.onReceiveResponse = this.onReceiveResponse.bind(this);
|
|||
|
|
this.allowedHeaders = ['accept', 'content-type', 'uppy-auth-token'];
|
|||
|
|
this.preflightDone = false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
get hostname() {
|
|||
|
|
const {
|
|||
|
|
companion
|
|||
|
|
} = this.uppy.getState();
|
|||
|
|
const host = this.opts.companionUrl;
|
|||
|
|
return stripSlash(companion && companion[host] ? companion[host] : host);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
headers() {
|
|||
|
|
const userHeaders = this.opts.companionHeaders || {};
|
|||
|
|
return Promise.resolve({ ...RequestClient.defaultHeaders,
|
|||
|
|
...userHeaders
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
onReceiveResponse(response) {
|
|||
|
|
const state = this.uppy.getState();
|
|||
|
|
const companion = state.companion || {};
|
|||
|
|
const host = this.opts.companionUrl;
|
|||
|
|
const {
|
|||
|
|
headers
|
|||
|
|
} = response; // Store the self-identified domain name for the Companion instance we just hit.
|
|||
|
|
|
|||
|
|
if (headers.has('i-am') && headers.get('i-am') !== companion[host]) {
|
|||
|
|
this.uppy.setState({
|
|||
|
|
companion: { ...companion,
|
|||
|
|
[host]: headers.get('i-am')
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return response;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
preflight(path) {
|
|||
|
|
if (this.preflightDone) {
|
|||
|
|
return Promise.resolve(this.allowedHeaders.slice());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return fetch(_classPrivateFieldLooseBase$4(this, _getUrl)[_getUrl](path), {
|
|||
|
|
method: 'OPTIONS'
|
|||
|
|
}).then(response => {
|
|||
|
|
if (response.headers.has('access-control-allow-headers')) {
|
|||
|
|
this.allowedHeaders = response.headers.get('access-control-allow-headers').split(',').map(headerName => headerName.trim().toLowerCase());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
this.preflightDone = true;
|
|||
|
|
return this.allowedHeaders.slice();
|
|||
|
|
}).catch(err => {
|
|||
|
|
this.uppy.log(`[CompanionClient] unable to make preflight request ${err}`, 'warning');
|
|||
|
|
this.preflightDone = true;
|
|||
|
|
return this.allowedHeaders.slice();
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
preflightAndHeaders(path) {
|
|||
|
|
return Promise.all([this.preflight(path), this.headers()]).then(_ref => {
|
|||
|
|
let [allowedHeaders, headers] = _ref;
|
|||
|
|
// filter to keep only allowed Headers
|
|||
|
|
Object.keys(headers).forEach(header => {
|
|||
|
|
if (!allowedHeaders.includes(header.toLowerCase())) {
|
|||
|
|
this.uppy.log(`[CompanionClient] excluding disallowed header ${header}`);
|
|||
|
|
delete headers[header]; // eslint-disable-line no-param-reassign
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
return headers;
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
get(path, skipPostResponse) {
|
|||
|
|
const method = 'get';
|
|||
|
|
return this.preflightAndHeaders(path).then(headers => fetchWithNetworkError(_classPrivateFieldLooseBase$4(this, _getUrl)[_getUrl](path), {
|
|||
|
|
method,
|
|||
|
|
headers,
|
|||
|
|
credentials: this.opts.companionCookiesRule || 'same-origin'
|
|||
|
|
})).then(_classPrivateFieldLooseBase$4(this, _getPostResponseFunc)[_getPostResponseFunc](skipPostResponse)).then(handleJSONResponse).catch(_classPrivateFieldLooseBase$4(this, _errorHandler)[_errorHandler](method, path));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
post(path, data, skipPostResponse) {
|
|||
|
|
const method = 'post';
|
|||
|
|
return this.preflightAndHeaders(path).then(headers => fetchWithNetworkError(_classPrivateFieldLooseBase$4(this, _getUrl)[_getUrl](path), {
|
|||
|
|
method,
|
|||
|
|
headers,
|
|||
|
|
credentials: this.opts.companionCookiesRule || 'same-origin',
|
|||
|
|
body: JSON.stringify(data)
|
|||
|
|
})).then(_classPrivateFieldLooseBase$4(this, _getPostResponseFunc)[_getPostResponseFunc](skipPostResponse)).then(handleJSONResponse).catch(_classPrivateFieldLooseBase$4(this, _errorHandler)[_errorHandler](method, path));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
delete(path, data, skipPostResponse) {
|
|||
|
|
const method = 'delete';
|
|||
|
|
return this.preflightAndHeaders(path).then(headers => fetchWithNetworkError(`${this.hostname}/${path}`, {
|
|||
|
|
method,
|
|||
|
|
headers,
|
|||
|
|
credentials: this.opts.companionCookiesRule || 'same-origin',
|
|||
|
|
body: data ? JSON.stringify(data) : null
|
|||
|
|
})).then(_classPrivateFieldLooseBase$4(this, _getPostResponseFunc)[_getPostResponseFunc](skipPostResponse)).then(handleJSONResponse).catch(_classPrivateFieldLooseBase$4(this, _errorHandler)[_errorHandler](method, path));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
}), _class$1.VERSION = "2.0.4", _class$1.defaultHeaders = {
|
|||
|
|
Accept: 'application/json',
|
|||
|
|
'Content-Type': 'application/json',
|
|||
|
|
'Uppy-Versions': `@uppy/companion-client=${_class$1.VERSION}`
|
|||
|
|
}, _temp$1);
|
|||
|
|
|
|||
|
|
function _getUrl2(url) {
|
|||
|
|
if (/^(https?:|)\/\//.test(url)) {
|
|||
|
|
return url;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return `${this.hostname}/${url}`;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function _errorHandler2(method, path) {
|
|||
|
|
return err => {
|
|||
|
|
var _err;
|
|||
|
|
|
|||
|
|
if (!((_err = err) != null && _err.isAuthError)) {
|
|||
|
|
const error = new Error(`Could not ${method} ${_classPrivateFieldLooseBase$4(this, _getUrl)[_getUrl](path)}`);
|
|||
|
|
error.cause = err;
|
|||
|
|
err = error; // eslint-disable-line no-param-reassign
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return Promise.reject(err);
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* This module serves as an Async wrapper for LocalStorage
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
var setItem = (key, value) => {
|
|||
|
|
return new Promise(resolve => {
|
|||
|
|
localStorage.setItem(key, value);
|
|||
|
|
resolve();
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var getItem = key => {
|
|||
|
|
return Promise.resolve(localStorage.getItem(key));
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var removeItem = key => {
|
|||
|
|
return new Promise(resolve => {
|
|||
|
|
localStorage.removeItem(key);
|
|||
|
|
resolve();
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var tokenStorage = {
|
|||
|
|
setItem: setItem,
|
|||
|
|
getItem: getItem,
|
|||
|
|
removeItem: removeItem
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const getName$1 = id => {
|
|||
|
|
return id.split('-').map(s => s.charAt(0).toUpperCase() + s.slice(1)).join(' ');
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var Provider_1 = class Provider extends RequestClient_1 {
|
|||
|
|
constructor(uppy, opts) {
|
|||
|
|
super(uppy, opts);
|
|||
|
|
this.provider = opts.provider;
|
|||
|
|
this.id = this.provider;
|
|||
|
|
this.name = this.opts.name || getName$1(this.id);
|
|||
|
|
this.pluginId = this.opts.pluginId;
|
|||
|
|
this.tokenKey = `companion-${this.pluginId}-auth-token`;
|
|||
|
|
this.companionKeysParams = this.opts.companionKeysParams;
|
|||
|
|
this.preAuthToken = null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
headers() {
|
|||
|
|
return Promise.all([super.headers(), this.getAuthToken()]).then(_ref => {
|
|||
|
|
let [headers, token] = _ref;
|
|||
|
|
const authHeaders = {};
|
|||
|
|
|
|||
|
|
if (token) {
|
|||
|
|
authHeaders['uppy-auth-token'] = token;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (this.companionKeysParams) {
|
|||
|
|
authHeaders['uppy-credentials-params'] = btoa(JSON.stringify({
|
|||
|
|
params: this.companionKeysParams
|
|||
|
|
}));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return { ...headers,
|
|||
|
|
...authHeaders
|
|||
|
|
};
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
onReceiveResponse(response) {
|
|||
|
|
response = super.onReceiveResponse(response);
|
|||
|
|
const plugin = this.uppy.getPlugin(this.pluginId);
|
|||
|
|
const oldAuthenticated = plugin.getPluginState().authenticated;
|
|||
|
|
const authenticated = oldAuthenticated ? response.status !== 401 : response.status < 400;
|
|||
|
|
plugin.setPluginState({
|
|||
|
|
authenticated
|
|||
|
|
});
|
|||
|
|
return response;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
setAuthToken(token) {
|
|||
|
|
return this.uppy.getPlugin(this.pluginId).storage.setItem(this.tokenKey, token);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
getAuthToken() {
|
|||
|
|
return this.uppy.getPlugin(this.pluginId).storage.getItem(this.tokenKey);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
authUrl(queries) {
|
|||
|
|
if (queries === void 0) {
|
|||
|
|
queries = {};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (this.preAuthToken) {
|
|||
|
|
queries.uppyPreAuthToken = this.preAuthToken;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return `${this.hostname}/${this.id}/connect?${new URLSearchParams(queries)}`;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
fileUrl(id) {
|
|||
|
|
return `${this.hostname}/${this.id}/get/${id}`;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
fetchPreAuthToken() {
|
|||
|
|
if (!this.companionKeysParams) {
|
|||
|
|
return Promise.resolve();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return this.post(`${this.id}/preauth/`, {
|
|||
|
|
params: this.companionKeysParams
|
|||
|
|
}).then(res => {
|
|||
|
|
this.preAuthToken = res.token;
|
|||
|
|
}).catch(err => {
|
|||
|
|
this.uppy.log(`[CompanionClient] unable to fetch preAuthToken ${err}`, 'warning');
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
list(directory) {
|
|||
|
|
return this.get(`${this.id}/list/${directory || ''}`);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
logout() {
|
|||
|
|
return this.get(`${this.id}/logout`).then(response => Promise.all([response, this.uppy.getPlugin(this.pluginId).storage.removeItem(this.tokenKey)])).then(_ref2 => {
|
|||
|
|
let [response] = _ref2;
|
|||
|
|
return response;
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static initPlugin(plugin, opts, defaultOpts) {
|
|||
|
|
plugin.type = 'acquirer';
|
|||
|
|
plugin.files = [];
|
|||
|
|
|
|||
|
|
if (defaultOpts) {
|
|||
|
|
plugin.opts = { ...defaultOpts,
|
|||
|
|
...opts
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (opts.serverUrl || opts.serverPattern) {
|
|||
|
|
throw new Error('`serverUrl` and `serverPattern` have been renamed to `companionUrl` and `companionAllowedHosts` respectively in the 0.30.5 release. Please consult the docs (for example, https://uppy.io/docs/instagram/ for the Instagram plugin) and use the updated options.`');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (opts.companionAllowedHosts) {
|
|||
|
|
const pattern = opts.companionAllowedHosts; // validate companionAllowedHosts param
|
|||
|
|
|
|||
|
|
if (typeof pattern !== 'string' && !Array.isArray(pattern) && !(pattern instanceof RegExp)) {
|
|||
|
|
throw new TypeError(`${plugin.id}: the option "companionAllowedHosts" must be one of string, Array, RegExp`);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
plugin.opts.companionAllowedHosts = pattern;
|
|||
|
|
} else if (/^(?!https?:\/\/).*$/i.test(opts.companionUrl)) {
|
|||
|
|
// does not start with https://
|
|||
|
|
plugin.opts.companionAllowedHosts = `https://${opts.companionUrl.replace(/^\/\//, '')}`;
|
|||
|
|
} else {
|
|||
|
|
plugin.opts.companionAllowedHosts = new URL(opts.companionUrl).origin;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
plugin.storage = plugin.opts.storage || tokenStorage;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const getName = id => {
|
|||
|
|
return id.split('-').map(s => s.charAt(0).toUpperCase() + s.slice(1)).join(' ');
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var SearchProvider_1 = class SearchProvider extends RequestClient_1 {
|
|||
|
|
constructor(uppy, opts) {
|
|||
|
|
super(uppy, opts);
|
|||
|
|
this.provider = opts.provider;
|
|||
|
|
this.id = this.provider;
|
|||
|
|
this.name = this.opts.name || getName(this.id);
|
|||
|
|
this.pluginId = this.opts.pluginId;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
fileUrl(id) {
|
|||
|
|
return `${this.hostname}/search/${this.id}/get/${id}`;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
search(text, queries) {
|
|||
|
|
queries = queries ? `&${queries}` : '';
|
|||
|
|
return this.get(`search/${this.id}/list?q=${encodeURIComponent(text)}${queries}`);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var _queued, _emitter$1, _isOpen, _socket, _handleMessage;
|
|||
|
|
|
|||
|
|
let _Symbol$for, _Symbol$for2;
|
|||
|
|
|
|||
|
|
function _classPrivateFieldLooseBase$3(receiver, privateKey) { if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) { throw new TypeError("attempted to use private field on non-instance"); } return receiver; }
|
|||
|
|
|
|||
|
|
var id$3 = 0;
|
|||
|
|
|
|||
|
|
function _classPrivateFieldLooseKey$3(name) { return "__private_" + id$3++ + "_" + name; }
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
var Socket$1 = (_queued = /*#__PURE__*/_classPrivateFieldLooseKey$3("queued"), _emitter$1 = /*#__PURE__*/_classPrivateFieldLooseKey$3("emitter"), _isOpen = /*#__PURE__*/_classPrivateFieldLooseKey$3("isOpen"), _socket = /*#__PURE__*/_classPrivateFieldLooseKey$3("socket"), _handleMessage = /*#__PURE__*/_classPrivateFieldLooseKey$3("handleMessage"), _Symbol$for = Symbol.for('uppy test: getSocket'), _Symbol$for2 = Symbol.for('uppy test: getQueued'), class UppySocket {
|
|||
|
|
constructor(opts) {
|
|||
|
|
Object.defineProperty(this, _queued, {
|
|||
|
|
writable: true,
|
|||
|
|
value: []
|
|||
|
|
});
|
|||
|
|
Object.defineProperty(this, _emitter$1, {
|
|||
|
|
writable: true,
|
|||
|
|
value: namespaceEmitter()
|
|||
|
|
});
|
|||
|
|
Object.defineProperty(this, _isOpen, {
|
|||
|
|
writable: true,
|
|||
|
|
value: false
|
|||
|
|
});
|
|||
|
|
Object.defineProperty(this, _socket, {
|
|||
|
|
writable: true,
|
|||
|
|
value: void 0
|
|||
|
|
});
|
|||
|
|
Object.defineProperty(this, _handleMessage, {
|
|||
|
|
writable: true,
|
|||
|
|
value: e => {
|
|||
|
|
try {
|
|||
|
|
const message = JSON.parse(e.data);
|
|||
|
|
this.emit(message.action, message.payload);
|
|||
|
|
} catch (err) {
|
|||
|
|
// TODO: use a more robust error handler.
|
|||
|
|
console.log(err); // eslint-disable-line no-console
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
this.opts = opts;
|
|||
|
|
|
|||
|
|
if (!opts || opts.autoOpen !== false) {
|
|||
|
|
this.open();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
get isOpen() {
|
|||
|
|
return _classPrivateFieldLooseBase$3(this, _isOpen)[_isOpen];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
[_Symbol$for]() {
|
|||
|
|
return _classPrivateFieldLooseBase$3(this, _socket)[_socket];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
[_Symbol$for2]() {
|
|||
|
|
return _classPrivateFieldLooseBase$3(this, _queued)[_queued];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
open() {
|
|||
|
|
_classPrivateFieldLooseBase$3(this, _socket)[_socket] = new WebSocket(this.opts.target);
|
|||
|
|
|
|||
|
|
_classPrivateFieldLooseBase$3(this, _socket)[_socket].onopen = () => {
|
|||
|
|
_classPrivateFieldLooseBase$3(this, _isOpen)[_isOpen] = true;
|
|||
|
|
|
|||
|
|
while (_classPrivateFieldLooseBase$3(this, _queued)[_queued].length > 0 && _classPrivateFieldLooseBase$3(this, _isOpen)[_isOpen]) {
|
|||
|
|
const first = _classPrivateFieldLooseBase$3(this, _queued)[_queued].shift();
|
|||
|
|
|
|||
|
|
this.send(first.action, first.payload);
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
_classPrivateFieldLooseBase$3(this, _socket)[_socket].onclose = () => {
|
|||
|
|
_classPrivateFieldLooseBase$3(this, _isOpen)[_isOpen] = false;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
_classPrivateFieldLooseBase$3(this, _socket)[_socket].onmessage = _classPrivateFieldLooseBase$3(this, _handleMessage)[_handleMessage];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
close() {
|
|||
|
|
var _classPrivateFieldLoo;
|
|||
|
|
|
|||
|
|
(_classPrivateFieldLoo = _classPrivateFieldLooseBase$3(this, _socket)[_socket]) == null ? void 0 : _classPrivateFieldLoo.close();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
send(action, payload) {
|
|||
|
|
// attach uuid
|
|||
|
|
if (!_classPrivateFieldLooseBase$3(this, _isOpen)[_isOpen]) {
|
|||
|
|
_classPrivateFieldLooseBase$3(this, _queued)[_queued].push({
|
|||
|
|
action,
|
|||
|
|
payload
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
_classPrivateFieldLooseBase$3(this, _socket)[_socket].send(JSON.stringify({
|
|||
|
|
action,
|
|||
|
|
payload
|
|||
|
|
}));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
on(action, handler) {
|
|||
|
|
_classPrivateFieldLooseBase$3(this, _emitter$1)[_emitter$1].on(action, handler);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
emit(action, payload) {
|
|||
|
|
_classPrivateFieldLooseBase$3(this, _emitter$1)[_emitter$1].emit(action, payload);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
once(action, handler) {
|
|||
|
|
_classPrivateFieldLooseBase$3(this, _emitter$1)[_emitter$1].once(action, handler);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Manages communications with Companion
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
var lib$1 = {
|
|||
|
|
RequestClient: RequestClient_1,
|
|||
|
|
Provider: Provider_1,
|
|||
|
|
SearchProvider: SearchProvider_1,
|
|||
|
|
Socket: Socket$1
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
function emitSocketProgress(uploader, progressData, file) {
|
|||
|
|
const {
|
|||
|
|
progress,
|
|||
|
|
bytesUploaded,
|
|||
|
|
bytesTotal
|
|||
|
|
} = progressData;
|
|||
|
|
|
|||
|
|
if (progress) {
|
|||
|
|
uploader.uppy.log(`Upload progress: ${progress}`);
|
|||
|
|
uploader.uppy.emit('upload-progress', file, {
|
|||
|
|
uploader,
|
|||
|
|
bytesUploaded,
|
|||
|
|
bytesTotal
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var emitSocketProgress_1 = lodash_throttle(emitSocketProgress, 300, {
|
|||
|
|
leading: true,
|
|||
|
|
trailing: true
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
var getSocketHost = function getSocketHost(url) {
|
|||
|
|
// get the host domain
|
|||
|
|
const regex = /^(?:https?:\/\/|\/\/)?(?:[^@\n]+@)?(?:www\.)?([^\n]+)/i;
|
|||
|
|
const host = regex.exec(url)[1];
|
|||
|
|
const socketProtocol = /^http:\/\//i.test(url) ? 'ws' : 'wss';
|
|||
|
|
return `${socketProtocol}://${host}`;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var settle = function settle(promises) {
|
|||
|
|
const resolutions = [];
|
|||
|
|
const rejections = [];
|
|||
|
|
|
|||
|
|
function resolved(value) {
|
|||
|
|
resolutions.push(value);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function rejected(error) {
|
|||
|
|
rejections.push(error);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const wait = Promise.all(promises.map(promise => promise.then(resolved, rejected)));
|
|||
|
|
return wait.then(() => {
|
|||
|
|
return {
|
|||
|
|
successful: resolutions,
|
|||
|
|
failed: rejections
|
|||
|
|
};
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var _emitter, _events;
|
|||
|
|
|
|||
|
|
function _classPrivateFieldLooseBase$2(receiver, privateKey) { if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) { throw new TypeError("attempted to use private field on non-instance"); } return receiver; }
|
|||
|
|
|
|||
|
|
var id$2 = 0;
|
|||
|
|
|
|||
|
|
function _classPrivateFieldLooseKey$2(name) { return "__private_" + id$2++ + "_" + name; }
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Create a wrapper around an event emitter with a `remove` method to remove
|
|||
|
|
* all events that were added using the wrapped emitter.
|
|||
|
|
*/
|
|||
|
|
var EventTracker_1 = (_emitter = /*#__PURE__*/_classPrivateFieldLooseKey$2("emitter"), _events = /*#__PURE__*/_classPrivateFieldLooseKey$2("events"), class EventTracker {
|
|||
|
|
constructor(emitter) {
|
|||
|
|
Object.defineProperty(this, _emitter, {
|
|||
|
|
writable: true,
|
|||
|
|
value: void 0
|
|||
|
|
});
|
|||
|
|
Object.defineProperty(this, _events, {
|
|||
|
|
writable: true,
|
|||
|
|
value: []
|
|||
|
|
});
|
|||
|
|
_classPrivateFieldLooseBase$2(this, _emitter)[_emitter] = emitter;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
on(event, fn) {
|
|||
|
|
_classPrivateFieldLooseBase$2(this, _events)[_events].push([event, fn]);
|
|||
|
|
|
|||
|
|
return _classPrivateFieldLooseBase$2(this, _emitter)[_emitter].on(event, fn);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
remove() {
|
|||
|
|
for (const [event, fn] of _classPrivateFieldLooseBase$2(this, _events)[_events].splice(0)) {
|
|||
|
|
_classPrivateFieldLooseBase$2(this, _emitter)[_emitter].off(event, fn);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
function _classPrivateFieldLooseBase$1(receiver, privateKey) { if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) { throw new TypeError("attempted to use private field on non-instance"); } return receiver; }
|
|||
|
|
|
|||
|
|
var id$1 = 0;
|
|||
|
|
|
|||
|
|
function _classPrivateFieldLooseKey$1(name) { return "__private_" + id$1++ + "_" + name; }
|
|||
|
|
|
|||
|
|
var _aliveTimer = /*#__PURE__*/_classPrivateFieldLooseKey$1("aliveTimer");
|
|||
|
|
|
|||
|
|
var _isDone = /*#__PURE__*/_classPrivateFieldLooseKey$1("isDone");
|
|||
|
|
|
|||
|
|
var _onTimedOut = /*#__PURE__*/_classPrivateFieldLooseKey$1("onTimedOut");
|
|||
|
|
|
|||
|
|
var _timeout = /*#__PURE__*/_classPrivateFieldLooseKey$1("timeout");
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Helper to abort upload requests if there has not been any progress for `timeout` ms.
|
|||
|
|
* Create an instance using `timer = new ProgressTimeout(10000, onTimeout)`
|
|||
|
|
* Call `timer.progress()` to signal that there has been progress of any kind.
|
|||
|
|
* Call `timer.done()` when the upload has completed.
|
|||
|
|
*/
|
|||
|
|
class ProgressTimeout {
|
|||
|
|
constructor(timeout, timeoutHandler) {
|
|||
|
|
Object.defineProperty(this, _aliveTimer, {
|
|||
|
|
writable: true,
|
|||
|
|
value: void 0
|
|||
|
|
});
|
|||
|
|
Object.defineProperty(this, _isDone, {
|
|||
|
|
writable: true,
|
|||
|
|
value: false
|
|||
|
|
});
|
|||
|
|
Object.defineProperty(this, _onTimedOut, {
|
|||
|
|
writable: true,
|
|||
|
|
value: void 0
|
|||
|
|
});
|
|||
|
|
Object.defineProperty(this, _timeout, {
|
|||
|
|
writable: true,
|
|||
|
|
value: void 0
|
|||
|
|
});
|
|||
|
|
_classPrivateFieldLooseBase$1(this, _timeout)[_timeout] = timeout;
|
|||
|
|
_classPrivateFieldLooseBase$1(this, _onTimedOut)[_onTimedOut] = timeoutHandler;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
progress() {
|
|||
|
|
// Some browsers fire another progress event when the upload is
|
|||
|
|
// cancelled, so we have to ignore progress after the timer was
|
|||
|
|
// told to stop.
|
|||
|
|
if (_classPrivateFieldLooseBase$1(this, _isDone)[_isDone]) return;
|
|||
|
|
|
|||
|
|
if (_classPrivateFieldLooseBase$1(this, _timeout)[_timeout] > 0) {
|
|||
|
|
clearTimeout(_classPrivateFieldLooseBase$1(this, _aliveTimer)[_aliveTimer]);
|
|||
|
|
_classPrivateFieldLooseBase$1(this, _aliveTimer)[_aliveTimer] = setTimeout(_classPrivateFieldLooseBase$1(this, _onTimedOut)[_onTimedOut], _classPrivateFieldLooseBase$1(this, _timeout)[_timeout]);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
done() {
|
|||
|
|
if (!_classPrivateFieldLooseBase$1(this, _isDone)[_isDone]) {
|
|||
|
|
clearTimeout(_classPrivateFieldLooseBase$1(this, _aliveTimer)[_aliveTimer]);
|
|||
|
|
_classPrivateFieldLooseBase$1(this, _aliveTimer)[_aliveTimer] = null;
|
|||
|
|
_classPrivateFieldLooseBase$1(this, _isDone)[_isDone] = true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var ProgressTimeout_1 = ProgressTimeout;
|
|||
|
|
|
|||
|
|
function _classPrivateFieldLooseBase(receiver, privateKey) { if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) { throw new TypeError("attempted to use private field on non-instance"); } return receiver; }
|
|||
|
|
|
|||
|
|
var id = 0;
|
|||
|
|
|
|||
|
|
function _classPrivateFieldLooseKey(name) { return "__private_" + id++ + "_" + name; }
|
|||
|
|
|
|||
|
|
function createCancelError() {
|
|||
|
|
return new Error('Cancelled');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var _activeRequests = /*#__PURE__*/_classPrivateFieldLooseKey("activeRequests");
|
|||
|
|
|
|||
|
|
var _queuedHandlers = /*#__PURE__*/_classPrivateFieldLooseKey("queuedHandlers");
|
|||
|
|
|
|||
|
|
var _call = /*#__PURE__*/_classPrivateFieldLooseKey("call");
|
|||
|
|
|
|||
|
|
var _queueNext = /*#__PURE__*/_classPrivateFieldLooseKey("queueNext");
|
|||
|
|
|
|||
|
|
var _next = /*#__PURE__*/_classPrivateFieldLooseKey("next");
|
|||
|
|
|
|||
|
|
var _queue = /*#__PURE__*/_classPrivateFieldLooseKey("queue");
|
|||
|
|
|
|||
|
|
var _dequeue = /*#__PURE__*/_classPrivateFieldLooseKey("dequeue");
|
|||
|
|
|
|||
|
|
class RateLimitedQueue$1 {
|
|||
|
|
constructor(limit) {
|
|||
|
|
Object.defineProperty(this, _dequeue, {
|
|||
|
|
value: _dequeue2
|
|||
|
|
});
|
|||
|
|
Object.defineProperty(this, _queue, {
|
|||
|
|
value: _queue2
|
|||
|
|
});
|
|||
|
|
Object.defineProperty(this, _next, {
|
|||
|
|
value: _next2
|
|||
|
|
});
|
|||
|
|
Object.defineProperty(this, _queueNext, {
|
|||
|
|
value: _queueNext2
|
|||
|
|
});
|
|||
|
|
Object.defineProperty(this, _call, {
|
|||
|
|
value: _call2
|
|||
|
|
});
|
|||
|
|
Object.defineProperty(this, _activeRequests, {
|
|||
|
|
writable: true,
|
|||
|
|
value: 0
|
|||
|
|
});
|
|||
|
|
Object.defineProperty(this, _queuedHandlers, {
|
|||
|
|
writable: true,
|
|||
|
|
value: []
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
if (typeof limit !== 'number' || limit === 0) {
|
|||
|
|
this.limit = Infinity;
|
|||
|
|
} else {
|
|||
|
|
this.limit = limit;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
run(fn, queueOptions) {
|
|||
|
|
if (_classPrivateFieldLooseBase(this, _activeRequests)[_activeRequests] < this.limit) {
|
|||
|
|
return _classPrivateFieldLooseBase(this, _call)[_call](fn);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return _classPrivateFieldLooseBase(this, _queue)[_queue](fn, queueOptions);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
wrapPromiseFunction(fn, queueOptions) {
|
|||
|
|
var _this = this;
|
|||
|
|
|
|||
|
|
return function () {
|
|||
|
|
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|||
|
|
args[_key] = arguments[_key];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
let queuedRequest;
|
|||
|
|
const outerPromise = new Promise((resolve, reject) => {
|
|||
|
|
queuedRequest = _this.run(() => {
|
|||
|
|
let cancelError;
|
|||
|
|
let innerPromise;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
innerPromise = Promise.resolve(fn(...args));
|
|||
|
|
} catch (err) {
|
|||
|
|
innerPromise = Promise.reject(err);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
innerPromise.then(result => {
|
|||
|
|
if (cancelError) {
|
|||
|
|
reject(cancelError);
|
|||
|
|
} else {
|
|||
|
|
queuedRequest.done();
|
|||
|
|
resolve(result);
|
|||
|
|
}
|
|||
|
|
}, err => {
|
|||
|
|
if (cancelError) {
|
|||
|
|
reject(cancelError);
|
|||
|
|
} else {
|
|||
|
|
queuedRequest.done();
|
|||
|
|
reject(err);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
return () => {
|
|||
|
|
cancelError = createCancelError();
|
|||
|
|
};
|
|||
|
|
}, queueOptions);
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
outerPromise.abort = () => {
|
|||
|
|
queuedRequest.abort();
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
return outerPromise;
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function _call2(fn) {
|
|||
|
|
_classPrivateFieldLooseBase(this, _activeRequests)[_activeRequests] += 1;
|
|||
|
|
let done = false;
|
|||
|
|
let cancelActive;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
cancelActive = fn();
|
|||
|
|
} catch (err) {
|
|||
|
|
_classPrivateFieldLooseBase(this, _activeRequests)[_activeRequests] -= 1;
|
|||
|
|
throw err;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return {
|
|||
|
|
abort: () => {
|
|||
|
|
if (done) return;
|
|||
|
|
done = true;
|
|||
|
|
_classPrivateFieldLooseBase(this, _activeRequests)[_activeRequests] -= 1;
|
|||
|
|
cancelActive();
|
|||
|
|
|
|||
|
|
_classPrivateFieldLooseBase(this, _queueNext)[_queueNext]();
|
|||
|
|
},
|
|||
|
|
done: () => {
|
|||
|
|
if (done) return;
|
|||
|
|
done = true;
|
|||
|
|
_classPrivateFieldLooseBase(this, _activeRequests)[_activeRequests] -= 1;
|
|||
|
|
|
|||
|
|
_classPrivateFieldLooseBase(this, _queueNext)[_queueNext]();
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function _queueNext2() {
|
|||
|
|
// Do it soon but not immediately, this allows clearing out the entire queue synchronously
|
|||
|
|
// one by one without continuously _advancing_ it (and starting new tasks before immediately
|
|||
|
|
// aborting them)
|
|||
|
|
queueMicrotask(() => _classPrivateFieldLooseBase(this, _next)[_next]());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function _next2() {
|
|||
|
|
if (_classPrivateFieldLooseBase(this, _activeRequests)[_activeRequests] >= this.limit) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (_classPrivateFieldLooseBase(this, _queuedHandlers)[_queuedHandlers].length === 0) {
|
|||
|
|
return;
|
|||
|
|
} // Dispatch the next request, and update the abort/done handlers
|
|||
|
|
// so that cancelling it does the Right Thing (and doesn't just try
|
|||
|
|
// to dequeue an already-running request).
|
|||
|
|
|
|||
|
|
|
|||
|
|
const next = _classPrivateFieldLooseBase(this, _queuedHandlers)[_queuedHandlers].shift();
|
|||
|
|
|
|||
|
|
const handler = _classPrivateFieldLooseBase(this, _call)[_call](next.fn);
|
|||
|
|
|
|||
|
|
next.abort = handler.abort;
|
|||
|
|
next.done = handler.done;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function _queue2(fn, options) {
|
|||
|
|
if (options === void 0) {
|
|||
|
|
options = {};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const handler = {
|
|||
|
|
fn,
|
|||
|
|
priority: options.priority || 0,
|
|||
|
|
abort: () => {
|
|||
|
|
_classPrivateFieldLooseBase(this, _dequeue)[_dequeue](handler);
|
|||
|
|
},
|
|||
|
|
done: () => {
|
|||
|
|
throw new Error('Cannot mark a queued request as done: this indicates a bug');
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const index = _classPrivateFieldLooseBase(this, _queuedHandlers)[_queuedHandlers].findIndex(other => {
|
|||
|
|
return handler.priority > other.priority;
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
if (index === -1) {
|
|||
|
|
_classPrivateFieldLooseBase(this, _queuedHandlers)[_queuedHandlers].push(handler);
|
|||
|
|
} else {
|
|||
|
|
_classPrivateFieldLooseBase(this, _queuedHandlers)[_queuedHandlers].splice(index, 0, handler);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return handler;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function _dequeue2(handler) {
|
|||
|
|
const index = _classPrivateFieldLooseBase(this, _queuedHandlers)[_queuedHandlers].indexOf(handler);
|
|||
|
|
|
|||
|
|
if (index !== -1) {
|
|||
|
|
_classPrivateFieldLooseBase(this, _queuedHandlers)[_queuedHandlers].splice(index, 1);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var RateLimitedQueue_1 = {
|
|||
|
|
RateLimitedQueue: RateLimitedQueue$1,
|
|||
|
|
internalRateLimitedQueue: Symbol('__queue')
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
function isNetworkError(xhr) {
|
|||
|
|
if (!xhr) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return xhr.readyState !== 0 && xhr.readyState !== 4 || xhr.status === 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var isNetworkError_1 = isNetworkError;
|
|||
|
|
|
|||
|
|
var locale = {
|
|||
|
|
strings: {
|
|||
|
|
// Shown in the Informer if an upload is being canceled because it stalled for too long.
|
|||
|
|
timedOut: 'Upload stalled for %{seconds} seconds, aborting.'
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var _class, _temp;
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
const {
|
|||
|
|
nanoid
|
|||
|
|
} = require$$4;
|
|||
|
|
|
|||
|
|
const {
|
|||
|
|
Provider,
|
|||
|
|
RequestClient,
|
|||
|
|
Socket
|
|||
|
|
} = lib$1;
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
const {
|
|||
|
|
RateLimitedQueue,
|
|||
|
|
internalRateLimitedQueue
|
|||
|
|
} = RateLimitedQueue_1;
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
function buildResponseError(xhr, err) {
|
|||
|
|
let error = err; // No error message
|
|||
|
|
|
|||
|
|
if (!error) error = new Error('Upload error'); // Got an error message string
|
|||
|
|
|
|||
|
|
if (typeof error === 'string') error = new Error(error); // Got something else
|
|||
|
|
|
|||
|
|
if (!(error instanceof Error)) {
|
|||
|
|
error = Object.assign(new Error('Upload error'), {
|
|||
|
|
data: error
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (isNetworkError_1(xhr)) {
|
|||
|
|
error = new NetworkError_1(error, xhr);
|
|||
|
|
return error;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
error.request = xhr;
|
|||
|
|
return error;
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Set `data.type` in the blob to `file.meta.type`,
|
|||
|
|
* because we might have detected a more accurate file type in Uppy
|
|||
|
|
* https://stackoverflow.com/a/50875615
|
|||
|
|
*
|
|||
|
|
* @param {object} file File object with `data`, `size` and `meta` properties
|
|||
|
|
* @returns {object} blob updated with the new `type` set from `file.meta.type`
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
function setTypeInBlob(file) {
|
|||
|
|
const dataWithUpdatedType = file.data.slice(0, file.data.size, file.meta.type);
|
|||
|
|
return dataWithUpdatedType;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var lib = (_temp = _class = class XHRUpload extends BasePlugin_1$1 {
|
|||
|
|
// eslint-disable-next-line global-require
|
|||
|
|
constructor(uppy, opts) {
|
|||
|
|
super(uppy, opts);
|
|||
|
|
this.type = 'uploader';
|
|||
|
|
this.id = this.opts.id || 'XHRUpload';
|
|||
|
|
this.title = 'XHRUpload';
|
|||
|
|
this.defaultLocale = locale; // Default options
|
|||
|
|
|
|||
|
|
const defaultOptions = {
|
|||
|
|
formData: true,
|
|||
|
|
fieldName: opts.bundle ? 'files[]' : 'file',
|
|||
|
|
method: 'post',
|
|||
|
|
metaFields: null,
|
|||
|
|
responseUrlFieldName: 'url',
|
|||
|
|
bundle: false,
|
|||
|
|
headers: {},
|
|||
|
|
timeout: 30 * 1000,
|
|||
|
|
limit: 5,
|
|||
|
|
withCredentials: false,
|
|||
|
|
responseType: '',
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @typedef respObj
|
|||
|
|
* @property {string} responseText
|
|||
|
|
* @property {number} status
|
|||
|
|
* @property {string} statusText
|
|||
|
|
* @property {object.<string, string>} headers
|
|||
|
|
*
|
|||
|
|
* @param {string} responseText the response body string
|
|||
|
|
* @param {XMLHttpRequest | respObj} response the response object (XHR or similar)
|
|||
|
|
*/
|
|||
|
|
getResponseData(responseText) {
|
|||
|
|
let parsedResponse = {};
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
parsedResponse = JSON.parse(responseText);
|
|||
|
|
} catch (err) {
|
|||
|
|
uppy.log(err);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return parsedResponse;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
*
|
|||
|
|
* @param {string} responseText the response body string
|
|||
|
|
* @param {XMLHttpRequest | respObj} response the response object (XHR or similar)
|
|||
|
|
*/
|
|||
|
|
getResponseError(_, response) {
|
|||
|
|
let error = new Error('Upload error');
|
|||
|
|
|
|||
|
|
if (isNetworkError_1(response)) {
|
|||
|
|
error = new NetworkError_1(error, response);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return error;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Check if the response from the upload endpoint indicates that the upload was successful.
|
|||
|
|
*
|
|||
|
|
* @param {number} status the response status code
|
|||
|
|
*/
|
|||
|
|
validateStatus(status) {
|
|||
|
|
return status >= 200 && status < 300;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
};
|
|||
|
|
this.opts = { ...defaultOptions,
|
|||
|
|
...opts
|
|||
|
|
};
|
|||
|
|
this.i18nInit();
|
|||
|
|
this.handleUpload = this.handleUpload.bind(this); // Simultaneous upload limiting is shared across all uploads with this plugin.
|
|||
|
|
|
|||
|
|
if (internalRateLimitedQueue in this.opts) {
|
|||
|
|
this.requests = this.opts[internalRateLimitedQueue];
|
|||
|
|
} else {
|
|||
|
|
this.requests = new RateLimitedQueue(this.opts.limit);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (this.opts.bundle && !this.opts.formData) {
|
|||
|
|
throw new Error('`opts.formData` must be true when `opts.bundle` is enabled.');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
this.uploaderEvents = Object.create(null);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
getOptions(file) {
|
|||
|
|
const overrides = this.uppy.getState().xhrUpload;
|
|||
|
|
const {
|
|||
|
|
headers
|
|||
|
|
} = this.opts;
|
|||
|
|
const opts = { ...this.opts,
|
|||
|
|
...(overrides || {}),
|
|||
|
|
...(file.xhrUpload || {}),
|
|||
|
|
headers: {}
|
|||
|
|
}; // Support for `headers` as a function, only in the XHRUpload settings.
|
|||
|
|
// Options set by other plugins in Uppy state or on the files themselves are still merged in afterward.
|
|||
|
|
//
|
|||
|
|
// ```js
|
|||
|
|
// headers: (file) => ({ expires: file.meta.expires })
|
|||
|
|
// ```
|
|||
|
|
|
|||
|
|
if (typeof headers === 'function') {
|
|||
|
|
opts.headers = headers(file);
|
|||
|
|
} else {
|
|||
|
|
Object.assign(opts.headers, this.opts.headers);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (overrides) {
|
|||
|
|
Object.assign(opts.headers, overrides.headers);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (file.xhrUpload) {
|
|||
|
|
Object.assign(opts.headers, file.xhrUpload.headers);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return opts;
|
|||
|
|
} // eslint-disable-next-line class-methods-use-this
|
|||
|
|
|
|||
|
|
|
|||
|
|
addMetadata(formData, meta, opts) {
|
|||
|
|
const metaFields = Array.isArray(opts.metaFields) ? opts.metaFields : Object.keys(meta); // Send along all fields by default.
|
|||
|
|
|
|||
|
|
metaFields.forEach(item => {
|
|||
|
|
formData.append(item, meta[item]);
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
createFormDataUpload(file, opts) {
|
|||
|
|
const formPost = new FormData();
|
|||
|
|
this.addMetadata(formPost, file.meta, opts);
|
|||
|
|
const dataWithUpdatedType = setTypeInBlob(file);
|
|||
|
|
|
|||
|
|
if (file.name) {
|
|||
|
|
formPost.append(opts.fieldName, dataWithUpdatedType, file.meta.name);
|
|||
|
|
} else {
|
|||
|
|
formPost.append(opts.fieldName, dataWithUpdatedType);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return formPost;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
createBundledUpload(files, opts) {
|
|||
|
|
const formPost = new FormData();
|
|||
|
|
const {
|
|||
|
|
meta
|
|||
|
|
} = this.uppy.getState();
|
|||
|
|
this.addMetadata(formPost, meta, opts);
|
|||
|
|
files.forEach(file => {
|
|||
|
|
const options = this.getOptions(file);
|
|||
|
|
const dataWithUpdatedType = setTypeInBlob(file);
|
|||
|
|
|
|||
|
|
if (file.name) {
|
|||
|
|
formPost.append(options.fieldName, dataWithUpdatedType, file.name);
|
|||
|
|
} else {
|
|||
|
|
formPost.append(options.fieldName, dataWithUpdatedType);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
return formPost;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
upload(file, current, total) {
|
|||
|
|
const opts = this.getOptions(file);
|
|||
|
|
this.uppy.log(`uploading ${current} of ${total}`);
|
|||
|
|
return new Promise((resolve, reject) => {
|
|||
|
|
this.uppy.emit('upload-started', file);
|
|||
|
|
const data = opts.formData ? this.createFormDataUpload(file, opts) : file.data;
|
|||
|
|
const xhr = new XMLHttpRequest();
|
|||
|
|
this.uploaderEvents[file.id] = new EventTracker_1(this.uppy);
|
|||
|
|
const timer = new ProgressTimeout_1(opts.timeout, () => {
|
|||
|
|
xhr.abort();
|
|||
|
|
queuedRequest.done();
|
|||
|
|
const error = new Error(this.i18n('timedOut', {
|
|||
|
|
seconds: Math.ceil(opts.timeout / 1000)
|
|||
|
|
}));
|
|||
|
|
this.uppy.emit('upload-error', file, error);
|
|||
|
|
reject(error);
|
|||
|
|
});
|
|||
|
|
const id = nanoid();
|
|||
|
|
xhr.upload.addEventListener('loadstart', () => {
|
|||
|
|
this.uppy.log(`[XHRUpload] ${id} started`);
|
|||
|
|
});
|
|||
|
|
xhr.upload.addEventListener('progress', ev => {
|
|||
|
|
this.uppy.log(`[XHRUpload] ${id} progress: ${ev.loaded} / ${ev.total}`); // Begin checking for timeouts when progress starts, instead of loading,
|
|||
|
|
// to avoid timing out requests on browser concurrency queue
|
|||
|
|
|
|||
|
|
timer.progress();
|
|||
|
|
|
|||
|
|
if (ev.lengthComputable) {
|
|||
|
|
this.uppy.emit('upload-progress', file, {
|
|||
|
|
uploader: this,
|
|||
|
|
bytesUploaded: ev.loaded,
|
|||
|
|
bytesTotal: ev.total
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
xhr.addEventListener('load', ev => {
|
|||
|
|
this.uppy.log(`[XHRUpload] ${id} finished`);
|
|||
|
|
timer.done();
|
|||
|
|
queuedRequest.done();
|
|||
|
|
|
|||
|
|
if (this.uploaderEvents[file.id]) {
|
|||
|
|
this.uploaderEvents[file.id].remove();
|
|||
|
|
this.uploaderEvents[file.id] = null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (opts.validateStatus(ev.target.status, xhr.responseText, xhr)) {
|
|||
|
|
const body = opts.getResponseData(xhr.responseText, xhr);
|
|||
|
|
const uploadURL = body[opts.responseUrlFieldName];
|
|||
|
|
const uploadResp = {
|
|||
|
|
status: ev.target.status,
|
|||
|
|
body,
|
|||
|
|
uploadURL
|
|||
|
|
};
|
|||
|
|
this.uppy.emit('upload-success', file, uploadResp);
|
|||
|
|
|
|||
|
|
if (uploadURL) {
|
|||
|
|
this.uppy.log(`Download ${file.name} from ${uploadURL}`);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return resolve(file);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const body = opts.getResponseData(xhr.responseText, xhr);
|
|||
|
|
const error = buildResponseError(xhr, opts.getResponseError(xhr.responseText, xhr));
|
|||
|
|
const response = {
|
|||
|
|
status: ev.target.status,
|
|||
|
|
body
|
|||
|
|
};
|
|||
|
|
this.uppy.emit('upload-error', file, error, response);
|
|||
|
|
return reject(error);
|
|||
|
|
});
|
|||
|
|
xhr.addEventListener('error', () => {
|
|||
|
|
this.uppy.log(`[XHRUpload] ${id} errored`);
|
|||
|
|
timer.done();
|
|||
|
|
queuedRequest.done();
|
|||
|
|
|
|||
|
|
if (this.uploaderEvents[file.id]) {
|
|||
|
|
this.uploaderEvents[file.id].remove();
|
|||
|
|
this.uploaderEvents[file.id] = null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const error = buildResponseError(xhr, opts.getResponseError(xhr.responseText, xhr));
|
|||
|
|
this.uppy.emit('upload-error', file, error);
|
|||
|
|
return reject(error);
|
|||
|
|
});
|
|||
|
|
xhr.open(opts.method.toUpperCase(), opts.endpoint, true); // IE10 does not allow setting `withCredentials` and `responseType`
|
|||
|
|
// before `open()` is called.
|
|||
|
|
|
|||
|
|
xhr.withCredentials = opts.withCredentials;
|
|||
|
|
|
|||
|
|
if (opts.responseType !== '') {
|
|||
|
|
xhr.responseType = opts.responseType;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const queuedRequest = this.requests.run(() => {
|
|||
|
|
this.uppy.emit('upload-started', file); // When using an authentication system like JWT, the bearer token goes as a header. This
|
|||
|
|
// header needs to be fresh each time the token is refreshed so computing and setting the
|
|||
|
|
// headers just before the upload starts enables this kind of authentication to work properly.
|
|||
|
|
// Otherwise, half-way through the list of uploads the token could be stale and the upload would fail.
|
|||
|
|
|
|||
|
|
const currentOpts = this.getOptions(file);
|
|||
|
|
Object.keys(currentOpts.headers).forEach(header => {
|
|||
|
|
xhr.setRequestHeader(header, currentOpts.headers[header]);
|
|||
|
|
});
|
|||
|
|
xhr.send(data);
|
|||
|
|
return () => {
|
|||
|
|
timer.done();
|
|||
|
|
xhr.abort();
|
|||
|
|
};
|
|||
|
|
});
|
|||
|
|
this.onFileRemove(file.id, () => {
|
|||
|
|
queuedRequest.abort();
|
|||
|
|
reject(new Error('File removed'));
|
|||
|
|
});
|
|||
|
|
this.onCancelAll(file.id, () => {
|
|||
|
|
queuedRequest.abort();
|
|||
|
|
reject(new Error('Upload cancelled'));
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
uploadRemote(file) {
|
|||
|
|
const opts = this.getOptions(file);
|
|||
|
|
return new Promise((resolve, reject) => {
|
|||
|
|
this.uppy.emit('upload-started', file);
|
|||
|
|
const fields = {};
|
|||
|
|
const metaFields = Array.isArray(opts.metaFields) ? opts.metaFields // Send along all fields by default.
|
|||
|
|
: Object.keys(file.meta);
|
|||
|
|
metaFields.forEach(name => {
|
|||
|
|
fields[name] = file.meta[name];
|
|||
|
|
});
|
|||
|
|
const Client = file.remote.providerOptions.provider ? Provider : RequestClient;
|
|||
|
|
const client = new Client(this.uppy, file.remote.providerOptions);
|
|||
|
|
client.post(file.remote.url, { ...file.remote.body,
|
|||
|
|
endpoint: opts.endpoint,
|
|||
|
|
size: file.data.size,
|
|||
|
|
fieldname: opts.fieldName,
|
|||
|
|
metadata: fields,
|
|||
|
|
httpMethod: opts.method,
|
|||
|
|
useFormData: opts.formData,
|
|||
|
|
headers: opts.headers
|
|||
|
|
}).then(res => {
|
|||
|
|
const {
|
|||
|
|
token
|
|||
|
|
} = res;
|
|||
|
|
const host = getSocketHost(file.remote.companionUrl);
|
|||
|
|
const socket = new Socket({
|
|||
|
|
target: `${host}/api/${token}`,
|
|||
|
|
autoOpen: false
|
|||
|
|
});
|
|||
|
|
this.uploaderEvents[file.id] = new EventTracker_1(this.uppy);
|
|||
|
|
this.onFileRemove(file.id, () => {
|
|||
|
|
socket.send('cancel', {});
|
|||
|
|
queuedRequest.abort();
|
|||
|
|
resolve(`upload ${file.id} was removed`);
|
|||
|
|
});
|
|||
|
|
this.onCancelAll(file.id, () => {
|
|||
|
|
socket.send('cancel', {});
|
|||
|
|
queuedRequest.abort();
|
|||
|
|
resolve(`upload ${file.id} was canceled`);
|
|||
|
|
});
|
|||
|
|
this.onRetry(file.id, () => {
|
|||
|
|
socket.send('pause', {});
|
|||
|
|
socket.send('resume', {});
|
|||
|
|
});
|
|||
|
|
this.onRetryAll(file.id, () => {
|
|||
|
|
socket.send('pause', {});
|
|||
|
|
socket.send('resume', {});
|
|||
|
|
});
|
|||
|
|
socket.on('progress', progressData => emitSocketProgress_1(this, progressData, file));
|
|||
|
|
socket.on('success', data => {
|
|||
|
|
const body = opts.getResponseData(data.response.responseText, data.response);
|
|||
|
|
const uploadURL = body[opts.responseUrlFieldName];
|
|||
|
|
const uploadResp = {
|
|||
|
|
status: data.response.status,
|
|||
|
|
body,
|
|||
|
|
uploadURL
|
|||
|
|
};
|
|||
|
|
this.uppy.emit('upload-success', file, uploadResp);
|
|||
|
|
queuedRequest.done();
|
|||
|
|
|
|||
|
|
if (this.uploaderEvents[file.id]) {
|
|||
|
|
this.uploaderEvents[file.id].remove();
|
|||
|
|
this.uploaderEvents[file.id] = null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return resolve();
|
|||
|
|
});
|
|||
|
|
socket.on('error', errData => {
|
|||
|
|
const resp = errData.response;
|
|||
|
|
const error = resp ? opts.getResponseError(resp.responseText, resp) : Object.assign(new Error(errData.error.message), {
|
|||
|
|
cause: errData.error
|
|||
|
|
});
|
|||
|
|
this.uppy.emit('upload-error', file, error);
|
|||
|
|
queuedRequest.done();
|
|||
|
|
|
|||
|
|
if (this.uploaderEvents[file.id]) {
|
|||
|
|
this.uploaderEvents[file.id].remove();
|
|||
|
|
this.uploaderEvents[file.id] = null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
reject(error);
|
|||
|
|
});
|
|||
|
|
const queuedRequest = this.requests.run(() => {
|
|||
|
|
socket.open();
|
|||
|
|
|
|||
|
|
if (file.isPaused) {
|
|||
|
|
socket.send('pause', {});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return () => socket.close();
|
|||
|
|
});
|
|||
|
|
}).catch(err => {
|
|||
|
|
this.uppy.emit('upload-error', file, err);
|
|||
|
|
reject(err);
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
uploadBundle(files) {
|
|||
|
|
return new Promise((resolve, reject) => {
|
|||
|
|
const {
|
|||
|
|
endpoint
|
|||
|
|
} = this.opts;
|
|||
|
|
const {
|
|||
|
|
method
|
|||
|
|
} = this.opts;
|
|||
|
|
const optsFromState = this.uppy.getState().xhrUpload;
|
|||
|
|
const formData = this.createBundledUpload(files, { ...this.opts,
|
|||
|
|
...(optsFromState || {})
|
|||
|
|
});
|
|||
|
|
const xhr = new XMLHttpRequest();
|
|||
|
|
const timer = new ProgressTimeout_1(this.opts.timeout, () => {
|
|||
|
|
xhr.abort();
|
|||
|
|
const error = new Error(this.i18n('timedOut', {
|
|||
|
|
seconds: Math.ceil(this.opts.timeout / 1000)
|
|||
|
|
}));
|
|||
|
|
emitError(error);
|
|||
|
|
reject(error);
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
const emitError = error => {
|
|||
|
|
files.forEach(file => {
|
|||
|
|
this.uppy.emit('upload-error', file, error);
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
xhr.upload.addEventListener('loadstart', () => {
|
|||
|
|
this.uppy.log('[XHRUpload] started uploading bundle');
|
|||
|
|
timer.progress();
|
|||
|
|
});
|
|||
|
|
xhr.upload.addEventListener('progress', ev => {
|
|||
|
|
timer.progress();
|
|||
|
|
if (!ev.lengthComputable) return;
|
|||
|
|
files.forEach(file => {
|
|||
|
|
this.uppy.emit('upload-progress', file, {
|
|||
|
|
uploader: this,
|
|||
|
|
bytesUploaded: ev.loaded / ev.total * file.size,
|
|||
|
|
bytesTotal: file.size
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
xhr.addEventListener('load', ev => {
|
|||
|
|
timer.done();
|
|||
|
|
|
|||
|
|
if (this.opts.validateStatus(ev.target.status, xhr.responseText, xhr)) {
|
|||
|
|
const body = this.opts.getResponseData(xhr.responseText, xhr);
|
|||
|
|
const uploadResp = {
|
|||
|
|
status: ev.target.status,
|
|||
|
|
body
|
|||
|
|
};
|
|||
|
|
files.forEach(file => {
|
|||
|
|
this.uppy.emit('upload-success', file, uploadResp);
|
|||
|
|
});
|
|||
|
|
return resolve();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const error = this.opts.getResponseError(xhr.responseText, xhr) || new Error('Upload error');
|
|||
|
|
error.request = xhr;
|
|||
|
|
emitError(error);
|
|||
|
|
return reject(error);
|
|||
|
|
});
|
|||
|
|
xhr.addEventListener('error', () => {
|
|||
|
|
timer.done();
|
|||
|
|
const error = this.opts.getResponseError(xhr.responseText, xhr) || new Error('Upload error');
|
|||
|
|
emitError(error);
|
|||
|
|
return reject(error);
|
|||
|
|
});
|
|||
|
|
this.uppy.on('cancel-all', () => {
|
|||
|
|
timer.done();
|
|||
|
|
xhr.abort();
|
|||
|
|
});
|
|||
|
|
xhr.open(method.toUpperCase(), endpoint, true); // IE10 does not allow setting `withCredentials` and `responseType`
|
|||
|
|
// before `open()` is called.
|
|||
|
|
|
|||
|
|
xhr.withCredentials = this.opts.withCredentials;
|
|||
|
|
|
|||
|
|
if (this.opts.responseType !== '') {
|
|||
|
|
xhr.responseType = this.opts.responseType;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Object.keys(this.opts.headers).forEach(header => {
|
|||
|
|
xhr.setRequestHeader(header, this.opts.headers[header]);
|
|||
|
|
});
|
|||
|
|
xhr.send(formData);
|
|||
|
|
files.forEach(file => {
|
|||
|
|
this.uppy.emit('upload-started', file);
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
uploadFiles(files) {
|
|||
|
|
const promises = files.map((file, i) => {
|
|||
|
|
const current = parseInt(i, 10) + 1;
|
|||
|
|
const total = files.length;
|
|||
|
|
|
|||
|
|
if (file.error) {
|
|||
|
|
return Promise.reject(new Error(file.error));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (file.isRemote) {
|
|||
|
|
return this.uploadRemote(file, current, total);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return this.upload(file, current, total);
|
|||
|
|
});
|
|||
|
|
return settle(promises);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
onFileRemove(fileID, cb) {
|
|||
|
|
this.uploaderEvents[fileID].on('file-removed', file => {
|
|||
|
|
if (fileID === file.id) cb(file.id);
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
onRetry(fileID, cb) {
|
|||
|
|
this.uploaderEvents[fileID].on('upload-retry', targetFileID => {
|
|||
|
|
if (fileID === targetFileID) {
|
|||
|
|
cb();
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
onRetryAll(fileID, cb) {
|
|||
|
|
this.uploaderEvents[fileID].on('retry-all', () => {
|
|||
|
|
if (!this.uppy.getFile(fileID)) return;
|
|||
|
|
cb();
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
onCancelAll(fileID, cb) {
|
|||
|
|
this.uploaderEvents[fileID].on('cancel-all', () => {
|
|||
|
|
if (!this.uppy.getFile(fileID)) return;
|
|||
|
|
cb();
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
handleUpload(fileIDs) {
|
|||
|
|
if (fileIDs.length === 0) {
|
|||
|
|
this.uppy.log('[XHRUpload] No files to upload!');
|
|||
|
|
return Promise.resolve();
|
|||
|
|
} // No limit configured by the user, and no RateLimitedQueue passed in by a "parent" plugin
|
|||
|
|
// (basically just AwsS3) using the internal symbol
|
|||
|
|
|
|||
|
|
|
|||
|
|
if (this.opts.limit === 0 && !this.opts[internalRateLimitedQueue]) {
|
|||
|
|
this.uppy.log('[XHRUpload] When uploading multiple files at once, consider setting the `limit` option (to `10` for example), to limit the number of concurrent uploads, which helps prevent memory and network issues: https://uppy.io/docs/xhr-upload/#limit-0', 'warning');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
this.uppy.log('[XHRUpload] Uploading...');
|
|||
|
|
const files = fileIDs.map(fileID => this.uppy.getFile(fileID));
|
|||
|
|
|
|||
|
|
if (this.opts.bundle) {
|
|||
|
|
// if bundle: true, we don’t support remote uploads
|
|||
|
|
const isSomeFileRemote = files.some(file => file.isRemote);
|
|||
|
|
|
|||
|
|
if (isSomeFileRemote) {
|
|||
|
|
throw new Error('Can’t upload remote files when the `bundle: true` option is set');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (typeof this.opts.headers === 'function') {
|
|||
|
|
throw new TypeError('`headers` may not be a function when the `bundle: true` option is set');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return this.uploadBundle(files);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return this.uploadFiles(files).then(() => null);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
install() {
|
|||
|
|
if (this.opts.bundle) {
|
|||
|
|
const {
|
|||
|
|
capabilities
|
|||
|
|
} = this.uppy.getState();
|
|||
|
|
this.uppy.setState({
|
|||
|
|
capabilities: { ...capabilities,
|
|||
|
|
individualCancellation: false
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
this.uppy.addUploader(this.handleUpload);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
uninstall() {
|
|||
|
|
if (this.opts.bundle) {
|
|||
|
|
const {
|
|||
|
|
capabilities
|
|||
|
|
} = this.uppy.getState();
|
|||
|
|
this.uppy.setState({
|
|||
|
|
capabilities: { ...capabilities,
|
|||
|
|
individualCancellation: true
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
this.uppy.removeUploader(this.handleUpload);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
}, _class.VERSION = "2.0.6", _temp);
|
|||
|
|
|
|||
|
|
var require$$2$1 = dist$7;
|
|||
|
|
|
|||
|
|
var require$$1 = dom7_cjs;
|
|||
|
|
|
|||
|
|
var require$$2 = snabbdom_cjs;
|
|||
|
|
|
|||
|
|
var dist$6 = createCommonjsModule$1(function (module, exports) {
|
|||
|
|
!function(e,t){t(exports,require$$2$1,lodash_toarray,require$$1,lodash_foreach,require$$4,lodash_throttle,require$$2,lodash_camelcase,lib$4,lodash_debounce,lodash_clonedeep,lib$2,lib);}(commonjsGlobal,(function(e,t,n,r,o,i,a,s,l,u,c,f,d,p){function h(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var g=h(t),v=h(n),y=h(r),m=h(o),b=h(a),w=h(l),x=h(c),E=h(f),S=h(d),k=h(p),O="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof commonjsGlobal?commonjsGlobal:"undefined"!=typeof self?self:{};function C(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}function T(e){var t={exports:{}};return e(t,t.exports),t.exports}var N,M,L=function(e){return e&&e.Math==Math&&e},P=L("object"==typeof globalThis&&globalThis)||L("object"==typeof window&&window)||L("object"==typeof self&&self)||L("object"==typeof O&&O)||function(){return this}()||Function("return this")(),R=Object.defineProperty,D=function(e,t){try{R(P,e,{value:t,configurable:!0,writable:!0});}catch(n){P[e]=t;}return t},j="__core-js_shared__",A=P[j]||D(j,{}),_=T((function(e){(e.exports=function(e,t){return A[e]||(A[e]=void 0!==t?t:{})})("versions",[]).push({version:"3.19.3",mode:"global",copyright:"© 2021 Denis Pushkarev (zloirock.ru)"});})),F=Function.prototype,I=F.bind,B=F.call,$=I&&I.bind(B),W=I?function(e){return e&&$(B,e)}:function(e){return e&&function(){return B.apply(e,arguments)}},H=P.TypeError,V=function(e){if(null==e)throw H("Can't call method on "+e);return e},z=P.Object,U=function(e){return z(V(e))},K=W({}.hasOwnProperty),q=Object.hasOwn||function(e,t){return K(U(e),t)},G=0,J=Math.random(),Y=W(1..toString),X=function(e){return "Symbol("+(void 0===e?"":e)+")_"+Y(++G+J,36)},Q=function(e){return "function"==typeof e},Z=function(e){return Q(e)?e:void 0},ee=function(e,t){return arguments.length<2?Z(P[e]):P[e]&&P[e][t]},te=ee("navigator","userAgent")||"",ne=P.process,re=P.Deno,oe=ne&&ne.versions||re&&re.version,ie=oe&&oe.v8;ie&&(M=(N=ie.split("."))[0]>0&&N[0]<4?1:+(N[0]+N[1])),!M&&te&&(!(N=te.match(/Edge\/(\d+)/))||N[1]>=74)&&(N=te.match(/Chrome\/(\d+)/))&&(M=+N[1]);var ae=M,se=function(e){try{return !!e()}catch(e){return !0}},le=!!Object.getOwnPropertySymbols&&!se((function(){var e=Symbol();return !String(e)||!(Object(e)instanceof Symbol)||!Symbol.sham&&ae&&ae<41})),ue=le&&!Symbol.sham&&"symbol"==typeof Symbol.iterator,ce=_("wks"),fe=P.Symbol,de=fe&&fe.for,pe=ue?fe:fe&&fe.withoutSetter||X,he=function(e){if(!q(ce,e)||!le&&"string"!=typeof ce[e]){var t="Symbol."+e;le&&q(fe,e)?ce[e]=fe[e]:ce[e]=ue&&de?de(t):pe(t);}return ce[e]},ge={};ge[he("toStringTag")]="z";var ve="[object z]"===String(ge),ye=!se((function(){return 7!=Object.defineProperty({},1,{get:function(){return 7}})[1]})),me=function(e){return "object"==typeof e?null!==e:Q(e)},be=P.document,we=me(be)&&me(be.createElement),xe=function(e){return we?be.createElement(e):{}},Ee=!ye&&!se((function(){return 7!=Object.defineProperty(xe("div"),"a",{get:function(){return 7}}).a})),Se=P.String,ke=P.TypeError,Oe=function(e){if(me(e))return e;throw ke(Se(e)+" is not an object")},Ce=Function.prototype.call,Te=Ce.bind?Ce.bind(Ce):function(){return Ce.apply(Ce,arguments)},Ne=W({}.isPrototypeOf),Me=P.Object,Le=ue?function(e){return "symbol"==typeof e}:function(e){var t=ee("Symbol");return Q(t)&&Ne(t.prototype,Me(e))},Pe=P.String,Re=function(e){try{return Pe(e)}catch(e){return "Object"}},De=P.TypeError,je=function(e){if(Q(e))return e;throw De(Re(e)+" is not a function")},Ae=function(e,t){var n=e[t];return null==n?void 0:je(n)},_e=P.TypeError,Fe=P.TypeError,Ie=he("toPrimitive"),Be=function(e,t){if(!me(e)||Le(e))return e;var n,r=Ae(e,Ie);if(r){if(void 0===t&&(t="default"),n=Te(r,e,t),!me(n)||Le(n))return n;throw Fe("Can't convert object to primitive value")}return void 0===t&&(t="number"),function(e,t){var n,r;if("string"===t&&Q(n=e.toString)&&!me(r=Te(n,e)))return r;if(Q(n=e.valueOf)&&!me(r=Te(n,e)))return r;if("string"!==t&&Q(n=e.toString)&&!me(r=Te(n,e)))return r;throw _e("Can't convert object to primitive value")}(e,t)},$e=function(e){
|
|||
|
|
/*!
|
|||
|
|
* is-plain-object <https://github.com/jonschlinkert/is-plain-object>
|
|||
|
|
*
|
|||
|
|
* Copyright (c) 2014-2017, Jon Schlinkert.
|
|||
|
|
* Released under the MIT License.
|
|||
|
|
*/
|
|||
|
|
function Bn(e){return "[object Object]"===Object.prototype.toString.call(e)}_n({target:"Object",stat:!0,forced:In},{keys:function(e){return Fn(U(e))}});var $n=function(e){var t,n;return !1!==Bn(e)&&(void 0===(t=e.constructor)||!1!==Bn(n=t.prototype)&&!1!==n.hasOwnProperty("isPrototypeOf"))},Wn=Object.defineProperty({isPlainObject:$n},"__esModule",{value:!0}),Hn=function(e){return Wn.isPlainObject(e)&&Array.isArray(e.redos)&&Array.isArray(e.undos)&&(0===e.redos.length||g.default.Operation.isOperationList(e.redos[0]))&&(0===e.undos.length||g.default.Operation.isOperationList(e.undos[0]))},Vn=new WeakMap,zn=new WeakMap,Un={isHistoryEditor:function(e){return Hn(e.history)&&g.default.Editor.isEditor(e)},isMerging:function(e){return zn.get(e)},isSaving:function(e){return Vn.get(e)},redo:function(e){e.redo();},undo:function(e){e.undo();},withoutMerging:function(e,t){var n=Un.isMerging(e);zn.set(e,!1),t(),zn.set(e,n);},withoutSaving:function(e,t){var n=Un.isSaving(e);Vn.set(e,!1),t(),Vn.set(e,n);}};function Kn(e,t){var n="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(!n){if(Array.isArray(e)||(n=function(e,t){if(!e)return;if("string"==typeof e)return qn(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return qn(e,t)}(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var r=0,o=function(){};return {s:o,n:function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}},e:function(e){throw e},f:o}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var i,a=!0,s=!1;return {s:function(){n=n.call(e);},n:function(){var e=n.next();return a=e.done,e},e:function(e){s=!0,i=e;},f:function(){try{a||null==n.return||n.return();}finally{if(s)throw i}}}}function qn(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}var Gn=function(e,t){return "set_selection"===e.type||(!(!t||"insert_text"!==e.type||"insert_text"!==t.type||e.offset!==t.offset+t.text.length||!g.default.Path.equals(e.path,t.path))||!(!t||"remove_text"!==e.type||"remove_text"!==t.type||e.offset+e.text.length!==t.offset||!g.default.Path.equals(e.path,t.path)))},Jn=function(e,t){return "set_selection"!==e.type||null!=e.properties&&null!=e.newProperties},Yn=function(e,t){return !(!t||"set_selection"!==e.type||"set_selection"!==t.type)},Xn=function(e){return "set_selection"!==e.type},Qn=function(e){var t=e,n=t.apply;return t.history={undos:[],redos:[]},t.redo=function(){var e=t.history,n=e.redos;if(n.length>0){var r=n[n.length-1];Un.withoutSaving(t,(function(){g.default.Editor.withoutNormalizing(t,(function(){var e,n=Kn(r);try{for(n.s();!(e=n.n()).done;){var o=e.value;t.apply(o);}}catch(e){n.e(e);}finally{n.f();}}));})),e.redos.pop(),e.undos.push(r);}},t.undo=function(){var e=t.history,n=e.undos;if(n.length>0){var r=n[n.length-1];Un.withoutSaving(t,(function(){g.default.Editor.withoutNormalizing(t,(function(){var e,n=Kn(r.map(g.default.Operation.inverse).reverse());try{for(n.s();!(e=n.n()).done;){var o=e.value;t.apply(o);}}catch(e){n.e(e);}finally{n.f();}}));})),e.redos.push(r),e.undos.pop();}},t.apply=function(e){var r=t.operations,o=t.history,i=o.undos,a=i[i.length-1],s=a&&a[a.length-1],l=Yn(e,s),u=Un.isSaving(t),c=Un.isMerging(t);if(null==u&&(u=Jn(e)),u){if(null==c&&(c=null!=a&&(0!==r.length||(Gn(e,s)||l))),a&&c)l&&a.pop(),a.push(e);else {var f=[e];i.push(f);}for(;i.length>100;)i.shift();Xn(e)&&(o.redos=[]);}n(e);},t},Zn=P.String,er=function(e){if("Symbol"===Et(e))throw TypeError("Cannot convert a Symbol value to a string");return Zn(e)},tr=function(){var e=Oe(this),t="";return e.global&&(t+="g"),e.ignoreCase&&(t+="i"),e.multiline&&(t+="m"),e.dotAll&&(t+="s"),e.unicode&&(t+="u"),e.sticky&&(t+="y"),t},nr=ht.PROPER,rr="toString",or=RegExp.prototype,ir=or.toString,ar=W(tr),sr=se((function(){return "/a/b"!=ir.call({source:"a",flags:"b"})})),lr=nr&&ir.n
|
|||
|
|
/*! *****************************************************************************
|
|||
|
|
Copyright (c) Microsoft Corporation.
|
|||
|
|
|
|||
|
|
Permission to use, copy, modify, and/or distribute this software for any
|
|||
|
|
purpose with or without fee is hereby granted.
|
|||
|
|
|
|||
|
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|||
|
|
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|||
|
|
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|||
|
|
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|||
|
|
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|||
|
|
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|||
|
|
PERFORMANCE OF THIS SOFTWARE.
|
|||
|
|
***************************************************************************** */
|
|||
|
|
var zi=function(e,t){return zi=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t;}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n]);},zi(e,t)};function Ui(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");function n(){this.constructor=e;}zi(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n);}var Ki=function(){return Ki=Object.assign||function(e){for(var t,n=1,r=arguments.length;n<r;n++)for(var o in t=arguments[n])Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o]);return e},Ki.apply(this,arguments)};function qi(e){var t="function"==typeof Symbol&&Symbol.iterator,n=t&&e[t],r=0;if(n)return n.call(e);if(e&&"number"==typeof e.length)return {next:function(){return e&&r>=e.length&&(e=void 0),{value:e&&e[r++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}function Gi(e,t){var n="function"==typeof Symbol&&e[Symbol.iterator];if(!n)return e;var r,o,i=n.call(e),a=[];try{for(;(void 0===t||t-- >0)&&!(r=i.next()).done;)a.push(r.value);}catch(e){o={error:e};}finally{try{r&&!r.done&&(n=i.return)&&n.call(i);}finally{if(o)throw o.error}}return a}function Ji(e,t){for(var n=0,r=t.length,o=e.length;n<r;n++,o++)e[o]=t[n];return e}var Yi=0,Xi=function(){this.id=""+Yi++;},Qi="Array Iterator",Zi=ct.set,ea=ct.getterFor(Qi),ta=Po(Array,"Array",(function(e,t){Zi(this,{type:Qi,target:cn(e),index:0,kind:t});}),(function(){var e=ea(this),t=e.target,n=e.kind,r=e.index++;return !t||r>=t.length?(e.target=void 0,{value:void 0,done:!0}):"keys"==n?{value:r,done:!1}:"values"==n?{value:t[r],done:!1}:{value:[r,t[r]],done:!1}}),"values");jr.Arguments=jr.Array,wr("keys"),wr("values"),wr("entries");var na=function(e,t,n){for(var r in t)gt(e,r,t[r],n);return e},ra=P.Array,oa=Math.max,ia=function(e,t,n){for(var r=It(e),o=gn(t,r),i=gn(void 0===n?r:n,r),a=ra(oa(i-o,0)),s=0;o<i;o++,s++)Ir(a,s,e[o]);return a.length=s,a},aa=Sn.f,sa="object"==typeof window&&window&&Object.getOwnPropertyNames?Object.getOwnPropertyNames(window):[],la={f:function(e){return sa&&"Window"==mt(e)?function(e){try{return aa(e)}catch(e){return ia(sa)}}(e):aa(cn(e))}},ua=se((function(){if("function"==typeof ArrayBuffer){var e=new ArrayBuffer(8);Object.isExtensible(e)&&Object.defineProperty(e,"a",{value:8});}})),ca=Object.isExtensible,fa=se((function(){ca(1);}))||ua?function(e){return !!me(e)&&((!ua||"ArrayBuffer"!=mt(e))&&(!ca||ca(e)))}:ca,da=!se((function(){return Object.isExtensible(Object.preventExtensions({}))})),pa=T((function(e){var t=Ve.f,n=!1,r=X("meta"),o=0,i=function(e){t(e,r,{value:{objectID:"O"+o++,weakData:{}}});},a=e.exports={enable:function(){a.enable=function(){},n=!0;var e=Sn.f,t=W([].splice),o={};o[r]=1,e(o).length&&(Sn.f=function(n){for(var o=e(n),i=0,a=o.length;i<a;i++)if(o[i]===r){t(o,i,1);break}return o},_n({target:"Object",stat:!0,forced:!0},{getOwnPropertyNames:la.f}));},fastKey:function(e,t){if(!me(e))return "symbol"==typeof e?e:("string"==typeof e?"S":"P")+e;if(!q(e,r)){if(!fa(e))return "F";if(!t)return "E";i(e);}return e[r].objectID},getWeakData:function(e,t){if(!q(e,r)){if(!fa(e))return !0;if(!t)return !1;i(e);}return e[r].weakData},onFreeze:function(e){return da&&n&&fa(e)&&!q(e,r)&&i(e),e}};tt[r]=!0;})),ha=P.TypeError,ga=function(e,t){this.stopped=e,this.result=t;},va=ga.prototype,ya=function(e,t,n){var r,o,i,a,s,l,u,c=n&&n.that,f=!(!n||!n.AS_ENTRIES),d=!(!n||!n.IS_ITERATOR),p=!(!n||!n.INTERRUPTED),h=Mt(t,c),g=function(e){return r&&Rr(r,"normal",e),new ga(!0,e)},v=function(e){return f?(Oe(e),p?h(e[0],e[1],g):h(e[0],e[1])):p?h(e,g):h(e)};if(d)r=e;else {if(!(o=$r(e)))throw ha(Re(e)+" is not iterable");if(Fr(o)){for(i=0,a=It(e);a>i;i++)if((s=v(e[i]))&&Ne(va,s))return s;return new ga(!1)}r=Hr(e,o);}for(l=r.next;!(u=Te(l,r)).done;){try{s=v(u.value);}catch(e){Rr(r,"throw",e);}if("object"==typeof s&&s&&Ne(va,s))return s}return new ga(!1)},ma=P.TypeError,ba=function(e,t){if(Ne(t,e))return e;throw ma("Incorrect invocation")},wa=function(e,t,n){var r,o;return xo&
|
|||
|
|
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @description i18n en
|
|||
|
|
* @author wangfupeng
|
|||
|
|
*/
|
|||
|
|
var enResources = {
|
|||
|
|
editor: {
|
|||
|
|
more: 'More',
|
|||
|
|
justify: 'Justify',
|
|||
|
|
indent: 'Indent',
|
|||
|
|
image: 'Image',
|
|||
|
|
video: 'Video',
|
|||
|
|
},
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @description i18n zh-CN
|
|||
|
|
* @author wangfupeng
|
|||
|
|
*/
|
|||
|
|
var zhResources = {
|
|||
|
|
editor: {
|
|||
|
|
more: '更多',
|
|||
|
|
justify: '对齐',
|
|||
|
|
indent: '缩进',
|
|||
|
|
image: '图片',
|
|||
|
|
video: '视频',
|
|||
|
|
},
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @description i18n entry
|
|||
|
|
* @author wangfupeng
|
|||
|
|
*/
|
|||
|
|
dist$6.i18nAddResources('en', enResources);
|
|||
|
|
dist$6.i18nAddResources('zh-CN', zhResources);
|
|||
|
|
|
|||
|
|
var dist$5 = createCommonjsModule$1(function (module, exports) {
|
|||
|
|
!function(t,e){e(exports,dist$6,require$$2,require$$2$1,require$$1,require$$4,lodash_throttle);}(commonjsGlobal,(function(t,e,n,r,o,i,u){function a(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}var c=a(o),l=a(u);e.i18nAddResources("en",{common:{ok:"OK",delete:"Delete",enter:"Enter"},blockQuote:{title:"Quote"},codeBlock:{title:"Code block"},color:{color:"Font color",bgColor:"Back color",default:"Default color",clear:"Clear back color"},divider:{title:"Divider"},emotion:{title:"Emotion"},fontSize:{title:"Font size",default:"Default"},fontFamily:{title:"Font family",default:"Default"},fullScreen:{title:"Full screen"},header:{title:"Header",text:"Text"},image:{netImage:"Net image",delete:"Delete image",edit:"Edit image",viewLink:"View link",src:"Image src",desc:"Description",link:"Image link"},indent:{decrease:"Decrease",increase:"Increase"},justify:{left:"Left",right:"Right",center:"Center",justify:"Justify"},lineHeight:{title:"Line height",default:"Default"},link:{insert:"Insert link",text:"Link text",url:"Link source",unLink:"Unlink",edit:"Edit link",view:"View link"},textStyle:{bold:"Bold",clear:"Clear styles",code:"Inline code",italic:"Italic",sub:"Sub",sup:"Sup",through:"Through",underline:"Underline"},undo:{undo:"undo",redo:"Redo"},todo:{todo:"Todo"}}),e.i18nAddResources("zh-CN",{common:{ok:"确定",delete:"删除",enter:"回车"},blockQuote:{title:"引用"},codeBlock:{title:"代码块"},color:{color:"文字颜色",bgColor:"背景色",default:"默认颜色",clear:"清除背景色"},divider:{title:"分割线"},emotion:{title:"表情"},fontSize:{title:"字号",default:"默认字号"},fontFamily:{title:"字体",default:"默认字体"},fullScreen:{title:"全屏"},header:{title:"标题",text:"正文"},image:{netImage:"网络图片",delete:"删除图片",edit:"编辑图片",viewLink:"查看链接",src:"图片地址",desc:"图片描述",link:"图片链接"},indent:{decrease:"减少缩进",increase:"增加缩进"},justify:{left:"左对齐",right:"右对齐",center:"居中对齐",justify:"两端对齐"},lineHeight:{title:"行高",default:"默认行高"},link:{insert:"插入链接",text:"链接文本",url:"链接地址",unLink:"取消链接",edit:"修改链接",view:"查看链接"},textStyle:{bold:"粗体",clear:"清除格式",code:"行内代码",italic:"斜体",sub:"下标",sup:"上标",through:"删除线",underline:"下划线"},undo:{undo:"撤销",redo:"重做"},todo:{todo:"待办"}});var s={type:"paragraph",renderElem:function(t,e,r){return n.jsx("p",null,e)}};var f={type:"paragraph",elemToHtml:function(t,e){return ""===e?"":"<p>"+e+"</p>"}},d="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof commonjsGlobal?commonjsGlobal:"undefined"!=typeof self?self:{};function p(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}function h(t){var e={exports:{}};return t(e,e.exports),e.exports}var v,g,m=function(t){return t&&t.Math==Math&&t},y=m("object"==typeof globalThis&&globalThis)||m("object"==typeof window&&window)||m("object"==typeof self&&self)||m("object"==typeof d&&d)||function(){return this}()||Function("return this")(),b=function(t){try{return !!t()}catch(t){return !0}},x=!b((function(){return 7!=Object.defineProperty({},1,{get:function(){return 7}})[1]})),w=Function.prototype.call,E=w.bind?w.bind(w):function(){return w.apply(w,arguments)},S={}.propertyIsEnumerable,k=Object.getOwnPropertyDescriptor,T=k&&!S.call({1:2},1)?function(t){var e=k(this,t);return !!e&&e.enumerable}:S,M={f:T},I=function(t,e){return {enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}},N=Function.prototype,H=N.bind,O=N.call,j=H&&H.bind(O),D=H?function(t){return t&&j(O,t)}:function(t){return t&&function(){return O.apply(t,arguments)}},L=D({}.toString),z=D("".slice),A=function(t){return z(L(t),8,-1)},P=y.Object,C=D("".split),V=b((function(){return !P("z").propertyIsEnumerable(0)}))?function(t){return "String"==A(t)?C(t,""):P(t)}:P,B=y.TypeError,R=function(t){if(null==t)throw B("Can't call method on "+t);return t},F=function(t){return V(R(t))},_=f
|
|||
|
|
/*! *****************************************************************************
|
|||
|
|
Copyright (c) Microsoft Corporation.
|
|||
|
|
|
|||
|
|
Permission to use, copy, modify, and/or distribute this software for any
|
|||
|
|
purpose with or without fee is hereby granted.
|
|||
|
|
|
|||
|
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|||
|
|
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|||
|
|
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|||
|
|
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|||
|
|
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|||
|
|
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|||
|
|
PERFORMANCE OF THIS SOFTWARE.
|
|||
|
|
***************************************************************************** */function vo(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Class extends value "+String(e)+" is not a constructor or null");function n(){this.constructor=t;}ho(t,e),t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n);}var go=function(){return go=Object.assign||function(t){for(var e,n=1,r=arguments.length;n<r;n++)for(var o in e=arguments[n])Object.prototype.hasOwnProperty.call(e,o)&&(t[o]=e[o]);return t},go.apply(this,arguments)};function mo(t,e,n,r){return new(n||(n=Promise))((function(o,i){function u(t){try{c(r.next(t));}catch(t){i(t);}}function a(t){try{c(r.throw(t));}catch(t){i(t);}}function c(t){var e;t.done?o(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e);}))).then(u,a);}c((r=r.apply(t,e||[])).next());}))}function yo(t,e){var n,r,o,i,u={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function a(i){return function(a){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;u;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return u.label++,{value:i[1],done:!1};case 5:u.label++,r=i[1],i=[0];continue;case 7:i=u.ops.pop(),u.trys.pop();continue;default:if(!(o=u.trys,(o=o.length>0&&o[o.length-1])||6!==i[0]&&2!==i[0])){u=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]<o[3])){u.label=i[1];break}if(6===i[0]&&u.label<o[1]){u.label=o[1],o=i;break}if(o&&u.label<o[2]){u.label=o[2],u.ops.push(i);break}o[2]&&u.ops.pop(),u.trys.pop();continue}i=e.call(t,u);}catch(t){i=[6,t],r=0;}finally{n=o=0;}if(5&i[0])throw i[1];return {value:i[0]?i[1]:void 0,done:!0}}([i,a])}}}function bo(t){var e="function"==typeof Symbol&&Symbol.iterator,n=e&&t[e],r=0;if(n)return n.call(t);if(t&&"number"==typeof t.length)return {next:function(){return t&&r>=t.length&&(t=void 0),{value:t&&t[r++],done:!t}}};throw new TypeError(e?"Object is not iterable.":"Symbol.iterator is not defined.")}function xo(t,e){var n="function"==typeof Symbol&&t[Symbol.iterator];if(!n)return t;var r,o,i=n.call(t),u=[];try{for(;(void 0===e||e-- >0)&&!(r=i.next()).done;)u.push(r.value);}catch(t){o={error:t};}finally{try{r&&!r.done&&(n=i.return)&&n.call(i);}finally{if(o)throw o.error}}return u}function wo(t){var e=xo(r.Editor.nodes(t,{match:function(e){return t.children[0]===e},mode:"highest"}),1),n=e[0];if(null==n)return !1;var o=n[0];if(!r.Element.isElement(o))return !1;if("paragraph"===o.type)return !1;if(""!==r.Node.string(o))return !1;var i=o.children,u=void 0===i?[]:i;return !!r.Text.isText(u[0])&&(r.Transforms.setNodes(t,{type:"paragraph"}),!0)}var Eo={renderElems:[s],elemsToHtml:[f],parseElemsHtml:[{selector:"p:not([data-w-e-type])",parseElemHtml:function(t,e,n){var o=c.default(t);return 0===(e=e.filter((function(t){return !!r.Text.isText(t)||!!n.isInline(t)}))).length&&(e=[{text:o.text().replace(/\s+/gm," ")}]),{type:"paragraph",children:e}}}],editorPlugin:function(t){var e=t.deleteBackward,n=t.deleteForward;t.insertText,t.insertBreak;var r=t;return r.deleteBackward=function(t){wo(r)||e(t);},r.deleteForward=function(t){wo(r)||n(t);},r}},So=/"/g,ko=D("".replace),To=function(t,e,n,r){var o=bn(R(t)),i="<"+e;return ""!==n&&(i+=" "+n+'="'+ko(bn(r),So,""")+'"'),i+">"+o+"</"+e+">"},Mo=function(t){return b((function(){var e=""[t]('"');return e!==e.toLowerCase()||e.split('"').length>3}))};function Io(t,e){var n=e,r=t,o=r.bold,i=r.italic,u=r.underline;return o&&(n="<strong>"+n+"</strong>"),r.code&&(n="<code>"+n+"</code>"),i&&(n="<em>"+n+"</em>"),u&&(n="<u>"+n+"</u>"),r.through&&(n="<s>"+n+"</s>"),r.sub&&(n="<sub>"+n+"</sub>"),r.sup&&(n="<sup>"+n+"</sup>"),n}function No(t,e){return 0!==t.length&&(!!t[0].matches(e)||t.find(e).length>0)}qe({target:"String",proto:!0,forced:Mo("bold")},{bold:function(){return To(this,"b","","")}}),qe({target:"String",proto:
|
|||
|
|
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
var basicModules = /*@__PURE__*/getDefaultExportFromCjs(dist$5);
|
|||
|
|
|
|||
|
|
var dist$4 = createCommonjsModule$1(function (module, exports) {
|
|||
|
|
!function(t,e){module.exports=e(dist$6,require$$2$1,require$$2,require$$1);}(commonjsGlobal,(function(t,e,r,n){function o(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}var i=o(n);t.i18nAddResources("en",{listModule:{unOrderedList:"Unordered list",orderedList:"Ordered list"}}),t.i18nAddResources("zh-CN",{listModule:{unOrderedList:"无序列表",orderedList:"有序列表"}});var u="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof commonjsGlobal?commonjsGlobal:"undefined"!=typeof self?self:{};function a(t){var e={exports:{}};return t(e,e.exports),e.exports}var c,f,l=function(t){return t&&t.Math==Math&&t},s=l("object"==typeof globalThis&&globalThis)||l("object"==typeof window&&window)||l("object"==typeof self&&self)||l("object"==typeof u&&u)||function(){return this}()||Function("return this")(),d=Function.prototype,v=d.bind,p=d.call,y=v&&v.bind(p),h=v?function(t){return t&&y(p,t)}:function(t){return t&&function(){return p.apply(t,arguments)}},g=function(t){try{return !!t()}catch(t){return !0}},b=h({}.toString),m=h("".slice),w=function(t){return m(b(t),8,-1)},x=s.Object,S=h("".split),O=g((function(){return !x("z").propertyIsEnumerable(0)}))?function(t){return "String"==w(t)?S(t,""):x(t)}:x,E=s.TypeError,T=function(t){if(null==t)throw E("Can't call method on "+t);return t},j=function(t){return O(T(t))},A=Object.defineProperty,I=function(t,e){try{A(s,t,{value:e,configurable:!0,writable:!0});}catch(r){s[t]=e;}return e},P="__core-js_shared__",R=s[P]||I(P,{}),L=a((function(t){(t.exports=function(t,e){return R[t]||(R[t]=void 0!==e?e:{})})("versions",[]).push({version:"3.19.3",mode:"global",copyright:"© 2021 Denis Pushkarev (zloirock.ru)"});})),k=s.Object,M=function(t){return k(T(t))},N=h({}.hasOwnProperty),_=Object.hasOwn||function(t,e){return N(M(t),e)},z=0,D=Math.random(),C=h(1..toString),F=function(t){return "Symbol("+(void 0===t?"":t)+")_"+C(++z+D,36)},H=function(t){return "function"==typeof t},B=function(t){return H(t)?t:void 0},G=function(t,e){return arguments.length<2?B(s[t]):s[t]&&s[t][e]},$=G("navigator","userAgent")||"",V=s.process,W=s.Deno,U=V&&V.versions||W&&W.version,q=U&&U.v8;q&&(f=(c=q.split("."))[0]>0&&c[0]<4?1:+(c[0]+c[1])),!f&&$&&(!(c=$.match(/Edge\/(\d+)/))||c[1]>=74)&&(c=$.match(/Chrome\/(\d+)/))&&(f=+c[1]);var K,Y=f,X=!!Object.getOwnPropertySymbols&&!g((function(){var t=Symbol();return !String(t)||!(Object(t)instanceof Symbol)||!Symbol.sham&&Y&&Y<41})),J=X&&!Symbol.sham&&"symbol"==typeof Symbol.iterator,Q=L("wks"),Z=s.Symbol,tt=Z&&Z.for,et=J?Z:Z&&Z.withoutSetter||F,rt=function(t){if(!_(Q,t)||!X&&"string"!=typeof Q[t]){var e="Symbol."+t;X&&_(Z,t)?Q[t]=Z[t]:Q[t]=J&&tt?tt(e):et(e);}return Q[t]},nt=function(t){return "object"==typeof t?null!==t:H(t)},ot=s.String,it=s.TypeError,ut=function(t){if(nt(t))return t;throw it(ot(t)+" is not an object")},at=!g((function(){return 7!=Object.defineProperty({},1,{get:function(){return 7}})[1]})),ct=s.document,ft=nt(ct)&&nt(ct.createElement),lt=function(t){return ft?ct.createElement(t):{}},st=!at&&!g((function(){return 7!=Object.defineProperty(lt("div"),"a",{get:function(){return 7}}).a})),dt=Function.prototype.call,vt=dt.bind?dt.bind(dt):function(){return dt.apply(dt,arguments)},pt=h({}.isPrototypeOf),yt=s.Object,ht=J?function(t){return "symbol"==typeof t}:function(t){var e=G("Symbol");return H(e)&&pt(e.prototype,yt(t))},gt=s.String,bt=function(t){try{return gt(t)}catch(t){return "Object"}},mt=s.TypeError,wt=function(t){if(H(t))return t;throw mt(bt(t)+" is not a function")},xt=function(t,e){var r=t[e];return null==r?void 0:wt(r)},St=s.TypeError,Ot=s.TypeError,Et=rt("toPrimitive"),Tt=function(t,e){if(!nt(t)||ht(t))return t;var r,n=xt(t,Et);if(n){if(void 0===e&&(e="default"),r=vt(n,t,e),!nt(r)||ht(r))return r;throw Ot("Can't convert object to primitive value")}return void 0===e&&(e="number"),function(t,e){var r,n;if("string"===e&&H(r=t.toString)&&!nt(n=vt(r,t)))return n;if(H(r=t.valueOf)&&!nt(n=vt(r,t)))return n;if("string"!==e&&H(r=t.toString)&&!nt(n=vt(r,t)))return n;throw St("Can't convert object to primitive val
|
|||
|
|
/*! *****************************************************************************
|
|||
|
|
Copyright (c) Microsoft Corporation.
|
|||
|
|
|
|||
|
|
Permission to use, copy, modify, and/or distribute this software for any
|
|||
|
|
purpose with or without fee is hereby granted.
|
|||
|
|
|
|||
|
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|||
|
|
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|||
|
|
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|||
|
|
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|||
|
|
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|||
|
|
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|||
|
|
PERFORMANCE OF THIS SOFTWARE.
|
|||
|
|
***************************************************************************** */function wo(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Class extends value "+String(e)+" is not a constructor or null");function r(){this.constructor=t;}mo(t,e),t.prototype=null===e?Object.create(e):(r.prototype=e.prototype,new r);}function xo(t){var e="function"==typeof Symbol&&Symbol.iterator,r=e&&t[e],n=0;if(r)return r.call(t);if(t&&"number"==typeof t.length)return {next:function(){return t&&n>=t.length&&(t=void 0),{value:t&&t[n++],done:!t}}};throw new TypeError(e?"Object is not iterable.":"Symbol.iterator is not defined.")}function So(t,e){var r="function"==typeof Symbol&&t[Symbol.iterator];if(!r)return t;var n,o,i=r.call(t),u=[];try{for(;(void 0===e||e-- >0)&&!(n=i.next()).done;)u.push(n.value);}catch(t){o={error:t};}finally{try{n&&!n.done&&(r=i.return)&&r.call(i);}finally{if(o)throw o.error}}return u}function Oo(r){return e.Editor.nodes(r,{at:r.selection||void 0,match:function(e){return 1===t.DomEditor.findPath(r,e).length}})}var Eo=Ht.includes;Qe({target:"Array",proto:!0},{includes:function(t){return Eo(this,t,arguments.length>1?arguments[1]:void 0)}}),ie("includes");var To,jo,Ao=function(){var t=ut(this),e="";return t.global&&(e+="g"),t.ignoreCase&&(e+="i"),t.multiline&&(e+="m"),t.dotAll&&(e+="s"),t.unicode&&(e+="u"),t.sticky&&(e+="y"),e},Io=s.RegExp,Po=g((function(){var t=Io("a","y");return t.lastIndex=2,null!=t.exec("abcd")})),Ro=Po||g((function(){return !Io("a","y").sticky})),Lo={BROKEN_CARET:Po||g((function(){var t=Io("^r","gy");return t.lastIndex=2,null!=t.exec("str")})),MISSED_STICKY:Ro,UNSUPPORTED_Y:Po},ko=s.RegExp,Mo=g((function(){var t=ko(".","s");return !(t.dotAll&&t.exec("\n")&&"s"===t.flags)})),No=s.RegExp,_o=g((function(){var t=No("(?<a>b)","g");return "b"!==t.exec("b").groups.a||"bc"!=="b".replace(t,"$<a>c")})),zo=Ae.get,Do=L("native-string-replace",String.prototype.replace),Co=RegExp.prototype.exec,Fo=Co,Ho=h("".charAt),Bo=h("".indexOf),Go=h("".replace),$o=h("".slice),Vo=(jo=/b*/g,vt(Co,To=/a/,"a"),vt(Co,jo,"a"),0!==To.lastIndex||0!==jo.lastIndex),Wo=Lo.BROKEN_CARET,Uo=void 0!==/()??/.exec("")[1];(Vo||Uo||Wo||Mo||_o)&&(Fo=function(t){var e,r,n,o,i,u,a,c=this,f=zo(c),l=Cr(t),s=f.raw;if(s)return s.lastIndex=c.lastIndex,e=vt(Fo,s,l),c.lastIndex=s.lastIndex,e;var d=f.groups,v=Wo&&c.sticky,p=vt(Ao,c),y=c.source,h=0,g=l;if(v&&(p=Go(p,"y",""),-1===Bo(p,"g")&&(p+="g"),g=$o(l,c.lastIndex),c.lastIndex>0&&(!c.multiline||c.multiline&&"\n"!==Ho(l,c.lastIndex-1))&&(y="(?: "+y+")",g=" "+g,h++),r=new RegExp("^(?:"+y+")",p)),Uo&&(r=new RegExp("^"+y+"$(?!\\s)",p)),Vo&&(n=c.lastIndex),o=vt(Co,v?r:c,g),v?o?(o.input=$o(o.input,h),o[0]=$o(o[0],h),o.index=c.lastIndex,c.lastIndex+=o[0].length):c.lastIndex=0:Vo&&o&&(c.lastIndex=c.global?o.index+o[0].length:n),Uo&&o&&o.length>1&&vt(Do,o[0],r,(function(){for(i=1;i<arguments.length-2;i++)void 0===arguments[i]&&(o[i]=void 0);})),o&&d)for(o.groups=u=re(null),i=0;i<d.length;i++)u[(a=d[i])[0]]=o[a[1]];return o});var qo=Fo;Qe({target:"RegExp",proto:!0,forced:/./.exec!==qo},{exec:qo});var Ko=function(){function r(){this.type="list-item",this.tag="button";}return r.prototype.getListNode=function(e){var r=this.type;return t.DomEditor.getSelectedNodeByType(e,r)},r.prototype.getValue=function(t){return ""},r.prototype.isActive=function(t){var e=this.getListNode(t);if(null==e)return !1;var r=e.ordered;return (void 0!==r&&r)===this.ordered},r.prototype.isDisabled=function(r){return null==r.selection||!!t.DomEditor.getSelectedElems(r).some((function(t){if(e.Editor.isVoid(r,t)&&e.Editor.isBlock(r,t))return !0;var n=t.type;return !!["pre","code","table"].includes(n)||void 0}))},r.prototype.exec=function(t,r){this.isActive(t)?e.Transforms.setNodes(t,{type:"paragraph",ordered:void 0,level:void 0}):e.Transforms.setNodes(t,{type:"list-item",ordered:this.ordered,indent:void 0});},r}(),Yo='<svg viewBox="0 0 1024 1024"><path d="M384 64h640v128H384V64z m0 384h640v128H384v-128z m0 384h640v128H384v-128zM0 128a128 128 0 1 1 256 0 128 128 0 0 1-256 0z m0 384a128 128 0 1 1 256 0 128 128 0 0 1-256 0z m0
|
|||
|
|
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Lodash (Custom Build) <https://lodash.com/>
|
|||
|
|
* Build: `lodash modularize exports="npm" -o ./`
|
|||
|
|
* Copyright JS Foundation and other contributors <https://js.foundation/>
|
|||
|
|
* Released under MIT license <https://lodash.com/license>
|
|||
|
|
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
|
|||
|
|
* Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
var lodash_isequal = createCommonjsModule$1(function (module, exports) {
|
|||
|
|
/** Used as the size to enable large array optimizations. */
|
|||
|
|
var LARGE_ARRAY_SIZE = 200;
|
|||
|
|
|
|||
|
|
/** Used to stand-in for `undefined` hash values. */
|
|||
|
|
var HASH_UNDEFINED = '__lodash_hash_undefined__';
|
|||
|
|
|
|||
|
|
/** Used to compose bitmasks for value comparisons. */
|
|||
|
|
var COMPARE_PARTIAL_FLAG = 1,
|
|||
|
|
COMPARE_UNORDERED_FLAG = 2;
|
|||
|
|
|
|||
|
|
/** Used as references for various `Number` constants. */
|
|||
|
|
var MAX_SAFE_INTEGER = 9007199254740991;
|
|||
|
|
|
|||
|
|
/** `Object#toString` result references. */
|
|||
|
|
var argsTag = '[object Arguments]',
|
|||
|
|
arrayTag = '[object Array]',
|
|||
|
|
asyncTag = '[object AsyncFunction]',
|
|||
|
|
boolTag = '[object Boolean]',
|
|||
|
|
dateTag = '[object Date]',
|
|||
|
|
errorTag = '[object Error]',
|
|||
|
|
funcTag = '[object Function]',
|
|||
|
|
genTag = '[object GeneratorFunction]',
|
|||
|
|
mapTag = '[object Map]',
|
|||
|
|
numberTag = '[object Number]',
|
|||
|
|
nullTag = '[object Null]',
|
|||
|
|
objectTag = '[object Object]',
|
|||
|
|
promiseTag = '[object Promise]',
|
|||
|
|
proxyTag = '[object Proxy]',
|
|||
|
|
regexpTag = '[object RegExp]',
|
|||
|
|
setTag = '[object Set]',
|
|||
|
|
stringTag = '[object String]',
|
|||
|
|
symbolTag = '[object Symbol]',
|
|||
|
|
undefinedTag = '[object Undefined]',
|
|||
|
|
weakMapTag = '[object WeakMap]';
|
|||
|
|
|
|||
|
|
var arrayBufferTag = '[object ArrayBuffer]',
|
|||
|
|
dataViewTag = '[object DataView]',
|
|||
|
|
float32Tag = '[object Float32Array]',
|
|||
|
|
float64Tag = '[object Float64Array]',
|
|||
|
|
int8Tag = '[object Int8Array]',
|
|||
|
|
int16Tag = '[object Int16Array]',
|
|||
|
|
int32Tag = '[object Int32Array]',
|
|||
|
|
uint8Tag = '[object Uint8Array]',
|
|||
|
|
uint8ClampedTag = '[object Uint8ClampedArray]',
|
|||
|
|
uint16Tag = '[object Uint16Array]',
|
|||
|
|
uint32Tag = '[object Uint32Array]';
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Used to match `RegExp`
|
|||
|
|
* [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
|
|||
|
|
*/
|
|||
|
|
var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
|
|||
|
|
|
|||
|
|
/** Used to detect host constructors (Safari). */
|
|||
|
|
var reIsHostCtor = /^\[object .+?Constructor\]$/;
|
|||
|
|
|
|||
|
|
/** Used to detect unsigned integer values. */
|
|||
|
|
var reIsUint = /^(?:0|[1-9]\d*)$/;
|
|||
|
|
|
|||
|
|
/** Used to identify `toStringTag` values of typed arrays. */
|
|||
|
|
var typedArrayTags = {};
|
|||
|
|
typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
|
|||
|
|
typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
|
|||
|
|
typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
|
|||
|
|
typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
|
|||
|
|
typedArrayTags[uint32Tag] = true;
|
|||
|
|
typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
|
|||
|
|
typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
|
|||
|
|
typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =
|
|||
|
|
typedArrayTags[errorTag] = typedArrayTags[funcTag] =
|
|||
|
|
typedArrayTags[mapTag] = typedArrayTags[numberTag] =
|
|||
|
|
typedArrayTags[objectTag] = typedArrayTags[regexpTag] =
|
|||
|
|
typedArrayTags[setTag] = typedArrayTags[stringTag] =
|
|||
|
|
typedArrayTags[weakMapTag] = false;
|
|||
|
|
|
|||
|
|
/** Detect free variable `global` from Node.js. */
|
|||
|
|
var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;
|
|||
|
|
|
|||
|
|
/** Detect free variable `self`. */
|
|||
|
|
var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
|
|||
|
|
|
|||
|
|
/** Used as a reference to the global object. */
|
|||
|
|
var root = freeGlobal || freeSelf || Function('return this')();
|
|||
|
|
|
|||
|
|
/** Detect free variable `exports`. */
|
|||
|
|
var freeExports = exports && !exports.nodeType && exports;
|
|||
|
|
|
|||
|
|
/** Detect free variable `module`. */
|
|||
|
|
var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module;
|
|||
|
|
|
|||
|
|
/** Detect the popular CommonJS extension `module.exports`. */
|
|||
|
|
var moduleExports = freeModule && freeModule.exports === freeExports;
|
|||
|
|
|
|||
|
|
/** Detect free variable `process` from Node.js. */
|
|||
|
|
var freeProcess = moduleExports && freeGlobal.process;
|
|||
|
|
|
|||
|
|
/** Used to access faster Node.js helpers. */
|
|||
|
|
var nodeUtil = (function() {
|
|||
|
|
try {
|
|||
|
|
return freeProcess && freeProcess.binding && freeProcess.binding('util');
|
|||
|
|
} catch (e) {}
|
|||
|
|
}());
|
|||
|
|
|
|||
|
|
/* Node.js helper references. */
|
|||
|
|
var nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* A specialized version of `_.filter` for arrays without support for
|
|||
|
|
* iteratee shorthands.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Array} [array] The array to iterate over.
|
|||
|
|
* @param {Function} predicate The function invoked per iteration.
|
|||
|
|
* @returns {Array} Returns the new filtered array.
|
|||
|
|
*/
|
|||
|
|
function arrayFilter(array, predicate) {
|
|||
|
|
var index = -1,
|
|||
|
|
length = array == null ? 0 : array.length,
|
|||
|
|
resIndex = 0,
|
|||
|
|
result = [];
|
|||
|
|
|
|||
|
|
while (++index < length) {
|
|||
|
|
var value = array[index];
|
|||
|
|
if (predicate(value, index, array)) {
|
|||
|
|
result[resIndex++] = value;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Appends the elements of `values` to `array`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Array} array The array to modify.
|
|||
|
|
* @param {Array} values The values to append.
|
|||
|
|
* @returns {Array} Returns `array`.
|
|||
|
|
*/
|
|||
|
|
function arrayPush(array, values) {
|
|||
|
|
var index = -1,
|
|||
|
|
length = values.length,
|
|||
|
|
offset = array.length;
|
|||
|
|
|
|||
|
|
while (++index < length) {
|
|||
|
|
array[offset + index] = values[index];
|
|||
|
|
}
|
|||
|
|
return array;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* A specialized version of `_.some` for arrays without support for iteratee
|
|||
|
|
* shorthands.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Array} [array] The array to iterate over.
|
|||
|
|
* @param {Function} predicate The function invoked per iteration.
|
|||
|
|
* @returns {boolean} Returns `true` if any element passes the predicate check,
|
|||
|
|
* else `false`.
|
|||
|
|
*/
|
|||
|
|
function arraySome(array, predicate) {
|
|||
|
|
var index = -1,
|
|||
|
|
length = array == null ? 0 : array.length;
|
|||
|
|
|
|||
|
|
while (++index < length) {
|
|||
|
|
if (predicate(array[index], index, array)) {
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* The base implementation of `_.times` without support for iteratee shorthands
|
|||
|
|
* or max array length checks.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {number} n The number of times to invoke `iteratee`.
|
|||
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|||
|
|
* @returns {Array} Returns the array of results.
|
|||
|
|
*/
|
|||
|
|
function baseTimes(n, iteratee) {
|
|||
|
|
var index = -1,
|
|||
|
|
result = Array(n);
|
|||
|
|
|
|||
|
|
while (++index < n) {
|
|||
|
|
result[index] = iteratee(index);
|
|||
|
|
}
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* The base implementation of `_.unary` without support for storing metadata.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Function} func The function to cap arguments for.
|
|||
|
|
* @returns {Function} Returns the new capped function.
|
|||
|
|
*/
|
|||
|
|
function baseUnary(func) {
|
|||
|
|
return function(value) {
|
|||
|
|
return func(value);
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if a `cache` value for `key` exists.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Object} cache The cache to query.
|
|||
|
|
* @param {string} key The key of the entry to check.
|
|||
|
|
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
|
|||
|
|
*/
|
|||
|
|
function cacheHas(cache, key) {
|
|||
|
|
return cache.has(key);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Gets the value at `key` of `object`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Object} [object] The object to query.
|
|||
|
|
* @param {string} key The key of the property to get.
|
|||
|
|
* @returns {*} Returns the property value.
|
|||
|
|
*/
|
|||
|
|
function getValue(object, key) {
|
|||
|
|
return object == null ? undefined : object[key];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Converts `map` to its key-value pairs.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Object} map The map to convert.
|
|||
|
|
* @returns {Array} Returns the key-value pairs.
|
|||
|
|
*/
|
|||
|
|
function mapToArray(map) {
|
|||
|
|
var index = -1,
|
|||
|
|
result = Array(map.size);
|
|||
|
|
|
|||
|
|
map.forEach(function(value, key) {
|
|||
|
|
result[++index] = [key, value];
|
|||
|
|
});
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Creates a unary function that invokes `func` with its argument transformed.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Function} func The function to wrap.
|
|||
|
|
* @param {Function} transform The argument transform.
|
|||
|
|
* @returns {Function} Returns the new function.
|
|||
|
|
*/
|
|||
|
|
function overArg(func, transform) {
|
|||
|
|
return function(arg) {
|
|||
|
|
return func(transform(arg));
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Converts `set` to an array of its values.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Object} set The set to convert.
|
|||
|
|
* @returns {Array} Returns the values.
|
|||
|
|
*/
|
|||
|
|
function setToArray(set) {
|
|||
|
|
var index = -1,
|
|||
|
|
result = Array(set.size);
|
|||
|
|
|
|||
|
|
set.forEach(function(value) {
|
|||
|
|
result[++index] = value;
|
|||
|
|
});
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/** Used for built-in method references. */
|
|||
|
|
var arrayProto = Array.prototype,
|
|||
|
|
funcProto = Function.prototype,
|
|||
|
|
objectProto = Object.prototype;
|
|||
|
|
|
|||
|
|
/** Used to detect overreaching core-js shims. */
|
|||
|
|
var coreJsData = root['__core-js_shared__'];
|
|||
|
|
|
|||
|
|
/** Used to resolve the decompiled source of functions. */
|
|||
|
|
var funcToString = funcProto.toString;
|
|||
|
|
|
|||
|
|
/** Used to check objects for own properties. */
|
|||
|
|
var hasOwnProperty = objectProto.hasOwnProperty;
|
|||
|
|
|
|||
|
|
/** Used to detect methods masquerading as native. */
|
|||
|
|
var maskSrcKey = (function() {
|
|||
|
|
var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
|
|||
|
|
return uid ? ('Symbol(src)_1.' + uid) : '';
|
|||
|
|
}());
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Used to resolve the
|
|||
|
|
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
|
|||
|
|
* of values.
|
|||
|
|
*/
|
|||
|
|
var nativeObjectToString = objectProto.toString;
|
|||
|
|
|
|||
|
|
/** Used to detect if a method is native. */
|
|||
|
|
var reIsNative = RegExp('^' +
|
|||
|
|
funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
|
|||
|
|
.replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
/** Built-in value references. */
|
|||
|
|
var Buffer = moduleExports ? root.Buffer : undefined,
|
|||
|
|
Symbol = root.Symbol,
|
|||
|
|
Uint8Array = root.Uint8Array,
|
|||
|
|
propertyIsEnumerable = objectProto.propertyIsEnumerable,
|
|||
|
|
splice = arrayProto.splice,
|
|||
|
|
symToStringTag = Symbol ? Symbol.toStringTag : undefined;
|
|||
|
|
|
|||
|
|
/* Built-in method references for those with the same name as other `lodash` methods. */
|
|||
|
|
var nativeGetSymbols = Object.getOwnPropertySymbols,
|
|||
|
|
nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined,
|
|||
|
|
nativeKeys = overArg(Object.keys, Object);
|
|||
|
|
|
|||
|
|
/* Built-in method references that are verified to be native. */
|
|||
|
|
var DataView = getNative(root, 'DataView'),
|
|||
|
|
Map = getNative(root, 'Map'),
|
|||
|
|
Promise = getNative(root, 'Promise'),
|
|||
|
|
Set = getNative(root, 'Set'),
|
|||
|
|
WeakMap = getNative(root, 'WeakMap'),
|
|||
|
|
nativeCreate = getNative(Object, 'create');
|
|||
|
|
|
|||
|
|
/** Used to detect maps, sets, and weakmaps. */
|
|||
|
|
var dataViewCtorString = toSource(DataView),
|
|||
|
|
mapCtorString = toSource(Map),
|
|||
|
|
promiseCtorString = toSource(Promise),
|
|||
|
|
setCtorString = toSource(Set),
|
|||
|
|
weakMapCtorString = toSource(WeakMap);
|
|||
|
|
|
|||
|
|
/** Used to convert symbols to primitives and strings. */
|
|||
|
|
var symbolProto = Symbol ? Symbol.prototype : undefined,
|
|||
|
|
symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Creates a hash object.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @constructor
|
|||
|
|
* @param {Array} [entries] The key-value pairs to cache.
|
|||
|
|
*/
|
|||
|
|
function Hash(entries) {
|
|||
|
|
var index = -1,
|
|||
|
|
length = entries == null ? 0 : entries.length;
|
|||
|
|
|
|||
|
|
this.clear();
|
|||
|
|
while (++index < length) {
|
|||
|
|
var entry = entries[index];
|
|||
|
|
this.set(entry[0], entry[1]);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Removes all key-value entries from the hash.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @name clear
|
|||
|
|
* @memberOf Hash
|
|||
|
|
*/
|
|||
|
|
function hashClear() {
|
|||
|
|
this.__data__ = nativeCreate ? nativeCreate(null) : {};
|
|||
|
|
this.size = 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Removes `key` and its value from the hash.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @name delete
|
|||
|
|
* @memberOf Hash
|
|||
|
|
* @param {Object} hash The hash to modify.
|
|||
|
|
* @param {string} key The key of the value to remove.
|
|||
|
|
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
|
|||
|
|
*/
|
|||
|
|
function hashDelete(key) {
|
|||
|
|
var result = this.has(key) && delete this.__data__[key];
|
|||
|
|
this.size -= result ? 1 : 0;
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Gets the hash value for `key`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @name get
|
|||
|
|
* @memberOf Hash
|
|||
|
|
* @param {string} key The key of the value to get.
|
|||
|
|
* @returns {*} Returns the entry value.
|
|||
|
|
*/
|
|||
|
|
function hashGet(key) {
|
|||
|
|
var data = this.__data__;
|
|||
|
|
if (nativeCreate) {
|
|||
|
|
var result = data[key];
|
|||
|
|
return result === HASH_UNDEFINED ? undefined : result;
|
|||
|
|
}
|
|||
|
|
return hasOwnProperty.call(data, key) ? data[key] : undefined;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if a hash value for `key` exists.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @name has
|
|||
|
|
* @memberOf Hash
|
|||
|
|
* @param {string} key The key of the entry to check.
|
|||
|
|
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
|
|||
|
|
*/
|
|||
|
|
function hashHas(key) {
|
|||
|
|
var data = this.__data__;
|
|||
|
|
return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Sets the hash `key` to `value`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @name set
|
|||
|
|
* @memberOf Hash
|
|||
|
|
* @param {string} key The key of the value to set.
|
|||
|
|
* @param {*} value The value to set.
|
|||
|
|
* @returns {Object} Returns the hash instance.
|
|||
|
|
*/
|
|||
|
|
function hashSet(key, value) {
|
|||
|
|
var data = this.__data__;
|
|||
|
|
this.size += this.has(key) ? 0 : 1;
|
|||
|
|
data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Add methods to `Hash`.
|
|||
|
|
Hash.prototype.clear = hashClear;
|
|||
|
|
Hash.prototype['delete'] = hashDelete;
|
|||
|
|
Hash.prototype.get = hashGet;
|
|||
|
|
Hash.prototype.has = hashHas;
|
|||
|
|
Hash.prototype.set = hashSet;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Creates an list cache object.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @constructor
|
|||
|
|
* @param {Array} [entries] The key-value pairs to cache.
|
|||
|
|
*/
|
|||
|
|
function ListCache(entries) {
|
|||
|
|
var index = -1,
|
|||
|
|
length = entries == null ? 0 : entries.length;
|
|||
|
|
|
|||
|
|
this.clear();
|
|||
|
|
while (++index < length) {
|
|||
|
|
var entry = entries[index];
|
|||
|
|
this.set(entry[0], entry[1]);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Removes all key-value entries from the list cache.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @name clear
|
|||
|
|
* @memberOf ListCache
|
|||
|
|
*/
|
|||
|
|
function listCacheClear() {
|
|||
|
|
this.__data__ = [];
|
|||
|
|
this.size = 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Removes `key` and its value from the list cache.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @name delete
|
|||
|
|
* @memberOf ListCache
|
|||
|
|
* @param {string} key The key of the value to remove.
|
|||
|
|
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
|
|||
|
|
*/
|
|||
|
|
function listCacheDelete(key) {
|
|||
|
|
var data = this.__data__,
|
|||
|
|
index = assocIndexOf(data, key);
|
|||
|
|
|
|||
|
|
if (index < 0) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
var lastIndex = data.length - 1;
|
|||
|
|
if (index == lastIndex) {
|
|||
|
|
data.pop();
|
|||
|
|
} else {
|
|||
|
|
splice.call(data, index, 1);
|
|||
|
|
}
|
|||
|
|
--this.size;
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Gets the list cache value for `key`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @name get
|
|||
|
|
* @memberOf ListCache
|
|||
|
|
* @param {string} key The key of the value to get.
|
|||
|
|
* @returns {*} Returns the entry value.
|
|||
|
|
*/
|
|||
|
|
function listCacheGet(key) {
|
|||
|
|
var data = this.__data__,
|
|||
|
|
index = assocIndexOf(data, key);
|
|||
|
|
|
|||
|
|
return index < 0 ? undefined : data[index][1];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if a list cache value for `key` exists.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @name has
|
|||
|
|
* @memberOf ListCache
|
|||
|
|
* @param {string} key The key of the entry to check.
|
|||
|
|
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
|
|||
|
|
*/
|
|||
|
|
function listCacheHas(key) {
|
|||
|
|
return assocIndexOf(this.__data__, key) > -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Sets the list cache `key` to `value`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @name set
|
|||
|
|
* @memberOf ListCache
|
|||
|
|
* @param {string} key The key of the value to set.
|
|||
|
|
* @param {*} value The value to set.
|
|||
|
|
* @returns {Object} Returns the list cache instance.
|
|||
|
|
*/
|
|||
|
|
function listCacheSet(key, value) {
|
|||
|
|
var data = this.__data__,
|
|||
|
|
index = assocIndexOf(data, key);
|
|||
|
|
|
|||
|
|
if (index < 0) {
|
|||
|
|
++this.size;
|
|||
|
|
data.push([key, value]);
|
|||
|
|
} else {
|
|||
|
|
data[index][1] = value;
|
|||
|
|
}
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Add methods to `ListCache`.
|
|||
|
|
ListCache.prototype.clear = listCacheClear;
|
|||
|
|
ListCache.prototype['delete'] = listCacheDelete;
|
|||
|
|
ListCache.prototype.get = listCacheGet;
|
|||
|
|
ListCache.prototype.has = listCacheHas;
|
|||
|
|
ListCache.prototype.set = listCacheSet;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Creates a map cache object to store key-value pairs.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @constructor
|
|||
|
|
* @param {Array} [entries] The key-value pairs to cache.
|
|||
|
|
*/
|
|||
|
|
function MapCache(entries) {
|
|||
|
|
var index = -1,
|
|||
|
|
length = entries == null ? 0 : entries.length;
|
|||
|
|
|
|||
|
|
this.clear();
|
|||
|
|
while (++index < length) {
|
|||
|
|
var entry = entries[index];
|
|||
|
|
this.set(entry[0], entry[1]);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Removes all key-value entries from the map.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @name clear
|
|||
|
|
* @memberOf MapCache
|
|||
|
|
*/
|
|||
|
|
function mapCacheClear() {
|
|||
|
|
this.size = 0;
|
|||
|
|
this.__data__ = {
|
|||
|
|
'hash': new Hash,
|
|||
|
|
'map': new (Map || ListCache),
|
|||
|
|
'string': new Hash
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Removes `key` and its value from the map.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @name delete
|
|||
|
|
* @memberOf MapCache
|
|||
|
|
* @param {string} key The key of the value to remove.
|
|||
|
|
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
|
|||
|
|
*/
|
|||
|
|
function mapCacheDelete(key) {
|
|||
|
|
var result = getMapData(this, key)['delete'](key);
|
|||
|
|
this.size -= result ? 1 : 0;
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Gets the map value for `key`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @name get
|
|||
|
|
* @memberOf MapCache
|
|||
|
|
* @param {string} key The key of the value to get.
|
|||
|
|
* @returns {*} Returns the entry value.
|
|||
|
|
*/
|
|||
|
|
function mapCacheGet(key) {
|
|||
|
|
return getMapData(this, key).get(key);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if a map value for `key` exists.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @name has
|
|||
|
|
* @memberOf MapCache
|
|||
|
|
* @param {string} key The key of the entry to check.
|
|||
|
|
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
|
|||
|
|
*/
|
|||
|
|
function mapCacheHas(key) {
|
|||
|
|
return getMapData(this, key).has(key);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Sets the map `key` to `value`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @name set
|
|||
|
|
* @memberOf MapCache
|
|||
|
|
* @param {string} key The key of the value to set.
|
|||
|
|
* @param {*} value The value to set.
|
|||
|
|
* @returns {Object} Returns the map cache instance.
|
|||
|
|
*/
|
|||
|
|
function mapCacheSet(key, value) {
|
|||
|
|
var data = getMapData(this, key),
|
|||
|
|
size = data.size;
|
|||
|
|
|
|||
|
|
data.set(key, value);
|
|||
|
|
this.size += data.size == size ? 0 : 1;
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Add methods to `MapCache`.
|
|||
|
|
MapCache.prototype.clear = mapCacheClear;
|
|||
|
|
MapCache.prototype['delete'] = mapCacheDelete;
|
|||
|
|
MapCache.prototype.get = mapCacheGet;
|
|||
|
|
MapCache.prototype.has = mapCacheHas;
|
|||
|
|
MapCache.prototype.set = mapCacheSet;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
*
|
|||
|
|
* Creates an array cache object to store unique values.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @constructor
|
|||
|
|
* @param {Array} [values] The values to cache.
|
|||
|
|
*/
|
|||
|
|
function SetCache(values) {
|
|||
|
|
var index = -1,
|
|||
|
|
length = values == null ? 0 : values.length;
|
|||
|
|
|
|||
|
|
this.__data__ = new MapCache;
|
|||
|
|
while (++index < length) {
|
|||
|
|
this.add(values[index]);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Adds `value` to the array cache.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @name add
|
|||
|
|
* @memberOf SetCache
|
|||
|
|
* @alias push
|
|||
|
|
* @param {*} value The value to cache.
|
|||
|
|
* @returns {Object} Returns the cache instance.
|
|||
|
|
*/
|
|||
|
|
function setCacheAdd(value) {
|
|||
|
|
this.__data__.set(value, HASH_UNDEFINED);
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is in the array cache.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @name has
|
|||
|
|
* @memberOf SetCache
|
|||
|
|
* @param {*} value The value to search for.
|
|||
|
|
* @returns {number} Returns `true` if `value` is found, else `false`.
|
|||
|
|
*/
|
|||
|
|
function setCacheHas(value) {
|
|||
|
|
return this.__data__.has(value);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Add methods to `SetCache`.
|
|||
|
|
SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;
|
|||
|
|
SetCache.prototype.has = setCacheHas;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Creates a stack cache object to store key-value pairs.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @constructor
|
|||
|
|
* @param {Array} [entries] The key-value pairs to cache.
|
|||
|
|
*/
|
|||
|
|
function Stack(entries) {
|
|||
|
|
var data = this.__data__ = new ListCache(entries);
|
|||
|
|
this.size = data.size;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Removes all key-value entries from the stack.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @name clear
|
|||
|
|
* @memberOf Stack
|
|||
|
|
*/
|
|||
|
|
function stackClear() {
|
|||
|
|
this.__data__ = new ListCache;
|
|||
|
|
this.size = 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Removes `key` and its value from the stack.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @name delete
|
|||
|
|
* @memberOf Stack
|
|||
|
|
* @param {string} key The key of the value to remove.
|
|||
|
|
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
|
|||
|
|
*/
|
|||
|
|
function stackDelete(key) {
|
|||
|
|
var data = this.__data__,
|
|||
|
|
result = data['delete'](key);
|
|||
|
|
|
|||
|
|
this.size = data.size;
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Gets the stack value for `key`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @name get
|
|||
|
|
* @memberOf Stack
|
|||
|
|
* @param {string} key The key of the value to get.
|
|||
|
|
* @returns {*} Returns the entry value.
|
|||
|
|
*/
|
|||
|
|
function stackGet(key) {
|
|||
|
|
return this.__data__.get(key);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if a stack value for `key` exists.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @name has
|
|||
|
|
* @memberOf Stack
|
|||
|
|
* @param {string} key The key of the entry to check.
|
|||
|
|
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
|
|||
|
|
*/
|
|||
|
|
function stackHas(key) {
|
|||
|
|
return this.__data__.has(key);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Sets the stack `key` to `value`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @name set
|
|||
|
|
* @memberOf Stack
|
|||
|
|
* @param {string} key The key of the value to set.
|
|||
|
|
* @param {*} value The value to set.
|
|||
|
|
* @returns {Object} Returns the stack cache instance.
|
|||
|
|
*/
|
|||
|
|
function stackSet(key, value) {
|
|||
|
|
var data = this.__data__;
|
|||
|
|
if (data instanceof ListCache) {
|
|||
|
|
var pairs = data.__data__;
|
|||
|
|
if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
|
|||
|
|
pairs.push([key, value]);
|
|||
|
|
this.size = ++data.size;
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
data = this.__data__ = new MapCache(pairs);
|
|||
|
|
}
|
|||
|
|
data.set(key, value);
|
|||
|
|
this.size = data.size;
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Add methods to `Stack`.
|
|||
|
|
Stack.prototype.clear = stackClear;
|
|||
|
|
Stack.prototype['delete'] = stackDelete;
|
|||
|
|
Stack.prototype.get = stackGet;
|
|||
|
|
Stack.prototype.has = stackHas;
|
|||
|
|
Stack.prototype.set = stackSet;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Creates an array of the enumerable property names of the array-like `value`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {*} value The value to query.
|
|||
|
|
* @param {boolean} inherited Specify returning inherited property names.
|
|||
|
|
* @returns {Array} Returns the array of property names.
|
|||
|
|
*/
|
|||
|
|
function arrayLikeKeys(value, inherited) {
|
|||
|
|
var isArr = isArray(value),
|
|||
|
|
isArg = !isArr && isArguments(value),
|
|||
|
|
isBuff = !isArr && !isArg && isBuffer(value),
|
|||
|
|
isType = !isArr && !isArg && !isBuff && isTypedArray(value),
|
|||
|
|
skipIndexes = isArr || isArg || isBuff || isType,
|
|||
|
|
result = skipIndexes ? baseTimes(value.length, String) : [],
|
|||
|
|
length = result.length;
|
|||
|
|
|
|||
|
|
for (var key in value) {
|
|||
|
|
if ((inherited || hasOwnProperty.call(value, key)) &&
|
|||
|
|
!(skipIndexes && (
|
|||
|
|
// Safari 9 has enumerable `arguments.length` in strict mode.
|
|||
|
|
key == 'length' ||
|
|||
|
|
// Node.js 0.10 has enumerable non-index properties on buffers.
|
|||
|
|
(isBuff && (key == 'offset' || key == 'parent')) ||
|
|||
|
|
// PhantomJS 2 has enumerable non-index properties on typed arrays.
|
|||
|
|
(isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||
|
|||
|
|
// Skip index properties.
|
|||
|
|
isIndex(key, length)
|
|||
|
|
))) {
|
|||
|
|
result.push(key);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Gets the index at which the `key` is found in `array` of key-value pairs.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Array} array The array to inspect.
|
|||
|
|
* @param {*} key The key to search for.
|
|||
|
|
* @returns {number} Returns the index of the matched value, else `-1`.
|
|||
|
|
*/
|
|||
|
|
function assocIndexOf(array, key) {
|
|||
|
|
var length = array.length;
|
|||
|
|
while (length--) {
|
|||
|
|
if (eq(array[length][0], key)) {
|
|||
|
|
return length;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* The base implementation of `getAllKeys` and `getAllKeysIn` which uses
|
|||
|
|
* `keysFunc` and `symbolsFunc` to get the enumerable property names and
|
|||
|
|
* symbols of `object`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Object} object The object to query.
|
|||
|
|
* @param {Function} keysFunc The function to get the keys of `object`.
|
|||
|
|
* @param {Function} symbolsFunc The function to get the symbols of `object`.
|
|||
|
|
* @returns {Array} Returns the array of property names and symbols.
|
|||
|
|
*/
|
|||
|
|
function baseGetAllKeys(object, keysFunc, symbolsFunc) {
|
|||
|
|
var result = keysFunc(object);
|
|||
|
|
return isArray(object) ? result : arrayPush(result, symbolsFunc(object));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* The base implementation of `getTag` without fallbacks for buggy environments.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {*} value The value to query.
|
|||
|
|
* @returns {string} Returns the `toStringTag`.
|
|||
|
|
*/
|
|||
|
|
function baseGetTag(value) {
|
|||
|
|
if (value == null) {
|
|||
|
|
return value === undefined ? undefinedTag : nullTag;
|
|||
|
|
}
|
|||
|
|
return (symToStringTag && symToStringTag in Object(value))
|
|||
|
|
? getRawTag(value)
|
|||
|
|
: objectToString(value);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* The base implementation of `_.isArguments`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is an `arguments` object,
|
|||
|
|
*/
|
|||
|
|
function baseIsArguments(value) {
|
|||
|
|
return isObjectLike(value) && baseGetTag(value) == argsTag;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* The base implementation of `_.isEqual` which supports partial comparisons
|
|||
|
|
* and tracks traversed objects.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {*} value The value to compare.
|
|||
|
|
* @param {*} other The other value to compare.
|
|||
|
|
* @param {boolean} bitmask The bitmask flags.
|
|||
|
|
* 1 - Unordered comparison
|
|||
|
|
* 2 - Partial comparison
|
|||
|
|
* @param {Function} [customizer] The function to customize comparisons.
|
|||
|
|
* @param {Object} [stack] Tracks traversed `value` and `other` objects.
|
|||
|
|
* @returns {boolean} Returns `true` if the values are equivalent, else `false`.
|
|||
|
|
*/
|
|||
|
|
function baseIsEqual(value, other, bitmask, customizer, stack) {
|
|||
|
|
if (value === other) {
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {
|
|||
|
|
return value !== value && other !== other;
|
|||
|
|
}
|
|||
|
|
return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* A specialized version of `baseIsEqual` for arrays and objects which performs
|
|||
|
|
* deep comparisons and tracks traversed objects enabling objects with circular
|
|||
|
|
* references to be compared.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Object} object The object to compare.
|
|||
|
|
* @param {Object} other The other object to compare.
|
|||
|
|
* @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
|
|||
|
|
* @param {Function} customizer The function to customize comparisons.
|
|||
|
|
* @param {Function} equalFunc The function to determine equivalents of values.
|
|||
|
|
* @param {Object} [stack] Tracks traversed `object` and `other` objects.
|
|||
|
|
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
|
|||
|
|
*/
|
|||
|
|
function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {
|
|||
|
|
var objIsArr = isArray(object),
|
|||
|
|
othIsArr = isArray(other),
|
|||
|
|
objTag = objIsArr ? arrayTag : getTag(object),
|
|||
|
|
othTag = othIsArr ? arrayTag : getTag(other);
|
|||
|
|
|
|||
|
|
objTag = objTag == argsTag ? objectTag : objTag;
|
|||
|
|
othTag = othTag == argsTag ? objectTag : othTag;
|
|||
|
|
|
|||
|
|
var objIsObj = objTag == objectTag,
|
|||
|
|
othIsObj = othTag == objectTag,
|
|||
|
|
isSameTag = objTag == othTag;
|
|||
|
|
|
|||
|
|
if (isSameTag && isBuffer(object)) {
|
|||
|
|
if (!isBuffer(other)) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
objIsArr = true;
|
|||
|
|
objIsObj = false;
|
|||
|
|
}
|
|||
|
|
if (isSameTag && !objIsObj) {
|
|||
|
|
stack || (stack = new Stack);
|
|||
|
|
return (objIsArr || isTypedArray(object))
|
|||
|
|
? equalArrays(object, other, bitmask, customizer, equalFunc, stack)
|
|||
|
|
: equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);
|
|||
|
|
}
|
|||
|
|
if (!(bitmask & COMPARE_PARTIAL_FLAG)) {
|
|||
|
|
var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
|
|||
|
|
othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
|
|||
|
|
|
|||
|
|
if (objIsWrapped || othIsWrapped) {
|
|||
|
|
var objUnwrapped = objIsWrapped ? object.value() : object,
|
|||
|
|
othUnwrapped = othIsWrapped ? other.value() : other;
|
|||
|
|
|
|||
|
|
stack || (stack = new Stack);
|
|||
|
|
return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if (!isSameTag) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
stack || (stack = new Stack);
|
|||
|
|
return equalObjects(object, other, bitmask, customizer, equalFunc, stack);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* The base implementation of `_.isNative` without bad shim checks.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is a native function,
|
|||
|
|
* else `false`.
|
|||
|
|
*/
|
|||
|
|
function baseIsNative(value) {
|
|||
|
|
if (!isObject(value) || isMasked(value)) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
var pattern = isFunction(value) ? reIsNative : reIsHostCtor;
|
|||
|
|
return pattern.test(toSource(value));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* The base implementation of `_.isTypedArray` without Node.js optimizations.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
|
|||
|
|
*/
|
|||
|
|
function baseIsTypedArray(value) {
|
|||
|
|
return isObjectLike(value) &&
|
|||
|
|
isLength(value.length) && !!typedArrayTags[baseGetTag(value)];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Object} object The object to query.
|
|||
|
|
* @returns {Array} Returns the array of property names.
|
|||
|
|
*/
|
|||
|
|
function baseKeys(object) {
|
|||
|
|
if (!isPrototype(object)) {
|
|||
|
|
return nativeKeys(object);
|
|||
|
|
}
|
|||
|
|
var result = [];
|
|||
|
|
for (var key in Object(object)) {
|
|||
|
|
if (hasOwnProperty.call(object, key) && key != 'constructor') {
|
|||
|
|
result.push(key);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* A specialized version of `baseIsEqualDeep` for arrays with support for
|
|||
|
|
* partial deep comparisons.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Array} array The array to compare.
|
|||
|
|
* @param {Array} other The other array to compare.
|
|||
|
|
* @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
|
|||
|
|
* @param {Function} customizer The function to customize comparisons.
|
|||
|
|
* @param {Function} equalFunc The function to determine equivalents of values.
|
|||
|
|
* @param {Object} stack Tracks traversed `array` and `other` objects.
|
|||
|
|
* @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
|
|||
|
|
*/
|
|||
|
|
function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {
|
|||
|
|
var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
|
|||
|
|
arrLength = array.length,
|
|||
|
|
othLength = other.length;
|
|||
|
|
|
|||
|
|
if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
// Assume cyclic values are equal.
|
|||
|
|
var stacked = stack.get(array);
|
|||
|
|
if (stacked && stack.get(other)) {
|
|||
|
|
return stacked == other;
|
|||
|
|
}
|
|||
|
|
var index = -1,
|
|||
|
|
result = true,
|
|||
|
|
seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;
|
|||
|
|
|
|||
|
|
stack.set(array, other);
|
|||
|
|
stack.set(other, array);
|
|||
|
|
|
|||
|
|
// Ignore non-index properties.
|
|||
|
|
while (++index < arrLength) {
|
|||
|
|
var arrValue = array[index],
|
|||
|
|
othValue = other[index];
|
|||
|
|
|
|||
|
|
if (customizer) {
|
|||
|
|
var compared = isPartial
|
|||
|
|
? customizer(othValue, arrValue, index, other, array, stack)
|
|||
|
|
: customizer(arrValue, othValue, index, array, other, stack);
|
|||
|
|
}
|
|||
|
|
if (compared !== undefined) {
|
|||
|
|
if (compared) {
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
result = false;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
// Recursively compare arrays (susceptible to call stack limits).
|
|||
|
|
if (seen) {
|
|||
|
|
if (!arraySome(other, function(othValue, othIndex) {
|
|||
|
|
if (!cacheHas(seen, othIndex) &&
|
|||
|
|
(arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {
|
|||
|
|
return seen.push(othIndex);
|
|||
|
|
}
|
|||
|
|
})) {
|
|||
|
|
result = false;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
} else if (!(
|
|||
|
|
arrValue === othValue ||
|
|||
|
|
equalFunc(arrValue, othValue, bitmask, customizer, stack)
|
|||
|
|
)) {
|
|||
|
|
result = false;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
stack['delete'](array);
|
|||
|
|
stack['delete'](other);
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* A specialized version of `baseIsEqualDeep` for comparing objects of
|
|||
|
|
* the same `toStringTag`.
|
|||
|
|
*
|
|||
|
|
* **Note:** This function only supports comparing values with tags of
|
|||
|
|
* `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Object} object The object to compare.
|
|||
|
|
* @param {Object} other The other object to compare.
|
|||
|
|
* @param {string} tag The `toStringTag` of the objects to compare.
|
|||
|
|
* @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
|
|||
|
|
* @param {Function} customizer The function to customize comparisons.
|
|||
|
|
* @param {Function} equalFunc The function to determine equivalents of values.
|
|||
|
|
* @param {Object} stack Tracks traversed `object` and `other` objects.
|
|||
|
|
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
|
|||
|
|
*/
|
|||
|
|
function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {
|
|||
|
|
switch (tag) {
|
|||
|
|
case dataViewTag:
|
|||
|
|
if ((object.byteLength != other.byteLength) ||
|
|||
|
|
(object.byteOffset != other.byteOffset)) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
object = object.buffer;
|
|||
|
|
other = other.buffer;
|
|||
|
|
|
|||
|
|
case arrayBufferTag:
|
|||
|
|
if ((object.byteLength != other.byteLength) ||
|
|||
|
|
!equalFunc(new Uint8Array(object), new Uint8Array(other))) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
return true;
|
|||
|
|
|
|||
|
|
case boolTag:
|
|||
|
|
case dateTag:
|
|||
|
|
case numberTag:
|
|||
|
|
// Coerce booleans to `1` or `0` and dates to milliseconds.
|
|||
|
|
// Invalid dates are coerced to `NaN`.
|
|||
|
|
return eq(+object, +other);
|
|||
|
|
|
|||
|
|
case errorTag:
|
|||
|
|
return object.name == other.name && object.message == other.message;
|
|||
|
|
|
|||
|
|
case regexpTag:
|
|||
|
|
case stringTag:
|
|||
|
|
// Coerce regexes to strings and treat strings, primitives and objects,
|
|||
|
|
// as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring
|
|||
|
|
// for more details.
|
|||
|
|
return object == (other + '');
|
|||
|
|
|
|||
|
|
case mapTag:
|
|||
|
|
var convert = mapToArray;
|
|||
|
|
|
|||
|
|
case setTag:
|
|||
|
|
var isPartial = bitmask & COMPARE_PARTIAL_FLAG;
|
|||
|
|
convert || (convert = setToArray);
|
|||
|
|
|
|||
|
|
if (object.size != other.size && !isPartial) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
// Assume cyclic values are equal.
|
|||
|
|
var stacked = stack.get(object);
|
|||
|
|
if (stacked) {
|
|||
|
|
return stacked == other;
|
|||
|
|
}
|
|||
|
|
bitmask |= COMPARE_UNORDERED_FLAG;
|
|||
|
|
|
|||
|
|
// Recursively compare objects (susceptible to call stack limits).
|
|||
|
|
stack.set(object, other);
|
|||
|
|
var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);
|
|||
|
|
stack['delete'](object);
|
|||
|
|
return result;
|
|||
|
|
|
|||
|
|
case symbolTag:
|
|||
|
|
if (symbolValueOf) {
|
|||
|
|
return symbolValueOf.call(object) == symbolValueOf.call(other);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* A specialized version of `baseIsEqualDeep` for objects with support for
|
|||
|
|
* partial deep comparisons.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Object} object The object to compare.
|
|||
|
|
* @param {Object} other The other object to compare.
|
|||
|
|
* @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
|
|||
|
|
* @param {Function} customizer The function to customize comparisons.
|
|||
|
|
* @param {Function} equalFunc The function to determine equivalents of values.
|
|||
|
|
* @param {Object} stack Tracks traversed `object` and `other` objects.
|
|||
|
|
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
|
|||
|
|
*/
|
|||
|
|
function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {
|
|||
|
|
var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
|
|||
|
|
objProps = getAllKeys(object),
|
|||
|
|
objLength = objProps.length,
|
|||
|
|
othProps = getAllKeys(other),
|
|||
|
|
othLength = othProps.length;
|
|||
|
|
|
|||
|
|
if (objLength != othLength && !isPartial) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
var index = objLength;
|
|||
|
|
while (index--) {
|
|||
|
|
var key = objProps[index];
|
|||
|
|
if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
// Assume cyclic values are equal.
|
|||
|
|
var stacked = stack.get(object);
|
|||
|
|
if (stacked && stack.get(other)) {
|
|||
|
|
return stacked == other;
|
|||
|
|
}
|
|||
|
|
var result = true;
|
|||
|
|
stack.set(object, other);
|
|||
|
|
stack.set(other, object);
|
|||
|
|
|
|||
|
|
var skipCtor = isPartial;
|
|||
|
|
while (++index < objLength) {
|
|||
|
|
key = objProps[index];
|
|||
|
|
var objValue = object[key],
|
|||
|
|
othValue = other[key];
|
|||
|
|
|
|||
|
|
if (customizer) {
|
|||
|
|
var compared = isPartial
|
|||
|
|
? customizer(othValue, objValue, key, other, object, stack)
|
|||
|
|
: customizer(objValue, othValue, key, object, other, stack);
|
|||
|
|
}
|
|||
|
|
// Recursively compare objects (susceptible to call stack limits).
|
|||
|
|
if (!(compared === undefined
|
|||
|
|
? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))
|
|||
|
|
: compared
|
|||
|
|
)) {
|
|||
|
|
result = false;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
skipCtor || (skipCtor = key == 'constructor');
|
|||
|
|
}
|
|||
|
|
if (result && !skipCtor) {
|
|||
|
|
var objCtor = object.constructor,
|
|||
|
|
othCtor = other.constructor;
|
|||
|
|
|
|||
|
|
// Non `Object` object instances with different constructors are not equal.
|
|||
|
|
if (objCtor != othCtor &&
|
|||
|
|
('constructor' in object && 'constructor' in other) &&
|
|||
|
|
!(typeof objCtor == 'function' && objCtor instanceof objCtor &&
|
|||
|
|
typeof othCtor == 'function' && othCtor instanceof othCtor)) {
|
|||
|
|
result = false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
stack['delete'](object);
|
|||
|
|
stack['delete'](other);
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Creates an array of own enumerable property names and symbols of `object`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Object} object The object to query.
|
|||
|
|
* @returns {Array} Returns the array of property names and symbols.
|
|||
|
|
*/
|
|||
|
|
function getAllKeys(object) {
|
|||
|
|
return baseGetAllKeys(object, keys, getSymbols);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Gets the data for `map`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Object} map The map to query.
|
|||
|
|
* @param {string} key The reference key.
|
|||
|
|
* @returns {*} Returns the map data.
|
|||
|
|
*/
|
|||
|
|
function getMapData(map, key) {
|
|||
|
|
var data = map.__data__;
|
|||
|
|
return isKeyable(key)
|
|||
|
|
? data[typeof key == 'string' ? 'string' : 'hash']
|
|||
|
|
: data.map;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Gets the native function at `key` of `object`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Object} object The object to query.
|
|||
|
|
* @param {string} key The key of the method to get.
|
|||
|
|
* @returns {*} Returns the function if it's native, else `undefined`.
|
|||
|
|
*/
|
|||
|
|
function getNative(object, key) {
|
|||
|
|
var value = getValue(object, key);
|
|||
|
|
return baseIsNative(value) ? value : undefined;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {*} value The value to query.
|
|||
|
|
* @returns {string} Returns the raw `toStringTag`.
|
|||
|
|
*/
|
|||
|
|
function getRawTag(value) {
|
|||
|
|
var isOwn = hasOwnProperty.call(value, symToStringTag),
|
|||
|
|
tag = value[symToStringTag];
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
value[symToStringTag] = undefined;
|
|||
|
|
var unmasked = true;
|
|||
|
|
} catch (e) {}
|
|||
|
|
|
|||
|
|
var result = nativeObjectToString.call(value);
|
|||
|
|
if (unmasked) {
|
|||
|
|
if (isOwn) {
|
|||
|
|
value[symToStringTag] = tag;
|
|||
|
|
} else {
|
|||
|
|
delete value[symToStringTag];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Creates an array of the own enumerable symbols of `object`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Object} object The object to query.
|
|||
|
|
* @returns {Array} Returns the array of symbols.
|
|||
|
|
*/
|
|||
|
|
var getSymbols = !nativeGetSymbols ? stubArray : function(object) {
|
|||
|
|
if (object == null) {
|
|||
|
|
return [];
|
|||
|
|
}
|
|||
|
|
object = Object(object);
|
|||
|
|
return arrayFilter(nativeGetSymbols(object), function(symbol) {
|
|||
|
|
return propertyIsEnumerable.call(object, symbol);
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Gets the `toStringTag` of `value`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {*} value The value to query.
|
|||
|
|
* @returns {string} Returns the `toStringTag`.
|
|||
|
|
*/
|
|||
|
|
var getTag = baseGetTag;
|
|||
|
|
|
|||
|
|
// Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.
|
|||
|
|
if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||
|
|||
|
|
(Map && getTag(new Map) != mapTag) ||
|
|||
|
|
(Promise && getTag(Promise.resolve()) != promiseTag) ||
|
|||
|
|
(Set && getTag(new Set) != setTag) ||
|
|||
|
|
(WeakMap && getTag(new WeakMap) != weakMapTag)) {
|
|||
|
|
getTag = function(value) {
|
|||
|
|
var result = baseGetTag(value),
|
|||
|
|
Ctor = result == objectTag ? value.constructor : undefined,
|
|||
|
|
ctorString = Ctor ? toSource(Ctor) : '';
|
|||
|
|
|
|||
|
|
if (ctorString) {
|
|||
|
|
switch (ctorString) {
|
|||
|
|
case dataViewCtorString: return dataViewTag;
|
|||
|
|
case mapCtorString: return mapTag;
|
|||
|
|
case promiseCtorString: return promiseTag;
|
|||
|
|
case setCtorString: return setTag;
|
|||
|
|
case weakMapCtorString: return weakMapTag;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return result;
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is a valid array-like index.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
|
|||
|
|
*/
|
|||
|
|
function isIndex(value, length) {
|
|||
|
|
length = length == null ? MAX_SAFE_INTEGER : length;
|
|||
|
|
return !!length &&
|
|||
|
|
(typeof value == 'number' || reIsUint.test(value)) &&
|
|||
|
|
(value > -1 && value % 1 == 0 && value < length);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is suitable for use as unique object key.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is suitable, else `false`.
|
|||
|
|
*/
|
|||
|
|
function isKeyable(value) {
|
|||
|
|
var type = typeof value;
|
|||
|
|
return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
|
|||
|
|
? (value !== '__proto__')
|
|||
|
|
: (value === null);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `func` has its source masked.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Function} func The function to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `func` is masked, else `false`.
|
|||
|
|
*/
|
|||
|
|
function isMasked(func) {
|
|||
|
|
return !!maskSrcKey && (maskSrcKey in func);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is likely a prototype object.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
|
|||
|
|
*/
|
|||
|
|
function isPrototype(value) {
|
|||
|
|
var Ctor = value && value.constructor,
|
|||
|
|
proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
|
|||
|
|
|
|||
|
|
return value === proto;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Converts `value` to a string using `Object.prototype.toString`.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {*} value The value to convert.
|
|||
|
|
* @returns {string} Returns the converted string.
|
|||
|
|
*/
|
|||
|
|
function objectToString(value) {
|
|||
|
|
return nativeObjectToString.call(value);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Converts `func` to its source code.
|
|||
|
|
*
|
|||
|
|
* @private
|
|||
|
|
* @param {Function} func The function to convert.
|
|||
|
|
* @returns {string} Returns the source code.
|
|||
|
|
*/
|
|||
|
|
function toSource(func) {
|
|||
|
|
if (func != null) {
|
|||
|
|
try {
|
|||
|
|
return funcToString.call(func);
|
|||
|
|
} catch (e) {}
|
|||
|
|
try {
|
|||
|
|
return (func + '');
|
|||
|
|
} catch (e) {}
|
|||
|
|
}
|
|||
|
|
return '';
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Performs a
|
|||
|
|
* [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
|
|||
|
|
* comparison between two values to determine if they are equivalent.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 4.0.0
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to compare.
|
|||
|
|
* @param {*} other The other value to compare.
|
|||
|
|
* @returns {boolean} Returns `true` if the values are equivalent, else `false`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* var object = { 'a': 1 };
|
|||
|
|
* var other = { 'a': 1 };
|
|||
|
|
*
|
|||
|
|
* _.eq(object, object);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.eq(object, other);
|
|||
|
|
* // => false
|
|||
|
|
*
|
|||
|
|
* _.eq('a', 'a');
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.eq('a', Object('a'));
|
|||
|
|
* // => false
|
|||
|
|
*
|
|||
|
|
* _.eq(NaN, NaN);
|
|||
|
|
* // => true
|
|||
|
|
*/
|
|||
|
|
function eq(value, other) {
|
|||
|
|
return value === other || (value !== value && other !== other);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is likely an `arguments` object.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 0.1.0
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is an `arguments` object,
|
|||
|
|
* else `false`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.isArguments(function() { return arguments; }());
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isArguments([1, 2, 3]);
|
|||
|
|
* // => false
|
|||
|
|
*/
|
|||
|
|
var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {
|
|||
|
|
return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&
|
|||
|
|
!propertyIsEnumerable.call(value, 'callee');
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is classified as an `Array` object.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 0.1.0
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is an array, else `false`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.isArray([1, 2, 3]);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isArray(document.body.children);
|
|||
|
|
* // => false
|
|||
|
|
*
|
|||
|
|
* _.isArray('abc');
|
|||
|
|
* // => false
|
|||
|
|
*
|
|||
|
|
* _.isArray(_.noop);
|
|||
|
|
* // => false
|
|||
|
|
*/
|
|||
|
|
var isArray = Array.isArray;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is array-like. A value is considered array-like if it's
|
|||
|
|
* not a function and has a `value.length` that's an integer greater than or
|
|||
|
|
* equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 4.0.0
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is array-like, else `false`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.isArrayLike([1, 2, 3]);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isArrayLike(document.body.children);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isArrayLike('abc');
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isArrayLike(_.noop);
|
|||
|
|
* // => false
|
|||
|
|
*/
|
|||
|
|
function isArrayLike(value) {
|
|||
|
|
return value != null && isLength(value.length) && !isFunction(value);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is a buffer.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 4.3.0
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.isBuffer(new Buffer(2));
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isBuffer(new Uint8Array(2));
|
|||
|
|
* // => false
|
|||
|
|
*/
|
|||
|
|
var isBuffer = nativeIsBuffer || stubFalse;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Performs a deep comparison between two values to determine if they are
|
|||
|
|
* equivalent.
|
|||
|
|
*
|
|||
|
|
* **Note:** This method supports comparing arrays, array buffers, booleans,
|
|||
|
|
* date objects, error objects, maps, numbers, `Object` objects, regexes,
|
|||
|
|
* sets, strings, symbols, and typed arrays. `Object` objects are compared
|
|||
|
|
* by their own, not inherited, enumerable properties. Functions and DOM
|
|||
|
|
* nodes are compared by strict equality, i.e. `===`.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 0.1.0
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to compare.
|
|||
|
|
* @param {*} other The other value to compare.
|
|||
|
|
* @returns {boolean} Returns `true` if the values are equivalent, else `false`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* var object = { 'a': 1 };
|
|||
|
|
* var other = { 'a': 1 };
|
|||
|
|
*
|
|||
|
|
* _.isEqual(object, other);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* object === other;
|
|||
|
|
* // => false
|
|||
|
|
*/
|
|||
|
|
function isEqual(value, other) {
|
|||
|
|
return baseIsEqual(value, other);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is classified as a `Function` object.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 0.1.0
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is a function, else `false`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.isFunction(_);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isFunction(/abc/);
|
|||
|
|
* // => false
|
|||
|
|
*/
|
|||
|
|
function isFunction(value) {
|
|||
|
|
if (!isObject(value)) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
// The use of `Object#toString` avoids issues with the `typeof` operator
|
|||
|
|
// in Safari 9 which returns 'object' for typed arrays and other constructors.
|
|||
|
|
var tag = baseGetTag(value);
|
|||
|
|
return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is a valid array-like length.
|
|||
|
|
*
|
|||
|
|
* **Note:** This method is loosely based on
|
|||
|
|
* [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 4.0.0
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.isLength(3);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isLength(Number.MIN_VALUE);
|
|||
|
|
* // => false
|
|||
|
|
*
|
|||
|
|
* _.isLength(Infinity);
|
|||
|
|
* // => false
|
|||
|
|
*
|
|||
|
|
* _.isLength('3');
|
|||
|
|
* // => false
|
|||
|
|
*/
|
|||
|
|
function isLength(value) {
|
|||
|
|
return typeof value == 'number' &&
|
|||
|
|
value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is the
|
|||
|
|
* [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
|
|||
|
|
* of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 0.1.0
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is an object, else `false`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.isObject({});
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isObject([1, 2, 3]);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isObject(_.noop);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isObject(null);
|
|||
|
|
* // => false
|
|||
|
|
*/
|
|||
|
|
function isObject(value) {
|
|||
|
|
var type = typeof value;
|
|||
|
|
return value != null && (type == 'object' || type == 'function');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is object-like. A value is object-like if it's not `null`
|
|||
|
|
* and has a `typeof` result of "object".
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 4.0.0
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.isObjectLike({});
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isObjectLike([1, 2, 3]);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isObjectLike(_.noop);
|
|||
|
|
* // => false
|
|||
|
|
*
|
|||
|
|
* _.isObjectLike(null);
|
|||
|
|
* // => false
|
|||
|
|
*/
|
|||
|
|
function isObjectLike(value) {
|
|||
|
|
return value != null && typeof value == 'object';
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Checks if `value` is classified as a typed array.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 3.0.0
|
|||
|
|
* @category Lang
|
|||
|
|
* @param {*} value The value to check.
|
|||
|
|
* @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.isTypedArray(new Uint8Array);
|
|||
|
|
* // => true
|
|||
|
|
*
|
|||
|
|
* _.isTypedArray([]);
|
|||
|
|
* // => false
|
|||
|
|
*/
|
|||
|
|
var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Creates an array of the own enumerable property names of `object`.
|
|||
|
|
*
|
|||
|
|
* **Note:** Non-object values are coerced to objects. See the
|
|||
|
|
* [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
|
|||
|
|
* for more details.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @since 0.1.0
|
|||
|
|
* @memberOf _
|
|||
|
|
* @category Object
|
|||
|
|
* @param {Object} object The object to query.
|
|||
|
|
* @returns {Array} Returns the array of property names.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* function Foo() {
|
|||
|
|
* this.a = 1;
|
|||
|
|
* this.b = 2;
|
|||
|
|
* }
|
|||
|
|
*
|
|||
|
|
* Foo.prototype.c = 3;
|
|||
|
|
*
|
|||
|
|
* _.keys(new Foo);
|
|||
|
|
* // => ['a', 'b'] (iteration order is not guaranteed)
|
|||
|
|
*
|
|||
|
|
* _.keys('hi');
|
|||
|
|
* // => ['0', '1']
|
|||
|
|
*/
|
|||
|
|
function keys(object) {
|
|||
|
|
return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* This method returns a new empty array.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 4.13.0
|
|||
|
|
* @category Util
|
|||
|
|
* @returns {Array} Returns the new empty array.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* var arrays = _.times(2, _.stubArray);
|
|||
|
|
*
|
|||
|
|
* console.log(arrays);
|
|||
|
|
* // => [[], []]
|
|||
|
|
*
|
|||
|
|
* console.log(arrays[0] === arrays[1]);
|
|||
|
|
* // => false
|
|||
|
|
*/
|
|||
|
|
function stubArray() {
|
|||
|
|
return [];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* This method returns `false`.
|
|||
|
|
*
|
|||
|
|
* @static
|
|||
|
|
* @memberOf _
|
|||
|
|
* @since 4.13.0
|
|||
|
|
* @category Util
|
|||
|
|
* @returns {boolean} Returns `false`.
|
|||
|
|
* @example
|
|||
|
|
*
|
|||
|
|
* _.times(2, _.stubFalse);
|
|||
|
|
* // => [false, false]
|
|||
|
|
*/
|
|||
|
|
function stubFalse() {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
module.exports = isEqual;
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
var dist$3 = createCommonjsModule$1(function (module, exports) {
|
|||
|
|
!function(t,e){module.exports=e(dist$6,require$$2$1,require$$2,lodash_throttle,require$$1,require$$4,lodash_isequal);}(commonjsGlobal,(function(t,e,n,r,o,i,a){function l(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}var u=l(r),c=l(o),s=l(a);t.i18nAddResources("en",{tableModule:{deleteCol:"Delete column",deleteRow:"Delete row",deleteTable:"Delete table",widthAuto:"Width auto",insertCol:"Insert column",insertRow:"Insert row",insertTable:"Insert table",header:"Header"}}),t.i18nAddResources("zh-CN",{tableModule:{deleteCol:"删除列",deleteRow:"删除行",deleteTable:"删除表格",widthAuto:"宽度自适应",insertCol:"插入列",insertRow:"插入行",insertTable:"插入表格",header:"表头"}});var f="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof commonjsGlobal?commonjsGlobal:"undefined"!=typeof self?self:{};function d(t){var e={exports:{}};return t(e,e.exports),e.exports}var p,v,h=function(t){return t&&t.Math==Math&&t},g=h("object"==typeof globalThis&&globalThis)||h("object"==typeof window&&window)||h("object"==typeof self&&self)||h("object"==typeof f&&f)||function(){return this}()||Function("return this")(),y=function(t){try{return !!t()}catch(t){return !0}},m=!y((function(){return 7!=Object.defineProperty({},1,{get:function(){return 7}})[1]})),b=Function.prototype.call,E=b.bind?b.bind(b):function(){return b.apply(b,arguments)},w={}.propertyIsEnumerable,x=Object.getOwnPropertyDescriptor,S={f:x&&!w.call({1:2},1)?function(t){var e=x(this,t);return !!e&&e.enumerable}:w},T=function(t,e){return {enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}},D=Function.prototype,N=D.bind,P=D.call,M=N&&N.bind(P),R=N?function(t){return t&&M(P,t)}:function(t){return t&&function(){return P.apply(t,arguments)}},O=R({}.toString),H=R("".slice),V=function(t){return H(O(t),8,-1)},z=g.Object,j=R("".split),L=y((function(){return !z("z").propertyIsEnumerable(0)}))?function(t){return "String"==V(t)?j(t,""):z(t)}:z,A=g.TypeError,C=function(t){if(null==t)throw A("Can't call method on "+t);return t},I=function(t){return L(C(t))},k=function(t){return "function"==typeof t},B=function(t){return "object"==typeof t?null!==t:k(t)},$=function(t){return k(t)?t:void 0},F=function(t,e){return arguments.length<2?$(g[t]):g[t]&&g[t][e]},q=R({}.isPrototypeOf),G=F("navigator","userAgent")||"",_=g.process,W=g.Deno,U=_&&_.versions||W&&W.version,X=U&&U.v8;X&&(v=(p=X.split("."))[0]>0&&p[0]<4?1:+(p[0]+p[1])),!v&&G&&(!(p=G.match(/Edge\/(\d+)/))||p[1]>=74)&&(p=G.match(/Chrome\/(\d+)/))&&(v=+p[1]);var Y=v,K=!!Object.getOwnPropertySymbols&&!y((function(){var t=Symbol();return !String(t)||!(Object(t)instanceof Symbol)||!Symbol.sham&&Y&&Y<41})),J=K&&!Symbol.sham&&"symbol"==typeof Symbol.iterator,Q=g.Object,Z=J?function(t){return "symbol"==typeof t}:function(t){var e=F("Symbol");return k(e)&&q(e.prototype,Q(t))},tt=g.String,et=function(t){try{return tt(t)}catch(t){return "Object"}},nt=g.TypeError,rt=function(t){if(k(t))return t;throw nt(et(t)+" is not a function")},ot=function(t,e){var n=t[e];return null==n?void 0:rt(n)},it=g.TypeError,at=Object.defineProperty,lt=function(t,e){try{at(g,t,{value:e,configurable:!0,writable:!0});}catch(n){g[t]=e;}return e},ut="__core-js_shared__",ct=g[ut]||lt(ut,{}),st=d((function(t){(t.exports=function(t,e){return ct[t]||(ct[t]=void 0!==e?e:{})})("versions",[]).push({version:"3.19.3",mode:"global",copyright:"© 2021 Denis Pushkarev (zloirock.ru)"});})),ft=g.Object,dt=function(t){return ft(C(t))},pt=R({}.hasOwnProperty),vt=Object.hasOwn||function(t,e){return pt(dt(t),e)},ht=0,gt=Math.random(),yt=R(1..toString),mt=function(t){return "Symbol("+(void 0===t?"":t)+")_"+yt(++ht+gt,36)},bt=st("wks"),Et=g.Symbol,wt=Et&&Et.for,xt=J?Et:Et&&Et.withoutSetter||mt,St=function(t){if(!vt(bt,t)||!K&&"string"!=typeof bt[t]){var e="Symbol."+t;K&&vt(Et,t)?bt[t]=Et[t]:bt[t]=J&&wt?wt(e):xt(e);}return bt[t]},Tt=g.TypeError,Dt=St("toPrimitive"),Nt=function(t,e){if(!B(t)||Z(t))return t;var n,r=ot(t,Dt);if(r){if(void 0===e&&(e="default"),n=E(r,t,e),!B(n)||Z(n))return n;throw Tt("Can't convert obj
|
|||
|
|
/*! *****************************************************************************
|
|||
|
|
Copyright (c) Microsoft Corporation.
|
|||
|
|
|
|||
|
|
Permission to use, copy, modify, and/or distribute this software for any
|
|||
|
|
purpose with or without fee is hereby granted.
|
|||
|
|
|
|||
|
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|||
|
|
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|||
|
|
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|||
|
|
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|||
|
|
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|||
|
|
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|||
|
|
PERFORMANCE OF THIS SOFTWARE.
|
|||
|
|
***************************************************************************** */
|
|||
|
|
function(t){var e="function"==typeof Symbol&&Symbol.iterator,n=e&&t[e],r=0;if(n)return n.call(t);if(t&&"number"==typeof t.length)return {next:function(){return t&&r>=t.length&&(t=void 0),{value:t&&t[r++],done:!t}}};throw new TypeError(e?"Object is not iterable.":"Symbol.iterator is not defined.")}(a),c=u.next();!c.done;c=u.next()){c.value;l=!0;}}catch(t){o={error:t};}finally{try{c&&!c.done&&(i=u.return)&&i.call(u);}finally{if(o)throw o.error}}return l}ke({target:"Array",proto:!0,forced:!Gn},{slice:function(t,e){var n,r,o,i=I(this),a=be(i),l=ge(t,a),u=ge(void 0===e?a:e,a);if(Hn(i)&&(n=i.constructor,(kn(n)&&(n===Wn||Hn(n.prototype))||B(n)&&null===(n=n[_n]))&&(n=void 0),n===Wn||void 0===n))return qn(i,l,u);for(r=new(void 0===n?Wn:n)(Un(u-l,0)),o=0;l<u;l++,o++)l in i&&Bn(r,o,i[l]);return r.length=o,r}});var Jn=R(R.bind),Qn=St("species"),Zn=g.Array,tr=function(t,e){return new(function(t){var e;return Hn(t)&&(e=t.constructor,(kn(e)&&(e===Zn||Hn(e.prototype))||B(e)&&null===(e=e[Qn]))&&(e=void 0)),void 0===e?Zn:e}(t))(0===e?0:e)},er=R([].push),nr=function(t){var e=1==t,n=2==t,r=3==t,o=4==t,i=6==t,a=7==t,l=5==t||i;return function(u,c,s,f){for(var d,p,v=dt(u),h=L(v),g=function(t,e){return rt(t),void 0===e?t:Jn?Jn(t,e):function(){return t.apply(e,arguments)}}(c,s),y=be(h),m=0,b=f||tr,E=e?b(u,y):n||a?b(u,0):void 0;y>m;m++)if((l||m in h)&&(p=g(d=h[m],m,v),t))if(e)E[m]=p;else if(p)switch(t){case 3:return !0;case 5:return d;case 6:return m;case 2:er(E,d);}else switch(t){case 4:return !1;case 7:er(E,d);}return i?-1:r||o?o:E}},rr={forEach:nr(0),map:nr(1),filter:nr(2),some:nr(3),every:nr(4),find:nr(5),findIndex:nr(6),filterReject:nr(7)},or=rr.map;ke({target:"Array",proto:!0,forced:!Fn("map")},{map:function(t){return or(this,t,arguments.length>1?arguments[1]:void 0)}});var ir=Fe?{}.toString:function(){return "[object "+We(this)+"]"};function ar(t){var e=t.children||[];return 0===e.length?[]:(e[0]||{}).children||[]}function lr(t){return ar(t).every((function(t){return !!t.isHeader}))}Fe||se(Object.prototype,"toString",ir,{unsafe:!0});var ur=ce.PROPER,cr="toString",sr=RegExp.prototype,fr=sr.toString,dr=R(Qe),pr=y((function(){return "/a/b"!=fr.call({source:"a",flags:"b"})})),vr=ur&&fr.name!=cr;(pr||vr)&&se(RegExp.prototype,cr,(function(){var t=At(this),e=Xe(t.source),n=t.flags;return "/"+e+"/"+Xe(void 0===n&&q(sr,t)&&!("flags"in sr)?dr(t):n)}),{unsafe:!0});var hr=St("unscopables"),gr=Array.prototype;null==gr[hr]&&kt.f(gr,hr,{configurable:!0,value:vn(null)});var yr,mr=rr.find,br="find",Er=!0;br in[]&&Array(1).find((function(){Er=!1;})),ke({target:"Array",proto:!0,forced:Er},{find:function(t){return mr(this,t,arguments.length>1?arguments[1]:void 0)}}),yr=br,gr[hr][yr]=!0;var wr=Function.prototype,xr=wr.apply,Sr=wr.bind,Tr=wr.call,Dr="object"==typeof Reflect&&Reflect.apply||(Sr?Tr.bind(xr):function(){return Tr.apply(xr,arguments)}),Nr=St("species"),Pr=RegExp.prototype,Mr=function(t,e,n,r){var o=St(t),i=!y((function(){var e={};return e[o]=function(){return 7},7!=""[t](e)})),a=i&&!y((function(){var e=!1,n=/a/;return "split"===t&&((n={}).constructor={},n.constructor[Nr]=function(){return n},n.flags="",n[o]=/./[o]),n.exec=function(){return e=!0,null},n[o](""),!e}));if(!i||!a||n){var l=R(/./[o]),u=e(o,""[t],(function(t,e,n,r,o){var a=R(t),u=e.exec;return u===On||u===Pr.exec?i&&!o?{done:!0,value:l(e,n,r)}:{done:!0,value:a(n,e,r)}:{done:!1}}));se(String.prototype,t,u[0]),se(Pr,o,u[1]);}r&&Bt(Pr[o],"sham",!0);},Rr=St("match"),Or=g.TypeError,Hr=St("species"),Vr=function(t,e){var n,r=At(t).constructor;return void 0===r||null==(n=At(r)[Hr])?e:function(t){if(kn(t))return t;throw Or(et(t)+" is not a constructor")}(n)},zr=R("".charAt),jr=R("".charCodeAt),Lr=R("".slice),Ar=function(t){return function(e,n){var r,o,i=Xe(C(e)),a=pe(n),l=i.length;return a<0||a>=l?t?"":void 0:(r=jr(i,a))<55296||r>56319||a+1===l||(o=jr(i,a+1))<56320||o>57343?t?zr(i,a):r:t?Lr(i,a,a+2):o-56320+(r-55296<<10)+65536}},Cr={codeAt:Ar(!1),charAt:Ar(!0)}.charAt,Ir=function(t,e,n){return e+(n?Cr(t,e).length:1)},kr=g.Array,Br=Math.max,$r=function(t,e,n){for(var r=be(t),o=ge(e,r),i=ge(void 0
|
|||
|
|
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
var dist$2 = createCommonjsModule$1(function (module, exports) {
|
|||
|
|
!function(t,e){module.exports=e(dist$6,require$$2$1,require$$2,require$$1,require$$4);}(commonjsGlobal,(function(t,e,n,r,o){function i(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}var u=i(r);t.i18nAddResources("en",{videoModule:{delete:"Delete",uploadVideo:"Upload video",insertVideo:"Insert video",videoSrc:"Video source",videoSrcPlaceHolder:"Video file url, or third-party <iframe>",videoPoster:"Video poster",videoPosterPlaceHolder:"Poster image url",ok:"Ok",editSize:"Edit size",width:"Width",height:"Height"}}),t.i18nAddResources("zh-CN",{videoModule:{delete:"删除视频",uploadVideo:"上传视频",insertVideo:"插入视频",videoSrc:"视频地址",videoSrcPlaceHolder:"视频文件 url 或第三方 <iframe>",videoPoster:"视频封面",videoPosterPlaceHolder:"封面图片 url",ok:"确定",editSize:"修改尺寸",width:"宽度",height:"高度"}});
|
|||
|
|
/*! *****************************************************************************
|
|||
|
|
Copyright (c) Microsoft Corporation.
|
|||
|
|
|
|||
|
|
Permission to use, copy, modify, and/or distribute this software for any
|
|||
|
|
purpose with or without fee is hereby granted.
|
|||
|
|
|
|||
|
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|||
|
|
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|||
|
|
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|||
|
|
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|||
|
|
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|||
|
|
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|||
|
|
PERFORMANCE OF THIS SOFTWARE.
|
|||
|
|
***************************************************************************** */
|
|||
|
|
var a=function(){return a=Object.assign||function(t){for(var e,n=1,r=arguments.length;n<r;n++)for(var o in e=arguments[n])Object.prototype.hasOwnProperty.call(e,o)&&(t[o]=e[o]);return t},a.apply(this,arguments)};function c(t,e,n,r){return new(n||(n=Promise))((function(o,i){function u(t){try{c(r.next(t));}catch(t){i(t);}}function a(t){try{c(r.throw(t));}catch(t){i(t);}}function c(t){var e;t.done?o(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e);}))).then(u,a);}c((r=r.apply(t,e||[])).next());}))}function f(t,e){var n,r,o,i,u={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function a(i){return function(a){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;u;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return u.label++,{value:i[1],done:!1};case 5:u.label++,r=i[1],i=[0];continue;case 7:i=u.ops.pop(),u.trys.pop();continue;default:if(!(o=u.trys,(o=o.length>0&&o[o.length-1])||6!==i[0]&&2!==i[0])){u=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]<o[3])){u.label=i[1];break}if(6===i[0]&&u.label<o[1]){u.label=o[1],o=i;break}if(o&&u.label<o[2]){u.label=o[2],u.ops.push(i);break}o[2]&&u.ops.pop(),u.trys.pop();continue}i=e.call(t,u);}catch(t){i=[6,t],r=0;}finally{n=o=0;}if(5&i[0])throw i[1];return {value:i[0]?i[1]:void 0,done:!0}}([i,a])}}}function s(t){var e="function"==typeof Symbol&&Symbol.iterator,n=e&&t[e],r=0;if(n)return n.call(t);if(t&&"number"==typeof t.length)return {next:function(){return t&&r>=t.length&&(t=void 0),{value:t&&t[r++],done:!t}}};throw new TypeError(e?"Object is not iterable.":"Symbol.iterator is not defined.")}function l(t,e){var n="function"==typeof Symbol&&t[Symbol.iterator];if(!n)return t;var r,o,i=n.call(t),u=[];try{for(;(void 0===e||e-- >0)&&!(r=i.next()).done;)u.push(r.value);}catch(t){o={error:t};}finally{try{r&&!r.done&&(n=i.return)&&n.call(i);}finally{if(o)throw o.error}}return u}function d(t){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var e,n=t[Symbol.asyncIterator];return n?n.call(t):(t=s(t),e={},r("next"),r("throw"),r("return"),e[Symbol.asyncIterator]=function(){return this},e);function r(n){e[n]=t[n]&&function(e){return new Promise((function(r,o){(function(t,e,n,r){Promise.resolve(r).then((function(e){t({value:e,done:n});}),e);})(r,o,(e=t[n](e)).done,e.value);}))};}}var p="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof commonjsGlobal?commonjsGlobal:"undefined"!=typeof self?self:{};function v(t){var e={exports:{}};return t(e,e.exports),e.exports}var h,y,g=function(t){return t&&t.Math==Math&&t},m=g("object"==typeof globalThis&&globalThis)||g("object"==typeof window&&window)||g("object"==typeof self&&self)||g("object"==typeof p&&p)||function(){return this}()||Function("return this")(),b=function(t){try{return !!t()}catch(t){return !0}},w=!b((function(){return 7!=Object.defineProperty({},1,{get:function(){return 7}})[1]})),S=Function.prototype.call,x=S.bind?S.bind(S):function(){return S.apply(S,arguments)},E={}.propertyIsEnumerable,O=Object.getOwnPropertyDescriptor,j={f:O&&!E.call({1:2},1)?function(t){var e=O(this,t);return !!e&&e.enumerable}:E},I=function(t,e){return {enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}},P=Function.prototype,T=P.bind,M=P.call,A=T&&T.bind(M),R=T?function(t){return t&&A(M,t)}:function(t){return t&&function(){return M.apply(t,arguments)}},k=R({}.toString),C=R("".slice),N=function(t){return C(k(t),8,-1)},L=m.Object,V=R("".split),D=b((function(){return !L("z").propertyIsEnumerable(0)}))?function(t){return "String"==N(t)?V(t,""):L(t)}:L,z=m.TypeError,F=function(t){if(null==t)throw z("Can't call method on "+t);return t},_=function(t){return D(F(t))},$=function(t){return "function"==typeof t},H=function(t){return "object"==typeof t?null!==t:$(t)},B=
|
|||
|
|
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
var dist$1 = createCommonjsModule$1(function (module, exports) {
|
|||
|
|
!function(t,e){module.exports=e(dist$6,dist$5,require$$1);}(commonjsGlobal,(function(t,e,n){function r(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}var o=r(n);t.i18nAddResources("en",{uploadImgModule:{uploadImage:"Upload Image",uploadError:"{{fileName}} upload error"}}),t.i18nAddResources("zh-CN",{uploadImgModule:{uploadImage:"上传图片",uploadError:"{{fileName}} 上传出错"}});var i="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof commonjsGlobal?commonjsGlobal:"undefined"!=typeof self?self:{};function u(t){var e={exports:{}};return t(e,e.exports),e.exports}var a,c,f=function(t){return t&&t.Math==Math&&t},s=f("object"==typeof globalThis&&globalThis)||f("object"==typeof window&&window)||f("object"==typeof self&&self)||f("object"==typeof i&&i)||function(){return this}()||Function("return this")(),l=function(t){try{return !!t()}catch(t){return !0}},p=!l((function(){return 7!=Object.defineProperty({},1,{get:function(){return 7}})[1]})),d=Function.prototype.call,v=d.bind?d.bind(d):function(){return d.apply(d,arguments)},h={}.propertyIsEnumerable,y=Object.getOwnPropertyDescriptor,g={f:y&&!h.call({1:2},1)?function(t){var e=y(this,t);return !!e&&e.enumerable}:h},m=function(t,e){return {enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}},b=Function.prototype,w=b.bind,x=b.call,S=w&&w.bind(x),O=w?function(t){return t&&S(x,t)}:function(t){return t&&function(){return x.apply(t,arguments)}},E=O({}.toString),j=O("".slice),I=function(t){return j(E(t),8,-1)},T=s.Object,A=O("".split),P=l((function(){return !T("z").propertyIsEnumerable(0)}))?function(t){return "String"==I(t)?A(t,""):T(t)}:T,R=s.TypeError,M=function(t){if(null==t)throw R("Can't call method on "+t);return t},k=function(t){return P(M(t))},L=function(t){return "function"==typeof t},F=function(t){return "object"==typeof t?null!==t:L(t)},C=function(t){return L(t)?t:void 0},N=function(t,e){return arguments.length<2?C(s[t]):s[t]&&s[t][e]},z=O({}.isPrototypeOf),_=N("navigator","userAgent")||"",D=s.process,U=s.Deno,G=D&&D.versions||U&&U.version,B=G&&G.v8;B&&(c=(a=B.split("."))[0]>0&&a[0]<4?1:+(a[0]+a[1])),!c&&_&&(!(a=_.match(/Edge\/(\d+)/))||a[1]>=74)&&(a=_.match(/Chrome\/(\d+)/))&&(c=+a[1]);var W=c,V=!!Object.getOwnPropertySymbols&&!l((function(){var t=Symbol();return !String(t)||!(Object(t)instanceof Symbol)||!Symbol.sham&&W&&W<41})),H=V&&!Symbol.sham&&"symbol"==typeof Symbol.iterator,q=s.Object,K=H?function(t){return "symbol"==typeof t}:function(t){var e=N("Symbol");return L(e)&&z(e.prototype,q(t))},Y=s.String,X=function(t){try{return Y(t)}catch(t){return "Object"}},$=s.TypeError,J=function(t){if(L(t))return t;throw $(X(t)+" is not a function")},Q=function(t,e){var n=t[e];return null==n?void 0:J(n)},Z=s.TypeError,tt=Object.defineProperty,et=function(t,e){try{tt(s,t,{value:e,configurable:!0,writable:!0});}catch(n){s[t]=e;}return e},nt="__core-js_shared__",rt=s[nt]||et(nt,{}),ot=u((function(t){(t.exports=function(t,e){return rt[t]||(rt[t]=void 0!==e?e:{})})("versions",[]).push({version:"3.19.3",mode:"global",copyright:"© 2021 Denis Pushkarev (zloirock.ru)"});})),it=s.Object,ut=function(t){return it(M(t))},at=O({}.hasOwnProperty),ct=Object.hasOwn||function(t,e){return at(ut(t),e)},ft=0,st=Math.random(),lt=O(1..toString),pt=function(t){return "Symbol("+(void 0===t?"":t)+")_"+lt(++ft+st,36)},dt=ot("wks"),vt=s.Symbol,ht=vt&&vt.for,yt=H?vt:vt&&vt.withoutSetter||pt,gt=function(t){if(!ct(dt,t)||!V&&"string"!=typeof dt[t]){var e="Symbol."+t;V&&ct(vt,t)?dt[t]=vt[t]:dt[t]=H&&ht?ht(e):yt(e);}return dt[t]},mt=s.TypeError,bt=gt("toPrimitive"),wt=function(t,e){if(!F(t)||K(t))return t;var n,r=Q(t,bt);if(r){if(void 0===e&&(e="default"),n=v(r,t,e),!F(n)||K(n))return n;throw mt("Can't convert object to primitive value")}return void 0===e&&(e="number"),function(t,e){var n,r;if("string"===e&&L(n=t.toString)&&!F(r=v(n,t)))return r;if(L(n=t.valueOf)&&!F(r=v(n,t)))return r;if("string"!==e&&L(n=t.toString)&&!F(r=v(n,t)))return r;throw Z("Can't convert object to primitive value")}(t,e)},xt=function(t){var e=wt(t,"string");r
|
|||
|
|
/*! *****************************************************************************
|
|||
|
|
Copyright (c) Microsoft Corporation.
|
|||
|
|
|
|||
|
|
Permission to use, copy, modify, and/or distribute this software for any
|
|||
|
|
purpose with or without fee is hereby granted.
|
|||
|
|
|
|||
|
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|||
|
|
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|||
|
|
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|||
|
|
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|||
|
|
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|||
|
|
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|||
|
|
PERFORMANCE OF THIS SOFTWARE.
|
|||
|
|
***************************************************************************** */
|
|||
|
|
var gr=function(){return gr=Object.assign||function(t){for(var e,n=1,r=arguments.length;n<r;n++)for(var o in e=arguments[n])Object.prototype.hasOwnProperty.call(e,o)&&(t[o]=e[o]);return t},gr.apply(this,arguments)};function mr(t,e,n,r){return new(n||(n=Promise))((function(o,i){function u(t){try{c(r.next(t));}catch(t){i(t);}}function a(t){try{c(r.throw(t));}catch(t){i(t);}}function c(t){var e;t.done?o(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e);}))).then(u,a);}c((r=r.apply(t,e||[])).next());}))}function br(t,e){var n,r,o,i,u={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function a(i){return function(a){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;u;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return u.label++,{value:i[1],done:!1};case 5:u.label++,r=i[1],i=[0];continue;case 7:i=u.ops.pop(),u.trys.pop();continue;default:if(!(o=u.trys,(o=o.length>0&&o[o.length-1])||6!==i[0]&&2!==i[0])){u=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]<o[3])){u.label=i[1];break}if(6===i[0]&&u.label<o[1]){u.label=o[1],o=i;break}if(o&&u.label<o[2]){u.label=o[2],u.ops.push(i);break}o[2]&&u.ops.pop(),u.trys.pop();continue}i=e.call(t,u);}catch(t){i=[6,t],r=0;}finally{n=o=0;}if(5&i[0])throw i[1];return {value:i[0]?i[1]:void 0,done:!0}}([i,a])}}}function wr(t){var e="function"==typeof Symbol&&Symbol.iterator,n=e&&t[e],r=0;if(n)return n.call(t);if(t&&"number"==typeof t.length)return {next:function(){return t&&r>=t.length&&(t=void 0),{value:t&&t[r++],done:!t}}};throw new TypeError(e?"Object is not iterable.":"Symbol.iterator is not defined.")}function xr(t){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var e,n=t[Symbol.asyncIterator];return n?n.call(t):(t=wr(t),e={},r("next"),r("throw"),r("return"),e[Symbol.asyncIterator]=function(){return this},e);function r(n){e[n]=t[n]&&function(e){return new Promise((function(r,o){(function(t,e,n,r){Promise.resolve(r).then((function(e){t({value:e,done:n});}),e);})(r,o,(e=t[n](e)).done,e.value);}))};}}var Sr=gt("unscopables"),Or=Array.prototype;null==Or[Sr]&&Lt.f(Or,Sr,{configurable:!0,value:On(null)});var Er,jr,Ir,Tr=function(t){Or[Sr][t]=!0;},Ar={},Pr=!l((function(){function t(){}return t.prototype.constructor=null,Object.getPrototypeOf(new t)!==t.prototype})),Rr=Wt("IE_PROTO"),Mr=s.Object,kr=Mr.prototype,Lr=Pr?Mr.getPrototypeOf:function(t){var e=ut(t);if(ct(e,Rr))return e[Rr];var n=e.constructor;return L(n)&&e instanceof n?n.prototype:e instanceof Mr?kr:null},Fr=gt("iterator"),Cr=!1;[].keys&&("next"in(Ir=[].keys())?(jr=Lr(Lr(Ir)))!==Object.prototype&&(Er=jr):Cr=!0);var Nr=null==Er||l((function(){var t={};return Er[Fr].call(t)!==t}));Nr&&(Er={}),L(Er[Fr])||oe(Er,Fr,(function(){return this}));var zr={IteratorPrototype:Er,BUGGY_SAFARI_ITERATORS:Cr},_r=Lt.f,Dr=gt("toStringTag"),Ur=function(t,e,n){t&&!ct(t=n?t:t.prototype,Dr)&&_r(t,Dr,{configurable:!0,value:e});},Gr=zr.IteratorPrototype,Br=function(){return this},Wr=s.String,Vr=s.TypeError,Hr=Object.setPrototypeOf||("__proto__"in{}?function(){var t,e=!1,n={};try{(t=O(Object.getOwnPropertyDescriptor(Object.prototype,"__proto__").set))(n,[]),e=n instanceof Array;}catch(t){}return function(n,r){return Rt(n),function(t){if("object"==typeof t||L(t))return t;throw Vr("Can't set "+Wr(t)+" as a prototype")}(r),e?t(n,r):n.__proto__=r,n}}():void 0),qr=re.PROPER,Kr=re.CONFIGURABLE,Yr=zr.IteratorPrototype,Xr=zr.BUGGY_SAFARI_ITERATORS,$r=gt("iterator"),Jr="keys",Qr="values",Zr="entries",to=function(){return this},eo=function(t,e,n,r,o,i,u){!function(t,e,n,r){var o=e+" Iterator";t.prototype=On(Gr,{next:m(+!r,n)}),Ur(t,o,!1),Ar[o]=Br;}(n,e,r);var a,c,f,s=function(t){if(t===o&&y)return y;if(!Xr&&t in d)return d[t];switch(t){case Jr:case Qr:case Zr:return function(){return new n(this,t)}}return function
|
|||
|
|
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
var dist = createCommonjsModule$1(function (module, exports) {
|
|||
|
|
!function(e,t){t(exports,dist$6,require$$1,require$$2$1);}(commonjsGlobal,(function(e,t,n,a){function r(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var i=r(n);t.i18nAddResources("en",{highLightModule:{selectLang:"Language"}}),t.i18nAddResources("zh-CN",{highLightModule:{selectLang:"选择语言"}});var s="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof commonjsGlobal?commonjsGlobal:"undefined"!=typeof self?self:{};function o(e){var t={exports:{}};return e(t,t.exports),t.exports}var l,u,c=function(e){return e&&e.Math==Math&&e},d=c("object"==typeof globalThis&&globalThis)||c("object"==typeof window&&window)||c("object"==typeof self&&self)||c("object"==typeof s&&s)||function(){return this}()||Function("return this")(),p=Object.defineProperty,g=function(e,t){try{p(d,e,{value:t,configurable:!0,writable:!0});}catch(n){d[e]=t;}return t},f="__core-js_shared__",b=d[f]||g(f,{}),h=o((function(e){(e.exports=function(e,t){return b[e]||(b[e]=void 0!==t?t:{})})("versions",[]).push({version:"3.19.3",mode:"global",copyright:"© 2021 Denis Pushkarev (zloirock.ru)"});})),m=Function.prototype,y=m.bind,E=m.call,v=y&&y.bind(E),S=y?function(e){return e&&v(E,e)}:function(e){return e&&function(){return E.apply(e,arguments)}},w=d.TypeError,k=function(e){if(null==e)throw w("Can't call method on "+e);return e},A=d.Object,x=function(e){return A(k(e))},T=S({}.hasOwnProperty),_=Object.hasOwn||function(e,t){return T(x(e),t)},O=0,I=Math.random(),R=S(1..toString),N=function(e){return "Symbol("+(void 0===e?"":e)+")_"+R(++O+I,36)},L=function(e){return "function"==typeof e},P=function(e){return L(e)?e:void 0},C=function(e,t){return arguments.length<2?P(d[e]):d[e]&&d[e][t]},F=C("navigator","userAgent")||"",D=d.process,$=d.Deno,M=D&&D.versions||$&&$.version,B=M&&M.v8;B&&(u=(l=B.split("."))[0]>0&&l[0]<4?1:+(l[0]+l[1])),!u&&F&&(!(l=F.match(/Edge\/(\d+)/))||l[1]>=74)&&(l=F.match(/Chrome\/(\d+)/))&&(u=+l[1]);var U=u,j=function(e){try{return !!e()}catch(e){return !0}},z=!!Object.getOwnPropertySymbols&&!j((function(){var e=Symbol();return !String(e)||!(Object(e)instanceof Symbol)||!Symbol.sham&&U&&U<41})),G=z&&!Symbol.sham&&"symbol"==typeof Symbol.iterator,H=h("wks"),q=d.Symbol,Y=q&&q.for,W=G?q:q&&q.withoutSetter||N,X=function(e){if(!_(H,e)||!z&&"string"!=typeof H[e]){var t="Symbol."+e;z&&_(q,e)?H[e]=q[e]:H[e]=G&&Y?Y(t):W(t);}return H[e]},Z={};Z[X("toStringTag")]="z";var V="[object z]"===String(Z),K=!j((function(){return 7!=Object.defineProperty({},1,{get:function(){return 7}})[1]})),J=function(e){return "object"==typeof e?null!==e:L(e)},Q=d.document,ee=J(Q)&&J(Q.createElement),te=function(e){return ee?Q.createElement(e):{}},ne=!K&&!j((function(){return 7!=Object.defineProperty(te("div"),"a",{get:function(){return 7}}).a})),ae=d.String,re=d.TypeError,ie=function(e){if(J(e))return e;throw re(ae(e)+" is not an object")},se=Function.prototype.call,oe=se.bind?se.bind(se):function(){return se.apply(se,arguments)},le=S({}.isPrototypeOf),ue=d.Object,ce=G?function(e){return "symbol"==typeof e}:function(e){var t=C("Symbol");return L(t)&&le(t.prototype,ue(e))},de=d.String,pe=function(e){try{return de(e)}catch(e){return "Object"}},ge=d.TypeError,fe=function(e){if(L(e))return e;throw ge(pe(e)+" is not a function")},be=function(e,t){var n=e[t];return null==n?void 0:fe(n)},he=d.TypeError,me=d.TypeError,ye=X("toPrimitive"),Ee=function(e,t){if(!J(e)||ce(e))return e;var n,a=be(e,ye);if(a){if(void 0===t&&(t="default"),n=oe(a,e,t),!J(n)||ce(n))return n;throw me("Can't convert object to primitive value")}return void 0===t&&(t="number"),function(e,t){var n,a;if("string"===t&&L(n=e.toString)&&!J(a=oe(n,e)))return a;if(L(n=e.valueOf)&&!J(a=oe(n,e)))return a;if("string"!==t&&L(n=e.toString)&&!J(a=oe(n,e)))return a;throw he("Can't convert object to primitive value")}(e,t)},ve=function(e){var t=Ee(e,"string");return ce(t)?t:t+""},Se=d.TypeError,we=Object.defineProperty,ke={f:K?we:function(e,t,n){if(ie(e),t=ve(t),ie(n),ne)try{return we(e,t,n)}catch(e){}if("get"in n||"set"in n)throw Se("Accessors not supported");return "value"
|
|||
|
|
/**
|
|||
|
|
* Prism: Lightweight, robust, elegant syntax highlighting
|
|||
|
|
*
|
|||
|
|
* @license MIT <https://opensource.org/licenses/MIT>
|
|||
|
|
* @author Lea Verou <https://lea.verou.me>
|
|||
|
|
* @namespace
|
|||
|
|
* @public
|
|||
|
|
*/e.exports&&(e.exports=t),void 0!==s&&(s.Prism=t),t.languages.markup={comment:{pattern:/<!--(?:(?!<!--)[\s\S])*?-->/,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^<!|>$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},t.languages.markup.tag.inside["attr-value"].inside.entity=t.languages.markup.entity,t.languages.markup.doctype.inside["internal-subset"].inside=t.languages.markup,t.hooks.add("wrap",(function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"));})),Object.defineProperty(t.languages.markup.tag,"addInlined",{value:function(e,n){var a={};a["language-"+n]={pattern:/(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,lookbehind:!0,inside:t.languages[n]},a.cdata=/^<!\[CDATA\[|\]\]>$/i;var r={"included-cdata":{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,inside:a}};r["language-"+n]={pattern:/[\s\S]+/,inside:t.languages[n]};var i={};i[e]={pattern:RegExp(/(<__[^>]*>)(?:<!\[CDATA\[(?:[^\]]|\](?!\]>))*\]\]>|(?!<!\[CDATA\[)[\s\S])*?(?=<\/__>)/.source.replace(/__/g,(function(){return e})),"i"),lookbehind:!0,greedy:!0,inside:r},t.languages.insertBefore("markup","cdata",i);}}),Object.defineProperty(t.languages.markup.tag,"addAttribute",{value:function(e,n){t.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+e+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[n,"language-"+n],inside:t.languages[n]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}});}}),t.languages.html=t.languages.markup,t.languages.mathml=t.languages.markup,t.languages.svg=t.languages.markup,t.languages.xml=t.languages.extend("markup",{}),t.languages.ssml=t.languages.xml,t.languages.atom=t.languages.xml,t.languages.rss=t.languages.xml,function(e){var t=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-](?:[^;{\s]|\s+(?![\s{]))*(?:;|(?=\s*\{))/,inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+t.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+t.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+t.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:t,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css;var n=e.languages.markup;n&&(n.tag.addInlined("style","css"),n.tag.addAttribute("style","css"));}(t),t.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^
|
|||
|
|
/*! *****************************************************************************
|
|||
|
|
Copyright (c) Microsoft Corporation.
|
|||
|
|
|
|||
|
|
Permission to use, copy, modify, and/or distribute this software for any
|
|||
|
|
purpose with or without fee is hereby granted.
|
|||
|
|
|
|||
|
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|||
|
|
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|||
|
|
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|||
|
|
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|||
|
|
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|||
|
|
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|||
|
|
PERFORMANCE OF THIS SOFTWARE.
|
|||
|
|
***************************************************************************** */
|
|||
|
|
function(e){var t="function"==typeof Symbol&&Symbol.iterator,n=t&&e[t],a=0;if(n)return n.call(e);if(e&&"number"==typeof e.length)return {next:function(){return e&&a>=e.length&&(e=void 0),{value:e&&e[a++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}(g),h=b.next();!h.done;h=b.next()){var m=h.value,y=f+Sn(m);"string"!=typeof m&&u.push(((i={})[m.type]=!0,i.anchor={path:l,offset:f},i.focus={path:l,offset:y},i)),f=y;}}catch(e){n={error:e};}finally{try{h&&!h.done&&(r=b.return)&&r.call(b);}finally{if(n)throw n.error}}return u},e.wangEditorCodeHighlightModule=Ua,Object.defineProperty(e,"__esModule",{value:!0});}));
|
|||
|
|
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
/*! *****************************************************************************
|
|||
|
|
Copyright (c) Microsoft Corporation.
|
|||
|
|
|
|||
|
|
Permission to use, copy, modify, and/or distribute this software for any
|
|||
|
|
purpose with or without fee is hereby granted.
|
|||
|
|
|
|||
|
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|||
|
|
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|||
|
|
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|||
|
|
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|||
|
|
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|||
|
|
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|||
|
|
PERFORMANCE OF THIS SOFTWARE.
|
|||
|
|
***************************************************************************** */
|
|||
|
|
|
|||
|
|
var __assign = function() {
|
|||
|
|
__assign = Object.assign || function __assign(t) {
|
|||
|
|
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|||
|
|
s = arguments[i];
|
|||
|
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
|
|||
|
|
}
|
|||
|
|
return t;
|
|||
|
|
};
|
|||
|
|
return __assign.apply(this, arguments);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @description Editor View class
|
|||
|
|
* @author wangfupeng
|
|||
|
|
*/
|
|||
|
|
var Boot = /** @class */ (function () {
|
|||
|
|
function Boot() {
|
|||
|
|
throw new Error('不能实例化\nCan not construct a instance');
|
|||
|
|
}
|
|||
|
|
Boot.setEditorConfig = function (newConfig) {
|
|||
|
|
if (newConfig === void 0) { newConfig = {}; }
|
|||
|
|
this.editorConfig = __assign(__assign({}, this.editorConfig), newConfig);
|
|||
|
|
};
|
|||
|
|
Boot.setSimpleEditorConfig = function (newConfig) {
|
|||
|
|
if (newConfig === void 0) { newConfig = {}; }
|
|||
|
|
this.simpleEditorConfig = __assign(__assign({}, this.simpleEditorConfig), newConfig);
|
|||
|
|
};
|
|||
|
|
Boot.setToolbarConfig = function (newConfig) {
|
|||
|
|
if (newConfig === void 0) { newConfig = {}; }
|
|||
|
|
this.toolbarConfig = __assign(__assign({}, this.toolbarConfig), newConfig);
|
|||
|
|
};
|
|||
|
|
Boot.setSimpleToolbarConfig = function (newConfig) {
|
|||
|
|
if (newConfig === void 0) { newConfig = {}; }
|
|||
|
|
this.simpleToolbarConfig = __assign(__assign({}, this.simpleToolbarConfig), newConfig);
|
|||
|
|
};
|
|||
|
|
Boot.registerPlugin = function (plugin) {
|
|||
|
|
this.plugins.push(plugin);
|
|||
|
|
};
|
|||
|
|
// 注册 menu
|
|||
|
|
// TODO 可在注册时传入配置,在开发文档中说明
|
|||
|
|
Boot.registerMenu = function (menuConf, customConfig) {
|
|||
|
|
dist$6.registerMenu(menuConf, customConfig);
|
|||
|
|
};
|
|||
|
|
// 注册 renderElem
|
|||
|
|
Boot.registerRenderElem = function (renderElemConf) {
|
|||
|
|
dist$6.registerRenderElemConf(renderElemConf);
|
|||
|
|
};
|
|||
|
|
// 注册 renderStyle
|
|||
|
|
Boot.registerRenderStyle = function (fn) {
|
|||
|
|
dist$6.registerStyleHandler(fn);
|
|||
|
|
};
|
|||
|
|
// 注册 elemToHtml
|
|||
|
|
Boot.registerElemToHtml = function (elemToHtmlConf) {
|
|||
|
|
dist$6.registerElemToHtmlConf(elemToHtmlConf);
|
|||
|
|
};
|
|||
|
|
// 注册 styleToHtml
|
|||
|
|
Boot.registerStyleToHtml = function (fn) {
|
|||
|
|
dist$6.registerStyleToHtmlHandler(fn);
|
|||
|
|
};
|
|||
|
|
// 注册 preParseHtml
|
|||
|
|
Boot.registerPreParseHtml = function (preParseHtmlConf) {
|
|||
|
|
dist$6.registerPreParseHtmlConf(preParseHtmlConf);
|
|||
|
|
};
|
|||
|
|
// 注册 parseElemHtml
|
|||
|
|
Boot.registerParseElemHtml = function (parseElemHtmlConf) {
|
|||
|
|
dist$6.registerParseElemHtmlConf(parseElemHtmlConf);
|
|||
|
|
};
|
|||
|
|
// 注册 parseStyleHtml
|
|||
|
|
Boot.registerParseStyleHtml = function (fn) {
|
|||
|
|
dist$6.registerParseStyleHtmlHandler(fn);
|
|||
|
|
};
|
|||
|
|
// 注册 module
|
|||
|
|
Boot.registerModule = function (module) {
|
|||
|
|
registerModule(module);
|
|||
|
|
};
|
|||
|
|
// editor 配置
|
|||
|
|
Boot.editorConfig = {};
|
|||
|
|
Boot.simpleEditorConfig = {};
|
|||
|
|
//toolbar 配置
|
|||
|
|
Boot.toolbarConfig = {};
|
|||
|
|
Boot.simpleToolbarConfig = {};
|
|||
|
|
// 注册插件
|
|||
|
|
Boot.plugins = [];
|
|||
|
|
return Boot;
|
|||
|
|
}());
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @description 注册 module
|
|||
|
|
* @author wangfupeng
|
|||
|
|
*/
|
|||
|
|
function registerModule(module) {
|
|||
|
|
var menus = module.menus, renderElems = module.renderElems, renderStyle = module.renderStyle, elemsToHtml = module.elemsToHtml, styleToHtml = module.styleToHtml, preParseHtml = module.preParseHtml, parseElemsHtml = module.parseElemsHtml, parseStyleHtml = module.parseStyleHtml, editorPlugin = module.editorPlugin;
|
|||
|
|
if (menus) {
|
|||
|
|
menus.forEach(function (menu) { return Boot.registerMenu(menu); });
|
|||
|
|
}
|
|||
|
|
if (renderElems) {
|
|||
|
|
renderElems.forEach(function (renderElemConf) { return Boot.registerRenderElem(renderElemConf); });
|
|||
|
|
}
|
|||
|
|
if (renderStyle) {
|
|||
|
|
Boot.registerRenderStyle(renderStyle);
|
|||
|
|
}
|
|||
|
|
if (elemsToHtml) {
|
|||
|
|
elemsToHtml.forEach(function (elemToHtmlConf) { return Boot.registerElemToHtml(elemToHtmlConf); });
|
|||
|
|
}
|
|||
|
|
if (styleToHtml) {
|
|||
|
|
Boot.registerStyleToHtml(styleToHtml);
|
|||
|
|
}
|
|||
|
|
if (preParseHtml) {
|
|||
|
|
preParseHtml.forEach(function (conf) { return Boot.registerPreParseHtml(conf); });
|
|||
|
|
}
|
|||
|
|
if (parseElemsHtml) {
|
|||
|
|
parseElemsHtml.forEach(function (parseElemHtmlConf) { return Boot.registerParseElemHtml(parseElemHtmlConf); });
|
|||
|
|
}
|
|||
|
|
if (parseStyleHtml) {
|
|||
|
|
Boot.registerParseStyleHtml(parseStyleHtml);
|
|||
|
|
}
|
|||
|
|
if (editorPlugin) {
|
|||
|
|
Boot.registerPlugin(editorPlugin);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @description register builtin modules
|
|||
|
|
* @author wangfupeng
|
|||
|
|
*/
|
|||
|
|
basicModules.forEach(function (module) { return registerModule(module); });
|
|||
|
|
registerModule(dist$4);
|
|||
|
|
registerModule(dist$3);
|
|||
|
|
registerModule(dist$2);
|
|||
|
|
registerModule(dist$1);
|
|||
|
|
registerModule(dist.wangEditorCodeHighlightModule);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @description svg tag
|
|||
|
|
* @author wangfupeng
|
|||
|
|
*/
|
|||
|
|
/**
|
|||
|
|
* 【注意】svg 字符串的长度 ,否则会导致代码体积过大
|
|||
|
|
* 尽量选择 https://www.iconfont.cn/collections/detail?spm=a313x.7781069.0.da5a778a4&cid=20293
|
|||
|
|
* 找不到再从 iconfont.com 搜索
|
|||
|
|
*/
|
|||
|
|
// 缩进 right
|
|||
|
|
var INDENT_RIGHT_SVG = '<svg viewBox="0 0 1024 1024"><path d="M0 64h1024v128H0z m384 192h640v128H384z m0 192h640v128H384z m0 192h640v128H384zM0 832h1024v128H0z m0-128V320l256 192z"></path></svg>';
|
|||
|
|
// 左对齐
|
|||
|
|
var JUSTIFY_LEFT_SVG = '<svg viewBox="0 0 1024 1024"><path d="M768 793.6v102.4H51.2v-102.4h716.8z m204.8-230.4v102.4H51.2v-102.4h921.6z m-204.8-230.4v102.4H51.2v-102.4h716.8zM972.8 102.4v102.4H51.2V102.4h921.6z"></path></svg>';
|
|||
|
|
// 图片
|
|||
|
|
var IMAGE_SVG = '<svg viewBox="0 0 1024 1024"><path d="M959.877 128l0.123 0.123v767.775l-0.123 0.122H64.102l-0.122-0.122V128.123l0.122-0.123h895.775zM960 64H64C28.795 64 0 92.795 0 128v768c0 35.205 28.795 64 64 64h896c35.205 0 64-28.795 64-64V128c0-35.205-28.795-64-64-64zM832 288.01c0 53.023-42.988 96.01-96.01 96.01s-96.01-42.987-96.01-96.01S682.967 192 735.99 192 832 234.988 832 288.01zM896 832H128V704l224.01-384 256 320h64l224.01-192z"></path></svg>';
|
|||
|
|
// plus
|
|||
|
|
var MORE_SVG = '<svg viewBox="0 0 1024 1024"><path d="M204.8 505.6m-76.8 0a76.8 76.8 0 1 0 153.6 0 76.8 76.8 0 1 0-153.6 0Z"></path><path d="M505.6 505.6m-76.8 0a76.8 76.8 0 1 0 153.6 0 76.8 76.8 0 1 0-153.6 0Z"></path><path d="M806.4 505.6m-76.8 0a76.8 76.8 0 1 0 153.6 0 76.8 76.8 0 1 0-153.6 0Z"></path></svg>';
|
|||
|
|
// 视频
|
|||
|
|
var VIDEO_SVG = '<svg viewBox="0 0 1024 1024"><path d="M981.184 160.096C837.568 139.456 678.848 128 512 128S186.432 139.456 42.816 160.096C15.296 267.808 0 386.848 0 512s15.264 244.16 42.816 351.904C186.464 884.544 345.152 896 512 896s325.568-11.456 469.184-32.096C1008.704 756.192 1024 637.152 1024 512s-15.264-244.16-42.816-351.904zM384 704V320l320 192-320 192z"></path></svg>';
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @description toolbar 配置
|
|||
|
|
* @author wangfupeng
|
|||
|
|
*/
|
|||
|
|
function genDefaultToolbarKeys() {
|
|||
|
|
return [
|
|||
|
|
'headerSelect',
|
|||
|
|
// 'header1',
|
|||
|
|
// 'header2',
|
|||
|
|
// 'header3',
|
|||
|
|
'blockquote',
|
|||
|
|
'|',
|
|||
|
|
'bold',
|
|||
|
|
'underline',
|
|||
|
|
'italic',
|
|||
|
|
{
|
|||
|
|
key: 'group-more-style',
|
|||
|
|
title: dist$6.t('editor.more'),
|
|||
|
|
iconSvg: MORE_SVG,
|
|||
|
|
menuKeys: ['through', 'code', 'sup', 'sub', 'clearStyle'],
|
|||
|
|
},
|
|||
|
|
'color',
|
|||
|
|
'bgColor',
|
|||
|
|
'|',
|
|||
|
|
'fontSize',
|
|||
|
|
'fontFamily',
|
|||
|
|
'lineHeight',
|
|||
|
|
'|',
|
|||
|
|
'bulletedList',
|
|||
|
|
'numberedList',
|
|||
|
|
'todo',
|
|||
|
|
{
|
|||
|
|
key: 'group-justify',
|
|||
|
|
title: dist$6.t('editor.justify'),
|
|||
|
|
iconSvg: JUSTIFY_LEFT_SVG,
|
|||
|
|
menuKeys: ['justifyLeft', 'justifyRight', 'justifyCenter', 'justifyJustify'],
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
key: 'group-indent',
|
|||
|
|
title: dist$6.t('editor.indent'),
|
|||
|
|
iconSvg: INDENT_RIGHT_SVG,
|
|||
|
|
menuKeys: ['indent', 'delIndent'],
|
|||
|
|
},
|
|||
|
|
'|',
|
|||
|
|
'emotion',
|
|||
|
|
'insertLink',
|
|||
|
|
// 'editLink',
|
|||
|
|
// 'unLink',
|
|||
|
|
// 'viewLink',
|
|||
|
|
{
|
|||
|
|
key: 'group-image',
|
|||
|
|
title: dist$6.t('editor.image'),
|
|||
|
|
iconSvg: IMAGE_SVG,
|
|||
|
|
menuKeys: ['insertImage', 'uploadImage'],
|
|||
|
|
},
|
|||
|
|
// 'deleteImage',
|
|||
|
|
// 'editImage',
|
|||
|
|
// 'viewImageLink',
|
|||
|
|
{
|
|||
|
|
key: 'group-video',
|
|||
|
|
title: dist$6.t('editor.video'),
|
|||
|
|
iconSvg: VIDEO_SVG,
|
|||
|
|
menuKeys: ['insertVideo', 'uploadVideo'],
|
|||
|
|
},
|
|||
|
|
// 'deleteVideo',
|
|||
|
|
'insertTable',
|
|||
|
|
'codeBlock',
|
|||
|
|
// 'codeSelectLang',
|
|||
|
|
'divider',
|
|||
|
|
// 'deleteTable',
|
|||
|
|
'|',
|
|||
|
|
'undo',
|
|||
|
|
'redo',
|
|||
|
|
'|',
|
|||
|
|
'fullScreen',
|
|||
|
|
];
|
|||
|
|
}
|
|||
|
|
function genSimpleToolbarKeys() {
|
|||
|
|
return [
|
|||
|
|
'blockquote',
|
|||
|
|
'header1',
|
|||
|
|
'header2',
|
|||
|
|
'header3',
|
|||
|
|
'|',
|
|||
|
|
'bold',
|
|||
|
|
'underline',
|
|||
|
|
'italic',
|
|||
|
|
'through',
|
|||
|
|
'color',
|
|||
|
|
'bgColor',
|
|||
|
|
'clearStyle',
|
|||
|
|
'|',
|
|||
|
|
'bulletedList',
|
|||
|
|
'numberedList',
|
|||
|
|
'todo',
|
|||
|
|
'justifyLeft',
|
|||
|
|
'justifyRight',
|
|||
|
|
'justifyCenter',
|
|||
|
|
'|',
|
|||
|
|
'insertLink',
|
|||
|
|
{
|
|||
|
|
key: 'group-image',
|
|||
|
|
title: dist$6.t('editor.image'),
|
|||
|
|
iconSvg: IMAGE_SVG,
|
|||
|
|
menuKeys: ['insertImage', 'uploadImage'],
|
|||
|
|
},
|
|||
|
|
'insertVideo',
|
|||
|
|
'insertTable',
|
|||
|
|
'codeBlock',
|
|||
|
|
'|',
|
|||
|
|
'undo',
|
|||
|
|
'redo',
|
|||
|
|
'|',
|
|||
|
|
'fullScreen',
|
|||
|
|
];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @description hoverbar 配置
|
|||
|
|
* @author wangfupeng
|
|||
|
|
*/
|
|||
|
|
var COMMON_HOVERBAR_KEYS = {
|
|||
|
|
// key 即 element type
|
|||
|
|
link: {
|
|||
|
|
menuKeys: ['editLink', 'unLink', 'viewLink'],
|
|||
|
|
},
|
|||
|
|
image: {
|
|||
|
|
menuKeys: [
|
|||
|
|
'imageWidth30',
|
|||
|
|
'imageWidth50',
|
|||
|
|
'imageWidth100',
|
|||
|
|
'editImage',
|
|||
|
|
'viewImageLink',
|
|||
|
|
'deleteImage',
|
|||
|
|
],
|
|||
|
|
},
|
|||
|
|
pre: {
|
|||
|
|
menuKeys: ['enter', 'codeBlock', 'codeSelectLang'],
|
|||
|
|
},
|
|||
|
|
table: {
|
|||
|
|
menuKeys: [
|
|||
|
|
'enter',
|
|||
|
|
'tableHeader',
|
|||
|
|
'tableFullWidth',
|
|||
|
|
'insertTableRow',
|
|||
|
|
'deleteTableRow',
|
|||
|
|
'insertTableCol',
|
|||
|
|
'deleteTableCol',
|
|||
|
|
'deleteTable',
|
|||
|
|
],
|
|||
|
|
},
|
|||
|
|
divider: {
|
|||
|
|
menuKeys: ['enter'],
|
|||
|
|
},
|
|||
|
|
video: {
|
|||
|
|
menuKeys: ['enter', 'editVideoSize'],
|
|||
|
|
},
|
|||
|
|
};
|
|||
|
|
function genDefaultHoverbarKeys() {
|
|||
|
|
return __assign(__assign({}, COMMON_HOVERBAR_KEYS), {
|
|||
|
|
// 也可以自定义 match 来匹配元素,此时 key 就随意了
|
|||
|
|
text: {
|
|||
|
|
menuKeys: [
|
|||
|
|
'headerSelect',
|
|||
|
|
'insertLink',
|
|||
|
|
'bulletedList',
|
|||
|
|
'|',
|
|||
|
|
'bold',
|
|||
|
|
'through',
|
|||
|
|
'color',
|
|||
|
|
'bgColor',
|
|||
|
|
'clearStyle',
|
|||
|
|
],
|
|||
|
|
} });
|
|||
|
|
}
|
|||
|
|
function genSimpleHoverbarKeys() {
|
|||
|
|
return COMMON_HOVERBAR_KEYS;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @description 获取编辑器默认配置
|
|||
|
|
* @author wangfupeng
|
|||
|
|
*/
|
|||
|
|
function getDefaultEditorConfig() {
|
|||
|
|
return {
|
|||
|
|
hoverbarKeys: genDefaultHoverbarKeys(),
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
function getSimpleEditorConfig() {
|
|||
|
|
return {
|
|||
|
|
hoverbarKeys: genSimpleHoverbarKeys(),
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
function getDefaultToolbarConfig() {
|
|||
|
|
return {
|
|||
|
|
toolbarKeys: genDefaultToolbarKeys(),
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
function getSimpleToolbarConfig() {
|
|||
|
|
return {
|
|||
|
|
toolbarKeys: genSimpleToolbarKeys(),
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @description set default config
|
|||
|
|
* @author wangfupeng
|
|||
|
|
*/
|
|||
|
|
var defaultEditorConfig = getDefaultEditorConfig();
|
|||
|
|
Boot.setEditorConfig(__assign(__assign({}, defaultEditorConfig), { decorate: dist.wangEditorCodeHighLightDecorate }));
|
|||
|
|
var simpleEditorConfig = getSimpleEditorConfig();
|
|||
|
|
Boot.setSimpleEditorConfig(__assign(__assign({}, simpleEditorConfig), { decorate: dist.wangEditorCodeHighLightDecorate }));
|
|||
|
|
var defaultToolbarConfig = getDefaultToolbarConfig();
|
|||
|
|
Boot.setToolbarConfig(defaultToolbarConfig);
|
|||
|
|
var simpleToolbarConfig = getSimpleToolbarConfig();
|
|||
|
|
Boot.setSimpleToolbarConfig(simpleToolbarConfig);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @description create
|
|||
|
|
* @author wangfupeng
|
|||
|
|
*/
|
|||
|
|
/**
|
|||
|
|
* 创建 editor 实例
|
|||
|
|
*/
|
|||
|
|
function createEditor(option) {
|
|||
|
|
if (option === void 0) { option = {}; }
|
|||
|
|
var _a = option.selector, selector = _a === void 0 ? '' : _a, _b = option.content, content = _b === void 0 ? [] : _b, html = option.html, _c = option.config, config = _c === void 0 ? {} : _c, _d = option.mode, mode = _d === void 0 ? 'default' : _d;
|
|||
|
|
var globalConfig = mode === 'simple' ? Boot.simpleEditorConfig : Boot.editorConfig;
|
|||
|
|
// 单独处理 hoverbarKeys
|
|||
|
|
var newHoverbarKeys = __assign(__assign({}, (globalConfig.hoverbarKeys || {})), (config.hoverbarKeys || {}));
|
|||
|
|
var editor = dist$6.coreCreateEditor({
|
|||
|
|
selector: selector,
|
|||
|
|
config: __assign(__assign(__assign({}, globalConfig), config), { hoverbarKeys: newHoverbarKeys }),
|
|||
|
|
content: content,
|
|||
|
|
html: html,
|
|||
|
|
plugins: Boot.plugins,
|
|||
|
|
});
|
|||
|
|
return editor;
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* 创建 toolbar 实例
|
|||
|
|
*/
|
|||
|
|
function createToolbar(option) {
|
|||
|
|
var selector = option.selector, editor = option.editor, _a = option.config, config = _a === void 0 ? {} : _a, _b = option.mode, mode = _b === void 0 ? 'default' : _b;
|
|||
|
|
if (!selector) {
|
|||
|
|
throw new Error("Cannot find 'selector' when create toolbar");
|
|||
|
|
}
|
|||
|
|
var globalConfig = mode === 'simple' ? Boot.simpleToolbarConfig : Boot.toolbarConfig;
|
|||
|
|
var toolbar = dist$6.coreCreateToolbar(editor, {
|
|||
|
|
selector: selector,
|
|||
|
|
config: __assign(__assign({}, globalConfig), config),
|
|||
|
|
});
|
|||
|
|
return toolbar;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @description editor entry
|
|||
|
|
* @author wangfupeng
|
|||
|
|
*/
|
|||
|
|
var index = {};
|
|||
|
|
|
|||
|
|
exports.Boot = Boot;
|
|||
|
|
exports.DomEditor = dist$6.DomEditor;
|
|||
|
|
exports.SlateEditor = Editor_1;
|
|||
|
|
exports.SlateElement = Element_1;
|
|||
|
|
exports.SlateLocation = Location_1;
|
|||
|
|
exports.SlateNode = Node_1;
|
|||
|
|
exports.SlatePath = Path_1;
|
|||
|
|
exports.SlatePoint = Point_1;
|
|||
|
|
exports.SlateRange = Range_1;
|
|||
|
|
exports.SlateText = Text_1;
|
|||
|
|
exports.SlateTransforms = Transforms_1;
|
|||
|
|
exports.Toolbar = dist$6.Toolbar;
|
|||
|
|
exports.createEditor = createEditor;
|
|||
|
|
exports.createToolbar = createToolbar;
|
|||
|
|
exports.createUploader = dist$6.createUploader;
|
|||
|
|
exports["default"] = index;
|
|||
|
|
exports.genModalButtonElems = dist$6.genModalButtonElems;
|
|||
|
|
exports.genModalInputElems = dist$6.genModalInputElems;
|
|||
|
|
exports.genModalTextareaElems = dist$6.genModalTextareaElems;
|
|||
|
|
exports.i18nAddResources = dist$6.i18nAddResources;
|
|||
|
|
exports.i18nChangeLanguage = dist$6.i18nChangeLanguage;
|
|||
|
|
exports.i18nGetResources = dist$6.i18nGetResources;
|
|||
|
|
exports.t = dist$6.t;
|
|||
|
|
|
|||
|
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|||
|
|
|
|||
|
|
}));
|