@openleaf-editor/core 0.1.0-beta.2 → 0.1.0-beta.4
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/README.md +127 -0
- package/dist/autolink.d.ts +7 -4
- package/dist/autolink.d.ts.map +1 -1
- package/dist/autolink.js +90 -11
- package/dist/autolink.js.map +1 -1
- package/dist/command-helpers.d.ts +8 -0
- package/dist/command-helpers.d.ts.map +1 -0
- package/dist/command-helpers.js +36 -0
- package/dist/command-helpers.js.map +1 -0
- package/dist/commands.d.ts +21 -63
- package/dist/commands.d.ts.map +1 -1
- package/dist/commands.js +430 -346
- package/dist/commands.js.map +1 -1
- package/dist/css.d.ts +1 -175
- package/dist/css.d.ts.map +1 -1
- package/dist/css.js +1 -516
- package/dist/css.js.map +1 -1
- package/dist/disclosure.d.ts +21 -0
- package/dist/disclosure.d.ts.map +1 -0
- package/dist/disclosure.js +144 -0
- package/dist/disclosure.js.map +1 -0
- package/dist/elements.d.ts +2 -0
- package/dist/elements.d.ts.map +1 -0
- package/dist/elements.js +2 -0
- package/dist/elements.js.map +1 -0
- package/dist/embed.d.ts +1 -51
- package/dist/embed.d.ts.map +1 -1
- package/dist/embed.js +1 -115
- package/dist/embed.js.map +1 -1
- package/dist/errors.d.ts +38 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +40 -0
- package/dist/errors.js.map +1 -0
- package/dist/extensions.d.ts +46 -5
- package/dist/extensions.d.ts.map +1 -1
- package/dist/extensions.js +272 -52
- package/dist/extensions.js.map +1 -1
- package/dist/figure-drag.d.ts +26 -0
- package/dist/figure-drag.d.ts.map +1 -0
- package/dist/figure-drag.js +75 -0
- package/dist/figure-drag.js.map +1 -0
- package/dist/formats.d.ts.map +1 -1
- package/dist/formats.js +19 -7
- package/dist/formats.js.map +1 -1
- package/dist/gapcursor.d.ts +14 -0
- package/dist/gapcursor.d.ts.map +1 -0
- package/dist/gapcursor.js +17 -0
- package/dist/gapcursor.js.map +1 -0
- package/dist/html.d.ts +32 -2
- package/dist/html.d.ts.map +1 -1
- package/dist/html.js +185 -31
- package/dist/html.js.map +1 -1
- package/dist/index.d.ts +23 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +34 -6
- package/dist/index.js.map +1 -1
- package/dist/insert-commands.d.ts +172 -0
- package/dist/insert-commands.d.ts.map +1 -0
- package/dist/insert-commands.js +560 -0
- package/dist/insert-commands.js.map +1 -0
- package/dist/isolating-selection.d.ts +59 -0
- package/dist/isolating-selection.d.ts.map +1 -0
- package/dist/isolating-selection.js +251 -0
- package/dist/isolating-selection.js.map +1 -0
- package/dist/noneditable.d.ts.map +1 -1
- package/dist/noneditable.js +18 -4
- package/dist/noneditable.js.map +1 -1
- package/dist/plugins.d.ts +20 -2
- package/dist/plugins.d.ts.map +1 -1
- package/dist/plugins.js +27 -2
- package/dist/plugins.js.map +1 -1
- package/dist/preserve.d.ts +48 -17
- package/dist/preserve.d.ts.map +1 -1
- package/dist/preserve.js +214 -43
- package/dist/preserve.js.map +1 -1
- package/dist/schema.d.ts +15 -0
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +157 -28
- package/dist/schema.js.map +1 -1
- package/dist/structure.d.ts +32 -0
- package/dist/structure.d.ts.map +1 -1
- package/dist/structure.js +53 -10
- package/dist/structure.js.map +1 -1
- package/dist/tables.d.ts +47 -1
- package/dist/tables.d.ts.map +1 -1
- package/dist/tables.js +417 -40
- package/dist/tables.js.map +1 -1
- package/dist/testing.d.ts +3 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +3 -0
- package/dist/testing.js.map +1 -0
- package/dist/tokens.d.ts +8 -0
- package/dist/tokens.d.ts.map +1 -1
- package/dist/tokens.js +54 -6
- package/dist/tokens.js.map +1 -1
- package/dist/url.d.ts +1 -25
- package/dist/url.d.ts.map +1 -1
- package/dist/url.js +1 -77
- package/dist/url.js.map +1 -1
- package/dist/visual-aids.d.ts +11 -1
- package/dist/visual-aids.d.ts.map +1 -1
- package/dist/visual-aids.js +124 -36
- package/dist/visual-aids.js.map +1 -1
- package/package.json +17 -1
package/dist/tokens.d.ts
CHANGED
|
@@ -25,4 +25,12 @@ export declare const IMAGE_ALIGN_CLASS: Readonly<Record<ImageAlign, string>>;
|
|
|
25
25
|
/** The modelled alignment class in this list, if any. */
|
|
26
26
|
export declare function imageAlignFromClass(value: string | null | undefined): ImageAlign | null;
|
|
27
27
|
export declare const IMAGE_ALIGN_CLASSES: ReadonlySet<string>;
|
|
28
|
+
/**
|
|
29
|
+
* True for a name that can be written back with `setAttribute` anywhere.
|
|
30
|
+
*
|
|
31
|
+
* Used where unmodelled attributes are picked up to be carried through the
|
|
32
|
+
* round trip: an attribute that cannot be written is not content, and refusing
|
|
33
|
+
* it there is what keeps `serializeHtml(parseHtml(x))` from throwing.
|
|
34
|
+
*/
|
|
35
|
+
export declare function isWritableAttributeName(name: string): boolean;
|
|
28
36
|
//# sourceMappingURL=tokens.d.ts.map
|
package/dist/tokens.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;
|
|
1
|
+
{"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAgBH,8CAA8C;AAC9C,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAKtE;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAChC,OAAO,GAAE,WAAW,CAAC,MAAM,CAAa,GACvC,MAAM,GAAG,IAAI,CAWf;AAED,kFAAkF;AAClF,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAA;AAEpD,eAAO,MAAM,gBAAgB,EAAE,SAAS,UAAU,EAAgC,CAAA;AAElF,eAAO,MAAM,iBAAiB,EAAE,QAAQ,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAIlE,CAAA;AASD,yDAAyD;AACzD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,UAAU,GAAG,IAAI,CAOvF;AAED,eAAO,MAAM,mBAAmB,EAAE,WAAW,CAAC,MAAM,CAA6C,CAAA;AAiCjG;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE7D"}
|
package/dist/tokens.js
CHANGED
|
@@ -8,16 +8,25 @@
|
|
|
8
8
|
* Which class names a deployment offers in a pick list is an integrator
|
|
9
9
|
* decision; which characters may appear in one is not.
|
|
10
10
|
*/
|
|
11
|
-
/**
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
/**
|
|
12
|
+
* HTML5 ids and class tokens: a non-empty run of non-whitespace.
|
|
13
|
+
*
|
|
14
|
+
* Class names are not CSS identifiers. Tailwind (`md:w-1/2`, `p-[10px]`),
|
|
15
|
+
* leading digits (`2col`), and non-ASCII (`größe-mittel`) are legal in HTML
|
|
16
|
+
* and in CSS (with escaping at selector time, which is the site's problem).
|
|
17
|
+
* Restricting tokens to ASCII identifiers silently deleted half of a mixed
|
|
18
|
+
* `class` whenever another token survived the filter -- the modelled write
|
|
19
|
+
* then overrode the residue that would have carried the original string.
|
|
20
|
+
* Policy about *which* classes a deployment stores belongs in sanitize, not
|
|
21
|
+
* here.
|
|
22
|
+
*/
|
|
23
|
+
const HTML_TOKEN = /^[^\s]+$/;
|
|
15
24
|
/** An `id` the schema will store, or null. */
|
|
16
25
|
export function safeId(value) {
|
|
17
26
|
if (value === null || value === undefined)
|
|
18
27
|
return null;
|
|
19
28
|
const candidate = value.trim();
|
|
20
|
-
if (candidate === '' || !
|
|
29
|
+
if (candidate === '' || !HTML_TOKEN.test(candidate))
|
|
21
30
|
return null;
|
|
22
31
|
return candidate;
|
|
23
32
|
}
|
|
@@ -34,7 +43,7 @@ export function safeClassList(value, exclude = new Set()) {
|
|
|
34
43
|
const kept = [];
|
|
35
44
|
const seen = new Set();
|
|
36
45
|
for (const token of value.trim().split(/\s+/)) {
|
|
37
|
-
if (token === '' || exclude.has(token) || !
|
|
46
|
+
if (token === '' || exclude.has(token) || !HTML_TOKEN.test(token))
|
|
38
47
|
continue;
|
|
39
48
|
if (seen.has(token))
|
|
40
49
|
continue;
|
|
@@ -65,4 +74,43 @@ export function imageAlignFromClass(value) {
|
|
|
65
74
|
return null;
|
|
66
75
|
}
|
|
67
76
|
export const IMAGE_ALIGN_CLASSES = new Set(Object.values(IMAGE_ALIGN_CLASS));
|
|
77
|
+
/*
|
|
78
|
+
* Attribute names the schema is willing to write back.
|
|
79
|
+
*
|
|
80
|
+
* The HTML parser accepts names `setAttribute` refuses. `<p ="v">` parses to one
|
|
81
|
+
* attribute literally named `="v"`, and every engine's `setAttribute` throws
|
|
82
|
+
* `InvalidCharacterError` on it -- so a name the parser produced through error
|
|
83
|
+
* recovery was carried in as residue and then detonated on the way out, in the
|
|
84
|
+
* middle of rendering a document. One stray `=` typed in the source box left the
|
|
85
|
+
* editor blank with no way back, and a stored document containing one could not
|
|
86
|
+
* be loaded at all.
|
|
87
|
+
*
|
|
88
|
+
* This is the XML `Name` production, which is what `setAttribute` validates
|
|
89
|
+
* against. Deliberately the spec's rule rather than the host's: browsers are
|
|
90
|
+
* laxer than the spec for HTML documents and jsdom implements it strictly, so
|
|
91
|
+
* asking the current runtime would accept names in a browser session that then
|
|
92
|
+
* throw on a jsdom server -- the cross-environment divergence this project
|
|
93
|
+
* refuses elsewhere. Being stricter than the strictest runtime is the only test
|
|
94
|
+
* that makes stored content portable.
|
|
95
|
+
*
|
|
96
|
+
* Nothing legal is lost. Every name a document could have meant -- including
|
|
97
|
+
* non-ASCII and namespaced ones -- is a `Name`; the names this rejects exist
|
|
98
|
+
* only because a parser recovered from malformed markup.
|
|
99
|
+
*/
|
|
100
|
+
const NAME_START = 'A-Za-z_:' +
|
|
101
|
+
'\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF' +
|
|
102
|
+
'\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF' +
|
|
103
|
+
'\\uFDF0-\\uFFFD\\u{10000}-\\u{EFFFF}';
|
|
104
|
+
const NAME_REST = NAME_START + '\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040';
|
|
105
|
+
const ATTRIBUTE_NAME = new RegExp(`^[${NAME_START}][${NAME_REST}]*$`, 'u');
|
|
106
|
+
/**
|
|
107
|
+
* True for a name that can be written back with `setAttribute` anywhere.
|
|
108
|
+
*
|
|
109
|
+
* Used where unmodelled attributes are picked up to be carried through the
|
|
110
|
+
* round trip: an attribute that cannot be written is not content, and refusing
|
|
111
|
+
* it there is what keeps `serializeHtml(parseHtml(x))` from throwing.
|
|
112
|
+
*/
|
|
113
|
+
export function isWritableAttributeName(name) {
|
|
114
|
+
return ATTRIBUTE_NAME.test(name);
|
|
115
|
+
}
|
|
68
116
|
//# sourceMappingURL=tokens.js.map
|
package/dist/tokens.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tokens.js","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH
|
|
1
|
+
{"version":3,"file":"tokens.js","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"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"}
|
package/dist/url.d.ts
CHANGED
|
@@ -1,26 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
* URL safety.
|
|
3
|
-
*
|
|
4
|
-
* A link is the cheapest XSS vector there is: `<a href="javascript:...">` needs
|
|
5
|
-
* no injected element, no script tag, and no clever parsing trick -- just a user
|
|
6
|
-
* who clicks. OpenLeaf's schema previously accepted any `href` at all.
|
|
7
|
-
*
|
|
8
|
-
* The checks here are deliberately a small allowlist of schemes rather than a
|
|
9
|
-
* blocklist of dangerous ones. A blocklist is a promise to have thought of every
|
|
10
|
-
* scheme, including the ones a browser will invent later.
|
|
11
|
-
*/
|
|
12
|
-
/**
|
|
13
|
-
* Is this URL safe to put in an `href` or `src`?
|
|
14
|
-
*
|
|
15
|
-
* Relative URLs, fragments and query-only URLs are allowed: they cannot carry a
|
|
16
|
-
* scheme, so they cannot execute. Protocol-relative `//host/path` is allowed
|
|
17
|
-
* because it inherits the page's scheme.
|
|
18
|
-
*/
|
|
19
|
-
export declare function isSafeUrl(value: string | null | undefined): boolean;
|
|
20
|
-
/** The safe URL, or null when it should be dropped. */
|
|
21
|
-
export declare function safeUrlOrNull(value: string | null | undefined): string | null;
|
|
22
|
-
/** Attributes whose values are URLs and therefore need checking. */
|
|
23
|
-
export declare const URL_ATTRIBUTES: ReadonlySet<string>;
|
|
24
|
-
/** True for `onclick`, `onmouseover` and every other inline event handler. */
|
|
25
|
-
export declare function isEventHandlerAttribute(name: string): boolean;
|
|
1
|
+
export * from '@openleaf-editor/content-policy/url';
|
|
26
2
|
//# sourceMappingURL=url.d.ts.map
|
package/dist/url.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"url.d.ts","sourceRoot":"","sources":["../src/url.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"url.d.ts","sourceRoot":"","sources":["../src/url.ts"],"names":[],"mappings":"AAAA,cAAc,qCAAqC,CAAA"}
|
package/dist/url.js
CHANGED
|
@@ -1,78 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
* URL safety.
|
|
3
|
-
*
|
|
4
|
-
* A link is the cheapest XSS vector there is: `<a href="javascript:...">` needs
|
|
5
|
-
* no injected element, no script tag, and no clever parsing trick -- just a user
|
|
6
|
-
* who clicks. OpenLeaf's schema previously accepted any `href` at all.
|
|
7
|
-
*
|
|
8
|
-
* The checks here are deliberately a small allowlist of schemes rather than a
|
|
9
|
-
* blocklist of dangerous ones. A blocklist is a promise to have thought of every
|
|
10
|
-
* scheme, including the ones a browser will invent later.
|
|
11
|
-
*/
|
|
12
|
-
/**
|
|
13
|
-
* Schemes an author may link to.
|
|
14
|
-
*
|
|
15
|
-
* `data:` is absent on purpose. `data:text/html` is a full XSS vector, and
|
|
16
|
-
* distinguishing safe data URLs from dangerous ones by sniffing the media type
|
|
17
|
-
* is exactly the kind of parsing that gets defeated. Integrators who genuinely
|
|
18
|
-
* need inline images can permit them in their server-side policy, where the
|
|
19
|
-
* decision is explicit and reviewable.
|
|
20
|
-
*/
|
|
21
|
-
const SAFE_SCHEMES = new Set(['http', 'https', 'mailto', 'tel', 'ftp', 'ftps']);
|
|
22
|
-
/** Matches a leading URL scheme, per RFC 3986. */
|
|
23
|
-
const SCHEME = /^([a-z][a-z0-9+.-]*):/i;
|
|
24
|
-
/**
|
|
25
|
-
* Strip the characters browsers ignore when resolving a scheme.
|
|
26
|
-
*
|
|
27
|
-
* `java\tscript:alert(1)` and `java\nscript:alert(1)` both navigate. Browsers
|
|
28
|
-
* discard ASCII whitespace and control characters while parsing the scheme, so
|
|
29
|
-
* any check that does not do the same is trivially bypassed. Attribute values
|
|
30
|
-
* arrive already entity-decoded from `getAttribute`, so `javascript:` is
|
|
31
|
-
* covered by the same normalization.
|
|
32
|
-
*/
|
|
33
|
-
function normalize(value) {
|
|
34
|
-
return value.replace(/[\u0000-\u0020\u007f-\u00a0]/g, '').toLowerCase();
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Is this URL safe to put in an `href` or `src`?
|
|
38
|
-
*
|
|
39
|
-
* Relative URLs, fragments and query-only URLs are allowed: they cannot carry a
|
|
40
|
-
* scheme, so they cannot execute. Protocol-relative `//host/path` is allowed
|
|
41
|
-
* because it inherits the page's scheme.
|
|
42
|
-
*/
|
|
43
|
-
export function isSafeUrl(value) {
|
|
44
|
-
if (value === null || value === undefined)
|
|
45
|
-
return false;
|
|
46
|
-
const candidate = normalize(value);
|
|
47
|
-
if (candidate === '')
|
|
48
|
-
return false;
|
|
49
|
-
const match = SCHEME.exec(candidate);
|
|
50
|
-
// No scheme means relative, fragment or protocol-relative. All are safe.
|
|
51
|
-
if (!match)
|
|
52
|
-
return true;
|
|
53
|
-
return SAFE_SCHEMES.has(match[1]);
|
|
54
|
-
}
|
|
55
|
-
/** The safe URL, or null when it should be dropped. */
|
|
56
|
-
export function safeUrlOrNull(value) {
|
|
57
|
-
return isSafeUrl(value) ? value : null;
|
|
58
|
-
}
|
|
59
|
-
/** Attributes whose values are URLs and therefore need checking. */
|
|
60
|
-
export const URL_ATTRIBUTES = new Set([
|
|
61
|
-
'href',
|
|
62
|
-
'src',
|
|
63
|
-
'action',
|
|
64
|
-
'formaction',
|
|
65
|
-
'data',
|
|
66
|
-
'poster',
|
|
67
|
-
'background',
|
|
68
|
-
'cite',
|
|
69
|
-
'longdesc',
|
|
70
|
-
'srcdoc',
|
|
71
|
-
'xlink:href',
|
|
72
|
-
'ping',
|
|
73
|
-
]);
|
|
74
|
-
/** True for `onclick`, `onmouseover` and every other inline event handler. */
|
|
75
|
-
export function isEventHandlerAttribute(name) {
|
|
76
|
-
return /^on/i.test(name);
|
|
77
|
-
}
|
|
1
|
+
export * from '@openleaf-editor/content-policy/url';
|
|
78
2
|
//# sourceMappingURL=url.js.map
|
package/dist/url.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"url.js","sourceRoot":"","sources":["../src/url.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"url.js","sourceRoot":"","sources":["../src/url.ts"],"names":[],"mappings":"AAAA,cAAc,qCAAqC,CAAA"}
|
package/dist/visual-aids.d.ts
CHANGED
|
@@ -4,7 +4,17 @@
|
|
|
4
4
|
*
|
|
5
5
|
* These marks are view-only. They must never reach serialized HTML: an empty
|
|
6
6
|
* paragraph is still an empty paragraph, and a ` ` is still a nbsp.
|
|
7
|
+
*
|
|
8
|
+
* The set lives in plugin state rather than being recomputed by the
|
|
9
|
+
* `decorations` prop. That prop is a *pull* prop -- ProseMirror calls it on
|
|
10
|
+
* every `updateState`, so building the set there rebuilt the whole document's
|
|
11
|
+
* decorations on every keystroke, every arrow key and every click. On
|
|
12
|
+
* Word-pasted content, which is mostly non-breaking spaces, that measured 263 ms
|
|
13
|
+
* per keystroke; mapping the existing set through the transaction instead
|
|
14
|
+
* measures under 2 ms. Only the ranges the transaction actually touched are
|
|
15
|
+
* rebuilt.
|
|
7
16
|
*/
|
|
8
17
|
import { Plugin } from 'prosemirror-state';
|
|
9
|
-
|
|
18
|
+
import { DecorationSet } from 'prosemirror-view';
|
|
19
|
+
export declare function visualAidsPlugin(): Plugin<DecorationSet>;
|
|
10
20
|
//# sourceMappingURL=visual-aids.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"visual-aids.d.ts","sourceRoot":"","sources":["../src/visual-aids.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"visual-aids.d.ts","sourceRoot":"","sources":["../src/visual-aids.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,EAAE,MAAM,EAAa,MAAM,mBAAmB,CAAA;AAErD,OAAO,EAAc,aAAa,EAAE,MAAM,kBAAkB,CAAA;AA0G5D,wBAAgB,gBAAgB,IAAI,MAAM,CAAC,aAAa,CAAC,CAwBxD"}
|
package/dist/visual-aids.js
CHANGED
|
@@ -4,56 +4,144 @@
|
|
|
4
4
|
*
|
|
5
5
|
* These marks are view-only. They must never reach serialized HTML: an empty
|
|
6
6
|
* paragraph is still an empty paragraph, and a ` ` is still a nbsp.
|
|
7
|
+
*
|
|
8
|
+
* The set lives in plugin state rather than being recomputed by the
|
|
9
|
+
* `decorations` prop. That prop is a *pull* prop -- ProseMirror calls it on
|
|
10
|
+
* every `updateState`, so building the set there rebuilt the whole document's
|
|
11
|
+
* decorations on every keystroke, every arrow key and every click. On
|
|
12
|
+
* Word-pasted content, which is mostly non-breaking spaces, that measured 263 ms
|
|
13
|
+
* per keystroke; mapping the existing set through the transaction instead
|
|
14
|
+
* measures under 2 ms. Only the ranges the transaction actually touched are
|
|
15
|
+
* rebuilt.
|
|
7
16
|
*/
|
|
8
17
|
import { Plugin, PluginKey } from 'prosemirror-state';
|
|
9
18
|
import { Decoration, DecorationSet } from 'prosemirror-view';
|
|
10
19
|
const key = new PluginKey('openleaf-visual-aids');
|
|
11
20
|
/**
|
|
12
|
-
*
|
|
21
|
+
* Mark every nbsp in one inline container, except a block-final one.
|
|
22
|
+
*
|
|
23
|
+
* ProseMirror renders a document space at the end of a text block as a
|
|
24
|
+
* non-breaking space itself, so the browser does not collapse it. Decorating
|
|
25
|
+
* that position wrapped the rendering artifact in a span, and the editor then
|
|
26
|
+
* read the nbsp back as the author's own character -- so every space typed at
|
|
27
|
+
* the end of a paragraph became a nbsp in the stored HTML, and the next one
|
|
28
|
+
* after it too. A genuinely stored trailing nbsp therefore goes unmarked. That
|
|
29
|
+
* is the price of the aid never changing the document it describes.
|
|
13
30
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
31
|
+
* The block-final test used to be `doc.resolve(at)` per nbsp, and
|
|
32
|
+
* `Fragment.findIndex` inside `resolve` is a linear scan of the parent's
|
|
33
|
+
* children -- O(nbsp x children) over the document. The traversal already knows
|
|
34
|
+
* the parent's `content.size` and the running offset of each child, so the same
|
|
35
|
+
* question is answered by comparing two integers.
|
|
36
|
+
*/
|
|
37
|
+
function markNbsp(parent, contentStart, out) {
|
|
38
|
+
const contentSize = parent.content.size;
|
|
39
|
+
let offset = 0;
|
|
40
|
+
parent.forEach((child) => {
|
|
41
|
+
if (child.isText) {
|
|
42
|
+
const text = child.text ?? '';
|
|
43
|
+
for (let i = 0; i < text.length; i += 1) {
|
|
44
|
+
if (text.charCodeAt(i) !== 0xa0)
|
|
45
|
+
continue;
|
|
46
|
+
// `parentOffset + 1 >= parent.content.size` is the block-final test,
|
|
47
|
+
// and `offset + i` is exactly that parent offset.
|
|
48
|
+
if (offset + i + 1 >= contentSize)
|
|
49
|
+
continue;
|
|
50
|
+
// `contentStart + offset + i` already addresses the character itself: a
|
|
51
|
+
// text node has no opening token to step over, unlike a node. Adding one
|
|
52
|
+
// marked the character after each nbsp, and ran off the end of the node
|
|
53
|
+
// when the nbsp was last -- where the decoration disappeared entirely.
|
|
54
|
+
const at = contentStart + offset + i;
|
|
55
|
+
out.push(Decoration.inline(at, at + 1, { class: 'ol-nbsp' }));
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
offset += child.nodeSize;
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
/** Every aid for the nodes overlapping `[from, to]`. */
|
|
62
|
+
function decorationsIn(doc, from, to) {
|
|
63
|
+
const out = [];
|
|
64
|
+
doc.nodesBetween(from, to, (node, pos) => {
|
|
65
|
+
// Text is scanned from its parent, which is where the offsets are known.
|
|
66
|
+
if (node.isText)
|
|
67
|
+
return false;
|
|
68
|
+
if (node.isTextblock && node.content.size === 0) {
|
|
69
|
+
out.push(Decoration.node(pos, pos + node.nodeSize, { class: 'ol-empty-block' }));
|
|
70
|
+
}
|
|
71
|
+
if (node.type.name === 'unknown_block' || node.type.name === 'unknown_inline') {
|
|
72
|
+
out.push(Decoration.node(pos, pos + node.nodeSize, { class: 'ol-hidden-structure' }));
|
|
73
|
+
}
|
|
74
|
+
if (node.inlineContent && node.content.size > 0)
|
|
75
|
+
markNbsp(node, pos + 1, out);
|
|
76
|
+
return true;
|
|
77
|
+
});
|
|
78
|
+
return out;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* The span of `tr.doc` the transaction touched, or null when it touched nothing.
|
|
19
82
|
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
83
|
+
* Each step's map reports positions in the document *that step* produced, which
|
|
84
|
+
* for every step but the last is not `tr.doc`. Rather than slicing the mapping
|
|
85
|
+
* per step -- the O(steps^2) shape this plugin exists to avoid -- the accumulated
|
|
86
|
+
* range is carried forward one step at a time, so the whole scan is O(steps).
|
|
22
87
|
*/
|
|
23
|
-
function
|
|
24
|
-
|
|
25
|
-
|
|
88
|
+
function changedRange(maps) {
|
|
89
|
+
let from = -1;
|
|
90
|
+
let to = -1;
|
|
91
|
+
for (const map of maps) {
|
|
92
|
+
if (from > -1) {
|
|
93
|
+
from = map.map(from, -1);
|
|
94
|
+
to = map.map(to, 1);
|
|
95
|
+
}
|
|
96
|
+
map.forEach((_oldStart, _oldEnd, newStart, newEnd) => {
|
|
97
|
+
from = from < 0 ? newStart : Math.min(from, newStart);
|
|
98
|
+
to = to < 0 ? newEnd : Math.max(to, newEnd);
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
return from < 0 ? null : { from, to };
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Widen a range to whole top-level blocks.
|
|
105
|
+
*
|
|
106
|
+
* Every aid is contained in one top-level block, so widening to that boundary
|
|
107
|
+
* means a node overlapping the rebuilt range is *entirely* inside it. Without
|
|
108
|
+
* that, a decoration on the half of a paragraph outside the range would survive
|
|
109
|
+
* the removal and be added a second time.
|
|
110
|
+
*/
|
|
111
|
+
function widen(doc, from, to) {
|
|
112
|
+
const size = doc.content.size;
|
|
113
|
+
const start = Math.max(0, Math.min(from, size));
|
|
114
|
+
const end = Math.max(start, Math.min(to, size));
|
|
115
|
+
const $start = doc.resolve(start);
|
|
116
|
+
const $end = doc.resolve(end);
|
|
117
|
+
return {
|
|
118
|
+
from: $start.depth > 0 ? $start.before(1) : start,
|
|
119
|
+
to: $end.depth > 0 ? $end.after(1) : end,
|
|
120
|
+
};
|
|
26
121
|
}
|
|
27
122
|
export function visualAidsPlugin() {
|
|
28
123
|
return new Plugin({
|
|
29
124
|
key,
|
|
125
|
+
state: {
|
|
126
|
+
init(_config, state) {
|
|
127
|
+
return DecorationSet.create(state.doc, decorationsIn(state.doc, 0, state.doc.content.size));
|
|
128
|
+
},
|
|
129
|
+
apply(tr, set) {
|
|
130
|
+
if (!tr.docChanged)
|
|
131
|
+
return set;
|
|
132
|
+
const changed = changedRange(tr.mapping.maps);
|
|
133
|
+
const mapped = set.map(tr.mapping, tr.doc);
|
|
134
|
+
if (!changed)
|
|
135
|
+
return mapped;
|
|
136
|
+
const { from, to } = widen(tr.doc, changed.from, changed.to);
|
|
137
|
+
const stale = mapped.find(from, to);
|
|
138
|
+
const kept = stale.length > 0 ? mapped.remove(stale) : mapped;
|
|
139
|
+
return kept.add(tr.doc, decorationsIn(tr.doc, from, to));
|
|
140
|
+
},
|
|
141
|
+
},
|
|
30
142
|
props: {
|
|
31
143
|
decorations(state) {
|
|
32
|
-
|
|
33
|
-
state.doc.descendants((node, pos) => {
|
|
34
|
-
if (node.isTextblock && node.content.size === 0) {
|
|
35
|
-
decorations.push(Decoration.node(pos, pos + node.nodeSize, { class: 'ol-empty-block' }));
|
|
36
|
-
}
|
|
37
|
-
if (node.type.name === 'unknown_block' || node.type.name === 'unknown_inline') {
|
|
38
|
-
decorations.push(Decoration.node(pos, pos + node.nodeSize, { class: 'ol-hidden-structure' }));
|
|
39
|
-
}
|
|
40
|
-
if (node.isText) {
|
|
41
|
-
const text = node.text ?? '';
|
|
42
|
-
for (let i = 0; i < text.length; i += 1) {
|
|
43
|
-
if (text.charCodeAt(i) !== 0xa0)
|
|
44
|
-
continue;
|
|
45
|
-
// `pos` already addresses the first character: a text node has no
|
|
46
|
-
// opening token to step over, unlike a node. Adding one marked the
|
|
47
|
-
// character after each nbsp, and ran off the end of the node when
|
|
48
|
-
// the nbsp was last -- where the decoration disappeared entirely.
|
|
49
|
-
const at = pos + i;
|
|
50
|
-
if (isBlockFinal(state.doc, at))
|
|
51
|
-
continue;
|
|
52
|
-
decorations.push(Decoration.inline(at, at + 1, { class: 'ol-nbsp' }));
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
});
|
|
56
|
-
return DecorationSet.create(state.doc, decorations);
|
|
144
|
+
return key.getState(state);
|
|
57
145
|
},
|
|
58
146
|
},
|
|
59
147
|
});
|
package/dist/visual-aids.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"visual-aids.js","sourceRoot":"","sources":["../src/visual-aids.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"visual-aids.js","sourceRoot":"","sources":["../src/visual-aids.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openleaf-editor/core",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.4",
|
|
4
4
|
"description": "OpenLeaf editing core: ProseMirror schema, HTML I/O, and the content-preservation layer. No UI, no framework dependencies.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"publishConfig": {
|
|
@@ -16,12 +16,19 @@
|
|
|
16
16
|
"url": "https://github.com/PeytonNowlin/openleaf/issues"
|
|
17
17
|
},
|
|
18
18
|
"type": "module",
|
|
19
|
+
"engines": {
|
|
20
|
+
"node": ">=20"
|
|
21
|
+
},
|
|
19
22
|
"main": "./dist/index.js",
|
|
20
23
|
"types": "./dist/index.d.ts",
|
|
21
24
|
"exports": {
|
|
22
25
|
".": {
|
|
23
26
|
"types": "./dist/index.d.ts",
|
|
24
27
|
"import": "./dist/index.js"
|
|
28
|
+
},
|
|
29
|
+
"./testing": {
|
|
30
|
+
"types": "./dist/testing.d.ts",
|
|
31
|
+
"import": "./dist/testing.js"
|
|
25
32
|
}
|
|
26
33
|
},
|
|
27
34
|
"files": [
|
|
@@ -30,7 +37,11 @@
|
|
|
30
37
|
"sideEffects": false,
|
|
31
38
|
"dependencies": {
|
|
32
39
|
"orderedmap": "^2.1.1",
|
|
40
|
+
"@openleaf-editor/content-policy": "0.1.0-beta.4"
|
|
41
|
+
},
|
|
42
|
+
"peerDependencies": {
|
|
33
43
|
"prosemirror-commands": "^1.6.2",
|
|
44
|
+
"prosemirror-gapcursor": "^1.4.1",
|
|
34
45
|
"prosemirror-history": "^1.4.1",
|
|
35
46
|
"prosemirror-model": "^1.24.1",
|
|
36
47
|
"prosemirror-schema-list": "^1.5.1",
|
|
@@ -38,6 +49,11 @@
|
|
|
38
49
|
"prosemirror-transform": "^1.10.2",
|
|
39
50
|
"prosemirror-view": "^1.37.0"
|
|
40
51
|
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"prosemirror-gapcursor": "^1.4.1",
|
|
54
|
+
"prosemirror-tables": "^1.6.4",
|
|
55
|
+
"prosemirror-transform": "^1.10.2"
|
|
56
|
+
},
|
|
41
57
|
"scripts": {
|
|
42
58
|
"build": "tsc -p tsconfig.json"
|
|
43
59
|
}
|