ckeditor5-elements-schema 0.0.0-stage → 49.0.0-alpha.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/LICENSE +21 -0
- package/README.md +70 -2
- package/dist/augmentation.d.ts +25 -0
- package/dist/augmentation.d.ts.map +1 -0
- package/dist/augmentation.js +2 -0
- package/dist/augmentation.js.map +1 -0
- package/dist/commands/elementBlockCommand.d.ts +46 -0
- package/dist/commands/elementBlockCommand.d.ts.map +1 -0
- package/dist/commands/elementBlockCommand.js +71 -0
- package/dist/commands/elementBlockCommand.js.map +1 -0
- package/dist/commands/elementContainerCommand.d.ts +36 -0
- package/dist/commands/elementContainerCommand.d.ts.map +1 -0
- package/dist/commands/elementContainerCommand.js +67 -0
- package/dist/commands/elementContainerCommand.js.map +1 -0
- package/dist/commands/elementInlineCommand.d.ts +87 -0
- package/dist/commands/elementInlineCommand.d.ts.map +1 -0
- package/dist/commands/elementInlineCommand.js +253 -0
- package/dist/commands/elementInlineCommand.js.map +1 -0
- package/dist/commands/elementInsertCommand.d.ts +33 -0
- package/dist/commands/elementInsertCommand.d.ts.map +1 -0
- package/dist/commands/elementInsertCommand.js +61 -0
- package/dist/commands/elementInsertCommand.js.map +1 -0
- package/dist/commands/elementSchemaCommand.d.ts +62 -0
- package/dist/commands/elementSchemaCommand.d.ts.map +1 -0
- package/dist/commands/elementSchemaCommand.js +107 -0
- package/dist/commands/elementSchemaCommand.js.map +1 -0
- package/dist/conversion/convertElementSchema.d.ts +17 -0
- package/dist/conversion/convertElementSchema.d.ts.map +1 -0
- package/dist/conversion/convertElementSchema.js +55 -0
- package/dist/conversion/convertElementSchema.js.map +1 -0
- package/dist/conversion/inlineTextElement.d.ts +24 -0
- package/dist/conversion/inlineTextElement.d.ts.map +1 -0
- package/dist/conversion/inlineTextElement.js +28 -0
- package/dist/conversion/inlineTextElement.js.map +1 -0
- package/dist/definition/canHold.d.ts +10 -0
- package/dist/definition/canHold.d.ts.map +1 -0
- package/dist/definition/canHold.js +22 -0
- package/dist/definition/canHold.js.map +1 -0
- package/dist/definition/compileElementSchema.d.ts +41 -0
- package/dist/definition/compileElementSchema.d.ts.map +1 -0
- package/dist/definition/compileElementSchema.js +60 -0
- package/dist/definition/compileElementSchema.js.map +1 -0
- package/dist/definition/elementSchemaError.d.ts +12 -0
- package/dist/definition/elementSchemaError.d.ts.map +1 -0
- package/dist/definition/elementSchemaError.js +16 -0
- package/dist/definition/elementSchemaError.js.map +1 -0
- package/dist/definition/readDefinition.d.ts +18 -0
- package/dist/definition/readDefinition.d.ts.map +1 -0
- package/dist/definition/readDefinition.js +60 -0
- package/dist/definition/readDefinition.js.map +1 -0
- package/dist/definition/suggest.d.ts +5 -0
- package/dist/definition/suggest.d.ts.map +1 -0
- package/dist/definition/suggest.js +27 -0
- package/dist/definition/suggest.js.map +1 -0
- package/dist/definition/types.d.ts +105 -0
- package/dist/definition/types.d.ts.map +1 -0
- package/dist/definition/types.js +2 -0
- package/dist/definition/types.js.map +1 -0
- package/dist/definition/validateElementSchema.d.ts +26 -0
- package/dist/definition/validateElementSchema.d.ts.map +1 -0
- package/dist/definition/validateElementSchema.js +145 -0
- package/dist/definition/validateElementSchema.js.map +1 -0
- package/dist/elementSchema.d.ts +47 -0
- package/dist/elementSchema.d.ts.map +1 -0
- package/dist/elementSchema.js +108 -0
- package/dist/elementSchema.js.map +1 -0
- package/dist/elementSchemaCommands.d.ts +83 -0
- package/dist/elementSchemaCommands.d.ts.map +1 -0
- package/dist/elementSchemaCommands.js +137 -0
- package/dist/elementSchemaCommands.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/typing/twoStepCaretMovement.d.ts +11 -0
- package/dist/typing/twoStepCaretMovement.d.ts.map +1 -0
- package/dist/typing/twoStepCaretMovement.js +76 -0
- package/dist/typing/twoStepCaretMovement.js.map +1 -0
- package/dist/validate.d.ts +12 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +11 -0
- package/dist/validate.js.map +1 -0
- package/package.json +49 -3
- package/src/augmentation.ts +28 -0
- package/src/commands/elementBlockCommand.ts +87 -0
- package/src/commands/elementContainerCommand.ts +83 -0
- package/src/commands/elementInlineCommand.ts +311 -0
- package/src/commands/elementInsertCommand.ts +74 -0
- package/src/commands/elementSchemaCommand.ts +140 -0
- package/src/conversion/convertElementSchema.ts +65 -0
- package/src/conversion/inlineTextElement.ts +31 -0
- package/src/definition/canHold.ts +29 -0
- package/src/definition/compileElementSchema.ts +88 -0
- package/src/definition/elementSchemaError.ts +21 -0
- package/src/definition/readDefinition.ts +98 -0
- package/src/definition/suggest.ts +38 -0
- package/src/definition/types.ts +123 -0
- package/src/definition/validateElementSchema.ts +238 -0
- package/src/elementSchema.ts +133 -0
- package/src/elementSchemaCommands.ts +202 -0
- package/src/index.ts +30 -0
- package/src/typing/twoStepCaretMovement.ts +119 -0
- package/src/validate.ts +20 -0
package/src/index.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Element schema: declare elements in the model schema from a simple definition, e.g. a JSON file, with three types of
|
|
3
|
+
* elements (`empty`, `block`, `container`), and a validation that rejects contradictory definitions. `ElementSchemaCommands`
|
|
4
|
+
* makes commands and buttons for its elements.
|
|
5
|
+
*
|
|
6
|
+
* @module ckeditor5-elements-schema
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
// Plugins.
|
|
10
|
+
export { default as ElementSchema } from './elementSchema.js';
|
|
11
|
+
export {
|
|
12
|
+
default as ElementSchemaCommands,
|
|
13
|
+
type ElementSchemaCommandDefinition,
|
|
14
|
+
type ElementSchemaCommandsConfig
|
|
15
|
+
} from './elementSchemaCommands.js';
|
|
16
|
+
|
|
17
|
+
// Commands.
|
|
18
|
+
export { default as ElementSchemaCommand } from './commands/elementSchemaCommand.js';
|
|
19
|
+
export { default as ElementInlineCommand } from './commands/elementInlineCommand.js';
|
|
20
|
+
export { default as ElementBlockCommand } from './commands/elementBlockCommand.js';
|
|
21
|
+
export { default as ElementContainerCommand } from './commands/elementContainerCommand.js';
|
|
22
|
+
export { default as ElementInsertCommand } from './commands/elementInsertCommand.js';
|
|
23
|
+
|
|
24
|
+
// Utils.
|
|
25
|
+
export { withoutBlockFiller } from './conversion/inlineTextElement.js';
|
|
26
|
+
|
|
27
|
+
// Validation and compiling, which do not need an editor (also in `validate.ts`, for Node.js).
|
|
28
|
+
export * from './validate.js';
|
|
29
|
+
|
|
30
|
+
import './augmentation.js';
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isForwardArrowKeyCode,
|
|
3
|
+
keyCodes,
|
|
4
|
+
type Editor,
|
|
5
|
+
type ModelDocumentFragment,
|
|
6
|
+
type ModelNode,
|
|
7
|
+
type ModelPosition,
|
|
8
|
+
type Plugin,
|
|
9
|
+
type ViewDocumentInsertTextEvent,
|
|
10
|
+
type ViewDocumentKeyDownEvent
|
|
11
|
+
} from 'ckeditor5';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Makes the left and right arrow keys move in two steps at the ends of inline elements, as CKEditor's two-step caret
|
|
15
|
+
* movement does at the ends of a bold: the first step goes into the element (or out of it), where the cursor looks the
|
|
16
|
+
* same, the next one moves in the text. `a[]<b>bc</b>` is `a<b>[]bc</b>`, then `a<b>b[]c</b>`. The browser would move by
|
|
17
|
+
* a character at once, and the positions on both sides of the end of an element would be out of reach.
|
|
18
|
+
*
|
|
19
|
+
* What is typed then goes where the cursor is. The listeners are the plugin's.
|
|
20
|
+
*/
|
|
21
|
+
export function enableTwoStepCaretMovement(plugin: Plugin, names: ReadonlySet<string>): void {
|
|
22
|
+
const editor = plugin.editor;
|
|
23
|
+
const viewDocument = editor.editing.view.document;
|
|
24
|
+
const isElement = (node: ModelNode | ModelDocumentFragment | null): node is ModelNode =>
|
|
25
|
+
!!node?.is('element') && names.has(node.name);
|
|
26
|
+
|
|
27
|
+
// Before the other features: e.g. `ElementSelectable` selects an inline object that the cursor reaches, and it may
|
|
28
|
+
// be just after the end of an element.
|
|
29
|
+
plugin.listenTo<ViewDocumentKeyDownEvent>(
|
|
30
|
+
viewDocument,
|
|
31
|
+
'keydown',
|
|
32
|
+
(evt, data) => {
|
|
33
|
+
const isPlain = !data.shiftKey && !data.ctrlKey && !data.altKey && !data.metaKey;
|
|
34
|
+
const isHorizontal = data.keyCode === keyCodes.arrowleft || data.keyCode === keyCodes.arrowright;
|
|
35
|
+
const isForward = isForwardArrowKeyCode(data.keyCode, editor.locale.contentLanguageDirection);
|
|
36
|
+
const position = isPlain && isHorizontal ? getStep(editor, isForward, isElement) : null;
|
|
37
|
+
|
|
38
|
+
if (position) {
|
|
39
|
+
editor.model.change(writer => {
|
|
40
|
+
writer.setSelection(position);
|
|
41
|
+
});
|
|
42
|
+
data.preventDefault();
|
|
43
|
+
evt.stop();
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
{ priority: 'highest' }
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
// The browser types at a place of its own at an end of an element, e.g. at the end of the text before it, whichever
|
|
50
|
+
// side of the end the cursor is on. When that place differs from the cursor only by ends of elements, the text goes
|
|
51
|
+
// where the cursor is: at the view selection, which is the model one. The browser must not type it at its place, as
|
|
52
|
+
// CKEditor does for a fake selection; a composition is left to the browser.
|
|
53
|
+
plugin.listenTo<ViewDocumentInsertTextEvent>(
|
|
54
|
+
viewDocument,
|
|
55
|
+
'insertText',
|
|
56
|
+
(evt, data) => {
|
|
57
|
+
const target = data.selection?.rangeCount === 1 ? data.selection.getFirstRange() : null;
|
|
58
|
+
const position = target?.isCollapsed ? editor.editing.mapper.toModelPosition(target.start) : null;
|
|
59
|
+
|
|
60
|
+
if (position && !data.isComposing && isAtCursor(editor, position, isElement)) {
|
|
61
|
+
data.selection = viewDocument.selection;
|
|
62
|
+
data.preventDefault();
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
{ priority: 'high' }
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Returns where the cursor goes with one step in the direction, when it is at an end of an element: into the element
|
|
71
|
+
* next to it, or out of the element it is in. `null` elsewhere, or for a selection that is not collapsed.
|
|
72
|
+
*/
|
|
73
|
+
function getStep(
|
|
74
|
+
editor: Editor,
|
|
75
|
+
isForward: boolean,
|
|
76
|
+
isElement: (node: ModelNode | ModelDocumentFragment | null) => node is ModelNode
|
|
77
|
+
): ModelPosition | null {
|
|
78
|
+
const model = editor.model;
|
|
79
|
+
const selection = model.document.selection;
|
|
80
|
+
const position = selection.getFirstPosition();
|
|
81
|
+
|
|
82
|
+
if (!selection.isCollapsed || !position) {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const next = isForward ? position.nodeAfter : position.nodeBefore;
|
|
87
|
+
|
|
88
|
+
if (isElement(next)) {
|
|
89
|
+
return model.createPositionAt(next, isForward ? 0 : 'end');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if ((isForward ? position.isAtEnd : position.isAtStart) && isElement(position.parent)) {
|
|
93
|
+
return isForward ? model.createPositionAfter(position.parent) : model.createPositionBefore(position.parent);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Whether a position differs from the cursor only by ends of elements: `a[]<b>c</b>` and `a<b>[]c</b>` look the same.
|
|
101
|
+
*/
|
|
102
|
+
function isAtCursor(
|
|
103
|
+
editor: Editor,
|
|
104
|
+
position: ModelPosition,
|
|
105
|
+
isElement: (node: ModelNode | ModelDocumentFragment | null) => boolean
|
|
106
|
+
): boolean {
|
|
107
|
+
const model = editor.model;
|
|
108
|
+
const selection = model.document.selection;
|
|
109
|
+
const cursor = selection.getFirstPosition();
|
|
110
|
+
|
|
111
|
+
// Where the cursor is exactly, the browser types as usual.
|
|
112
|
+
if (!selection.isCollapsed || !cursor || cursor.isEqual(position)) {
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const range = cursor.isBefore(position) ? model.createRange(cursor, position) : model.createRange(position, cursor);
|
|
117
|
+
|
|
118
|
+
return Array.from(range.getWalker()).every(({ item }) => item.is('element') && isElement(item));
|
|
119
|
+
}
|
package/src/validate.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The part of the element schema that needs no editor and no browser: the validation, the compiling to schema
|
|
3
|
+
* definitions, the error and the types. It is in its own module, so that it can be used in Node.js, e.g. to validate a
|
|
4
|
+
* schema file in a test or in CI: the main entry loads CKEditor, which needs a DOM.
|
|
5
|
+
*
|
|
6
|
+
* @module ckeditor5-elements-schema/validate
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
export { validateElementSchema } from './definition/validateElementSchema.js';
|
|
10
|
+
export { compileElementSchema, type CompiledElementSchema } from './definition/compileElementSchema.js';
|
|
11
|
+
export { default as ElementSchemaError } from './definition/elementSchemaError.js';
|
|
12
|
+
export type {
|
|
13
|
+
ElementSchemaDefinition,
|
|
14
|
+
ElementSchemaElement,
|
|
15
|
+
ElementSchemaInput,
|
|
16
|
+
ElementSchemaIssue,
|
|
17
|
+
ElementSchemaKind,
|
|
18
|
+
ElementSchemaType,
|
|
19
|
+
ValidateElementSchemaOptions
|
|
20
|
+
} from './definition/types.js';
|