@nldd/design-system 0.8.86 → 0.8.88
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/custom-elements.json +662 -144
- package/dist/components/actions/icon-button/icon-button.d.ts +2 -2
- package/dist/components/actions/icon-button/icon-button.d.ts.map +1 -1
- package/dist/components/actions/icon-button/icon-button.js +3 -3
- package/dist/components/actions/icon-button/icon-button.js.map +1 -1
- package/dist/components/components.js +1263 -273
- package/dist/components/content/avatar/avatar.d.ts +6 -6
- package/dist/components/content/avatar/avatar.d.ts.map +1 -1
- package/dist/components/content/avatar/avatar.js +9 -9
- package/dist/components/content/avatar/avatar.js.map +1 -1
- package/dist/components/content/icon/icon-aliases.d.ts.map +1 -1
- package/dist/components/content/icon/icon-aliases.js +4 -0
- package/dist/components/content/icon/icon-aliases.js.map +1 -1
- package/dist/components/content/icon/icon-gallery-status.d.ts.map +1 -1
- package/dist/components/content/icon/icon-gallery-status.js +3 -26
- package/dist/components/content/icon/icon-gallery-status.js.map +1 -1
- package/dist/components/content/icon/icon-registry.d.ts.map +1 -1
- package/dist/components/content/icon/icon-registry.js +2 -0
- package/dist/components/content/icon/icon-registry.js.map +1 -1
- package/dist/components/content/icon/icon.d.ts +2 -2
- package/dist/components/content/icon/icon.d.ts.map +1 -1
- package/dist/components/content/icon/icon.js +3 -3
- package/dist/components/content/icon/icon.js.map +1 -1
- package/dist/components/content/icon/icon.styles.d.ts.map +1 -1
- package/dist/components/content/icon/icon.styles.js +8 -2
- package/dist/components/content/icon/icon.styles.js.map +1 -1
- package/dist/components/content/rich-text/rich-text.d.ts +7 -6
- package/dist/components/content/rich-text/rich-text.d.ts.map +1 -1
- package/dist/components/content/rich-text/rich-text.js +8 -7
- package/dist/components/content/rich-text/rich-text.js.map +1 -1
- package/dist/components/content/text/text.d.ts +2 -2
- package/dist/components/content/text/text.js +3 -3
- package/dist/components/content/title/title.d.ts +5 -5
- package/dist/components/content/title/title.d.ts.map +1 -1
- package/dist/components/content/title/title.js +6 -6
- package/dist/components/content/title/title.js.map +1 -1
- package/dist/components/content/tooltip/tooltip.d.ts +2 -2
- package/dist/components/content/tooltip/tooltip.d.ts.map +1 -1
- package/dist/components/content/tooltip/tooltip.js +4 -4
- package/dist/components/content/tooltip/tooltip.js.map +1 -1
- package/dist/components/{dist-C09E9-dJ.js → dist-B_Mnmrj4.js} +1 -1
- package/dist/components/{dist-CjaG8dOI.js → dist-ByH8hQze.js} +2 -2
- package/dist/components/{dist-BB7TxeMK.js → dist-CRwuSgMM.js} +2 -2
- package/dist/components/{dist-la_b3ZSq.js → dist-CSrO_mYe.js} +1 -1
- package/dist/components/{dist-762GHPyH.js → dist-CX3DK4i7.js} +3 -3
- package/dist/components/{dist-DZoFKUO-.js → dist-CbCO0WCd.js} +1 -1
- package/dist/components/{dist-B_3OW7pC.js → dist-CgDuh26K.js} +1 -1
- package/dist/components/{dist-DaavuU6W.js → dist-DXZ-cFAl.js} +2 -2
- package/dist/components/{dist-CRsR6ckU.js → dist-LX8LuMac.js} +1 -1
- package/dist/components/{dist-BJI4-6iQ.js → dist-eVFegyjM.js} +1 -1
- package/dist/components/{dist-C6gnorjP.js → dist-fIxe0l7k.js} +9 -1
- package/dist/components/{icon-Cd4BloIM.js → icon-C_zwJZ_g.js} +14 -4
- package/dist/components/{icon-button-CXN0yaVx.js → icon-button-CEz4MB9H.js} +10 -10
- package/dist/components/inputs/code-editor/code-editor.styles.js +2 -2
- package/dist/components/inputs/text-editor/text-editor.annotation-sentinels.d.ts +3 -5
- package/dist/components/inputs/text-editor/text-editor.annotation-sentinels.d.ts.map +1 -1
- package/dist/components/inputs/text-editor/text-editor.annotation-sentinels.js +30 -44
- package/dist/components/inputs/text-editor/text-editor.annotation-sentinels.js.map +1 -1
- package/dist/components/inputs/text-editor/text-editor.annotations.d.ts.map +1 -1
- package/dist/components/inputs/text-editor/text-editor.annotations.js +31 -5
- package/dist/components/inputs/text-editor/text-editor.annotations.js.map +1 -1
- package/dist/components/inputs/text-editor/text-editor.commands.d.ts +14 -2
- package/dist/components/inputs/text-editor/text-editor.commands.d.ts.map +1 -1
- package/dist/components/inputs/text-editor/text-editor.commands.js +115 -36
- package/dist/components/inputs/text-editor/text-editor.commands.js.map +1 -1
- package/dist/components/inputs/text-editor/text-editor.cursor.d.ts +7 -0
- package/dist/components/inputs/text-editor/text-editor.cursor.d.ts.map +1 -0
- package/dist/components/inputs/text-editor/text-editor.cursor.js +207 -0
- package/dist/components/inputs/text-editor/text-editor.cursor.js.map +1 -0
- package/dist/components/inputs/text-editor/text-editor.d.ts +65 -13
- package/dist/components/inputs/text-editor/text-editor.d.ts.map +1 -1
- package/dist/components/inputs/text-editor/text-editor.emphasis.d.ts +32 -0
- package/dist/components/inputs/text-editor/text-editor.emphasis.d.ts.map +1 -0
- package/dist/components/inputs/text-editor/text-editor.emphasis.js +229 -0
- package/dist/components/inputs/text-editor/text-editor.emphasis.js.map +1 -0
- package/dist/components/inputs/text-editor/text-editor.js +177 -18
- package/dist/components/inputs/text-editor/text-editor.js.map +1 -1
- package/dist/components/inputs/text-editor/text-editor.links.d.ts +8 -0
- package/dist/components/inputs/text-editor/text-editor.links.d.ts.map +1 -1
- package/dist/components/inputs/text-editor/text-editor.links.js +30 -4
- package/dist/components/inputs/text-editor/text-editor.links.js.map +1 -1
- package/dist/components/inputs/text-editor/text-editor.markdown.d.ts.map +1 -1
- package/dist/components/inputs/text-editor/text-editor.markdown.js +52 -18
- package/dist/components/inputs/text-editor/text-editor.markdown.js.map +1 -1
- package/dist/components/inputs/text-editor/text-editor.mentions.d.ts +78 -11
- package/dist/components/inputs/text-editor/text-editor.mentions.d.ts.map +1 -1
- package/dist/components/inputs/text-editor/text-editor.mentions.js +190 -41
- package/dist/components/inputs/text-editor/text-editor.mentions.js.map +1 -1
- package/dist/components/inputs/text-editor/text-editor.ordered-list.d.ts +0 -2
- package/dist/components/inputs/text-editor/text-editor.ordered-list.d.ts.map +1 -1
- package/dist/components/inputs/text-editor/text-editor.ordered-list.js +21 -1
- package/dist/components/inputs/text-editor/text-editor.ordered-list.js.map +1 -1
- package/dist/components/inputs/text-editor/text-editor.styles.d.ts.map +1 -1
- package/dist/components/inputs/text-editor/text-editor.styles.js +11 -10
- package/dist/components/inputs/text-editor/text-editor.styles.js.map +1 -1
- package/dist/components/inputs/text-editor/text-editor.syntax.d.ts +9 -0
- package/dist/components/inputs/text-editor/text-editor.syntax.d.ts.map +1 -0
- package/dist/components/inputs/text-editor/text-editor.syntax.js +20 -0
- package/dist/components/inputs/text-editor/text-editor.syntax.js.map +1 -0
- package/dist/components/layout/page/page.d.ts +23 -5
- package/dist/components/layout/page/page.d.ts.map +1 -1
- package/dist/components/layout/page/page.js +39 -34
- package/dist/components/layout/page/page.js.map +1 -1
- package/dist/components/layout/page/page.styles.d.ts.map +1 -1
- package/dist/components/layout/page/page.styles.js +2 -0
- package/dist/components/layout/page/page.styles.js.map +1 -1
- package/dist/components/layout/page-sections/page-section-controls.d.ts +0 -70
- package/dist/components/layout/page-sections/page-section-controls.d.ts.map +1 -1
- package/dist/components/layout/page-sections/page-section-controls.js +0 -3
- package/dist/components/layout/page-sections/page-section-controls.js.map +1 -1
- package/dist/components/layout/sheet/sheet.d.ts +3 -7
- package/dist/components/layout/sheet/sheet.d.ts.map +1 -1
- package/dist/components/layout/sheet/sheet.js +4 -18
- package/dist/components/layout/sheet/sheet.js.map +1 -1
- package/dist/components/layout/sheet/sheet.styles.d.ts.map +1 -1
- package/dist/components/layout/sheet/sheet.styles.js +0 -4
- package/dist/components/layout/sheet/sheet.styles.js.map +1 -1
- package/dist/components/layout/sheet/sheet.template.d.ts.map +1 -1
- package/dist/components/layout/sheet/sheet.template.js +5 -2
- package/dist/components/layout/sheet/sheet.template.js.map +1 -1
- package/dist/components/layout/window/window.d.ts +2 -4
- package/dist/components/layout/window/window.d.ts.map +1 -1
- package/dist/components/layout/window/window.js +4 -14
- package/dist/components/layout/window/window.js.map +1 -1
- package/dist/components/layout/window/window.template.d.ts.map +1 -1
- package/dist/components/layout/window/window.template.js +5 -2
- package/dist/components/layout/window/window.template.js.map +1 -1
- package/dist/components/lists-and-tables/cells/icon-cell/icon-cell.d.ts +2 -2
- package/dist/components/lists-and-tables/cells/icon-cell/icon-cell.js +3 -3
- package/dist/components/lists-and-tables/cells/text-cell/text-cell.d.ts +2 -2
- package/dist/components/lists-and-tables/cells/text-cell/text-cell.js +3 -3
- package/dist/components/lists-and-tables/cells/title-cell/title-cell.d.ts +2 -2
- package/dist/components/lists-and-tables/cells/title-cell/title-cell.js +3 -3
- package/dist/components/lists-and-tables/list/list.d.ts +4 -2
- package/dist/components/lists-and-tables/list/list.d.ts.map +1 -1
- package/dist/components/lists-and-tables/list/list.js +23 -5
- package/dist/components/lists-and-tables/list/list.js.map +1 -1
- package/dist/components/navigation/document-tab-bar/document-tab-bar.template.js +1 -1
- package/dist/components/navigation/document-tab-bar/document-tab-bar.template.js.map +1 -1
- package/dist/components/navigation/link/link.d.ts +2 -2
- package/dist/components/navigation/link/link.d.ts.map +1 -1
- package/dist/components/navigation/link/link.js +3 -2
- package/dist/components/navigation/link/link.js.map +1 -1
- package/dist/components/navigation/menu-bar/menu-bar.d.ts +4 -2
- package/dist/components/navigation/menu-bar/menu-bar.d.ts.map +1 -1
- package/dist/components/navigation/menu-bar/menu-bar.js +4 -2
- package/dist/components/navigation/menu-bar/menu-bar.js.map +1 -1
- package/dist/components/status-and-feedback/activity-indicator/activity-indicator.d.ts +3 -3
- package/dist/components/status-and-feedback/activity-indicator/activity-indicator.d.ts.map +1 -1
- package/dist/components/status-and-feedback/activity-indicator/activity-indicator.js +4 -4
- package/dist/components/status-and-feedback/activity-indicator/activity-indicator.js.map +1 -1
- package/dist/components/status-and-feedback/inline-dialog/inline-dialog.d.ts +8 -0
- package/dist/components/status-and-feedback/inline-dialog/inline-dialog.d.ts.map +1 -1
- package/dist/components/status-and-feedback/inline-dialog/inline-dialog.js +14 -0
- package/dist/components/status-and-feedback/inline-dialog/inline-dialog.js.map +1 -1
- package/dist/components/status-and-feedback/inline-dialog/inline-dialog.styles.d.ts.map +1 -1
- package/dist/components/status-and-feedback/inline-dialog/inline-dialog.styles.js +22 -1
- package/dist/components/status-and-feedback/inline-dialog/inline-dialog.styles.js.map +1 -1
- package/dist/components/status-and-feedback/inline-dialog/inline-dialog.template.d.ts.map +1 -1
- package/dist/components/status-and-feedback/inline-dialog/inline-dialog.template.js +6 -2
- package/dist/components/status-and-feedback/inline-dialog/inline-dialog.template.js.map +1 -1
- package/dist/components/status-and-feedback/modal-dialog/modal-dialog.d.ts +3 -1
- package/dist/components/status-and-feedback/modal-dialog/modal-dialog.d.ts.map +1 -1
- package/dist/components/status-and-feedback/modal-dialog/modal-dialog.js +5 -0
- package/dist/components/status-and-feedback/modal-dialog/modal-dialog.js.map +1 -1
- package/dist/components/status-and-feedback/modal-dialog/modal-dialog.template.d.ts.map +1 -1
- package/dist/components/status-and-feedback/modal-dialog/modal-dialog.template.js +4 -0
- package/dist/components/status-and-feedback/modal-dialog/modal-dialog.template.js.map +1 -1
- package/dist/components/status-and-feedback/notification/notification-region.d.ts.map +1 -1
- package/dist/components/status-and-feedback/notification/notification-region.js +74 -1
- package/dist/components/status-and-feedback/notification/notification-region.js.map +1 -1
- package/dist/components/status-and-feedback/notification/notification.d.ts +11 -0
- package/dist/components/status-and-feedback/notification/notification.d.ts.map +1 -1
- package/dist/components/status-and-feedback/notification/notification.js +13 -0
- package/dist/components/status-and-feedback/notification/notification.js.map +1 -1
- package/dist/favicon.svg +8 -2
- package/dist/nldd.min.js +536 -496
- package/dist/types/vue.d.ts +33 -25
- package/package.json +1 -1
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { EditorSelection, StateEffect, StateField } from '@codemirror/state';
|
|
2
|
+
import { ViewPlugin } from '@codemirror/view';
|
|
3
|
+
import { enclosingNamed, enclosingNode } from './text-editor.syntax.js';
|
|
4
|
+
/* Emphasis that holds while you type inside it.
|
|
5
|
+
*
|
|
6
|
+
* CommonMark's flanking rules decide whether a `**` opens or closes, and a
|
|
7
|
+
* closing run may not follow whitespace. So `**woord**` is bold and, the moment
|
|
8
|
+
* a space is typed before the closing markers, `**woord **` is not: the line
|
|
9
|
+
* falls back to plain text (the weight, the markers' size, the line height)
|
|
10
|
+
* until the next letter arrives. A bold sentence flickers on every word
|
|
11
|
+
* boundary (#213).
|
|
12
|
+
*
|
|
13
|
+
* The parse is right; showing it that eagerly is not. So the emphasis the caret
|
|
14
|
+
* is in is remembered, and while the caret stays between its markers the styling
|
|
15
|
+
* is held whatever the parser says. When the hold ends (the caret leaves, the
|
|
16
|
+
* editor blurs, a paragraph break cuts the run) the whitespace that broke it is
|
|
17
|
+
* moved outside the markers, `**woord** `. That is what wrapping a selection
|
|
18
|
+
* produces too (#212), so bold made by typing and bold made by selecting end
|
|
19
|
+
* the same. */
|
|
20
|
+
/** The emphasis nodes that live by the flanking rules, with the marker the
|
|
21
|
+
* editor writes for them. Inline code is not among them: a code span keeps its
|
|
22
|
+
* whitespace and never fails to close. */
|
|
23
|
+
export const EMPHASIS_MARKERS = new Map([
|
|
24
|
+
['StrongEmphasis', '**'],
|
|
25
|
+
['Emphasis', '*'],
|
|
26
|
+
['Strikethrough', '~~'],
|
|
27
|
+
]);
|
|
28
|
+
/** The blocks that hold inline content. A held emphasis must stay within one:
|
|
29
|
+
* a paragraph break inside it (Enter twice) ends the run for good. */
|
|
30
|
+
const INLINE_BLOCKS = new Set([
|
|
31
|
+
'Paragraph', 'ATXHeading1', 'ATXHeading2', 'ATXHeading3', 'ATXHeading4', 'ATXHeading5', 'ATXHeading6',
|
|
32
|
+
'SetextHeading1', 'SetextHeading2', 'TableCell',
|
|
33
|
+
]);
|
|
34
|
+
/** What may sit between the end of a run's text and its closing marker for the
|
|
35
|
+
* marker to be moved back to the text: whitespace, and after a line break the
|
|
36
|
+
* scaffolding Enter writes for the next list item, task or quote line. Text
|
|
37
|
+
* there means the break fell inside the run, and that is left alone. */
|
|
38
|
+
const TRAIL_RE = /^\s*(?:\n\s*(?:(?:[-*+]|\d+[.)]|>|\[[ xX]\])\s*)*)*$/;
|
|
39
|
+
/** Starts a hold on markers just written around an empty selection: `****`
|
|
40
|
+
* parses as nothing, so there is no node to remember, but what is typed
|
|
41
|
+
* between them is meant to be bold. */
|
|
42
|
+
export const holdEmphasis = StateEffect.define({
|
|
43
|
+
map: (value, mapping) => ({ ...value, from: mapping.mapPos(value.from, 1), to: mapping.mapPos(value.to, -1) }),
|
|
44
|
+
});
|
|
45
|
+
function emphasisAround(state, pos, side) {
|
|
46
|
+
return enclosingNode(state, pos, side, (node) => EMPHASIS_MARKERS.has(node.name));
|
|
47
|
+
}
|
|
48
|
+
function inlineBlockAt(state, pos) {
|
|
49
|
+
return enclosingNamed(state, pos, 1, INLINE_BLOCKS);
|
|
50
|
+
}
|
|
51
|
+
/** The innermost emphasis the main selection is inside of on both of its sides,
|
|
52
|
+
* as the tree parses it now. Just before the opening marker or just after the
|
|
53
|
+
* closing one is outside: text typed there lands outside the emphasis. */
|
|
54
|
+
function liveEmphasis(state) {
|
|
55
|
+
const { from, to } = state.selection.main;
|
|
56
|
+
const left = emphasisAround(state, from, -1);
|
|
57
|
+
const right = left && emphasisAround(state, to, 1);
|
|
58
|
+
if (!left || !right || left.from !== right.from || left.to !== right.to)
|
|
59
|
+
return null;
|
|
60
|
+
const len = EMPHASIS_MARKERS.get(left.name).length;
|
|
61
|
+
return { from: left.from, to: left.to, name: left.name, marker: state.sliceDoc(left.from, left.from + len), live: true };
|
|
62
|
+
}
|
|
63
|
+
/** Whether a remembered emphasis is still worth holding: the selection is between
|
|
64
|
+
* its markers, both markers are still there, no paragraph break cut it, and
|
|
65
|
+
* the parser has not made something else of its start. (Typing `**` inside
|
|
66
|
+
* bold splits it, and then the tree's own reading should show.) */
|
|
67
|
+
function holds(state, held) {
|
|
68
|
+
const len = held.marker.length;
|
|
69
|
+
const { from, to } = state.selection.main;
|
|
70
|
+
if (from < held.from + len || to > held.to - len)
|
|
71
|
+
return false;
|
|
72
|
+
const text = state.sliceDoc(held.from, held.to);
|
|
73
|
+
if (text.length < 2 * len || !text.startsWith(held.marker) || !text.endsWith(held.marker))
|
|
74
|
+
return false;
|
|
75
|
+
const block = inlineBlockAt(state, held.from);
|
|
76
|
+
if (!block || block.to < held.to)
|
|
77
|
+
return false;
|
|
78
|
+
const parsed = emphasisAround(state, held.from, 1);
|
|
79
|
+
return !(parsed && parsed.name === held.name && parsed.from === held.from);
|
|
80
|
+
}
|
|
81
|
+
function mapHeld(held, through) {
|
|
82
|
+
return { ...held, from: through.changes.mapPos(held.from, 1), to: through.changes.mapPos(held.to, -1) };
|
|
83
|
+
}
|
|
84
|
+
/** The emphasis the caret is in: the tree's own while it parses, and the held
|
|
85
|
+
* one, mapped along through edits, once it does not. Null outside any. */
|
|
86
|
+
export const heldEmphasisField = StateField.define({
|
|
87
|
+
create: (state) => liveEmphasis(state),
|
|
88
|
+
update(prev, tr) {
|
|
89
|
+
// The run the caret was in comes first, live or held: if the tree has let
|
|
90
|
+
// go of it (or still has not taken it up) it is held from here. The tree
|
|
91
|
+
// may well parse an outer emphasis around it, and that one needs no holding.
|
|
92
|
+
if (prev) {
|
|
93
|
+
const held = mapHeld({ ...prev, live: false }, tr);
|
|
94
|
+
if (holds(tr.state, held))
|
|
95
|
+
return held;
|
|
96
|
+
}
|
|
97
|
+
const live = liveEmphasis(tr.state);
|
|
98
|
+
if (live)
|
|
99
|
+
return live;
|
|
100
|
+
const seed = tr.effects.find((effect) => effect.is(holdEmphasis));
|
|
101
|
+
return seed ? { ...seed.value, live: false } : null;
|
|
102
|
+
},
|
|
103
|
+
});
|
|
104
|
+
/** The whitespace at the inside edges of `held`, or null when there is nothing
|
|
105
|
+
* to move: no whitespace at the edges, nothing but whitespace inside, or the
|
|
106
|
+
* markers are gone. The text ends where the opening block's text does: past
|
|
107
|
+
* a paragraph break the rest of the run can never be inside the emphasis, so
|
|
108
|
+
* it counts as trail, provided it is scaffolding and not text. */
|
|
109
|
+
function repairFor(state, held) {
|
|
110
|
+
const len = held.marker.length;
|
|
111
|
+
const text = state.sliceDoc(held.from, held.to);
|
|
112
|
+
if (text.length < 2 * len || !text.startsWith(held.marker) || !text.endsWith(held.marker))
|
|
113
|
+
return null;
|
|
114
|
+
const inner = text.slice(len, text.length - len);
|
|
115
|
+
const lead = /^\s*/.exec(inner)[0].length;
|
|
116
|
+
const block = inlineBlockAt(state, held.from);
|
|
117
|
+
const inBlock = state.sliceDoc(held.from + len, Math.min(held.to - len, block ? block.to : held.to - len));
|
|
118
|
+
const contentEnd = held.from + len + inBlock.replace(/\s+$/, '').length;
|
|
119
|
+
if (contentEnd <= held.from + len + lead)
|
|
120
|
+
return null;
|
|
121
|
+
const trail = held.to - len - contentEnd;
|
|
122
|
+
if (!lead && !trail)
|
|
123
|
+
return null;
|
|
124
|
+
if (!TRAIL_RE.test(state.sliceDoc(contentEnd, held.to - len)))
|
|
125
|
+
return null;
|
|
126
|
+
return { from: held.from, to: held.to, len, lead, trail };
|
|
127
|
+
}
|
|
128
|
+
/** Moves the lead in front of the opening marker and the trail past the closing
|
|
129
|
+
* one. Moving the whitespace rather than the markers keeps an annotation on
|
|
130
|
+
* the text on the text. */
|
|
131
|
+
function repairChanges(state, r) {
|
|
132
|
+
const changes = [];
|
|
133
|
+
if (r.lead) {
|
|
134
|
+
changes.push({ from: r.from, insert: state.sliceDoc(r.from + r.len, r.from + r.len + r.lead) }, { from: r.from + r.len, to: r.from + r.len + r.lead });
|
|
135
|
+
}
|
|
136
|
+
if (r.trail) {
|
|
137
|
+
changes.push({ from: r.to - r.len - r.trail, to: r.to - r.len }, { from: r.to, insert: state.sliceDoc(r.to - r.len - r.trail, r.to - r.len) });
|
|
138
|
+
}
|
|
139
|
+
return changes;
|
|
140
|
+
}
|
|
141
|
+
/** Where a position lands after the repair. The markers and the whitespace swap
|
|
142
|
+
* places, and a caret in the whitespace goes with it past the marker: after
|
|
143
|
+
* the space it typed, outside the run. With `stay` it stays with the text,
|
|
144
|
+
* inside the markers. That is what a blur wants: a toolbar click blurs the
|
|
145
|
+
* editor before its command runs, and the command must find the caret where
|
|
146
|
+
* the typing was. */
|
|
147
|
+
function mapRepair(pos, r, stay) {
|
|
148
|
+
const contentStart = r.from + r.len + r.lead;
|
|
149
|
+
const contentEnd = r.to - r.len - r.trail;
|
|
150
|
+
if (r.lead) {
|
|
151
|
+
if (pos > r.from && pos < r.from + r.len)
|
|
152
|
+
return pos + r.lead;
|
|
153
|
+
if (pos >= r.from + r.len && pos < contentStart)
|
|
154
|
+
return stay ? contentStart : pos - r.len;
|
|
155
|
+
}
|
|
156
|
+
if (r.trail) {
|
|
157
|
+
if (pos > contentEnd && pos <= r.to - r.len)
|
|
158
|
+
return stay ? contentEnd : pos + r.len;
|
|
159
|
+
if (pos > r.to - r.len && pos < r.to)
|
|
160
|
+
return pos - r.trail;
|
|
161
|
+
}
|
|
162
|
+
return pos;
|
|
163
|
+
}
|
|
164
|
+
function repairSpec(state, held, stay) {
|
|
165
|
+
const r = repairFor(state, held);
|
|
166
|
+
if (!r)
|
|
167
|
+
return null;
|
|
168
|
+
const sel = state.selection;
|
|
169
|
+
return {
|
|
170
|
+
changes: repairChanges(state, r),
|
|
171
|
+
selection: EditorSelection.create(sel.ranges.map((range) => EditorSelection.range(mapRepair(range.anchor, r, stay), mapRepair(range.head, r, stay))), sel.mainIndex),
|
|
172
|
+
userEvent: 'input.emphasis',
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
/** The changes that move edge whitespace out of `held`, for a command that
|
|
176
|
+
* steps out of the run itself. Empty when there is nothing to move. */
|
|
177
|
+
export function repairChangesFor(state, held) {
|
|
178
|
+
const r = repairFor(state, held);
|
|
179
|
+
return r ? repairChanges(state, r) : [];
|
|
180
|
+
}
|
|
181
|
+
/** Ends a hold at once, for a blur. The display must be right while the editor
|
|
182
|
+
* is unfocused, and the value it commits must be markdown that renders the way
|
|
183
|
+
* it looked. */
|
|
184
|
+
export function repairHeldEmphasis(view) {
|
|
185
|
+
const held = view.state.field(heldEmphasisField, false);
|
|
186
|
+
if (!held || held.live || view.state.readOnly)
|
|
187
|
+
return;
|
|
188
|
+
const spec = repairSpec(view.state, held, true);
|
|
189
|
+
if (spec)
|
|
190
|
+
view.dispatch(spec);
|
|
191
|
+
}
|
|
192
|
+
/** Repairs an emphasis the moment its hold ends: the caret left it, or a
|
|
193
|
+
* paragraph break cut it. A dispatch during an update is an error, so the
|
|
194
|
+
* repair waits for the update to finish. A microtask is soon enough to land
|
|
195
|
+
* before the paint, so nothing flickers. */
|
|
196
|
+
const repairOnRelease = ViewPlugin.fromClass(class {
|
|
197
|
+
constructor(view) {
|
|
198
|
+
this.view = view;
|
|
199
|
+
this.pending = null;
|
|
200
|
+
this.destroyed = false;
|
|
201
|
+
}
|
|
202
|
+
update(update) {
|
|
203
|
+
if (this.pending)
|
|
204
|
+
this.pending = mapHeld(this.pending, update);
|
|
205
|
+
const before = update.startState.field(heldEmphasisField);
|
|
206
|
+
if (!before)
|
|
207
|
+
return;
|
|
208
|
+
const gone = mapHeld(before, update);
|
|
209
|
+
const after = update.state.field(heldEmphasisField);
|
|
210
|
+
if (after && after.name === gone.name && after.from === gone.from && after.to === gone.to)
|
|
211
|
+
return;
|
|
212
|
+
this.pending = gone;
|
|
213
|
+
queueMicrotask(() => this.flush());
|
|
214
|
+
}
|
|
215
|
+
flush() {
|
|
216
|
+
const held = this.pending;
|
|
217
|
+
this.pending = null;
|
|
218
|
+
if (!held || this.destroyed || this.view.state.readOnly)
|
|
219
|
+
return;
|
|
220
|
+
const spec = repairSpec(this.view.state, held, false);
|
|
221
|
+
if (spec)
|
|
222
|
+
this.view.dispatch(spec);
|
|
223
|
+
}
|
|
224
|
+
destroy() {
|
|
225
|
+
this.destroyed = true;
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
export const heldEmphasis = [heldEmphasisField, repairOnRelease];
|
|
229
|
+
//# sourceMappingURL=text-editor.emphasis.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text-editor.emphasis.js","sourceRoot":"","sources":["../../../../src/components/inputs/text-editor/text-editor.emphasis.ts"],"names":[],"mappings":"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"}
|
|
@@ -19,12 +19,20 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
19
19
|
*
|
|
20
20
|
* Headless: there is no built-in toolbar. A consumer drives formatting via the
|
|
21
21
|
* command methods (toggleBold/toggleItalic/toggleInlineCode/toggleStrikethrough/
|
|
22
|
-
* toggleHeading/toggleBulletList/toggleQuote/toggleLink/runCommand
|
|
22
|
+
* toggleHeading/toggleBulletList/toggleTaskList/toggleQuote/toggleLink/runCommand
|
|
23
|
+
* to toggle, and
|
|
23
24
|
* setHeading/setList for picker-style "set" semantics), reads the active formats
|
|
24
25
|
* with getState(), listens to the nldd-text-editor-state event to render toggle
|
|
25
26
|
* states, and forwards padding clicks with focusFromPoint(). Cmd/Ctrl+B/I/E/K are
|
|
26
|
-
* bound out of the box. Commands keep focus on the editor. An
|
|
27
|
-
*
|
|
27
|
+
* bound out of the box. Commands keep focus on the editor. An inline toggle wraps
|
|
28
|
+
* the selected text (whitespace at its edges stays outside the markers), unwraps
|
|
29
|
+
* a run the caret is in, and with the caret at the very end of a run steps out
|
|
30
|
+
* of it. Bold that a typed space has broken (`**woord **`) keeps its styling
|
|
31
|
+
* while the caret is inside; the space moves outside the markers when the caret
|
|
32
|
+
* leaves. insertAtCursor(text) puts text at the caret and replaceRange(from, to,
|
|
33
|
+
* text) writes at the same clean offsets getSelection() reads. An @-mention typeahead
|
|
34
|
+
* (mentionSource) collapses to an atomic token, further typeahead lists on their
|
|
35
|
+
* own trigger (typeaheads) write what you tell them to, and a W3C-style annotation overlay
|
|
28
36
|
* (annotations) marks ranges with a dashed underline, light tint and a count badge
|
|
29
37
|
* without touching the underlying text.
|
|
30
38
|
*
|
|
@@ -44,6 +52,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
44
52
|
* @attr {string} accessible-label - Accessible label forwarded to the editor. Set automatically by nldd-form-field.
|
|
45
53
|
*
|
|
46
54
|
* @prop {MentionSource} mentionSource - Consumer-supplied @-mention candidate source (property only). Without it, @-typeahead is inert.
|
|
55
|
+
* @prop {Typeahead[]} typeaheads - Your own typeahead lists next to the @-mention (property only): each a trigger character (`#`, `:`, `/`), a `source` that returns candidates for the text typed after it, and an optional `insert` that decides what a choice writes (by default the trigger, the text and a space). Lists on one trigger are merged in order. A candidate is `{ id, text, supportingText? }` and can carry an `avatar` (its row then takes two lines, the supporting text under the text), an `icon` or a `symbol` for its row.
|
|
47
56
|
* @attr {boolean} annotatable - Enable the annotation overlay (off by default). Annotations only render when this is set.
|
|
48
57
|
* @prop {Annotation[]} annotations - Consumer-supplied annotation overlay (property only). Anchored by offset and mapped through edits; the text stays clean. Requires `annotatable`. Assign a NEW array to apply changes (Lit dirty-checks by identity, so in-place mutation like `.push()` won't re-render): `editor.annotations = [...editor.annotations, next]`.
|
|
49
58
|
* @attr {object} translations - Override the editor's assistive-tech strings (the open-in-new-tab link badge and the annotation count badge). Unset keys fall back to Dutch.
|
|
@@ -52,7 +61,8 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
52
61
|
* @fires input - When the content changes (detail: { value })
|
|
53
62
|
* @fires change - When the content is committed on blur (detail: { value })
|
|
54
63
|
* @fires nldd-text-editor-state - When the selection or content changes (detail: TextEditorState), for toolbar toggle state
|
|
55
|
-
* @fires nldd-text-editor-mention - When an @-mention is inserted (detail: MentionInsertedDetail with id,
|
|
64
|
+
* @fires nldd-text-editor-mention - When an @-mention is inserted (detail: MentionInsertedDetail with id, text, from, to; clean offsets, like getSelection())
|
|
65
|
+
* @fires nldd-text-editor-typeahead - When a candidate from one of the `typeaheads` is chosen (detail: TypeaheadChosenDetail with trigger, candidate, from, to; clean offsets)
|
|
56
66
|
* @fires nldd-text-editor-annotation-click - When an annotation's count badge is clicked (detail: { ids: string[], rect: DOMRect }); rect is the badge's viewport box so a consumer can anchor its own note UI to it
|
|
57
67
|
*/
|
|
58
68
|
import { LitElement } from 'lit';
|
|
@@ -65,15 +75,17 @@ import { defaultKeymap, history, historyKeymap, undo as cmUndo, redo as cmRedo,
|
|
|
65
75
|
import { NLDDCodeMirrorElement } from '../../../utilities/codemirror/codemirror-element.js';
|
|
66
76
|
import { nlddCodeMirrorTheme } from '../../../utilities/codemirror/theme.js';
|
|
67
77
|
import { markdownEditing, mentionRangeAt, mentionRangeEndingAt, mentionRangeStartingAt } from './text-editor.markdown.js';
|
|
68
|
-
import {
|
|
78
|
+
import { typeaheads as typeaheadExtension, mentionInsert, mentionToken, } from './text-editor.mentions.js';
|
|
79
|
+
import { repairHeldEmphasis } from './text-editor.emphasis.js';
|
|
69
80
|
import { annotations as annotationExtension, setAnnotations, pasteAnnotations, currentAnnotations } from './text-editor.annotations.js';
|
|
70
81
|
import { orderedListRenumber } from './text-editor.ordered-list.js';
|
|
71
82
|
import { dragToMove, dragMovePlugin } from './text-editor.drag.js';
|
|
72
83
|
import { linkOpenBadge } from './text-editor.links.js';
|
|
73
|
-
import {
|
|
84
|
+
import { stableCursor } from './text-editor.cursor.js';
|
|
85
|
+
import { toggleInlineWrap, indentListItems as cmIndentListItems, outdentListItems as cmOutdentListItems, canIndentListItem as cmCanIndent, canOutdentListItem as cmCanOutdent, toggleHeading as cmToggleHeading, setHeading as cmSetHeading, toggleBulletList as cmToggleBulletList, toggleTaskList as cmToggleTaskList, setList as cmSetList, toggleQuote as cmToggleQuote, toggleLink as cmToggleLink, toggleCodeBlock as cmToggleCodeBlock, clearListMarkerBackward, readActiveFormats, EMPTY_FORMATS, } from './text-editor.commands.js';
|
|
74
86
|
import { textEditorStyles } from './text-editor.styles.js';
|
|
75
87
|
import { textEditorTemplate } from './text-editor.template.js';
|
|
76
|
-
import { stripSentinels, docToClean } from './text-editor.annotation-sentinels.js';
|
|
88
|
+
import { stripSentinels, docToClean, cleanToDoc, sentinelPositions } from './text-editor.annotation-sentinels.js';
|
|
77
89
|
import { nlddTextEditorTranslations } from './text-editor.i18n.js';
|
|
78
90
|
import { DescribedBy } from '../../../utilities/described-by-mixin.js';
|
|
79
91
|
let NLDDTextEditor = class NLDDTextEditor extends DescribedBy(FormAssociated(NLDDCodeMirrorElement)) {
|
|
@@ -94,6 +106,18 @@ let NLDDTextEditor = class NLDDTextEditor extends DescribedBy(FormAssociated(NLD
|
|
|
94
106
|
this.resize = 'auto';
|
|
95
107
|
this.variant = 'simple';
|
|
96
108
|
this.accessibleLabel = '';
|
|
109
|
+
/** Your own typeahead lists next to the @-mention, each on its own trigger
|
|
110
|
+
* character. Property only. Read on every keystroke, so a new array takes
|
|
111
|
+
* effect at once. */
|
|
112
|
+
this.typeaheads = [];
|
|
113
|
+
/** The built-in mention as a typeahead: the `@` list fed by `mentionSource`,
|
|
114
|
+
* writing the token. One object, so a choice can be told apart from a
|
|
115
|
+
* consumer's own `@` list and fire the mention event. */
|
|
116
|
+
this._mentionTypeahead = {
|
|
117
|
+
trigger: '@',
|
|
118
|
+
source: (query) => this.mentionSource?.(query) ?? [],
|
|
119
|
+
insert: mentionInsert,
|
|
120
|
+
};
|
|
97
121
|
/** Whether the annotation overlay is enabled. Off by default; set the
|
|
98
122
|
* `annotatable` attribute to turn it on (so the comment affordance and the
|
|
99
123
|
* overlay only appear when the consumer opts in). */
|
|
@@ -131,6 +155,11 @@ let NLDDTextEditor = class NLDDTextEditor extends DescribedBy(FormAssociated(NLD
|
|
|
131
155
|
/** Text and annotations of the last cut, so a same-editor paste can move the
|
|
132
156
|
* annotations along with their text. Cleared by copy and by a matching paste. */
|
|
133
157
|
this._cutBuffer = null;
|
|
158
|
+
/** The last state handed out, to keep from repeating it. The event drives a
|
|
159
|
+
* toolbar's toggles, and moving the caret within one paragraph leaves every
|
|
160
|
+
* one of them where it was: a consumer would re-render its whole bar on every
|
|
161
|
+
* arrow key for nothing. */
|
|
162
|
+
this._lastState = null;
|
|
134
163
|
/* # Internals */
|
|
135
164
|
this._onScrollerPointerDown = (event) => {
|
|
136
165
|
if (event.target !== this.view?.scrollDOM)
|
|
@@ -201,7 +230,7 @@ let NLDDTextEditor = class NLDDTextEditor extends DescribedBy(FormAssociated(NLD
|
|
|
201
230
|
return [
|
|
202
231
|
nlddCodeMirrorTheme,
|
|
203
232
|
markdownEditing,
|
|
204
|
-
|
|
233
|
+
typeaheadExtension(() => this._typeaheadLists(), (choice) => this._onTypeaheadChosen(choice)),
|
|
205
234
|
// Prec.low so this transaction filter runs *before* the annotation filter
|
|
206
235
|
// (filters run low-precedence first), letting the annotation map through the
|
|
207
236
|
// renumber changes too — otherwise a marker growing from 1 to 11 drifts a
|
|
@@ -222,6 +251,10 @@ let NLDDTextEditor = class NLDDTextEditor extends DescribedBy(FormAssociated(NLD
|
|
|
222
251
|
Prec.highest(linkOpenBadge((url) => this._t('components.text-editor.open-in-new-tab-label', { url }))),
|
|
223
252
|
this._historyCompartment.of(history()),
|
|
224
253
|
drawSelection(),
|
|
254
|
+
// Draws the caret in drawSelection's place, on a side that does not depend on
|
|
255
|
+
// the direction it arrived from unless that direction means something (a
|
|
256
|
+
// widget, a line wrap). See text-editor.cursor.ts.
|
|
257
|
+
stableCursor,
|
|
225
258
|
dropCursor(),
|
|
226
259
|
dragToMove,
|
|
227
260
|
// Prec.highest so this beats the markdown language's deleteMarkupBackward,
|
|
@@ -237,6 +270,12 @@ let NLDDTextEditor = class NLDDTextEditor extends DescribedBy(FormAssociated(NLD
|
|
|
237
270
|
// selects the whole token, the second removes it.
|
|
238
271
|
{ key: 'Backspace', run: (view) => this._selectMentionBeforeDelete(view, -1) },
|
|
239
272
|
{ key: 'Delete', run: (view) => this._selectMentionBeforeDelete(view, 1) },
|
|
273
|
+
// Cmd/Ctrl+] and +[ nest and un-nest list items. defaultKeymap binds them
|
|
274
|
+
// to indentMore/indentLess, whose four-space indent turns plain text into
|
|
275
|
+
// an indented code block. Consumed here in every case: off a list item
|
|
276
|
+
// they do nothing, which beats a code block nobody asked for.
|
|
277
|
+
{ key: 'Mod-]', run: (view) => { cmIndentListItems(view); return true; } },
|
|
278
|
+
{ key: 'Mod-[', run: (view) => { cmOutdentListItems(view); return true; } },
|
|
240
279
|
...defaultKeymap,
|
|
241
280
|
...historyKeymap,
|
|
242
281
|
]),
|
|
@@ -254,7 +293,10 @@ let NLDDTextEditor = class NLDDTextEditor extends DescribedBy(FormAssociated(NLD
|
|
|
254
293
|
focus: () => {
|
|
255
294
|
this._valueAtFocus = this.value;
|
|
256
295
|
},
|
|
257
|
-
blur: () => {
|
|
296
|
+
blur: (_event, view) => {
|
|
297
|
+
// An emphasis held together while it was being typed is closed
|
|
298
|
+
// properly first, so the committed value renders the way it looked.
|
|
299
|
+
repairHeldEmphasis(view);
|
|
258
300
|
if (this.value !== this._valueAtFocus)
|
|
259
301
|
this._emitChange();
|
|
260
302
|
},
|
|
@@ -315,7 +357,9 @@ let NLDDTextEditor = class NLDDTextEditor extends DescribedBy(FormAssociated(NLD
|
|
|
315
357
|
firstUpdated() {
|
|
316
358
|
this._initialValue = this.value;
|
|
317
359
|
this.style.setProperty('--_rows', String(this.rows));
|
|
318
|
-
|
|
360
|
+
// The sentinels are the overlay's own; a value that carries one (an editor
|
|
361
|
+
// whose text was round-tripped through another) hands it back stripped.
|
|
362
|
+
this.mountEditor(stripSentinels(this.value));
|
|
319
363
|
this.onEditorMounted();
|
|
320
364
|
}
|
|
321
365
|
/* Runs on the initial mount and on every re-mount after a detach/reattach
|
|
@@ -349,7 +393,7 @@ let NLDDTextEditor = class NLDDTextEditor extends DescribedBy(FormAssociated(NLD
|
|
|
349
393
|
// mirrors the current (sentinel-stripped) doc must not trigger a rewrite,
|
|
350
394
|
// which would strip the sentinels the filter then re-adds (caret churn).
|
|
351
395
|
if (stripSentinels(this.doc) !== this.value)
|
|
352
|
-
this.setDoc(this.value);
|
|
396
|
+
this.setDoc(stripSentinels(this.value));
|
|
353
397
|
this.commitFormValue();
|
|
354
398
|
}
|
|
355
399
|
if (changed.has('disabled') || changed.has('readonly')) {
|
|
@@ -425,8 +469,15 @@ let NLDDTextEditor = class NLDDTextEditor extends DescribedBy(FormAssociated(NLD
|
|
|
425
469
|
if (this.view)
|
|
426
470
|
cmToggleBulletList(this.view);
|
|
427
471
|
}
|
|
472
|
+
/** Turn the selected lines into GFM task items (`- [ ] `), or back into
|
|
473
|
+
* bullets when they all are tasks. Checking a box is not a command. */
|
|
474
|
+
toggleTaskList() {
|
|
475
|
+
if (this.view)
|
|
476
|
+
cmToggleTaskList(this.view);
|
|
477
|
+
}
|
|
428
478
|
/** Set the list type, replacing any existing list ('none' strips it) — for an
|
|
429
|
-
* exclusive list picker.
|
|
479
|
+
* exclusive list picker. A task keeps its checkbox only within its own type:
|
|
480
|
+
* switching to bullet or ordered takes the box along with the marker. */
|
|
430
481
|
setList(type) {
|
|
431
482
|
if (this.view)
|
|
432
483
|
cmSetList(this.view, type);
|
|
@@ -551,6 +602,41 @@ let NLDDTextEditor = class NLDDTextEditor extends DescribedBy(FormAssociated(NLD
|
|
|
551
602
|
this._pasteText(stripSentinels(raw));
|
|
552
603
|
this.view?.focus();
|
|
553
604
|
}
|
|
605
|
+
/** Puts `text` at the caret, in place of the selection when there is one, and
|
|
606
|
+
* leaves the caret after it, with focus on the editor. Plain text: markdown
|
|
607
|
+
* in it stays as written and is styled like anything typed. Does nothing on
|
|
608
|
+
* a read-only editor. */
|
|
609
|
+
insertAtCursor(text) {
|
|
610
|
+
if (!this.view || this.view.state.readOnly)
|
|
611
|
+
return;
|
|
612
|
+
const clean = stripSentinels(text);
|
|
613
|
+
if (clean)
|
|
614
|
+
this.view.dispatch({ ...this.view.state.replaceSelection(clean), userEvent: 'input' });
|
|
615
|
+
this.view.focus();
|
|
616
|
+
}
|
|
617
|
+
/** Replaces the text between two offsets with `text`, and leaves the caret
|
|
618
|
+
* after it. The offsets are CLEAN, the same coordinates `getSelection()` and
|
|
619
|
+
* the annotations speak, so a consumer can act on what it read there. Both
|
|
620
|
+
* are clamped into the text, and `to` below `from` counts as an insert at
|
|
621
|
+
* `from`. Does nothing on a read-only editor. */
|
|
622
|
+
replaceRange(from, to, text) {
|
|
623
|
+
if (!this.view || this.view.state.readOnly)
|
|
624
|
+
return;
|
|
625
|
+
const doc = this.view.state.doc.toString();
|
|
626
|
+
const sentinels = sentinelPositions(doc);
|
|
627
|
+
const cleanLength = doc.length - sentinels.length;
|
|
628
|
+
const start = Math.max(0, Math.min(from, cleanLength));
|
|
629
|
+
const end = Math.max(start, Math.min(to, cleanLength));
|
|
630
|
+
const insert = stripSentinels(text);
|
|
631
|
+
const docFrom = cleanToDoc(sentinels, start);
|
|
632
|
+
const docTo = cleanToDoc(sentinels, end);
|
|
633
|
+
this.view.dispatch({
|
|
634
|
+
changes: { from: docFrom, to: docTo, insert },
|
|
635
|
+
selection: { anchor: docFrom + insert.length },
|
|
636
|
+
userEvent: 'input',
|
|
637
|
+
});
|
|
638
|
+
this.view.focus();
|
|
639
|
+
}
|
|
554
640
|
/** Insert `text` at the selection, re-attaching the cut annotations when it matches
|
|
555
641
|
* a cut made in this editor (a move, one-shot). Shared by the toolbar's paste()
|
|
556
642
|
* and the native Cmd/Ctrl+V handler. */
|
|
@@ -566,16 +652,28 @@ let NLDDTextEditor = class NLDDTextEditor extends DescribedBy(FormAssociated(NLD
|
|
|
566
652
|
const sameText = (a, b) => a.replace(/\r\n/g, '\n') === b.replace(/\r\n/g, '\n');
|
|
567
653
|
const carry = !!(buffer && sameText(buffer.text, text) && buffer.anns.length > 0);
|
|
568
654
|
const at = docToClean(this.view.state.doc.toString(), this.view.state.selection.main.from);
|
|
569
|
-
|
|
655
|
+
// input.paste, like CodeMirror's own paste: history groups it as one step and
|
|
656
|
+
// a transaction filter can tell a paste from typing.
|
|
657
|
+
const spec = { ...this.view.state.replaceSelection(text), userEvent: 'input.paste' };
|
|
570
658
|
this.view.dispatch(carry ? { ...spec, effects: pasteAnnotations.of({ at, anns: buffer.anns }) } : spec);
|
|
571
659
|
// One-shot: a second paste of the same cut would duplicate the ids, so drop it.
|
|
572
660
|
if (carry)
|
|
573
661
|
this._cutBuffer = null;
|
|
574
662
|
}
|
|
575
|
-
/** Escape hatch: run a command by name
|
|
576
|
-
*
|
|
577
|
-
*
|
|
663
|
+
/** Escape hatch: run a command by name, so a toolbar can carry the name in its
|
|
664
|
+
* markup instead of a method reference. Every method above is reachable.
|
|
665
|
+
*
|
|
666
|
+
* Toggles (no payload): `bold`, `italic`, `inlineCode`, `strikethrough`,
|
|
667
|
+
* `bulletList`, `taskList`, `quote`, `codeBlock`, `heading` (payload: the
|
|
668
|
+
* level, default 1), `link` (payload: the href).
|
|
669
|
+
* Setters: `setHeading` (payload: the level, 0 for a paragraph), `setList`
|
|
670
|
+
* (payload: 'none' | 'bullet' | 'ordered' | 'task').
|
|
671
|
+
* The rest: `indent`, `outdent`, `undo`, `redo`, `copy`, `cut`, `paste`.
|
|
672
|
+
*
|
|
673
|
+
* An unknown name warns rather than doing nothing quietly: a typo in a
|
|
674
|
+
* toolbar is otherwise invisible. */
|
|
578
675
|
runCommand(name, payload) {
|
|
676
|
+
const level = (fallback) => (typeof payload === 'number' ? payload : fallback);
|
|
579
677
|
switch (name) {
|
|
580
678
|
case 'bold':
|
|
581
679
|
this.toggleBold();
|
|
@@ -592,15 +690,39 @@ let NLDDTextEditor = class NLDDTextEditor extends DescribedBy(FormAssociated(NLD
|
|
|
592
690
|
case 'bulletList':
|
|
593
691
|
this.toggleBulletList();
|
|
594
692
|
break;
|
|
693
|
+
case 'taskList':
|
|
694
|
+
this.toggleTaskList();
|
|
695
|
+
break;
|
|
595
696
|
case 'quote':
|
|
596
697
|
this.toggleQuote();
|
|
597
698
|
break;
|
|
699
|
+
case 'codeBlock':
|
|
700
|
+
this.toggleCodeBlock();
|
|
701
|
+
break;
|
|
598
702
|
case 'heading':
|
|
599
|
-
this.toggleHeading((
|
|
703
|
+
this.toggleHeading(level(1));
|
|
704
|
+
break;
|
|
705
|
+
case 'setHeading':
|
|
706
|
+
this.setHeading(level(0));
|
|
707
|
+
break;
|
|
708
|
+
case 'setList':
|
|
709
|
+
this.setList(typeof payload === 'string' ? payload : 'none');
|
|
600
710
|
break;
|
|
601
711
|
case 'link':
|
|
602
712
|
this.toggleLink(typeof payload === 'string' ? payload : '');
|
|
603
713
|
break;
|
|
714
|
+
case 'indent':
|
|
715
|
+
this.indent();
|
|
716
|
+
break;
|
|
717
|
+
case 'outdent':
|
|
718
|
+
this.outdent();
|
|
719
|
+
break;
|
|
720
|
+
case 'undo':
|
|
721
|
+
this.undo();
|
|
722
|
+
break;
|
|
723
|
+
case 'redo':
|
|
724
|
+
this.redo();
|
|
725
|
+
break;
|
|
604
726
|
case 'copy':
|
|
605
727
|
void this.copy();
|
|
606
728
|
break;
|
|
@@ -610,6 +732,7 @@ let NLDDTextEditor = class NLDDTextEditor extends DescribedBy(FormAssociated(NLD
|
|
|
610
732
|
case 'paste':
|
|
611
733
|
void this.paste();
|
|
612
734
|
break;
|
|
735
|
+
default: console.warn(`<nldd-text-editor>: runCommand('${name}') is not a command.`);
|
|
613
736
|
}
|
|
614
737
|
}
|
|
615
738
|
/** The formats active at the current selection (drives a toolbar's state). */
|
|
@@ -667,8 +790,41 @@ let NLDDTextEditor = class NLDDTextEditor extends DescribedBy(FormAssociated(NLD
|
|
|
667
790
|
}));
|
|
668
791
|
}
|
|
669
792
|
_emitState() {
|
|
793
|
+
const state = this.getState();
|
|
794
|
+
const last = this._lastState;
|
|
795
|
+
if (last
|
|
796
|
+
&& last.empty === state.empty
|
|
797
|
+
&& last.canIndent === state.canIndent
|
|
798
|
+
&& last.canOutdent === state.canOutdent
|
|
799
|
+
&& last.canUndo === state.canUndo
|
|
800
|
+
&& last.canRedo === state.canRedo
|
|
801
|
+
&& Object.keys(state.active).every((key) => last.active[key] === state.active[key]))
|
|
802
|
+
return;
|
|
803
|
+
this._lastState = state;
|
|
670
804
|
this.dispatchEvent(new CustomEvent('nldd-text-editor-state', {
|
|
671
|
-
detail:
|
|
805
|
+
detail: state,
|
|
806
|
+
bubbles: true,
|
|
807
|
+
composed: true,
|
|
808
|
+
}));
|
|
809
|
+
}
|
|
810
|
+
_typeaheadLists() {
|
|
811
|
+
return this.mentionSource ? [this._mentionTypeahead, ...this.typeaheads] : this.typeaheads;
|
|
812
|
+
}
|
|
813
|
+
/** A choice from any list. Offsets in the events are clean, like
|
|
814
|
+
* getSelection() and the annotations: the document carries sentinels the
|
|
815
|
+
* value never shows. */
|
|
816
|
+
_onTypeaheadChosen(choice) {
|
|
817
|
+
if (!this.view)
|
|
818
|
+
return;
|
|
819
|
+
const doc = this.view.state.doc.toString();
|
|
820
|
+
const from = docToClean(doc, choice.from);
|
|
821
|
+
if (choice.typeahead === this._mentionTypeahead) {
|
|
822
|
+
const { id, text } = choice.candidate;
|
|
823
|
+
this._emitMention({ id, text, from, to: from + mentionToken(choice.candidate).length });
|
|
824
|
+
return;
|
|
825
|
+
}
|
|
826
|
+
this.dispatchEvent(new CustomEvent('nldd-text-editor-typeahead', {
|
|
827
|
+
detail: { trigger: choice.trigger, candidate: choice.candidate, from, to: docToClean(doc, choice.to) },
|
|
672
828
|
bubbles: true,
|
|
673
829
|
composed: true,
|
|
674
830
|
}));
|
|
@@ -774,6 +930,9 @@ __decorate([
|
|
|
774
930
|
__decorate([
|
|
775
931
|
property({ attribute: false })
|
|
776
932
|
], NLDDTextEditor.prototype, "mentionSource", void 0);
|
|
933
|
+
__decorate([
|
|
934
|
+
property({ attribute: false })
|
|
935
|
+
], NLDDTextEditor.prototype, "typeaheads", void 0);
|
|
777
936
|
__decorate([
|
|
778
937
|
property({ type: Boolean, reflect: true })
|
|
779
938
|
], NLDDTextEditor.prototype, "annotatable", void 0);
|