@limetech/lime-elements 37.56.0 → 37.56.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/CHANGELOG.md +8 -0
- package/dist/cjs/limel-prosemirror-adapter.cjs.entry.js +315 -247
- package/dist/cjs/limel-prosemirror-adapter.cjs.entry.js.map +1 -1
- package/dist/cjs/limel-snackbar.cjs.entry.js +1 -0
- package/dist/cjs/limel-snackbar.cjs.entry.js.map +1 -1
- package/dist/cjs/limel-text-editor.cjs.entry.js +2 -2
- package/dist/cjs/limel-text-editor.cjs.entry.js.map +1 -1
- package/dist/collection/components/snackbar/snackbar.js +1 -0
- package/dist/collection/components/snackbar/snackbar.js.map +1 -1
- package/dist/collection/components/text-editor/text-editor.css +6 -13
- package/dist/collection/components/text-editor/text-editor.js +1 -1
- package/dist/collection/components/text-editor/text-editor.js.map +1 -1
- package/dist/esm/limel-prosemirror-adapter.entry.js +315 -247
- package/dist/esm/limel-prosemirror-adapter.entry.js.map +1 -1
- package/dist/esm/limel-snackbar.entry.js +1 -0
- package/dist/esm/limel-snackbar.entry.js.map +1 -1
- package/dist/esm/limel-text-editor.entry.js +2 -2
- package/dist/esm/limel-text-editor.entry.js.map +1 -1
- package/dist/lime-elements/lime-elements.esm.js +1 -1
- package/dist/lime-elements/p-232dd438.entry.js +2 -0
- package/dist/lime-elements/p-232dd438.entry.js.map +1 -0
- package/dist/lime-elements/p-4ae6f448.entry.js +2 -0
- package/dist/lime-elements/p-4ae6f448.entry.js.map +1 -0
- package/dist/lime-elements/{p-385f680b.entry.js → p-84c9482c.entry.js} +2 -2
- package/dist/lime-elements/{p-385f680b.entry.js.map → p-84c9482c.entry.js.map} +1 -1
- package/package.json +2 -2
- package/dist/lime-elements/p-200b7739.entry.js +0 -2
- package/dist/lime-elements/p-200b7739.entry.js.map +0 -1
- package/dist/lime-elements/p-a82054c2.entry.js +0 -2
- package/dist/lime-elements/p-a82054c2.entry.js.map +0 -1
|
@@ -1025,7 +1025,7 @@ class Fragment {
|
|
|
1025
1025
|
/**
|
|
1026
1026
|
Find the index and inner offset corresponding to a given relative
|
|
1027
1027
|
position in this fragment. The result object will be reused
|
|
1028
|
-
(overwritten) the next time the function is called.
|
|
1028
|
+
(overwritten) the next time the function is called. @internal
|
|
1029
1029
|
*/
|
|
1030
1030
|
findIndex(pos, round = -1) {
|
|
1031
1031
|
if (pos == 0)
|
|
@@ -1258,7 +1258,9 @@ class Mark {
|
|
|
1258
1258
|
let type = schema.marks[json.type];
|
|
1259
1259
|
if (!type)
|
|
1260
1260
|
throw new RangeError(`There is no mark type ${json.type} in this schema`);
|
|
1261
|
-
|
|
1261
|
+
let mark = type.create(json.attrs);
|
|
1262
|
+
type.checkAttrs(mark.attrs);
|
|
1263
|
+
return mark;
|
|
1262
1264
|
}
|
|
1263
1265
|
/**
|
|
1264
1266
|
Test whether two sets of marks are identical.
|
|
@@ -1816,17 +1818,29 @@ class ResolvedPos {
|
|
|
1816
1818
|
@internal
|
|
1817
1819
|
*/
|
|
1818
1820
|
static resolveCached(doc, pos) {
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1821
|
+
let cache = resolveCache.get(doc);
|
|
1822
|
+
if (cache) {
|
|
1823
|
+
for (let i = 0; i < cache.elts.length; i++) {
|
|
1824
|
+
let elt = cache.elts[i];
|
|
1825
|
+
if (elt.pos == pos)
|
|
1826
|
+
return elt;
|
|
1827
|
+
}
|
|
1828
|
+
}
|
|
1829
|
+
else {
|
|
1830
|
+
resolveCache.set(doc, cache = new ResolveCache);
|
|
1823
1831
|
}
|
|
1824
|
-
let result =
|
|
1825
|
-
|
|
1832
|
+
let result = cache.elts[cache.i] = ResolvedPos.resolve(doc, pos);
|
|
1833
|
+
cache.i = (cache.i + 1) % resolveCacheSize;
|
|
1826
1834
|
return result;
|
|
1827
1835
|
}
|
|
1828
1836
|
}
|
|
1829
|
-
|
|
1837
|
+
class ResolveCache {
|
|
1838
|
+
constructor() {
|
|
1839
|
+
this.elts = [];
|
|
1840
|
+
this.i = 0;
|
|
1841
|
+
}
|
|
1842
|
+
}
|
|
1843
|
+
const resolveCacheSize = 12, resolveCache = new WeakMap();
|
|
1830
1844
|
/**
|
|
1831
1845
|
Represents a flat range of content, i.e. one that starts and
|
|
1832
1846
|
ends in the same node.
|
|
@@ -2226,13 +2240,17 @@ class Node$1 {
|
|
|
2226
2240
|
}
|
|
2227
2241
|
/**
|
|
2228
2242
|
Check whether this node and its descendants conform to the
|
|
2229
|
-
schema, and raise
|
|
2243
|
+
schema, and raise an exception when they do not.
|
|
2230
2244
|
*/
|
|
2231
2245
|
check() {
|
|
2232
2246
|
this.type.checkContent(this.content);
|
|
2247
|
+
this.type.checkAttrs(this.attrs);
|
|
2233
2248
|
let copy = Mark.none;
|
|
2234
|
-
for (let i = 0; i < this.marks.length; i++)
|
|
2235
|
-
|
|
2249
|
+
for (let i = 0; i < this.marks.length; i++) {
|
|
2250
|
+
let mark = this.marks[i];
|
|
2251
|
+
mark.type.checkAttrs(mark.attrs);
|
|
2252
|
+
copy = mark.addToSet(copy);
|
|
2253
|
+
}
|
|
2236
2254
|
if (!Mark.sameSet(copy, this.marks))
|
|
2237
2255
|
throw new RangeError(`Invalid collection of marks for node ${this.type.name}: ${this.marks.map(m => m.type.name)}`);
|
|
2238
2256
|
this.content.forEach(node => node.check());
|
|
@@ -2258,7 +2276,7 @@ class Node$1 {
|
|
|
2258
2276
|
static fromJSON(schema, json) {
|
|
2259
2277
|
if (!json)
|
|
2260
2278
|
throw new RangeError("Invalid input for Node.fromJSON");
|
|
2261
|
-
let marks =
|
|
2279
|
+
let marks = undefined;
|
|
2262
2280
|
if (json.marks) {
|
|
2263
2281
|
if (!Array.isArray(json.marks))
|
|
2264
2282
|
throw new RangeError("Invalid mark data for Node.fromJSON");
|
|
@@ -2270,7 +2288,9 @@ class Node$1 {
|
|
|
2270
2288
|
return schema.text(json.text, marks);
|
|
2271
2289
|
}
|
|
2272
2290
|
let content = Fragment.fromJSON(schema, json.content);
|
|
2273
|
-
|
|
2291
|
+
let node = schema.nodeType(json.type).create(json.attrs, content, marks);
|
|
2292
|
+
node.type.checkAttrs(node.attrs);
|
|
2293
|
+
return node;
|
|
2274
2294
|
}
|
|
2275
2295
|
}
|
|
2276
2296
|
Node$1.prototype.text = undefined;
|
|
@@ -2787,11 +2807,21 @@ function computeAttrs(attrs, value) {
|
|
|
2787
2807
|
}
|
|
2788
2808
|
return built;
|
|
2789
2809
|
}
|
|
2790
|
-
function
|
|
2810
|
+
function checkAttrs(attrs, values, type, name) {
|
|
2811
|
+
for (let name in values)
|
|
2812
|
+
if (!(name in attrs))
|
|
2813
|
+
throw new RangeError(`Unsupported attribute ${name} for ${type} of type ${name}`);
|
|
2814
|
+
for (let name in attrs) {
|
|
2815
|
+
let attr = attrs[name];
|
|
2816
|
+
if (attr.validate)
|
|
2817
|
+
attr.validate(values[name]);
|
|
2818
|
+
}
|
|
2819
|
+
}
|
|
2820
|
+
function initAttrs(typeName, attrs) {
|
|
2791
2821
|
let result = Object.create(null);
|
|
2792
2822
|
if (attrs)
|
|
2793
2823
|
for (let name in attrs)
|
|
2794
|
-
result[name] = new Attribute(attrs[name]);
|
|
2824
|
+
result[name] = new Attribute(typeName, name, attrs[name]);
|
|
2795
2825
|
return result;
|
|
2796
2826
|
}
|
|
2797
2827
|
/**
|
|
@@ -2826,7 +2856,7 @@ class NodeType$1 {
|
|
|
2826
2856
|
*/
|
|
2827
2857
|
this.markSet = null;
|
|
2828
2858
|
this.groups = spec.group ? spec.group.split(" ") : [];
|
|
2829
|
-
this.attrs = initAttrs(spec.attrs);
|
|
2859
|
+
this.attrs = initAttrs(name, spec.attrs);
|
|
2830
2860
|
this.defaultAttrs = defaultAttrs(this.attrs);
|
|
2831
2861
|
this.contentMatch = null;
|
|
2832
2862
|
this.inlineContent = null;
|
|
@@ -2930,7 +2960,7 @@ class NodeType$1 {
|
|
|
2930
2960
|
}
|
|
2931
2961
|
/**
|
|
2932
2962
|
Returns true if the given fragment is valid content for this node
|
|
2933
|
-
type
|
|
2963
|
+
type.
|
|
2934
2964
|
*/
|
|
2935
2965
|
validContent(content) {
|
|
2936
2966
|
let result = this.contentMatch.matchFragment(content);
|
|
@@ -2951,6 +2981,12 @@ class NodeType$1 {
|
|
|
2951
2981
|
throw new RangeError(`Invalid content for node ${this.name}: ${content.toString().slice(0, 50)}`);
|
|
2952
2982
|
}
|
|
2953
2983
|
/**
|
|
2984
|
+
@internal
|
|
2985
|
+
*/
|
|
2986
|
+
checkAttrs(attrs) {
|
|
2987
|
+
checkAttrs(this.attrs, attrs, "node");
|
|
2988
|
+
}
|
|
2989
|
+
/**
|
|
2954
2990
|
Check whether the given mark type is allowed in this node.
|
|
2955
2991
|
*/
|
|
2956
2992
|
allowsMarkType(markType) {
|
|
@@ -3001,11 +3037,20 @@ class NodeType$1 {
|
|
|
3001
3037
|
return result;
|
|
3002
3038
|
}
|
|
3003
3039
|
}
|
|
3040
|
+
function validateType(typeName, attrName, type) {
|
|
3041
|
+
let types = type.split("|");
|
|
3042
|
+
return (value) => {
|
|
3043
|
+
let name = value === null ? "null" : typeof value;
|
|
3044
|
+
if (types.indexOf(name) < 0)
|
|
3045
|
+
throw new RangeError(`Expected value of type ${types} for attribute ${attrName} on type ${typeName}, got ${name}`);
|
|
3046
|
+
};
|
|
3047
|
+
}
|
|
3004
3048
|
// Attribute descriptors
|
|
3005
3049
|
class Attribute {
|
|
3006
|
-
constructor(options) {
|
|
3050
|
+
constructor(typeName, attrName, options) {
|
|
3007
3051
|
this.hasDefault = Object.prototype.hasOwnProperty.call(options, "default");
|
|
3008
3052
|
this.default = options.default;
|
|
3053
|
+
this.validate = typeof options.validate == "string" ? validateType(typeName, attrName, options.validate) : options.validate;
|
|
3009
3054
|
}
|
|
3010
3055
|
get isRequired() {
|
|
3011
3056
|
return !this.hasDefault;
|
|
@@ -3043,7 +3088,7 @@ class MarkType {
|
|
|
3043
3088
|
this.rank = rank;
|
|
3044
3089
|
this.schema = schema;
|
|
3045
3090
|
this.spec = spec;
|
|
3046
|
-
this.attrs = initAttrs(spec.attrs);
|
|
3091
|
+
this.attrs = initAttrs(name, spec.attrs);
|
|
3047
3092
|
this.excluded = null;
|
|
3048
3093
|
let defaults = defaultAttrs(this.attrs);
|
|
3049
3094
|
this.instance = defaults ? new Mark(this, defaults) : null;
|
|
@@ -3087,6 +3132,12 @@ class MarkType {
|
|
|
3087
3132
|
return set[i];
|
|
3088
3133
|
}
|
|
3089
3134
|
/**
|
|
3135
|
+
@internal
|
|
3136
|
+
*/
|
|
3137
|
+
checkAttrs(attrs) {
|
|
3138
|
+
checkAttrs(this.attrs, attrs, "mark");
|
|
3139
|
+
}
|
|
3140
|
+
/**
|
|
3090
3141
|
Queries whether a given mark type is
|
|
3091
3142
|
[excluded](https://prosemirror.net/docs/ref/#model.MarkSpec.excludes) by this one.
|
|
3092
3143
|
*/
|
|
@@ -3108,6 +3159,12 @@ class Schema {
|
|
|
3108
3159
|
Construct a schema from a schema [specification](https://prosemirror.net/docs/ref/#model.SchemaSpec).
|
|
3109
3160
|
*/
|
|
3110
3161
|
constructor(spec) {
|
|
3162
|
+
/**
|
|
3163
|
+
The [linebreak
|
|
3164
|
+
replacement](https://prosemirror.net/docs/ref/#model.NodeSpec.linebreakReplacement) node defined
|
|
3165
|
+
in this schema, if any.
|
|
3166
|
+
*/
|
|
3167
|
+
this.linebreakReplacement = null;
|
|
3111
3168
|
/**
|
|
3112
3169
|
An object for storing whatever values modules may want to
|
|
3113
3170
|
compute and cache per schema. (If you want to store something
|
|
@@ -3129,6 +3186,13 @@ class Schema {
|
|
|
3129
3186
|
type.contentMatch = contentExprCache[contentExpr] ||
|
|
3130
3187
|
(contentExprCache[contentExpr] = ContentMatch.parse(contentExpr, this.nodes));
|
|
3131
3188
|
type.inlineContent = type.contentMatch.inlineContent;
|
|
3189
|
+
if (type.spec.linebreakReplacement) {
|
|
3190
|
+
if (this.linebreakReplacement)
|
|
3191
|
+
throw new RangeError("Multiple linebreak nodes defined");
|
|
3192
|
+
if (!type.isInline || !type.isLeaf)
|
|
3193
|
+
throw new RangeError("Linebreak replacement nodes must be inline leaf nodes");
|
|
3194
|
+
this.linebreakReplacement = type;
|
|
3195
|
+
}
|
|
3132
3196
|
type.markSet = markExpr == "_" ? null :
|
|
3133
3197
|
markExpr ? gatherMarks(this, markExpr.split(" ")) :
|
|
3134
3198
|
markExpr == "" || !type.inlineContent ? [] : null;
|
|
@@ -3217,6 +3281,8 @@ function gatherMarks(schema, marks) {
|
|
|
3217
3281
|
return found;
|
|
3218
3282
|
}
|
|
3219
3283
|
|
|
3284
|
+
function isTagRule(rule) { return rule.tag != null; }
|
|
3285
|
+
function isStyleRule(rule) { return rule.style != null; }
|
|
3220
3286
|
/**
|
|
3221
3287
|
A DOM parser represents a strategy for parsing DOM content into a
|
|
3222
3288
|
ProseMirror document conforming to a given schema. Its behavior is
|
|
@@ -3247,11 +3313,17 @@ class DOMParser {
|
|
|
3247
3313
|
@internal
|
|
3248
3314
|
*/
|
|
3249
3315
|
this.styles = [];
|
|
3316
|
+
let matchedStyles = this.matchedStyles = [];
|
|
3250
3317
|
rules.forEach(rule => {
|
|
3251
|
-
if (rule
|
|
3318
|
+
if (isTagRule(rule)) {
|
|
3252
3319
|
this.tags.push(rule);
|
|
3253
|
-
|
|
3320
|
+
}
|
|
3321
|
+
else if (isStyleRule(rule)) {
|
|
3322
|
+
let prop = /[^=]*/.exec(rule.style)[0];
|
|
3323
|
+
if (matchedStyles.indexOf(prop) < 0)
|
|
3324
|
+
matchedStyles.push(prop);
|
|
3254
3325
|
this.styles.push(rule);
|
|
3326
|
+
}
|
|
3255
3327
|
});
|
|
3256
3328
|
// Only normalize list elements when lists in the schema can't directly contain themselves
|
|
3257
3329
|
this.normalizeLists = !this.tags.some(r => {
|
|
@@ -3266,7 +3338,7 @@ class DOMParser {
|
|
|
3266
3338
|
*/
|
|
3267
3339
|
parse(dom, options = {}) {
|
|
3268
3340
|
let context = new ParseContext(this, options, false);
|
|
3269
|
-
context.addAll(dom, options.from, options.to);
|
|
3341
|
+
context.addAll(dom, Mark.none, options.from, options.to);
|
|
3270
3342
|
return context.finish();
|
|
3271
3343
|
}
|
|
3272
3344
|
/**
|
|
@@ -3279,7 +3351,7 @@ class DOMParser {
|
|
|
3279
3351
|
*/
|
|
3280
3352
|
parseSlice(dom, options = {}) {
|
|
3281
3353
|
let context = new ParseContext(this, options, true);
|
|
3282
|
-
context.addAll(dom, options.from, options.to);
|
|
3354
|
+
context.addAll(dom, Mark.none, options.from, options.to);
|
|
3283
3355
|
return Slice.maxOpen(context.finish());
|
|
3284
3356
|
}
|
|
3285
3357
|
/**
|
|
@@ -3388,22 +3460,15 @@ function wsOptionsFor(type, preserveWhitespace, base) {
|
|
|
3388
3460
|
return type && type.whitespace == "pre" ? OPT_PRESERVE_WS | OPT_PRESERVE_WS_FULL : base & ~OPT_OPEN_LEFT;
|
|
3389
3461
|
}
|
|
3390
3462
|
class NodeContext {
|
|
3391
|
-
constructor(type, attrs,
|
|
3392
|
-
// Marks applied to this node itself
|
|
3393
|
-
marks,
|
|
3394
|
-
// Marks that can't apply here, but will be used in children if possible
|
|
3395
|
-
pendingMarks, solid, match, options) {
|
|
3463
|
+
constructor(type, attrs, marks, solid, match, options) {
|
|
3396
3464
|
this.type = type;
|
|
3397
3465
|
this.attrs = attrs;
|
|
3398
3466
|
this.marks = marks;
|
|
3399
|
-
this.pendingMarks = pendingMarks;
|
|
3400
3467
|
this.solid = solid;
|
|
3401
3468
|
this.options = options;
|
|
3402
3469
|
this.content = [];
|
|
3403
3470
|
// Marks applied to the node's children
|
|
3404
3471
|
this.activeMarks = Mark.none;
|
|
3405
|
-
// Nested Marks with same type
|
|
3406
|
-
this.stashMarks = [];
|
|
3407
3472
|
this.match = match || (options & OPT_OPEN_LEFT ? null : type.contentMatch);
|
|
3408
3473
|
}
|
|
3409
3474
|
findWrapping(node) {
|
|
@@ -3443,21 +3508,6 @@ class NodeContext {
|
|
|
3443
3508
|
content = content.append(this.match.fillBefore(Fragment.empty, true));
|
|
3444
3509
|
return this.type ? this.type.create(this.attrs, content, this.marks) : content;
|
|
3445
3510
|
}
|
|
3446
|
-
popFromStashMark(mark) {
|
|
3447
|
-
for (let i = this.stashMarks.length - 1; i >= 0; i--)
|
|
3448
|
-
if (mark.eq(this.stashMarks[i]))
|
|
3449
|
-
return this.stashMarks.splice(i, 1)[0];
|
|
3450
|
-
}
|
|
3451
|
-
applyPending(nextType) {
|
|
3452
|
-
for (let i = 0, pending = this.pendingMarks; i < pending.length; i++) {
|
|
3453
|
-
let mark = pending[i];
|
|
3454
|
-
if ((this.type ? this.type.allowsMarkType(mark.type) : markMayApply(mark.type, nextType)) &&
|
|
3455
|
-
!mark.isInSet(this.activeMarks)) {
|
|
3456
|
-
this.activeMarks = mark.addToSet(this.activeMarks);
|
|
3457
|
-
this.pendingMarks = mark.removeFromSet(this.pendingMarks);
|
|
3458
|
-
}
|
|
3459
|
-
}
|
|
3460
|
-
}
|
|
3461
3511
|
inlineContext(node) {
|
|
3462
3512
|
if (this.type)
|
|
3463
3513
|
return this.type.inlineContent;
|
|
@@ -3479,11 +3529,11 @@ class ParseContext {
|
|
|
3479
3529
|
let topNode = options.topNode, topContext;
|
|
3480
3530
|
let topOptions = wsOptionsFor(null, options.preserveWhitespace, 0) | (isOpen ? OPT_OPEN_LEFT : 0);
|
|
3481
3531
|
if (topNode)
|
|
3482
|
-
topContext = new NodeContext(topNode.type, topNode.attrs, Mark.none,
|
|
3532
|
+
topContext = new NodeContext(topNode.type, topNode.attrs, Mark.none, true, options.topMatch || topNode.type.contentMatch, topOptions);
|
|
3483
3533
|
else if (isOpen)
|
|
3484
|
-
topContext = new NodeContext(null, null, Mark.none,
|
|
3534
|
+
topContext = new NodeContext(null, null, Mark.none, true, null, topOptions);
|
|
3485
3535
|
else
|
|
3486
|
-
topContext = new NodeContext(parser.schema.topNodeType, null, Mark.none,
|
|
3536
|
+
topContext = new NodeContext(parser.schema.topNodeType, null, Mark.none, true, null, topOptions);
|
|
3487
3537
|
this.nodes = [topContext];
|
|
3488
3538
|
this.find = options.findPositions;
|
|
3489
3539
|
this.needsBlock = false;
|
|
@@ -3494,31 +3544,13 @@ class ParseContext {
|
|
|
3494
3544
|
// Add a DOM node to the content. Text is inserted as text node,
|
|
3495
3545
|
// otherwise, the node is passed to `addElement` or, if it has a
|
|
3496
3546
|
// `style` attribute, `addElementWithStyles`.
|
|
3497
|
-
addDOM(dom) {
|
|
3547
|
+
addDOM(dom, marks) {
|
|
3498
3548
|
if (dom.nodeType == 3)
|
|
3499
|
-
this.addTextNode(dom);
|
|
3549
|
+
this.addTextNode(dom, marks);
|
|
3500
3550
|
else if (dom.nodeType == 1)
|
|
3501
|
-
this.addElement(dom);
|
|
3502
|
-
}
|
|
3503
|
-
withStyleRules(dom, f) {
|
|
3504
|
-
let style = dom.getAttribute("style");
|
|
3505
|
-
if (!style)
|
|
3506
|
-
return f();
|
|
3507
|
-
let marks = this.readStyles(parseStyles(style));
|
|
3508
|
-
if (!marks)
|
|
3509
|
-
return; // A style with ignore: true
|
|
3510
|
-
let [addMarks, removeMarks] = marks, top = this.top;
|
|
3511
|
-
for (let i = 0; i < removeMarks.length; i++)
|
|
3512
|
-
this.removePendingMark(removeMarks[i], top);
|
|
3513
|
-
for (let i = 0; i < addMarks.length; i++)
|
|
3514
|
-
this.addPendingMark(addMarks[i]);
|
|
3515
|
-
f();
|
|
3516
|
-
for (let i = 0; i < addMarks.length; i++)
|
|
3517
|
-
this.removePendingMark(addMarks[i], top);
|
|
3518
|
-
for (let i = 0; i < removeMarks.length; i++)
|
|
3519
|
-
this.addPendingMark(removeMarks[i]);
|
|
3551
|
+
this.addElement(dom, marks);
|
|
3520
3552
|
}
|
|
3521
|
-
addTextNode(dom) {
|
|
3553
|
+
addTextNode(dom, marks) {
|
|
3522
3554
|
let value = dom.nodeValue;
|
|
3523
3555
|
let top = this.top;
|
|
3524
3556
|
if (top.options & OPT_PRESERVE_WS_FULL ||
|
|
@@ -3545,7 +3577,7 @@ class ParseContext {
|
|
|
3545
3577
|
value = value.replace(/\r\n?/g, "\n");
|
|
3546
3578
|
}
|
|
3547
3579
|
if (value)
|
|
3548
|
-
this.insertNode(this.parser.schema.text(value));
|
|
3580
|
+
this.insertNode(this.parser.schema.text(value), marks);
|
|
3549
3581
|
this.findInText(dom);
|
|
3550
3582
|
}
|
|
3551
3583
|
else {
|
|
@@ -3554,7 +3586,7 @@ class ParseContext {
|
|
|
3554
3586
|
}
|
|
3555
3587
|
// Try to find a handler for the given tag and use that to parse. If
|
|
3556
3588
|
// none is found, the element's content nodes are added directly.
|
|
3557
|
-
addElement(dom, matchAfter) {
|
|
3589
|
+
addElement(dom, marks, matchAfter) {
|
|
3558
3590
|
let name = dom.nodeName.toLowerCase(), ruleID;
|
|
3559
3591
|
if (listTags.hasOwnProperty(name) && this.parser.normalizeLists)
|
|
3560
3592
|
normalizeList(dom);
|
|
@@ -3562,7 +3594,7 @@ class ParseContext {
|
|
|
3562
3594
|
(ruleID = this.parser.matchTag(dom, this, matchAfter));
|
|
3563
3595
|
if (rule ? rule.ignore : ignoreTags.hasOwnProperty(name)) {
|
|
3564
3596
|
this.findInside(dom);
|
|
3565
|
-
this.ignoreFallback(dom);
|
|
3597
|
+
this.ignoreFallback(dom, marks);
|
|
3566
3598
|
}
|
|
3567
3599
|
else if (!rule || rule.skip || rule.closeParent) {
|
|
3568
3600
|
if (rule && rule.closeParent)
|
|
@@ -3580,92 +3612,97 @@ class ParseContext {
|
|
|
3580
3612
|
this.needsBlock = true;
|
|
3581
3613
|
}
|
|
3582
3614
|
else if (!dom.firstChild) {
|
|
3583
|
-
this.leafFallback(dom);
|
|
3615
|
+
this.leafFallback(dom, marks);
|
|
3584
3616
|
return;
|
|
3585
3617
|
}
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
this.withStyleRules(dom, () => this.addAll(dom));
|
|
3618
|
+
let innerMarks = rule && rule.skip ? marks : this.readStyles(dom, marks);
|
|
3619
|
+
if (innerMarks)
|
|
3620
|
+
this.addAll(dom, innerMarks);
|
|
3590
3621
|
if (sync)
|
|
3591
3622
|
this.sync(top);
|
|
3592
3623
|
this.needsBlock = oldNeedsBlock;
|
|
3593
3624
|
}
|
|
3594
3625
|
else {
|
|
3595
|
-
this.
|
|
3596
|
-
|
|
3597
|
-
|
|
3626
|
+
let innerMarks = this.readStyles(dom, marks);
|
|
3627
|
+
if (innerMarks)
|
|
3628
|
+
this.addElementByRule(dom, rule, innerMarks, rule.consuming === false ? ruleID : undefined);
|
|
3598
3629
|
}
|
|
3599
3630
|
}
|
|
3600
3631
|
// Called for leaf DOM nodes that would otherwise be ignored
|
|
3601
|
-
leafFallback(dom) {
|
|
3632
|
+
leafFallback(dom, marks) {
|
|
3602
3633
|
if (dom.nodeName == "BR" && this.top.type && this.top.type.inlineContent)
|
|
3603
|
-
this.addTextNode(dom.ownerDocument.createTextNode("\n"));
|
|
3634
|
+
this.addTextNode(dom.ownerDocument.createTextNode("\n"), marks);
|
|
3604
3635
|
}
|
|
3605
3636
|
// Called for ignored nodes
|
|
3606
|
-
ignoreFallback(dom) {
|
|
3637
|
+
ignoreFallback(dom, marks) {
|
|
3607
3638
|
// Ignored BR nodes should at least create an inline context
|
|
3608
3639
|
if (dom.nodeName == "BR" && (!this.top.type || !this.top.type.inlineContent))
|
|
3609
|
-
this.findPlace(this.parser.schema.text("-"));
|
|
3640
|
+
this.findPlace(this.parser.schema.text("-"), marks);
|
|
3610
3641
|
}
|
|
3611
3642
|
// Run any style parser associated with the node's styles. Either
|
|
3612
|
-
// return an array of marks, or null to indicate some of the
|
|
3613
|
-
// had a rule with `ignore` set.
|
|
3614
|
-
readStyles(
|
|
3615
|
-
let
|
|
3616
|
-
|
|
3617
|
-
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
|
|
3629
|
-
|
|
3630
|
-
|
|
3631
|
-
|
|
3632
|
-
|
|
3633
|
-
|
|
3634
|
-
|
|
3635
|
-
|
|
3643
|
+
// return an updated array of marks, or null to indicate some of the
|
|
3644
|
+
// styles had a rule with `ignore` set.
|
|
3645
|
+
readStyles(dom, marks) {
|
|
3646
|
+
let styles = dom.style;
|
|
3647
|
+
// Because many properties will only show up in 'normalized' form
|
|
3648
|
+
// in `style.item` (i.e. text-decoration becomes
|
|
3649
|
+
// text-decoration-line, text-decoration-color, etc), we directly
|
|
3650
|
+
// query the styles mentioned in our rules instead of iterating
|
|
3651
|
+
// over the items.
|
|
3652
|
+
if (styles && styles.length)
|
|
3653
|
+
for (let i = 0; i < this.parser.matchedStyles.length; i++) {
|
|
3654
|
+
let name = this.parser.matchedStyles[i], value = styles.getPropertyValue(name);
|
|
3655
|
+
if (value)
|
|
3656
|
+
for (let after = undefined;;) {
|
|
3657
|
+
let rule = this.parser.matchStyle(name, value, this, after);
|
|
3658
|
+
if (!rule)
|
|
3659
|
+
break;
|
|
3660
|
+
if (rule.ignore)
|
|
3661
|
+
return null;
|
|
3662
|
+
if (rule.clearMark)
|
|
3663
|
+
marks = marks.filter(m => !rule.clearMark(m));
|
|
3664
|
+
else
|
|
3665
|
+
marks = marks.concat(this.parser.schema.marks[rule.mark].create(rule.attrs));
|
|
3666
|
+
if (rule.consuming === false)
|
|
3667
|
+
after = rule;
|
|
3668
|
+
else
|
|
3669
|
+
break;
|
|
3670
|
+
}
|
|
3636
3671
|
}
|
|
3637
|
-
|
|
3638
|
-
return [add, remove];
|
|
3672
|
+
return marks;
|
|
3639
3673
|
}
|
|
3640
3674
|
// Look up a handler for the given node. If none are found, return
|
|
3641
3675
|
// false. Otherwise, apply it, use its return value to drive the way
|
|
3642
3676
|
// the node's content is wrapped, and return true.
|
|
3643
|
-
addElementByRule(dom, rule, continueAfter) {
|
|
3644
|
-
let sync, nodeType
|
|
3677
|
+
addElementByRule(dom, rule, marks, continueAfter) {
|
|
3678
|
+
let sync, nodeType;
|
|
3645
3679
|
if (rule.node) {
|
|
3646
3680
|
nodeType = this.parser.schema.nodes[rule.node];
|
|
3647
3681
|
if (!nodeType.isLeaf) {
|
|
3648
|
-
|
|
3682
|
+
let inner = this.enter(nodeType, rule.attrs || null, marks, rule.preserveWhitespace);
|
|
3683
|
+
if (inner) {
|
|
3684
|
+
sync = true;
|
|
3685
|
+
marks = inner;
|
|
3686
|
+
}
|
|
3649
3687
|
}
|
|
3650
|
-
else if (!this.insertNode(nodeType.create(rule.attrs))) {
|
|
3651
|
-
this.leafFallback(dom);
|
|
3688
|
+
else if (!this.insertNode(nodeType.create(rule.attrs), marks)) {
|
|
3689
|
+
this.leafFallback(dom, marks);
|
|
3652
3690
|
}
|
|
3653
3691
|
}
|
|
3654
3692
|
else {
|
|
3655
3693
|
let markType = this.parser.schema.marks[rule.mark];
|
|
3656
|
-
|
|
3657
|
-
this.addPendingMark(mark);
|
|
3694
|
+
marks = marks.concat(markType.create(rule.attrs));
|
|
3658
3695
|
}
|
|
3659
3696
|
let startIn = this.top;
|
|
3660
3697
|
if (nodeType && nodeType.isLeaf) {
|
|
3661
3698
|
this.findInside(dom);
|
|
3662
3699
|
}
|
|
3663
3700
|
else if (continueAfter) {
|
|
3664
|
-
this.addElement(dom, continueAfter);
|
|
3701
|
+
this.addElement(dom, marks, continueAfter);
|
|
3665
3702
|
}
|
|
3666
3703
|
else if (rule.getContent) {
|
|
3667
3704
|
this.findInside(dom);
|
|
3668
|
-
rule.getContent(dom, this.parser.schema).forEach(node => this.insertNode(node));
|
|
3705
|
+
rule.getContent(dom, this.parser.schema).forEach(node => this.insertNode(node, marks));
|
|
3669
3706
|
}
|
|
3670
3707
|
else {
|
|
3671
3708
|
let contentDOM = dom;
|
|
@@ -3676,28 +3713,26 @@ class ParseContext {
|
|
|
3676
3713
|
else if (rule.contentElement)
|
|
3677
3714
|
contentDOM = rule.contentElement;
|
|
3678
3715
|
this.findAround(dom, contentDOM, true);
|
|
3679
|
-
this.addAll(contentDOM);
|
|
3716
|
+
this.addAll(contentDOM, marks);
|
|
3680
3717
|
}
|
|
3681
3718
|
if (sync && this.sync(startIn))
|
|
3682
3719
|
this.open--;
|
|
3683
|
-
if (mark)
|
|
3684
|
-
this.removePendingMark(mark, startIn);
|
|
3685
3720
|
}
|
|
3686
3721
|
// Add all child nodes between `startIndex` and `endIndex` (or the
|
|
3687
3722
|
// whole node, if not given). If `sync` is passed, use it to
|
|
3688
3723
|
// synchronize after every block element.
|
|
3689
|
-
addAll(parent, startIndex, endIndex) {
|
|
3724
|
+
addAll(parent, marks, startIndex, endIndex) {
|
|
3690
3725
|
let index = startIndex || 0;
|
|
3691
3726
|
for (let dom = startIndex ? parent.childNodes[startIndex] : parent.firstChild, end = endIndex == null ? null : parent.childNodes[endIndex]; dom != end; dom = dom.nextSibling, ++index) {
|
|
3692
3727
|
this.findAtPoint(parent, index);
|
|
3693
|
-
this.addDOM(dom);
|
|
3728
|
+
this.addDOM(dom, marks);
|
|
3694
3729
|
}
|
|
3695
3730
|
this.findAtPoint(parent, index);
|
|
3696
3731
|
}
|
|
3697
3732
|
// Try to find a way to fit the given node type into the current
|
|
3698
3733
|
// context. May add intermediate wrappers and/or leave non-solid
|
|
3699
3734
|
// nodes that we're in.
|
|
3700
|
-
findPlace(node) {
|
|
3735
|
+
findPlace(node, marks) {
|
|
3701
3736
|
let route, sync;
|
|
3702
3737
|
for (let depth = this.open; depth >= 0; depth--) {
|
|
3703
3738
|
let cx = this.nodes[depth];
|
|
@@ -3712,53 +3747,61 @@ class ParseContext {
|
|
|
3712
3747
|
break;
|
|
3713
3748
|
}
|
|
3714
3749
|
if (!route)
|
|
3715
|
-
return
|
|
3750
|
+
return null;
|
|
3716
3751
|
this.sync(sync);
|
|
3717
3752
|
for (let i = 0; i < route.length; i++)
|
|
3718
|
-
this.enterInner(route[i], null, false);
|
|
3719
|
-
return
|
|
3753
|
+
marks = this.enterInner(route[i], null, marks, false);
|
|
3754
|
+
return marks;
|
|
3720
3755
|
}
|
|
3721
3756
|
// Try to insert the given node, adjusting the context when needed.
|
|
3722
|
-
insertNode(node) {
|
|
3757
|
+
insertNode(node, marks) {
|
|
3723
3758
|
if (node.isInline && this.needsBlock && !this.top.type) {
|
|
3724
3759
|
let block = this.textblockFromContext();
|
|
3725
3760
|
if (block)
|
|
3726
|
-
this.enterInner(block);
|
|
3761
|
+
marks = this.enterInner(block, null, marks);
|
|
3727
3762
|
}
|
|
3728
|
-
|
|
3763
|
+
let innerMarks = this.findPlace(node, marks);
|
|
3764
|
+
if (innerMarks) {
|
|
3729
3765
|
this.closeExtra();
|
|
3730
3766
|
let top = this.top;
|
|
3731
|
-
top.applyPending(node.type);
|
|
3732
3767
|
if (top.match)
|
|
3733
3768
|
top.match = top.match.matchType(node.type);
|
|
3734
|
-
let
|
|
3735
|
-
for (let
|
|
3736
|
-
if (
|
|
3737
|
-
|
|
3738
|
-
top.content.push(node.mark(
|
|
3769
|
+
let nodeMarks = Mark.none;
|
|
3770
|
+
for (let m of innerMarks.concat(node.marks))
|
|
3771
|
+
if (top.type ? top.type.allowsMarkType(m.type) : markMayApply(m.type, node.type))
|
|
3772
|
+
nodeMarks = m.addToSet(nodeMarks);
|
|
3773
|
+
top.content.push(node.mark(nodeMarks));
|
|
3739
3774
|
return true;
|
|
3740
3775
|
}
|
|
3741
3776
|
return false;
|
|
3742
3777
|
}
|
|
3743
3778
|
// Try to start a node of the given type, adjusting the context when
|
|
3744
3779
|
// necessary.
|
|
3745
|
-
enter(type, attrs, preserveWS) {
|
|
3746
|
-
let
|
|
3747
|
-
if (
|
|
3748
|
-
this.enterInner(type, attrs, true, preserveWS);
|
|
3749
|
-
return
|
|
3780
|
+
enter(type, attrs, marks, preserveWS) {
|
|
3781
|
+
let innerMarks = this.findPlace(type.create(attrs), marks);
|
|
3782
|
+
if (innerMarks)
|
|
3783
|
+
innerMarks = this.enterInner(type, attrs, marks, true, preserveWS);
|
|
3784
|
+
return innerMarks;
|
|
3750
3785
|
}
|
|
3751
3786
|
// Open a node of the given type
|
|
3752
|
-
enterInner(type, attrs
|
|
3787
|
+
enterInner(type, attrs, marks, solid = false, preserveWS) {
|
|
3753
3788
|
this.closeExtra();
|
|
3754
3789
|
let top = this.top;
|
|
3755
|
-
top.applyPending(type);
|
|
3756
3790
|
top.match = top.match && top.match.matchType(type);
|
|
3757
3791
|
let options = wsOptionsFor(type, preserveWS, top.options);
|
|
3758
3792
|
if ((top.options & OPT_OPEN_LEFT) && top.content.length == 0)
|
|
3759
3793
|
options |= OPT_OPEN_LEFT;
|
|
3760
|
-
|
|
3794
|
+
let applyMarks = Mark.none;
|
|
3795
|
+
marks = marks.filter(m => {
|
|
3796
|
+
if (top.type ? top.type.allowsMarkType(m.type) : markMayApply(m.type, type)) {
|
|
3797
|
+
applyMarks = m.addToSet(applyMarks);
|
|
3798
|
+
return false;
|
|
3799
|
+
}
|
|
3800
|
+
return true;
|
|
3801
|
+
});
|
|
3802
|
+
this.nodes.push(new NodeContext(type, attrs, applyMarks, solid, null, options));
|
|
3761
3803
|
this.open++;
|
|
3804
|
+
return marks;
|
|
3762
3805
|
}
|
|
3763
3806
|
// Make sure all nodes above this.open are finished and added to
|
|
3764
3807
|
// their parents
|
|
@@ -3872,29 +3915,6 @@ class ParseContext {
|
|
|
3872
3915
|
return type;
|
|
3873
3916
|
}
|
|
3874
3917
|
}
|
|
3875
|
-
addPendingMark(mark) {
|
|
3876
|
-
let found = findSameMarkInSet(mark, this.top.pendingMarks);
|
|
3877
|
-
if (found)
|
|
3878
|
-
this.top.stashMarks.push(found);
|
|
3879
|
-
this.top.pendingMarks = mark.addToSet(this.top.pendingMarks);
|
|
3880
|
-
}
|
|
3881
|
-
removePendingMark(mark, upto) {
|
|
3882
|
-
for (let depth = this.open; depth >= 0; depth--) {
|
|
3883
|
-
let level = this.nodes[depth];
|
|
3884
|
-
let found = level.pendingMarks.lastIndexOf(mark);
|
|
3885
|
-
if (found > -1) {
|
|
3886
|
-
level.pendingMarks = mark.removeFromSet(level.pendingMarks);
|
|
3887
|
-
}
|
|
3888
|
-
else {
|
|
3889
|
-
level.activeMarks = mark.removeFromSet(level.activeMarks);
|
|
3890
|
-
let stashMark = level.popFromStashMark(mark);
|
|
3891
|
-
if (stashMark && level.type && level.type.allowsMarkType(stashMark.type))
|
|
3892
|
-
level.activeMarks = stashMark.addToSet(level.activeMarks);
|
|
3893
|
-
}
|
|
3894
|
-
if (level == upto)
|
|
3895
|
-
break;
|
|
3896
|
-
}
|
|
3897
|
-
}
|
|
3898
3918
|
}
|
|
3899
3919
|
// Kludge to work around directly nested list nodes produced by some
|
|
3900
3920
|
// tools and allowed by browsers to mean that the nested list is
|
|
@@ -3918,13 +3938,6 @@ function normalizeList(dom) {
|
|
|
3918
3938
|
function matches(dom, selector) {
|
|
3919
3939
|
return (dom.matches || dom.msMatchesSelector || dom.webkitMatchesSelector || dom.mozMatchesSelector).call(dom, selector);
|
|
3920
3940
|
}
|
|
3921
|
-
// Tokenize a style attribute into property/value pairs.
|
|
3922
|
-
function parseStyles(style) {
|
|
3923
|
-
let re = /\s*([\w-]+)\s*:\s*([^;]+)/g, m, result = [];
|
|
3924
|
-
while (m = re.exec(style))
|
|
3925
|
-
result.push(m[1], m[2].trim());
|
|
3926
|
-
return result;
|
|
3927
|
-
}
|
|
3928
3941
|
function copy(obj) {
|
|
3929
3942
|
let copy = {};
|
|
3930
3943
|
for (let prop in obj)
|
|
@@ -3954,12 +3967,6 @@ function markMayApply(markType, nodeType) {
|
|
|
3954
3967
|
return true;
|
|
3955
3968
|
}
|
|
3956
3969
|
}
|
|
3957
|
-
function findSameMarkInSet(mark, set) {
|
|
3958
|
-
for (let i = 0; i < set.length; i++) {
|
|
3959
|
-
if (mark.eq(set[i]))
|
|
3960
|
-
return set[i];
|
|
3961
|
-
}
|
|
3962
|
-
}
|
|
3963
3970
|
|
|
3964
3971
|
/**
|
|
3965
3972
|
A DOM serializer knows how to convert ProseMirror nodes and
|
|
@@ -4031,7 +4038,7 @@ class DOMSerializer {
|
|
|
4031
4038
|
@internal
|
|
4032
4039
|
*/
|
|
4033
4040
|
serializeNodeInner(node, options) {
|
|
4034
|
-
let { dom, contentDOM } =
|
|
4041
|
+
let { dom, contentDOM } = renderSpec(doc$1(options), this.nodes[node.type.name](node), null, node.attrs);
|
|
4035
4042
|
if (contentDOM) {
|
|
4036
4043
|
if (node.isLeaf)
|
|
4037
4044
|
throw new RangeError("Content hole not allowed in a leaf node spec");
|
|
@@ -4062,57 +4069,10 @@ class DOMSerializer {
|
|
|
4062
4069
|
*/
|
|
4063
4070
|
serializeMark(mark, inline, options = {}) {
|
|
4064
4071
|
let toDOM = this.marks[mark.type.name];
|
|
4065
|
-
return toDOM &&
|
|
4066
|
-
}
|
|
4067
|
-
|
|
4068
|
-
|
|
4069
|
-
the spec has a hole (zero) in it, `contentDOM` will point at the
|
|
4070
|
-
node with the hole.
|
|
4071
|
-
*/
|
|
4072
|
-
static renderSpec(doc, structure, xmlNS = null) {
|
|
4073
|
-
if (typeof structure == "string")
|
|
4074
|
-
return { dom: doc.createTextNode(structure) };
|
|
4075
|
-
if (structure.nodeType != null)
|
|
4076
|
-
return { dom: structure };
|
|
4077
|
-
if (structure.dom && structure.dom.nodeType != null)
|
|
4078
|
-
return structure;
|
|
4079
|
-
let tagName = structure[0], space = tagName.indexOf(" ");
|
|
4080
|
-
if (space > 0) {
|
|
4081
|
-
xmlNS = tagName.slice(0, space);
|
|
4082
|
-
tagName = tagName.slice(space + 1);
|
|
4083
|
-
}
|
|
4084
|
-
let contentDOM;
|
|
4085
|
-
let dom = (xmlNS ? doc.createElementNS(xmlNS, tagName) : doc.createElement(tagName));
|
|
4086
|
-
let attrs = structure[1], start = 1;
|
|
4087
|
-
if (attrs && typeof attrs == "object" && attrs.nodeType == null && !Array.isArray(attrs)) {
|
|
4088
|
-
start = 2;
|
|
4089
|
-
for (let name in attrs)
|
|
4090
|
-
if (attrs[name] != null) {
|
|
4091
|
-
let space = name.indexOf(" ");
|
|
4092
|
-
if (space > 0)
|
|
4093
|
-
dom.setAttributeNS(name.slice(0, space), name.slice(space + 1), attrs[name]);
|
|
4094
|
-
else
|
|
4095
|
-
dom.setAttribute(name, attrs[name]);
|
|
4096
|
-
}
|
|
4097
|
-
}
|
|
4098
|
-
for (let i = start; i < structure.length; i++) {
|
|
4099
|
-
let child = structure[i];
|
|
4100
|
-
if (child === 0) {
|
|
4101
|
-
if (i < structure.length - 1 || i > start)
|
|
4102
|
-
throw new RangeError("Content hole must be the only child of its parent node");
|
|
4103
|
-
return { dom, contentDOM: dom };
|
|
4104
|
-
}
|
|
4105
|
-
else {
|
|
4106
|
-
let { dom: inner, contentDOM: innerContent } = DOMSerializer.renderSpec(doc, child, xmlNS);
|
|
4107
|
-
dom.appendChild(inner);
|
|
4108
|
-
if (innerContent) {
|
|
4109
|
-
if (contentDOM)
|
|
4110
|
-
throw new RangeError("Multiple content holes");
|
|
4111
|
-
contentDOM = innerContent;
|
|
4112
|
-
}
|
|
4113
|
-
}
|
|
4114
|
-
}
|
|
4115
|
-
return { dom, contentDOM };
|
|
4072
|
+
return toDOM && renderSpec(doc$1(options), toDOM(mark, inline), null, mark.attrs);
|
|
4073
|
+
}
|
|
4074
|
+
static renderSpec(doc, structure, xmlNS = null, blockArraysIn) {
|
|
4075
|
+
return renderSpec(doc, structure, xmlNS, blockArraysIn);
|
|
4116
4076
|
}
|
|
4117
4077
|
/**
|
|
4118
4078
|
Build a serializer using the [`toDOM`](https://prosemirror.net/docs/ref/#model.NodeSpec.toDOM)
|
|
@@ -4151,6 +4111,88 @@ function gatherToDOM(obj) {
|
|
|
4151
4111
|
function doc$1(options) {
|
|
4152
4112
|
return options.document || window.document;
|
|
4153
4113
|
}
|
|
4114
|
+
const suspiciousAttributeCache = new WeakMap();
|
|
4115
|
+
function suspiciousAttributes(attrs) {
|
|
4116
|
+
let value = suspiciousAttributeCache.get(attrs);
|
|
4117
|
+
if (value === undefined)
|
|
4118
|
+
suspiciousAttributeCache.set(attrs, value = suspiciousAttributesInner(attrs));
|
|
4119
|
+
return value;
|
|
4120
|
+
}
|
|
4121
|
+
function suspiciousAttributesInner(attrs) {
|
|
4122
|
+
let result = null;
|
|
4123
|
+
function scan(value) {
|
|
4124
|
+
if (value && typeof value == "object") {
|
|
4125
|
+
if (Array.isArray(value)) {
|
|
4126
|
+
if (typeof value[0] == "string") {
|
|
4127
|
+
if (!result)
|
|
4128
|
+
result = [];
|
|
4129
|
+
result.push(value);
|
|
4130
|
+
}
|
|
4131
|
+
else {
|
|
4132
|
+
for (let i = 0; i < value.length; i++)
|
|
4133
|
+
scan(value[i]);
|
|
4134
|
+
}
|
|
4135
|
+
}
|
|
4136
|
+
else {
|
|
4137
|
+
for (let prop in value)
|
|
4138
|
+
scan(value[prop]);
|
|
4139
|
+
}
|
|
4140
|
+
}
|
|
4141
|
+
}
|
|
4142
|
+
scan(attrs);
|
|
4143
|
+
return result;
|
|
4144
|
+
}
|
|
4145
|
+
function renderSpec(doc, structure, xmlNS, blockArraysIn) {
|
|
4146
|
+
if (typeof structure == "string")
|
|
4147
|
+
return { dom: doc.createTextNode(structure) };
|
|
4148
|
+
if (structure.nodeType != null)
|
|
4149
|
+
return { dom: structure };
|
|
4150
|
+
if (structure.dom && structure.dom.nodeType != null)
|
|
4151
|
+
return structure;
|
|
4152
|
+
let tagName = structure[0], suspicious;
|
|
4153
|
+
if (typeof tagName != "string")
|
|
4154
|
+
throw new RangeError("Invalid array passed to renderSpec");
|
|
4155
|
+
if (blockArraysIn && (suspicious = suspiciousAttributes(blockArraysIn)) &&
|
|
4156
|
+
suspicious.indexOf(structure) > -1)
|
|
4157
|
+
throw new RangeError("Using an array from an attribute object as a DOM spec. This may be an attempted cross site scripting attack.");
|
|
4158
|
+
let space = tagName.indexOf(" ");
|
|
4159
|
+
if (space > 0) {
|
|
4160
|
+
xmlNS = tagName.slice(0, space);
|
|
4161
|
+
tagName = tagName.slice(space + 1);
|
|
4162
|
+
}
|
|
4163
|
+
let contentDOM;
|
|
4164
|
+
let dom = (xmlNS ? doc.createElementNS(xmlNS, tagName) : doc.createElement(tagName));
|
|
4165
|
+
let attrs = structure[1], start = 1;
|
|
4166
|
+
if (attrs && typeof attrs == "object" && attrs.nodeType == null && !Array.isArray(attrs)) {
|
|
4167
|
+
start = 2;
|
|
4168
|
+
for (let name in attrs)
|
|
4169
|
+
if (attrs[name] != null) {
|
|
4170
|
+
let space = name.indexOf(" ");
|
|
4171
|
+
if (space > 0)
|
|
4172
|
+
dom.setAttributeNS(name.slice(0, space), name.slice(space + 1), attrs[name]);
|
|
4173
|
+
else
|
|
4174
|
+
dom.setAttribute(name, attrs[name]);
|
|
4175
|
+
}
|
|
4176
|
+
}
|
|
4177
|
+
for (let i = start; i < structure.length; i++) {
|
|
4178
|
+
let child = structure[i];
|
|
4179
|
+
if (child === 0) {
|
|
4180
|
+
if (i < structure.length - 1 || i > start)
|
|
4181
|
+
throw new RangeError("Content hole must be the only child of its parent node");
|
|
4182
|
+
return { dom, contentDOM: dom };
|
|
4183
|
+
}
|
|
4184
|
+
else {
|
|
4185
|
+
let { dom: inner, contentDOM: innerContent } = renderSpec(doc, child, xmlNS, blockArraysIn);
|
|
4186
|
+
dom.appendChild(inner);
|
|
4187
|
+
if (innerContent) {
|
|
4188
|
+
if (contentDOM)
|
|
4189
|
+
throw new RangeError("Multiple content holes");
|
|
4190
|
+
contentDOM = innerContent;
|
|
4191
|
+
}
|
|
4192
|
+
}
|
|
4193
|
+
}
|
|
4194
|
+
return { dom, contentDOM };
|
|
4195
|
+
}
|
|
4154
4196
|
|
|
4155
4197
|
// Recovery values encode a range index and an offset. They are
|
|
4156
4198
|
// represented as numbers, because tons of them will be created when
|
|
@@ -24871,9 +24913,9 @@ const schema = new Schema({
|
|
|
24871
24913
|
strong: {
|
|
24872
24914
|
parseDOM: [
|
|
24873
24915
|
{ tag: "strong" },
|
|
24874
|
-
{ tag: "b", getAttrs:
|
|
24916
|
+
{ tag: "b", getAttrs: node => node.style.fontWeight != "normal" && null },
|
|
24875
24917
|
{ style: "font-weight=400", clearMark: m => m.type.name == "strong" },
|
|
24876
|
-
{ style: "font-weight", getAttrs:
|
|
24918
|
+
{ style: "font-weight", getAttrs: value => /^(bold(er)?|[5-9]\d{2,})$/.test(value) && null }
|
|
24877
24919
|
],
|
|
24878
24920
|
toDOM() { return ["strong"]; }
|
|
24879
24921
|
},
|
|
@@ -25127,6 +25169,7 @@ new MarkdownParser(schema, MarkdownIt("commonmark", { html: false }), {
|
|
|
25127
25169
|
code_inline: { mark: "code", noCloseToken: true }
|
|
25128
25170
|
});
|
|
25129
25171
|
|
|
25172
|
+
const blankMark = { open: "", close: "", mixable: true };
|
|
25130
25173
|
/**
|
|
25131
25174
|
A specification for serializing a ProseMirror document as
|
|
25132
25175
|
Markdown/CommonMark text.
|
|
@@ -25334,6 +25377,18 @@ class MarkdownSerializerState {
|
|
|
25334
25377
|
}
|
|
25335
25378
|
}
|
|
25336
25379
|
/**
|
|
25380
|
+
@internal
|
|
25381
|
+
*/
|
|
25382
|
+
getMark(name) {
|
|
25383
|
+
let info = this.marks[name];
|
|
25384
|
+
if (!info) {
|
|
25385
|
+
if (this.options.strict !== false)
|
|
25386
|
+
throw new Error(`Mark type \`${name}\` not supported by Markdown renderer`);
|
|
25387
|
+
info = blankMark;
|
|
25388
|
+
}
|
|
25389
|
+
return info;
|
|
25390
|
+
}
|
|
25391
|
+
/**
|
|
25337
25392
|
Render a block, prefixing each line with `delim`, and the first
|
|
25338
25393
|
line in `firstDelim`. `node` should be the node that is closed at
|
|
25339
25394
|
the end of the block, and `f` is a function that renders the
|
|
@@ -25398,9 +25453,22 @@ class MarkdownSerializerState {
|
|
|
25398
25453
|
Render the given node as a block.
|
|
25399
25454
|
*/
|
|
25400
25455
|
render(node, parent, index) {
|
|
25401
|
-
if (
|
|
25402
|
-
|
|
25403
|
-
|
|
25456
|
+
if (this.nodes[node.type.name]) {
|
|
25457
|
+
this.nodes[node.type.name](this, node, parent, index);
|
|
25458
|
+
}
|
|
25459
|
+
else {
|
|
25460
|
+
if (this.options.strict !== false) {
|
|
25461
|
+
throw new Error("Token type `" + node.type.name + "` not supported by Markdown renderer");
|
|
25462
|
+
}
|
|
25463
|
+
else if (!node.type.isLeaf) {
|
|
25464
|
+
if (node.type.inlineContent)
|
|
25465
|
+
this.renderInline(node);
|
|
25466
|
+
else
|
|
25467
|
+
this.renderContent(node);
|
|
25468
|
+
if (node.isBlock)
|
|
25469
|
+
this.closeBlock(node);
|
|
25470
|
+
}
|
|
25471
|
+
}
|
|
25404
25472
|
}
|
|
25405
25473
|
/**
|
|
25406
25474
|
Render the contents of `parent` as block nodes.
|
|
@@ -25431,7 +25499,7 @@ class MarkdownSerializerState {
|
|
|
25431
25499
|
// If whitespace has to be expelled from the node, adjust
|
|
25432
25500
|
// leading and trailing accordingly.
|
|
25433
25501
|
if (node && node.isText && marks.some(mark => {
|
|
25434
|
-
let info = this.
|
|
25502
|
+
let info = this.getMark(mark.type.name);
|
|
25435
25503
|
return info && info.expelEnclosingWhitespace && !mark.isInSet(active);
|
|
25436
25504
|
})) {
|
|
25437
25505
|
let [_, lead, rest] = /^(\s*)(.*)$/m.exec(node.text);
|
|
@@ -25443,7 +25511,7 @@ class MarkdownSerializerState {
|
|
|
25443
25511
|
}
|
|
25444
25512
|
}
|
|
25445
25513
|
if (node && node.isText && marks.some(mark => {
|
|
25446
|
-
let info = this.
|
|
25514
|
+
let info = this.getMark(mark.type.name);
|
|
25447
25515
|
return info && info.expelEnclosingWhitespace &&
|
|
25448
25516
|
(index == parent.childCount - 1 || !mark.isInSet(parent.child(index + 1).marks));
|
|
25449
25517
|
})) {
|
|
@@ -25456,7 +25524,7 @@ class MarkdownSerializerState {
|
|
|
25456
25524
|
}
|
|
25457
25525
|
}
|
|
25458
25526
|
let inner = marks.length ? marks[marks.length - 1] : null;
|
|
25459
|
-
let noEsc = inner && this.
|
|
25527
|
+
let noEsc = inner && this.getMark(inner.type.name).escape === false;
|
|
25460
25528
|
let len = marks.length - (noEsc ? 1 : 0);
|
|
25461
25529
|
// Try to reorder 'mixable' marks, such as em and strong, which
|
|
25462
25530
|
// in Markdown may be opened and closed in different order, so
|
|
@@ -25464,11 +25532,11 @@ class MarkdownSerializerState {
|
|
|
25464
25532
|
// active.
|
|
25465
25533
|
outer: for (let i = 0; i < len; i++) {
|
|
25466
25534
|
let mark = marks[i];
|
|
25467
|
-
if (!this.
|
|
25535
|
+
if (!this.getMark(mark.type.name).mixable)
|
|
25468
25536
|
break;
|
|
25469
25537
|
for (let j = 0; j < active.length; j++) {
|
|
25470
25538
|
let other = active[j];
|
|
25471
|
-
if (!this.
|
|
25539
|
+
if (!this.getMark(other.type.name).mixable)
|
|
25472
25540
|
break;
|
|
25473
25541
|
if (mark.eq(other)) {
|
|
25474
25542
|
if (i > j)
|
|
@@ -25574,7 +25642,7 @@ class MarkdownSerializerState {
|
|
|
25574
25642
|
Get the markdown string for a given opening or closing mark.
|
|
25575
25643
|
*/
|
|
25576
25644
|
markString(mark, open, parent, index) {
|
|
25577
|
-
let info = this.
|
|
25645
|
+
let info = this.getMark(mark.type.name);
|
|
25578
25646
|
let value = open ? info.open : info.close;
|
|
25579
25647
|
return typeof value == "string" ? value : value(this, mark, parent, index);
|
|
25580
25648
|
}
|