@limetech/lime-elements 37.73.0 → 37.74.0
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 +53 -36
- package/dist/cjs/limel-prosemirror-adapter.cjs.entry.js.map +1 -1
- package/dist/collection/components/text-editor/prosemirror-adapter/plugins/trigger/create-html-inserter.js +11 -0
- package/dist/collection/components/text-editor/prosemirror-adapter/plugins/trigger/create-html-inserter.js.map +1 -0
- package/dist/collection/components/text-editor/prosemirror-adapter/plugins/trigger/factory.js +8 -8
- package/dist/collection/components/text-editor/prosemirror-adapter/plugins/trigger/factory.js.map +1 -1
- package/dist/collection/components/text-editor/prosemirror-adapter/plugins/trigger/inserter.js +35 -27
- package/dist/collection/components/text-editor/prosemirror-adapter/plugins/trigger/inserter.js.map +1 -1
- package/dist/collection/components/text-editor/prosemirror-adapter/prosemirror-adapter.js +1 -1
- package/dist/collection/components/text-editor/prosemirror-adapter/prosemirror-adapter.js.map +1 -1
- package/dist/collection/components/text-editor/text-editor.types.js.map +1 -1
- package/dist/esm/limel-prosemirror-adapter.entry.js +53 -36
- package/dist/esm/limel-prosemirror-adapter.entry.js.map +1 -1
- package/dist/lime-elements/lime-elements.esm.js +1 -1
- package/dist/lime-elements/{p-830d655c.entry.js → p-e83e845a.entry.js} +2 -2
- package/dist/lime-elements/p-e83e845a.entry.js.map +1 -0
- package/dist/types/components/text-editor/prosemirror-adapter/plugins/trigger/create-html-inserter.d.ts +5 -0
- package/dist/types/components/text-editor/prosemirror-adapter/plugins/trigger/factory.d.ts +2 -1
- package/dist/types/components/text-editor/prosemirror-adapter/plugins/trigger/inserter.d.ts +2 -1
- package/dist/types/components/text-editor/text-editor.types.d.ts +4 -1
- package/package.json +1 -1
- package/dist/lime-elements/p-830d655c.entry.js.map +0 -1
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { DOMParser } from 'prosemirror-model';
|
|
2
|
+
export const createHtmlInserter = (view, contentConverter, startPos, dispatchTransaction) => {
|
|
3
|
+
const schema = view.state.schema;
|
|
4
|
+
return async (input) => {
|
|
5
|
+
const container = document.createElement('span');
|
|
6
|
+
container.innerHTML = await contentConverter.parseAsHTML(input, schema);
|
|
7
|
+
const fragment = DOMParser.fromSchema(schema).parse(container).content;
|
|
8
|
+
dispatchTransaction(view, startPos, fragment);
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=create-html-inserter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-html-inserter.js","sourceRoot":"","sources":["../../../../../../src/components/text-editor/prosemirror-adapter/plugins/trigger/create-html-inserter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,SAAS,EAAY,MAAM,mBAAmB,CAAC;AAI9D,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAC9B,IAAgB,EAChB,gBAAsC,EACtC,QAAgB,EAChB,mBAIS,EACyB,EAAE;EACpC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;EAEjC,OAAO,KAAK,EAAE,KAAa,EAAiB,EAAE;IAC1C,MAAM,SAAS,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IACjD,SAAS,CAAC,SAAS,GAAG,MAAM,gBAAgB,CAAC,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAExE,MAAM,QAAQ,GAAG,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC;IAEvE,mBAAmB,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;EAClD,CAAC,CAAC;AACN,CAAC,CAAC","sourcesContent":["import { Node, DOMParser, Fragment } from 'prosemirror-model';\nimport { EditorView } from 'prosemirror-view';\nimport { ContentTypeConverter } from '../../../utils/content-type-converter';\n\nexport const createHtmlInserter = (\n view: EditorView,\n contentConverter: ContentTypeConverter,\n startPos: number,\n dispatchTransaction: (\n view: EditorView,\n startPos: number,\n fragment: Fragment | Node,\n ) => void,\n): ((input: string) => Promise<void>) => {\n const schema = view.state.schema;\n\n return async (input: string): Promise<void> => {\n const container = document.createElement('span');\n container.innerHTML = await contentConverter.parseAsHTML(input, schema);\n\n const fragment = DOMParser.fromSchema(schema).parse(container).content;\n\n dispatchTransaction(view, startPos, fragment);\n };\n};\n"]}
|
package/dist/collection/components/text-editor/prosemirror-adapter/plugins/trigger/factory.js
CHANGED
|
@@ -30,16 +30,16 @@ const stillHasTrigger = (state, activeTrigger, triggerPosition, triggerLength) =
|
|
|
30
30
|
return (state.doc.textBetween(triggerPosition, triggerPosition + 1) ===
|
|
31
31
|
activeTrigger);
|
|
32
32
|
};
|
|
33
|
-
const getTriggerEventDetail = (view, trigger, value) => {
|
|
33
|
+
const getTriggerEventDetail = (view, contentConverter, trigger, value) => {
|
|
34
34
|
return {
|
|
35
35
|
trigger: trigger,
|
|
36
|
-
textEditor: inserterFactory(view),
|
|
36
|
+
textEditor: inserterFactory(view, contentConverter),
|
|
37
37
|
value: value,
|
|
38
38
|
};
|
|
39
39
|
};
|
|
40
|
-
const sendTriggerEvent = (type, view, trigger, value) => {
|
|
40
|
+
const sendTriggerEvent = (type, view, contentConverter, trigger, value) => {
|
|
41
41
|
const event = new CustomEvent(type, {
|
|
42
|
-
detail: getTriggerEventDetail(view, trigger, value),
|
|
42
|
+
detail: getTriggerEventDetail(view, contentConverter, trigger, value),
|
|
43
43
|
bubbles: true,
|
|
44
44
|
composed: true,
|
|
45
45
|
});
|
|
@@ -77,14 +77,14 @@ const processTransactions = (text, transactions, oldState) => {
|
|
|
77
77
|
}
|
|
78
78
|
return text;
|
|
79
79
|
};
|
|
80
|
-
export const createTriggerPlugin = (triggerCharacters) => {
|
|
80
|
+
export const createTriggerPlugin = (triggerCharacters, contentConverter) => {
|
|
81
81
|
let activeTrigger = null;
|
|
82
82
|
let triggerText = '';
|
|
83
83
|
let pluginView = null;
|
|
84
84
|
let triggerPosition = null;
|
|
85
85
|
const stopTrigger = () => {
|
|
86
86
|
triggerText = '';
|
|
87
|
-
sendTriggerEvent('triggerStop', pluginView, activeTrigger, triggerText);
|
|
87
|
+
sendTriggerEvent('triggerStop', pluginView, contentConverter, activeTrigger, triggerText);
|
|
88
88
|
triggerPosition = null;
|
|
89
89
|
activeTrigger = null;
|
|
90
90
|
};
|
|
@@ -103,7 +103,7 @@ export const createTriggerPlugin = (triggerCharacters) => {
|
|
|
103
103
|
activeTrigger = event.data;
|
|
104
104
|
triggerText = '';
|
|
105
105
|
triggerPosition = state.selection.$from.pos - triggerText.length;
|
|
106
|
-
sendTriggerEvent('triggerStart', view, activeTrigger, triggerText);
|
|
106
|
+
sendTriggerEvent('triggerStart', view, contentConverter, activeTrigger, triggerText);
|
|
107
107
|
return false;
|
|
108
108
|
}
|
|
109
109
|
return false;
|
|
@@ -118,7 +118,7 @@ export const createTriggerPlugin = (triggerCharacters) => {
|
|
|
118
118
|
const updatedText = processTransactions(triggerText, transactions, oldState);
|
|
119
119
|
if (updatedText !== triggerText) {
|
|
120
120
|
triggerText = updatedText;
|
|
121
|
-
sendTriggerEvent('triggerChange', pluginView, activeTrigger, triggerText.slice(1));
|
|
121
|
+
sendTriggerEvent('triggerChange', pluginView, contentConverter, activeTrigger, triggerText.slice(1));
|
|
122
122
|
}
|
|
123
123
|
};
|
|
124
124
|
return new Plugin({
|
package/dist/collection/components/text-editor/prosemirror-adapter/plugins/trigger/factory.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.js","sourceRoot":"","sources":["../../../../../../src/components/text-editor/prosemirror-adapter/plugins/trigger/factory.ts"],"names":[],"mappings":"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","sourcesContent":["import { Plugin, PluginKey, EditorState, Transaction } from 'prosemirror-state';\nimport { ReplaceStep, ReplaceAroundStep } from 'prosemirror-transform';\nimport { EditorView } from 'prosemirror-view';\nimport { inserterFactory } from './inserter';\nimport {\n TriggerCharacter,\n TriggerEventDetail,\n} from 'src/components/text-editor/text-editor.types';\n\nconst isTrigger = (\n key: string,\n validTriggers: TriggerCharacter[],\n): key is TriggerCharacter => {\n return key.length === 1 && validTriggers.includes(key as TriggerCharacter);\n};\n\nconst shouldTrigger = (state: EditorState): boolean => {\n const { $from } = state.selection;\n\n if ($from.pos === 1) {\n return true;\n }\n\n // Getting the position immediately before the current selection\n const prevPos = $from.pos - 1;\n\n if (prevPos > 0) {\n // allow trigger if the cursor is at the start of a new paragraph\n if ($from.parentOffset === 0) {\n return true;\n }\n\n const prevChar = state.doc.textBetween(prevPos, $from.pos);\n\n return prevChar === ' ' || prevChar === '\\n';\n }\n\n return false;\n};\n\nconst stillHasTrigger = (\n state: EditorState,\n activeTrigger: string,\n triggerPosition: number,\n triggerLength: number,\n): boolean => {\n const cursorPosition = state.selection.$from.pos;\n\n if (\n cursorPosition < triggerPosition ||\n cursorPosition > triggerPosition + triggerLength + 1\n ) {\n return false;\n }\n\n return (\n state.doc.textBetween(triggerPosition, triggerPosition + 1) ===\n activeTrigger\n );\n};\n\nconst getTriggerEventDetail = (\n view: EditorView,\n trigger: TriggerCharacter,\n value: string,\n): TriggerEventDetail => {\n return {\n trigger: trigger,\n textEditor: inserterFactory(view),\n value: value,\n };\n};\n\nconst sendTriggerEvent = (\n type: 'triggerStart' | 'triggerStop' | 'triggerChange',\n view: EditorView,\n trigger: TriggerCharacter,\n value: string,\n) => {\n const event = new CustomEvent<TriggerEventDetail>(type, {\n detail: getTriggerEventDetail(view, trigger, value),\n bubbles: true,\n composed: true,\n });\n view.dom.dispatchEvent(event);\n};\n\nconst processTransactions = (\n text: string,\n transactions: Transaction[],\n oldState: EditorState,\n): string => {\n let textAdded = '';\n let textRemoved = '';\n\n transactions.forEach((transaction) => {\n if (transaction.docChanged) {\n transaction.steps.forEach((step) => {\n if (\n step instanceof ReplaceStep ||\n step instanceof ReplaceAroundStep\n ) {\n const slice = step.slice;\n const fromPos = step.from;\n const toPos = step.to;\n\n if (slice?.size) {\n // Text added\n textAdded += slice.content.textBetween(0, slice.size);\n } else if (fromPos !== toPos) {\n // Text removed\n const removedText = oldState.doc.textBetween(\n fromPos,\n toPos,\n );\n textRemoved += removedText;\n }\n }\n });\n }\n });\n\n if (textAdded) {\n text += textAdded;\n } else if (textRemoved) {\n text = text.slice(0, -textRemoved.length);\n }\n\n return text;\n};\n\nexport const createTriggerPlugin = (triggerCharacters: TriggerCharacter[]) => {\n let activeTrigger: TriggerCharacter | null = null;\n let triggerText = '';\n let pluginView: EditorView | null = null;\n let triggerPosition: number | null = null;\n\n const stopTrigger = () => {\n triggerText = '';\n sendTriggerEvent('triggerStop', pluginView, activeTrigger, triggerText);\n triggerPosition = null;\n activeTrigger = null;\n };\n\n const handleKeyDown = (_: EditorView, event: any) => {\n if (event.key === 'Escape') {\n stopTrigger();\n\n return true;\n }\n\n return false;\n };\n\n const handleInput = (view: EditorView, event: any) => {\n const { state } = view;\n\n if (\n event.inputType === 'insertText' &&\n isTrigger(event.data, triggerCharacters) &&\n shouldTrigger(state)\n ) {\n activeTrigger = event.data;\n triggerText = '';\n triggerPosition = state.selection.$from.pos - triggerText.length;\n sendTriggerEvent('triggerStart', view, activeTrigger, triggerText);\n\n return false;\n }\n\n return false;\n };\n\n const appendTransactions = (\n transactions: Transaction[],\n oldState: EditorState,\n newState: EditorState,\n ): Transaction => {\n if (!activeTrigger || !triggerPosition || !pluginView) {\n return;\n }\n\n if (\n !stillHasTrigger(\n newState,\n activeTrigger,\n triggerPosition,\n triggerText.length,\n )\n ) {\n return;\n }\n\n const updatedText = processTransactions(\n triggerText,\n transactions,\n oldState,\n );\n\n if (updatedText !== triggerText) {\n triggerText = updatedText;\n sendTriggerEvent(\n 'triggerChange',\n pluginView,\n activeTrigger,\n triggerText.slice(1),\n );\n }\n };\n\n return new Plugin({\n key: new PluginKey('triggerPlugin'),\n view: (view: EditorView) => {\n pluginView = view;\n\n return {};\n },\n state: {\n init: () => {\n return {};\n },\n apply: (transaction: Transaction) => {\n if (transaction.getMeta('stopTrigger')) {\n stopTrigger();\n }\n\n return {};\n },\n },\n props: {\n handleKeyDown: handleKeyDown,\n handleDOMEvents: {\n input: handleInput,\n },\n },\n appendTransaction: appendTransactions,\n });\n};\n"]}
|
|
1
|
+
{"version":3,"file":"factory.js","sourceRoot":"","sources":["../../../../../../src/components/text-editor/prosemirror-adapter/plugins/trigger/factory.ts"],"names":[],"mappings":"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","sourcesContent":["import { Plugin, PluginKey, EditorState, Transaction } from 'prosemirror-state';\nimport { ReplaceStep, ReplaceAroundStep } from 'prosemirror-transform';\nimport { EditorView } from 'prosemirror-view';\nimport { inserterFactory } from './inserter';\nimport {\n TriggerCharacter,\n TriggerEventDetail,\n} from 'src/components/text-editor/text-editor.types';\nimport { ContentTypeConverter } from '../../../utils/content-type-converter';\n\nconst isTrigger = (\n key: string,\n validTriggers: TriggerCharacter[],\n): key is TriggerCharacter => {\n return key.length === 1 && validTriggers.includes(key as TriggerCharacter);\n};\n\nconst shouldTrigger = (state: EditorState): boolean => {\n const { $from } = state.selection;\n\n if ($from.pos === 1) {\n return true;\n }\n\n // Getting the position immediately before the current selection\n const prevPos = $from.pos - 1;\n\n if (prevPos > 0) {\n // allow trigger if the cursor is at the start of a new paragraph\n if ($from.parentOffset === 0) {\n return true;\n }\n\n const prevChar = state.doc.textBetween(prevPos, $from.pos);\n\n return prevChar === ' ' || prevChar === '\\n';\n }\n\n return false;\n};\n\nconst stillHasTrigger = (\n state: EditorState,\n activeTrigger: string,\n triggerPosition: number,\n triggerLength: number,\n): boolean => {\n const cursorPosition = state.selection.$from.pos;\n\n if (\n cursorPosition < triggerPosition ||\n cursorPosition > triggerPosition + triggerLength + 1\n ) {\n return false;\n }\n\n return (\n state.doc.textBetween(triggerPosition, triggerPosition + 1) ===\n activeTrigger\n );\n};\n\nconst getTriggerEventDetail = (\n view: EditorView,\n contentConverter: ContentTypeConverter,\n trigger: TriggerCharacter,\n value: string,\n): TriggerEventDetail => {\n return {\n trigger: trigger,\n textEditor: inserterFactory(view, contentConverter),\n value: value,\n };\n};\n\nconst sendTriggerEvent = (\n type: 'triggerStart' | 'triggerStop' | 'triggerChange',\n view: EditorView,\n contentConverter: ContentTypeConverter,\n trigger: TriggerCharacter,\n value: string,\n) => {\n const event = new CustomEvent<TriggerEventDetail>(type, {\n detail: getTriggerEventDetail(view, contentConverter, trigger, value),\n bubbles: true,\n composed: true,\n });\n view.dom.dispatchEvent(event);\n};\n\nconst processTransactions = (\n text: string,\n transactions: Transaction[],\n oldState: EditorState,\n): string => {\n let textAdded = '';\n let textRemoved = '';\n\n transactions.forEach((transaction) => {\n if (transaction.docChanged) {\n transaction.steps.forEach((step) => {\n if (\n step instanceof ReplaceStep ||\n step instanceof ReplaceAroundStep\n ) {\n const slice = step.slice;\n const fromPos = step.from;\n const toPos = step.to;\n\n if (slice?.size) {\n // Text added\n textAdded += slice.content.textBetween(0, slice.size);\n } else if (fromPos !== toPos) {\n // Text removed\n const removedText = oldState.doc.textBetween(\n fromPos,\n toPos,\n );\n textRemoved += removedText;\n }\n }\n });\n }\n });\n\n if (textAdded) {\n text += textAdded;\n } else if (textRemoved) {\n text = text.slice(0, -textRemoved.length);\n }\n\n return text;\n};\n\nexport const createTriggerPlugin = (\n triggerCharacters: TriggerCharacter[],\n contentConverter: ContentTypeConverter,\n) => {\n let activeTrigger: TriggerCharacter | null = null;\n let triggerText = '';\n let pluginView: EditorView | null = null;\n let triggerPosition: number | null = null;\n\n const stopTrigger = () => {\n triggerText = '';\n sendTriggerEvent(\n 'triggerStop',\n pluginView,\n contentConverter,\n activeTrigger,\n triggerText,\n );\n triggerPosition = null;\n activeTrigger = null;\n };\n\n const handleKeyDown = (_: EditorView, event: any) => {\n if (event.key === 'Escape') {\n stopTrigger();\n\n return true;\n }\n\n return false;\n };\n\n const handleInput = (view: EditorView, event: any) => {\n const { state } = view;\n\n if (\n event.inputType === 'insertText' &&\n isTrigger(event.data, triggerCharacters) &&\n shouldTrigger(state)\n ) {\n activeTrigger = event.data;\n triggerText = '';\n triggerPosition = state.selection.$from.pos - triggerText.length;\n sendTriggerEvent(\n 'triggerStart',\n view,\n contentConverter,\n activeTrigger,\n triggerText,\n );\n\n return false;\n }\n\n return false;\n };\n\n const appendTransactions = (\n transactions: Transaction[],\n oldState: EditorState,\n newState: EditorState,\n ): Transaction => {\n if (!activeTrigger || !triggerPosition || !pluginView) {\n return;\n }\n\n if (\n !stillHasTrigger(\n newState,\n activeTrigger,\n triggerPosition,\n triggerText.length,\n )\n ) {\n return;\n }\n\n const updatedText = processTransactions(\n triggerText,\n transactions,\n oldState,\n );\n\n if (updatedText !== triggerText) {\n triggerText = updatedText;\n sendTriggerEvent(\n 'triggerChange',\n pluginView,\n contentConverter,\n activeTrigger,\n triggerText.slice(1),\n );\n }\n };\n\n return new Plugin({\n key: new PluginKey('triggerPlugin'),\n view: (view: EditorView) => {\n pluginView = view;\n\n return {};\n },\n state: {\n init: () => {\n return {};\n },\n apply: (transaction: Transaction) => {\n if (transaction.getMeta('stopTrigger')) {\n stopTrigger();\n }\n\n return {};\n },\n },\n props: {\n handleKeyDown: handleKeyDown,\n handleDOMEvents: {\n input: handleInput,\n },\n },\n appendTransaction: appendTransactions,\n });\n};\n"]}
|
package/dist/collection/components/text-editor/prosemirror-adapter/plugins/trigger/inserter.js
CHANGED
|
@@ -1,33 +1,41 @@
|
|
|
1
|
-
|
|
1
|
+
import { createHtmlInserter } from './create-html-inserter';
|
|
2
|
+
export const inserterFactory = (view, contentConverter) => {
|
|
2
3
|
const startPos = getTriggerStartPosition(view);
|
|
3
4
|
return {
|
|
4
|
-
insert: (
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const { $from } = selection;
|
|
8
|
-
let node;
|
|
9
|
-
try {
|
|
10
|
-
node = createNode(input, schema);
|
|
11
|
-
}
|
|
12
|
-
catch (error) {
|
|
13
|
-
// eslint-disable-next-line no-console
|
|
14
|
-
console.error(error.message);
|
|
15
|
-
return;
|
|
16
|
-
}
|
|
17
|
-
const spaceNode = schema.text(' ');
|
|
18
|
-
const fragment = schema.nodes.doc.create(null, [node, spaceNode]);
|
|
19
|
-
const transaction = state.tr.replaceWith(startPos, $from.pos, fragment);
|
|
20
|
-
transaction.setMeta('stopTrigger', true);
|
|
21
|
-
dispatch(transaction);
|
|
22
|
-
},
|
|
23
|
-
stopTrigger: () => {
|
|
24
|
-
const { state, dispatch } = view;
|
|
25
|
-
const transaction = state.tr;
|
|
26
|
-
transaction.setMeta('stopTrigger', true);
|
|
27
|
-
dispatch(transaction);
|
|
28
|
-
},
|
|
5
|
+
insert: createNodeAndTextInserter(view, startPos),
|
|
6
|
+
insertHtml: createHtmlInserter(view, contentConverter, startPos, dispatchTransaction),
|
|
7
|
+
stopTrigger: () => stopTriggerTransaction(view),
|
|
29
8
|
};
|
|
30
9
|
};
|
|
10
|
+
const createNodeAndTextInserter = (view, startPos) => (input) => {
|
|
11
|
+
const schema = view.state.schema;
|
|
12
|
+
let node;
|
|
13
|
+
try {
|
|
14
|
+
node = createNode(input, schema);
|
|
15
|
+
}
|
|
16
|
+
catch (error) {
|
|
17
|
+
// eslint-disable-next-line no-console
|
|
18
|
+
console.error(error.message);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const spaceNode = schema.text(' ');
|
|
22
|
+
const fragment = schema.nodes.doc.create(null, [node, spaceNode]);
|
|
23
|
+
dispatchTransaction(view, startPos, fragment);
|
|
24
|
+
};
|
|
25
|
+
const stopTriggerTransaction = (view) => {
|
|
26
|
+
const { state, dispatch } = view;
|
|
27
|
+
const transaction = state.tr;
|
|
28
|
+
transaction.setMeta('stopTrigger', true);
|
|
29
|
+
dispatch(transaction);
|
|
30
|
+
};
|
|
31
|
+
const dispatchTransaction = (view, startPos, fragment) => {
|
|
32
|
+
const state = view.state;
|
|
33
|
+
const dispatch = view.dispatch;
|
|
34
|
+
const fromPos = state.selection.$from.pos;
|
|
35
|
+
const transaction = state.tr.replaceWith(startPos, fromPos, fragment);
|
|
36
|
+
transaction.setMeta('stopTrigger', true);
|
|
37
|
+
dispatch(transaction);
|
|
38
|
+
};
|
|
31
39
|
const createNode = (input, schema) => {
|
|
32
40
|
var _a;
|
|
33
41
|
if (typeof input === 'string') {
|
|
@@ -46,7 +54,7 @@ const createNode = (input, schema) => {
|
|
|
46
54
|
const getCustomNode = (name, schema) => {
|
|
47
55
|
const customNode = Object.values(schema.nodes).find((prosemirrorNode) => prosemirrorNode.name === name);
|
|
48
56
|
if (!customNode) {
|
|
49
|
-
throw new Error(`
|
|
57
|
+
throw new Error(`No custom element has been registered for node ${name}`);
|
|
50
58
|
}
|
|
51
59
|
return customNode;
|
|
52
60
|
};
|
package/dist/collection/components/text-editor/prosemirror-adapter/plugins/trigger/inserter.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inserter.js","sourceRoot":"","sources":["../../../../../../src/components/text-editor/prosemirror-adapter/plugins/trigger/inserter.ts"],"names":[],"mappings":"AAOA,MAAM,CAAC,MAAM,eAAe,GAAG,
|
|
1
|
+
{"version":3,"file":"inserter.js","sourceRoot":"","sources":["../../../../../../src/components/text-editor/prosemirror-adapter/plugins/trigger/inserter.ts"],"names":[],"mappings":"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","sourcesContent":["import { Node, NodeType, Schema, Fragment } from 'prosemirror-model';\nimport { EditorView } from 'prosemirror-view';\nimport {\n TextEditor,\n TextEditorNode,\n} from 'src/components/text-editor/text-editor.types';\nimport { ContentTypeConverter } from '../../../utils/content-type-converter';\nimport { createHtmlInserter } from './create-html-inserter';\n\nexport const inserterFactory = (\n view: EditorView,\n contentConverter: ContentTypeConverter,\n): TextEditor => {\n const startPos = getTriggerStartPosition(view);\n\n return {\n insert: createNodeAndTextInserter(view, startPos),\n insertHtml: createHtmlInserter(\n view,\n contentConverter,\n startPos,\n dispatchTransaction,\n ),\n stopTrigger: () => stopTriggerTransaction(view),\n };\n};\n\nconst createNodeAndTextInserter =\n (view: EditorView, startPos: number) =>\n (input: TextEditorNode | string): void => {\n const schema = view.state.schema;\n let node: Node;\n\n try {\n node = createNode(input, schema);\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error(error.message);\n\n return;\n }\n\n const spaceNode = schema.text(' ');\n\n const fragment = schema.nodes.doc.create(null, [node, spaceNode]);\n\n dispatchTransaction(view, startPos, fragment);\n };\n\nconst stopTriggerTransaction = (view: EditorView): void => {\n const { state, dispatch } = view;\n\n const transaction = state.tr;\n transaction.setMeta('stopTrigger', true);\n\n dispatch(transaction);\n};\n\nconst dispatchTransaction = (\n view: EditorView,\n startPos: number,\n fragment: Fragment | Node,\n): void => {\n const state = view.state;\n const dispatch = view.dispatch;\n const fromPos = state.selection.$from.pos;\n\n const transaction = state.tr.replaceWith(startPos, fromPos, fragment);\n transaction.setMeta('stopTrigger', true);\n dispatch(transaction);\n};\n\nconst createNode = (input: TextEditorNode | string, schema: Schema): Node => {\n if (typeof input === 'string') {\n return schema.text(input);\n }\n\n const node = input.node;\n\n if (typeof node === 'string') {\n return schema.text(node);\n }\n\n const customNode = getCustomNode(node.tagName, schema);\n\n const childNodes: Node[] = (input.children ?? [])\n .map((child) => createNode(child, schema))\n .filter(Boolean);\n\n return customNode.create(node.attributes, childNodes);\n};\n\nconst getCustomNode = (name: string, schema: Schema): NodeType => {\n const customNode = Object.values(schema.nodes).find(\n (prosemirrorNode) => prosemirrorNode.name === name,\n );\n\n if (!customNode) {\n throw new Error(\n `No custom element has been registered for node ${name}`,\n );\n }\n\n return customNode;\n};\n\nconst getTriggerStartPosition = (view: EditorView): number => {\n return view.state?.selection?.$from?.pos;\n};\n"]}
|
|
@@ -253,7 +253,7 @@ export class ProsemirrorAdapter {
|
|
|
253
253
|
...exampleSetup({ schema: this.schema, menuBar: false }),
|
|
254
254
|
keymap(this.menuCommandFactory.buildKeymap()),
|
|
255
255
|
createLinkPlugin(this.handleNewLinkSelection),
|
|
256
|
-
createTriggerPlugin(this.triggerCharacters),
|
|
256
|
+
createTriggerPlugin(this.triggerCharacters, this.contentConverter),
|
|
257
257
|
createImageRemoverPlugin(),
|
|
258
258
|
createMenuStateTrackingPlugin(editorMenuTypesArray, this.menuCommandFactory, this.updateActiveActionBarItems),
|
|
259
259
|
createActionBarInteractionPlugin(this.menuCommandFactory),
|
package/dist/collection/components/text-editor/prosemirror-adapter/prosemirror-adapter.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prosemirror-adapter.js","sourceRoot":"","sources":["../../../../src/components/text-editor/prosemirror-adapter/prosemirror-adapter.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n Element,\n Event,\n EventEmitter,\n Host,\n Prop,\n State,\n Watch,\n h,\n} from '@stencil/core';\nimport { EditorState, Transaction } from 'prosemirror-state';\nimport { EditorView } from 'prosemirror-view';\nimport { Schema, DOMParser } from 'prosemirror-model';\nimport { schema } from 'prosemirror-schema-basic';\nimport { addListNodes } from 'prosemirror-schema-list';\nimport { exampleSetup } from 'prosemirror-example-setup';\nimport { keymap } from 'prosemirror-keymap';\nimport { ActionBarItem } from 'src/components/action-bar/action-bar.types';\nimport { ListSeparator } from 'src/components/list/list-item.types';\nimport { MenuCommandFactory } from './menu/menu-commands';\nimport { menuTranslationIDs, getTextEditorMenuItems } from './menu/menu-items';\nimport { ContentTypeConverter } from '../utils/content-type-converter';\nimport { MarkdownConverter } from '../utils/markdown-converter';\nimport { HTMLConverter } from '../utils/html-converter';\nimport {\n EditorMenuTypes,\n EditorTextLink,\n editorMenuTypesArray,\n} from './menu/types';\nimport translate from 'src/global/translations';\nimport { createRandomString } from 'src/util/random-string';\nimport { isItem } from 'src/components/action-bar/isItem';\nimport { cloneDeep, debounce } from 'lodash-es';\nimport { Languages } from '../../date-picker/date.types';\nimport { strikethrough } from './menu/menu-schema-extender';\nimport {\n EditorLinkMenuEventDetail,\n createLinkPlugin,\n} from './plugins/link-plugin';\nimport { createImageRemoverPlugin } from './plugins/image-remover-plugin';\nimport { createMenuStateTrackingPlugin } from './plugins/menu-state-tracking-plugin';\nimport { createActionBarInteractionPlugin } from './plugins/menu-action-interaction-plugin';\nimport { CustomElementDefinition } from '../../../global/shared-types/custom-element.types';\nimport { createNodeSpec } from '../utils/plugin-factory';\nimport { createTriggerPlugin } from './plugins/trigger/factory';\nimport { TriggerCharacter } from '../text-editor.types';\nimport { getTableNodes, getTableEditingPlugins } from './plugins/table-plugin';\n\nconst DEBOUNCE_TIMEOUT = 300;\n\n/**\n * The ProseMirror adapter offers a rich text editing experience with markdown support.\n * [Read more...](https://prosemirror.net/)\n *\n * @exampleComponent limel-example-prosemirror-adapter-basic\n * @exampleComponent limel-example-prosemirror-adapter-with-custom-menu\n * @beta\n * @private\n */\n@Component({\n tag: 'limel-prosemirror-adapter',\n shadow: true,\n styleUrl: 'prosemirror-adapter.scss',\n})\nexport class ProsemirrorAdapter {\n /**\n * The type of content that the editor should handle and emit, defaults to `markdown`\n *\n * Assumed to be set only once, so not reactive to changes\n */\n @Prop()\n public contentType: 'markdown' | 'html' = 'markdown';\n\n /**\n * The value of the editor, expected to be markdown\n */\n @Prop()\n public value: string;\n\n /**\n * Defines the language for translations.\n */\n @Prop({ reflect: true })\n public language: Languages;\n\n /**\n * Set to `true` to disable the field.\n * Use `disabled` to indicate that the field can normally be interacted\n * with, but is currently disabled. This tells the user that if certain\n * requirements are met, the field may become enabled again.\n */\n @Prop({ reflect: true })\n public disabled?: boolean = false;\n\n /**\n * set to private to avoid usage while under development\n *\n * @private\n * @alpha\n */\n @Prop()\n customElements: CustomElementDefinition[] = [];\n\n /**\n * set to private to avoid usage while under development\n *\n * @private\n * @alpha\n */\n @Prop()\n triggerCharacters: TriggerCharacter[] = [];\n\n @Element()\n private host: HTMLLimelTextEditorElement;\n\n private portalId: string;\n\n @State()\n private view: EditorView;\n\n @State()\n private actionBarItems: Array<\n ActionBarItem<EditorMenuTypes> | ListSeparator\n > = [];\n\n @State()\n private link: EditorTextLink = { href: 'https://' };\n\n /**\n * Open state of the dialog\n */\n @State()\n public isLinkMenuOpen: boolean = false;\n\n private menuCommandFactory: MenuCommandFactory;\n private schema: Schema;\n private contentConverter: ContentTypeConverter;\n private actionBarElement: HTMLElement;\n private lastEmittedValue: string;\n private changeWaiting = false;\n\n /**\n * Used to stop change event emitting as result of getting updated value from consumer\n */\n private suppressChangeEvent = false;\n\n /**\n * Dispatched when a change is made to the editor\n */\n @Event()\n private change: EventEmitter<string>;\n\n constructor() {\n this.portalId = createRandomString();\n }\n\n @Watch('value')\n protected watchValue(newValue: string) {\n if (!this.view) {\n return;\n }\n\n if (this.changeWaiting) {\n // A change is pending; do not update the editor's content\n return;\n }\n\n const currentContent = this.contentConverter.serialize(\n this.view,\n this.schema,\n );\n\n // If the new value is the same as the current content, do nothing\n if (newValue === currentContent) {\n return;\n }\n\n // Update the editor's content with the new value\n this.updateView(newValue);\n }\n\n public componentWillLoad() {\n this.getActionBarItems();\n this.setupContentConverter();\n }\n\n public componentDidLoad() {\n // Stencil complains loudly about triggering rerenders in\n // componentDidLoad, but we have to, so we're using setTimeout to\n // suppress the warning. /Ads\n setTimeout(() => {\n this.initializeTextEditor();\n }, 0);\n }\n\n public connectedCallback() {\n if (this.view) {\n this.initializeTextEditor();\n }\n\n this.host.addEventListener(\n 'open-editor-link-menu',\n this.handleOpenLinkMenu,\n );\n }\n\n public disconnectedCallback() {\n this.host.removeEventListener(\n 'open-editor-link-menu',\n this.handleOpenLinkMenu,\n );\n this.view?.dom?.removeEventListener('blur', this.handleBlur);\n this.view?.destroy();\n }\n\n public render() {\n return (\n <Host onFocus={this.handleFocus}>\n <div id=\"editor\" />\n <div class=\"toolbar\">\n <limel-action-bar\n ref={(el) => (this.actionBarElement = el)}\n accessibleLabel=\"Toolbar\"\n actions={this.actionBarItems}\n onItemSelected={this.handleActionBarItem}\n />\n </div>\n {this.renderLinkMenu()}\n </Host>\n );\n }\n\n renderLinkMenu() {\n if (!this.isLinkMenuOpen) {\n return;\n }\n\n return (\n <limel-portal\n containerId={this.portalId}\n visible={this.isLinkMenuOpen}\n openDirection=\"top\"\n inheritParentWidth={true}\n anchor={this.actionBarElement}\n >\n <limel-text-editor-link-menu\n link={this.link}\n isOpen={this.isLinkMenuOpen}\n onLinkChange={this.handleLinkChange}\n onCancel={this.handleCancelLinkMenu}\n onSave={this.handleSaveLinkMenu}\n />\n </limel-portal>\n );\n }\n\n private setupContentConverter() {\n if (this.contentType === 'markdown') {\n this.contentConverter = new MarkdownConverter(this.customElements);\n } else if (this.contentType === 'html') {\n this.contentConverter = new HTMLConverter(this.customElements);\n } else {\n throw new Error(\n `Unsupported content type: ${this.contentType}. Only 'markdown' and 'html' are supported.`,\n );\n }\n }\n\n private getActionBarItems = () => {\n this.actionBarItems = getTextEditorMenuItems().map(\n this.getTranslatedItem,\n );\n };\n\n private getTranslatedItem = (item) => {\n const newItem = cloneDeep(item);\n\n if (isItem(item)) {\n const translationId = menuTranslationIDs[item.value];\n\n if (translationId) {\n newItem.text = translate.get(translationId, this.language);\n }\n }\n\n return newItem;\n };\n\n private async initializeTextEditor() {\n this.schema = this.initializeSchema();\n const initialDoc = await this.parseInitialContent();\n this.menuCommandFactory = new MenuCommandFactory(this.schema);\n this.view = new EditorView(\n this.host.shadowRoot.querySelector('#editor'),\n {\n state: this.createEditorState(initialDoc),\n dispatchTransaction: this.handleTransaction,\n },\n );\n\n this.view.dom.addEventListener('blur', this.handleBlur);\n\n if (this.value) {\n this.updateView(this.value);\n }\n }\n\n private initializeSchema() {\n let nodes = schema.spec.nodes;\n\n this.customElements.forEach((customElement) => {\n const newNodeSpec = createNodeSpec(customElement);\n const nodeName = customElement.tagName;\n\n nodes = nodes.append({ [nodeName]: newNodeSpec });\n });\n nodes = addListNodes(nodes, 'paragraph block*', 'block');\n\n if (this.contentType === 'html') {\n nodes = nodes.append(getTableNodes());\n }\n\n return new Schema({\n nodes: nodes,\n marks: schema.spec.marks.append({\n strikethrough: strikethrough,\n }),\n });\n }\n\n private async parseInitialContent() {\n const initialContentElement = document.createElement('div');\n\n if (this.value) {\n initialContentElement.innerHTML =\n await this.contentConverter.parseAsHTML(\n this.value,\n this.schema,\n );\n } else {\n initialContentElement.innerHTML = '<p></p>';\n }\n\n return DOMParser.fromSchema(this.schema).parse(initialContentElement);\n }\n\n private createEditorState(initialDoc) {\n return EditorState.create({\n doc: initialDoc,\n plugins: [\n ...exampleSetup({ schema: this.schema, menuBar: false }),\n keymap(this.menuCommandFactory.buildKeymap()),\n createLinkPlugin(this.handleNewLinkSelection),\n createTriggerPlugin(this.triggerCharacters),\n createImageRemoverPlugin(),\n createMenuStateTrackingPlugin(\n editorMenuTypesArray,\n this.menuCommandFactory,\n this.updateActiveActionBarItems,\n ),\n createActionBarInteractionPlugin(this.menuCommandFactory),\n ...getTableEditingPlugins(this.contentType === 'html'),\n ],\n });\n }\n\n private updateActiveActionBarItems = (\n activeTypes: Record<EditorMenuTypes, boolean>,\n ) => {\n const newItems = getTextEditorMenuItems().map((item) => {\n if (isItem(item)) {\n return {\n ...item,\n selected: activeTypes[item.value],\n };\n }\n\n return item;\n });\n\n this.actionBarItems = newItems;\n };\n\n private async updateView(content: string) {\n this.suppressChangeEvent = true;\n const html = await this.contentConverter.parseAsHTML(\n content,\n this.schema,\n );\n const prosemirrorDOMparser = DOMParser.fromSchema(\n this.view.state.schema,\n );\n const domParser = new window.DOMParser();\n const doc = domParser.parseFromString(html, 'text/html');\n const prosemirrorDoc = prosemirrorDOMparser.parse(doc.body);\n const tr = this.view.state.tr;\n tr.replaceWith(0, tr.doc.content.size, prosemirrorDoc.content);\n this.view.dispatch(tr);\n this.suppressChangeEvent = false;\n }\n\n private handleTransaction = (transaction: Transaction) => {\n const newState = this.view.state.apply(transaction);\n this.view.updateState(newState);\n\n if (this.suppressChangeEvent || transaction.getMeta('pointer')) {\n return;\n }\n\n const content = this.contentConverter.serialize(this.view, this.schema);\n\n if (content === this.lastEmittedValue) {\n return;\n }\n\n this.lastEmittedValue = content;\n this.changeWaiting = true;\n this.changeEmitter(content);\n };\n\n private handleActionBarItem = (\n event: CustomEvent<ActionBarItem<EditorMenuTypes>>,\n ) => {\n event.preventDefault();\n event.stopImmediatePropagation();\n const { value } = event.detail;\n\n if (value === EditorMenuTypes.Link) {\n this.isLinkMenuOpen = true;\n\n return;\n }\n\n const actionBarEvent = new CustomEvent('actionBarItemClick', {\n detail: event.detail,\n });\n this.view.dom.dispatchEvent(actionBarEvent);\n };\n\n private handleCancelLinkMenu = (event: CustomEvent<void>) => {\n event.preventDefault();\n event.stopPropagation();\n\n this.isLinkMenuOpen = false;\n this.link = { text: '', href: 'https://' };\n };\n\n private handleSaveLinkMenu = () => {\n this.isLinkMenuOpen = false;\n\n const saveLinkEvent = new CustomEvent('saveLinkMenu', {\n detail: {\n type: EditorMenuTypes.Link,\n link: this.link,\n },\n });\n this.view.dom.dispatchEvent(saveLinkEvent);\n\n this.link = { href: 'https://' };\n };\n\n private handleLinkChange = (event: CustomEvent<EditorTextLink>) => {\n this.link = event.detail;\n };\n\n private handleFocus = () => {\n if (!this.disabled) {\n this.view?.focus();\n }\n };\n\n private handleNewLinkSelection = (text: string, href: string) => {\n this.link.text = text;\n this.link.href = href || 'https://';\n };\n\n private handleOpenLinkMenu = (\n event: CustomEvent<EditorLinkMenuEventDetail>,\n ) => {\n event.stopImmediatePropagation();\n const { href, text } = event.detail;\n this.link = { href: href, text: text };\n this.isLinkMenuOpen = true;\n };\n\n private changeEmitter = debounce((value: string) => {\n this.change.emit(value);\n this.changeWaiting = false;\n }, DEBOUNCE_TIMEOUT);\n\n private handleBlur = () => {\n this.changeEmitter.flush();\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"prosemirror-adapter.js","sourceRoot":"","sources":["../../../../src/components/text-editor/prosemirror-adapter/prosemirror-adapter.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n Element,\n Event,\n EventEmitter,\n Host,\n Prop,\n State,\n Watch,\n h,\n} from '@stencil/core';\nimport { EditorState, Transaction } from 'prosemirror-state';\nimport { EditorView } from 'prosemirror-view';\nimport { Schema, DOMParser } from 'prosemirror-model';\nimport { schema } from 'prosemirror-schema-basic';\nimport { addListNodes } from 'prosemirror-schema-list';\nimport { exampleSetup } from 'prosemirror-example-setup';\nimport { keymap } from 'prosemirror-keymap';\nimport { ActionBarItem } from 'src/components/action-bar/action-bar.types';\nimport { ListSeparator } from 'src/components/list/list-item.types';\nimport { MenuCommandFactory } from './menu/menu-commands';\nimport { menuTranslationIDs, getTextEditorMenuItems } from './menu/menu-items';\nimport { ContentTypeConverter } from '../utils/content-type-converter';\nimport { MarkdownConverter } from '../utils/markdown-converter';\nimport { HTMLConverter } from '../utils/html-converter';\nimport {\n EditorMenuTypes,\n EditorTextLink,\n editorMenuTypesArray,\n} from './menu/types';\nimport translate from 'src/global/translations';\nimport { createRandomString } from 'src/util/random-string';\nimport { isItem } from 'src/components/action-bar/isItem';\nimport { cloneDeep, debounce } from 'lodash-es';\nimport { Languages } from '../../date-picker/date.types';\nimport { strikethrough } from './menu/menu-schema-extender';\nimport {\n EditorLinkMenuEventDetail,\n createLinkPlugin,\n} from './plugins/link-plugin';\nimport { createImageRemoverPlugin } from './plugins/image-remover-plugin';\nimport { createMenuStateTrackingPlugin } from './plugins/menu-state-tracking-plugin';\nimport { createActionBarInteractionPlugin } from './plugins/menu-action-interaction-plugin';\nimport { CustomElementDefinition } from '../../../global/shared-types/custom-element.types';\nimport { createNodeSpec } from '../utils/plugin-factory';\nimport { createTriggerPlugin } from './plugins/trigger/factory';\nimport { TriggerCharacter } from '../text-editor.types';\nimport { getTableNodes, getTableEditingPlugins } from './plugins/table-plugin';\n\nconst DEBOUNCE_TIMEOUT = 300;\n\n/**\n * The ProseMirror adapter offers a rich text editing experience with markdown support.\n * [Read more...](https://prosemirror.net/)\n *\n * @exampleComponent limel-example-prosemirror-adapter-basic\n * @exampleComponent limel-example-prosemirror-adapter-with-custom-menu\n * @beta\n * @private\n */\n@Component({\n tag: 'limel-prosemirror-adapter',\n shadow: true,\n styleUrl: 'prosemirror-adapter.scss',\n})\nexport class ProsemirrorAdapter {\n /**\n * The type of content that the editor should handle and emit, defaults to `markdown`\n *\n * Assumed to be set only once, so not reactive to changes\n */\n @Prop()\n public contentType: 'markdown' | 'html' = 'markdown';\n\n /**\n * The value of the editor, expected to be markdown\n */\n @Prop()\n public value: string;\n\n /**\n * Defines the language for translations.\n */\n @Prop({ reflect: true })\n public language: Languages;\n\n /**\n * Set to `true` to disable the field.\n * Use `disabled` to indicate that the field can normally be interacted\n * with, but is currently disabled. This tells the user that if certain\n * requirements are met, the field may become enabled again.\n */\n @Prop({ reflect: true })\n public disabled?: boolean = false;\n\n /**\n * set to private to avoid usage while under development\n *\n * @private\n * @alpha\n */\n @Prop()\n customElements: CustomElementDefinition[] = [];\n\n /**\n * set to private to avoid usage while under development\n *\n * @private\n * @alpha\n */\n @Prop()\n triggerCharacters: TriggerCharacter[] = [];\n\n @Element()\n private host: HTMLLimelTextEditorElement;\n\n private portalId: string;\n\n @State()\n private view: EditorView;\n\n @State()\n private actionBarItems: Array<\n ActionBarItem<EditorMenuTypes> | ListSeparator\n > = [];\n\n @State()\n private link: EditorTextLink = { href: 'https://' };\n\n /**\n * Open state of the dialog\n */\n @State()\n public isLinkMenuOpen: boolean = false;\n\n private menuCommandFactory: MenuCommandFactory;\n private schema: Schema;\n private contentConverter: ContentTypeConverter;\n private actionBarElement: HTMLElement;\n private lastEmittedValue: string;\n private changeWaiting = false;\n\n /**\n * Used to stop change event emitting as result of getting updated value from consumer\n */\n private suppressChangeEvent = false;\n\n /**\n * Dispatched when a change is made to the editor\n */\n @Event()\n private change: EventEmitter<string>;\n\n constructor() {\n this.portalId = createRandomString();\n }\n\n @Watch('value')\n protected watchValue(newValue: string) {\n if (!this.view) {\n return;\n }\n\n if (this.changeWaiting) {\n // A change is pending; do not update the editor's content\n return;\n }\n\n const currentContent = this.contentConverter.serialize(\n this.view,\n this.schema,\n );\n\n // If the new value is the same as the current content, do nothing\n if (newValue === currentContent) {\n return;\n }\n\n // Update the editor's content with the new value\n this.updateView(newValue);\n }\n\n public componentWillLoad() {\n this.getActionBarItems();\n this.setupContentConverter();\n }\n\n public componentDidLoad() {\n // Stencil complains loudly about triggering rerenders in\n // componentDidLoad, but we have to, so we're using setTimeout to\n // suppress the warning. /Ads\n setTimeout(() => {\n this.initializeTextEditor();\n }, 0);\n }\n\n public connectedCallback() {\n if (this.view) {\n this.initializeTextEditor();\n }\n\n this.host.addEventListener(\n 'open-editor-link-menu',\n this.handleOpenLinkMenu,\n );\n }\n\n public disconnectedCallback() {\n this.host.removeEventListener(\n 'open-editor-link-menu',\n this.handleOpenLinkMenu,\n );\n this.view?.dom?.removeEventListener('blur', this.handleBlur);\n this.view?.destroy();\n }\n\n public render() {\n return (\n <Host onFocus={this.handleFocus}>\n <div id=\"editor\" />\n <div class=\"toolbar\">\n <limel-action-bar\n ref={(el) => (this.actionBarElement = el)}\n accessibleLabel=\"Toolbar\"\n actions={this.actionBarItems}\n onItemSelected={this.handleActionBarItem}\n />\n </div>\n {this.renderLinkMenu()}\n </Host>\n );\n }\n\n renderLinkMenu() {\n if (!this.isLinkMenuOpen) {\n return;\n }\n\n return (\n <limel-portal\n containerId={this.portalId}\n visible={this.isLinkMenuOpen}\n openDirection=\"top\"\n inheritParentWidth={true}\n anchor={this.actionBarElement}\n >\n <limel-text-editor-link-menu\n link={this.link}\n isOpen={this.isLinkMenuOpen}\n onLinkChange={this.handleLinkChange}\n onCancel={this.handleCancelLinkMenu}\n onSave={this.handleSaveLinkMenu}\n />\n </limel-portal>\n );\n }\n\n private setupContentConverter() {\n if (this.contentType === 'markdown') {\n this.contentConverter = new MarkdownConverter(this.customElements);\n } else if (this.contentType === 'html') {\n this.contentConverter = new HTMLConverter(this.customElements);\n } else {\n throw new Error(\n `Unsupported content type: ${this.contentType}. Only 'markdown' and 'html' are supported.`,\n );\n }\n }\n\n private getActionBarItems = () => {\n this.actionBarItems = getTextEditorMenuItems().map(\n this.getTranslatedItem,\n );\n };\n\n private getTranslatedItem = (item) => {\n const newItem = cloneDeep(item);\n\n if (isItem(item)) {\n const translationId = menuTranslationIDs[item.value];\n\n if (translationId) {\n newItem.text = translate.get(translationId, this.language);\n }\n }\n\n return newItem;\n };\n\n private async initializeTextEditor() {\n this.schema = this.initializeSchema();\n const initialDoc = await this.parseInitialContent();\n this.menuCommandFactory = new MenuCommandFactory(this.schema);\n this.view = new EditorView(\n this.host.shadowRoot.querySelector('#editor'),\n {\n state: this.createEditorState(initialDoc),\n dispatchTransaction: this.handleTransaction,\n },\n );\n\n this.view.dom.addEventListener('blur', this.handleBlur);\n\n if (this.value) {\n this.updateView(this.value);\n }\n }\n\n private initializeSchema() {\n let nodes = schema.spec.nodes;\n\n this.customElements.forEach((customElement) => {\n const newNodeSpec = createNodeSpec(customElement);\n const nodeName = customElement.tagName;\n\n nodes = nodes.append({ [nodeName]: newNodeSpec });\n });\n nodes = addListNodes(nodes, 'paragraph block*', 'block');\n\n if (this.contentType === 'html') {\n nodes = nodes.append(getTableNodes());\n }\n\n return new Schema({\n nodes: nodes,\n marks: schema.spec.marks.append({\n strikethrough: strikethrough,\n }),\n });\n }\n\n private async parseInitialContent() {\n const initialContentElement = document.createElement('div');\n\n if (this.value) {\n initialContentElement.innerHTML =\n await this.contentConverter.parseAsHTML(\n this.value,\n this.schema,\n );\n } else {\n initialContentElement.innerHTML = '<p></p>';\n }\n\n return DOMParser.fromSchema(this.schema).parse(initialContentElement);\n }\n\n private createEditorState(initialDoc) {\n return EditorState.create({\n doc: initialDoc,\n plugins: [\n ...exampleSetup({ schema: this.schema, menuBar: false }),\n keymap(this.menuCommandFactory.buildKeymap()),\n createLinkPlugin(this.handleNewLinkSelection),\n createTriggerPlugin(\n this.triggerCharacters,\n this.contentConverter,\n ),\n createImageRemoverPlugin(),\n createMenuStateTrackingPlugin(\n editorMenuTypesArray,\n this.menuCommandFactory,\n this.updateActiveActionBarItems,\n ),\n createActionBarInteractionPlugin(this.menuCommandFactory),\n ...getTableEditingPlugins(this.contentType === 'html'),\n ],\n });\n }\n\n private updateActiveActionBarItems = (\n activeTypes: Record<EditorMenuTypes, boolean>,\n ) => {\n const newItems = getTextEditorMenuItems().map((item) => {\n if (isItem(item)) {\n return {\n ...item,\n selected: activeTypes[item.value],\n };\n }\n\n return item;\n });\n\n this.actionBarItems = newItems;\n };\n\n private async updateView(content: string) {\n this.suppressChangeEvent = true;\n const html = await this.contentConverter.parseAsHTML(\n content,\n this.schema,\n );\n const prosemirrorDOMparser = DOMParser.fromSchema(\n this.view.state.schema,\n );\n const domParser = new window.DOMParser();\n const doc = domParser.parseFromString(html, 'text/html');\n const prosemirrorDoc = prosemirrorDOMparser.parse(doc.body);\n const tr = this.view.state.tr;\n tr.replaceWith(0, tr.doc.content.size, prosemirrorDoc.content);\n this.view.dispatch(tr);\n this.suppressChangeEvent = false;\n }\n\n private handleTransaction = (transaction: Transaction) => {\n const newState = this.view.state.apply(transaction);\n this.view.updateState(newState);\n\n if (this.suppressChangeEvent || transaction.getMeta('pointer')) {\n return;\n }\n\n const content = this.contentConverter.serialize(this.view, this.schema);\n\n if (content === this.lastEmittedValue) {\n return;\n }\n\n this.lastEmittedValue = content;\n this.changeWaiting = true;\n this.changeEmitter(content);\n };\n\n private handleActionBarItem = (\n event: CustomEvent<ActionBarItem<EditorMenuTypes>>,\n ) => {\n event.preventDefault();\n event.stopImmediatePropagation();\n const { value } = event.detail;\n\n if (value === EditorMenuTypes.Link) {\n this.isLinkMenuOpen = true;\n\n return;\n }\n\n const actionBarEvent = new CustomEvent('actionBarItemClick', {\n detail: event.detail,\n });\n this.view.dom.dispatchEvent(actionBarEvent);\n };\n\n private handleCancelLinkMenu = (event: CustomEvent<void>) => {\n event.preventDefault();\n event.stopPropagation();\n\n this.isLinkMenuOpen = false;\n this.link = { text: '', href: 'https://' };\n };\n\n private handleSaveLinkMenu = () => {\n this.isLinkMenuOpen = false;\n\n const saveLinkEvent = new CustomEvent('saveLinkMenu', {\n detail: {\n type: EditorMenuTypes.Link,\n link: this.link,\n },\n });\n this.view.dom.dispatchEvent(saveLinkEvent);\n\n this.link = { href: 'https://' };\n };\n\n private handleLinkChange = (event: CustomEvent<EditorTextLink>) => {\n this.link = event.detail;\n };\n\n private handleFocus = () => {\n if (!this.disabled) {\n this.view?.focus();\n }\n };\n\n private handleNewLinkSelection = (text: string, href: string) => {\n this.link.text = text;\n this.link.href = href || 'https://';\n };\n\n private handleOpenLinkMenu = (\n event: CustomEvent<EditorLinkMenuEventDetail>,\n ) => {\n event.stopImmediatePropagation();\n const { href, text } = event.detail;\n this.link = { href: href, text: text };\n this.isLinkMenuOpen = true;\n };\n\n private changeEmitter = debounce((value: string) => {\n this.change.emit(value);\n this.changeWaiting = false;\n }, DEBOUNCE_TIMEOUT);\n\n private handleBlur = () => {\n this.changeEmitter.flush();\n };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text-editor.types.js","sourceRoot":"","sources":["../../../src/components/text-editor/text-editor.types.ts"],"names":[],"mappings":"","sourcesContent":["import { CustomElement } from '../../global/shared-types/custom-element.types';\n\n/**\n * @alpha\n */\nexport type TriggerCharacter =\n | '@'\n | '#'\n | '$'\n | '!'\n | '?'\n | '&'\n | '*'\n | '%'\n | '+'\n | '-'\n | '='\n | '/'\n | '\\\\'\n | '^'\n | '~'\n | '`'\n | ':'\n | ';'\n | '|'\n | '.'\n | ','\n | '<'\n | '>'\n | '['\n | ']'\n | '{'\n | '}'\n | '('\n | ')'\n | \"'\";\n\n/**\n * @alpha\n */\nexport type TextEditorNode = {\n /**\n * The top node\n */\n node: CustomElement | string;\n\n /**\n * One more more children under the top node\n */\n children?: Array<TextEditorNode | string>;\n};\n\n/**\n * @alpha\n */\nexport interface TextEditor {\n /**\n * Method to insert either text or a node at the cursor position\n
|
|
1
|
+
{"version":3,"file":"text-editor.types.js","sourceRoot":"","sources":["../../../src/components/text-editor/text-editor.types.ts"],"names":[],"mappings":"","sourcesContent":["import { CustomElement } from '../../global/shared-types/custom-element.types';\n\n/**\n * @alpha\n */\nexport type TriggerCharacter =\n | '@'\n | '#'\n | '$'\n | '!'\n | '?'\n | '&'\n | '*'\n | '%'\n | '+'\n | '-'\n | '='\n | '/'\n | '\\\\'\n | '^'\n | '~'\n | '`'\n | ':'\n | ';'\n | '|'\n | '.'\n | ','\n | '<'\n | '>'\n | '['\n | ']'\n | '{'\n | '}'\n | '('\n | ')'\n | \"'\";\n\n/**\n * @alpha\n */\nexport type TextEditorNode = {\n /**\n * The top node\n */\n node: CustomElement | string;\n\n /**\n * One more more children under the top node\n */\n children?: Array<TextEditorNode | string>;\n};\n\n/**\n * @alpha\n */\nexport interface TextEditor {\n /**\n * Method to insert either text or a node at the cursor position\n */\n insert: (input: TextEditorNode | string) => void;\n\n /**\n * Method to insert an HTML string at the cursor position\n */\n insertHtml: (input: string) => Promise<void>;\n\n stopTrigger: () => void;\n}\n\n/**\n * @alpha\n */\nexport interface TriggerEventDetail {\n /**\n * The trigger that triggered this event\n *\n */\n trigger: TriggerCharacter;\n\n /**\n * The text editor\n */\n textEditor: TextEditor;\n\n /**\n * Current value of the trigger\n */\n value: string;\n}\n"]}
|
|
@@ -26121,36 +26121,53 @@ const createNodeSpec = (config) => {
|
|
|
26121
26121
|
};
|
|
26122
26122
|
};
|
|
26123
26123
|
|
|
26124
|
-
const
|
|
26124
|
+
const createHtmlInserter = (view, contentConverter, startPos, dispatchTransaction) => {
|
|
26125
|
+
const schema = view.state.schema;
|
|
26126
|
+
return async (input) => {
|
|
26127
|
+
const container = document.createElement('span');
|
|
26128
|
+
container.innerHTML = await contentConverter.parseAsHTML(input, schema);
|
|
26129
|
+
const fragment = DOMParser.fromSchema(schema).parse(container).content;
|
|
26130
|
+
dispatchTransaction(view, startPos, fragment);
|
|
26131
|
+
};
|
|
26132
|
+
};
|
|
26133
|
+
|
|
26134
|
+
const inserterFactory = (view, contentConverter) => {
|
|
26125
26135
|
const startPos = getTriggerStartPosition(view);
|
|
26126
26136
|
return {
|
|
26127
|
-
insert: (
|
|
26128
|
-
|
|
26129
|
-
|
|
26130
|
-
const { $from } = selection;
|
|
26131
|
-
let node;
|
|
26132
|
-
try {
|
|
26133
|
-
node = createNode(input, schema);
|
|
26134
|
-
}
|
|
26135
|
-
catch (error) {
|
|
26136
|
-
// eslint-disable-next-line no-console
|
|
26137
|
-
console.error(error.message);
|
|
26138
|
-
return;
|
|
26139
|
-
}
|
|
26140
|
-
const spaceNode = schema.text(' ');
|
|
26141
|
-
const fragment = schema.nodes.doc.create(null, [node, spaceNode]);
|
|
26142
|
-
const transaction = state.tr.replaceWith(startPos, $from.pos, fragment);
|
|
26143
|
-
transaction.setMeta('stopTrigger', true);
|
|
26144
|
-
dispatch(transaction);
|
|
26145
|
-
},
|
|
26146
|
-
stopTrigger: () => {
|
|
26147
|
-
const { state, dispatch } = view;
|
|
26148
|
-
const transaction = state.tr;
|
|
26149
|
-
transaction.setMeta('stopTrigger', true);
|
|
26150
|
-
dispatch(transaction);
|
|
26151
|
-
},
|
|
26137
|
+
insert: createNodeAndTextInserter(view, startPos),
|
|
26138
|
+
insertHtml: createHtmlInserter(view, contentConverter, startPos, dispatchTransaction),
|
|
26139
|
+
stopTrigger: () => stopTriggerTransaction(view),
|
|
26152
26140
|
};
|
|
26153
26141
|
};
|
|
26142
|
+
const createNodeAndTextInserter = (view, startPos) => (input) => {
|
|
26143
|
+
const schema = view.state.schema;
|
|
26144
|
+
let node;
|
|
26145
|
+
try {
|
|
26146
|
+
node = createNode(input, schema);
|
|
26147
|
+
}
|
|
26148
|
+
catch (error) {
|
|
26149
|
+
// eslint-disable-next-line no-console
|
|
26150
|
+
console.error(error.message);
|
|
26151
|
+
return;
|
|
26152
|
+
}
|
|
26153
|
+
const spaceNode = schema.text(' ');
|
|
26154
|
+
const fragment = schema.nodes.doc.create(null, [node, spaceNode]);
|
|
26155
|
+
dispatchTransaction(view, startPos, fragment);
|
|
26156
|
+
};
|
|
26157
|
+
const stopTriggerTransaction = (view) => {
|
|
26158
|
+
const { state, dispatch } = view;
|
|
26159
|
+
const transaction = state.tr;
|
|
26160
|
+
transaction.setMeta('stopTrigger', true);
|
|
26161
|
+
dispatch(transaction);
|
|
26162
|
+
};
|
|
26163
|
+
const dispatchTransaction = (view, startPos, fragment) => {
|
|
26164
|
+
const state = view.state;
|
|
26165
|
+
const dispatch = view.dispatch;
|
|
26166
|
+
const fromPos = state.selection.$from.pos;
|
|
26167
|
+
const transaction = state.tr.replaceWith(startPos, fromPos, fragment);
|
|
26168
|
+
transaction.setMeta('stopTrigger', true);
|
|
26169
|
+
dispatch(transaction);
|
|
26170
|
+
};
|
|
26154
26171
|
const createNode = (input, schema) => {
|
|
26155
26172
|
var _a;
|
|
26156
26173
|
if (typeof input === 'string') {
|
|
@@ -26169,7 +26186,7 @@ const createNode = (input, schema) => {
|
|
|
26169
26186
|
const getCustomNode = (name, schema) => {
|
|
26170
26187
|
const customNode = Object.values(schema.nodes).find((prosemirrorNode) => prosemirrorNode.name === name);
|
|
26171
26188
|
if (!customNode) {
|
|
26172
|
-
throw new Error(`
|
|
26189
|
+
throw new Error(`No custom element has been registered for node ${name}`);
|
|
26173
26190
|
}
|
|
26174
26191
|
return customNode;
|
|
26175
26192
|
};
|
|
@@ -26207,16 +26224,16 @@ const stillHasTrigger = (state, activeTrigger, triggerPosition, triggerLength) =
|
|
|
26207
26224
|
return (state.doc.textBetween(triggerPosition, triggerPosition + 1) ===
|
|
26208
26225
|
activeTrigger);
|
|
26209
26226
|
};
|
|
26210
|
-
const getTriggerEventDetail = (view, trigger, value) => {
|
|
26227
|
+
const getTriggerEventDetail = (view, contentConverter, trigger, value) => {
|
|
26211
26228
|
return {
|
|
26212
26229
|
trigger: trigger,
|
|
26213
|
-
textEditor: inserterFactory(view),
|
|
26230
|
+
textEditor: inserterFactory(view, contentConverter),
|
|
26214
26231
|
value: value,
|
|
26215
26232
|
};
|
|
26216
26233
|
};
|
|
26217
|
-
const sendTriggerEvent = (type, view, trigger, value) => {
|
|
26234
|
+
const sendTriggerEvent = (type, view, contentConverter, trigger, value) => {
|
|
26218
26235
|
const event = new CustomEvent(type, {
|
|
26219
|
-
detail: getTriggerEventDetail(view, trigger, value),
|
|
26236
|
+
detail: getTriggerEventDetail(view, contentConverter, trigger, value),
|
|
26220
26237
|
bubbles: true,
|
|
26221
26238
|
composed: true,
|
|
26222
26239
|
});
|
|
@@ -26254,14 +26271,14 @@ const processTransactions = (text, transactions, oldState) => {
|
|
|
26254
26271
|
}
|
|
26255
26272
|
return text;
|
|
26256
26273
|
};
|
|
26257
|
-
const createTriggerPlugin = (triggerCharacters) => {
|
|
26274
|
+
const createTriggerPlugin = (triggerCharacters, contentConverter) => {
|
|
26258
26275
|
let activeTrigger = null;
|
|
26259
26276
|
let triggerText = '';
|
|
26260
26277
|
let pluginView = null;
|
|
26261
26278
|
let triggerPosition = null;
|
|
26262
26279
|
const stopTrigger = () => {
|
|
26263
26280
|
triggerText = '';
|
|
26264
|
-
sendTriggerEvent('triggerStop', pluginView, activeTrigger, triggerText);
|
|
26281
|
+
sendTriggerEvent('triggerStop', pluginView, contentConverter, activeTrigger, triggerText);
|
|
26265
26282
|
triggerPosition = null;
|
|
26266
26283
|
activeTrigger = null;
|
|
26267
26284
|
};
|
|
@@ -26280,7 +26297,7 @@ const createTriggerPlugin = (triggerCharacters) => {
|
|
|
26280
26297
|
activeTrigger = event.data;
|
|
26281
26298
|
triggerText = '';
|
|
26282
26299
|
triggerPosition = state.selection.$from.pos - triggerText.length;
|
|
26283
|
-
sendTriggerEvent('triggerStart', view, activeTrigger, triggerText);
|
|
26300
|
+
sendTriggerEvent('triggerStart', view, contentConverter, activeTrigger, triggerText);
|
|
26284
26301
|
return false;
|
|
26285
26302
|
}
|
|
26286
26303
|
return false;
|
|
@@ -26295,7 +26312,7 @@ const createTriggerPlugin = (triggerCharacters) => {
|
|
|
26295
26312
|
const updatedText = processTransactions(triggerText, transactions, oldState);
|
|
26296
26313
|
if (updatedText !== triggerText) {
|
|
26297
26314
|
triggerText = updatedText;
|
|
26298
|
-
sendTriggerEvent('triggerChange', pluginView, activeTrigger, triggerText.slice(1));
|
|
26315
|
+
sendTriggerEvent('triggerChange', pluginView, contentConverter, activeTrigger, triggerText.slice(1));
|
|
26299
26316
|
}
|
|
26300
26317
|
};
|
|
26301
26318
|
return new Plugin({
|
|
@@ -28008,7 +28025,7 @@ const ProsemirrorAdapter = class {
|
|
|
28008
28025
|
...exampleSetup({ schema: this.schema, menuBar: false }),
|
|
28009
28026
|
keymap(this.menuCommandFactory.buildKeymap()),
|
|
28010
28027
|
createLinkPlugin(this.handleNewLinkSelection),
|
|
28011
|
-
createTriggerPlugin(this.triggerCharacters),
|
|
28028
|
+
createTriggerPlugin(this.triggerCharacters, this.contentConverter),
|
|
28012
28029
|
createImageRemoverPlugin(),
|
|
28013
28030
|
createMenuStateTrackingPlugin(editorMenuTypesArray, this.menuCommandFactory, this.updateActiveActionBarItems),
|
|
28014
28031
|
createActionBarInteractionPlugin(this.menuCommandFactory),
|