@modusoperandi/licit 1.4.3 → 1.4.7
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/BlockquoteInsertNewLineCommand.js.flow +70 -70
- package/BlockquoteNodeSpec.js.flow +29 -29
- package/BlockquoteToggleCommand.js.flow +56 -56
- package/BookmarkNodeSpec.js.flow +39 -39
- package/BulletListNodeSpec.js.flow +61 -61
- package/CZIProseMirror.js.flow +90 -90
- package/CodeBlockCommand.js.flow +65 -65
- package/CodeBlockNodeSpec.js.flow +24 -24
- package/CodeMarkSpec.js.flow +14 -14
- package/ContentPlaceholderPlugin.js.flow +183 -183
- package/CursorPlaceholderPlugin.js.flow +113 -113
- package/DocLayoutCommand.js.flow +97 -97
- package/DocNodeSpec.js.flow +62 -62
- package/EMMarkSpec.js.flow +39 -39
- package/EditorCommands.js.flow +124 -124
- package/EditorKeyMap.js.flow +173 -173
- package/EditorMarks.js +4 -2
- package/EditorMarks.js.flow +77 -74
- package/EditorNodes.js.flow +55 -55
- package/EditorPageLayoutPlugin.js.flow +67 -67
- package/EditorPlugins.js.flow +8 -8
- package/EditorSchema.js.flow +12 -12
- package/EditorState.js.flow +7 -7
- package/FontSizeMarkSpec.js.flow +54 -54
- package/FontTypeMarkSpec.js.flow +89 -89
- package/HTMLMutator.js.flow +58 -58
- package/HangingIndentMarkSpec.js +34 -0
- package/HangingIndentMarkSpec.js.flow +30 -0
- package/HardBreakNodeSpec.js.flow +15 -15
- package/HeadingNodeSpec.js.flow +42 -42
- package/HistoryRedoCommand.js.flow +41 -41
- package/HistoryUndoCommand.js.flow +41 -41
- package/HorizontalRuleCommand.js.flow +71 -71
- package/HorizontalRuleNodeSpec.js.flow +39 -39
- package/ImageUploadPlaceholderPlugin.js.flow +187 -187
- package/LICENSE +22 -22
- package/LinkMarkSpec.js +13 -3
- package/LinkMarkSpec.js.flow +41 -37
- package/LinkSetURLCommand.js.flow +129 -129
- package/LinkTooltipPlugin.js +34 -37
- package/LinkTooltipPlugin.js.flow +207 -217
- package/ListItemInsertNewLineCommand.js.flow +76 -76
- package/ListItemMergeCommand.js.flow +197 -197
- package/ListItemNodeSpec.js.flow +52 -52
- package/ListSplitCommand.js.flow +54 -54
- package/ListToggleCommand.js.flow +99 -99
- package/MarkNames.js +2 -1
- package/MarkNames.js.flow +20 -19
- package/MarksClearCommand.js.flow +66 -66
- package/NodeNames.js.flow +23 -23
- package/OrderedListNodeSpec.js.flow +131 -131
- package/OverrideMarkSpec.js.flow +49 -49
- package/ParagraphNodeSpec.js +21 -2
- package/ParagraphNodeSpec.js.flow +233 -215
- package/ParagraphSpacingCommand.js.flow +139 -139
- package/PrintCommand.js.flow +53 -53
- package/SelectionPlaceholderPlugin.js.flow +129 -129
- package/SpacerMarkSpec.js.flow +47 -47
- package/StrikeMarkSpec.js.flow +24 -24
- package/StrongMarkSpec.js.flow +39 -39
- package/StyleView.js.flow +18 -18
- package/TableBackgroundColorCommand.js.flow +79 -79
- package/TableBorderColorCommand.js +5 -3
- package/TableBorderColorCommand.js.flow +108 -106
- package/TableCellColorCommand.js.flow +73 -73
- package/TableCellMenuPlugin.js.flow +129 -129
- package/TableInsertCommand.js.flow +117 -117
- package/TableMergeCellsCommand.js.flow +113 -113
- package/TableNodesSpecs.js.flow +144 -144
- package/TablePlugins.js.flow +14 -14
- package/TableResizePlugin.js.flow +636 -636
- package/TextColorMarkSpec.js.flow +40 -40
- package/TextHighlightMarkSpec.js.flow +47 -47
- package/TextInsertTabSpaceCommand.js +0 -3
- package/TextInsertTabSpaceCommand.js.flow +103 -106
- package/TextNoWrapMarkSpec.js.flow +14 -14
- package/TextNodeSpec.js.flow +7 -7
- package/TextSelectionMarkSpec.js.flow +24 -24
- package/TextSubMarkSpec.js.flow +28 -28
- package/TextSuperMarkSpec.js.flow +28 -28
- package/TextUnderlineMarkSpec.js.flow +24 -24
- package/Types.js.flow +77 -77
- package/WebFontLoader.js.flow +22 -22
- package/blockQuoteInputRule.js.flow +36 -36
- package/bom.xml +9555 -9683
- package/browser.js.flow +7 -7
- package/buildEditorPlugins.js.flow +48 -48
- package/buildInputRules.js.flow +85 -85
- package/client/CollabConnector.js.flow +90 -90
- package/client/EditorConnection.js.flow +324 -324
- package/client/Licit.js +39 -39
- package/client/Licit.js.flow +649 -649
- package/client/Licit.test.js.flow +104 -104
- package/client/Reporter.js.flow +35 -35
- package/client/SimpleConnector.js.flow +61 -61
- package/client/http.js.flow +60 -60
- package/client/licit.css +12 -12
- package/client/throttle.js.flow +27 -27
- package/convertFromDOMElement.js.flow +33 -33
- package/convertFromHTML.js.flow +15 -15
- package/convertFromJSON.js.flow +53 -53
- package/convertToCSSPTValue.js.flow +19 -19
- package/convertToJSON.js.flow +7 -7
- package/createCommand.js.flow +62 -62
- package/createEditorKeyMap.js.flow +87 -87
- package/createEmptyEditorState.js.flow +29 -29
- package/createTableResizingPlugin.js.flow +86 -86
- package/findActionableCell.js.flow +74 -74
- package/findActiveMark.js.flow +32 -32
- package/hyphenize.js.flow +17 -17
- package/index.d.ts +167 -167
- package/index.js.flow +10 -10
- package/insertTable.js.flow +54 -54
- package/isEditorStateEmpty.js.flow +32 -32
- package/isTableNode.js.flow +15 -15
- package/joinDown.js.flow +25 -25
- package/joinListNode.js.flow +55 -55
- package/joinUp.js.flow +37 -37
- package/keymaps.js.flow +175 -175
- package/lookUpElement.js.flow +14 -14
- package/nodeAt.js.flow +12 -12
- package/normalizeHTML.js.flow +80 -80
- package/package.json +152 -152
- package/patchAnchorElements.js.flow +38 -38
- package/patchBreakElements.js.flow +22 -22
- package/patchElementInlineStyles.js.flow +92 -92
- package/patchListElements.js.flow +275 -275
- package/patchMathElements.js.flow +58 -58
- package/patchParagraphElements.js.flow +20 -20
- package/patchStyleElements.js.flow +197 -197
- package/patchTableElements.js.flow +88 -88
- package/rebaseDocWithSteps.js.flow +42 -42
- package/sanitizeURL.js.flow +13 -13
- package/splitListItem.js.flow +191 -191
- package/styles.css +46 -46
- package/toClosestFontPtSize.js.flow +22 -22
- package/toSafeHTMLDocument.js.flow +9 -9
- package/toggleBlockquote.js.flow +101 -101
- package/toggleCodeBlock.js.flow +102 -102
- package/ui/AlertInfo.js.flow +63 -63
- package/ui/BookmarkNodeView.js.flow +64 -64
- package/ui/CommandButton.js.flow +68 -68
- package/ui/CommandMenu.js.flow +74 -74
- package/ui/CommandMenuButton.js.flow +128 -128
- package/ui/CustomEditorView.js.flow +29 -29
- package/ui/CustomMenu.js.flow +14 -14
- package/ui/CustomMenuItem.js.flow +35 -35
- package/ui/CustomNodeView.js.flow +207 -207
- package/ui/CustomRadioButton.js.flow +63 -63
- package/ui/DocLayoutEditor.js.flow +130 -130
- package/ui/Editor.js.flow +281 -281
- package/ui/EditorFrameset.js.flow +79 -79
- package/ui/EditorToolbar.js.flow +197 -197
- package/ui/EditorToolbarConfig.js.flow +162 -162
- package/ui/FontSizeCommandMenuButton.js.flow +66 -66
- package/ui/FontTypeCommandMenuButton.js.flow +60 -60
- package/ui/Frag.js.flow +11 -11
- package/ui/Icon.js.flow +82 -82
- package/ui/ImageInlineEditor.js.flow +66 -66
- package/ui/KeyCodes.js.flow +12 -12
- package/ui/LinkTooltip.js.flow +51 -51
- package/ui/LinkURLEditor.js.flow +227 -227
- package/ui/ListItemNodeView.js.flow +101 -101
- package/ui/ListTypeButton.js.flow +121 -121
- package/ui/ListTypeCommandButton.js.flow +85 -85
- package/ui/ListTypeMenu.js.flow +78 -78
- package/ui/LoadingIndicator.js.flow +19 -19
- package/ui/PasteMenu.js.flow +52 -52
- package/ui/ResizeObserver.js.flow +105 -105
- package/ui/RichTextEditor.js.flow +133 -133
- package/ui/SelectionObserver.js.flow +134 -134
- package/ui/TableCellMenu.js.flow +49 -49
- package/ui/TableGridSizeEditor.js.flow +185 -185
- package/ui/TableNodeView.js.flow +36 -36
- package/ui/bindScrollHandler.js.flow +46 -46
- package/ui/canUseCSSFont.js.flow +42 -42
- package/ui/czi-body-layout-editor.css +16 -16
- package/ui/czi-bookmark-view.css +10 -10
- package/ui/czi-cursor-placeholder.css +36 -36
- package/ui/czi-custom-menu-button.css +18 -18
- package/ui/czi-custom-menu-item.css +30 -30
- package/ui/czi-custom-menu.css +8 -8
- package/ui/czi-custom-radio-button.css +80 -80
- package/ui/czi-custom-scrollbar.css +21 -21
- package/ui/czi-editor-frameset.css +81 -81
- package/ui/czi-editor-toolbar.css +122 -122
- package/ui/czi-editor.css +239 -216
- package/ui/czi-form.css +201 -201
- package/ui/czi-frag.css +3 -3
- package/ui/czi-heading.css +40 -40
- package/ui/czi-icon.css +72 -72
- package/ui/czi-image-resize-box.css +165 -165
- package/ui/czi-image-upload-editor.css +57 -57
- package/ui/czi-image-upload-placeholder.css +50 -50
- package/ui/czi-image-url-editor.css +38 -38
- package/ui/czi-image-view.css +121 -121
- package/ui/czi-indent.css +137 -137
- package/ui/czi-inline-editor.css +20 -20
- package/ui/czi-link-tooltip.css +112 -112
- package/ui/czi-list.css +406 -406
- package/ui/czi-loading-indicator.css +66 -66
- package/ui/czi-math-view.css +62 -62
- package/ui/czi-selection-placeholder.css +24 -24
- package/ui/czi-table-cell-menu.css +16 -16
- package/ui/czi-table-grid-size-editor.css +37 -37
- package/ui/czi-table.css +89 -89
- package/ui/czi-vars.css +47 -45
- package/ui/findActiveFontSize.js.flow +55 -55
- package/ui/findActiveFontType.js.flow +35 -35
- package/ui/fonts.css +460 -460
- package/ui/handleEditorDrop.js.flow +28 -28
- package/ui/handleEditorKeyDown.js.flow +39 -39
- package/ui/handleEditorPaste.js.flow +33 -33
- package/ui/htmlElementToRect.js.flow +18 -18
- package/ui/icon-font.css +9 -9
- package/ui/injectStyleSheet.js.flow +40 -40
- package/ui/isElementFullyVisible.js.flow +14 -14
- package/ui/isOffline.js.flow +8 -8
- package/ui/isReactClass.js.flow +12 -12
- package/ui/listType.css +21 -21
- package/ui/resolveImage.js.flow +121 -121
- package/ui/toCSSColor.js.flow +51 -51
- package/ui/toCSSLineSpacing.js.flow +53 -53
- package/ui/toHexColor.js.flow +26 -26
- package/ui/uuid.js.flow +9 -9
- package/uuid.js.flow +9 -9
|
@@ -1,42 +1,42 @@
|
|
|
1
|
-
// @flow
|
|
2
|
-
|
|
3
|
-
import { Step } from 'prosemirror-transform';
|
|
4
|
-
import EditorSchema from './EditorSchema';
|
|
5
|
-
|
|
6
|
-
type RebaseResult = {
|
|
7
|
-
docJSON: Object,
|
|
8
|
-
stepsJSON: Array<Object>,
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
export default function rebaseDocWithSteps(
|
|
12
|
-
clientID: string,
|
|
13
|
-
docJSON: Object,
|
|
14
|
-
stepsJSON: Array<Object>
|
|
15
|
-
): Promise<RebaseResult> {
|
|
16
|
-
return new Promise((resolve, reject) => {
|
|
17
|
-
// TODO: Move this into a separate server request.
|
|
18
|
-
let docNode = EditorSchema.nodeFromJSON(docJSON);
|
|
19
|
-
|
|
20
|
-
const steps = stepsJSON.map((step) => {
|
|
21
|
-
const result = Step.fromJSON(EditorSchema, step);
|
|
22
|
-
result.clientID = clientID;
|
|
23
|
-
return result;
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
steps.forEach((step) => {
|
|
27
|
-
const result = step.apply(docNode);
|
|
28
|
-
docNode = result.doc;
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
const newDocJSON = docNode.toJSON();
|
|
32
|
-
|
|
33
|
-
const newStepsJSON = steps.map((step) => {
|
|
34
|
-
return step.toJSON();
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
resolve({
|
|
38
|
-
docJSON: newDocJSON,
|
|
39
|
-
stepsJSON: newStepsJSON,
|
|
40
|
-
});
|
|
41
|
-
});
|
|
42
|
-
}
|
|
1
|
+
// @flow
|
|
2
|
+
|
|
3
|
+
import { Step } from 'prosemirror-transform';
|
|
4
|
+
import EditorSchema from './EditorSchema';
|
|
5
|
+
|
|
6
|
+
type RebaseResult = {
|
|
7
|
+
docJSON: Object,
|
|
8
|
+
stepsJSON: Array<Object>,
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export default function rebaseDocWithSteps(
|
|
12
|
+
clientID: string,
|
|
13
|
+
docJSON: Object,
|
|
14
|
+
stepsJSON: Array<Object>
|
|
15
|
+
): Promise<RebaseResult> {
|
|
16
|
+
return new Promise((resolve, reject) => {
|
|
17
|
+
// TODO: Move this into a separate server request.
|
|
18
|
+
let docNode = EditorSchema.nodeFromJSON(docJSON);
|
|
19
|
+
|
|
20
|
+
const steps = stepsJSON.map((step) => {
|
|
21
|
+
const result = Step.fromJSON(EditorSchema, step);
|
|
22
|
+
result.clientID = clientID;
|
|
23
|
+
return result;
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
steps.forEach((step) => {
|
|
27
|
+
const result = step.apply(docNode);
|
|
28
|
+
docNode = result.doc;
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const newDocJSON = docNode.toJSON();
|
|
32
|
+
|
|
33
|
+
const newStepsJSON = steps.map((step) => {
|
|
34
|
+
return step.toJSON();
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
resolve({
|
|
38
|
+
docJSON: newDocJSON,
|
|
39
|
+
stepsJSON: newStepsJSON,
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
}
|
package/sanitizeURL.js.flow
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
// @flow
|
|
2
|
-
|
|
3
|
-
const HTTP_PREFIX = /^http(s?):*\/\//i;
|
|
4
|
-
|
|
5
|
-
export default function sanitizeURL(url: ?string): string {
|
|
6
|
-
if (!url) {
|
|
7
|
-
return 'http://';
|
|
8
|
-
}
|
|
9
|
-
if (HTTP_PREFIX.test(url)) {
|
|
10
|
-
return url;
|
|
11
|
-
}
|
|
12
|
-
return 'https://' + url;
|
|
13
|
-
}
|
|
1
|
+
// @flow
|
|
2
|
+
|
|
3
|
+
const HTTP_PREFIX = /^http(s?):*\/\//i;
|
|
4
|
+
|
|
5
|
+
export default function sanitizeURL(url: ?string): string {
|
|
6
|
+
if (!url) {
|
|
7
|
+
return 'http://';
|
|
8
|
+
}
|
|
9
|
+
if (HTTP_PREFIX.test(url)) {
|
|
10
|
+
return url;
|
|
11
|
+
}
|
|
12
|
+
return 'https://' + url;
|
|
13
|
+
}
|
package/splitListItem.js.flow
CHANGED
|
@@ -1,191 +1,191 @@
|
|
|
1
|
-
// @flow
|
|
2
|
-
|
|
3
|
-
import uuid from './ui/uuid.js';
|
|
4
|
-
import { Fragment, Schema } from 'prosemirror-model';
|
|
5
|
-
import { TextSelection } from 'prosemirror-state';
|
|
6
|
-
import { Transform, canSplit } from 'prosemirror-transform';
|
|
7
|
-
import { LIST_ITEM, ORDERED_LIST, BULLET_LIST, PARAGRAPH } from './NodeNames.js';
|
|
8
|
-
import { findParentNodeOfType } from 'prosemirror-utils';
|
|
9
|
-
|
|
10
|
-
// Splits a list item by the current cursor's position.
|
|
11
|
-
// Some examples:
|
|
12
|
-
//
|
|
13
|
-
// - split before item's text:
|
|
14
|
-
// - before:
|
|
15
|
-
// 1. <cursor>AA
|
|
16
|
-
// 2. BB
|
|
17
|
-
// 3. CC
|
|
18
|
-
// - after:
|
|
19
|
-
// 1. <cursor>
|
|
20
|
-
// 2. AA
|
|
21
|
-
// 3. BB
|
|
22
|
-
// 4. CC
|
|
23
|
-
//
|
|
24
|
-
// - split between item's text:
|
|
25
|
-
// - before:
|
|
26
|
-
// 1. AA
|
|
27
|
-
// 2. B<cursor>B
|
|
28
|
-
// 3. CC
|
|
29
|
-
// - after:
|
|
30
|
-
// 1. AA
|
|
31
|
-
// 2. B
|
|
32
|
-
// 3. B
|
|
33
|
-
// 4. CC
|
|
34
|
-
//
|
|
35
|
-
// - split after item's text:
|
|
36
|
-
// - before:
|
|
37
|
-
// 1. AA
|
|
38
|
-
// 2. BB<cursor>
|
|
39
|
-
// 3. CC
|
|
40
|
-
// - after:
|
|
41
|
-
// 1. AA
|
|
42
|
-
// 2. BB
|
|
43
|
-
// 3. <cursor>
|
|
44
|
-
// 4. CC
|
|
45
|
-
//
|
|
46
|
-
// - split at item with empty content:
|
|
47
|
-
// - before:
|
|
48
|
-
// 1. AA
|
|
49
|
-
// 2. <cursor>
|
|
50
|
-
// 3. CC
|
|
51
|
-
// - after:
|
|
52
|
-
// 1. AA
|
|
53
|
-
// <cursor>
|
|
54
|
-
// 2. BB
|
|
55
|
-
// 3. CC
|
|
56
|
-
//
|
|
57
|
-
export default function splitListItem(
|
|
58
|
-
tr: Transform,
|
|
59
|
-
schema: Schema
|
|
60
|
-
): Transform {
|
|
61
|
-
const nodeType = schema.nodes[LIST_ITEM];
|
|
62
|
-
if (!nodeType) {
|
|
63
|
-
return tr;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const { selection } = tr;
|
|
67
|
-
if (!selection) {
|
|
68
|
-
return tr;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
const { $from, $to, node } = selection;
|
|
72
|
-
if ((node?.isBlock) || $from.depth < 2 || !$from.sameParent($to)) {
|
|
73
|
-
return tr;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
const grandParent = $from.node(-1);
|
|
77
|
-
if (grandParent.type !== nodeType) {
|
|
78
|
-
return tr;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
if ($from.parent.content.size == 0) {
|
|
82
|
-
// In an empty list item.
|
|
83
|
-
return splitEmptyListItem(tr, schema);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
const nextType =
|
|
87
|
-
$to.pos == $from.end()
|
|
88
|
-
? grandParent.contentMatchAt($from.indexAfter(-1)).defaultType
|
|
89
|
-
: null;
|
|
90
|
-
|
|
91
|
-
tr = tr.delete($from.pos, $to.pos);
|
|
92
|
-
const types = nextType && [null, { type: nextType }];
|
|
93
|
-
if (!canSplit(tr.doc, $from.pos, 2, types)) {
|
|
94
|
-
return tr;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
return tr.split($from.pos, 2, types);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// Splits an item with empty content:
|
|
101
|
-
// - before:
|
|
102
|
-
// 1. AA
|
|
103
|
-
// 2. <cursor>
|
|
104
|
-
// 3. CC
|
|
105
|
-
// - after:
|
|
106
|
-
// 1. AA
|
|
107
|
-
// <cursor>
|
|
108
|
-
// 2. BB
|
|
109
|
-
// 3. CC
|
|
110
|
-
function splitEmptyListItem(tr: Transform, schema: Schema): Transform {
|
|
111
|
-
const listItemType = schema.nodes[LIST_ITEM];
|
|
112
|
-
const orderedListType = schema.nodes[ORDERED_LIST];
|
|
113
|
-
const bulletListType = schema.nodes[BULLET_LIST];
|
|
114
|
-
const paragraphType = schema.nodes[PARAGRAPH];
|
|
115
|
-
if (!listItemType || !paragraphType) {
|
|
116
|
-
// Schema does not support the nodes expected.
|
|
117
|
-
return tr;
|
|
118
|
-
}
|
|
119
|
-
const listItemFound = findParentNodeOfType(listItemType)(tr.selection);
|
|
120
|
-
if (!listItemFound || listItemFound.node.textContent !== '') {
|
|
121
|
-
// Cursor is not inside an empty list item.
|
|
122
|
-
return tr;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
const listFound =
|
|
126
|
-
(orderedListType && findParentNodeOfType(orderedListType)(tr.selection)) ||
|
|
127
|
-
(bulletListType && findParentNodeOfType(bulletListType)(tr.selection));
|
|
128
|
-
|
|
129
|
-
if (!listFound) {
|
|
130
|
-
// Cursor isn't inside an list.
|
|
131
|
-
return tr;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
const $listItemPos = tr.doc.resolve(listItemFound.pos);
|
|
135
|
-
const listItemIndex = $listItemPos.index($listItemPos.depth);
|
|
136
|
-
const listFoundNode = listFound.node;
|
|
137
|
-
if (
|
|
138
|
-
listFoundNode.childCount < 3 ||
|
|
139
|
-
listItemIndex < 1 ||
|
|
140
|
-
listItemIndex >= listFoundNode.childCount - 1
|
|
141
|
-
) {
|
|
142
|
-
// - The list must have at least three list items
|
|
143
|
-
// - The cursor must be after the first list item and before the last list
|
|
144
|
-
// item.
|
|
145
|
-
// If both conditions don't match, bails out, which will remove the empty
|
|
146
|
-
// item.
|
|
147
|
-
return tr;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// Find the name of the current list to split. If the name isn't available,
|
|
151
|
-
// assigns a new name.
|
|
152
|
-
let { name } = listFoundNode.attrs;
|
|
153
|
-
if (!name) {
|
|
154
|
-
name = uuid();
|
|
155
|
-
tr = tr.setNodeMarkup(
|
|
156
|
-
listFound.pos,
|
|
157
|
-
listFoundNode.type,
|
|
158
|
-
{
|
|
159
|
-
...listFoundNode.attrs,
|
|
160
|
-
name,
|
|
161
|
-
},
|
|
162
|
-
listFoundNode.marks
|
|
163
|
-
);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
// We'll split the list into two lists.
|
|
167
|
-
// the first list contains the items before the cursor, and the second
|
|
168
|
-
// list contains the items after the cursor and the second list will "follow"
|
|
169
|
-
// the first list by sharing the same counter variable.
|
|
170
|
-
const sliceFrom = listItemFound.pos + listItemFound.node.nodeSize;
|
|
171
|
-
const sliceTo = listFound.pos + listFound.node.nodeSize - 1;
|
|
172
|
-
const slicedItems = tr.doc.slice(sliceFrom, sliceTo, false);
|
|
173
|
-
|
|
174
|
-
const deleteFrom = listItemFound.pos;
|
|
175
|
-
const deleteTo = listFound.pos + listFound.node.nodeSize;
|
|
176
|
-
tr = tr.delete(deleteFrom, deleteTo);
|
|
177
|
-
const sourceListNode = listFound.node;
|
|
178
|
-
const listAttrs = { ...sourceListNode.attrs };
|
|
179
|
-
if (orderedListType === sourceListNode.type) {
|
|
180
|
-
listAttrs.counterReset = 'none';
|
|
181
|
-
listAttrs.following = name;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
const insertFrom = deleteFrom + 1;
|
|
185
|
-
const listNode = sourceListNode.type.create(listAttrs, slicedItems.content);
|
|
186
|
-
tr = tr.insert(insertFrom, listNode);
|
|
187
|
-
const paragraph = paragraphType.create({}, Fragment.empty);
|
|
188
|
-
tr = tr.insert(insertFrom, paragraph);
|
|
189
|
-
tr = tr.setSelection(TextSelection.create(tr.doc, insertFrom));
|
|
190
|
-
return tr;
|
|
191
|
-
}
|
|
1
|
+
// @flow
|
|
2
|
+
|
|
3
|
+
import uuid from './ui/uuid.js';
|
|
4
|
+
import { Fragment, Schema } from 'prosemirror-model';
|
|
5
|
+
import { TextSelection } from 'prosemirror-state';
|
|
6
|
+
import { Transform, canSplit } from 'prosemirror-transform';
|
|
7
|
+
import { LIST_ITEM, ORDERED_LIST, BULLET_LIST, PARAGRAPH } from './NodeNames.js';
|
|
8
|
+
import { findParentNodeOfType } from 'prosemirror-utils';
|
|
9
|
+
|
|
10
|
+
// Splits a list item by the current cursor's position.
|
|
11
|
+
// Some examples:
|
|
12
|
+
//
|
|
13
|
+
// - split before item's text:
|
|
14
|
+
// - before:
|
|
15
|
+
// 1. <cursor>AA
|
|
16
|
+
// 2. BB
|
|
17
|
+
// 3. CC
|
|
18
|
+
// - after:
|
|
19
|
+
// 1. <cursor>
|
|
20
|
+
// 2. AA
|
|
21
|
+
// 3. BB
|
|
22
|
+
// 4. CC
|
|
23
|
+
//
|
|
24
|
+
// - split between item's text:
|
|
25
|
+
// - before:
|
|
26
|
+
// 1. AA
|
|
27
|
+
// 2. B<cursor>B
|
|
28
|
+
// 3. CC
|
|
29
|
+
// - after:
|
|
30
|
+
// 1. AA
|
|
31
|
+
// 2. B
|
|
32
|
+
// 3. B
|
|
33
|
+
// 4. CC
|
|
34
|
+
//
|
|
35
|
+
// - split after item's text:
|
|
36
|
+
// - before:
|
|
37
|
+
// 1. AA
|
|
38
|
+
// 2. BB<cursor>
|
|
39
|
+
// 3. CC
|
|
40
|
+
// - after:
|
|
41
|
+
// 1. AA
|
|
42
|
+
// 2. BB
|
|
43
|
+
// 3. <cursor>
|
|
44
|
+
// 4. CC
|
|
45
|
+
//
|
|
46
|
+
// - split at item with empty content:
|
|
47
|
+
// - before:
|
|
48
|
+
// 1. AA
|
|
49
|
+
// 2. <cursor>
|
|
50
|
+
// 3. CC
|
|
51
|
+
// - after:
|
|
52
|
+
// 1. AA
|
|
53
|
+
// <cursor>
|
|
54
|
+
// 2. BB
|
|
55
|
+
// 3. CC
|
|
56
|
+
//
|
|
57
|
+
export default function splitListItem(
|
|
58
|
+
tr: Transform,
|
|
59
|
+
schema: Schema
|
|
60
|
+
): Transform {
|
|
61
|
+
const nodeType = schema.nodes[LIST_ITEM];
|
|
62
|
+
if (!nodeType) {
|
|
63
|
+
return tr;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const { selection } = tr;
|
|
67
|
+
if (!selection) {
|
|
68
|
+
return tr;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const { $from, $to, node } = selection;
|
|
72
|
+
if ((node?.isBlock) || $from.depth < 2 || !$from.sameParent($to)) {
|
|
73
|
+
return tr;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const grandParent = $from.node(-1);
|
|
77
|
+
if (grandParent.type !== nodeType) {
|
|
78
|
+
return tr;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if ($from.parent.content.size == 0) {
|
|
82
|
+
// In an empty list item.
|
|
83
|
+
return splitEmptyListItem(tr, schema);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const nextType =
|
|
87
|
+
$to.pos == $from.end()
|
|
88
|
+
? grandParent.contentMatchAt($from.indexAfter(-1)).defaultType
|
|
89
|
+
: null;
|
|
90
|
+
|
|
91
|
+
tr = tr.delete($from.pos, $to.pos);
|
|
92
|
+
const types = nextType && [null, { type: nextType }];
|
|
93
|
+
if (!canSplit(tr.doc, $from.pos, 2, types)) {
|
|
94
|
+
return tr;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return tr.split($from.pos, 2, types);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Splits an item with empty content:
|
|
101
|
+
// - before:
|
|
102
|
+
// 1. AA
|
|
103
|
+
// 2. <cursor>
|
|
104
|
+
// 3. CC
|
|
105
|
+
// - after:
|
|
106
|
+
// 1. AA
|
|
107
|
+
// <cursor>
|
|
108
|
+
// 2. BB
|
|
109
|
+
// 3. CC
|
|
110
|
+
function splitEmptyListItem(tr: Transform, schema: Schema): Transform {
|
|
111
|
+
const listItemType = schema.nodes[LIST_ITEM];
|
|
112
|
+
const orderedListType = schema.nodes[ORDERED_LIST];
|
|
113
|
+
const bulletListType = schema.nodes[BULLET_LIST];
|
|
114
|
+
const paragraphType = schema.nodes[PARAGRAPH];
|
|
115
|
+
if (!listItemType || !paragraphType) {
|
|
116
|
+
// Schema does not support the nodes expected.
|
|
117
|
+
return tr;
|
|
118
|
+
}
|
|
119
|
+
const listItemFound = findParentNodeOfType(listItemType)(tr.selection);
|
|
120
|
+
if (!listItemFound || listItemFound.node.textContent !== '') {
|
|
121
|
+
// Cursor is not inside an empty list item.
|
|
122
|
+
return tr;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const listFound =
|
|
126
|
+
(orderedListType && findParentNodeOfType(orderedListType)(tr.selection)) ||
|
|
127
|
+
(bulletListType && findParentNodeOfType(bulletListType)(tr.selection));
|
|
128
|
+
|
|
129
|
+
if (!listFound) {
|
|
130
|
+
// Cursor isn't inside an list.
|
|
131
|
+
return tr;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const $listItemPos = tr.doc.resolve(listItemFound.pos);
|
|
135
|
+
const listItemIndex = $listItemPos.index($listItemPos.depth);
|
|
136
|
+
const listFoundNode = listFound.node;
|
|
137
|
+
if (
|
|
138
|
+
listFoundNode.childCount < 3 ||
|
|
139
|
+
listItemIndex < 1 ||
|
|
140
|
+
listItemIndex >= listFoundNode.childCount - 1
|
|
141
|
+
) {
|
|
142
|
+
// - The list must have at least three list items
|
|
143
|
+
// - The cursor must be after the first list item and before the last list
|
|
144
|
+
// item.
|
|
145
|
+
// If both conditions don't match, bails out, which will remove the empty
|
|
146
|
+
// item.
|
|
147
|
+
return tr;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Find the name of the current list to split. If the name isn't available,
|
|
151
|
+
// assigns a new name.
|
|
152
|
+
let { name } = listFoundNode.attrs;
|
|
153
|
+
if (!name) {
|
|
154
|
+
name = uuid();
|
|
155
|
+
tr = tr.setNodeMarkup(
|
|
156
|
+
listFound.pos,
|
|
157
|
+
listFoundNode.type,
|
|
158
|
+
{
|
|
159
|
+
...listFoundNode.attrs,
|
|
160
|
+
name,
|
|
161
|
+
},
|
|
162
|
+
listFoundNode.marks
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// We'll split the list into two lists.
|
|
167
|
+
// the first list contains the items before the cursor, and the second
|
|
168
|
+
// list contains the items after the cursor and the second list will "follow"
|
|
169
|
+
// the first list by sharing the same counter variable.
|
|
170
|
+
const sliceFrom = listItemFound.pos + listItemFound.node.nodeSize;
|
|
171
|
+
const sliceTo = listFound.pos + listFound.node.nodeSize - 1;
|
|
172
|
+
const slicedItems = tr.doc.slice(sliceFrom, sliceTo, false);
|
|
173
|
+
|
|
174
|
+
const deleteFrom = listItemFound.pos;
|
|
175
|
+
const deleteTo = listFound.pos + listFound.node.nodeSize;
|
|
176
|
+
tr = tr.delete(deleteFrom, deleteTo);
|
|
177
|
+
const sourceListNode = listFound.node;
|
|
178
|
+
const listAttrs = { ...sourceListNode.attrs };
|
|
179
|
+
if (orderedListType === sourceListNode.type) {
|
|
180
|
+
listAttrs.counterReset = 'none';
|
|
181
|
+
listAttrs.following = name;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const insertFrom = deleteFrom + 1;
|
|
185
|
+
const listNode = sourceListNode.type.create(listAttrs, slicedItems.content);
|
|
186
|
+
tr = tr.insert(insertFrom, listNode);
|
|
187
|
+
const paragraph = paragraphType.create({}, Fragment.empty);
|
|
188
|
+
tr = tr.insert(insertFrom, paragraph);
|
|
189
|
+
tr = tr.setSelection(TextSelection.create(tr.doc, insertFrom));
|
|
190
|
+
return tr;
|
|
191
|
+
}
|
package/styles.css
CHANGED
|
@@ -1,47 +1,47 @@
|
|
|
1
|
-
@import './ui/czi-vars.css';
|
|
2
|
-
@import './ui/czi-heading.css';
|
|
3
|
-
@import './ui/czi-indent.css';
|
|
4
|
-
@import './ui/czi-list.css';
|
|
5
|
-
@import './ui/czi-table.css';
|
|
6
|
-
@import './ui/czi-bookmark-view.css';
|
|
7
|
-
@import './ui/czi-body-layout-editor.css';
|
|
8
|
-
@import './ui/czi-cursor-placeholder.css';
|
|
9
|
-
@import './ui/czi-custom-menu.css';
|
|
10
|
-
@import './ui/czi-custom-menu-button.css';
|
|
11
|
-
@import './ui/czi-custom-menu-item.css';
|
|
12
|
-
@import './ui/czi-custom-radio-button.css';
|
|
13
|
-
@import './ui/czi-custom-scrollbar.css';
|
|
14
|
-
@import './ui/czi-editor.css';
|
|
15
|
-
@import './ui/czi-editor-frameset.css';
|
|
16
|
-
@import './ui/czi-editor-toolbar.css';
|
|
17
|
-
@import './ui/czi-form.css';
|
|
18
|
-
@import './ui/czi-frag.css';
|
|
19
|
-
@import './ui/czi-icon.css';
|
|
20
|
-
@import './ui/czi-image-resize-box.css';
|
|
21
|
-
@import './ui/czi-image-upload-editor.css';
|
|
22
|
-
@import './ui/czi-image-upload-placeholder.css';
|
|
23
|
-
@import './ui/czi-image-url-editor.css';
|
|
24
|
-
@import './ui/czi-image-view.css';
|
|
25
|
-
@import './ui/czi-inline-editor.css';
|
|
26
|
-
@import './ui/czi-link-tooltip.css';
|
|
27
|
-
@import './ui/czi-loading-indicator.css';
|
|
28
|
-
@import './ui/czi-math-view.css';
|
|
29
|
-
@import './ui/czi-selection-placeholder.css';
|
|
30
|
-
@import './ui/czi-table-cell-menu.css';
|
|
31
|
-
@import './ui/czi-table-grid-size-editor.css';
|
|
32
|
-
@import './client/licit.css';
|
|
33
|
-
@import '@modusoperandi/licit-ui-commands/styles.css';
|
|
34
|
-
|
|
35
|
-
/* Now loaded locally, so that it work in closed network as well. */
|
|
36
|
-
@import './ui/fonts.css';
|
|
37
|
-
@import './ui/icon-font.css';
|
|
38
|
-
@import 'prosemirror-gapcursor/style/gapcursor.css';
|
|
39
|
-
@import 'prosemirror-view/style/prosemirror.css';
|
|
40
|
-
@import 'react-tooltip/dist/react-tooltip.css';
|
|
41
|
-
@import './ui/listType.css';
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
.ProseMirror {
|
|
45
|
-
content-visibility: auto /* (browser) Only render visable content /
|
|
46
|
-
}
|
|
1
|
+
@import './ui/czi-vars.css';
|
|
2
|
+
@import './ui/czi-heading.css';
|
|
3
|
+
@import './ui/czi-indent.css';
|
|
4
|
+
@import './ui/czi-list.css';
|
|
5
|
+
@import './ui/czi-table.css';
|
|
6
|
+
@import './ui/czi-bookmark-view.css';
|
|
7
|
+
@import './ui/czi-body-layout-editor.css';
|
|
8
|
+
@import './ui/czi-cursor-placeholder.css';
|
|
9
|
+
@import './ui/czi-custom-menu.css';
|
|
10
|
+
@import './ui/czi-custom-menu-button.css';
|
|
11
|
+
@import './ui/czi-custom-menu-item.css';
|
|
12
|
+
@import './ui/czi-custom-radio-button.css';
|
|
13
|
+
@import './ui/czi-custom-scrollbar.css';
|
|
14
|
+
@import './ui/czi-editor.css';
|
|
15
|
+
@import './ui/czi-editor-frameset.css';
|
|
16
|
+
@import './ui/czi-editor-toolbar.css';
|
|
17
|
+
@import './ui/czi-form.css';
|
|
18
|
+
@import './ui/czi-frag.css';
|
|
19
|
+
@import './ui/czi-icon.css';
|
|
20
|
+
@import './ui/czi-image-resize-box.css';
|
|
21
|
+
@import './ui/czi-image-upload-editor.css';
|
|
22
|
+
@import './ui/czi-image-upload-placeholder.css';
|
|
23
|
+
@import './ui/czi-image-url-editor.css';
|
|
24
|
+
@import './ui/czi-image-view.css';
|
|
25
|
+
@import './ui/czi-inline-editor.css';
|
|
26
|
+
@import './ui/czi-link-tooltip.css';
|
|
27
|
+
@import './ui/czi-loading-indicator.css';
|
|
28
|
+
@import './ui/czi-math-view.css';
|
|
29
|
+
@import './ui/czi-selection-placeholder.css';
|
|
30
|
+
@import './ui/czi-table-cell-menu.css';
|
|
31
|
+
@import './ui/czi-table-grid-size-editor.css';
|
|
32
|
+
@import './client/licit.css';
|
|
33
|
+
@import '@modusoperandi/licit-ui-commands/styles.css';
|
|
34
|
+
|
|
35
|
+
/* Now loaded locally, so that it work in closed network as well. */
|
|
36
|
+
@import './ui/fonts.css';
|
|
37
|
+
@import './ui/icon-font.css';
|
|
38
|
+
@import 'prosemirror-gapcursor/style/gapcursor.css';
|
|
39
|
+
@import 'prosemirror-view/style/prosemirror.css';
|
|
40
|
+
@import 'react-tooltip/dist/react-tooltip.css';
|
|
41
|
+
@import './ui/listType.css';
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
.ProseMirror {
|
|
45
|
+
content-visibility: auto /* (browser) Only render visable content /
|
|
46
|
+
}
|
|
47
47
|
*/
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
// [FS-SEA][24-02-2020]
|
|
2
|
-
// overrided the method form 'convertToCSSPTValue.js' file to avoid the compiling issue .
|
|
3
|
-
// [FS][28-02-2020]
|
|
4
|
-
// IRAD-893 - Copy Paste From External Source Not Working
|
|
5
|
-
// removed {} from import, because convertToCSSPTValue is a default export function.
|
|
6
|
-
import convertToCSSPTValue from './convertToCSSPTValue.js';
|
|
7
|
-
|
|
8
|
-
export function toClosestFontPtSize(styleValue: string): number {
|
|
9
|
-
// duplicated FONT_PT_SIZES(available in ./ui/FontSizeCommandMenuButton)
|
|
10
|
-
const FONT_PT_SIZES = [8, 9, 10, 11, 12, 14, 18, 24, 30, 36, 48, 60, 72, 90];
|
|
11
|
-
const originalPTValue = convertToCSSPTValue(styleValue);
|
|
12
|
-
|
|
13
|
-
if (FONT_PT_SIZES.includes(originalPTValue)) {
|
|
14
|
-
return originalPTValue;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
return FONT_PT_SIZES.reduce((prev, curr) => {
|
|
18
|
-
return Math.abs(curr - originalPTValue) < Math.abs(prev - originalPTValue)
|
|
19
|
-
? curr
|
|
20
|
-
: prev;
|
|
21
|
-
}, Number.NEGATIVE_INFINITY);
|
|
22
|
-
}
|
|
1
|
+
// [FS-SEA][24-02-2020]
|
|
2
|
+
// overrided the method form 'convertToCSSPTValue.js' file to avoid the compiling issue .
|
|
3
|
+
// [FS][28-02-2020]
|
|
4
|
+
// IRAD-893 - Copy Paste From External Source Not Working
|
|
5
|
+
// removed {} from import, because convertToCSSPTValue is a default export function.
|
|
6
|
+
import convertToCSSPTValue from './convertToCSSPTValue.js';
|
|
7
|
+
|
|
8
|
+
export function toClosestFontPtSize(styleValue: string): number {
|
|
9
|
+
// duplicated FONT_PT_SIZES(available in ./ui/FontSizeCommandMenuButton)
|
|
10
|
+
const FONT_PT_SIZES = [8, 9, 10, 11, 12, 14, 18, 24, 30, 36, 48, 60, 72, 90];
|
|
11
|
+
const originalPTValue = convertToCSSPTValue(styleValue);
|
|
12
|
+
|
|
13
|
+
if (FONT_PT_SIZES.includes(originalPTValue)) {
|
|
14
|
+
return originalPTValue;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return FONT_PT_SIZES.reduce((prev, curr) => {
|
|
18
|
+
return Math.abs(curr - originalPTValue) < Math.abs(prev - originalPTValue)
|
|
19
|
+
? curr
|
|
20
|
+
: prev;
|
|
21
|
+
}, Number.NEGATIVE_INFINITY);
|
|
22
|
+
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
// @flow
|
|
2
|
-
|
|
3
|
-
// Parses HTML in a detached document to help with avoiding XSS
|
|
4
|
-
// https://developer.mozilla.org/en-US/docs/Archive/Add-ons/Code_snippets/HTML_to_DOM
|
|
5
|
-
// https://github.com/ProseMirror/prosemirror/issues/473#issuecomment-255727531
|
|
6
|
-
export default function toSafeHTMLDocument(html: string): ?Document {
|
|
7
|
-
const parser = new window.DOMParser();
|
|
8
|
-
return parser.parseFromString(html, 'text/html');
|
|
9
|
-
}
|
|
1
|
+
// @flow
|
|
2
|
+
|
|
3
|
+
// Parses HTML in a detached document to help with avoiding XSS
|
|
4
|
+
// https://developer.mozilla.org/en-US/docs/Archive/Add-ons/Code_snippets/HTML_to_DOM
|
|
5
|
+
// https://github.com/ProseMirror/prosemirror/issues/473#issuecomment-255727531
|
|
6
|
+
export default function toSafeHTMLDocument(html: string): ?Document {
|
|
7
|
+
const parser = new window.DOMParser();
|
|
8
|
+
return parser.parseFromString(html, 'text/html');
|
|
9
|
+
}
|