@kerebron/extension-dev-toolkit 0.3.2

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.
Files changed (61) hide show
  1. package/LICENSE +23 -0
  2. package/README.md +67 -0
  3. package/esm/editor/src/CoreEditor.d.ts +31 -0
  4. package/esm/editor/src/CoreEditor.d.ts.map +1 -0
  5. package/esm/editor/src/CoreEditor.js +200 -0
  6. package/esm/editor/src/DummyEditorView.d.ts +60 -0
  7. package/esm/editor/src/DummyEditorView.d.ts.map +1 -0
  8. package/esm/editor/src/DummyEditorView.js +277 -0
  9. package/esm/editor/src/Extension.d.ts +26 -0
  10. package/esm/editor/src/Extension.d.ts.map +1 -0
  11. package/esm/editor/src/Extension.js +33 -0
  12. package/esm/editor/src/ExtensionManager.d.ts +33 -0
  13. package/esm/editor/src/ExtensionManager.d.ts.map +1 -0
  14. package/esm/editor/src/ExtensionManager.js +272 -0
  15. package/esm/editor/src/Mark.d.ts +20 -0
  16. package/esm/editor/src/Mark.d.ts.map +1 -0
  17. package/esm/editor/src/Mark.js +40 -0
  18. package/esm/editor/src/Node.d.ts +29 -0
  19. package/esm/editor/src/Node.d.ts.map +1 -0
  20. package/esm/editor/src/Node.js +49 -0
  21. package/esm/editor/src/commands/CommandManager.d.ts +16 -0
  22. package/esm/editor/src/commands/CommandManager.d.ts.map +1 -0
  23. package/esm/editor/src/commands/CommandManager.js +61 -0
  24. package/esm/editor/src/commands/createChainableState.d.ts +3 -0
  25. package/esm/editor/src/commands/createChainableState.d.ts.map +1 -0
  26. package/esm/editor/src/commands/createChainableState.js +29 -0
  27. package/esm/editor/src/commands/mod.d.ts +55 -0
  28. package/esm/editor/src/commands/mod.d.ts.map +1 -0
  29. package/esm/editor/src/commands/mod.js +883 -0
  30. package/esm/editor/src/mod.d.ts +7 -0
  31. package/esm/editor/src/mod.d.ts.map +1 -0
  32. package/esm/editor/src/mod.js +6 -0
  33. package/esm/editor/src/nodeToTreeString.d.ts +10 -0
  34. package/esm/editor/src/nodeToTreeString.d.ts.map +1 -0
  35. package/esm/editor/src/nodeToTreeString.js +74 -0
  36. package/esm/editor/src/plugins/input-rules/InputRulesPlugin.d.ts +23 -0
  37. package/esm/editor/src/plugins/input-rules/InputRulesPlugin.d.ts.map +1 -0
  38. package/esm/editor/src/plugins/input-rules/InputRulesPlugin.js +163 -0
  39. package/esm/editor/src/plugins/keymap/keymap.d.ts +11 -0
  40. package/esm/editor/src/plugins/keymap/keymap.d.ts.map +1 -0
  41. package/esm/editor/src/plugins/keymap/keymap.js +125 -0
  42. package/esm/editor/src/plugins/keymap/w3c-keyname.d.ts +4 -0
  43. package/esm/editor/src/plugins/keymap/w3c-keyname.d.ts.map +1 -0
  44. package/esm/editor/src/plugins/keymap/w3c-keyname.js +124 -0
  45. package/esm/editor/src/types.d.ts +34 -0
  46. package/esm/editor/src/types.d.ts.map +1 -0
  47. package/esm/editor/src/types.js +1 -0
  48. package/esm/editor/src/utilities/SmartOutput.d.ts +39 -0
  49. package/esm/editor/src/utilities/SmartOutput.d.ts.map +1 -0
  50. package/esm/editor/src/utilities/SmartOutput.js +213 -0
  51. package/esm/editor/src/utilities/createNodeFromContent.d.ts +9 -0
  52. package/esm/editor/src/utilities/createNodeFromContent.d.ts.map +1 -0
  53. package/esm/editor/src/utilities/createNodeFromContent.js +32 -0
  54. package/esm/editor/src/utilities/getHtmlAttributes.d.ts +9 -0
  55. package/esm/editor/src/utilities/getHtmlAttributes.d.ts.map +1 -0
  56. package/esm/editor/src/utilities/getHtmlAttributes.js +47 -0
  57. package/esm/extension-dev-toolkit/src/mod.d.ts +13 -0
  58. package/esm/extension-dev-toolkit/src/mod.d.ts.map +1 -0
  59. package/esm/extension-dev-toolkit/src/mod.js +50 -0
  60. package/esm/package.json +3 -0
  61. package/package.json +23 -0
package/LICENSE ADDED
@@ -0,0 +1,23 @@
1
+ Permission is hereby granted, free of charge, to any
2
+ person obtaining a copy of this software and associated
3
+ documentation files (the "Software"), to deal in the
4
+ Software without restriction, including without
5
+ limitation the rights to use, copy, modify, merge,
6
+ publish, distribute, sublicense, and/or sell copies of
7
+ the Software, and to permit persons to whom the Software
8
+ is furnished to do so, subject to the following
9
+ conditions:
10
+
11
+ The above copyright notice and this permission notice
12
+ shall be included in all copies or substantial portions
13
+ of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
16
+ ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
17
+ TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
18
+ PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
19
+ SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
22
+ IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
+ DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,67 @@
1
+ # Kerebron - Prosemirror based online editor kit
2
+
3
+ ## Watch a Demo
4
+
5
+ <a href="https://youtube.com/shorts/OdJjhAPj-wA?feature=share" target="_blank">
6
+ <img src="https://github.com/user-attachments/assets/b63ec84a-0ed2-4f98-920c-76f6d3215168" alt="Alt Text" width="200">
7
+ </a>
8
+
9
+ ## Playground Demo
10
+
11
+ [playground](https://demo.kerebron.com) - be nice.
12
+
13
+ ## Overview
14
+
15
+ Using vanilla Prosemirror modules is often impossible because of
16
+ incompatibilities.
17
+
18
+ Kerebron forks several prosemirror projects into one monorepo in order to keep
19
+ them in sync.
20
+
21
+ Project is inspired on https://tiptap.dev/, but instead of building wrapper
22
+ around a wrapper it borrows concept of extension and command manager.
23
+
24
+ It has simplified tooling (deno), fewer dependencies and resulting in lower
25
+ number of output npm modules.
26
+
27
+ **Work in progress**
28
+
29
+ ## Development
30
+
31
+ To start example server:
32
+
33
+ ```
34
+ deno task -f server-deno-hono start
35
+ ```
36
+
37
+ ## Examples
38
+
39
+ TODO
40
+
41
+ ## Build
42
+
43
+ ### Build static examples
44
+
45
+ ```shell
46
+ deno task -r build
47
+ ```
48
+
49
+ ### NPM packages are generated using DNT
50
+
51
+ - https://deno.com/blog/publish-esm-cjs-module-dnt - the easiest way to publish
52
+ a hybrid npm module for ESM and CommonJS
53
+ - https://github.com/denoland/dnt
54
+ - https://gaubee.com/article/Publishing-Your-Deno-Project-as-a-Monorepo-using-dnt/
55
+
56
+ To generate npm packages
57
+
58
+ ```shell
59
+ deno -A ./build/build_npm.ts
60
+ ```
61
+
62
+ ## Run through docker
63
+
64
+ ```
65
+ docker build . -t editor-test
66
+ docker run -it -p 8000:8000 -v $PWD:/usr/src/app editor-test
67
+ ```
@@ -0,0 +1,31 @@
1
+ import { EditorView } from 'prosemirror-view';
2
+ import { Node as ProseMirrorNode, Schema } from 'prosemirror-model';
3
+ import type { EditorOptions, JSONContent } from './types.js';
4
+ import { EditorState, Transaction } from 'prosemirror-state';
5
+ import { DummyEditorView } from './DummyEditorView.js';
6
+ import { ChainedCommands } from './commands/mod.js';
7
+ import { Extension } from './Extension.js';
8
+ export declare class CoreEditor extends EventTarget {
9
+ readonly options: Partial<EditorOptions>;
10
+ private extensionManager;
11
+ private commandManager;
12
+ view: EditorView | DummyEditorView;
13
+ state: EditorState;
14
+ constructor(options?: Partial<EditorOptions>);
15
+ getExtension<T extends Extension>(name: string): T | undefined;
16
+ get schema(): Schema<any, any>;
17
+ chain(): ChainedCommands;
18
+ can(): ChainedCommands;
19
+ private createView;
20
+ dispatchTransaction(transaction: Transaction): void;
21
+ private setupPlugins;
22
+ clearDocument(): void;
23
+ setDocument(content: any): void;
24
+ getDocument(): ProseMirrorNode;
25
+ loadDocument(mediaType: string, content: Uint8Array): Promise<void>;
26
+ saveDocument(mediaType: string): Promise<Uint8Array>;
27
+ getJSON(): JSONContent;
28
+ clone(options?: Partial<EditorOptions>): CoreEditor;
29
+ debug(doc?: ProseMirrorNode): void;
30
+ }
31
+ //# sourceMappingURL=CoreEditor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CoreEditor.d.ts","sourceRoot":"","sources":["../../../src/editor/src/CoreEditor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,IAAI,IAAI,eAAe,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAGpE,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAG7D,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAc3C,qBAAa,UAAW,SAAQ,WAAW;IACzC,SAAgB,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,CAG7C;IACF,OAAO,CAAC,gBAAgB,CAAmB;IAC3C,OAAO,CAAC,cAAc,CAAiB;IAChC,IAAI,EAAG,UAAU,GAAG,eAAe,CAAC;IACpC,KAAK,EAAG,WAAW,CAAC;gBAEf,OAAO,GAAE,OAAO,CAAC,aAAa,CAAM;IA4BhD,YAAY,CAAC,CAAC,SAAS,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAI9D,IAAW,MAAM,qBAEhB;IAEM,KAAK,IAAI,eAAe;IAIxB,GAAG,IAAI,eAAe;IAI7B,OAAO,CAAC,UAAU;IAqBX,mBAAmB,CAAC,WAAW,EAAE,WAAW;IAcnD,OAAO,CAAC,YAAY;IAcb,aAAa;IASb,WAAW,CAAC,OAAO,EAAE,GAAG;IAyBxB,WAAW;IAIL,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU;IA0BnD,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAY1D,OAAO,IAAI,WAAW;IAItB,KAAK,CAAC,OAAO,GAAE,OAAO,CAAC,aAAa,CAAM,GAAG,UAAU;IAOvD,KAAK,CAAC,GAAG,CAAC,EAAE,eAAe;CAMnC"}
@@ -0,0 +1,200 @@
1
+ import { EditorView } from 'prosemirror-view';
2
+ import { Node as ProseMirrorNode } from 'prosemirror-model';
3
+ import { ExtensionManager } from './ExtensionManager.js';
4
+ import { EditorState } from 'prosemirror-state';
5
+ import { CommandManager } from './commands/CommandManager.js';
6
+ import { nodeToTreeString } from './nodeToTreeString.js';
7
+ import { DummyEditorView } from './DummyEditorView.js';
8
+ import { createNodeFromObject } from './utilities/createNodeFromContent.js';
9
+ function ensureDocSchema(doc, schema) {
10
+ if (doc.type.schema === schema) {
11
+ return doc;
12
+ }
13
+ const json = doc.toJSON();
14
+ return ProseMirrorNode.fromJSON(schema, json);
15
+ }
16
+ export class CoreEditor extends EventTarget {
17
+ constructor(options = {}) {
18
+ super();
19
+ Object.defineProperty(this, "options", {
20
+ enumerable: true,
21
+ configurable: true,
22
+ writable: true,
23
+ value: {
24
+ element: undefined,
25
+ extensions: [],
26
+ }
27
+ });
28
+ Object.defineProperty(this, "extensionManager", {
29
+ enumerable: true,
30
+ configurable: true,
31
+ writable: true,
32
+ value: void 0
33
+ });
34
+ Object.defineProperty(this, "commandManager", {
35
+ enumerable: true,
36
+ configurable: true,
37
+ writable: true,
38
+ value: void 0
39
+ });
40
+ Object.defineProperty(this, "view", {
41
+ enumerable: true,
42
+ configurable: true,
43
+ writable: true,
44
+ value: void 0
45
+ });
46
+ Object.defineProperty(this, "state", {
47
+ enumerable: true,
48
+ configurable: true,
49
+ writable: true,
50
+ value: void 0
51
+ });
52
+ this.options = {
53
+ ...this.options,
54
+ ...options,
55
+ };
56
+ this.extensionManager = new ExtensionManager(this.options.extensions || [], this);
57
+ // const content = this.options.content ? this.options.content : {
58
+ // type: this.extensionManager.schema.topNodeType.name,
59
+ // content: this.extensionManager.schema.topNodeType.spec.EMPTY_DOC,
60
+ // };
61
+ const content = this.options.content
62
+ ? this.options.content
63
+ : this.extensionManager.schema.topNodeType.spec.EMPTY_DOC;
64
+ this.createView(content);
65
+ this.commandManager = new CommandManager(this, this.extensionManager.commandFactories);
66
+ this.setupPlugins();
67
+ }
68
+ getExtension(name) {
69
+ return this.extensionManager.getExtension(name);
70
+ }
71
+ get schema() {
72
+ return this.extensionManager.schema;
73
+ }
74
+ chain() {
75
+ return this.commandManager.createChain();
76
+ }
77
+ can() {
78
+ return this.commandManager.createCan();
79
+ }
80
+ createView(content) {
81
+ const doc = createNodeFromObject(content, this.schema);
82
+ this.state = EditorState.create({ doc });
83
+ if (this.options.element) {
84
+ this.view = new EditorView(this.options.element, {
85
+ state: this.state,
86
+ attributes: {
87
+ class: 'kb-editor',
88
+ },
89
+ dispatchTransaction: (tx) => this.dispatchTransaction(tx),
90
+ });
91
+ }
92
+ else {
93
+ this.view = new DummyEditorView({
94
+ state: this.state,
95
+ dispatchTransaction: (tx) => this.dispatchTransaction(tx),
96
+ });
97
+ }
98
+ }
99
+ dispatchTransaction(transaction) {
100
+ this.state = this.state.apply(transaction);
101
+ if (this.view) {
102
+ this.view.updateState(this.state);
103
+ const event = new CustomEvent('transaction', {
104
+ detail: {
105
+ editor: this,
106
+ transaction,
107
+ },
108
+ });
109
+ this.dispatchEvent(event);
110
+ }
111
+ }
112
+ setupPlugins() {
113
+ this.state = this.state.reconfigure({
114
+ plugins: this.extensionManager.plugins,
115
+ });
116
+ if (this.view) {
117
+ this.view.updateState(this.state);
118
+ this.view.setProps({
119
+ nodeViews: this.extensionManager.nodeViews,
120
+ });
121
+ }
122
+ }
123
+ clearDocument() {
124
+ const content = {
125
+ type: this.extensionManager.schema.topNodeType.name,
126
+ content: this.extensionManager.schema.topNodeType.spec.EMPTY_DOC.content,
127
+ };
128
+ this.setDocument(content);
129
+ }
130
+ setDocument(content) {
131
+ let doc = createNodeFromObject(content, this.schema, {
132
+ errorOnInvalidContent: true,
133
+ });
134
+ doc = ensureDocSchema(doc, this.schema);
135
+ this.state = EditorState.create({
136
+ doc,
137
+ plugins: this.state.plugins,
138
+ storedMarks: this.state.storedMarks,
139
+ });
140
+ if (this.view) {
141
+ this.view.updateState(this.state);
142
+ }
143
+ const event = new CustomEvent('doc:loaded', {
144
+ detail: {
145
+ editor: this,
146
+ doc,
147
+ },
148
+ });
149
+ this.dispatchEvent(event);
150
+ }
151
+ getDocument() {
152
+ return this.state.doc;
153
+ }
154
+ async loadDocument(mediaType, content) {
155
+ const converter = this.extensionManager.converters[mediaType];
156
+ if (!converter) {
157
+ throw new Error('Converter not found for: ' + mediaType);
158
+ }
159
+ const doc = await converter.toDoc(content);
160
+ this.state = EditorState.create({
161
+ doc,
162
+ plugins: this.state.plugins,
163
+ storedMarks: this.state.storedMarks,
164
+ });
165
+ if (this.view) {
166
+ this.view.updateState(this.state);
167
+ }
168
+ const event = new CustomEvent('doc:loaded', {
169
+ detail: {
170
+ editor: this,
171
+ doc,
172
+ },
173
+ });
174
+ this.dispatchEvent(event);
175
+ }
176
+ async saveDocument(mediaType) {
177
+ const converter = this.extensionManager.converters[mediaType];
178
+ if (!converter) {
179
+ throw new Error('Converter not found for: ' + mediaType);
180
+ }
181
+ const json = this.state.doc.toJSON();
182
+ const clonedDoc = ProseMirrorNode.fromJSON(this.state.schema, json);
183
+ return await converter.fromDoc(clonedDoc);
184
+ }
185
+ getJSON() {
186
+ return this.state.doc.toJSON();
187
+ }
188
+ clone(options = {}) {
189
+ return new CoreEditor({
190
+ ...options,
191
+ extensions: [...(this.options.extensions || [])],
192
+ });
193
+ }
194
+ debug(doc) {
195
+ if (!doc) {
196
+ doc = this.state.doc;
197
+ }
198
+ console.debug(nodeToTreeString(doc));
199
+ }
200
+ }
@@ -0,0 +1,60 @@
1
+ import { EditorState, Plugin, Transaction } from 'prosemirror-state';
2
+ import { Mark, Node } from 'prosemirror-model';
3
+ import { EditorView, MarkView, NodeView } from 'prosemirror-view';
4
+ import { Decoration, DecorationSource } from 'prosemirror-view';
5
+ export declare class DummyEditorView {
6
+ private _props;
7
+ private directPlugins;
8
+ private nodeViews;
9
+ private prevDirectPlugins;
10
+ private pluginViews;
11
+ state: EditorState;
12
+ constructor(props: DirectEditorProps);
13
+ editable: boolean;
14
+ get composing(): boolean;
15
+ get dom(): {
16
+ addEventListener(): void;
17
+ removeEventListener(): void;
18
+ };
19
+ get props(): DirectEditorProps;
20
+ update(props: DirectEditorProps): void;
21
+ setProps(props: Partial<DirectEditorProps>): void;
22
+ updateState(state: EditorState): void;
23
+ private updateStateInner;
24
+ scrollToSelection(): void;
25
+ private destroyPluginViews;
26
+ private updatePluginViews;
27
+ someProp<PropName extends keyof EditorProps, Result>(propName: PropName, f: (value: NonNullable<EditorProps[PropName]>) => Result): Result | undefined;
28
+ someProp<PropName extends keyof EditorProps>(propName: PropName): NonNullable<EditorProps[PropName]> | undefined;
29
+ hasFocus(): boolean;
30
+ focus(): void;
31
+ destroy(): void;
32
+ get isDestroyed(): boolean;
33
+ dispatchEvent(event: Event): void;
34
+ dispatch: (tr: Transaction) => void;
35
+ }
36
+ export type NodeViewConstructor = (node: Node, view: EditorView, getPos: () => number | undefined, decorations: readonly Decoration[], innerDecorations: DecorationSource) => NodeView;
37
+ export type MarkViewConstructor = (mark: Mark, view: EditorView, inline: boolean) => MarkView;
38
+ export interface DOMEventMap extends HTMLElementEventMap {
39
+ [event: string]: any;
40
+ }
41
+ export interface EditorProps<P = any> {
42
+ nodeViews?: {
43
+ [node: string]: NodeViewConstructor;
44
+ };
45
+ markViews?: {
46
+ [mark: string]: MarkViewConstructor;
47
+ };
48
+ editable?: (this: P, state: EditorState) => boolean;
49
+ attributes?: {
50
+ [name: string]: string;
51
+ } | ((state: EditorState) => {
52
+ [name: string]: string;
53
+ });
54
+ }
55
+ export interface DirectEditorProps extends EditorProps {
56
+ state: EditorState;
57
+ plugins?: readonly Plugin[];
58
+ dispatchTransaction?: (tr: Transaction) => void;
59
+ }
60
+ //# sourceMappingURL=DummyEditorView.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DummyEditorView.d.ts","sourceRoot":"","sources":["../../../src/editor/src/DummyEditorView.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,277 @@
1
+ // Headless View to be used on Server-side
2
+ // TODO: remove all unnecessary props and methods
3
+ /// An editor view manages the DOM structure that represents an
4
+ /// editable document. Its state and behavior are determined by its
5
+ /// [props](#view.DirectEditorProps).
6
+ export class DummyEditorView {
7
+ /// Create a view. `place` may be a DOM node that the editor should
8
+ /// be appended to, a function that will place it into the document,
9
+ /// or an object whose `mount` property holds the node to use as the
10
+ /// document container. If it is `null`, the editor will not be
11
+ /// added to the document.
12
+ constructor(props) {
13
+ /// @internal
14
+ Object.defineProperty(this, "_props", {
15
+ enumerable: true,
16
+ configurable: true,
17
+ writable: true,
18
+ value: void 0
19
+ });
20
+ Object.defineProperty(this, "directPlugins", {
21
+ enumerable: true,
22
+ configurable: true,
23
+ writable: true,
24
+ value: void 0
25
+ });
26
+ /// @internal
27
+ Object.defineProperty(this, "nodeViews", {
28
+ enumerable: true,
29
+ configurable: true,
30
+ writable: true,
31
+ value: void 0
32
+ });
33
+ Object.defineProperty(this, "prevDirectPlugins", {
34
+ enumerable: true,
35
+ configurable: true,
36
+ writable: true,
37
+ value: []
38
+ });
39
+ Object.defineProperty(this, "pluginViews", {
40
+ enumerable: true,
41
+ configurable: true,
42
+ writable: true,
43
+ value: []
44
+ });
45
+ /// The view's current [state](#state.EditorState).
46
+ Object.defineProperty(this, "state", {
47
+ enumerable: true,
48
+ configurable: true,
49
+ writable: true,
50
+ value: void 0
51
+ });
52
+ /// Indicates whether the editor is currently [editable](#view.EditorProps.editable).
53
+ Object.defineProperty(this, "editable", {
54
+ enumerable: true,
55
+ configurable: true,
56
+ writable: true,
57
+ value: void 0
58
+ });
59
+ this._props = props;
60
+ this.state = props.state;
61
+ this.directPlugins = props.plugins || [];
62
+ this.directPlugins.forEach(checkStateComponent);
63
+ this.dispatch = this.dispatch.bind(this);
64
+ this.editable = getEditable(this);
65
+ this.nodeViews = buildNodeViews(this);
66
+ // TODO initInput(this)
67
+ this.updatePluginViews();
68
+ }
69
+ /// Holds `true` when a
70
+ /// [composition](https://w3c.github.io/uievents/#events-compositionevents)
71
+ /// is active.
72
+ get composing() {
73
+ return false;
74
+ }
75
+ get dom() {
76
+ return {
77
+ addEventListener() { },
78
+ removeEventListener() { },
79
+ };
80
+ }
81
+ /// The view's current [props](#view.EditorProps).
82
+ get props() {
83
+ if (this._props.state != this.state) {
84
+ let prev = this._props;
85
+ this._props = {};
86
+ for (let name in prev)
87
+ this._props[name] = prev[name];
88
+ this._props.state = this.state;
89
+ }
90
+ return this._props;
91
+ }
92
+ /// Update the view's props. Will immediately cause an update to
93
+ /// the DOM.
94
+ update(props) {
95
+ let prevProps = this._props;
96
+ this._props = props;
97
+ if (props.plugins) {
98
+ props.plugins.forEach(checkStateComponent);
99
+ this.directPlugins = props.plugins;
100
+ }
101
+ this.updateStateInner(props.state, prevProps);
102
+ }
103
+ /// Update the view by updating existing props object with the object
104
+ /// given as argument. Equivalent to `view.update(Object.assign({},
105
+ /// view.props, props))`.
106
+ setProps(props) {
107
+ let updated = {};
108
+ for (let name in this._props) {
109
+ updated[name] = this._props[name];
110
+ }
111
+ updated.state = this.state;
112
+ for (let name in props)
113
+ updated[name] = props[name];
114
+ this.update(updated);
115
+ }
116
+ /// Update the editor's `state` prop, without touching any of the
117
+ /// other props.
118
+ updateState(state) {
119
+ this.updateStateInner(state, this._props);
120
+ }
121
+ updateStateInner(state, prevProps) {
122
+ let prev = this.state, redraw = false, updateSel = false;
123
+ // When stored marks are added, stop composition, so that they can
124
+ // be displayed.
125
+ if (state.storedMarks && this.composing) {
126
+ // TODO clearComposition(this)
127
+ updateSel = true;
128
+ }
129
+ this.state = state;
130
+ let pluginsChanged = prev.plugins != state.plugins ||
131
+ this._props.plugins != prevProps.plugins;
132
+ if (pluginsChanged || this._props.plugins != prevProps.plugins ||
133
+ this._props.nodeViews != prevProps.nodeViews) {
134
+ let nodeViews = buildNodeViews(this);
135
+ if (changedNodeViews(nodeViews, this.nodeViews)) {
136
+ this.nodeViews = nodeViews;
137
+ redraw = true;
138
+ }
139
+ }
140
+ this.editable = getEditable(this);
141
+ let updateDoc = redraw;
142
+ if (updateDoc || !state.selection.eq(prev.selection))
143
+ updateSel = true;
144
+ if (updateSel) {
145
+ // Work around an issue in Chrome, IE, and Edge where changing
146
+ // the DOM around an active selection puts it into a broken
147
+ // state where the thing the user sees differs from the
148
+ // selection reported by the Selection object (#710, #973,
149
+ // #1011, #1013, #1035).
150
+ let forceSelUpdate = false;
151
+ if (updateDoc) {
152
+ // If the node that the selection points into is written to,
153
+ // Chrome sometimes starts misreporting the selection, so this
154
+ // tracks that and forces a selection reset when our update
155
+ // did write to the node.
156
+ // TODO if (this.composing) this.input.compositionNode = findCompositionNode(this)
157
+ }
158
+ }
159
+ this.updatePluginViews(prev);
160
+ }
161
+ /// @internal
162
+ scrollToSelection() {
163
+ }
164
+ destroyPluginViews() {
165
+ let view;
166
+ while (view = this.pluginViews.pop())
167
+ if (view.destroy)
168
+ view.destroy();
169
+ }
170
+ updatePluginViews(prevState) {
171
+ if (!prevState || prevState.plugins != this.state.plugins ||
172
+ this.directPlugins != this.prevDirectPlugins) {
173
+ this.prevDirectPlugins = this.directPlugins;
174
+ this.destroyPluginViews();
175
+ for (let i = 0; i < this.directPlugins.length; i++) {
176
+ let plugin = this.directPlugins[i];
177
+ if (plugin.spec.view) {
178
+ this.pluginViews.push(plugin.spec.view(this));
179
+ }
180
+ }
181
+ for (let i = 0; i < this.state.plugins.length; i++) {
182
+ let plugin = this.state.plugins[i];
183
+ if (plugin.spec.view) {
184
+ this.pluginViews.push(plugin.spec.view(this));
185
+ }
186
+ }
187
+ }
188
+ else {
189
+ for (let i = 0; i < this.pluginViews.length; i++) {
190
+ let pluginView = this.pluginViews[i];
191
+ if (pluginView.update)
192
+ pluginView.update(this, prevState);
193
+ }
194
+ }
195
+ }
196
+ someProp(propName, f) {
197
+ let prop = this._props && this._props[propName], value;
198
+ if (prop != null && (value = f ? f(prop) : prop)) {
199
+ return value;
200
+ }
201
+ for (let i = 0; i < this.directPlugins.length; i++) {
202
+ let prop = this.directPlugins[i].props[propName];
203
+ if (prop != null && (value = f ? f(prop) : prop)) {
204
+ return value;
205
+ }
206
+ }
207
+ let plugins = this.state.plugins;
208
+ if (plugins) {
209
+ for (let i = 0; i < plugins.length; i++) {
210
+ let prop = plugins[i].props[propName];
211
+ if (prop != null && (value = f ? f(prop) : prop))
212
+ return value;
213
+ }
214
+ }
215
+ }
216
+ /// Query whether the view has focus.
217
+ hasFocus() {
218
+ return false;
219
+ }
220
+ /// Focus the editor.
221
+ focus() {
222
+ }
223
+ /// Removes the editor from the DOM and destroys all [node
224
+ /// views](#view.NodeView).
225
+ destroy() {
226
+ this.destroyPluginViews();
227
+ }
228
+ /// This is true when the view has been
229
+ /// [destroyed](#view.DummyEditorView.destroy) (and thus should not be
230
+ /// used anymore).
231
+ get isDestroyed() {
232
+ return false;
233
+ }
234
+ /// Used for testing.
235
+ dispatchEvent(event) {
236
+ }
237
+ }
238
+ DummyEditorView.prototype.dispatch = function (tr) {
239
+ let dispatchTransaction = this.props.dispatchTransaction;
240
+ if (dispatchTransaction)
241
+ dispatchTransaction.call(this, tr);
242
+ else
243
+ this.updateState(this.state.apply(tr));
244
+ };
245
+ function getEditable(view) {
246
+ return !view.someProp('editable', (value) => value(view.state) === false);
247
+ }
248
+ function buildNodeViews(view) {
249
+ let result = Object.create(null);
250
+ function add(obj) {
251
+ for (let prop in obj) {
252
+ if (!Object.prototype.hasOwnProperty.call(result, prop)) {
253
+ result[prop] = obj[prop];
254
+ }
255
+ }
256
+ }
257
+ view.someProp('nodeViews', add);
258
+ view.someProp('markViews', add);
259
+ return result;
260
+ }
261
+ function changedNodeViews(a, b) {
262
+ let nA = 0, nB = 0;
263
+ for (let prop in a) {
264
+ if (a[prop] != b[prop])
265
+ return true;
266
+ nA++;
267
+ }
268
+ for (let _ in b)
269
+ nB++;
270
+ return nA != nB;
271
+ }
272
+ function checkStateComponent(plugin) {
273
+ if (plugin.spec.state || plugin.spec.filterTransaction ||
274
+ plugin.spec.appendTransaction) {
275
+ throw new RangeError('Plugins passed directly to the view must not have a state component');
276
+ }
277
+ }