remons-markdown-editor 1.0.0 → 2.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/MarkdownEditor.d.ts +24 -5
- package/dist/components/Dialog/EditDialog.d.ts +6 -3
- package/dist/components/Editor/codemirrorExtensions.d.ts +4 -4
- package/dist/components/Editor/containerWidget.d.ts +24 -8
- package/dist/components/Editor/index.d.ts +2 -1
- package/dist/components/Icon/config.d.ts +9 -0
- package/dist/components/Preview/index.d.ts +6 -5
- package/dist/components/Toolbar/buttons.d.ts +3 -3
- package/dist/components/Toolbar/config.d.ts +9 -2
- package/dist/components/Toolbar/hooks/useToolbar.d.ts +3 -1
- package/dist/components/Toolbar/index.d.ts +6 -3
- package/dist/components/Toolbar/renderers/TablePicker/TableDropdown.d.ts +1 -2
- package/dist/hooks/useRegisterToolbar.d.ts +3 -0
- package/dist/hooks/useScrollSync.d.ts +5 -2
- package/dist/index.cjs +2101 -406
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +51 -80
- package/dist/index.d.ts +3 -1
- package/dist/index.js +2123 -409
- package/dist/index.js.map +1 -1
- package/dist/registry/componentRegistry.d.ts +17 -4
- package/dist/types/index.d.ts +19 -10
- package/dist/utils/parseContainer.d.ts +26 -6
- package/dist/utils/writeContainer.d.ts +11 -7
- package/package.json +12 -15
- package/readme.md +26 -22
- package/dist/App.d.ts +0 -2
- package/dist/main.d.ts +0 -0
package/dist/index.cjs
CHANGED
|
@@ -6,6 +6,7 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
6
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
7
|
var __getProtoOf = Object.getPrototypeOf;
|
|
8
8
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
|
|
9
10
|
var __copyProps = (to, from, except, desc) => {
|
|
10
11
|
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
11
12
|
key = keys[i];
|
|
@@ -36,83 +37,1195 @@ let remons_render_markdown = require("remons-render-markdown");
|
|
|
36
37
|
remons_render_markdown = __toESM(remons_render_markdown, 1);
|
|
37
38
|
require("remons-render-markdown/dist/index.css");
|
|
38
39
|
let _ant_design_icons = require("@ant-design/icons");
|
|
39
|
-
//#
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
if (trimmed.startsWith("{") && trimmed.endsWith("}")) {
|
|
49
|
-
const inner = trimmed.slice(1, -1).trim();
|
|
50
|
-
if (!inner) return props;
|
|
51
|
-
const matches = inner.matchAll(/(?:["']?)(\w+)(?:["']?)\s*:\s*(?:"([^"]*)"|'([^']*)'|(\d+))/g);
|
|
52
|
-
for (const m of matches) props[m[1]] = m[2] ?? m[3] ?? m[4] ?? "";
|
|
40
|
+
//#endregion
|
|
41
|
+
//#region src/registry/componentRegistry.tsx
|
|
42
|
+
var import_dist = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
43
|
+
(function(global, factory) {
|
|
44
|
+
typeof exports === "object" && typeof module !== "undefined" ? module.exports = factory() : typeof define === "function" && define.amd ? define(factory) : global.JSON5 = factory();
|
|
45
|
+
})(exports, (function() {
|
|
46
|
+
"use strict";
|
|
47
|
+
function createCommonjsModule(fn, module$1) {
|
|
48
|
+
return module$1 = { exports: {} }, fn(module$1, module$1.exports), module$1.exports;
|
|
53
49
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
50
|
+
var _global = createCommonjsModule(function(module$2) {
|
|
51
|
+
var global = module$2.exports = typeof window != "undefined" && window.Math == Math ? window : typeof self != "undefined" && self.Math == Math ? self : Function("return this")();
|
|
52
|
+
if (typeof __g == "number") __g = global;
|
|
53
|
+
});
|
|
54
|
+
var _core = createCommonjsModule(function(module$3) {
|
|
55
|
+
var core = module$3.exports = { version: "2.6.5" };
|
|
56
|
+
if (typeof __e == "number") __e = core;
|
|
57
|
+
});
|
|
58
|
+
_core.version;
|
|
59
|
+
var _isObject = function(it) {
|
|
60
|
+
return typeof it === "object" ? it !== null : typeof it === "function";
|
|
61
|
+
};
|
|
62
|
+
var _anObject = function(it) {
|
|
63
|
+
if (!_isObject(it)) throw TypeError(it + " is not an object!");
|
|
64
|
+
return it;
|
|
65
|
+
};
|
|
66
|
+
var _fails = function(exec) {
|
|
67
|
+
try {
|
|
68
|
+
return !!exec();
|
|
69
|
+
} catch (e) {
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
var _descriptors = !_fails(function() {
|
|
74
|
+
return Object.defineProperty({}, "a", { get: function() {
|
|
75
|
+
return 7;
|
|
76
|
+
} }).a != 7;
|
|
77
|
+
});
|
|
78
|
+
var document = _global.document;
|
|
79
|
+
var is = _isObject(document) && _isObject(document.createElement);
|
|
80
|
+
var _domCreate = function(it) {
|
|
81
|
+
return is ? document.createElement(it) : {};
|
|
82
|
+
};
|
|
83
|
+
var _ie8DomDefine = !_descriptors && !_fails(function() {
|
|
84
|
+
return Object.defineProperty(_domCreate("div"), "a", { get: function() {
|
|
85
|
+
return 7;
|
|
86
|
+
} }).a != 7;
|
|
87
|
+
});
|
|
88
|
+
var _toPrimitive = function(it, S) {
|
|
89
|
+
if (!_isObject(it)) return it;
|
|
90
|
+
var fn, val;
|
|
91
|
+
if (S && typeof (fn = it.toString) == "function" && !_isObject(val = fn.call(it))) return val;
|
|
92
|
+
if (typeof (fn = it.valueOf) == "function" && !_isObject(val = fn.call(it))) return val;
|
|
93
|
+
if (!S && typeof (fn = it.toString) == "function" && !_isObject(val = fn.call(it))) return val;
|
|
94
|
+
throw TypeError("Can't convert object to primitive value");
|
|
95
|
+
};
|
|
96
|
+
var dP = Object.defineProperty;
|
|
97
|
+
var _objectDp = { f: _descriptors ? Object.defineProperty : function defineProperty(O, P, Attributes) {
|
|
98
|
+
_anObject(O);
|
|
99
|
+
P = _toPrimitive(P, true);
|
|
100
|
+
_anObject(Attributes);
|
|
101
|
+
if (_ie8DomDefine) try {
|
|
102
|
+
return dP(O, P, Attributes);
|
|
103
|
+
} catch (e) {}
|
|
104
|
+
if ("get" in Attributes || "set" in Attributes) throw TypeError("Accessors not supported!");
|
|
105
|
+
if ("value" in Attributes) O[P] = Attributes.value;
|
|
106
|
+
return O;
|
|
107
|
+
} };
|
|
108
|
+
var _propertyDesc = function(bitmap, value) {
|
|
109
|
+
return {
|
|
110
|
+
enumerable: !(bitmap & 1),
|
|
111
|
+
configurable: !(bitmap & 2),
|
|
112
|
+
writable: !(bitmap & 4),
|
|
113
|
+
value
|
|
114
|
+
};
|
|
115
|
+
};
|
|
116
|
+
var _hide = _descriptors ? function(object, key, value) {
|
|
117
|
+
return _objectDp.f(object, key, _propertyDesc(1, value));
|
|
118
|
+
} : function(object, key, value) {
|
|
119
|
+
object[key] = value;
|
|
120
|
+
return object;
|
|
121
|
+
};
|
|
122
|
+
var hasOwnProperty = {}.hasOwnProperty;
|
|
123
|
+
var _has = function(it, key) {
|
|
124
|
+
return hasOwnProperty.call(it, key);
|
|
125
|
+
};
|
|
126
|
+
var id = 0;
|
|
127
|
+
var px = Math.random();
|
|
128
|
+
var _uid = function(key) {
|
|
129
|
+
return "Symbol(".concat(key === void 0 ? "" : key, ")_", (++id + px).toString(36));
|
|
130
|
+
};
|
|
131
|
+
var _library = false;
|
|
132
|
+
var _functionToString = createCommonjsModule(function(module$4) {
|
|
133
|
+
var SHARED = "__core-js_shared__";
|
|
134
|
+
var store = _global[SHARED] || (_global[SHARED] = {});
|
|
135
|
+
(module$4.exports = function(key, value) {
|
|
136
|
+
return store[key] || (store[key] = value !== void 0 ? value : {});
|
|
137
|
+
})("versions", []).push({
|
|
138
|
+
version: _core.version,
|
|
139
|
+
mode: _library ? "pure" : "global",
|
|
140
|
+
copyright: "© 2019 Denis Pushkarev (zloirock.ru)"
|
|
141
|
+
});
|
|
142
|
+
})("native-function-to-string", Function.toString);
|
|
143
|
+
var _redefine = createCommonjsModule(function(module$5) {
|
|
144
|
+
var SRC = _uid("src");
|
|
145
|
+
var TO_STRING = "toString";
|
|
146
|
+
var TPL = ("" + _functionToString).split(TO_STRING);
|
|
147
|
+
_core.inspectSource = function(it) {
|
|
148
|
+
return _functionToString.call(it);
|
|
149
|
+
};
|
|
150
|
+
(module$5.exports = function(O, key, val, safe) {
|
|
151
|
+
var isFunction = typeof val == "function";
|
|
152
|
+
if (isFunction) _has(val, "name") || _hide(val, "name", key);
|
|
153
|
+
if (O[key] === val) return;
|
|
154
|
+
if (isFunction) _has(val, SRC) || _hide(val, SRC, O[key] ? "" + O[key] : TPL.join(String(key)));
|
|
155
|
+
if (O === _global) O[key] = val;
|
|
156
|
+
else if (!safe) {
|
|
157
|
+
delete O[key];
|
|
158
|
+
_hide(O, key, val);
|
|
159
|
+
} else if (O[key]) O[key] = val;
|
|
160
|
+
else _hide(O, key, val);
|
|
161
|
+
})(Function.prototype, TO_STRING, function toString() {
|
|
162
|
+
return typeof this == "function" && this[SRC] || _functionToString.call(this);
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
var _aFunction = function(it) {
|
|
166
|
+
if (typeof it != "function") throw TypeError(it + " is not a function!");
|
|
167
|
+
return it;
|
|
168
|
+
};
|
|
169
|
+
var _ctx = function(fn, that, length) {
|
|
170
|
+
_aFunction(fn);
|
|
171
|
+
if (that === void 0) return fn;
|
|
172
|
+
switch (length) {
|
|
173
|
+
case 1: return function(a) {
|
|
174
|
+
return fn.call(that, a);
|
|
175
|
+
};
|
|
176
|
+
case 2: return function(a, b) {
|
|
177
|
+
return fn.call(that, a, b);
|
|
178
|
+
};
|
|
179
|
+
case 3: return function(a, b, c) {
|
|
180
|
+
return fn.call(that, a, b, c);
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
return function() {
|
|
184
|
+
return fn.apply(that, arguments);
|
|
185
|
+
};
|
|
186
|
+
};
|
|
187
|
+
var PROTOTYPE = "prototype";
|
|
188
|
+
var $export = function(type, name, source) {
|
|
189
|
+
var IS_FORCED = type & $export.F;
|
|
190
|
+
var IS_GLOBAL = type & $export.G;
|
|
191
|
+
var IS_STATIC = type & $export.S;
|
|
192
|
+
var IS_PROTO = type & $export.P;
|
|
193
|
+
var IS_BIND = type & $export.B;
|
|
194
|
+
var target = IS_GLOBAL ? _global : IS_STATIC ? _global[name] || (_global[name] = {}) : (_global[name] || {})[PROTOTYPE];
|
|
195
|
+
var exports$1 = IS_GLOBAL ? _core : _core[name] || (_core[name] = {});
|
|
196
|
+
var expProto = exports$1[PROTOTYPE] || (exports$1[PROTOTYPE] = {});
|
|
197
|
+
var key, own, out, exp;
|
|
198
|
+
if (IS_GLOBAL) source = name;
|
|
199
|
+
for (key in source) {
|
|
200
|
+
own = !IS_FORCED && target && target[key] !== void 0;
|
|
201
|
+
out = (own ? target : source)[key];
|
|
202
|
+
exp = IS_BIND && own ? _ctx(out, _global) : IS_PROTO && typeof out == "function" ? _ctx(Function.call, out) : out;
|
|
203
|
+
if (target) _redefine(target, key, out, type & $export.U);
|
|
204
|
+
if (exports$1[key] != out) _hide(exports$1, key, exp);
|
|
205
|
+
if (IS_PROTO && expProto[key] != out) expProto[key] = out;
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
_global.core = _core;
|
|
209
|
+
$export.F = 1;
|
|
210
|
+
$export.G = 2;
|
|
211
|
+
$export.S = 4;
|
|
212
|
+
$export.P = 8;
|
|
213
|
+
$export.B = 16;
|
|
214
|
+
$export.W = 32;
|
|
215
|
+
$export.U = 64;
|
|
216
|
+
$export.R = 128;
|
|
217
|
+
var _export = $export;
|
|
218
|
+
var ceil = Math.ceil;
|
|
219
|
+
var floor = Math.floor;
|
|
220
|
+
var _toInteger = function(it) {
|
|
221
|
+
return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it);
|
|
222
|
+
};
|
|
223
|
+
var _defined = function(it) {
|
|
224
|
+
if (it == void 0) throw TypeError("Can't call method on " + it);
|
|
225
|
+
return it;
|
|
226
|
+
};
|
|
227
|
+
var _stringAt = function(TO_STRING) {
|
|
228
|
+
return function(that, pos) {
|
|
229
|
+
var s = String(_defined(that));
|
|
230
|
+
var i = _toInteger(pos);
|
|
231
|
+
var l = s.length;
|
|
232
|
+
var a, b;
|
|
233
|
+
if (i < 0 || i >= l) return TO_STRING ? "" : void 0;
|
|
234
|
+
a = s.charCodeAt(i);
|
|
235
|
+
return a < 55296 || a > 56319 || i + 1 === l || (b = s.charCodeAt(i + 1)) < 56320 || b > 57343 ? TO_STRING ? s.charAt(i) : a : TO_STRING ? s.slice(i, i + 2) : (a - 55296 << 10) + (b - 56320) + 65536;
|
|
236
|
+
};
|
|
237
|
+
};
|
|
238
|
+
var $at = _stringAt(false);
|
|
239
|
+
_export(_export.P, "String", { codePointAt: function codePointAt(pos) {
|
|
240
|
+
return $at(this, pos);
|
|
241
|
+
} });
|
|
242
|
+
_core.String.codePointAt;
|
|
243
|
+
var max = Math.max;
|
|
244
|
+
var min = Math.min;
|
|
245
|
+
var _toAbsoluteIndex = function(index, length) {
|
|
246
|
+
index = _toInteger(index);
|
|
247
|
+
return index < 0 ? max(index + length, 0) : min(index, length);
|
|
248
|
+
};
|
|
249
|
+
var fromCharCode = String.fromCharCode;
|
|
250
|
+
var $fromCodePoint = String.fromCodePoint;
|
|
251
|
+
_export(_export.S + _export.F * (!!$fromCodePoint && $fromCodePoint.length != 1), "String", { fromCodePoint: function fromCodePoint(x) {
|
|
252
|
+
var arguments$1 = arguments;
|
|
253
|
+
var res = [];
|
|
254
|
+
var aLen = arguments.length;
|
|
255
|
+
var i = 0;
|
|
256
|
+
var code;
|
|
257
|
+
while (aLen > i) {
|
|
258
|
+
code = +arguments$1[i++];
|
|
259
|
+
if (_toAbsoluteIndex(code, 1114111) !== code) throw RangeError(code + " is not a valid code point");
|
|
260
|
+
res.push(code < 65536 ? fromCharCode(code) : fromCharCode(((code -= 65536) >> 10) + 55296, code % 1024 + 56320));
|
|
261
|
+
}
|
|
262
|
+
return res.join("");
|
|
263
|
+
} });
|
|
264
|
+
_core.String.fromCodePoint;
|
|
265
|
+
var unicode = {
|
|
266
|
+
Space_Separator: /[\u1680\u2000-\u200A\u202F\u205F\u3000]/,
|
|
267
|
+
ID_Start: /[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE83\uDE86-\uDE89\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4\uDD00-\uDD43]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]/,
|
|
268
|
+
ID_Continue: /[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u08D4-\u08E1\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u09FC\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9-\u0AFF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C80-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D00-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D54-\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1CD0-\u1CD2\u1CD4-\u1CF9\u1D00-\u1DF9\u1DFB-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C5\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE3E\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC00-\uDC4A\uDC50-\uDC59\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDE00-\uDE3E\uDE47\uDE50-\uDE83\uDE86-\uDE99\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC36\uDC38-\uDC40\uDC50-\uDC59\uDC72-\uDC8F\uDC92-\uDCA7\uDCA9-\uDCB6\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD47\uDD50-\uDD59]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6\uDD00-\uDD4A\uDD50-\uDD59]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/
|
|
269
|
+
};
|
|
270
|
+
var util = {
|
|
271
|
+
isSpaceSeparator: function isSpaceSeparator(c) {
|
|
272
|
+
return typeof c === "string" && unicode.Space_Separator.test(c);
|
|
273
|
+
},
|
|
274
|
+
isIdStartChar: function isIdStartChar(c) {
|
|
275
|
+
return typeof c === "string" && (c >= "a" && c <= "z" || c >= "A" && c <= "Z" || c === "$" || c === "_" || unicode.ID_Start.test(c));
|
|
276
|
+
},
|
|
277
|
+
isIdContinueChar: function isIdContinueChar(c) {
|
|
278
|
+
return typeof c === "string" && (c >= "a" && c <= "z" || c >= "A" && c <= "Z" || c >= "0" && c <= "9" || c === "$" || c === "_" || c === "" || c === "" || unicode.ID_Continue.test(c));
|
|
279
|
+
},
|
|
280
|
+
isDigit: function isDigit(c) {
|
|
281
|
+
return typeof c === "string" && /[0-9]/.test(c);
|
|
282
|
+
},
|
|
283
|
+
isHexDigit: function isHexDigit(c) {
|
|
284
|
+
return typeof c === "string" && /[0-9A-Fa-f]/.test(c);
|
|
285
|
+
}
|
|
286
|
+
};
|
|
287
|
+
var source;
|
|
288
|
+
var parseState;
|
|
289
|
+
var stack;
|
|
290
|
+
var pos;
|
|
291
|
+
var line;
|
|
292
|
+
var column;
|
|
293
|
+
var token;
|
|
294
|
+
var key;
|
|
295
|
+
var root;
|
|
296
|
+
var parse = function parse(text, reviver) {
|
|
297
|
+
source = String(text);
|
|
298
|
+
parseState = "start";
|
|
299
|
+
stack = [];
|
|
300
|
+
pos = 0;
|
|
301
|
+
line = 1;
|
|
302
|
+
column = 0;
|
|
303
|
+
token = void 0;
|
|
304
|
+
key = void 0;
|
|
305
|
+
root = void 0;
|
|
306
|
+
do {
|
|
307
|
+
token = lex();
|
|
308
|
+
parseStates[parseState]();
|
|
309
|
+
} while (token.type !== "eof");
|
|
310
|
+
if (typeof reviver === "function") return internalize({ "": root }, "", reviver);
|
|
311
|
+
return root;
|
|
312
|
+
};
|
|
313
|
+
function internalize(holder, name, reviver) {
|
|
314
|
+
var value = holder[name];
|
|
315
|
+
if (value != null && typeof value === "object") {
|
|
316
|
+
if (Array.isArray(value)) for (var i = 0; i < value.length; i++) {
|
|
317
|
+
var key = String(i);
|
|
318
|
+
var replacement = internalize(value, key, reviver);
|
|
319
|
+
if (replacement === void 0) delete value[key];
|
|
320
|
+
else Object.defineProperty(value, key, {
|
|
321
|
+
value: replacement,
|
|
322
|
+
writable: true,
|
|
323
|
+
enumerable: true,
|
|
324
|
+
configurable: true
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
else for (var key$1 in value) {
|
|
328
|
+
var replacement$1 = internalize(value, key$1, reviver);
|
|
329
|
+
if (replacement$1 === void 0) delete value[key$1];
|
|
330
|
+
else Object.defineProperty(value, key$1, {
|
|
331
|
+
value: replacement$1,
|
|
332
|
+
writable: true,
|
|
333
|
+
enumerable: true,
|
|
334
|
+
configurable: true
|
|
335
|
+
});
|
|
80
336
|
}
|
|
81
337
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
338
|
+
return reviver.call(holder, name, value);
|
|
339
|
+
}
|
|
340
|
+
var lexState;
|
|
341
|
+
var buffer;
|
|
342
|
+
var doubleQuote;
|
|
343
|
+
var sign;
|
|
344
|
+
var c;
|
|
345
|
+
function lex() {
|
|
346
|
+
lexState = "default";
|
|
347
|
+
buffer = "";
|
|
348
|
+
doubleQuote = false;
|
|
349
|
+
sign = 1;
|
|
350
|
+
for (;;) {
|
|
351
|
+
c = peek();
|
|
352
|
+
var token = lexStates[lexState]();
|
|
353
|
+
if (token) return token;
|
|
89
354
|
}
|
|
90
|
-
containers.push({
|
|
91
|
-
startPos: charPos,
|
|
92
|
-
typeName,
|
|
93
|
-
propsLineFrom,
|
|
94
|
-
propsLineTo,
|
|
95
|
-
props,
|
|
96
|
-
endPos
|
|
97
|
-
});
|
|
98
355
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
356
|
+
function peek() {
|
|
357
|
+
if (source[pos]) return String.fromCodePoint(source.codePointAt(pos));
|
|
358
|
+
}
|
|
359
|
+
function read() {
|
|
360
|
+
var c = peek();
|
|
361
|
+
if (c === "\n") {
|
|
362
|
+
line++;
|
|
363
|
+
column = 0;
|
|
364
|
+
} else if (c) column += c.length;
|
|
365
|
+
else column++;
|
|
366
|
+
if (c) pos += c.length;
|
|
367
|
+
return c;
|
|
368
|
+
}
|
|
369
|
+
var lexStates = {
|
|
370
|
+
default: function default$1() {
|
|
371
|
+
switch (c) {
|
|
372
|
+
case " ":
|
|
373
|
+
case "\v":
|
|
374
|
+
case "\f":
|
|
375
|
+
case " ":
|
|
376
|
+
case "\xA0":
|
|
377
|
+
case "":
|
|
378
|
+
case "\n":
|
|
379
|
+
case "\r":
|
|
380
|
+
case "\u2028":
|
|
381
|
+
case "\u2029":
|
|
382
|
+
read();
|
|
383
|
+
return;
|
|
384
|
+
case "/":
|
|
385
|
+
read();
|
|
386
|
+
lexState = "comment";
|
|
387
|
+
return;
|
|
388
|
+
case void 0:
|
|
389
|
+
read();
|
|
390
|
+
return newToken("eof");
|
|
391
|
+
}
|
|
392
|
+
if (util.isSpaceSeparator(c)) {
|
|
393
|
+
read();
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
return lexStates[parseState]();
|
|
397
|
+
},
|
|
398
|
+
comment: function comment() {
|
|
399
|
+
switch (c) {
|
|
400
|
+
case "*":
|
|
401
|
+
read();
|
|
402
|
+
lexState = "multiLineComment";
|
|
403
|
+
return;
|
|
404
|
+
case "/":
|
|
405
|
+
read();
|
|
406
|
+
lexState = "singleLineComment";
|
|
407
|
+
return;
|
|
408
|
+
}
|
|
409
|
+
throw invalidChar(read());
|
|
410
|
+
},
|
|
411
|
+
multiLineComment: function multiLineComment() {
|
|
412
|
+
switch (c) {
|
|
413
|
+
case "*":
|
|
414
|
+
read();
|
|
415
|
+
lexState = "multiLineCommentAsterisk";
|
|
416
|
+
return;
|
|
417
|
+
case void 0: throw invalidChar(read());
|
|
418
|
+
}
|
|
419
|
+
read();
|
|
420
|
+
},
|
|
421
|
+
multiLineCommentAsterisk: function multiLineCommentAsterisk() {
|
|
422
|
+
switch (c) {
|
|
423
|
+
case "*":
|
|
424
|
+
read();
|
|
425
|
+
return;
|
|
426
|
+
case "/":
|
|
427
|
+
read();
|
|
428
|
+
lexState = "default";
|
|
429
|
+
return;
|
|
430
|
+
case void 0: throw invalidChar(read());
|
|
431
|
+
}
|
|
432
|
+
read();
|
|
433
|
+
lexState = "multiLineComment";
|
|
434
|
+
},
|
|
435
|
+
singleLineComment: function singleLineComment() {
|
|
436
|
+
switch (c) {
|
|
437
|
+
case "\n":
|
|
438
|
+
case "\r":
|
|
439
|
+
case "\u2028":
|
|
440
|
+
case "\u2029":
|
|
441
|
+
read();
|
|
442
|
+
lexState = "default";
|
|
443
|
+
return;
|
|
444
|
+
case void 0:
|
|
445
|
+
read();
|
|
446
|
+
return newToken("eof");
|
|
447
|
+
}
|
|
448
|
+
read();
|
|
449
|
+
},
|
|
450
|
+
value: function value() {
|
|
451
|
+
switch (c) {
|
|
452
|
+
case "{":
|
|
453
|
+
case "[": return newToken("punctuator", read());
|
|
454
|
+
case "n":
|
|
455
|
+
read();
|
|
456
|
+
literal("ull");
|
|
457
|
+
return newToken("null", null);
|
|
458
|
+
case "t":
|
|
459
|
+
read();
|
|
460
|
+
literal("rue");
|
|
461
|
+
return newToken("boolean", true);
|
|
462
|
+
case "f":
|
|
463
|
+
read();
|
|
464
|
+
literal("alse");
|
|
465
|
+
return newToken("boolean", false);
|
|
466
|
+
case "-":
|
|
467
|
+
case "+":
|
|
468
|
+
if (read() === "-") sign = -1;
|
|
469
|
+
lexState = "sign";
|
|
470
|
+
return;
|
|
471
|
+
case ".":
|
|
472
|
+
buffer = read();
|
|
473
|
+
lexState = "decimalPointLeading";
|
|
474
|
+
return;
|
|
475
|
+
case "0":
|
|
476
|
+
buffer = read();
|
|
477
|
+
lexState = "zero";
|
|
478
|
+
return;
|
|
479
|
+
case "1":
|
|
480
|
+
case "2":
|
|
481
|
+
case "3":
|
|
482
|
+
case "4":
|
|
483
|
+
case "5":
|
|
484
|
+
case "6":
|
|
485
|
+
case "7":
|
|
486
|
+
case "8":
|
|
487
|
+
case "9":
|
|
488
|
+
buffer = read();
|
|
489
|
+
lexState = "decimalInteger";
|
|
490
|
+
return;
|
|
491
|
+
case "I":
|
|
492
|
+
read();
|
|
493
|
+
literal("nfinity");
|
|
494
|
+
return newToken("numeric", Infinity);
|
|
495
|
+
case "N":
|
|
496
|
+
read();
|
|
497
|
+
literal("aN");
|
|
498
|
+
return newToken("numeric", NaN);
|
|
499
|
+
case "\"":
|
|
500
|
+
case "'":
|
|
501
|
+
doubleQuote = read() === "\"";
|
|
502
|
+
buffer = "";
|
|
503
|
+
lexState = "string";
|
|
504
|
+
return;
|
|
505
|
+
}
|
|
506
|
+
throw invalidChar(read());
|
|
507
|
+
},
|
|
508
|
+
identifierNameStartEscape: function identifierNameStartEscape() {
|
|
509
|
+
if (c !== "u") throw invalidChar(read());
|
|
510
|
+
read();
|
|
511
|
+
var u = unicodeEscape();
|
|
512
|
+
switch (u) {
|
|
513
|
+
case "$":
|
|
514
|
+
case "_": break;
|
|
515
|
+
default: if (!util.isIdStartChar(u)) throw invalidIdentifier();
|
|
516
|
+
}
|
|
517
|
+
buffer += u;
|
|
518
|
+
lexState = "identifierName";
|
|
519
|
+
},
|
|
520
|
+
identifierName: function identifierName() {
|
|
521
|
+
switch (c) {
|
|
522
|
+
case "$":
|
|
523
|
+
case "_":
|
|
524
|
+
case "":
|
|
525
|
+
case "":
|
|
526
|
+
buffer += read();
|
|
527
|
+
return;
|
|
528
|
+
case "\\":
|
|
529
|
+
read();
|
|
530
|
+
lexState = "identifierNameEscape";
|
|
531
|
+
return;
|
|
532
|
+
}
|
|
533
|
+
if (util.isIdContinueChar(c)) {
|
|
534
|
+
buffer += read();
|
|
535
|
+
return;
|
|
536
|
+
}
|
|
537
|
+
return newToken("identifier", buffer);
|
|
538
|
+
},
|
|
539
|
+
identifierNameEscape: function identifierNameEscape() {
|
|
540
|
+
if (c !== "u") throw invalidChar(read());
|
|
541
|
+
read();
|
|
542
|
+
var u = unicodeEscape();
|
|
543
|
+
switch (u) {
|
|
544
|
+
case "$":
|
|
545
|
+
case "_":
|
|
546
|
+
case "":
|
|
547
|
+
case "": break;
|
|
548
|
+
default: if (!util.isIdContinueChar(u)) throw invalidIdentifier();
|
|
549
|
+
}
|
|
550
|
+
buffer += u;
|
|
551
|
+
lexState = "identifierName";
|
|
552
|
+
},
|
|
553
|
+
sign: function sign$1() {
|
|
554
|
+
switch (c) {
|
|
555
|
+
case ".":
|
|
556
|
+
buffer = read();
|
|
557
|
+
lexState = "decimalPointLeading";
|
|
558
|
+
return;
|
|
559
|
+
case "0":
|
|
560
|
+
buffer = read();
|
|
561
|
+
lexState = "zero";
|
|
562
|
+
return;
|
|
563
|
+
case "1":
|
|
564
|
+
case "2":
|
|
565
|
+
case "3":
|
|
566
|
+
case "4":
|
|
567
|
+
case "5":
|
|
568
|
+
case "6":
|
|
569
|
+
case "7":
|
|
570
|
+
case "8":
|
|
571
|
+
case "9":
|
|
572
|
+
buffer = read();
|
|
573
|
+
lexState = "decimalInteger";
|
|
574
|
+
return;
|
|
575
|
+
case "I":
|
|
576
|
+
read();
|
|
577
|
+
literal("nfinity");
|
|
578
|
+
return newToken("numeric", sign * Infinity);
|
|
579
|
+
case "N":
|
|
580
|
+
read();
|
|
581
|
+
literal("aN");
|
|
582
|
+
return newToken("numeric", NaN);
|
|
583
|
+
}
|
|
584
|
+
throw invalidChar(read());
|
|
585
|
+
},
|
|
586
|
+
zero: function zero() {
|
|
587
|
+
switch (c) {
|
|
588
|
+
case ".":
|
|
589
|
+
buffer += read();
|
|
590
|
+
lexState = "decimalPoint";
|
|
591
|
+
return;
|
|
592
|
+
case "e":
|
|
593
|
+
case "E":
|
|
594
|
+
buffer += read();
|
|
595
|
+
lexState = "decimalExponent";
|
|
596
|
+
return;
|
|
597
|
+
case "x":
|
|
598
|
+
case "X":
|
|
599
|
+
buffer += read();
|
|
600
|
+
lexState = "hexadecimal";
|
|
601
|
+
return;
|
|
602
|
+
}
|
|
603
|
+
return newToken("numeric", sign * 0);
|
|
604
|
+
},
|
|
605
|
+
decimalInteger: function decimalInteger() {
|
|
606
|
+
switch (c) {
|
|
607
|
+
case ".":
|
|
608
|
+
buffer += read();
|
|
609
|
+
lexState = "decimalPoint";
|
|
610
|
+
return;
|
|
611
|
+
case "e":
|
|
612
|
+
case "E":
|
|
613
|
+
buffer += read();
|
|
614
|
+
lexState = "decimalExponent";
|
|
615
|
+
return;
|
|
616
|
+
}
|
|
617
|
+
if (util.isDigit(c)) {
|
|
618
|
+
buffer += read();
|
|
619
|
+
return;
|
|
620
|
+
}
|
|
621
|
+
return newToken("numeric", sign * Number(buffer));
|
|
622
|
+
},
|
|
623
|
+
decimalPointLeading: function decimalPointLeading() {
|
|
624
|
+
if (util.isDigit(c)) {
|
|
625
|
+
buffer += read();
|
|
626
|
+
lexState = "decimalFraction";
|
|
627
|
+
return;
|
|
628
|
+
}
|
|
629
|
+
throw invalidChar(read());
|
|
630
|
+
},
|
|
631
|
+
decimalPoint: function decimalPoint() {
|
|
632
|
+
switch (c) {
|
|
633
|
+
case "e":
|
|
634
|
+
case "E":
|
|
635
|
+
buffer += read();
|
|
636
|
+
lexState = "decimalExponent";
|
|
637
|
+
return;
|
|
638
|
+
}
|
|
639
|
+
if (util.isDigit(c)) {
|
|
640
|
+
buffer += read();
|
|
641
|
+
lexState = "decimalFraction";
|
|
642
|
+
return;
|
|
643
|
+
}
|
|
644
|
+
return newToken("numeric", sign * Number(buffer));
|
|
645
|
+
},
|
|
646
|
+
decimalFraction: function decimalFraction() {
|
|
647
|
+
switch (c) {
|
|
648
|
+
case "e":
|
|
649
|
+
case "E":
|
|
650
|
+
buffer += read();
|
|
651
|
+
lexState = "decimalExponent";
|
|
652
|
+
return;
|
|
653
|
+
}
|
|
654
|
+
if (util.isDigit(c)) {
|
|
655
|
+
buffer += read();
|
|
656
|
+
return;
|
|
657
|
+
}
|
|
658
|
+
return newToken("numeric", sign * Number(buffer));
|
|
659
|
+
},
|
|
660
|
+
decimalExponent: function decimalExponent() {
|
|
661
|
+
switch (c) {
|
|
662
|
+
case "+":
|
|
663
|
+
case "-":
|
|
664
|
+
buffer += read();
|
|
665
|
+
lexState = "decimalExponentSign";
|
|
666
|
+
return;
|
|
667
|
+
}
|
|
668
|
+
if (util.isDigit(c)) {
|
|
669
|
+
buffer += read();
|
|
670
|
+
lexState = "decimalExponentInteger";
|
|
671
|
+
return;
|
|
672
|
+
}
|
|
673
|
+
throw invalidChar(read());
|
|
674
|
+
},
|
|
675
|
+
decimalExponentSign: function decimalExponentSign() {
|
|
676
|
+
if (util.isDigit(c)) {
|
|
677
|
+
buffer += read();
|
|
678
|
+
lexState = "decimalExponentInteger";
|
|
679
|
+
return;
|
|
680
|
+
}
|
|
681
|
+
throw invalidChar(read());
|
|
682
|
+
},
|
|
683
|
+
decimalExponentInteger: function decimalExponentInteger() {
|
|
684
|
+
if (util.isDigit(c)) {
|
|
685
|
+
buffer += read();
|
|
686
|
+
return;
|
|
687
|
+
}
|
|
688
|
+
return newToken("numeric", sign * Number(buffer));
|
|
689
|
+
},
|
|
690
|
+
hexadecimal: function hexadecimal() {
|
|
691
|
+
if (util.isHexDigit(c)) {
|
|
692
|
+
buffer += read();
|
|
693
|
+
lexState = "hexadecimalInteger";
|
|
694
|
+
return;
|
|
695
|
+
}
|
|
696
|
+
throw invalidChar(read());
|
|
697
|
+
},
|
|
698
|
+
hexadecimalInteger: function hexadecimalInteger() {
|
|
699
|
+
if (util.isHexDigit(c)) {
|
|
700
|
+
buffer += read();
|
|
701
|
+
return;
|
|
702
|
+
}
|
|
703
|
+
return newToken("numeric", sign * Number(buffer));
|
|
704
|
+
},
|
|
705
|
+
string: function string() {
|
|
706
|
+
switch (c) {
|
|
707
|
+
case "\\":
|
|
708
|
+
read();
|
|
709
|
+
buffer += escape();
|
|
710
|
+
return;
|
|
711
|
+
case "\"":
|
|
712
|
+
if (doubleQuote) {
|
|
713
|
+
read();
|
|
714
|
+
return newToken("string", buffer);
|
|
715
|
+
}
|
|
716
|
+
buffer += read();
|
|
717
|
+
return;
|
|
718
|
+
case "'":
|
|
719
|
+
if (!doubleQuote) {
|
|
720
|
+
read();
|
|
721
|
+
return newToken("string", buffer);
|
|
722
|
+
}
|
|
723
|
+
buffer += read();
|
|
724
|
+
return;
|
|
725
|
+
case "\n":
|
|
726
|
+
case "\r": throw invalidChar(read());
|
|
727
|
+
case "\u2028":
|
|
728
|
+
case "\u2029":
|
|
729
|
+
separatorChar(c);
|
|
730
|
+
break;
|
|
731
|
+
case void 0: throw invalidChar(read());
|
|
732
|
+
}
|
|
733
|
+
buffer += read();
|
|
734
|
+
},
|
|
735
|
+
start: function start() {
|
|
736
|
+
switch (c) {
|
|
737
|
+
case "{":
|
|
738
|
+
case "[": return newToken("punctuator", read());
|
|
739
|
+
}
|
|
740
|
+
lexState = "value";
|
|
741
|
+
},
|
|
742
|
+
beforePropertyName: function beforePropertyName() {
|
|
743
|
+
switch (c) {
|
|
744
|
+
case "$":
|
|
745
|
+
case "_":
|
|
746
|
+
buffer = read();
|
|
747
|
+
lexState = "identifierName";
|
|
748
|
+
return;
|
|
749
|
+
case "\\":
|
|
750
|
+
read();
|
|
751
|
+
lexState = "identifierNameStartEscape";
|
|
752
|
+
return;
|
|
753
|
+
case "}": return newToken("punctuator", read());
|
|
754
|
+
case "\"":
|
|
755
|
+
case "'":
|
|
756
|
+
doubleQuote = read() === "\"";
|
|
757
|
+
lexState = "string";
|
|
758
|
+
return;
|
|
759
|
+
}
|
|
760
|
+
if (util.isIdStartChar(c)) {
|
|
761
|
+
buffer += read();
|
|
762
|
+
lexState = "identifierName";
|
|
763
|
+
return;
|
|
764
|
+
}
|
|
765
|
+
throw invalidChar(read());
|
|
766
|
+
},
|
|
767
|
+
afterPropertyName: function afterPropertyName() {
|
|
768
|
+
if (c === ":") return newToken("punctuator", read());
|
|
769
|
+
throw invalidChar(read());
|
|
770
|
+
},
|
|
771
|
+
beforePropertyValue: function beforePropertyValue() {
|
|
772
|
+
lexState = "value";
|
|
773
|
+
},
|
|
774
|
+
afterPropertyValue: function afterPropertyValue() {
|
|
775
|
+
switch (c) {
|
|
776
|
+
case ",":
|
|
777
|
+
case "}": return newToken("punctuator", read());
|
|
778
|
+
}
|
|
779
|
+
throw invalidChar(read());
|
|
780
|
+
},
|
|
781
|
+
beforeArrayValue: function beforeArrayValue() {
|
|
782
|
+
if (c === "]") return newToken("punctuator", read());
|
|
783
|
+
lexState = "value";
|
|
784
|
+
},
|
|
785
|
+
afterArrayValue: function afterArrayValue() {
|
|
786
|
+
switch (c) {
|
|
787
|
+
case ",":
|
|
788
|
+
case "]": return newToken("punctuator", read());
|
|
789
|
+
}
|
|
790
|
+
throw invalidChar(read());
|
|
791
|
+
},
|
|
792
|
+
end: function end() {
|
|
793
|
+
throw invalidChar(read());
|
|
794
|
+
}
|
|
795
|
+
};
|
|
796
|
+
function newToken(type, value) {
|
|
797
|
+
return {
|
|
798
|
+
type,
|
|
799
|
+
value,
|
|
800
|
+
line,
|
|
801
|
+
column
|
|
802
|
+
};
|
|
803
|
+
}
|
|
804
|
+
function literal(s) {
|
|
805
|
+
for (var i = 0, list = s; i < list.length; i += 1) {
|
|
806
|
+
var c = list[i];
|
|
807
|
+
if (peek() !== c) throw invalidChar(read());
|
|
808
|
+
read();
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
function escape() {
|
|
812
|
+
switch (peek()) {
|
|
813
|
+
case "b":
|
|
814
|
+
read();
|
|
815
|
+
return "\b";
|
|
816
|
+
case "f":
|
|
817
|
+
read();
|
|
818
|
+
return "\f";
|
|
819
|
+
case "n":
|
|
820
|
+
read();
|
|
821
|
+
return "\n";
|
|
822
|
+
case "r":
|
|
823
|
+
read();
|
|
824
|
+
return "\r";
|
|
825
|
+
case "t":
|
|
826
|
+
read();
|
|
827
|
+
return " ";
|
|
828
|
+
case "v":
|
|
829
|
+
read();
|
|
830
|
+
return "\v";
|
|
831
|
+
case "0":
|
|
832
|
+
read();
|
|
833
|
+
if (util.isDigit(peek())) throw invalidChar(read());
|
|
834
|
+
return "\0";
|
|
835
|
+
case "x":
|
|
836
|
+
read();
|
|
837
|
+
return hexEscape();
|
|
838
|
+
case "u":
|
|
839
|
+
read();
|
|
840
|
+
return unicodeEscape();
|
|
841
|
+
case "\n":
|
|
842
|
+
case "\u2028":
|
|
843
|
+
case "\u2029":
|
|
844
|
+
read();
|
|
845
|
+
return "";
|
|
846
|
+
case "\r":
|
|
847
|
+
read();
|
|
848
|
+
if (peek() === "\n") read();
|
|
849
|
+
return "";
|
|
850
|
+
case "1":
|
|
851
|
+
case "2":
|
|
852
|
+
case "3":
|
|
853
|
+
case "4":
|
|
854
|
+
case "5":
|
|
855
|
+
case "6":
|
|
856
|
+
case "7":
|
|
857
|
+
case "8":
|
|
858
|
+
case "9": throw invalidChar(read());
|
|
859
|
+
case void 0: throw invalidChar(read());
|
|
860
|
+
}
|
|
861
|
+
return read();
|
|
862
|
+
}
|
|
863
|
+
function hexEscape() {
|
|
864
|
+
var buffer = "";
|
|
865
|
+
var c = peek();
|
|
866
|
+
if (!util.isHexDigit(c)) throw invalidChar(read());
|
|
867
|
+
buffer += read();
|
|
868
|
+
c = peek();
|
|
869
|
+
if (!util.isHexDigit(c)) throw invalidChar(read());
|
|
870
|
+
buffer += read();
|
|
871
|
+
return String.fromCodePoint(parseInt(buffer, 16));
|
|
872
|
+
}
|
|
873
|
+
function unicodeEscape() {
|
|
874
|
+
var buffer = "";
|
|
875
|
+
var count = 4;
|
|
876
|
+
while (count-- > 0) {
|
|
877
|
+
var c = peek();
|
|
878
|
+
if (!util.isHexDigit(c)) throw invalidChar(read());
|
|
879
|
+
buffer += read();
|
|
880
|
+
}
|
|
881
|
+
return String.fromCodePoint(parseInt(buffer, 16));
|
|
882
|
+
}
|
|
883
|
+
var parseStates = {
|
|
884
|
+
start: function start() {
|
|
885
|
+
if (token.type === "eof") throw invalidEOF();
|
|
886
|
+
push();
|
|
887
|
+
},
|
|
888
|
+
beforePropertyName: function beforePropertyName() {
|
|
889
|
+
switch (token.type) {
|
|
890
|
+
case "identifier":
|
|
891
|
+
case "string":
|
|
892
|
+
key = token.value;
|
|
893
|
+
parseState = "afterPropertyName";
|
|
894
|
+
return;
|
|
895
|
+
case "punctuator":
|
|
896
|
+
pop();
|
|
897
|
+
return;
|
|
898
|
+
case "eof": throw invalidEOF();
|
|
899
|
+
}
|
|
900
|
+
},
|
|
901
|
+
afterPropertyName: function afterPropertyName() {
|
|
902
|
+
if (token.type === "eof") throw invalidEOF();
|
|
903
|
+
parseState = "beforePropertyValue";
|
|
904
|
+
},
|
|
905
|
+
beforePropertyValue: function beforePropertyValue() {
|
|
906
|
+
if (token.type === "eof") throw invalidEOF();
|
|
907
|
+
push();
|
|
908
|
+
},
|
|
909
|
+
beforeArrayValue: function beforeArrayValue() {
|
|
910
|
+
if (token.type === "eof") throw invalidEOF();
|
|
911
|
+
if (token.type === "punctuator" && token.value === "]") {
|
|
912
|
+
pop();
|
|
913
|
+
return;
|
|
914
|
+
}
|
|
915
|
+
push();
|
|
916
|
+
},
|
|
917
|
+
afterPropertyValue: function afterPropertyValue() {
|
|
918
|
+
if (token.type === "eof") throw invalidEOF();
|
|
919
|
+
switch (token.value) {
|
|
920
|
+
case ",":
|
|
921
|
+
parseState = "beforePropertyName";
|
|
922
|
+
return;
|
|
923
|
+
case "}": pop();
|
|
924
|
+
}
|
|
925
|
+
},
|
|
926
|
+
afterArrayValue: function afterArrayValue() {
|
|
927
|
+
if (token.type === "eof") throw invalidEOF();
|
|
928
|
+
switch (token.value) {
|
|
929
|
+
case ",":
|
|
930
|
+
parseState = "beforeArrayValue";
|
|
931
|
+
return;
|
|
932
|
+
case "]": pop();
|
|
933
|
+
}
|
|
934
|
+
},
|
|
935
|
+
end: function end() {}
|
|
936
|
+
};
|
|
937
|
+
function push() {
|
|
938
|
+
var value;
|
|
939
|
+
switch (token.type) {
|
|
940
|
+
case "punctuator":
|
|
941
|
+
switch (token.value) {
|
|
942
|
+
case "{":
|
|
943
|
+
value = {};
|
|
944
|
+
break;
|
|
945
|
+
case "[": value = [];
|
|
946
|
+
}
|
|
947
|
+
break;
|
|
948
|
+
case "null":
|
|
949
|
+
case "boolean":
|
|
950
|
+
case "numeric":
|
|
951
|
+
case "string": value = token.value;
|
|
952
|
+
}
|
|
953
|
+
if (root === void 0) root = value;
|
|
954
|
+
else {
|
|
955
|
+
var parent = stack[stack.length - 1];
|
|
956
|
+
if (Array.isArray(parent)) parent.push(value);
|
|
957
|
+
else Object.defineProperty(parent, key, {
|
|
958
|
+
value,
|
|
959
|
+
writable: true,
|
|
960
|
+
enumerable: true,
|
|
961
|
+
configurable: true
|
|
962
|
+
});
|
|
963
|
+
}
|
|
964
|
+
if (value !== null && typeof value === "object") {
|
|
965
|
+
stack.push(value);
|
|
966
|
+
if (Array.isArray(value)) parseState = "beforeArrayValue";
|
|
967
|
+
else parseState = "beforePropertyName";
|
|
968
|
+
} else {
|
|
969
|
+
var current = stack[stack.length - 1];
|
|
970
|
+
if (current == null) parseState = "end";
|
|
971
|
+
else if (Array.isArray(current)) parseState = "afterArrayValue";
|
|
972
|
+
else parseState = "afterPropertyValue";
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
function pop() {
|
|
976
|
+
stack.pop();
|
|
977
|
+
var current = stack[stack.length - 1];
|
|
978
|
+
if (current == null) parseState = "end";
|
|
979
|
+
else if (Array.isArray(current)) parseState = "afterArrayValue";
|
|
980
|
+
else parseState = "afterPropertyValue";
|
|
981
|
+
}
|
|
982
|
+
function invalidChar(c) {
|
|
983
|
+
if (c === void 0) return syntaxError("JSON5: invalid end of input at " + line + ":" + column);
|
|
984
|
+
return syntaxError("JSON5: invalid character '" + formatChar(c) + "' at " + line + ":" + column);
|
|
985
|
+
}
|
|
986
|
+
function invalidEOF() {
|
|
987
|
+
return syntaxError("JSON5: invalid end of input at " + line + ":" + column);
|
|
988
|
+
}
|
|
989
|
+
function invalidIdentifier() {
|
|
990
|
+
column -= 5;
|
|
991
|
+
return syntaxError("JSON5: invalid identifier character at " + line + ":" + column);
|
|
992
|
+
}
|
|
993
|
+
function separatorChar(c) {
|
|
994
|
+
console.warn("JSON5: '" + formatChar(c) + "' in strings is not valid ECMAScript; consider escaping");
|
|
995
|
+
}
|
|
996
|
+
function formatChar(c) {
|
|
997
|
+
var replacements = {
|
|
998
|
+
"'": "\\'",
|
|
999
|
+
"\"": "\\\"",
|
|
1000
|
+
"\\": "\\\\",
|
|
1001
|
+
"\b": "\\b",
|
|
1002
|
+
"\f": "\\f",
|
|
1003
|
+
"\n": "\\n",
|
|
1004
|
+
"\r": "\\r",
|
|
1005
|
+
" ": "\\t",
|
|
1006
|
+
"\v": "\\v",
|
|
1007
|
+
"\0": "\\0",
|
|
1008
|
+
"\u2028": "\\u2028",
|
|
1009
|
+
"\u2029": "\\u2029"
|
|
1010
|
+
};
|
|
1011
|
+
if (replacements[c]) return replacements[c];
|
|
1012
|
+
if (c < " ") {
|
|
1013
|
+
var hexString = c.charCodeAt(0).toString(16);
|
|
1014
|
+
return "\\x" + ("00" + hexString).substring(hexString.length);
|
|
1015
|
+
}
|
|
1016
|
+
return c;
|
|
1017
|
+
}
|
|
1018
|
+
function syntaxError(message) {
|
|
1019
|
+
var err = new SyntaxError(message);
|
|
1020
|
+
err.lineNumber = line;
|
|
1021
|
+
err.columnNumber = column;
|
|
1022
|
+
return err;
|
|
1023
|
+
}
|
|
1024
|
+
return {
|
|
1025
|
+
parse,
|
|
1026
|
+
stringify: function stringify(value, replacer, space) {
|
|
1027
|
+
var stack = [];
|
|
1028
|
+
var indent = "";
|
|
1029
|
+
var propertyList;
|
|
1030
|
+
var replacerFunc;
|
|
1031
|
+
var gap = "";
|
|
1032
|
+
var quote;
|
|
1033
|
+
if (replacer != null && typeof replacer === "object" && !Array.isArray(replacer)) {
|
|
1034
|
+
space = replacer.space;
|
|
1035
|
+
quote = replacer.quote;
|
|
1036
|
+
replacer = replacer.replacer;
|
|
1037
|
+
}
|
|
1038
|
+
if (typeof replacer === "function") replacerFunc = replacer;
|
|
1039
|
+
else if (Array.isArray(replacer)) {
|
|
1040
|
+
propertyList = [];
|
|
1041
|
+
for (var i = 0, list = replacer; i < list.length; i += 1) {
|
|
1042
|
+
var v = list[i];
|
|
1043
|
+
var item = void 0;
|
|
1044
|
+
if (typeof v === "string") item = v;
|
|
1045
|
+
else if (typeof v === "number" || v instanceof String || v instanceof Number) item = String(v);
|
|
1046
|
+
if (item !== void 0 && propertyList.indexOf(item) < 0) propertyList.push(item);
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
if (space instanceof Number) space = Number(space);
|
|
1050
|
+
else if (space instanceof String) space = String(space);
|
|
1051
|
+
if (typeof space === "number") {
|
|
1052
|
+
if (space > 0) {
|
|
1053
|
+
space = Math.min(10, Math.floor(space));
|
|
1054
|
+
gap = " ".substr(0, space);
|
|
1055
|
+
}
|
|
1056
|
+
} else if (typeof space === "string") gap = space.substr(0, 10);
|
|
1057
|
+
return serializeProperty("", { "": value });
|
|
1058
|
+
function serializeProperty(key, holder) {
|
|
1059
|
+
var value = holder[key];
|
|
1060
|
+
if (value != null) {
|
|
1061
|
+
if (typeof value.toJSON5 === "function") value = value.toJSON5(key);
|
|
1062
|
+
else if (typeof value.toJSON === "function") value = value.toJSON(key);
|
|
1063
|
+
}
|
|
1064
|
+
if (replacerFunc) value = replacerFunc.call(holder, key, value);
|
|
1065
|
+
if (value instanceof Number) value = Number(value);
|
|
1066
|
+
else if (value instanceof String) value = String(value);
|
|
1067
|
+
else if (value instanceof Boolean) value = value.valueOf();
|
|
1068
|
+
switch (value) {
|
|
1069
|
+
case null: return "null";
|
|
1070
|
+
case true: return "true";
|
|
1071
|
+
case false: return "false";
|
|
1072
|
+
}
|
|
1073
|
+
if (typeof value === "string") return quoteString(value, false);
|
|
1074
|
+
if (typeof value === "number") return String(value);
|
|
1075
|
+
if (typeof value === "object") return Array.isArray(value) ? serializeArray(value) : serializeObject(value);
|
|
1076
|
+
}
|
|
1077
|
+
function quoteString(value) {
|
|
1078
|
+
var quotes = {
|
|
1079
|
+
"'": .1,
|
|
1080
|
+
"\"": .2
|
|
1081
|
+
};
|
|
1082
|
+
var replacements = {
|
|
1083
|
+
"'": "\\'",
|
|
1084
|
+
"\"": "\\\"",
|
|
1085
|
+
"\\": "\\\\",
|
|
1086
|
+
"\b": "\\b",
|
|
1087
|
+
"\f": "\\f",
|
|
1088
|
+
"\n": "\\n",
|
|
1089
|
+
"\r": "\\r",
|
|
1090
|
+
" ": "\\t",
|
|
1091
|
+
"\v": "\\v",
|
|
1092
|
+
"\0": "\\0",
|
|
1093
|
+
"\u2028": "\\u2028",
|
|
1094
|
+
"\u2029": "\\u2029"
|
|
1095
|
+
};
|
|
1096
|
+
var product = "";
|
|
1097
|
+
for (var i = 0; i < value.length; i++) {
|
|
1098
|
+
var c = value[i];
|
|
1099
|
+
switch (c) {
|
|
1100
|
+
case "'":
|
|
1101
|
+
case "\"":
|
|
1102
|
+
quotes[c]++;
|
|
1103
|
+
product += c;
|
|
1104
|
+
continue;
|
|
1105
|
+
case "\0": if (util.isDigit(value[i + 1])) {
|
|
1106
|
+
product += "\\x00";
|
|
1107
|
+
continue;
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
if (replacements[c]) {
|
|
1111
|
+
product += replacements[c];
|
|
1112
|
+
continue;
|
|
1113
|
+
}
|
|
1114
|
+
if (c < " ") {
|
|
1115
|
+
var hexString = c.charCodeAt(0).toString(16);
|
|
1116
|
+
product += "\\x" + ("00" + hexString).substring(hexString.length);
|
|
1117
|
+
continue;
|
|
1118
|
+
}
|
|
1119
|
+
product += c;
|
|
1120
|
+
}
|
|
1121
|
+
var quoteChar = quote || Object.keys(quotes).reduce(function(a, b) {
|
|
1122
|
+
return quotes[a] < quotes[b] ? a : b;
|
|
1123
|
+
});
|
|
1124
|
+
product = product.replace(new RegExp(quoteChar, "g"), replacements[quoteChar]);
|
|
1125
|
+
return quoteChar + product + quoteChar;
|
|
1126
|
+
}
|
|
1127
|
+
function serializeObject(value) {
|
|
1128
|
+
if (stack.indexOf(value) >= 0) throw TypeError("Converting circular structure to JSON5");
|
|
1129
|
+
stack.push(value);
|
|
1130
|
+
var stepback = indent;
|
|
1131
|
+
indent = indent + gap;
|
|
1132
|
+
var keys = propertyList || Object.keys(value);
|
|
1133
|
+
var partial = [];
|
|
1134
|
+
for (var i = 0, list = keys; i < list.length; i += 1) {
|
|
1135
|
+
var key = list[i];
|
|
1136
|
+
var propertyString = serializeProperty(key, value);
|
|
1137
|
+
if (propertyString !== void 0) {
|
|
1138
|
+
var member = serializeKey(key) + ":";
|
|
1139
|
+
if (gap !== "") member += " ";
|
|
1140
|
+
member += propertyString;
|
|
1141
|
+
partial.push(member);
|
|
1142
|
+
}
|
|
1143
|
+
}
|
|
1144
|
+
var final;
|
|
1145
|
+
if (partial.length === 0) final = "{}";
|
|
1146
|
+
else {
|
|
1147
|
+
var properties;
|
|
1148
|
+
if (gap === "") {
|
|
1149
|
+
properties = partial.join(",");
|
|
1150
|
+
final = "{" + properties + "}";
|
|
1151
|
+
} else {
|
|
1152
|
+
var separator = ",\n" + indent;
|
|
1153
|
+
properties = partial.join(separator);
|
|
1154
|
+
final = "{\n" + indent + properties + ",\n" + stepback + "}";
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1157
|
+
stack.pop();
|
|
1158
|
+
indent = stepback;
|
|
1159
|
+
return final;
|
|
1160
|
+
}
|
|
1161
|
+
function serializeKey(key) {
|
|
1162
|
+
if (key.length === 0) return quoteString(key, true);
|
|
1163
|
+
var firstChar = String.fromCodePoint(key.codePointAt(0));
|
|
1164
|
+
if (!util.isIdStartChar(firstChar)) return quoteString(key, true);
|
|
1165
|
+
for (var i = firstChar.length; i < key.length; i++) if (!util.isIdContinueChar(String.fromCodePoint(key.codePointAt(i)))) return quoteString(key, true);
|
|
1166
|
+
return key;
|
|
1167
|
+
}
|
|
1168
|
+
function serializeArray(value) {
|
|
1169
|
+
if (stack.indexOf(value) >= 0) throw TypeError("Converting circular structure to JSON5");
|
|
1170
|
+
stack.push(value);
|
|
1171
|
+
var stepback = indent;
|
|
1172
|
+
indent = indent + gap;
|
|
1173
|
+
var partial = [];
|
|
1174
|
+
for (var i = 0; i < value.length; i++) {
|
|
1175
|
+
var propertyString = serializeProperty(String(i), value);
|
|
1176
|
+
partial.push(propertyString !== void 0 ? propertyString : "null");
|
|
1177
|
+
}
|
|
1178
|
+
var final;
|
|
1179
|
+
if (partial.length === 0) final = "[]";
|
|
1180
|
+
else if (gap === "") final = "[" + partial.join(",") + "]";
|
|
1181
|
+
else {
|
|
1182
|
+
var separator = ",\n" + indent;
|
|
1183
|
+
var properties$1 = partial.join(separator);
|
|
1184
|
+
final = "[\n" + indent + properties$1 + ",\n" + stepback + "]";
|
|
1185
|
+
}
|
|
1186
|
+
stack.pop();
|
|
1187
|
+
indent = stepback;
|
|
1188
|
+
return final;
|
|
1189
|
+
}
|
|
1190
|
+
}
|
|
1191
|
+
};
|
|
1192
|
+
}));
|
|
1193
|
+
})))(), 1);
|
|
109
1194
|
var ComponentRegistry = class {
|
|
110
1195
|
schemas = /* @__PURE__ */ new Map();
|
|
1196
|
+
listeners = /* @__PURE__ */ new Set();
|
|
1197
|
+
version = 0;
|
|
111
1198
|
/**
|
|
112
1199
|
* 注册组件 schema
|
|
113
1200
|
*/
|
|
114
1201
|
register(name, schema) {
|
|
115
1202
|
this.schemas.set(name, schema);
|
|
1203
|
+
this.emit();
|
|
1204
|
+
}
|
|
1205
|
+
/**
|
|
1206
|
+
* 移除组件注册
|
|
1207
|
+
*/
|
|
1208
|
+
unregister(name) {
|
|
1209
|
+
if (this.schemas.delete(name)) this.emit();
|
|
1210
|
+
}
|
|
1211
|
+
/**
|
|
1212
|
+
* 当前版本号,任意注册变更都会自增
|
|
1213
|
+
*/
|
|
1214
|
+
getVersion() {
|
|
1215
|
+
return this.version;
|
|
1216
|
+
}
|
|
1217
|
+
/**
|
|
1218
|
+
* 订阅注册变更,返回退订函数
|
|
1219
|
+
*/
|
|
1220
|
+
subscribe(listener) {
|
|
1221
|
+
this.listeners.add(listener);
|
|
1222
|
+
return () => {
|
|
1223
|
+
this.listeners.delete(listener);
|
|
1224
|
+
};
|
|
1225
|
+
}
|
|
1226
|
+
emit() {
|
|
1227
|
+
this.version += 1;
|
|
1228
|
+
this.listeners.forEach((listener) => listener(this.version));
|
|
116
1229
|
}
|
|
117
1230
|
/**
|
|
118
1231
|
* 根据组件名获取已注册的 schema
|
|
@@ -138,47 +1251,164 @@ var ComponentRegistry = class {
|
|
|
138
1251
|
getAll() {
|
|
139
1252
|
return Array.from(this.schemas.values());
|
|
140
1253
|
}
|
|
141
|
-
/**
|
|
142
|
-
* 移除组件注册
|
|
143
|
-
*/
|
|
144
|
-
unregister(name) {
|
|
145
|
-
this.schemas.delete(name);
|
|
146
|
-
}
|
|
147
1254
|
};
|
|
148
1255
|
var componentRegistry = new ComponentRegistry();
|
|
149
1256
|
//#endregion
|
|
1257
|
+
//#region src/utils/parseContainer.ts
|
|
1258
|
+
/**
|
|
1259
|
+
* 解析容器属性行。
|
|
1260
|
+
* 优先按 JSON5 解析(兼容标准 JSON 与 { key: 'value' } 宽松写法),
|
|
1261
|
+
* 失败时返回空对象,保证往返编辑不丢数据。
|
|
1262
|
+
*/
|
|
1263
|
+
function parseContainerProps(line) {
|
|
1264
|
+
const trimmed = line.trim();
|
|
1265
|
+
if (!trimmed.startsWith("{") || !trimmed.endsWith("}")) return {};
|
|
1266
|
+
try {
|
|
1267
|
+
const parsed = import_dist.default.parse(trimmed);
|
|
1268
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) return {};
|
|
1269
|
+
const props = {};
|
|
1270
|
+
for (const [key, value] of Object.entries(parsed)) {
|
|
1271
|
+
if (value === null || value === void 0) continue;
|
|
1272
|
+
if (typeof value === "object") continue;
|
|
1273
|
+
props[key] = value;
|
|
1274
|
+
}
|
|
1275
|
+
return props;
|
|
1276
|
+
} catch {
|
|
1277
|
+
return {};
|
|
1278
|
+
}
|
|
1279
|
+
}
|
|
1280
|
+
/**
|
|
1281
|
+
* 解析行首的引用(blockquote)嵌套前缀。
|
|
1282
|
+
* markdown-it 解析引用内部内容时会剥掉一层 "> ",因此 "> :::badge" 在渲染侧
|
|
1283
|
+
* 等同于 ":::badge";编辑器侧需同样识别,否则嵌套引用的容器匹配不到标签。
|
|
1284
|
+
* 返回 [前缀文本(含 "> " 及尾随空格), 去掉前缀后的内容],无前缀时返回 ['', 原文本]。
|
|
1285
|
+
*/
|
|
1286
|
+
function splitQuotePrefix(line) {
|
|
1287
|
+
const m = line.match(/^((?:>\s*)+)(\S.*)$/);
|
|
1288
|
+
if (!m) return ["", line];
|
|
1289
|
+
return [m[1], m[2]];
|
|
1290
|
+
}
|
|
1291
|
+
/** 引用嵌套深度("> > x" 为 2,无前缀为 0) */
|
|
1292
|
+
function quoteDepth(prefix) {
|
|
1293
|
+
return (prefix.match(/>/g) ?? []).length;
|
|
1294
|
+
}
|
|
1295
|
+
/**
|
|
1296
|
+
* 在编辑器文档中查找容器块。
|
|
1297
|
+
* 单次遍历 + 预累计行偏移,复杂度 O(行数)。
|
|
1298
|
+
* 支持整体嵌套在引用中的容器:头行、属性行、闭合行需具有相同的 "> " 前缀深度,
|
|
1299
|
+
* 避免跨引用层级错误配对。闭合 ::: 改为按栈配对,嵌套容器不会被内层闭合误截断。
|
|
1300
|
+
*/
|
|
1301
|
+
function findContainers(docText) {
|
|
1302
|
+
const containers = [];
|
|
1303
|
+
const lines = docText.split("\n");
|
|
1304
|
+
const offsets = new Array(lines.length);
|
|
1305
|
+
let pos = 0;
|
|
1306
|
+
for (let i = 0; i < lines.length; i++) {
|
|
1307
|
+
offsets[i] = pos;
|
|
1308
|
+
pos += lines[i].length + 1;
|
|
1309
|
+
}
|
|
1310
|
+
const stack = [];
|
|
1311
|
+
for (let i = 0; i < lines.length; i++) {
|
|
1312
|
+
const [prefix, body] = splitQuotePrefix(lines[i]);
|
|
1313
|
+
const depth = quoteDepth(prefix);
|
|
1314
|
+
if (/^:::$/.test(body)) {
|
|
1315
|
+
let top = stack.length - 1;
|
|
1316
|
+
while (top >= 0 && stack[top].depth !== depth) top--;
|
|
1317
|
+
if (top >= 0) {
|
|
1318
|
+
stack[top].block.endPos = offsets[i];
|
|
1319
|
+
stack.length = top;
|
|
1320
|
+
}
|
|
1321
|
+
continue;
|
|
1322
|
+
}
|
|
1323
|
+
const match = body.match(/^:::(\w+)$/);
|
|
1324
|
+
if (!match) continue;
|
|
1325
|
+
const typeName = match[1];
|
|
1326
|
+
const headerPos = offsets[i];
|
|
1327
|
+
let props = {};
|
|
1328
|
+
let propsLineFrom = 0;
|
|
1329
|
+
let propsLineTo = 0;
|
|
1330
|
+
let propsQuotePrefix = "";
|
|
1331
|
+
const nextLine = lines[i + 1];
|
|
1332
|
+
if (nextLine) {
|
|
1333
|
+
const [nextPrefix, nextBody] = splitQuotePrefix(nextLine);
|
|
1334
|
+
if ((quoteDepth(nextPrefix) === depth || nextPrefix === "") && nextBody.trimStart().startsWith("{") && nextBody.trimEnd().endsWith("}")) {
|
|
1335
|
+
props = parseContainerProps(nextBody);
|
|
1336
|
+
propsLineFrom = offsets[i + 1];
|
|
1337
|
+
propsLineTo = propsLineFrom + nextLine.length;
|
|
1338
|
+
propsQuotePrefix = nextPrefix;
|
|
1339
|
+
i += 1;
|
|
1340
|
+
}
|
|
1341
|
+
}
|
|
1342
|
+
const block = {
|
|
1343
|
+
startPos: headerPos,
|
|
1344
|
+
typeName,
|
|
1345
|
+
propsLineFrom,
|
|
1346
|
+
propsLineTo,
|
|
1347
|
+
props,
|
|
1348
|
+
endPos: 0,
|
|
1349
|
+
registered: componentRegistry.has(typeName),
|
|
1350
|
+
quotePrefix: prefix,
|
|
1351
|
+
propsQuotePrefix
|
|
1352
|
+
};
|
|
1353
|
+
containers.push(block);
|
|
1354
|
+
stack.push({
|
|
1355
|
+
block,
|
|
1356
|
+
depth
|
|
1357
|
+
});
|
|
1358
|
+
}
|
|
1359
|
+
return containers;
|
|
1360
|
+
}
|
|
1361
|
+
//#endregion
|
|
150
1362
|
//#region src/components/Editor/containerWidget.ts
|
|
151
1363
|
/**
|
|
1364
|
+
* 唤醒容器装饰重建的状态 effect(不改变文档)。
|
|
1365
|
+
* 编辑按钮是否展示取决于容器类型是否已注册,而宿主常在编辑器挂载之后才
|
|
1366
|
+
* 通过 useRegisterToolbar 异步注册 schema;注册不是 CodeMirror 事务,默认不会触发
|
|
1367
|
+
* ViewPlugin.update,导致初始化时烘焙的 registered=false 无法刷新(需手动改一个字才出现)。
|
|
1368
|
+
* 宿主在注册中心版本变化时 dispatch 本 effect,驱动插件重新求值 registered。
|
|
1369
|
+
*/
|
|
1370
|
+
var refreshContainers = _codemirror_state.StateEffect.define();
|
|
1371
|
+
/**
|
|
152
1372
|
* 自定义 facet 用于传递编辑回调
|
|
153
1373
|
*/
|
|
154
|
-
var containerEditCallback = _codemirror_state.Facet.define({ combine: (values) => values[
|
|
1374
|
+
var containerEditCallback = _codemirror_state.Facet.define({ combine: (values) => values.length ? values[values.length - 1] : null });
|
|
155
1375
|
/**
|
|
156
1376
|
* 只读的容器头行 Widget(显示 :::typeName + 编辑按钮)
|
|
157
|
-
* 使用 Decoration.replace
|
|
1377
|
+
* 使用 Decoration.replace 替换原始文本,使其不可直接编辑。
|
|
1378
|
+
* widget 直接携带所属容器索引与类型,点击时无需再做位置猜测。
|
|
158
1379
|
*/
|
|
159
1380
|
var ContainerHeaderWidget = class extends _codemirror_view.WidgetType {
|
|
160
1381
|
typeName;
|
|
161
|
-
|
|
1382
|
+
containerIndex;
|
|
1383
|
+
registered;
|
|
1384
|
+
quotePrefix;
|
|
1385
|
+
constructor(typeName, containerIndex, registered, quotePrefix) {
|
|
162
1386
|
super();
|
|
163
1387
|
this.typeName = typeName;
|
|
1388
|
+
this.containerIndex = containerIndex;
|
|
1389
|
+
this.registered = registered;
|
|
1390
|
+
this.quotePrefix = quotePrefix;
|
|
164
1391
|
}
|
|
165
1392
|
toDOM() {
|
|
166
1393
|
const container = document.createElement("span");
|
|
167
1394
|
container.className = "container-widget-header";
|
|
168
1395
|
const text = document.createElement("span");
|
|
169
1396
|
text.className = "container-widget-text";
|
|
170
|
-
text.textContent =
|
|
171
|
-
const button = document.createElement("button");
|
|
172
|
-
button.className = "container-edit-btn";
|
|
173
|
-
button.title = `编辑 ${componentRegistry.get(this.typeName)?.label ?? this.typeName}`;
|
|
174
|
-
button.textContent = "✎";
|
|
175
|
-
button.__typeName = this.typeName;
|
|
1397
|
+
text.textContent = `${this.quotePrefix}:::${this.typeName}`;
|
|
176
1398
|
container.appendChild(text);
|
|
177
|
-
|
|
1399
|
+
if (this.registered) {
|
|
1400
|
+
const button = document.createElement("button");
|
|
1401
|
+
button.className = "container-edit-btn";
|
|
1402
|
+
button.title = `编辑 ${this.typeName}`;
|
|
1403
|
+
button.textContent = "✎";
|
|
1404
|
+
button.dataset.containerIndex = String(this.containerIndex);
|
|
1405
|
+
button.dataset.typeName = this.typeName;
|
|
1406
|
+
container.appendChild(button);
|
|
1407
|
+
}
|
|
178
1408
|
return container;
|
|
179
1409
|
}
|
|
180
1410
|
eq(other) {
|
|
181
|
-
return this.typeName === other.typeName;
|
|
1411
|
+
return this.typeName === other.typeName && this.containerIndex === other.containerIndex && this.registered === other.registered && this.quotePrefix === other.quotePrefix;
|
|
182
1412
|
}
|
|
183
1413
|
ignoreEvent() {
|
|
184
1414
|
return false;
|
|
@@ -186,40 +1416,46 @@ var ContainerHeaderWidget = class extends _codemirror_view.WidgetType {
|
|
|
186
1416
|
};
|
|
187
1417
|
/**
|
|
188
1418
|
* 只读的容器属性行 Widget(显示 { key: value, ... })
|
|
189
|
-
*
|
|
1419
|
+
* 嵌套在引用中时原始行带 "> " 前缀,展示时剔除,与头行 widget 风格一致
|
|
190
1420
|
*/
|
|
191
1421
|
var ContainerPropsWidget = class extends _codemirror_view.WidgetType {
|
|
192
1422
|
propsText;
|
|
193
|
-
|
|
1423
|
+
quotePrefix;
|
|
1424
|
+
constructor(propsText, quotePrefix) {
|
|
194
1425
|
super();
|
|
195
1426
|
this.propsText = propsText;
|
|
1427
|
+
this.quotePrefix = quotePrefix;
|
|
196
1428
|
}
|
|
197
1429
|
toDOM() {
|
|
198
1430
|
const span = document.createElement("span");
|
|
199
1431
|
span.className = "container-widget-props";
|
|
200
|
-
span.textContent = this.propsText;
|
|
1432
|
+
span.textContent = this.propsText.startsWith(this.quotePrefix) ? this.propsText.slice(this.quotePrefix.length) : this.propsText;
|
|
201
1433
|
return span;
|
|
202
1434
|
}
|
|
203
1435
|
eq(other) {
|
|
204
|
-
return this.propsText === other.propsText;
|
|
1436
|
+
return this.propsText === other.propsText && this.quotePrefix === other.quotePrefix;
|
|
205
1437
|
}
|
|
206
1438
|
ignoreEvent() {
|
|
207
1439
|
return false;
|
|
208
1440
|
}
|
|
209
1441
|
};
|
|
210
1442
|
/**
|
|
211
|
-
* 只读的容器结束行 Widget(显示
|
|
212
|
-
* 使用 Decoration.replace 替换原始文本,使其不可直接编辑
|
|
1443
|
+
* 只读的容器结束行 Widget(显示 :::,嵌套引用时保留 "> " 前缀)
|
|
213
1444
|
*/
|
|
214
1445
|
var ContainerCloseWidget = class extends _codemirror_view.WidgetType {
|
|
1446
|
+
text;
|
|
1447
|
+
constructor(text) {
|
|
1448
|
+
super();
|
|
1449
|
+
this.text = text;
|
|
1450
|
+
}
|
|
215
1451
|
toDOM() {
|
|
216
1452
|
const span = document.createElement("span");
|
|
217
1453
|
span.className = "container-widget-text";
|
|
218
|
-
span.textContent =
|
|
1454
|
+
span.textContent = this.text;
|
|
219
1455
|
return span;
|
|
220
1456
|
}
|
|
221
|
-
eq() {
|
|
222
|
-
return
|
|
1457
|
+
eq(other) {
|
|
1458
|
+
return this.text === other.text;
|
|
223
1459
|
}
|
|
224
1460
|
ignoreEvent() {
|
|
225
1461
|
return false;
|
|
@@ -232,20 +1468,19 @@ var ContainerCloseWidget = class extends _codemirror_view.WidgetType {
|
|
|
232
1468
|
function findContainerDecorations(state) {
|
|
233
1469
|
const containers = findContainers(state.doc.toString());
|
|
234
1470
|
const decorations = [];
|
|
235
|
-
|
|
1471
|
+
containers.forEach((container, index) => {
|
|
236
1472
|
const headerLine = state.doc.lineAt(container.startPos);
|
|
237
1473
|
decorations.push({
|
|
238
1474
|
from: headerLine.from,
|
|
239
1475
|
to: headerLine.to,
|
|
240
|
-
value: _codemirror_view.Decoration.replace({ widget: new ContainerHeaderWidget(container.typeName) })
|
|
1476
|
+
value: _codemirror_view.Decoration.replace({ widget: new ContainerHeaderWidget(container.typeName, index, container.registered, container.quotePrefix ?? "") })
|
|
241
1477
|
});
|
|
242
1478
|
if (container.propsLineFrom > 0 && container.propsLineTo > 0) {
|
|
243
1479
|
const propsLine = state.doc.lineAt(container.propsLineFrom);
|
|
244
|
-
const propsText = propsLine.text;
|
|
245
1480
|
decorations.push({
|
|
246
1481
|
from: propsLine.from,
|
|
247
1482
|
to: propsLine.to,
|
|
248
|
-
value: _codemirror_view.Decoration.replace({ widget: new ContainerPropsWidget(
|
|
1483
|
+
value: _codemirror_view.Decoration.replace({ widget: new ContainerPropsWidget(propsLine.text, container.quotePrefix ?? "") })
|
|
249
1484
|
});
|
|
250
1485
|
}
|
|
251
1486
|
if (container.endPos > 0) {
|
|
@@ -253,55 +1488,64 @@ function findContainerDecorations(state) {
|
|
|
253
1488
|
decorations.push({
|
|
254
1489
|
from: endLine.from,
|
|
255
1490
|
to: endLine.to,
|
|
256
|
-
value: _codemirror_view.Decoration.replace({ widget: new ContainerCloseWidget() })
|
|
1491
|
+
value: _codemirror_view.Decoration.replace({ widget: new ContainerCloseWidget(endLine.text) })
|
|
257
1492
|
});
|
|
258
1493
|
}
|
|
259
|
-
}
|
|
1494
|
+
});
|
|
1495
|
+
decorations.sort((a, b) => a.from - b.from || b.to - a.to);
|
|
260
1496
|
return decorations;
|
|
261
1497
|
}
|
|
262
1498
|
/**
|
|
1499
|
+
* 点击编辑按钮时,依据按钮携带的容器索引回查最新属性并触发回调
|
|
1500
|
+
*/
|
|
1501
|
+
function handleEditButtonClick(event, view) {
|
|
1502
|
+
const target = event.target;
|
|
1503
|
+
if (!target.classList.contains("container-edit-btn")) return false;
|
|
1504
|
+
event.preventDefault();
|
|
1505
|
+
event.stopPropagation();
|
|
1506
|
+
const indexAttr = target.dataset.containerIndex;
|
|
1507
|
+
if (indexAttr === void 0) return false;
|
|
1508
|
+
const container = findContainers(view.state.doc.toString())[Number(indexAttr)];
|
|
1509
|
+
if (!container || !container.registered) return false;
|
|
1510
|
+
const callback = view.state.facet(containerEditCallback);
|
|
1511
|
+
if (callback) callback(view, {
|
|
1512
|
+
...container,
|
|
1513
|
+
props: { ...container.props }
|
|
1514
|
+
});
|
|
1515
|
+
return true;
|
|
1516
|
+
}
|
|
1517
|
+
/**
|
|
263
1518
|
* 容器编辑 ViewPlugin
|
|
264
|
-
* 将容器的 ::: 头行和 {} 属性行替换为只读 widget
|
|
1519
|
+
* 将容器的 ::: 头行和 {} 属性行替换为只读 widget,使其无法在编辑器中直接编辑。
|
|
1520
|
+
* 仅在文档内容变化时重建装饰,光标移动不触发全文扫描。
|
|
265
1521
|
*/
|
|
266
1522
|
var containerWidgetPlugin = _codemirror_view.ViewPlugin.fromClass(class {
|
|
267
1523
|
decorations;
|
|
1524
|
+
/** 上次构建装饰时的注册中心版本,用于感知异步注册(不能标 private,否则导出匿名类的 dts 报 TS4094) */
|
|
1525
|
+
registryVersion;
|
|
268
1526
|
constructor(view) {
|
|
1527
|
+
this.registryVersion = componentRegistry.getVersion();
|
|
269
1528
|
this.decorations = _codemirror_view.Decoration.set(findContainerDecorations(view.state), true);
|
|
270
1529
|
}
|
|
271
1530
|
update(update) {
|
|
272
|
-
|
|
1531
|
+
const registryChanged = componentRegistry.getVersion() !== this.registryVersion;
|
|
1532
|
+
const woken = update.transactions.some((tr) => tr.effects.some((e) => e.is(refreshContainers)));
|
|
1533
|
+
if (update.docChanged || registryChanged || woken) {
|
|
1534
|
+
this.registryVersion = componentRegistry.getVersion();
|
|
1535
|
+
this.decorations = _codemirror_view.Decoration.set(findContainerDecorations(update.state), true);
|
|
1536
|
+
}
|
|
273
1537
|
}
|
|
274
1538
|
}, {
|
|
275
1539
|
decorations: (value) => value.decorations,
|
|
276
1540
|
eventHandlers: {
|
|
277
|
-
mousedown: (event,
|
|
1541
|
+
mousedown: (event, _view) => {
|
|
278
1542
|
if (event.target.classList.contains("container-edit-btn")) {
|
|
279
1543
|
event.preventDefault();
|
|
280
1544
|
return true;
|
|
281
1545
|
}
|
|
282
1546
|
return false;
|
|
283
1547
|
},
|
|
284
|
-
click:
|
|
285
|
-
const target = event.target;
|
|
286
|
-
if (target.classList.contains("container-edit-btn")) {
|
|
287
|
-
event.preventDefault();
|
|
288
|
-
event.stopPropagation();
|
|
289
|
-
if (target.__typeName) {
|
|
290
|
-
const containers = findContainers(view.state.doc.toString());
|
|
291
|
-
const buttonPos = view.posAtDOM(target);
|
|
292
|
-
for (const container of containers) {
|
|
293
|
-
const headerLine = view.state.doc.lineAt(container.startPos);
|
|
294
|
-
if (buttonPos >= headerLine.from - 5 && buttonPos <= headerLine.to + 5) {
|
|
295
|
-
const callback = view.state.facet(containerEditCallback);
|
|
296
|
-
if (callback) callback(view, container.typeName, container.propsLineFrom, container.propsLineTo, { ...container.props });
|
|
297
|
-
return true;
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
return false;
|
|
302
|
-
}
|
|
303
|
-
return false;
|
|
304
|
-
}
|
|
1548
|
+
click: handleEditButtonClick
|
|
305
1549
|
}
|
|
306
1550
|
});
|
|
307
1551
|
//#endregion
|
|
@@ -399,7 +1643,11 @@ function toggleTaskList(view) {
|
|
|
399
1643
|
});
|
|
400
1644
|
}
|
|
401
1645
|
}
|
|
402
|
-
view.
|
|
1646
|
+
const anchor = view.state.changes(changes).mapPos(from, 1);
|
|
1647
|
+
view.dispatch({
|
|
1648
|
+
changes,
|
|
1649
|
+
selection: { anchor }
|
|
1650
|
+
});
|
|
403
1651
|
}
|
|
404
1652
|
/**
|
|
405
1653
|
* 切换行首前缀(支持多行选区)
|
|
@@ -429,7 +1677,11 @@ function toggleLinePrefix(view, pattern, insertText) {
|
|
|
429
1677
|
insert: insertText
|
|
430
1678
|
});
|
|
431
1679
|
}
|
|
432
|
-
view.
|
|
1680
|
+
const anchor = view.state.changes(changes).mapPos(from, 1);
|
|
1681
|
+
view.dispatch({
|
|
1682
|
+
changes,
|
|
1683
|
+
selection: { anchor }
|
|
1684
|
+
});
|
|
433
1685
|
}
|
|
434
1686
|
/** Markdown 列表行:缩进 + 列表标记(无序/有序)+ 空白 */
|
|
435
1687
|
var LIST_LINE_RE = /^(\s*)([-*+]|\d+\.)([ \t]+)/;
|
|
@@ -542,28 +1794,32 @@ function dedentMarkdownList(view) {
|
|
|
542
1794
|
return true;
|
|
543
1795
|
}
|
|
544
1796
|
/**
|
|
545
|
-
*
|
|
1797
|
+
* 上传图片:失败(含网络异常)统一返回 null,不抛错
|
|
546
1798
|
* @param file - 要上传的文件
|
|
547
1799
|
* @param uploadConfig - 上传配置
|
|
548
1800
|
*/
|
|
549
1801
|
async function uploadFileToServer(file, uploadConfig) {
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
1802
|
+
try {
|
|
1803
|
+
if (uploadConfig.onUploadImage) return await uploadConfig.onUploadImage(file);
|
|
1804
|
+
if (uploadConfig.uploadUrl) {
|
|
1805
|
+
const formData = new FormData();
|
|
1806
|
+
formData.append("file", file);
|
|
1807
|
+
const response = await fetch(uploadConfig.uploadUrl, {
|
|
1808
|
+
method: "POST",
|
|
1809
|
+
body: formData
|
|
1810
|
+
});
|
|
1811
|
+
if (!response.ok) return null;
|
|
1812
|
+
const result = await response.json();
|
|
1813
|
+
if (uploadConfig.onGetUploadUrl) return uploadConfig.onGetUploadUrl(result);
|
|
1814
|
+
return result?.data?.path ?? null;
|
|
1815
|
+
}
|
|
1816
|
+
return null;
|
|
1817
|
+
} catch {
|
|
1818
|
+
return null;
|
|
562
1819
|
}
|
|
563
|
-
return null;
|
|
564
1820
|
}
|
|
565
1821
|
/**
|
|
566
|
-
*
|
|
1822
|
+
* 判断是否配置了图片上传(类型谓词,守卫后可安全访问配置)
|
|
567
1823
|
*/
|
|
568
1824
|
function isUploadConfigured(uploadConfig) {
|
|
569
1825
|
return !!(uploadConfig?.uploadUrl || uploadConfig?.onUploadImage);
|
|
@@ -577,7 +1833,6 @@ function uploadImage(view, uploadConfig) {
|
|
|
577
1833
|
const input = document.createElement("input");
|
|
578
1834
|
input.type = "file";
|
|
579
1835
|
input.accept = "image/*";
|
|
580
|
-
input.style.display = "none";
|
|
581
1836
|
input.addEventListener("change", async () => {
|
|
582
1837
|
if (!input.files || input.files.length === 0) return;
|
|
583
1838
|
const file = input.files[0];
|
|
@@ -594,7 +1849,6 @@ function uploadImage(view, uploadConfig) {
|
|
|
594
1849
|
}
|
|
595
1850
|
input.remove();
|
|
596
1851
|
});
|
|
597
|
-
document.body.appendChild(input);
|
|
598
1852
|
input.click();
|
|
599
1853
|
}
|
|
600
1854
|
/**
|
|
@@ -652,10 +1906,14 @@ function toggleWrap(view, openTag, closeTag) {
|
|
|
652
1906
|
}
|
|
653
1907
|
//#endregion
|
|
654
1908
|
//#region src/components/Editor/codemirrorExtensions.ts
|
|
655
|
-
/**
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
1909
|
+
/**
|
|
1910
|
+
* 图片上传配置 facet。
|
|
1911
|
+
* 传入 getter 而非配置本身:扩展只在 mount 时创建一次,
|
|
1912
|
+
* 运行期通过 getter 读取最新配置,避免闭包过期。
|
|
1913
|
+
*/
|
|
1914
|
+
var uploadConfigFacet = _codemirror_state.Facet.define({ combine: (values) => values.length ? values[values.length - 1] : null });
|
|
1915
|
+
/** 未配置上传时的提示回调 facet(同为 getter 形式) */
|
|
1916
|
+
var messageFacet = _codemirror_state.Facet.define({ combine: (values) => values.length ? values[values.length - 1] : null });
|
|
659
1917
|
/** 粘贴事件处理:拦截图片并上传 */
|
|
660
1918
|
var pasteHandler = _codemirror_view.EditorView.domEventHandlers({ paste: (event, view) => {
|
|
661
1919
|
const files = event.clipboardData?.files;
|
|
@@ -663,23 +1921,38 @@ var pasteHandler = _codemirror_view.EditorView.domEventHandlers({ paste: (event,
|
|
|
663
1921
|
const imageFiles = Array.from(files).filter((f) => f.type.startsWith("image/"));
|
|
664
1922
|
if (imageFiles.length === 0) return false;
|
|
665
1923
|
event.preventDefault();
|
|
666
|
-
const uploadConfig = view.state.facet(uploadConfigFacet);
|
|
667
|
-
const showMessage = view.state.facet(messageFacet);
|
|
1924
|
+
const uploadConfig = view.state.facet(uploadConfigFacet)?.();
|
|
1925
|
+
const showMessage = view.state.facet(messageFacet)?.();
|
|
668
1926
|
if (!isUploadConfigured(uploadConfig)) {
|
|
669
1927
|
showMessage?.();
|
|
670
1928
|
return true;
|
|
671
1929
|
}
|
|
672
|
-
const
|
|
673
|
-
let
|
|
674
|
-
for (const file of imageFiles) uploadFileToServer(file,
|
|
675
|
-
if (url)
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
1930
|
+
const config = uploadConfig;
|
|
1931
|
+
let isFirst = true;
|
|
1932
|
+
for (const file of imageFiles) uploadFileToServer(file, config).then((url) => {
|
|
1933
|
+
if (!url) return;
|
|
1934
|
+
const insert = `![${file.name.replace(/\.[^.]+$/, "")}](${url})`;
|
|
1935
|
+
const { state } = view;
|
|
1936
|
+
if (isFirst) {
|
|
1937
|
+
isFirst = false;
|
|
1938
|
+
const { from, to } = state.selection.main;
|
|
1939
|
+
view.dispatch({
|
|
1940
|
+
changes: {
|
|
1941
|
+
from,
|
|
1942
|
+
to,
|
|
1943
|
+
insert
|
|
1944
|
+
},
|
|
1945
|
+
selection: { anchor: from + insert.length }
|
|
1946
|
+
});
|
|
1947
|
+
} else {
|
|
1948
|
+
const end = state.doc.length;
|
|
1949
|
+
view.dispatch({
|
|
1950
|
+
changes: {
|
|
1951
|
+
from: end,
|
|
1952
|
+
insert: `\n${insert}`
|
|
1953
|
+
},
|
|
1954
|
+
selection: { anchor: end + insert.length + 1 }
|
|
1955
|
+
});
|
|
683
1956
|
}
|
|
684
1957
|
});
|
|
685
1958
|
return true;
|
|
@@ -739,8 +2012,8 @@ var getCodeMirrorExtensions = (opts) => {
|
|
|
739
2012
|
];
|
|
740
2013
|
extensions.push(containerWidgetPlugin);
|
|
741
2014
|
if (opts?.onEditContainer) extensions.push(containerEditCallback.of(opts.onEditContainer));
|
|
742
|
-
if (opts?.
|
|
743
|
-
if (opts?.
|
|
2015
|
+
if (opts?.getUploadConfig) extensions.push(uploadConfigFacet.of(opts.getUploadConfig));
|
|
2016
|
+
if (opts?.getOnMessageNoUploadConfig) extensions.push(messageFacet.of(opts.getOnMessageNoUploadConfig));
|
|
744
2017
|
return extensions;
|
|
745
2018
|
};
|
|
746
2019
|
//#endregion
|
|
@@ -748,17 +2021,29 @@ var getCodeMirrorExtensions = (opts) => {
|
|
|
748
2021
|
function Editor({ value, onChange, onScrollReady, onViewReady, onEditContainer, uploadConfig, onMessageNoUploadConfig }) {
|
|
749
2022
|
const editorRef = (0, react.useRef)(null);
|
|
750
2023
|
const viewRef = (0, react.useRef)(null);
|
|
2024
|
+
const latestRef = (0, react.useRef)({
|
|
2025
|
+
onChange,
|
|
2026
|
+
onEditContainer,
|
|
2027
|
+
uploadConfig,
|
|
2028
|
+
onMessageNoUploadConfig
|
|
2029
|
+
});
|
|
2030
|
+
latestRef.current = {
|
|
2031
|
+
onChange,
|
|
2032
|
+
onEditContainer,
|
|
2033
|
+
uploadConfig,
|
|
2034
|
+
onMessageNoUploadConfig
|
|
2035
|
+
};
|
|
751
2036
|
(0, react.useEffect)(() => {
|
|
752
2037
|
if (!editorRef.current) return;
|
|
753
2038
|
const extensions = [
|
|
754
2039
|
codemirror.basicSetup,
|
|
755
2040
|
...getCodeMirrorExtensions({
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
2041
|
+
getUploadConfig: () => latestRef.current.uploadConfig,
|
|
2042
|
+
getOnMessageNoUploadConfig: () => latestRef.current.onMessageNoUploadConfig,
|
|
2043
|
+
onEditContainer: (view, container) => latestRef.current.onEditContainer?.(view, container)
|
|
759
2044
|
}),
|
|
760
2045
|
codemirror.EditorView.updateListener.of((update) => {
|
|
761
|
-
if (update.docChanged) onChange(update.state.doc.toString());
|
|
2046
|
+
if (update.docChanged) latestRef.current.onChange(update.state.doc.toString());
|
|
762
2047
|
})
|
|
763
2048
|
];
|
|
764
2049
|
const state = _codemirror_state.EditorState.create({
|
|
@@ -769,18 +2054,26 @@ function Editor({ value, onChange, onScrollReady, onViewReady, onEditContainer,
|
|
|
769
2054
|
state,
|
|
770
2055
|
parent: editorRef.current
|
|
771
2056
|
});
|
|
772
|
-
if (
|
|
773
|
-
|
|
2057
|
+
if (viewRef.current) {
|
|
2058
|
+
onScrollReady?.(viewRef.current.scrollDOM);
|
|
2059
|
+
onViewReady?.(viewRef.current);
|
|
2060
|
+
}
|
|
774
2061
|
return () => {
|
|
775
2062
|
viewRef.current?.destroy();
|
|
2063
|
+
viewRef.current = null;
|
|
776
2064
|
};
|
|
777
2065
|
}, []);
|
|
778
2066
|
(0, react.useEffect)(() => {
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
2067
|
+
const view = viewRef.current;
|
|
2068
|
+
if (view && view.state.doc.toString() !== value) view.dispatch({
|
|
2069
|
+
changes: {
|
|
2070
|
+
from: 0,
|
|
2071
|
+
to: view.state.doc.length,
|
|
2072
|
+
insert: value
|
|
2073
|
+
},
|
|
2074
|
+
effects: view.scrollSnapshot(),
|
|
2075
|
+
scrollIntoView: false
|
|
2076
|
+
});
|
|
784
2077
|
}, [value]);
|
|
785
2078
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
786
2079
|
ref: editorRef,
|
|
@@ -789,23 +2082,25 @@ function Editor({ value, onChange, onScrollReady, onViewReady, onEditContainer,
|
|
|
789
2082
|
}
|
|
790
2083
|
//#endregion
|
|
791
2084
|
//#region src/components/Preview/index.tsx
|
|
792
|
-
var Preview = (0, react.forwardRef)(({ content, previewOptions }, ref) => {
|
|
2085
|
+
var Preview = (0, react.forwardRef)(({ content, previewOptions, languages }, ref) => {
|
|
793
2086
|
(0, react.useEffect)(() => {
|
|
794
2087
|
(0, remons_render_markdown.initHighlighter)({
|
|
795
2088
|
...remons_render_markdown.languagesCommon,
|
|
796
|
-
...
|
|
2089
|
+
...languages ?? {}
|
|
797
2090
|
});
|
|
798
|
-
}, [
|
|
2091
|
+
}, [languages]);
|
|
2092
|
+
const { languages: _ignored, ...restOptions } = previewOptions ?? {};
|
|
799
2093
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
800
2094
|
ref,
|
|
801
2095
|
className: "preview",
|
|
802
2096
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(remons_render_markdown.default, {
|
|
803
2097
|
content,
|
|
804
|
-
...
|
|
2098
|
+
...restOptions
|
|
805
2099
|
})
|
|
806
2100
|
});
|
|
807
2101
|
});
|
|
808
2102
|
Preview.displayName = "Preview";
|
|
2103
|
+
var Preview_default = (0, react.memo)(Preview);
|
|
809
2104
|
//#endregion
|
|
810
2105
|
//#region src/components/Panel/SplitPanels.tsx
|
|
811
2106
|
var { Panel } = antd.Splitter;
|
|
@@ -821,9 +2116,31 @@ function SplitPanels({ leftPanel, rightPanel }) {
|
|
|
821
2116
|
});
|
|
822
2117
|
}
|
|
823
2118
|
//#endregion
|
|
2119
|
+
//#region src/components/Icon/config.ts
|
|
2120
|
+
var scriptUrl = "https://at.alicdn.com/t/c/font_5241307_xoojyr52dqn.js";
|
|
2121
|
+
var IconComp = null;
|
|
2122
|
+
/**
|
|
2123
|
+
* 配置 iconfont 脚本地址(宿主在应用入口调用),需在首次渲染前设置;
|
|
2124
|
+
* 变更后重置内部缓存,下次渲染时以新地址重建图标组件。
|
|
2125
|
+
*/
|
|
2126
|
+
function setIconfontScriptUrl(url) {
|
|
2127
|
+
if (url === scriptUrl) return;
|
|
2128
|
+
scriptUrl = url;
|
|
2129
|
+
IconComp = null;
|
|
2130
|
+
}
|
|
2131
|
+
/** 读取当前 iconfont 脚本地址 */
|
|
2132
|
+
function getIconfontScriptUrl() {
|
|
2133
|
+
return scriptUrl;
|
|
2134
|
+
}
|
|
2135
|
+
/** 懒创建图标组件:首次渲染时才注入 iconfont 脚本,避免模块层副作用 */
|
|
2136
|
+
function getIconComponent() {
|
|
2137
|
+
if (!IconComp) IconComp = (0, _ant_design_icons.createFromIconfontCN)({ scriptUrl });
|
|
2138
|
+
return IconComp;
|
|
2139
|
+
}
|
|
2140
|
+
//#endregion
|
|
824
2141
|
//#region src/components/Icon/index.tsx
|
|
825
|
-
var Icon = (0, _ant_design_icons.createFromIconfontCN)({ scriptUrl: "https://at.alicdn.com/t/c/font_5241307_xoojyr52dqn.js" });
|
|
826
2142
|
function IconComponent(type, className) {
|
|
2143
|
+
const Icon = getIconComponent();
|
|
827
2144
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, {
|
|
828
2145
|
type: `icon-${type}`,
|
|
829
2146
|
className
|
|
@@ -844,7 +2161,8 @@ var UPLOAD_CONFIG_MISSING_MESSAGE = "请先配置图片上传功能";
|
|
|
844
2161
|
* @param options - 配置选项
|
|
845
2162
|
*/
|
|
846
2163
|
function createToolbarConfig(options) {
|
|
847
|
-
const hasUploadConfig = isUploadConfigured(options);
|
|
2164
|
+
const hasUploadConfig = isUploadConfigured(options?.upload);
|
|
2165
|
+
const notify = options?.notify;
|
|
848
2166
|
return [
|
|
849
2167
|
{
|
|
850
2168
|
id: "heading",
|
|
@@ -938,7 +2256,7 @@ function createToolbarConfig(options) {
|
|
|
938
2256
|
id: "image",
|
|
939
2257
|
label: "图片",
|
|
940
2258
|
icon: _ant_design_icons.PictureOutlined,
|
|
941
|
-
handler: hasUploadConfig && options ? (v) => uploadImage(v, options) : () =>
|
|
2259
|
+
handler: hasUploadConfig && options?.upload ? (v) => uploadImage(v, options.upload) : () => notify?.("warning", UPLOAD_CONFIG_MISSING_MESSAGE)
|
|
942
2260
|
},
|
|
943
2261
|
{ separatorBefore: true },
|
|
944
2262
|
{
|
|
@@ -985,11 +2303,14 @@ function createToolbarConfig(options) {
|
|
|
985
2303
|
//#endregion
|
|
986
2304
|
//#region src/components/Toolbar/hooks/useToolbar.ts
|
|
987
2305
|
function useToolbar(editorView, options) {
|
|
988
|
-
const { extraItems, uploadConfig } = options || {};
|
|
2306
|
+
const { extraItems, uploadConfig, notify } = options || {};
|
|
989
2307
|
return {
|
|
990
2308
|
config: (0, react.useMemo)(() => {
|
|
991
|
-
return createToolbarConfig(
|
|
992
|
-
|
|
2309
|
+
return createToolbarConfig({
|
|
2310
|
+
upload: uploadConfig,
|
|
2311
|
+
notify
|
|
2312
|
+
});
|
|
2313
|
+
}, [uploadConfig, notify]),
|
|
993
2314
|
extraItemsConfig: (0, react.useMemo)(() => {
|
|
994
2315
|
return extraItems || [];
|
|
995
2316
|
}, [extraItems]),
|
|
@@ -1009,34 +2330,52 @@ function useToolbar(editorView, options) {
|
|
|
1009
2330
|
}
|
|
1010
2331
|
//#endregion
|
|
1011
2332
|
//#region src/components/Toolbar/renderers/ToolbarItemRenderer.tsx
|
|
2333
|
+
/**
|
|
2334
|
+
* 渲染图标:统一接受组件类型;兼容传入 ReactNode 的旧用法。
|
|
2335
|
+
* 组件类型不仅指函数/class,也包括 forwardRef、memo 包装出的对象
|
|
2336
|
+
* (@ant-design/icons 即为 forwardRef,不能当作普通 child 直接渲染)。
|
|
2337
|
+
*/
|
|
2338
|
+
var REACT_FORWARD_REF = Symbol.for("react.forward_ref");
|
|
2339
|
+
var REACT_MEMO = Symbol.for("react.memo");
|
|
2340
|
+
function isComponentType(icon) {
|
|
2341
|
+
if (typeof icon === "function") return true;
|
|
2342
|
+
if (typeof icon === "object" && icon !== null) {
|
|
2343
|
+
const t = icon.$$typeof;
|
|
2344
|
+
return t === REACT_FORWARD_REF || t === REACT_MEMO;
|
|
2345
|
+
}
|
|
2346
|
+
return false;
|
|
2347
|
+
}
|
|
2348
|
+
function renderIcon(icon) {
|
|
2349
|
+
if (isComponentType(icon)) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(icon, {});
|
|
2350
|
+
return icon;
|
|
2351
|
+
}
|
|
1012
2352
|
function ToolbarItemRenderer({ item, onClick }) {
|
|
1013
|
-
const Icon = item.icon;
|
|
1014
2353
|
if (item.children && item.children.length > 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [item.separatorBefore && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "toolbar-separator" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1015
2354
|
className: "toolbar-group",
|
|
1016
2355
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Tooltip, {
|
|
1017
2356
|
title: item.label,
|
|
1018
2357
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Dropdown, {
|
|
1019
|
-
menu: {
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
children: [
|
|
1025
|
-
child.icon && (() => {
|
|
1026
|
-
const ChildIcon = child.icon;
|
|
1027
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChildIcon, {});
|
|
1028
|
-
})(),
|
|
2358
|
+
menu: {
|
|
2359
|
+
items: item.children.map((child) => ({
|
|
2360
|
+
key: child.id ?? "",
|
|
2361
|
+
label: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
|
|
2362
|
+
child.icon && renderIcon(child.icon),
|
|
1029
2363
|
" ",
|
|
1030
2364
|
child.label
|
|
1031
|
-
]
|
|
1032
|
-
|
|
1033
|
-
|
|
2365
|
+
] }),
|
|
2366
|
+
disabled: child.disabled
|
|
2367
|
+
})),
|
|
2368
|
+
onClick: ({ key }) => {
|
|
2369
|
+
const child = item.children?.find((c) => c.id === key);
|
|
2370
|
+
if (child && !child.disabled) onClick(child);
|
|
2371
|
+
}
|
|
2372
|
+
},
|
|
1034
2373
|
placement: "bottomLeft",
|
|
1035
2374
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(antd.Button, {
|
|
1036
2375
|
className: "toolbar-button",
|
|
1037
2376
|
type: "text",
|
|
1038
2377
|
size: "small",
|
|
1039
|
-
children: [
|
|
2378
|
+
children: [item.icon && renderIcon(item.icon), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_ant_design_icons.DownOutlined, { style: { fontSize: 10 } })]
|
|
1040
2379
|
})
|
|
1041
2380
|
})
|
|
1042
2381
|
})
|
|
@@ -1053,7 +2392,7 @@ function ToolbarItemRenderer({ item, onClick }) {
|
|
|
1053
2392
|
size: "small",
|
|
1054
2393
|
disabled: isDisabled,
|
|
1055
2394
|
onClick: () => !isDisabled && onClick(item),
|
|
1056
|
-
children:
|
|
2395
|
+
children: item.icon && renderIcon(item.icon)
|
|
1057
2396
|
})
|
|
1058
2397
|
})
|
|
1059
2398
|
})] });
|
|
@@ -1071,125 +2410,81 @@ var index_module_default = {
|
|
|
1071
2410
|
var MAX_ROW = 8;
|
|
1072
2411
|
var MAX_COL = 8;
|
|
1073
2412
|
function TablePicker({ onSelect }) {
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
2413
|
+
/** 当前高亮区域(rows x cols),渲染唯一依赖此状态 */
|
|
2414
|
+
const [size, setSize] = (0, react.useState)({
|
|
2415
|
+
rows: 0,
|
|
2416
|
+
cols: 0
|
|
1077
2417
|
});
|
|
1078
|
-
|
|
1079
|
-
row: 0,
|
|
1080
|
-
col: 0
|
|
1081
|
-
});
|
|
1082
|
-
const maxColRef = (0, react.useRef)(0);
|
|
2418
|
+
/** 鼠标回撤(向上/向左)后需要重置列跟踪,prevRow 与 pending 成对出现,仅事件处理内使用 */
|
|
1083
2419
|
const prevRowRef = (0, react.useRef)(0);
|
|
1084
|
-
const
|
|
1085
|
-
const
|
|
1086
|
-
const commitRef = (0, react.useRef)(null);
|
|
1087
|
-
const clearTimer = (0, react.useCallback)(() => {
|
|
1088
|
-
if (timerIdRef.current) {
|
|
1089
|
-
clearTimeout(timerIdRef.current);
|
|
1090
|
-
timerIdRef.current = null;
|
|
1091
|
-
}
|
|
1092
|
-
}, []);
|
|
2420
|
+
const pendingColsRef = (0, react.useRef)(0);
|
|
2421
|
+
const flashTimerRef = (0, react.useRef)(null);
|
|
1093
2422
|
const clearFlash = (0, react.useCallback)(() => {
|
|
1094
|
-
if (
|
|
1095
|
-
clearInterval(
|
|
1096
|
-
|
|
2423
|
+
if (flashTimerRef.current) {
|
|
2424
|
+
clearInterval(flashTimerRef.current);
|
|
2425
|
+
flashTimerRef.current = null;
|
|
1097
2426
|
}
|
|
1098
2427
|
}, []);
|
|
1099
2428
|
(0, react.useEffect)(() => () => {
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
}, []);
|
|
2429
|
+
clearFlash();
|
|
2430
|
+
}, [clearFlash]);
|
|
1103
2431
|
/**
|
|
1104
2432
|
* 扩展选中区域至 (col, row)
|
|
1105
2433
|
*/
|
|
1106
2434
|
function extend(col, row) {
|
|
1107
|
-
if (row < prevRowRef.current || col <
|
|
1108
|
-
if (col >
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
setConfirmedSize({
|
|
1114
|
-
row,
|
|
1115
|
-
col: maxColRef.current
|
|
2435
|
+
if (row < prevRowRef.current || col < pendingColsRef.current) pendingColsRef.current = 0;
|
|
2436
|
+
if (col > pendingColsRef.current) pendingColsRef.current = col;
|
|
2437
|
+
const cols = pendingColsRef.current;
|
|
2438
|
+
setSize({
|
|
2439
|
+
rows: row,
|
|
2440
|
+
cols
|
|
1116
2441
|
});
|
|
1117
|
-
|
|
1118
|
-
cols: maxColRef.current,
|
|
1119
|
-
rows: 1
|
|
1120
|
-
};
|
|
2442
|
+
prevRowRef.current = row;
|
|
1121
2443
|
}
|
|
1122
2444
|
/**
|
|
1123
|
-
*
|
|
2445
|
+
* 跳跃动画效果:逐行推进高亮,结束后落到 (col, limit)
|
|
1124
2446
|
*/
|
|
1125
|
-
function flash(col, dir, limit
|
|
2447
|
+
function flash(col, dir, limit) {
|
|
2448
|
+
clearFlash();
|
|
1126
2449
|
let current = dir === 1 ? 1 : limit;
|
|
1127
2450
|
const step = dir === 1 ? 1 : -1;
|
|
1128
|
-
|
|
1129
|
-
setHoverSize({
|
|
1130
|
-
row: current,
|
|
1131
|
-
col
|
|
1132
|
-
});
|
|
1133
|
-
if (current > confirmedSize.row || dir === -1) maxColRef.current = Math.min(MAX_COL, col);
|
|
1134
|
-
current += step;
|
|
2451
|
+
flashTimerRef.current = setInterval(() => {
|
|
1135
2452
|
if (dir === 1 && current > limit || dir === -1 && current < 1) {
|
|
1136
|
-
|
|
1137
|
-
refreshTimerRef.current = null;
|
|
2453
|
+
clearFlash();
|
|
1138
2454
|
const finalRow = current - step;
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
col
|
|
2455
|
+
setSize({
|
|
2456
|
+
rows: finalRow,
|
|
2457
|
+
cols: col
|
|
1142
2458
|
});
|
|
1143
|
-
|
|
2459
|
+
return;
|
|
1144
2460
|
}
|
|
2461
|
+
setSize({
|
|
2462
|
+
rows: current,
|
|
2463
|
+
cols: col
|
|
2464
|
+
});
|
|
2465
|
+
current += step;
|
|
1145
2466
|
}, 50);
|
|
1146
2467
|
}
|
|
1147
2468
|
/**
|
|
1148
2469
|
* 核心逻辑:鼠标进入格子
|
|
1149
2470
|
*/
|
|
1150
|
-
function
|
|
1151
|
-
clearTimer();
|
|
2471
|
+
function onCellEnter(index) {
|
|
1152
2472
|
clearFlash();
|
|
1153
2473
|
const row = Math.floor(index / MAX_COL) + 1;
|
|
1154
2474
|
const col = index % MAX_COL + 1;
|
|
1155
|
-
const
|
|
1156
|
-
const isJump = Math.abs(row -
|
|
1157
|
-
const isDown = row > prevRow;
|
|
2475
|
+
const maxCol = pendingColsRef.current;
|
|
2476
|
+
const isJump = Math.abs(row - prevRowRef.current) > 1;
|
|
1158
2477
|
prevRowRef.current = row;
|
|
1159
2478
|
if (!isJump) extend(col, row);
|
|
1160
|
-
else if (
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
row: r,
|
|
1164
|
-
col: c
|
|
1165
|
-
});
|
|
1166
|
-
});
|
|
1167
|
-
else extend(col, row);
|
|
2479
|
+
else if (row > 0 && (col > maxCol || maxCol >= MAX_COL)) {
|
|
2480
|
+
pendingColsRef.current = Math.min(MAX_COL, col);
|
|
2481
|
+
flash(Math.min(MAX_COL, col), 1, Math.min(row, MAX_ROW));
|
|
1168
2482
|
} else {
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
setConfirmedSize({
|
|
1172
|
-
row: r,
|
|
1173
|
-
col: c
|
|
1174
|
-
});
|
|
1175
|
-
if (r === 1) {
|
|
1176
|
-
commitRef.current = {
|
|
1177
|
-
cols: Math.min(MAX_COL, col),
|
|
1178
|
-
rows: 1
|
|
1179
|
-
};
|
|
1180
|
-
setConfirmedSize({
|
|
1181
|
-
row: 1,
|
|
1182
|
-
col: Math.min(MAX_COL, col)
|
|
1183
|
-
});
|
|
1184
|
-
}
|
|
1185
|
-
});
|
|
2483
|
+
pendingColsRef.current = 0;
|
|
2484
|
+
extend(col, row);
|
|
1186
2485
|
}
|
|
1187
2486
|
}
|
|
1188
2487
|
function onMouseDown() {
|
|
1189
|
-
const size = commitRef.current || {
|
|
1190
|
-
cols: maxColRef.current,
|
|
1191
|
-
rows: confirmedSize.row
|
|
1192
|
-
};
|
|
1193
2488
|
if (size.rows > 0 && size.cols > 0) onSelect(size);
|
|
1194
2489
|
}
|
|
1195
2490
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -1201,18 +2496,18 @@ function TablePicker({ onSelect }) {
|
|
|
1201
2496
|
children: Array.from({ length: 64 }).map((_, i) => {
|
|
1202
2497
|
const row = Math.floor(i / MAX_COL) + 1;
|
|
1203
2498
|
const col = i % MAX_COL + 1;
|
|
1204
|
-
const isSelected = row <=
|
|
2499
|
+
const isSelected = row <= size.rows && col <= size.cols;
|
|
1205
2500
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1206
2501
|
className: `${index_module_default.cell} ${isSelected ? index_module_default.cellActive : ""}`,
|
|
1207
|
-
onMouseEnter: () =>
|
|
2502
|
+
onMouseEnter: () => onCellEnter(i)
|
|
1208
2503
|
}, i);
|
|
1209
2504
|
})
|
|
1210
2505
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1211
2506
|
className: index_module_default.label,
|
|
1212
2507
|
children: [
|
|
1213
|
-
|
|
2508
|
+
size.rows,
|
|
1214
2509
|
" x ",
|
|
1215
|
-
|
|
2510
|
+
size.cols || 1
|
|
1216
2511
|
]
|
|
1217
2512
|
})]
|
|
1218
2513
|
});
|
|
@@ -1220,8 +2515,10 @@ function TablePicker({ onSelect }) {
|
|
|
1220
2515
|
//#endregion
|
|
1221
2516
|
//#region src/components/Toolbar/renderers/TablePicker/TableDropdown.tsx
|
|
1222
2517
|
function TableDropdown({ editorView }) {
|
|
1223
|
-
const [open, setOpen] = react.
|
|
1224
|
-
const
|
|
2518
|
+
const [open, setOpen] = (0, react.useState)(false);
|
|
2519
|
+
const handleOpenChange = (0, react.useCallback)((next) => {
|
|
2520
|
+
setOpen(next);
|
|
2521
|
+
}, []);
|
|
1225
2522
|
const handleTableSelect = (0, react.useCallback)((rows, cols) => {
|
|
1226
2523
|
if (!editorView || rows <= 0 || cols <= 0) return;
|
|
1227
2524
|
editorView.focus();
|
|
@@ -1238,18 +2535,15 @@ function TableDropdown({ editorView }) {
|
|
|
1238
2535
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Dropdown, {
|
|
1239
2536
|
trigger: ["click"],
|
|
1240
2537
|
open,
|
|
1241
|
-
onOpenChange:
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
} }, openCountRef.current)
|
|
1251
|
-
});
|
|
1252
|
-
},
|
|
2538
|
+
onOpenChange: handleOpenChange,
|
|
2539
|
+
destroyOnHidden: true,
|
|
2540
|
+
popupRender: () => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2541
|
+
style: { padding: 4 },
|
|
2542
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TablePicker, { onSelect: (size) => {
|
|
2543
|
+
handleTableSelect(size.rows, size.cols);
|
|
2544
|
+
setOpen(false);
|
|
2545
|
+
} })
|
|
2546
|
+
}),
|
|
1253
2547
|
placement: "bottomLeft",
|
|
1254
2548
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
|
|
1255
2549
|
className: "toolbar-button",
|
|
@@ -1262,10 +2556,11 @@ function TableDropdown({ editorView }) {
|
|
|
1262
2556
|
}
|
|
1263
2557
|
//#endregion
|
|
1264
2558
|
//#region src/components/Toolbar/index.tsx
|
|
1265
|
-
function Toolbar({ editorView, fullscreen = true, onToggleFullscreen, extraItems, uploadConfig }) {
|
|
2559
|
+
function Toolbar({ editorView, fullscreen = true, onToggleFullscreen, extraItems, uploadConfig, notify }) {
|
|
1266
2560
|
const { config, extraItemsConfig, handleClick } = useToolbar(editorView, {
|
|
1267
2561
|
extraItems,
|
|
1268
|
-
uploadConfig
|
|
2562
|
+
uploadConfig,
|
|
2563
|
+
notify
|
|
1269
2564
|
});
|
|
1270
2565
|
const renderFullscreen = (0, react.useCallback)(() => {
|
|
1271
2566
|
if (!onToggleFullscreen) return null;
|
|
@@ -1305,8 +2600,305 @@ function Toolbar({ editorView, fullscreen = true, onToggleFullscreen, extraItems
|
|
|
1305
2600
|
]
|
|
1306
2601
|
});
|
|
1307
2602
|
}
|
|
2603
|
+
var Toolbar_default = (0, react.memo)(Toolbar);
|
|
1308
2604
|
//#endregion
|
|
1309
2605
|
//#region src/components/Dialog/EditDialog.tsx
|
|
2606
|
+
var import_dayjs_min = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
2607
|
+
(function(t, e) {
|
|
2608
|
+
"object" == typeof exports && "undefined" != typeof module ? module.exports = e() : "function" == typeof define && define.amd ? define(e) : (t = "undefined" != typeof globalThis ? globalThis : t || self).dayjs = e();
|
|
2609
|
+
})(exports, (function() {
|
|
2610
|
+
"use strict";
|
|
2611
|
+
var t = 1e3, e = 6e4, n = 36e5, r = "millisecond", i = "second", s = "minute", u = "hour", a = "day", o = "week", c = "month", f = "quarter", h = "year", d = "date", l = "Invalid Date", $ = /^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/, y = /\[([^\]]+)]|YYYY|YY|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g, M = {
|
|
2612
|
+
name: "en",
|
|
2613
|
+
weekdays: "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),
|
|
2614
|
+
months: "January_February_March_April_May_June_July_August_September_October_November_December".split("_"),
|
|
2615
|
+
ordinal: function(t) {
|
|
2616
|
+
var e = [
|
|
2617
|
+
"th",
|
|
2618
|
+
"st",
|
|
2619
|
+
"nd",
|
|
2620
|
+
"rd"
|
|
2621
|
+
], n = t % 100;
|
|
2622
|
+
return "[" + t + (e[(n - 20) % 10] || e[n] || e[0]) + "]";
|
|
2623
|
+
}
|
|
2624
|
+
}, m = function(t, e, n) {
|
|
2625
|
+
var r = String(t);
|
|
2626
|
+
return !r || r.length >= e ? t : "" + Array(e + 1 - r.length).join(n) + t;
|
|
2627
|
+
}, v = {
|
|
2628
|
+
s: m,
|
|
2629
|
+
z: function(t) {
|
|
2630
|
+
var e = -t.utcOffset(), n = Math.abs(e), r = Math.floor(n / 60), i = n % 60;
|
|
2631
|
+
return (e <= 0 ? "+" : "-") + m(r, 2, "0") + ":" + m(i, 2, "0");
|
|
2632
|
+
},
|
|
2633
|
+
m: function t(e, n) {
|
|
2634
|
+
if (e.date() < n.date()) return -t(n, e);
|
|
2635
|
+
var r = 12 * (n.year() - e.year()) + (n.month() - e.month()), i = e.clone().add(r, c), s = n - i < 0, u = e.clone().add(r + (s ? -1 : 1), c);
|
|
2636
|
+
return +(-(r + (n - i) / (s ? i - u : u - i)) || 0);
|
|
2637
|
+
},
|
|
2638
|
+
a: function(t) {
|
|
2639
|
+
return t < 0 ? Math.ceil(t) || 0 : Math.floor(t);
|
|
2640
|
+
},
|
|
2641
|
+
p: function(t) {
|
|
2642
|
+
return {
|
|
2643
|
+
M: c,
|
|
2644
|
+
y: h,
|
|
2645
|
+
w: o,
|
|
2646
|
+
d: a,
|
|
2647
|
+
D: d,
|
|
2648
|
+
h: u,
|
|
2649
|
+
m: s,
|
|
2650
|
+
s: i,
|
|
2651
|
+
ms: r,
|
|
2652
|
+
Q: f
|
|
2653
|
+
}[t] || String(t || "").toLowerCase().replace(/s$/, "");
|
|
2654
|
+
},
|
|
2655
|
+
u: function(t) {
|
|
2656
|
+
return void 0 === t;
|
|
2657
|
+
}
|
|
2658
|
+
}, g = "en", D = {};
|
|
2659
|
+
D[g] = M;
|
|
2660
|
+
var p = "$isDayjsObject", S = function(t) {
|
|
2661
|
+
return t instanceof _ || !(!t || !t[p]);
|
|
2662
|
+
}, w = function t(e, n, r) {
|
|
2663
|
+
var i;
|
|
2664
|
+
if (!e) return g;
|
|
2665
|
+
if ("string" == typeof e) {
|
|
2666
|
+
var s = e.toLowerCase();
|
|
2667
|
+
D[s] && (i = s), n && (D[s] = n, i = s);
|
|
2668
|
+
var u = e.split("-");
|
|
2669
|
+
if (!i && u.length > 1) return t(u[0]);
|
|
2670
|
+
} else {
|
|
2671
|
+
var a = e.name;
|
|
2672
|
+
D[a] = e, i = a;
|
|
2673
|
+
}
|
|
2674
|
+
return !r && i && (g = i), i || !r && g;
|
|
2675
|
+
}, O = function(t, e) {
|
|
2676
|
+
if (S(t)) return t.clone();
|
|
2677
|
+
var n = "object" == typeof e ? e : {};
|
|
2678
|
+
return n.date = t, n.args = arguments, new _(n);
|
|
2679
|
+
}, b = v;
|
|
2680
|
+
b.l = w, b.i = S, b.w = function(t, e) {
|
|
2681
|
+
return O(t, {
|
|
2682
|
+
locale: e.$L,
|
|
2683
|
+
utc: e.$u,
|
|
2684
|
+
x: e.$x,
|
|
2685
|
+
$offset: e.$offset
|
|
2686
|
+
});
|
|
2687
|
+
};
|
|
2688
|
+
var _ = function() {
|
|
2689
|
+
function M(t) {
|
|
2690
|
+
this.$L = w(t.locale, null, !0), this.parse(t), this.$x = this.$x || t.x || {}, this[p] = !0;
|
|
2691
|
+
}
|
|
2692
|
+
var m = M.prototype;
|
|
2693
|
+
return m.parse = function(t) {
|
|
2694
|
+
this.$d = function(t) {
|
|
2695
|
+
var e = t.date, n = t.utc;
|
|
2696
|
+
if (null === e) return /* @__PURE__ */ new Date(NaN);
|
|
2697
|
+
if (b.u(e)) return /* @__PURE__ */ new Date();
|
|
2698
|
+
if (e instanceof Date) return new Date(e);
|
|
2699
|
+
if ("string" == typeof e && !/Z$/i.test(e)) {
|
|
2700
|
+
var r = e.match($);
|
|
2701
|
+
if (r) {
|
|
2702
|
+
var i = r[2] - 1 || 0, s = (r[7] || "0").substring(0, 3);
|
|
2703
|
+
return n ? new Date(Date.UTC(r[1], i, r[3] || 1, r[4] || 0, r[5] || 0, r[6] || 0, s)) : new Date(r[1], i, r[3] || 1, r[4] || 0, r[5] || 0, r[6] || 0, s);
|
|
2704
|
+
}
|
|
2705
|
+
}
|
|
2706
|
+
return new Date(e);
|
|
2707
|
+
}(t), this.init();
|
|
2708
|
+
}, m.init = function() {
|
|
2709
|
+
var t = this.$d;
|
|
2710
|
+
this.$y = t.getFullYear(), this.$M = t.getMonth(), this.$D = t.getDate(), this.$W = t.getDay(), this.$H = t.getHours(), this.$m = t.getMinutes(), this.$s = t.getSeconds(), this.$ms = t.getMilliseconds();
|
|
2711
|
+
}, m.$utils = function() {
|
|
2712
|
+
return b;
|
|
2713
|
+
}, m.isValid = function() {
|
|
2714
|
+
return !(this.$d.toString() === l);
|
|
2715
|
+
}, m.isSame = function(t, e) {
|
|
2716
|
+
var n = O(t);
|
|
2717
|
+
return this.startOf(e) <= n && n <= this.endOf(e);
|
|
2718
|
+
}, m.isAfter = function(t, e) {
|
|
2719
|
+
return O(t) < this.startOf(e);
|
|
2720
|
+
}, m.isBefore = function(t, e) {
|
|
2721
|
+
return this.endOf(e) < O(t);
|
|
2722
|
+
}, m.$g = function(t, e, n) {
|
|
2723
|
+
return b.u(t) ? this[e] : this.set(n, t);
|
|
2724
|
+
}, m.unix = function() {
|
|
2725
|
+
return Math.floor(this.valueOf() / 1e3);
|
|
2726
|
+
}, m.valueOf = function() {
|
|
2727
|
+
return this.$d.getTime();
|
|
2728
|
+
}, m.startOf = function(t, e) {
|
|
2729
|
+
var n = this, r = !!b.u(e) || e, f = b.p(t), l = function(t, e) {
|
|
2730
|
+
var i = b.w(n.$u ? Date.UTC(n.$y, e, t) : new Date(n.$y, e, t), n);
|
|
2731
|
+
return r ? i : i.endOf(a);
|
|
2732
|
+
}, $ = function(t, e) {
|
|
2733
|
+
return b.w(n.toDate()[t].apply(n.toDate("s"), (r ? [
|
|
2734
|
+
0,
|
|
2735
|
+
0,
|
|
2736
|
+
0,
|
|
2737
|
+
0
|
|
2738
|
+
] : [
|
|
2739
|
+
23,
|
|
2740
|
+
59,
|
|
2741
|
+
59,
|
|
2742
|
+
999
|
|
2743
|
+
]).slice(e)), n);
|
|
2744
|
+
}, y = this.$W, M = this.$M, m = this.$D, v = "set" + (this.$u ? "UTC" : "");
|
|
2745
|
+
switch (f) {
|
|
2746
|
+
case h: return r ? l(1, 0) : l(31, 11);
|
|
2747
|
+
case c: return r ? l(1, M) : l(0, M + 1);
|
|
2748
|
+
case o:
|
|
2749
|
+
var g = this.$locale().weekStart || 0, D = (y < g ? y + 7 : y) - g;
|
|
2750
|
+
return l(r ? m - D : m + (6 - D), M);
|
|
2751
|
+
case a:
|
|
2752
|
+
case d: return $(v + "Hours", 0);
|
|
2753
|
+
case u: return $(v + "Minutes", 1);
|
|
2754
|
+
case s: return $(v + "Seconds", 2);
|
|
2755
|
+
case i: return $(v + "Milliseconds", 3);
|
|
2756
|
+
default: return this.clone();
|
|
2757
|
+
}
|
|
2758
|
+
}, m.endOf = function(t) {
|
|
2759
|
+
return this.startOf(t, !1);
|
|
2760
|
+
}, m.$set = function(t, e) {
|
|
2761
|
+
var n, o = b.p(t), f = "set" + (this.$u ? "UTC" : ""), l = (n = {}, n[a] = f + "Date", n[d] = f + "Date", n[c] = f + "Month", n[h] = f + "FullYear", n[u] = f + "Hours", n[s] = f + "Minutes", n[i] = f + "Seconds", n[r] = f + "Milliseconds", n)[o], $ = o === a ? this.$D + (e - this.$W) : e;
|
|
2762
|
+
if (o === c || o === h) {
|
|
2763
|
+
var y = this.clone().set(d, 1);
|
|
2764
|
+
y.$d[l]($), y.init(), this.$d = y.set(d, Math.min(this.$D, y.daysInMonth())).$d;
|
|
2765
|
+
} else l && this.$d[l]($);
|
|
2766
|
+
return this.init(), this;
|
|
2767
|
+
}, m.set = function(t, e) {
|
|
2768
|
+
return this.clone().$set(t, e);
|
|
2769
|
+
}, m.get = function(t) {
|
|
2770
|
+
return this[b.p(t)]();
|
|
2771
|
+
}, m.add = function(r, f) {
|
|
2772
|
+
var d, l = this;
|
|
2773
|
+
r = Number(r);
|
|
2774
|
+
var $ = b.p(f), y = function(t) {
|
|
2775
|
+
var e = O(l);
|
|
2776
|
+
return b.w(e.date(e.date() + Math.round(t * r)), l);
|
|
2777
|
+
};
|
|
2778
|
+
if ($ === c) return this.set(c, this.$M + r);
|
|
2779
|
+
if ($ === h) return this.set(h, this.$y + r);
|
|
2780
|
+
if ($ === a) return y(1);
|
|
2781
|
+
if ($ === o) return y(7);
|
|
2782
|
+
var M = (d = {}, d[s] = e, d[u] = n, d[i] = t, d)[$] || 1, m = this.$d.getTime() + r * M;
|
|
2783
|
+
return b.w(m, this);
|
|
2784
|
+
}, m.subtract = function(t, e) {
|
|
2785
|
+
return this.add(-1 * t, e);
|
|
2786
|
+
}, m.format = function(t) {
|
|
2787
|
+
var e = this, n = this.$locale();
|
|
2788
|
+
if (!this.isValid()) return n.invalidDate || l;
|
|
2789
|
+
var r = t || "YYYY-MM-DDTHH:mm:ssZ", i = b.z(this), s = this.$H, u = this.$m, a = this.$M, o = n.weekdays, c = n.months, f = n.meridiem, h = function(t, n, i, s) {
|
|
2790
|
+
return t && (t[n] || t(e, r)) || i[n].slice(0, s);
|
|
2791
|
+
}, d = function(t) {
|
|
2792
|
+
return b.s(s % 12 || 12, t, "0");
|
|
2793
|
+
}, $ = f || function(t, e, n) {
|
|
2794
|
+
var r = t < 12 ? "AM" : "PM";
|
|
2795
|
+
return n ? r.toLowerCase() : r;
|
|
2796
|
+
};
|
|
2797
|
+
return r.replace(y, (function(t, r) {
|
|
2798
|
+
return r || function(t) {
|
|
2799
|
+
switch (t) {
|
|
2800
|
+
case "YY": return String(e.$y).slice(-2);
|
|
2801
|
+
case "YYYY": return b.s(e.$y, 4, "0");
|
|
2802
|
+
case "M": return a + 1;
|
|
2803
|
+
case "MM": return b.s(a + 1, 2, "0");
|
|
2804
|
+
case "MMM": return h(n.monthsShort, a, c, 3);
|
|
2805
|
+
case "MMMM": return h(c, a);
|
|
2806
|
+
case "D": return e.$D;
|
|
2807
|
+
case "DD": return b.s(e.$D, 2, "0");
|
|
2808
|
+
case "d": return String(e.$W);
|
|
2809
|
+
case "dd": return h(n.weekdaysMin, e.$W, o, 2);
|
|
2810
|
+
case "ddd": return h(n.weekdaysShort, e.$W, o, 3);
|
|
2811
|
+
case "dddd": return o[e.$W];
|
|
2812
|
+
case "H": return String(s);
|
|
2813
|
+
case "HH": return b.s(s, 2, "0");
|
|
2814
|
+
case "h": return d(1);
|
|
2815
|
+
case "hh": return d(2);
|
|
2816
|
+
case "a": return $(s, u, !0);
|
|
2817
|
+
case "A": return $(s, u, !1);
|
|
2818
|
+
case "m": return String(u);
|
|
2819
|
+
case "mm": return b.s(u, 2, "0");
|
|
2820
|
+
case "s": return String(e.$s);
|
|
2821
|
+
case "ss": return b.s(e.$s, 2, "0");
|
|
2822
|
+
case "SSS": return b.s(e.$ms, 3, "0");
|
|
2823
|
+
case "Z": return i;
|
|
2824
|
+
}
|
|
2825
|
+
return null;
|
|
2826
|
+
}(t) || i.replace(":", "");
|
|
2827
|
+
}));
|
|
2828
|
+
}, m.utcOffset = function() {
|
|
2829
|
+
return 15 * -Math.round(this.$d.getTimezoneOffset() / 15);
|
|
2830
|
+
}, m.diff = function(r, d, l) {
|
|
2831
|
+
var $, y = this, M = b.p(d), m = O(r), v = (m.utcOffset() - this.utcOffset()) * e, g = this - m, D = function() {
|
|
2832
|
+
return b.m(y, m);
|
|
2833
|
+
};
|
|
2834
|
+
switch (M) {
|
|
2835
|
+
case h:
|
|
2836
|
+
$ = D() / 12;
|
|
2837
|
+
break;
|
|
2838
|
+
case c:
|
|
2839
|
+
$ = D();
|
|
2840
|
+
break;
|
|
2841
|
+
case f:
|
|
2842
|
+
$ = D() / 3;
|
|
2843
|
+
break;
|
|
2844
|
+
case o:
|
|
2845
|
+
$ = (g - v) / 6048e5;
|
|
2846
|
+
break;
|
|
2847
|
+
case a:
|
|
2848
|
+
$ = (g - v) / 864e5;
|
|
2849
|
+
break;
|
|
2850
|
+
case u:
|
|
2851
|
+
$ = g / n;
|
|
2852
|
+
break;
|
|
2853
|
+
case s:
|
|
2854
|
+
$ = g / e;
|
|
2855
|
+
break;
|
|
2856
|
+
case i:
|
|
2857
|
+
$ = g / t;
|
|
2858
|
+
break;
|
|
2859
|
+
default: $ = g;
|
|
2860
|
+
}
|
|
2861
|
+
return l ? $ : b.a($);
|
|
2862
|
+
}, m.daysInMonth = function() {
|
|
2863
|
+
return this.endOf(c).$D;
|
|
2864
|
+
}, m.$locale = function() {
|
|
2865
|
+
return D[this.$L];
|
|
2866
|
+
}, m.locale = function(t, e) {
|
|
2867
|
+
if (!t) return this.$L;
|
|
2868
|
+
var n = this.clone(), r = w(t, e, !0);
|
|
2869
|
+
return r && (n.$L = r), n;
|
|
2870
|
+
}, m.clone = function() {
|
|
2871
|
+
return b.w(this.$d, this);
|
|
2872
|
+
}, m.toDate = function() {
|
|
2873
|
+
return new Date(this.valueOf());
|
|
2874
|
+
}, m.toJSON = function() {
|
|
2875
|
+
return this.isValid() ? this.toISOString() : null;
|
|
2876
|
+
}, m.toISOString = function() {
|
|
2877
|
+
return this.$d.toISOString();
|
|
2878
|
+
}, m.toString = function() {
|
|
2879
|
+
return this.$d.toUTCString();
|
|
2880
|
+
}, M;
|
|
2881
|
+
}(), Y = _.prototype;
|
|
2882
|
+
return O.prototype = Y, [
|
|
2883
|
+
["$ms", r],
|
|
2884
|
+
["$s", i],
|
|
2885
|
+
["$m", s],
|
|
2886
|
+
["$H", u],
|
|
2887
|
+
["$W", a],
|
|
2888
|
+
["$M", c],
|
|
2889
|
+
["$y", h],
|
|
2890
|
+
["$D", d]
|
|
2891
|
+
].forEach((function(t) {
|
|
2892
|
+
Y[t[1]] = function(e) {
|
|
2893
|
+
return this.$g(e, t[0], t[1]);
|
|
2894
|
+
};
|
|
2895
|
+
})), O.extend = function(t, e) {
|
|
2896
|
+
return t.$i || (t(e, _, O), t.$i = !0), O;
|
|
2897
|
+
}, O.locale = w, O.isDayjs = S, O.unix = function(t) {
|
|
2898
|
+
return O(1e3 * t);
|
|
2899
|
+
}, O.en = D[g], O.Ls = D, O.p = {}, O;
|
|
2900
|
+
}));
|
|
2901
|
+
})))(), 1);
|
|
1310
2902
|
/**
|
|
1311
2903
|
* 组件类型到 antd 表单组件的映射
|
|
1312
2904
|
*/
|
|
@@ -1323,7 +2915,7 @@ var FormComponents = {
|
|
|
1323
2915
|
dateRange: antd.DatePicker.RangePicker
|
|
1324
2916
|
};
|
|
1325
2917
|
/**
|
|
1326
|
-
* 渲染对应类型的 antd
|
|
2918
|
+
* 渲染对应类型的 antd 表单组件(仅接收 componentProps,不再与 Form.Item props 混用)
|
|
1327
2919
|
*/
|
|
1328
2920
|
function renderFormItemComponent(field) {
|
|
1329
2921
|
const props = field.componentProps || {};
|
|
@@ -1332,32 +2924,70 @@ function renderFormItemComponent(field) {
|
|
|
1332
2924
|
}
|
|
1333
2925
|
/**
|
|
1334
2926
|
* 根据 fields 自动生成 Form.Item 列表
|
|
2927
|
+
* 初始值走 <Form initialValues> + 按次打开的 key:
|
|
2928
|
+
* initialValues 在字段实体注册时消费,天然避开“Modal 首次挂载前 setFieldsValue 落空”的时序竞态;
|
|
2929
|
+
* key 每次打开变化触发 Form 重挂载,确保切换到不同容器时重新取值。
|
|
1335
2930
|
*/
|
|
1336
|
-
function renderAutoForm(form, fields) {
|
|
2931
|
+
function renderAutoForm(form, fields, initialValues, initKey) {
|
|
1337
2932
|
if (!fields || fields.length === 0) return null;
|
|
1338
2933
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Form, {
|
|
1339
2934
|
form,
|
|
1340
2935
|
layout: "vertical",
|
|
2936
|
+
preserve: false,
|
|
2937
|
+
initialValues,
|
|
1341
2938
|
children: fields.map((field) => {
|
|
1342
2939
|
if (!field.componentType) return null;
|
|
1343
2940
|
const formItemProps = {
|
|
1344
2941
|
name: field.key,
|
|
1345
2942
|
label: field.name || field.key,
|
|
1346
2943
|
valuePropName: field.componentType === "switch" ? "checked" : void 0,
|
|
1347
|
-
...field.
|
|
2944
|
+
...field.formItemProps
|
|
1348
2945
|
};
|
|
1349
2946
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Form.Item, {
|
|
1350
2947
|
...formItemProps,
|
|
1351
2948
|
children: renderFormItemComponent(field)
|
|
1352
2949
|
}, field.key);
|
|
1353
2950
|
})
|
|
1354
|
-
});
|
|
2951
|
+
}, initKey);
|
|
2952
|
+
}
|
|
2953
|
+
/** 字符串形式的历史属性值('true'/'false')还原为布尔,供 Switch 初始化 */
|
|
2954
|
+
function toFormInitialValue(field, value) {
|
|
2955
|
+
if (value === void 0) return field.defaultValue ?? (field.componentType === "switch" ? false : void 0);
|
|
2956
|
+
if (field.componentType === "switch") {
|
|
2957
|
+
if (typeof value === "boolean") return value;
|
|
2958
|
+
return value === "true" || value === 1 || value === "1";
|
|
2959
|
+
}
|
|
2960
|
+
if (field.componentType === "number" || field.componentType === "slider" || field.componentType === "rate") {
|
|
2961
|
+
const num = Number(value);
|
|
2962
|
+
return Number.isNaN(num) ? void 0 : num;
|
|
2963
|
+
}
|
|
2964
|
+
if (field.componentType === "date") {
|
|
2965
|
+
const d = (0, import_dayjs_min.default)(typeof value === "boolean" ? String(value) : value);
|
|
2966
|
+
return d.isValid() ? d : void 0;
|
|
2967
|
+
}
|
|
2968
|
+
if (field.componentType === "dateRange") {
|
|
2969
|
+
const parts = String(value).split(",").map((s) => s.trim()).filter(Boolean);
|
|
2970
|
+
if (parts.length !== 2) return void 0;
|
|
2971
|
+
const [start, end] = parts.map((p) => (0, import_dayjs_min.default)(p));
|
|
2972
|
+
return start.isValid() && end.isValid() ? [start, end] : void 0;
|
|
2973
|
+
}
|
|
2974
|
+
return value;
|
|
2975
|
+
}
|
|
2976
|
+
/** 表单控件值归一化为容器属性可存储的字符串(容器语法仅支持扁平原始值) */
|
|
2977
|
+
function normalizeValue(field, value) {
|
|
2978
|
+
if (value === null || value === void 0) return "";
|
|
2979
|
+
if (field?.componentType === "date" && import_dayjs_min.default.isDayjs(value)) return value.format("YYYY-MM-DD");
|
|
2980
|
+
if (field?.componentType === "dateRange" && Array.isArray(value)) return value.filter((v) => import_dayjs_min.default.isDayjs(v)).map((v) => v.format("YYYY-MM-DD")).join(", ");
|
|
2981
|
+
const colorLike = value;
|
|
2982
|
+
if (colorLike && typeof colorLike === "object" && typeof colorLike.toHexString === "function") return colorLike.toHexString();
|
|
2983
|
+
if (typeof value === "boolean" || typeof value === "number") return value;
|
|
2984
|
+
return String(value);
|
|
1355
2985
|
}
|
|
1356
2986
|
/**
|
|
1357
2987
|
* 属性编辑弹窗组件
|
|
1358
2988
|
* 根据组件 schema 的 renderDialog 函数渲染弹窗内容
|
|
1359
2989
|
*/
|
|
1360
|
-
function EditDialog({ visible, typeName, currentProps, onSave, onClose }) {
|
|
2990
|
+
function EditDialog({ visible, typeName, currentProps, initKey, onSave, onClose }) {
|
|
1361
2991
|
const schema = componentRegistry.get(typeName);
|
|
1362
2992
|
const [formProps, setFormProps] = (0, react.useState)({});
|
|
1363
2993
|
const [form] = antd.Form.useForm();
|
|
@@ -1366,46 +2996,57 @@ function EditDialog({ visible, typeName, currentProps, onSave, onClose }) {
|
|
|
1366
2996
|
const dirtyRef = (0, react.useRef)(false);
|
|
1367
2997
|
const mergedProps = (0, react.useMemo)(() => {
|
|
1368
2998
|
if (!schema) return currentProps;
|
|
1369
|
-
const
|
|
1370
|
-
for (const field of schema.fields || [])
|
|
2999
|
+
const merged = {};
|
|
3000
|
+
for (const field of schema.fields || []) if (field.defaultValue !== void 0) merged[field.key] = field.defaultValue;
|
|
1371
3001
|
return {
|
|
1372
|
-
...
|
|
3002
|
+
...merged,
|
|
1373
3003
|
...currentProps
|
|
1374
3004
|
};
|
|
1375
3005
|
}, [schema, currentProps]);
|
|
3006
|
+
const initialValues = (0, react.useMemo)(() => {
|
|
3007
|
+
const initial = {};
|
|
3008
|
+
for (const [key, value] of Object.entries(mergedProps)) {
|
|
3009
|
+
const field = schema?.fields?.find((f) => f.key === key);
|
|
3010
|
+
const formValue = toFormInitialValue(field ?? { key }, value);
|
|
3011
|
+
if (formValue !== void 0) initial[key] = formValue;
|
|
3012
|
+
}
|
|
3013
|
+
return initial;
|
|
3014
|
+
}, [mergedProps, schema]);
|
|
1376
3015
|
(0, react.useEffect)(() => {
|
|
1377
3016
|
if (visible) {
|
|
1378
|
-
form.setFieldsValue(mergedProps);
|
|
1379
3017
|
setFormProps({});
|
|
3018
|
+
form.setFieldsValue(initialValues);
|
|
3019
|
+
dirtyRef.current = false;
|
|
1380
3020
|
}
|
|
1381
|
-
}, [
|
|
1382
|
-
visible,
|
|
1383
|
-
mergedProps,
|
|
1384
|
-
form
|
|
1385
|
-
]);
|
|
3021
|
+
}, [visible, form]);
|
|
1386
3022
|
const handleDialogChange = (key, value) => {
|
|
1387
3023
|
setFormProps((prev) => ({
|
|
1388
3024
|
...prev,
|
|
1389
3025
|
[key]: value
|
|
1390
3026
|
}));
|
|
3027
|
+
dirtyRef.current = true;
|
|
1391
3028
|
};
|
|
1392
3029
|
const handleOk = async () => {
|
|
1393
|
-
let finalProps = visible ? {
|
|
1394
|
-
...mergedProps,
|
|
1395
|
-
...formProps
|
|
1396
|
-
} : mergedProps;
|
|
1397
3030
|
try {
|
|
1398
3031
|
const formValues = await form.validateFields();
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
3032
|
+
for (const [key, value] of Object.entries(formValues)) formProps[key] = value;
|
|
3033
|
+
} catch {
|
|
3034
|
+
return;
|
|
3035
|
+
}
|
|
3036
|
+
const finalProps = {};
|
|
3037
|
+
for (const [key, value] of Object.entries({
|
|
3038
|
+
...mergedProps,
|
|
3039
|
+
...formProps
|
|
3040
|
+
})) {
|
|
3041
|
+
const field = schema?.fields?.find((f) => f.key === key);
|
|
3042
|
+
finalProps[key] = normalizeValue(field, value);
|
|
3043
|
+
}
|
|
1404
3044
|
onSaveRef.current(finalProps);
|
|
1405
3045
|
dirtyRef.current = false;
|
|
1406
3046
|
onClose();
|
|
1407
3047
|
};
|
|
1408
3048
|
const handleClose = () => {
|
|
3049
|
+
if (dirtyRef.current && !window.confirm("属性修改尚未保存,确定关闭吗?")) return;
|
|
1409
3050
|
setFormProps({});
|
|
1410
3051
|
dirtyRef.current = false;
|
|
1411
3052
|
onClose();
|
|
@@ -1419,14 +3060,17 @@ function EditDialog({ visible, typeName, currentProps, onSave, onClose }) {
|
|
|
1419
3060
|
dirtyRef.current = true;
|
|
1420
3061
|
};
|
|
1421
3062
|
const context = {
|
|
1422
|
-
props:
|
|
3063
|
+
props: {
|
|
3064
|
+
...mergedProps,
|
|
3065
|
+
...formProps
|
|
3066
|
+
},
|
|
1423
3067
|
form,
|
|
1424
3068
|
onChange: handleDialogChange,
|
|
1425
3069
|
onSave: contextSave
|
|
1426
3070
|
};
|
|
1427
3071
|
const renderDialogContent = () => {
|
|
1428
3072
|
if (schema.renderDialog) return schema.renderDialog(context);
|
|
1429
|
-
if (schema.fields?.some((f) => f.componentType) && schema.fields) return renderAutoForm(form, schema.fields);
|
|
3073
|
+
if (schema.fields?.some((f) => f.componentType) && schema.fields) return renderAutoForm(form, schema.fields, initialValues, initKey);
|
|
1430
3074
|
return null;
|
|
1431
3075
|
};
|
|
1432
3076
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Modal, {
|
|
@@ -1442,36 +3086,47 @@ function EditDialog({ visible, typeName, currentProps, onSave, onClose }) {
|
|
|
1442
3086
|
//#endregion
|
|
1443
3087
|
//#region src/utils/writeContainer.ts
|
|
1444
3088
|
/**
|
|
1445
|
-
*
|
|
1446
|
-
*
|
|
3089
|
+
* 从属性对象生成属性行。
|
|
3090
|
+
* 使用 JSON5 序列化:单引号风格与旧格式兼容,特殊字符会被正确转义,
|
|
3091
|
+
* 配合 parseContainerProps 保证读写往返无损。
|
|
1447
3092
|
*/
|
|
1448
3093
|
function writeContainerProps(props) {
|
|
1449
|
-
|
|
1450
|
-
return entries ? `{ ${entries} }` : "{}";
|
|
3094
|
+
return import_dist.default.stringify(props) ?? "{}";
|
|
1451
3095
|
}
|
|
1452
3096
|
/**
|
|
1453
3097
|
* 更新编辑器文档中的容器属性。
|
|
1454
|
-
*
|
|
3098
|
+
* 已有属性行则整行替换;没有属性行则在容器头行后插入一行。
|
|
3099
|
+
* @param headerPos 容器头行(:::type)任意位置,用于无属性行时定位插入点
|
|
3100
|
+
* @param quotePrefix 容器所处的引用前缀(如 "> "),嵌套在引用中时插入的属性行需保持一致
|
|
1455
3101
|
*/
|
|
1456
|
-
function updateContainerProps(view, propsLineFrom, propsLineTo, newProps) {
|
|
3102
|
+
function updateContainerProps(view, headerPos, propsLineFrom, propsLineTo, newProps, quotePrefix = "") {
|
|
1457
3103
|
const newPropsLine = writeContainerProps(newProps);
|
|
1458
|
-
view.dispatch({ changes: {
|
|
3104
|
+
if (propsLineTo > propsLineFrom) view.dispatch({ changes: {
|
|
1459
3105
|
from: propsLineFrom,
|
|
1460
3106
|
to: propsLineTo,
|
|
1461
|
-
insert: newPropsLine
|
|
3107
|
+
insert: `${quotePrefix}${newPropsLine}`
|
|
1462
3108
|
} });
|
|
3109
|
+
else {
|
|
3110
|
+
const headerLine = view.state.doc.lineAt(headerPos);
|
|
3111
|
+
view.dispatch({ changes: {
|
|
3112
|
+
from: headerLine.to,
|
|
3113
|
+
insert: `\n${quotePrefix}${newPropsLine}`
|
|
3114
|
+
} });
|
|
3115
|
+
}
|
|
1463
3116
|
}
|
|
1464
3117
|
/**
|
|
1465
3118
|
* 在当前光标位置插入新容器。
|
|
1466
|
-
* 创建 :::type 打开行 +
|
|
3119
|
+
* 创建 :::type 打开行 + 属性行 + ::: 关闭行的结构。
|
|
1467
3120
|
*/
|
|
1468
3121
|
function insertContainer(view, typeName, defaultProps) {
|
|
1469
3122
|
const { from } = view.state.selection.main;
|
|
1470
|
-
const
|
|
3123
|
+
const propsLine = writeContainerProps(defaultProps);
|
|
3124
|
+
const container = `\n:::${typeName}\n${propsLine}\n:::\n`;
|
|
1471
3125
|
view.dispatch({ changes: {
|
|
1472
3126
|
from,
|
|
1473
3127
|
insert: container
|
|
1474
3128
|
} });
|
|
3129
|
+
view.dispatch({ selection: { anchor: from + `\n:::${typeName}\n${propsLine}\n`.length } });
|
|
1475
3130
|
}
|
|
1476
3131
|
//#endregion
|
|
1477
3132
|
//#region src/hooks/useFullscreen.ts
|
|
@@ -1510,9 +3165,12 @@ function useFullscreen() {
|
|
|
1510
3165
|
/**
|
|
1511
3166
|
* 双向滚动同步 Hook
|
|
1512
3167
|
* 编辑器与预览区互相同步滚动位置(基于比例)
|
|
1513
|
-
* 使用
|
|
3168
|
+
* 使用 syncing 锁防止双向循环触发
|
|
3169
|
+
*
|
|
3170
|
+
* 直接接收滚动容器元素(而非 ref):元素变化时 effect 重新执行并重新绑定监听,
|
|
3171
|
+
* 避免"挂载时容器尚未就绪 / 编辑器 view 被重建"导致监听永久失效或绑到旧节点。
|
|
1514
3172
|
*/
|
|
1515
|
-
function useScrollSync(
|
|
3173
|
+
function useScrollSync(source, target) {
|
|
1516
3174
|
const rafIdRef = (0, react.useRef)(null);
|
|
1517
3175
|
const syncingRef = (0, react.useRef)(null);
|
|
1518
3176
|
const syncScroll = (from, fromEl, toEl) => {
|
|
@@ -1537,132 +3195,164 @@ function useScrollSync(sourceRef, targetRef) {
|
|
|
1537
3195
|
});
|
|
1538
3196
|
};
|
|
1539
3197
|
(0, react.useEffect)(() => {
|
|
1540
|
-
const source = sourceRef.current;
|
|
1541
|
-
const target = targetRef.current;
|
|
1542
3198
|
if (!source || !target) return;
|
|
1543
3199
|
const onSourceScroll = () => {
|
|
1544
3200
|
if (syncingRef.current !== null) return;
|
|
1545
|
-
|
|
1546
|
-
const t = targetRef.current;
|
|
1547
|
-
syncScroll("source", s, t);
|
|
3201
|
+
syncScroll("source", source, target);
|
|
1548
3202
|
};
|
|
1549
3203
|
const onTargetScroll = () => {
|
|
1550
3204
|
if (syncingRef.current !== null) return;
|
|
1551
|
-
|
|
1552
|
-
const t = targetRef.current;
|
|
1553
|
-
syncScroll("target", t, s);
|
|
3205
|
+
syncScroll("target", target, source);
|
|
1554
3206
|
};
|
|
1555
3207
|
source.addEventListener("scroll", onSourceScroll, { passive: true });
|
|
1556
3208
|
target.addEventListener("scroll", onTargetScroll, { passive: true });
|
|
1557
3209
|
return () => {
|
|
1558
3210
|
source.removeEventListener("scroll", onSourceScroll);
|
|
1559
3211
|
target.removeEventListener("scroll", onTargetScroll);
|
|
1560
|
-
if (rafIdRef.current)
|
|
3212
|
+
if (rafIdRef.current) {
|
|
3213
|
+
cancelAnimationFrame(rafIdRef.current);
|
|
3214
|
+
rafIdRef.current = null;
|
|
3215
|
+
}
|
|
3216
|
+
syncingRef.current = null;
|
|
1561
3217
|
};
|
|
1562
|
-
}, [
|
|
3218
|
+
}, [source, target]);
|
|
1563
3219
|
}
|
|
1564
3220
|
//#endregion
|
|
1565
3221
|
//#region src/MarkdownEditor.tsx
|
|
1566
|
-
|
|
3222
|
+
/** 订阅注册中心版本,注册变化时触发重渲染 */
|
|
3223
|
+
function useRegistryVersion() {
|
|
3224
|
+
const subscribe = (0, react.useCallback)((onChange) => componentRegistry.subscribe(onChange), []);
|
|
3225
|
+
const getSnapshot = (0, react.useCallback)(() => componentRegistry.getVersion(), []);
|
|
3226
|
+
return (0, react.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
|
|
3227
|
+
}
|
|
3228
|
+
var MarkdownEditorInner = ({ defaultValue = "", value, onChange, showPreview = true, fullscreen: fullscreenProp = true, previewOptions, uploadConfig, schemas, onNotify }, ref) => {
|
|
1567
3229
|
const [content, setContent] = (0, react.useState)(value ?? defaultValue);
|
|
1568
3230
|
const [editorView, setEditorView] = (0, react.useState)(null);
|
|
1569
|
-
const
|
|
1570
|
-
const
|
|
3231
|
+
const [scrollDOM, setScrollDOM] = (0, react.useState)(null);
|
|
3232
|
+
const [previewEl, setPreviewEl] = (0, react.useState)(null);
|
|
1571
3233
|
const { fullscreen, toggleFullscreen } = useFullscreen();
|
|
1572
|
-
useScrollSync(
|
|
3234
|
+
useScrollSync(scrollDOM, previewEl);
|
|
1573
3235
|
const [dialogVisible, setDialogVisible] = (0, react.useState)(false);
|
|
1574
3236
|
const [dialogTypeName, setDialogTypeName] = (0, react.useState)("");
|
|
1575
|
-
const [
|
|
1576
|
-
const [
|
|
3237
|
+
const [dialogContainer, setDialogContainer] = (0, react.useState)(null);
|
|
3238
|
+
const [dialogSeq, setDialogSeq] = (0, react.useState)(0);
|
|
3239
|
+
const app = antd.App.useApp();
|
|
3240
|
+
const notify = (0, react.useCallback)((type, text) => {
|
|
3241
|
+
if (onNotify) {
|
|
3242
|
+
onNotify(type, text);
|
|
3243
|
+
return;
|
|
3244
|
+
}
|
|
3245
|
+
(app?.message ?? antd.message)[type](text);
|
|
3246
|
+
}, [onNotify, app]);
|
|
3247
|
+
const lastEmittedRef = (0, react.useRef)(void 0);
|
|
1577
3248
|
(0, react.useEffect)(() => {
|
|
1578
|
-
if (value !== void 0) setContent(value);
|
|
3249
|
+
if (value !== void 0 && value !== lastEmittedRef.current) setContent(value);
|
|
1579
3250
|
}, [value]);
|
|
1580
3251
|
const internalSetContent = (0, react.useCallback)((newContent) => {
|
|
1581
3252
|
setContent(newContent);
|
|
3253
|
+
lastEmittedRef.current = newContent;
|
|
1582
3254
|
onChange?.(newContent);
|
|
1583
3255
|
}, [onChange]);
|
|
1584
3256
|
(0, react.useImperativeHandle)(ref, () => ({ getContent: () => content }), [content]);
|
|
1585
|
-
const
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
const
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
3257
|
+
const registryVersion = useRegistryVersion();
|
|
3258
|
+
(0, react.useEffect)(() => {
|
|
3259
|
+
editorView?.dispatch({ effects: refreshContainers.of(null) });
|
|
3260
|
+
}, [registryVersion, editorView]);
|
|
3261
|
+
const extraToolbarItems = (0, react.useMemo)(() => {
|
|
3262
|
+
const merged = /* @__PURE__ */ new Map();
|
|
3263
|
+
for (const schema of componentRegistry.getAll()) merged.set(schema.name, schema);
|
|
3264
|
+
for (const schema of schemas ?? []) merged.set(schema.name, schema);
|
|
3265
|
+
return [...merged.values()].flatMap((schema) => {
|
|
3266
|
+
if (schema.wrapTags) return {
|
|
3267
|
+
id: `wrap-${schema.name}`,
|
|
3268
|
+
label: schema.label,
|
|
3269
|
+
icon: schema.icon ?? _ant_design_icons.ReadOutlined,
|
|
3270
|
+
wrapTags: schema.wrapTags
|
|
3271
|
+
};
|
|
3272
|
+
const defaultProps = {};
|
|
3273
|
+
for (const field of schema.fields ?? []) if (field.defaultValue !== void 0) defaultProps[field.key] = field.defaultValue;
|
|
3274
|
+
return {
|
|
3275
|
+
id: `container-${schema.name}`,
|
|
3276
|
+
label: schema.label,
|
|
3277
|
+
icon: schema.icon ?? _ant_design_icons.ReadOutlined,
|
|
3278
|
+
handler: (view) => insertContainer(view, schema.name, defaultProps)
|
|
3279
|
+
};
|
|
3280
|
+
});
|
|
3281
|
+
}, [registryVersion, schemas]);
|
|
3282
|
+
const handleScrollReady = (0, react.useCallback)((dom) => {
|
|
3283
|
+
setScrollDOM(dom);
|
|
1603
3284
|
}, []);
|
|
1604
3285
|
const handlePreviewRef = (0, react.useCallback)((node) => {
|
|
1605
|
-
|
|
3286
|
+
setPreviewEl(node);
|
|
1606
3287
|
}, []);
|
|
1607
3288
|
const handleViewReady = (0, react.useCallback)((view) => {
|
|
1608
3289
|
setEditorView(view);
|
|
1609
3290
|
}, []);
|
|
1610
|
-
const handleEditContainer = (0, react.useCallback)((_view,
|
|
1611
|
-
setDialogTypeName(typeName);
|
|
1612
|
-
|
|
1613
|
-
|
|
3291
|
+
const handleEditContainer = (0, react.useCallback)((_view, container) => {
|
|
3292
|
+
setDialogTypeName(container.typeName);
|
|
3293
|
+
setDialogContainer(container);
|
|
3294
|
+
setDialogSeq((seq) => seq + 1);
|
|
1614
3295
|
setDialogVisible(true);
|
|
1615
3296
|
}, []);
|
|
1616
3297
|
const handleDialogSave = (0, react.useCallback)((newProps) => {
|
|
1617
|
-
if (editorView) updateContainerProps(editorView,
|
|
1618
|
-
}, [editorView,
|
|
3298
|
+
if (editorView && dialogContainer) updateContainerProps(editorView, dialogContainer.startPos, dialogContainer.propsLineFrom, dialogContainer.propsLineTo, newProps, dialogContainer.quotePrefix);
|
|
3299
|
+
}, [editorView, dialogContainer]);
|
|
1619
3300
|
const handleDialogClose = (0, react.useCallback)(() => {
|
|
1620
3301
|
setDialogVisible(false);
|
|
1621
3302
|
}, []);
|
|
3303
|
+
const editorNode = /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Editor, {
|
|
3304
|
+
value: content,
|
|
3305
|
+
onChange: internalSetContent,
|
|
3306
|
+
onScrollReady: handleScrollReady,
|
|
3307
|
+
onViewReady: handleViewReady,
|
|
3308
|
+
onEditContainer: handleEditContainer,
|
|
3309
|
+
uploadConfig,
|
|
3310
|
+
onMessageNoUploadConfig: () => notify("warning", "请先配置图片上传功能")
|
|
3311
|
+
});
|
|
1622
3312
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1623
3313
|
className: fullscreen ? "markdown-editor-app fullscreen" : "markdown-editor-app",
|
|
1624
3314
|
children: [
|
|
1625
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
3315
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Toolbar_default, {
|
|
1626
3316
|
editorView,
|
|
1627
3317
|
fullscreen,
|
|
1628
3318
|
onToggleFullscreen: fullscreenProp ? toggleFullscreen : void 0,
|
|
1629
3319
|
extraItems: extraToolbarItems,
|
|
1630
|
-
uploadConfig
|
|
3320
|
+
uploadConfig,
|
|
3321
|
+
notify
|
|
1631
3322
|
}),
|
|
1632
3323
|
showPreview ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SplitPanels, {
|
|
1633
|
-
leftPanel:
|
|
1634
|
-
|
|
1635
|
-
onChange: internalSetContent,
|
|
1636
|
-
onScrollReady: handleScrollReady,
|
|
1637
|
-
onViewReady: handleViewReady,
|
|
1638
|
-
onEditContainer: handleEditContainer,
|
|
1639
|
-
uploadConfig,
|
|
1640
|
-
onMessageNoUploadConfig: () => antd.message.warning("请先配置图片上传功能")
|
|
1641
|
-
}),
|
|
1642
|
-
rightPanel: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Preview, {
|
|
3324
|
+
leftPanel: editorNode,
|
|
3325
|
+
rightPanel: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Preview_default, {
|
|
1643
3326
|
content,
|
|
1644
3327
|
ref: handlePreviewRef,
|
|
1645
3328
|
previewOptions
|
|
1646
3329
|
})
|
|
1647
|
-
}) :
|
|
1648
|
-
value: content,
|
|
1649
|
-
onChange: internalSetContent,
|
|
1650
|
-
onScrollReady: handleScrollReady,
|
|
1651
|
-
onViewReady: handleViewReady,
|
|
1652
|
-
onEditContainer: handleEditContainer,
|
|
1653
|
-
uploadConfig,
|
|
1654
|
-
onMessageNoUploadConfig: () => antd.message.warning("请先配置图片上传功能")
|
|
1655
|
-
}),
|
|
3330
|
+
}) : editorNode,
|
|
1656
3331
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(EditDialog, {
|
|
1657
3332
|
visible: dialogVisible,
|
|
1658
3333
|
typeName: dialogTypeName,
|
|
1659
|
-
currentProps:
|
|
3334
|
+
currentProps: dialogContainer?.props ?? {},
|
|
3335
|
+
initKey: dialogSeq,
|
|
1660
3336
|
onSave: handleDialogSave,
|
|
1661
3337
|
onClose: handleDialogClose
|
|
1662
3338
|
})
|
|
1663
3339
|
]
|
|
1664
3340
|
});
|
|
1665
|
-
}
|
|
3341
|
+
};
|
|
3342
|
+
var MarkdownEditor = (0, react.forwardRef)(MarkdownEditorInner);
|
|
3343
|
+
/**
|
|
3344
|
+
* 包一层 antd App:为库内部的 message 等反馈组件提供上下文;
|
|
3345
|
+
* 宿主已有 App 包裹时内层仅作兜底(component={false} 不额外渲染 DOM)。
|
|
3346
|
+
*/
|
|
3347
|
+
function MarkdownEditorWithApp({ ref, ...props }) {
|
|
3348
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.App, {
|
|
3349
|
+
component: false,
|
|
3350
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MarkdownEditor, {
|
|
3351
|
+
...props,
|
|
3352
|
+
ref
|
|
3353
|
+
})
|
|
3354
|
+
});
|
|
3355
|
+
}
|
|
1666
3356
|
//#endregion
|
|
1667
3357
|
//#region src/hooks/useRegisterToolbar.ts
|
|
1668
3358
|
/**
|
|
@@ -1759,14 +3449,17 @@ var MarkdownEditor_default = (0, react.forwardRef)(function MarkdownEditor({ def
|
|
|
1759
3449
|
* @example 批量注册
|
|
1760
3450
|
* ```tsx
|
|
1761
3451
|
* function MyPage() {
|
|
3452
|
+
* // 注意:schema 需声明为稳定引用(组件外常量或 useMemo),
|
|
3453
|
+
* // 否则每次渲染都会重新注册;多实例互不干扰的场景请改用
|
|
3454
|
+
* // <MarkdownEditor schemas={[...]} /> 局部注册
|
|
1762
3455
|
* useRegisterToolbar([schema1, schema2, schema3])
|
|
1763
3456
|
* return <MarkdownEditor />
|
|
1764
3457
|
* }
|
|
1765
3458
|
* ```
|
|
1766
3459
|
*/
|
|
1767
3460
|
function useRegisterToolbar(schemas) {
|
|
1768
|
-
const schemaList = Array.isArray(schemas) ? schemas : [schemas];
|
|
1769
3461
|
(0, react.useEffect)(() => {
|
|
3462
|
+
const schemaList = Array.isArray(schemas) ? schemas : [schemas];
|
|
1770
3463
|
schemaList.forEach((schema) => {
|
|
1771
3464
|
componentRegistry.register(schema.name, schema);
|
|
1772
3465
|
});
|
|
@@ -1775,10 +3468,12 @@ function useRegisterToolbar(schemas) {
|
|
|
1775
3468
|
componentRegistry.unregister(schema.name);
|
|
1776
3469
|
});
|
|
1777
3470
|
};
|
|
1778
|
-
}, [
|
|
3471
|
+
}, [schemas]);
|
|
1779
3472
|
}
|
|
1780
3473
|
//#endregion
|
|
1781
|
-
exports.MarkdownEditor =
|
|
3474
|
+
exports.MarkdownEditor = MarkdownEditorWithApp;
|
|
3475
|
+
exports.getIconfontScriptUrl = getIconfontScriptUrl;
|
|
3476
|
+
exports.setIconfontScriptUrl = setIconfontScriptUrl;
|
|
1782
3477
|
exports.useRegisterToolbar = useRegisterToolbar;
|
|
1783
3478
|
|
|
1784
3479
|
//# sourceMappingURL=index.cjs.map
|