@malva-ui/editor 0.1.13 → 0.1.14
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/README.md +5 -5
- package/fesm2022/malva-ui-editor-ai.mjs +17 -0
- package/fesm2022/malva-ui-editor-ai.mjs.map +1 -0
- package/fesm2022/malva-ui-editor.mjs +10227 -0
- package/fesm2022/malva-ui-editor.mjs.map +1 -0
- package/package.json +35 -26
- package/types/malva-ui-editor-ai.d.ts +1 -0
- package/types/malva-ui-editor.d.ts +2995 -0
- package/ai/index.d.ts +0 -12
- package/ai/malva-ui-editor-ai.d.ts +0 -5
- package/esm2022/ai/index.js +0 -12
- package/esm2022/ai/index.js.map +0 -1
- package/esm2022/ai/malva-ui-editor-ai.js +0 -5
- package/esm2022/ai/malva-ui-editor-ai.js.map +0 -1
- package/esm2022/index.js +0 -37
- package/esm2022/index.js.map +0 -1
- package/esm2022/lib/ai/editor-ai-actions.js +0 -69
- package/esm2022/lib/ai/editor-ai-actions.js.map +0 -1
- package/esm2022/lib/ai/editor-ai-context.js +0 -612
- package/esm2022/lib/ai/editor-ai-context.js.map +0 -1
- package/esm2022/lib/ai/editor-ai-menu.js +0 -288
- package/esm2022/lib/ai/editor-ai-menu.js.map +0 -1
- package/esm2022/lib/ai/editor-ai-review-bar.js +0 -223
- package/esm2022/lib/ai/editor-ai-review-bar.js.map +0 -1
- package/esm2022/lib/ai/editor-ai-stream.js +0 -677
- package/esm2022/lib/ai/editor-ai-stream.js.map +0 -1
- package/esm2022/lib/ai/editor-ai-suggestions.js +0 -751
- package/esm2022/lib/ai/editor-ai-suggestions.js.map +0 -1
- package/esm2022/lib/ai/editor-ai.tokens.js +0 -10
- package/esm2022/lib/ai/editor-ai.tokens.js.map +0 -1
- package/esm2022/lib/ai/editor-ai.types.js +0 -1
- package/esm2022/lib/ai/editor-ai.types.js.map +0 -1
- package/esm2022/lib/editor/editor.js +0 -985
- package/esm2022/lib/editor/editor.js.map +0 -1
- package/esm2022/lib/editor-extension-preflight.js +0 -83
- package/esm2022/lib/editor-extension-preflight.js.map +0 -1
- package/esm2022/lib/editor-serialization.js +0 -152
- package/esm2022/lib/editor-serialization.js.map +0 -1
- package/esm2022/lib/editor-toolbar-context.js +0 -259
- package/esm2022/lib/editor-toolbar-context.js.map +0 -1
- package/esm2022/lib/editor.tokens.js +0 -10
- package/esm2022/lib/editor.tokens.js.map +0 -1
- package/esm2022/lib/editor.types.js +0 -48
- package/esm2022/lib/editor.types.js.map +0 -1
- package/esm2022/lib/extensions/editor-block-handle.js +0 -760
- package/esm2022/lib/extensions/editor-block-handle.js.map +0 -1
- package/esm2022/lib/extensions/editor-extensions.js +0 -321
- package/esm2022/lib/extensions/editor-extensions.js.map +0 -1
- package/esm2022/lib/extensions/editor-markdown-compatibility.js +0 -162
- package/esm2022/lib/extensions/editor-markdown-compatibility.js.map +0 -1
- package/esm2022/lib/extensions/editor-upload-placeholder.js +0 -156
- package/esm2022/lib/extensions/editor-upload-placeholder.js.map +0 -1
- package/esm2022/lib/status/editor-status.js +0 -64
- package/esm2022/lib/status/editor-status.js.map +0 -1
- package/esm2022/lib/toolbar/editor-alignment.js +0 -203
- package/esm2022/lib/toolbar/editor-alignment.js.map +0 -1
- package/esm2022/lib/toolbar/editor-block-insert.js +0 -101
- package/esm2022/lib/toolbar/editor-block-insert.js.map +0 -1
- package/esm2022/lib/toolbar/editor-color-control.js +0 -71
- package/esm2022/lib/toolbar/editor-color-control.js.map +0 -1
- package/esm2022/lib/toolbar/editor-command-button.js +0 -115
- package/esm2022/lib/toolbar/editor-command-button.js.map +0 -1
- package/esm2022/lib/toolbar/editor-heading.js +0 -266
- package/esm2022/lib/toolbar/editor-heading.js.map +0 -1
- package/esm2022/lib/toolbar/editor-highlight.js +0 -84
- package/esm2022/lib/toolbar/editor-highlight.js.map +0 -1
- package/esm2022/lib/toolbar/editor-image-upload-dialog.js +0 -289
- package/esm2022/lib/toolbar/editor-image-upload-dialog.js.map +0 -1
- package/esm2022/lib/toolbar/editor-image-upload.js +0 -315
- package/esm2022/lib/toolbar/editor-image-upload.js.map +0 -1
- package/esm2022/lib/toolbar/editor-inline-marks.js +0 -124
- package/esm2022/lib/toolbar/editor-inline-marks.js.map +0 -1
- package/esm2022/lib/toolbar/editor-link.js +0 -265
- package/esm2022/lib/toolbar/editor-link.js.map +0 -1
- package/esm2022/lib/toolbar/editor-list.js +0 -249
- package/esm2022/lib/toolbar/editor-list.js.map +0 -1
- package/esm2022/lib/toolbar/editor-table.js +0 -292
- package/esm2022/lib/toolbar/editor-table.js.map +0 -1
- package/esm2022/lib/toolbar/editor-text-color.js +0 -82
- package/esm2022/lib/toolbar/editor-text-color.js.map +0 -1
- package/esm2022/lib/toolbar/editor-toolbar-widget.js +0 -41
- package/esm2022/lib/toolbar/editor-toolbar-widget.js.map +0 -1
- package/esm2022/lib/toolbar/editor-toolbar.defs.js +0 -60
- package/esm2022/lib/toolbar/editor-toolbar.defs.js.map +0 -1
- package/esm2022/lib/toolbar/editor-toolbar.js +0 -826
- package/esm2022/lib/toolbar/editor-toolbar.js.map +0 -1
- package/esm2022/lib/toolbar/editor-undo-redo.js +0 -72
- package/esm2022/lib/toolbar/editor-undo-redo.js.map +0 -1
- package/esm2022/lib/toolbar/editor-zoom.js +0 -330
- package/esm2022/lib/toolbar/editor-zoom.js.map +0 -1
- package/esm2022/lib/upload/editor-image-upload-coordinator.js +0 -480
- package/esm2022/lib/upload/editor-image-upload-coordinator.js.map +0 -1
- package/esm2022/malva-ui-editor.js +0 -5
- package/esm2022/malva-ui-editor.js.map +0 -1
- package/index.d.ts +0 -35
- package/lib/ai/editor-ai-actions.d.ts +0 -27
- package/lib/ai/editor-ai-context.d.ts +0 -307
- package/lib/ai/editor-ai-menu.d.ts +0 -142
- package/lib/ai/editor-ai-review-bar.d.ts +0 -116
- package/lib/ai/editor-ai-stream.d.ts +0 -207
- package/lib/ai/editor-ai-suggestions.d.ts +0 -219
- package/lib/ai/editor-ai.tokens.d.ts +0 -10
- package/lib/ai/editor-ai.types.d.ts +0 -176
- package/lib/editor/editor.d.ts +0 -243
- package/lib/editor-extension-preflight.d.ts +0 -23
- package/lib/editor-serialization.d.ts +0 -74
- package/lib/editor-toolbar-context.d.ts +0 -116
- package/lib/editor.tokens.d.ts +0 -6
- package/lib/editor.types.d.ts +0 -194
- package/lib/extensions/editor-block-handle.d.ts +0 -59
- package/lib/extensions/editor-extensions.d.ts +0 -165
- package/lib/extensions/editor-markdown-compatibility.d.ts +0 -11
- package/lib/extensions/editor-upload-placeholder.d.ts +0 -75
- package/lib/status/editor-status.d.ts +0 -24
- package/lib/toolbar/editor-alignment.d.ts +0 -61
- package/lib/toolbar/editor-block-insert.d.ts +0 -26
- package/lib/toolbar/editor-color-control.d.ts +0 -32
- package/lib/toolbar/editor-command-button.d.ts +0 -29
- package/lib/toolbar/editor-heading.d.ts +0 -68
- package/lib/toolbar/editor-highlight.d.ts +0 -21
- package/lib/toolbar/editor-image-upload-dialog.d.ts +0 -96
- package/lib/toolbar/editor-image-upload.d.ts +0 -71
- package/lib/toolbar/editor-inline-marks.d.ts +0 -30
- package/lib/toolbar/editor-link.d.ts +0 -78
- package/lib/toolbar/editor-list.d.ts +0 -67
- package/lib/toolbar/editor-table.d.ts +0 -133
- package/lib/toolbar/editor-text-color.d.ts +0 -21
- package/lib/toolbar/editor-toolbar-widget.d.ts +0 -19
- package/lib/toolbar/editor-toolbar.d.ts +0 -157
- package/lib/toolbar/editor-toolbar.defs.d.ts +0 -35
- package/lib/toolbar/editor-undo-redo.d.ts +0 -26
- package/lib/toolbar/editor-zoom.d.ts +0 -108
- package/lib/upload/editor-image-upload-coordinator.d.ts +0 -55
- package/malva-ui-editor.d.ts +0 -5
|
@@ -1,265 +0,0 @@
|
|
|
1
|
-
import { ChangeDetectionStrategy, Component, computed, ElementRef, effect, inject, input, signal, viewChild, ViewEncapsulation, } from '@angular/core';
|
|
2
|
-
import { getMarkRange } from '@tiptap/core';
|
|
3
|
-
import { LucideLink } from '@lucide/angular';
|
|
4
|
-
import { MlvButton, MlvButtonIcon, MlvButtonToggle, } from '@malva-ui/core/button';
|
|
5
|
-
import { MlvInput } from '@malva-ui/core/input';
|
|
6
|
-
import { MlvPopup, MlvPopupContent, MlvPopupTrigger, } from '@malva-ui/core/popup';
|
|
7
|
-
import { MLV_EDITOR_I18N } from '@malva-ui/i18n';
|
|
8
|
-
import { MlvTooltip } from '@malva-ui/core/tooltip';
|
|
9
|
-
import { MLV_EDITOR_OVERLAY_REGISTRY, MLV_EDITOR_TOOLBAR_CONTEXT, MLV_EDITOR_TOOLBAR_REVISION, } from '../editor-toolbar-context';
|
|
10
|
-
import { MlvEditorToolbarWidget } from './editor-toolbar-widget';
|
|
11
|
-
import { MlvSwitch } from '@malva-ui/core/switch';
|
|
12
|
-
import * as i0 from "@angular/core";
|
|
13
|
-
/** Safe URL and label editor for the active Tiptap link mark. */
|
|
14
|
-
export class MlvEditorLink {
|
|
15
|
-
/**
|
|
16
|
-
* URL schemes accepted by Malva before the active Tiptap Link extension
|
|
17
|
-
* applies its own configured protocol policy.
|
|
18
|
-
*/
|
|
19
|
-
allowedProtocols = input([
|
|
20
|
-
'https',
|
|
21
|
-
'http',
|
|
22
|
-
'mailto',
|
|
23
|
-
'tel',
|
|
24
|
-
], /* @ts-ignore */
|
|
25
|
-
...(ngDevMode ? [{ debugName: "allowedProtocols" }] : /* istanbul ignore next */ []));
|
|
26
|
-
/** @protected Editor-scoped command and form state. */
|
|
27
|
-
_context = inject(MLV_EDITOR_TOOLBAR_CONTEXT);
|
|
28
|
-
/** @private Toolbar transaction/selection invalidation state. */
|
|
29
|
-
_revision = inject(MLV_EDITOR_TOOLBAR_REVISION, {
|
|
30
|
-
optional: true,
|
|
31
|
-
});
|
|
32
|
-
/** @private Detached panel ownership for composite focus. */
|
|
33
|
-
_overlays = inject(MLV_EDITOR_OVERLAY_REGISTRY);
|
|
34
|
-
/** @private Optional localized editor copy. */
|
|
35
|
-
_i18n = inject(MLV_EDITOR_I18N, { optional: true });
|
|
36
|
-
/** @protected Popup controller owned by the trigger. */
|
|
37
|
-
_popup = viewChild.required('_popup', /* @ts-ignore */
|
|
38
|
-
...(ngDevMode ? [{ debugName: "_popup" }] : /* istanbul ignore next */ []));
|
|
39
|
-
/** @protected Connected trigger controller. */
|
|
40
|
-
_trigger = viewChild.required('_trigger', /* @ts-ignore */
|
|
41
|
-
...(ngDevMode ? [{ debugName: "_trigger" }] : /* istanbul ignore next */ []));
|
|
42
|
-
/** @protected Native trigger restored after popup teardown. */
|
|
43
|
-
_triggerElement = viewChild.required('_triggerElement', {
|
|
44
|
-
read: ElementRef,
|
|
45
|
-
});
|
|
46
|
-
/** @protected URL field focused on open. */
|
|
47
|
-
_urlInput = viewChild.required('_urlInput', /* @ts-ignore */
|
|
48
|
-
...(ngDevMode ? [{ debugName: "_urlInput" }] : /* istanbul ignore next */ []));
|
|
49
|
-
/** @private Detached panel queried through Angular rather than selectors. */
|
|
50
|
-
_panel = viewChild('_panel', /* @ts-ignore */
|
|
51
|
-
...(ngDevMode ? [{ debugName: "_panel" }] : /* istanbul ignore next */ []));
|
|
52
|
-
/** @protected URL draft retained when validation fails. */
|
|
53
|
-
_urlDraft = signal('', /* @ts-ignore */
|
|
54
|
-
...(ngDevMode ? [{ debugName: "_urlDraft" }] : /* istanbul ignore next */ []));
|
|
55
|
-
/** @protected Linked/selected text draft. */
|
|
56
|
-
_textDraft = signal('', /* @ts-ignore */
|
|
57
|
-
...(ngDevMode ? [{ debugName: "_textDraft" }] : /* istanbul ignore next */ []));
|
|
58
|
-
/** @protected Whether the link should open in a new browsing context. */
|
|
59
|
-
_newTab = signal(false, /* @ts-ignore */
|
|
60
|
-
...(ngDevMode ? [{ debugName: "_newTab" }] : /* istanbul ignore next */ []));
|
|
61
|
-
/** @protected Whether the current URL draft failed strict policy. */
|
|
62
|
-
_invalid = signal(false, /* @ts-ignore */
|
|
63
|
-
...(ngDevMode ? [{ debugName: "_invalid" }] : /* istanbul ignore next */ []));
|
|
64
|
-
/** @protected Whether the currently edited range already carries a link. */
|
|
65
|
-
_canRemove = signal(false, /* @ts-ignore */
|
|
66
|
-
...(ngDevMode ? [{ debugName: "_canRemove" }] : /* istanbul ignore next */ []));
|
|
67
|
-
/** @private Whole mark or selected range retained while focus is detached. */
|
|
68
|
-
_selection = null;
|
|
69
|
-
/** @protected Reactive localized copy for trigger, fields, and actions. */
|
|
70
|
-
_copy = computed(() => {
|
|
71
|
-
const copy = this._i18n?.();
|
|
72
|
-
return {
|
|
73
|
-
link: copy?.link ?? 'Link',
|
|
74
|
-
linkUrl: copy?.linkUrl ?? 'Link URL',
|
|
75
|
-
linkText: copy?.linkText ?? 'Link text',
|
|
76
|
-
invalidLink: copy?.invalidLink ?? 'Enter a valid link URL.',
|
|
77
|
-
openInNewTab: copy?.openInNewTab ?? 'Open in new tab',
|
|
78
|
-
applyLink: copy?.applyLink ?? 'Apply link',
|
|
79
|
-
removeLink: copy?.removeLink ?? 'Remove link',
|
|
80
|
-
};
|
|
81
|
-
}, /* @ts-ignore */
|
|
82
|
-
...(ngDevMode ? [{ debugName: "_copy" }] : /* istanbul ignore next */ []));
|
|
83
|
-
/** @protected Exact command presence without dispatching a transaction. */
|
|
84
|
-
_supported = computed(() => {
|
|
85
|
-
this._revision?.();
|
|
86
|
-
const commands = this._context.editor()?.commands;
|
|
87
|
-
return (typeof commands?.['setLink'] === 'function' &&
|
|
88
|
-
typeof commands['unsetLink'] === 'function');
|
|
89
|
-
}, /* @ts-ignore */
|
|
90
|
-
...(ngDevMode ? [{ debugName: "_supported" }] : /* istanbul ignore next */ []));
|
|
91
|
-
/** @protected Link mark state at the retained editor selection. */
|
|
92
|
-
_active = computed(() => {
|
|
93
|
-
this._revision?.();
|
|
94
|
-
return this._context.isActive('link');
|
|
95
|
-
}, /* @ts-ignore */
|
|
96
|
-
...(ngDevMode ? [{ debugName: "_active" }] : /* istanbul ignore next */ []));
|
|
97
|
-
/** @protected Whether readonly/disabled state blocks the complete popup. */
|
|
98
|
-
_disabled = computed(() => this._context.disabled() || this._context.readonly(), /* @ts-ignore */
|
|
99
|
-
...(ngDevMode ? [{ debugName: "_disabled" }] : /* istanbul ignore next */ []));
|
|
100
|
-
constructor() {
|
|
101
|
-
effect(() => {
|
|
102
|
-
if (this._disabled() && this._popup().opened()) {
|
|
103
|
-
this._popup().opened.set(false);
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
effect((onCleanup) => {
|
|
107
|
-
const panel = this._panel()?.nativeElement;
|
|
108
|
-
if (!panel)
|
|
109
|
-
return;
|
|
110
|
-
const unregister = this._overlays.register(panel, () => this._popup().opened.set(false));
|
|
111
|
-
onCleanup(unregister);
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
/** @protected Preloads the active whole-link range or current selection. */
|
|
115
|
-
_onOpened() {
|
|
116
|
-
const editor = this._context.editor();
|
|
117
|
-
if (!editor || this._disabled()) {
|
|
118
|
-
this._popup().opened.set(false);
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
const selection = editor.state.selection;
|
|
122
|
-
const linkType = editor.schema.marks['link'];
|
|
123
|
-
const markRange = linkType
|
|
124
|
-
? getMarkRange(selection.$from, linkType)
|
|
125
|
-
: undefined;
|
|
126
|
-
const linked = Boolean(markRange && editor.isActive('link'));
|
|
127
|
-
const from = linked && markRange ? markRange.from : selection.from;
|
|
128
|
-
const to = linked && markRange ? markRange.to : selection.to;
|
|
129
|
-
const text = editor.state.doc.textBetween(from, to, ' ');
|
|
130
|
-
const attributes = linked ? editor.getAttributes('link') : {};
|
|
131
|
-
this._selection = { from, to, text, linked };
|
|
132
|
-
this._canRemove.set(linked);
|
|
133
|
-
this._urlDraft.set(typeof attributes['href'] === 'string' ? attributes['href'] : '');
|
|
134
|
-
this._textDraft.set(text);
|
|
135
|
-
this._newTab.set(attributes['target'] === '_blank');
|
|
136
|
-
this._invalid.set(false);
|
|
137
|
-
queueMicrotask(() => {
|
|
138
|
-
if (!this._popup().opened())
|
|
139
|
-
return;
|
|
140
|
-
this._urlInput().focus();
|
|
141
|
-
this._urlInput().select();
|
|
142
|
-
});
|
|
143
|
-
}
|
|
144
|
-
/** @protected Restores the connected toolbar trigger after final teardown. */
|
|
145
|
-
_onClosed() {
|
|
146
|
-
if (!this._disabled() && this._triggerElement().nativeElement.isConnected) {
|
|
147
|
-
this._triggerElement().nativeElement.focus();
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
/** @protected Clears stale validation as the user edits without closing. */
|
|
151
|
-
_onUrlChange(value) {
|
|
152
|
-
this._urlDraft.set(value);
|
|
153
|
-
this._invalid.set(false);
|
|
154
|
-
}
|
|
155
|
-
/** @protected Applies an inserted or updated link after both policy checks. */
|
|
156
|
-
_apply() {
|
|
157
|
-
const selection = this._selection;
|
|
158
|
-
const href = this._validateUrl(this._urlDraft());
|
|
159
|
-
if (!selection || !href) {
|
|
160
|
-
this._invalid.set(true);
|
|
161
|
-
return;
|
|
162
|
-
}
|
|
163
|
-
const text = this._textDraft() || href;
|
|
164
|
-
const applied = this._context.run((editor) => this._applyToEditor(editor, selection, href, text));
|
|
165
|
-
if (applied) {
|
|
166
|
-
this._trigger().close();
|
|
167
|
-
}
|
|
168
|
-
else {
|
|
169
|
-
this._invalid.set(true);
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
/** @protected Removes only the link mark while retaining its text. */
|
|
173
|
-
_remove() {
|
|
174
|
-
const selection = this._selection;
|
|
175
|
-
if (!selection)
|
|
176
|
-
return;
|
|
177
|
-
const removed = this._context.run((editor) => editor
|
|
178
|
-
.chain()
|
|
179
|
-
.setTextSelection({ from: selection.from, to: selection.to })
|
|
180
|
-
.unsetLink()
|
|
181
|
-
.run());
|
|
182
|
-
if (removed)
|
|
183
|
-
this._trigger().close();
|
|
184
|
-
}
|
|
185
|
-
/** @private Preflights Link policy before replacing text and applying attributes. */
|
|
186
|
-
_applyToEditor(editor, selection, href, text) {
|
|
187
|
-
const newTab = this._newTab();
|
|
188
|
-
const attributes = {
|
|
189
|
-
href,
|
|
190
|
-
target: newTab ? '_blank' : null,
|
|
191
|
-
rel: newTab ? 'noopener noreferrer' : null,
|
|
192
|
-
};
|
|
193
|
-
const canApplyLink = editor
|
|
194
|
-
.can()
|
|
195
|
-
.chain()
|
|
196
|
-
.setTextSelection({ from: selection.from, to: selection.to })
|
|
197
|
-
.setLink(attributes)
|
|
198
|
-
.run();
|
|
199
|
-
if (!canApplyLink)
|
|
200
|
-
return false;
|
|
201
|
-
let range = { from: selection.from, to: selection.to };
|
|
202
|
-
let chain = editor.chain().setTextSelection(range);
|
|
203
|
-
if (text !== selection.text) {
|
|
204
|
-
chain = chain.insertContentAt(range, { type: 'text', text });
|
|
205
|
-
range = { from: range.from, to: range.from + text.length };
|
|
206
|
-
chain = chain.setTextSelection(range);
|
|
207
|
-
}
|
|
208
|
-
return chain.setLink(attributes).run();
|
|
209
|
-
}
|
|
210
|
-
/** @private Strict scheme allowlist validation before Tiptap's own policy. */
|
|
211
|
-
_validateUrl(draft) {
|
|
212
|
-
const href = draft.trim();
|
|
213
|
-
if (!href || /^(?:\/\/|\/|\?|#)/.test(href))
|
|
214
|
-
return null;
|
|
215
|
-
const match = /^([a-z][a-z0-9+.-]*):(.*)$/i.exec(href);
|
|
216
|
-
if (!match)
|
|
217
|
-
return null;
|
|
218
|
-
const scheme = match[1]?.toLowerCase();
|
|
219
|
-
const schemeValue = match[2]?.trim() ?? '';
|
|
220
|
-
if (!scheme || !schemeValue || !this._normalizedProtocols().has(scheme)) {
|
|
221
|
-
return null;
|
|
222
|
-
}
|
|
223
|
-
if (scheme === 'http' || scheme === 'https') {
|
|
224
|
-
try {
|
|
225
|
-
const parsed = new URL(href);
|
|
226
|
-
if (parsed.protocol !== `${scheme}:` || !parsed.hostname)
|
|
227
|
-
return null;
|
|
228
|
-
}
|
|
229
|
-
catch {
|
|
230
|
-
return null;
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
return href;
|
|
234
|
-
}
|
|
235
|
-
/** @private Trims, lowercases, and removes trailing colons from the API input. */
|
|
236
|
-
_normalizedProtocols() {
|
|
237
|
-
return new Set(this.allowedProtocols()
|
|
238
|
-
.map((protocol) => protocol.trim().toLowerCase().replace(/:+$/, ''))
|
|
239
|
-
.filter(Boolean));
|
|
240
|
-
}
|
|
241
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MlvEditorLink, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
242
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: MlvEditorLink, isStandalone: true, selector: "mlv-editor-link", inputs: { allowedProtocols: { classPropertyName: "allowedProtocols", publicName: "allowedProtocols", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "hidden": "!_supported()" }, classAttribute: "mlv-editor-link" }, viewQueries: [{ propertyName: "_popup", first: true, predicate: ["_popup"], descendants: true, isSignal: true }, { propertyName: "_trigger", first: true, predicate: ["_trigger"], descendants: true, isSignal: true }, { propertyName: "_triggerElement", first: true, predicate: ["_triggerElement"], descendants: true, read: ElementRef, isSignal: true }, { propertyName: "_urlInput", first: true, predicate: ["_urlInput"], descendants: true, isSignal: true }, { propertyName: "_panel", first: true, predicate: ["_panel"], descendants: true, isSignal: true }], ngImport: i0, template: "<button\n #_trigger=\"mlvPopupTrigger\"\n #_triggerElement\n mlvButton\n mlvEditorToolbarWidget\n type=\"button\"\n shape=\"square\"\n mlvDensity=\"tight\"\n variant=\"transparent\"\n [disabled]=\"_disabled()\"\n [mlvPopupTrigger]=\"_popup\"\n [ariaHasPopup]=\"'dialog'\"\n [attr.aria-label]=\"_copy().link\"\n [attr.aria-pressed]=\"_active()\"\n [mlvTooltip]=\"_copy().link\"\n>\n <svg mlvButtonIcon lucideLink aria-hidden=\"true\" />\n</button>\n\n<mlv-popup\n #_popup\n panelRole=\"dialog\"\n [modal]=\"true\"\n [ariaLabel]=\"_copy().link\"\n (afterOpened)=\"_onOpened()\"\n (afterClosed)=\"_onClosed()\"\n>\n <ng-template mlvPopupContent>\n <div #_panel class=\"mlv-editor-link__panel\">\n <mlv-input\n #_urlInput\n type=\"url\"\n [label]=\"_copy().linkUrl\"\n [value]=\"_urlDraft()\"\n [disabled]=\"_disabled()\"\n [state]=\"_invalid() ? 'error' : 'default'\"\n [message]=\"_invalid() ? _copy().invalidLink : ''\"\n (valueChange)=\"_onUrlChange($event)\"\n (keydown.enter)=\"_apply()\"\n />\n <mlv-input\n [label]=\"_copy().linkText\"\n [value]=\"_textDraft()\"\n [disabled]=\"_disabled()\"\n (valueChange)=\"_textDraft.set($event)\"\n (keydown.enter)=\"_apply()\"\n />\n <mlv-switch [label]=\"_copy().openInNewTab\" [(checked)]=\"_newTab\"\n >{{_copy().openInNewTab}}</mlv-switch\n >\n <div class=\"mlv-editor-link__actions\">\n <button\n mlvButton\n type=\"button\"\n variant=\"primary\"\n [disabled]=\"_disabled()\"\n (click)=\"_apply()\"\n >\n {{ _copy().applyLink }}\n </button>\n @if (_canRemove()) {\n <button\n mlvButton\n type=\"button\"\n variant=\"secondary\"\n [disabled]=\"_disabled()\"\n (click)=\"_remove()\"\n >\n {{ _copy().removeLink }}\n </button>\n }\n </div>\n </div>\n </ng-template>\n</mlv-popup>\n", styles: [".mlv-editor-link{box-sizing:border-box;padding:0;margin:0;font-family:var(--mlv-typography-family-text);font-size:var(--mlv-font-size-m)}.mlv-editor-link *{box-sizing:border-box}.mlv-editor-link{display:inline-flex}.mlv-editor-link__panel{display:grid;width:min(22rem,100vw - 3.5rem);gap:var(--mlv-spacing-1-5);padding:var(--mlv-spacing-2)}.mlv-editor-link__actions{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:var(--mlv-spacing-3)}\n"], dependencies: [{ kind: "component", type: MlvButton, selector: "button[mlvButton], a[mlvButton]", inputs: ["variant", "shape", "disabled", "loading"] }, { kind: "directive", type: MlvButtonIcon, selector: "[mlvButtonIcon]" }, { kind: "directive", type: MlvTooltip, selector: "[mlvTooltip]", inputs: ["mlvTooltip", "tooltipPlacement", "tooltipTone", "tooltipDelay", "tooltipDisabled", "tooltipArrow"] }, { kind: "component", type: LucideLink, selector: "svg[lucideLink]" }, { kind: "directive", type: MlvEditorToolbarWidget, selector: "[mlvEditorToolbarWidget]" }, { kind: "component", type: MlvInput, selector: "mlv-input", inputs: ["type", "placeholder", "autocomplete", "inputMode", "maxLength", "minLength", "pattern", "name", "autofocus", "min", "max", "step", "bare", "projectControl", "role", "ariaExpanded", "ariaHasPopup", "ariaAutocomplete", "ariaControls", "ariaActiveDescendant", "ariaDescribedBy", "value"], outputs: ["valueChange", "inputFocus", "inputBlur"] }, { kind: "component", type: MlvPopup, selector: "mlv-popup", inputs: ["position", "positions", "width", "height", "minWidth", "minHeight", "maxWidth", "maxHeight", "hasArrow", "hasShadow", "class", "mlvDensity", "flexibleDimensions", "scrollStrategy", "hasBackdrop", "restrictPosition", "panelRole", "modal", "ariaLabel", "dismissExcludeElements", "mobileMode", "mobileBreakpoint", "mobileTitle", "mobileCloseLabel", "opened"], outputs: ["openedChange", "afterOpened", "afterClosed"] }, { kind: "directive", type: MlvPopupContent, selector: "[mlvPopupContent]" }, { kind: "directive", type: MlvPopupTrigger, selector: "[mlvPopupTrigger]", inputs: ["mlvPopupTrigger", "triggerOn", "ariaHasPopup"], exportAs: ["mlvPopupTrigger"] }, { kind: "component", type: MlvSwitch, selector: "mlv-switch", inputs: ["ariaLabelledBy", "checked"], outputs: ["checkedChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
243
|
-
}
|
|
244
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MlvEditorLink, decorators: [{
|
|
245
|
-
type: Component,
|
|
246
|
-
args: [{ selector: 'mlv-editor-link', imports: [
|
|
247
|
-
MlvButton,
|
|
248
|
-
MlvButtonIcon,
|
|
249
|
-
MlvButtonToggle,
|
|
250
|
-
MlvTooltip,
|
|
251
|
-
LucideLink,
|
|
252
|
-
MlvEditorToolbarWidget,
|
|
253
|
-
MlvInput,
|
|
254
|
-
MlvPopup,
|
|
255
|
-
MlvPopupContent,
|
|
256
|
-
MlvPopupTrigger,
|
|
257
|
-
MlvSwitch,
|
|
258
|
-
], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
259
|
-
class: 'mlv-editor-link',
|
|
260
|
-
'[hidden]': '!_supported()',
|
|
261
|
-
}, template: "<button\n #_trigger=\"mlvPopupTrigger\"\n #_triggerElement\n mlvButton\n mlvEditorToolbarWidget\n type=\"button\"\n shape=\"square\"\n mlvDensity=\"tight\"\n variant=\"transparent\"\n [disabled]=\"_disabled()\"\n [mlvPopupTrigger]=\"_popup\"\n [ariaHasPopup]=\"'dialog'\"\n [attr.aria-label]=\"_copy().link\"\n [attr.aria-pressed]=\"_active()\"\n [mlvTooltip]=\"_copy().link\"\n>\n <svg mlvButtonIcon lucideLink aria-hidden=\"true\" />\n</button>\n\n<mlv-popup\n #_popup\n panelRole=\"dialog\"\n [modal]=\"true\"\n [ariaLabel]=\"_copy().link\"\n (afterOpened)=\"_onOpened()\"\n (afterClosed)=\"_onClosed()\"\n>\n <ng-template mlvPopupContent>\n <div #_panel class=\"mlv-editor-link__panel\">\n <mlv-input\n #_urlInput\n type=\"url\"\n [label]=\"_copy().linkUrl\"\n [value]=\"_urlDraft()\"\n [disabled]=\"_disabled()\"\n [state]=\"_invalid() ? 'error' : 'default'\"\n [message]=\"_invalid() ? _copy().invalidLink : ''\"\n (valueChange)=\"_onUrlChange($event)\"\n (keydown.enter)=\"_apply()\"\n />\n <mlv-input\n [label]=\"_copy().linkText\"\n [value]=\"_textDraft()\"\n [disabled]=\"_disabled()\"\n (valueChange)=\"_textDraft.set($event)\"\n (keydown.enter)=\"_apply()\"\n />\n <mlv-switch [label]=\"_copy().openInNewTab\" [(checked)]=\"_newTab\"\n >{{_copy().openInNewTab}}</mlv-switch\n >\n <div class=\"mlv-editor-link__actions\">\n <button\n mlvButton\n type=\"button\"\n variant=\"primary\"\n [disabled]=\"_disabled()\"\n (click)=\"_apply()\"\n >\n {{ _copy().applyLink }}\n </button>\n @if (_canRemove()) {\n <button\n mlvButton\n type=\"button\"\n variant=\"secondary\"\n [disabled]=\"_disabled()\"\n (click)=\"_remove()\"\n >\n {{ _copy().removeLink }}\n </button>\n }\n </div>\n </div>\n </ng-template>\n</mlv-popup>\n", styles: [".mlv-editor-link{box-sizing:border-box;padding:0;margin:0;font-family:var(--mlv-typography-family-text);font-size:var(--mlv-font-size-m)}.mlv-editor-link *{box-sizing:border-box}.mlv-editor-link{display:inline-flex}.mlv-editor-link__panel{display:grid;width:min(22rem,100vw - 3.5rem);gap:var(--mlv-spacing-1-5);padding:var(--mlv-spacing-2)}.mlv-editor-link__actions{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:var(--mlv-spacing-3)}\n"] }]
|
|
262
|
-
}], ctorParameters: () => [], propDecorators: { allowedProtocols: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowedProtocols", required: false }] }], _popup: [{ type: i0.ViewChild, args: ['_popup', { isSignal: true }] }], _trigger: [{ type: i0.ViewChild, args: ['_trigger', { isSignal: true }] }], _triggerElement: [{ type: i0.ViewChild, args: ['_triggerElement', { ...{
|
|
263
|
-
read: ElementRef,
|
|
264
|
-
}, isSignal: true }] }], _urlInput: [{ type: i0.ViewChild, args: ['_urlInput', { isSignal: true }] }], _panel: [{ type: i0.ViewChild, args: ['_panel', { isSignal: true }] }] } });
|
|
265
|
-
//# sourceMappingURL=editor-link.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"editor-link.js","sourceRoot":"","sources":["../../../../../../libs/editor/src/lib/toolbar/editor-link.ts","../../../../../../libs/editor/src/lib/toolbar/editor-link.html"],"names":[],"mappings":"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","sourcesContent":["import type { Signal } from '@angular/core';\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n ElementRef,\n effect,\n inject,\n input,\n signal,\n viewChild,\n ViewEncapsulation,\n} from '@angular/core';\nimport type { Editor } from '@tiptap/core';\nimport { getMarkRange } from '@tiptap/core';\nimport { LucideLink } from '@lucide/angular';\nimport {\n MlvButton,\n MlvButtonIcon,\n MlvButtonToggle,\n} from '@malva-ui/core/button';\nimport { MlvInput } from '@malva-ui/core/input';\nimport {\n MlvPopup,\n MlvPopupContent,\n MlvPopupTrigger,\n} from '@malva-ui/core/popup';\nimport { MLV_EDITOR_I18N } from '@malva-ui/i18n';\nimport { MlvTooltip } from '@malva-ui/core/tooltip';\nimport {\n MLV_EDITOR_OVERLAY_REGISTRY,\n MLV_EDITOR_TOOLBAR_CONTEXT,\n MLV_EDITOR_TOOLBAR_REVISION,\n} from '../editor-toolbar-context';\nimport { MlvEditorToolbarWidget } from './editor-toolbar-widget';\nimport { MlvSwitch } from '@malva-ui/core/switch';\n\ninterface EditorLinkSelection {\n readonly from: number;\n readonly to: number;\n readonly text: string;\n readonly linked: boolean;\n}\n\n/** Safe URL and label editor for the active Tiptap link mark. */\n@Component({\n selector: 'mlv-editor-link',\n imports: [\n MlvButton,\n MlvButtonIcon,\n MlvButtonToggle,\n MlvTooltip,\n LucideLink,\n MlvEditorToolbarWidget,\n MlvInput,\n MlvPopup,\n MlvPopupContent,\n MlvPopupTrigger,\n MlvSwitch,\n ],\n templateUrl: './editor-link.html',\n styleUrl: './editor-link.scss',\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n class: 'mlv-editor-link',\n '[hidden]': '!_supported()',\n },\n})\nexport class MlvEditorLink {\n /**\n * URL schemes accepted by Malva before the active Tiptap Link extension\n * applies its own configured protocol policy.\n */\n readonly allowedProtocols = input<readonly string[]>([\n 'https',\n 'http',\n 'mailto',\n 'tel',\n ]);\n\n /** @protected Editor-scoped command and form state. */\n protected readonly _context = inject(MLV_EDITOR_TOOLBAR_CONTEXT);\n\n /** @private Toolbar transaction/selection invalidation state. */\n private readonly _revision = inject(MLV_EDITOR_TOOLBAR_REVISION, {\n optional: true,\n });\n\n /** @private Detached panel ownership for composite focus. */\n private readonly _overlays = inject(MLV_EDITOR_OVERLAY_REGISTRY);\n\n /** @private Optional localized editor copy. */\n private readonly _i18n = inject(MLV_EDITOR_I18N, { optional: true });\n\n /** @protected Popup controller owned by the trigger. */\n protected readonly _popup = viewChild.required<MlvPopup>('_popup');\n\n /** @protected Connected trigger controller. */\n protected readonly _trigger = viewChild.required<MlvPopupTrigger>('_trigger');\n\n /** @protected Native trigger restored after popup teardown. */\n protected readonly _triggerElement = viewChild.required('_triggerElement', {\n read: ElementRef,\n }) as Signal<ElementRef<HTMLButtonElement>>;\n\n /** @protected URL field focused on open. */\n protected readonly _urlInput = viewChild.required<MlvInput>('_urlInput');\n\n /** @private Detached panel queried through Angular rather than selectors. */\n private readonly _panel = viewChild<ElementRef<HTMLElement>>('_panel');\n\n /** @protected URL draft retained when validation fails. */\n protected readonly _urlDraft = signal('');\n\n /** @protected Linked/selected text draft. */\n protected readonly _textDraft = signal('');\n\n /** @protected Whether the link should open in a new browsing context. */\n protected readonly _newTab = signal(false);\n\n /** @protected Whether the current URL draft failed strict policy. */\n protected readonly _invalid = signal(false);\n\n /** @protected Whether the currently edited range already carries a link. */\n protected readonly _canRemove = signal(false);\n\n /** @private Whole mark or selected range retained while focus is detached. */\n private _selection: EditorLinkSelection | null = null;\n\n /** @protected Reactive localized copy for trigger, fields, and actions. */\n protected readonly _copy = computed(() => {\n const copy = this._i18n?.();\n return {\n link: copy?.link ?? 'Link',\n linkUrl: copy?.linkUrl ?? 'Link URL',\n linkText: copy?.linkText ?? 'Link text',\n invalidLink: copy?.invalidLink ?? 'Enter a valid link URL.',\n openInNewTab: copy?.openInNewTab ?? 'Open in new tab',\n applyLink: copy?.applyLink ?? 'Apply link',\n removeLink: copy?.removeLink ?? 'Remove link',\n };\n });\n\n /** @protected Exact command presence without dispatching a transaction. */\n protected readonly _supported = computed(() => {\n this._revision?.();\n const commands = this._context.editor()?.commands as\n | Record<string, unknown>\n | undefined;\n return (\n typeof commands?.['setLink'] === 'function' &&\n typeof commands['unsetLink'] === 'function'\n );\n });\n\n /** @protected Link mark state at the retained editor selection. */\n protected readonly _active = computed(() => {\n this._revision?.();\n return this._context.isActive('link');\n });\n\n /** @protected Whether readonly/disabled state blocks the complete popup. */\n protected readonly _disabled = computed(\n () => this._context.disabled() || this._context.readonly(),\n );\n\n constructor() {\n effect(() => {\n if (this._disabled() && this._popup().opened()) {\n this._popup().opened.set(false);\n }\n });\n\n effect((onCleanup) => {\n const panel = this._panel()?.nativeElement;\n if (!panel) return;\n const unregister = this._overlays.register(panel, () =>\n this._popup().opened.set(false),\n );\n onCleanup(unregister);\n });\n }\n\n /** @protected Preloads the active whole-link range or current selection. */\n protected _onOpened(): void {\n const editor = this._context.editor();\n if (!editor || this._disabled()) {\n this._popup().opened.set(false);\n return;\n }\n const selection = editor.state.selection;\n const linkType = editor.schema.marks['link'];\n const markRange = linkType\n ? getMarkRange(selection.$from, linkType)\n : undefined;\n const linked = Boolean(markRange && editor.isActive('link'));\n const from = linked && markRange ? markRange.from : selection.from;\n const to = linked && markRange ? markRange.to : selection.to;\n const text = editor.state.doc.textBetween(from, to, ' ');\n const attributes = linked ? editor.getAttributes('link') : {};\n this._selection = { from, to, text, linked };\n this._canRemove.set(linked);\n this._urlDraft.set(\n typeof attributes['href'] === 'string' ? attributes['href'] : '',\n );\n this._textDraft.set(text);\n this._newTab.set(attributes['target'] === '_blank');\n this._invalid.set(false);\n queueMicrotask(() => {\n if (!this._popup().opened()) return;\n this._urlInput().focus();\n this._urlInput().select();\n });\n }\n\n /** @protected Restores the connected toolbar trigger after final teardown. */\n protected _onClosed(): void {\n if (!this._disabled() && this._triggerElement().nativeElement.isConnected) {\n this._triggerElement().nativeElement.focus();\n }\n }\n\n /** @protected Clears stale validation as the user edits without closing. */\n protected _onUrlChange(value: string): void {\n this._urlDraft.set(value);\n this._invalid.set(false);\n }\n\n /** @protected Applies an inserted or updated link after both policy checks. */\n protected _apply(): void {\n const selection = this._selection;\n const href = this._validateUrl(this._urlDraft());\n if (!selection || !href) {\n this._invalid.set(true);\n return;\n }\n const text = this._textDraft() || href;\n const applied = this._context.run((editor) =>\n this._applyToEditor(editor, selection, href, text),\n );\n if (applied) {\n this._trigger().close();\n } else {\n this._invalid.set(true);\n }\n }\n\n /** @protected Removes only the link mark while retaining its text. */\n protected _remove(): void {\n const selection = this._selection;\n if (!selection) return;\n const removed = this._context.run((editor) =>\n editor\n .chain()\n .setTextSelection({ from: selection.from, to: selection.to })\n .unsetLink()\n .run(),\n );\n if (removed) this._trigger().close();\n }\n\n /** @private Preflights Link policy before replacing text and applying attributes. */\n private _applyToEditor(\n editor: Editor,\n selection: EditorLinkSelection,\n href: string,\n text: string,\n ): boolean {\n const newTab = this._newTab();\n const attributes = {\n href,\n target: newTab ? '_blank' : null,\n rel: newTab ? 'noopener noreferrer' : null,\n };\n const canApplyLink = editor\n .can()\n .chain()\n .setTextSelection({ from: selection.from, to: selection.to })\n .setLink(attributes)\n .run();\n if (!canApplyLink) return false;\n\n let range = { from: selection.from, to: selection.to };\n let chain = editor.chain().setTextSelection(range);\n if (text !== selection.text) {\n chain = chain.insertContentAt(range, { type: 'text', text });\n range = { from: range.from, to: range.from + text.length };\n chain = chain.setTextSelection(range);\n }\n return chain.setLink(attributes).run();\n }\n\n /** @private Strict scheme allowlist validation before Tiptap's own policy. */\n private _validateUrl(draft: string): string | null {\n const href = draft.trim();\n if (!href || /^(?:\\/\\/|\\/|\\?|#)/.test(href)) return null;\n const match = /^([a-z][a-z0-9+.-]*):(.*)$/i.exec(href);\n if (!match) return null;\n const scheme = match[1]?.toLowerCase();\n const schemeValue = match[2]?.trim() ?? '';\n if (!scheme || !schemeValue || !this._normalizedProtocols().has(scheme)) {\n return null;\n }\n if (scheme === 'http' || scheme === 'https') {\n try {\n const parsed = new URL(href);\n if (parsed.protocol !== `${scheme}:` || !parsed.hostname) return null;\n } catch {\n return null;\n }\n }\n return href;\n }\n\n /** @private Trims, lowercases, and removes trailing colons from the API input. */\n private _normalizedProtocols(): ReadonlySet<string> {\n return new Set(\n this.allowedProtocols()\n .map((protocol) => protocol.trim().toLowerCase().replace(/:+$/, ''))\n .filter(Boolean),\n );\n }\n}\n","<button\n #_trigger=\"mlvPopupTrigger\"\n #_triggerElement\n mlvButton\n mlvEditorToolbarWidget\n type=\"button\"\n shape=\"square\"\n mlvDensity=\"tight\"\n variant=\"transparent\"\n [disabled]=\"_disabled()\"\n [mlvPopupTrigger]=\"_popup\"\n [ariaHasPopup]=\"'dialog'\"\n [attr.aria-label]=\"_copy().link\"\n [attr.aria-pressed]=\"_active()\"\n [mlvTooltip]=\"_copy().link\"\n>\n <svg mlvButtonIcon lucideLink aria-hidden=\"true\" />\n</button>\n\n<mlv-popup\n #_popup\n panelRole=\"dialog\"\n [modal]=\"true\"\n [ariaLabel]=\"_copy().link\"\n (afterOpened)=\"_onOpened()\"\n (afterClosed)=\"_onClosed()\"\n>\n <ng-template mlvPopupContent>\n <div #_panel class=\"mlv-editor-link__panel\">\n <mlv-input\n #_urlInput\n type=\"url\"\n [label]=\"_copy().linkUrl\"\n [value]=\"_urlDraft()\"\n [disabled]=\"_disabled()\"\n [state]=\"_invalid() ? 'error' : 'default'\"\n [message]=\"_invalid() ? _copy().invalidLink : ''\"\n (valueChange)=\"_onUrlChange($event)\"\n (keydown.enter)=\"_apply()\"\n />\n <mlv-input\n [label]=\"_copy().linkText\"\n [value]=\"_textDraft()\"\n [disabled]=\"_disabled()\"\n (valueChange)=\"_textDraft.set($event)\"\n (keydown.enter)=\"_apply()\"\n />\n <mlv-switch [label]=\"_copy().openInNewTab\" [(checked)]=\"_newTab\"\n >{{_copy().openInNewTab}}</mlv-switch\n >\n <div class=\"mlv-editor-link__actions\">\n <button\n mlvButton\n type=\"button\"\n variant=\"primary\"\n [disabled]=\"_disabled()\"\n (click)=\"_apply()\"\n >\n {{ _copy().applyLink }}\n </button>\n @if (_canRemove()) {\n <button\n mlvButton\n type=\"button\"\n variant=\"secondary\"\n [disabled]=\"_disabled()\"\n (click)=\"_remove()\"\n >\n {{ _copy().removeLink }}\n </button>\n }\n </div>\n </div>\n </ng-template>\n</mlv-popup>\n"]}
|
|
@@ -1,249 +0,0 @@
|
|
|
1
|
-
import { DOCUMENT } from '@angular/common';
|
|
2
|
-
import { ChangeDetectionStrategy, Component, DestroyRef, computed, inject, ViewEncapsulation, viewChild, } from '@angular/core';
|
|
3
|
-
import { LucideList } from '@lucide/angular';
|
|
4
|
-
import { MlvButton, MlvButtonIcon } from '@malva-ui/core/button';
|
|
5
|
-
import { MlvListItem } from '@malva-ui/core/list';
|
|
6
|
-
import { MlvMenu, MlvMenuItem, MlvMenuTrigger } from '@malva-ui/core/menu';
|
|
7
|
-
import { MlvTooltip } from '@malva-ui/core/tooltip';
|
|
8
|
-
import { MLV_EDITOR_I18N } from '@malva-ui/i18n';
|
|
9
|
-
import { MLV_EDITOR_OVERLAY_REGISTRY, MLV_EDITOR_TOOLBAR_CONTEXT, MLV_EDITOR_TOOLBAR_REVISION, } from '../editor-toolbar-context';
|
|
10
|
-
import { MlvEditorToolbarWidget } from './editor-toolbar-widget';
|
|
11
|
-
import * as i0 from "@angular/core";
|
|
12
|
-
/** Bullet, ordered, and task-list toolbar commands in a compact menu. */
|
|
13
|
-
export class MlvEditorList {
|
|
14
|
-
/** @protected Editor command state. */
|
|
15
|
-
_context = inject(MLV_EDITOR_TOOLBAR_CONTEXT);
|
|
16
|
-
/** @private Per-editor state invalidation signal. */
|
|
17
|
-
_revision = inject(MLV_EDITOR_TOOLBAR_REVISION);
|
|
18
|
-
/** @private The editor-owned overlay registry. */
|
|
19
|
-
_overlays = inject(MLV_EDITOR_OVERLAY_REGISTRY);
|
|
20
|
-
/** @private Document used to resolve the public menu panel id. */
|
|
21
|
-
_document = inject(DOCUMENT);
|
|
22
|
-
/** @private Removes a pending or active overlay registration. */
|
|
23
|
-
_destroyRef = inject(DestroyRef);
|
|
24
|
-
/** @private Optional localized editor copy. */
|
|
25
|
-
_i18n = inject(MLV_EDITOR_I18N, { optional: true });
|
|
26
|
-
/** @protected Rendered Malva menu. */
|
|
27
|
-
_menu = viewChild.required('_menu', /* @ts-ignore */
|
|
28
|
-
...(ngDevMode ? [{ debugName: "_menu" }] : /* istanbul ignore next */ []));
|
|
29
|
-
/** @protected Trigger owning the menu overlay. */
|
|
30
|
-
_trigger = viewChild.required(MlvMenuTrigger, /* @ts-ignore */
|
|
31
|
-
...(ngDevMode ? [{ debugName: "_trigger" }] : /* istanbul ignore next */ []));
|
|
32
|
-
/** @private Tears down the active panel registration. */
|
|
33
|
-
_unregister;
|
|
34
|
-
/** @private Guards queued registration after a quick close or destroy. */
|
|
35
|
-
_menuOpen = false;
|
|
36
|
-
/** @protected Resolved menu labels. */
|
|
37
|
-
_copy = computed(() => ({
|
|
38
|
-
bullet: this._i18n?.().bulletList ?? 'Bullet list',
|
|
39
|
-
ordered: this._i18n?.().orderedList ?? 'Ordered list',
|
|
40
|
-
task: this._i18n?.().taskList ?? 'Task list',
|
|
41
|
-
}), /* @ts-ignore */
|
|
42
|
-
...(ngDevMode ? [{ debugName: "_copy" }] : /* istanbul ignore next */ []));
|
|
43
|
-
/** @protected Bullet-list command availability at the current selection. */
|
|
44
|
-
_canBullet = (editor) => editor.can().chain().toggleBulletList().run();
|
|
45
|
-
/** @protected Ordered-list command availability at the current selection. */
|
|
46
|
-
_canOrdered = (editor) => editor.can().chain().toggleOrderedList().run();
|
|
47
|
-
/** @protected Task-list command availability at the current selection. */
|
|
48
|
-
_canTask = (editor) => editor.can().chain().toggleTaskList().run();
|
|
49
|
-
/** @protected Bullet-list command. */
|
|
50
|
-
_bullet = (editor) => editor.chain().focus().toggleBulletList().run();
|
|
51
|
-
/** @protected Ordered-list command. */
|
|
52
|
-
_ordered = (editor) => editor.chain().focus().toggleOrderedList().run();
|
|
53
|
-
/** @protected Task-list command. */
|
|
54
|
-
_task = (editor) => editor.chain().focus().toggleTaskList().run();
|
|
55
|
-
constructor() {
|
|
56
|
-
this._destroyRef.onDestroy(() => this._unregisterOverlay());
|
|
57
|
-
}
|
|
58
|
-
/** @protected The list style currently active at the selection. */
|
|
59
|
-
_label() {
|
|
60
|
-
if (this._context.isActive('orderedList'))
|
|
61
|
-
return this._copy().ordered;
|
|
62
|
-
if (this._context.isActive('taskList'))
|
|
63
|
-
return this._copy().task;
|
|
64
|
-
return this._copy().bullet;
|
|
65
|
-
}
|
|
66
|
-
/** @protected Whether one list command is registered by the active extension set. */
|
|
67
|
-
_supported() {
|
|
68
|
-
this._revision();
|
|
69
|
-
const editor = this._context.editor();
|
|
70
|
-
return (!!editor &&
|
|
71
|
-
(editor.commands.toggleBulletList !== undefined ||
|
|
72
|
-
editor.commands.toggleOrderedList !== undefined ||
|
|
73
|
-
editor.commands.toggleTaskList !== undefined));
|
|
74
|
-
}
|
|
75
|
-
/** @protected Whether the bullet-list command is registered. */
|
|
76
|
-
_hasBullet() {
|
|
77
|
-
this._revision();
|
|
78
|
-
return this._context.editor()?.commands.toggleBulletList !== undefined;
|
|
79
|
-
}
|
|
80
|
-
/** @protected Whether the ordered-list command is registered. */
|
|
81
|
-
_hasOrdered() {
|
|
82
|
-
this._revision();
|
|
83
|
-
return this._context.editor()?.commands.toggleOrderedList !== undefined;
|
|
84
|
-
}
|
|
85
|
-
/** @protected Whether the task-list command is registered. */
|
|
86
|
-
_hasTask() {
|
|
87
|
-
this._revision();
|
|
88
|
-
return this._context.editor()?.commands.toggleTaskList !== undefined;
|
|
89
|
-
}
|
|
90
|
-
/** @protected Whether the menu trigger cannot be opened. */
|
|
91
|
-
_triggerDisabled() {
|
|
92
|
-
return (!this._supported() || this._context.disabled() || this._context.readonly());
|
|
93
|
-
}
|
|
94
|
-
/** @protected Whether an available menu item currently cannot mutate. */
|
|
95
|
-
_disabled(command) {
|
|
96
|
-
this._revision();
|
|
97
|
-
return this._triggerDisabled() || !this._context.can(command);
|
|
98
|
-
}
|
|
99
|
-
/** @protected Runs a selection-restoring list command. */
|
|
100
|
-
_run(command) {
|
|
101
|
-
this._context.run(command);
|
|
102
|
-
}
|
|
103
|
-
/** @protected Registers the portaled panel as editor-owned focus. */
|
|
104
|
-
_registerOverlay() {
|
|
105
|
-
this._menuOpen = true;
|
|
106
|
-
queueMicrotask(() => {
|
|
107
|
-
if (!this._menuOpen)
|
|
108
|
-
return;
|
|
109
|
-
const panel = this._document.getElementById(this._menu().panelId);
|
|
110
|
-
if (!panel)
|
|
111
|
-
return;
|
|
112
|
-
this._unregister?.();
|
|
113
|
-
this._unregister = this._overlays.register(panel, () => this._trigger().close());
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
/** @protected Removes menu-panel focus ownership after close. */
|
|
117
|
-
_unregisterOverlay() {
|
|
118
|
-
this._menuOpen = false;
|
|
119
|
-
this._unregister?.();
|
|
120
|
-
this._unregister = undefined;
|
|
121
|
-
}
|
|
122
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MlvEditorList, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
123
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: MlvEditorList, isStandalone: true, selector: "mlv-editor-list", host: { properties: { "hidden": "!_supported()" }, classAttribute: "mlv-editor-list" }, viewQueries: [{ propertyName: "_menu", first: true, predicate: ["_menu"], descendants: true, isSignal: true }, { propertyName: "_trigger", first: true, predicate: MlvMenuTrigger, descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
124
|
-
<button
|
|
125
|
-
mlvButton
|
|
126
|
-
mlvEditorToolbarWidget
|
|
127
|
-
type="button"
|
|
128
|
-
shape="square"
|
|
129
|
-
mlvDensity="tight"
|
|
130
|
-
variant="transparent"
|
|
131
|
-
[disabled]="_triggerDisabled()"
|
|
132
|
-
[mlvMenuTrigger]="_menu"
|
|
133
|
-
[menuTriggerDisabled]="_triggerDisabled()"
|
|
134
|
-
[attr.aria-label]="_copy().bullet"
|
|
135
|
-
[mlvTooltip]="_label()"
|
|
136
|
-
(menuOpened)="_registerOverlay()"
|
|
137
|
-
(menuClosed)="_unregisterOverlay()"
|
|
138
|
-
>
|
|
139
|
-
<svg mlvButtonIcon lucideList aria-hidden="true" />
|
|
140
|
-
</button>
|
|
141
|
-
<mlv-menu #_menu [label]="_copy().bullet">
|
|
142
|
-
@if (_hasBullet()) {
|
|
143
|
-
<mlv-list-item
|
|
144
|
-
mlvMenuItem
|
|
145
|
-
[disabled]="_disabled(_canBullet)"
|
|
146
|
-
[attr.aria-current]="_context.isActive('bulletList') ? 'true' : null"
|
|
147
|
-
(itemClick)="_run(_bullet)"
|
|
148
|
-
>
|
|
149
|
-
{{ _copy().bullet }}
|
|
150
|
-
</mlv-list-item>
|
|
151
|
-
}
|
|
152
|
-
@if (_hasOrdered()) {
|
|
153
|
-
<mlv-list-item
|
|
154
|
-
mlvMenuItem
|
|
155
|
-
[disabled]="_disabled(_canOrdered)"
|
|
156
|
-
[attr.aria-current]="_context.isActive('orderedList') ? 'true' : null"
|
|
157
|
-
(itemClick)="_run(_ordered)"
|
|
158
|
-
>
|
|
159
|
-
{{ _copy().ordered }}
|
|
160
|
-
</mlv-list-item>
|
|
161
|
-
}
|
|
162
|
-
@if (_hasTask()) {
|
|
163
|
-
<mlv-list-item
|
|
164
|
-
mlvMenuItem
|
|
165
|
-
[disabled]="_disabled(_canTask)"
|
|
166
|
-
[attr.aria-current]="_context.isActive('taskList') ? 'true' : null"
|
|
167
|
-
(itemClick)="_run(_task)"
|
|
168
|
-
>
|
|
169
|
-
{{ _copy().task }}
|
|
170
|
-
</mlv-list-item>
|
|
171
|
-
}
|
|
172
|
-
</mlv-menu>
|
|
173
|
-
`, isInline: true, dependencies: [{ kind: "component", type: MlvButton, selector: "button[mlvButton], a[mlvButton]", inputs: ["variant", "shape", "disabled", "loading"] }, { kind: "directive", type: MlvButtonIcon, selector: "[mlvButtonIcon]" }, { kind: "directive", type: MlvTooltip, selector: "[mlvTooltip]", inputs: ["mlvTooltip", "tooltipPlacement", "tooltipTone", "tooltipDelay", "tooltipDisabled", "tooltipArrow"] }, { kind: "component", type: LucideList, selector: "svg[lucideList]" }, { kind: "component", type: MlvListItem, selector: "mlv-list-item", inputs: ["itemRole", "unread", "accent"] }, { kind: "component", type: MlvMenu, selector: "mlv-menu", inputs: ["label", "mlvDensity"], outputs: ["closed"] }, { kind: "directive", type: MlvMenuItem, selector: "mlv-list-item[mlvMenuItem]", inputs: ["disabled"], outputs: ["itemClick"] }, { kind: "directive", type: MlvMenuTrigger, selector: "[mlvMenuTrigger]", inputs: ["mlvMenuTrigger", "isSubmenuTrigger", "menuTriggerDisabled"], outputs: ["menuOpened", "menuClosed"] }, { kind: "directive", type: MlvEditorToolbarWidget, selector: "[mlvEditorToolbarWidget]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
174
|
-
}
|
|
175
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MlvEditorList, decorators: [{
|
|
176
|
-
type: Component,
|
|
177
|
-
args: [{
|
|
178
|
-
selector: 'mlv-editor-list',
|
|
179
|
-
imports: [
|
|
180
|
-
MlvButton,
|
|
181
|
-
MlvButtonIcon,
|
|
182
|
-
MlvTooltip,
|
|
183
|
-
LucideList,
|
|
184
|
-
MlvListItem,
|
|
185
|
-
MlvMenu,
|
|
186
|
-
MlvMenuItem,
|
|
187
|
-
MlvMenuTrigger,
|
|
188
|
-
MlvEditorToolbarWidget,
|
|
189
|
-
],
|
|
190
|
-
template: `
|
|
191
|
-
<button
|
|
192
|
-
mlvButton
|
|
193
|
-
mlvEditorToolbarWidget
|
|
194
|
-
type="button"
|
|
195
|
-
shape="square"
|
|
196
|
-
mlvDensity="tight"
|
|
197
|
-
variant="transparent"
|
|
198
|
-
[disabled]="_triggerDisabled()"
|
|
199
|
-
[mlvMenuTrigger]="_menu"
|
|
200
|
-
[menuTriggerDisabled]="_triggerDisabled()"
|
|
201
|
-
[attr.aria-label]="_copy().bullet"
|
|
202
|
-
[mlvTooltip]="_label()"
|
|
203
|
-
(menuOpened)="_registerOverlay()"
|
|
204
|
-
(menuClosed)="_unregisterOverlay()"
|
|
205
|
-
>
|
|
206
|
-
<svg mlvButtonIcon lucideList aria-hidden="true" />
|
|
207
|
-
</button>
|
|
208
|
-
<mlv-menu #_menu [label]="_copy().bullet">
|
|
209
|
-
@if (_hasBullet()) {
|
|
210
|
-
<mlv-list-item
|
|
211
|
-
mlvMenuItem
|
|
212
|
-
[disabled]="_disabled(_canBullet)"
|
|
213
|
-
[attr.aria-current]="_context.isActive('bulletList') ? 'true' : null"
|
|
214
|
-
(itemClick)="_run(_bullet)"
|
|
215
|
-
>
|
|
216
|
-
{{ _copy().bullet }}
|
|
217
|
-
</mlv-list-item>
|
|
218
|
-
}
|
|
219
|
-
@if (_hasOrdered()) {
|
|
220
|
-
<mlv-list-item
|
|
221
|
-
mlvMenuItem
|
|
222
|
-
[disabled]="_disabled(_canOrdered)"
|
|
223
|
-
[attr.aria-current]="_context.isActive('orderedList') ? 'true' : null"
|
|
224
|
-
(itemClick)="_run(_ordered)"
|
|
225
|
-
>
|
|
226
|
-
{{ _copy().ordered }}
|
|
227
|
-
</mlv-list-item>
|
|
228
|
-
}
|
|
229
|
-
@if (_hasTask()) {
|
|
230
|
-
<mlv-list-item
|
|
231
|
-
mlvMenuItem
|
|
232
|
-
[disabled]="_disabled(_canTask)"
|
|
233
|
-
[attr.aria-current]="_context.isActive('taskList') ? 'true' : null"
|
|
234
|
-
(itemClick)="_run(_task)"
|
|
235
|
-
>
|
|
236
|
-
{{ _copy().task }}
|
|
237
|
-
</mlv-list-item>
|
|
238
|
-
}
|
|
239
|
-
</mlv-menu>
|
|
240
|
-
`,
|
|
241
|
-
encapsulation: ViewEncapsulation.None,
|
|
242
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
243
|
-
host: {
|
|
244
|
-
class: 'mlv-editor-list',
|
|
245
|
-
'[hidden]': '!_supported()',
|
|
246
|
-
},
|
|
247
|
-
}]
|
|
248
|
-
}], ctorParameters: () => [], propDecorators: { _menu: [{ type: i0.ViewChild, args: ['_menu', { isSignal: true }] }], _trigger: [{ type: i0.ViewChild, args: [i0.forwardRef(() => MlvMenuTrigger), { isSignal: true }] }] } });
|
|
249
|
-
//# sourceMappingURL=editor-list.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"editor-list.js","sourceRoot":"","sources":["../../../../../../libs/editor/src/lib/toolbar/editor-list.ts"],"names":[],"mappings":"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","sourcesContent":["import { DOCUMENT } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n computed,\n inject,\n ViewEncapsulation,\n viewChild,\n} from '@angular/core';\nimport type { Editor } from '@tiptap/core';\nimport { LucideList } from '@lucide/angular';\nimport { MlvButton, MlvButtonIcon } from '@malva-ui/core/button';\nimport { MlvListItem } from '@malva-ui/core/list';\nimport { MlvMenu, MlvMenuItem, MlvMenuTrigger } from '@malva-ui/core/menu';\nimport { MlvTooltip } from '@malva-ui/core/tooltip';\nimport { MLV_EDITOR_I18N } from '@malva-ui/i18n';\nimport {\n MLV_EDITOR_OVERLAY_REGISTRY,\n MLV_EDITOR_TOOLBAR_CONTEXT,\n MLV_EDITOR_TOOLBAR_REVISION,\n} from '../editor-toolbar-context';\nimport type { MlvEditorOverlayRegistry } from '../editor-toolbar-context';\nimport { MlvEditorToolbarWidget } from './editor-toolbar-widget';\n\n/** Bullet, ordered, and task-list toolbar commands in a compact menu. */\n@Component({\n selector: 'mlv-editor-list',\n imports: [\n MlvButton,\n MlvButtonIcon,\n MlvTooltip,\n LucideList,\n MlvListItem,\n MlvMenu,\n MlvMenuItem,\n MlvMenuTrigger,\n MlvEditorToolbarWidget,\n ],\n template: `\n <button\n mlvButton\n mlvEditorToolbarWidget\n type=\"button\"\n shape=\"square\"\n mlvDensity=\"tight\"\n variant=\"transparent\"\n [disabled]=\"_triggerDisabled()\"\n [mlvMenuTrigger]=\"_menu\"\n [menuTriggerDisabled]=\"_triggerDisabled()\"\n [attr.aria-label]=\"_copy().bullet\"\n [mlvTooltip]=\"_label()\"\n (menuOpened)=\"_registerOverlay()\"\n (menuClosed)=\"_unregisterOverlay()\"\n >\n <svg mlvButtonIcon lucideList aria-hidden=\"true\" />\n </button>\n <mlv-menu #_menu [label]=\"_copy().bullet\">\n @if (_hasBullet()) {\n <mlv-list-item\n mlvMenuItem\n [disabled]=\"_disabled(_canBullet)\"\n [attr.aria-current]=\"_context.isActive('bulletList') ? 'true' : null\"\n (itemClick)=\"_run(_bullet)\"\n >\n {{ _copy().bullet }}\n </mlv-list-item>\n }\n @if (_hasOrdered()) {\n <mlv-list-item\n mlvMenuItem\n [disabled]=\"_disabled(_canOrdered)\"\n [attr.aria-current]=\"_context.isActive('orderedList') ? 'true' : null\"\n (itemClick)=\"_run(_ordered)\"\n >\n {{ _copy().ordered }}\n </mlv-list-item>\n }\n @if (_hasTask()) {\n <mlv-list-item\n mlvMenuItem\n [disabled]=\"_disabled(_canTask)\"\n [attr.aria-current]=\"_context.isActive('taskList') ? 'true' : null\"\n (itemClick)=\"_run(_task)\"\n >\n {{ _copy().task }}\n </mlv-list-item>\n }\n </mlv-menu>\n `,\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n class: 'mlv-editor-list',\n '[hidden]': '!_supported()',\n },\n})\nexport class MlvEditorList {\n /** @protected Editor command state. */\n protected readonly _context = inject(MLV_EDITOR_TOOLBAR_CONTEXT);\n\n /** @private Per-editor state invalidation signal. */\n private readonly _revision = inject(MLV_EDITOR_TOOLBAR_REVISION);\n\n /** @private The editor-owned overlay registry. */\n private readonly _overlays = inject<MlvEditorOverlayRegistry>(\n MLV_EDITOR_OVERLAY_REGISTRY,\n );\n\n /** @private Document used to resolve the public menu panel id. */\n private readonly _document = inject(DOCUMENT);\n\n /** @private Removes a pending or active overlay registration. */\n private readonly _destroyRef = inject(DestroyRef);\n\n /** @private Optional localized editor copy. */\n private readonly _i18n = inject(MLV_EDITOR_I18N, { optional: true });\n\n /** @protected Rendered Malva menu. */\n protected readonly _menu = viewChild.required<MlvMenu>('_menu');\n\n /** @protected Trigger owning the menu overlay. */\n protected readonly _trigger = viewChild.required(MlvMenuTrigger);\n\n /** @private Tears down the active panel registration. */\n private _unregister: (() => void) | undefined;\n\n /** @private Guards queued registration after a quick close or destroy. */\n private _menuOpen = false;\n\n /** @protected Resolved menu labels. */\n protected readonly _copy = computed(() => ({\n bullet: this._i18n?.().bulletList ?? 'Bullet list',\n ordered: this._i18n?.().orderedList ?? 'Ordered list',\n task: this._i18n?.().taskList ?? 'Task list',\n }));\n\n /** @protected Bullet-list command availability at the current selection. */\n protected readonly _canBullet = (editor: Editor): boolean =>\n editor.can().chain().toggleBulletList().run();\n\n /** @protected Ordered-list command availability at the current selection. */\n protected readonly _canOrdered = (editor: Editor): boolean =>\n editor.can().chain().toggleOrderedList().run();\n\n /** @protected Task-list command availability at the current selection. */\n protected readonly _canTask = (editor: Editor): boolean =>\n editor.can().chain().toggleTaskList().run();\n\n /** @protected Bullet-list command. */\n protected readonly _bullet = (editor: Editor): boolean =>\n editor.chain().focus().toggleBulletList().run();\n\n /** @protected Ordered-list command. */\n protected readonly _ordered = (editor: Editor): boolean =>\n editor.chain().focus().toggleOrderedList().run();\n\n /** @protected Task-list command. */\n protected readonly _task = (editor: Editor): boolean =>\n editor.chain().focus().toggleTaskList().run();\n\n constructor() {\n this._destroyRef.onDestroy(() => this._unregisterOverlay());\n }\n\n /** @protected The list style currently active at the selection. */\n protected _label(): string {\n if (this._context.isActive('orderedList')) return this._copy().ordered;\n if (this._context.isActive('taskList')) return this._copy().task;\n return this._copy().bullet;\n }\n\n /** @protected Whether one list command is registered by the active extension set. */\n protected _supported(): boolean {\n this._revision();\n const editor = this._context.editor();\n return (\n !!editor &&\n (editor.commands.toggleBulletList !== undefined ||\n editor.commands.toggleOrderedList !== undefined ||\n editor.commands.toggleTaskList !== undefined)\n );\n }\n\n /** @protected Whether the bullet-list command is registered. */\n protected _hasBullet(): boolean {\n this._revision();\n return this._context.editor()?.commands.toggleBulletList !== undefined;\n }\n\n /** @protected Whether the ordered-list command is registered. */\n protected _hasOrdered(): boolean {\n this._revision();\n return this._context.editor()?.commands.toggleOrderedList !== undefined;\n }\n\n /** @protected Whether the task-list command is registered. */\n protected _hasTask(): boolean {\n this._revision();\n return this._context.editor()?.commands.toggleTaskList !== undefined;\n }\n\n /** @protected Whether the menu trigger cannot be opened. */\n protected _triggerDisabled(): boolean {\n return (\n !this._supported() || this._context.disabled() || this._context.readonly()\n );\n }\n\n /** @protected Whether an available menu item currently cannot mutate. */\n protected _disabled(command: (editor: Editor) => boolean): boolean {\n this._revision();\n return this._triggerDisabled() || !this._context.can(command);\n }\n\n /** @protected Runs a selection-restoring list command. */\n protected _run(command: (editor: Editor) => boolean): void {\n this._context.run(command);\n }\n\n /** @protected Registers the portaled panel as editor-owned focus. */\n protected _registerOverlay(): void {\n this._menuOpen = true;\n queueMicrotask(() => {\n if (!this._menuOpen) return;\n const panel = this._document.getElementById(this._menu().panelId);\n if (!panel) return;\n this._unregister?.();\n this._unregister = this._overlays.register(panel, () =>\n this._trigger().close(),\n );\n });\n }\n\n /** @protected Removes menu-panel focus ownership after close. */\n protected _unregisterOverlay(): void {\n this._menuOpen = false;\n this._unregister?.();\n this._unregister = undefined;\n }\n}\n"]}
|