@threadlabs/looma 0.30.9 → 0.31.1
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/components/shared/icons.js +1 -0
- package/components/ui-affordance-scope/ui-affordance-scope.html +1 -1
- package/components/ui-affordance-scope/ui-affordance-scope.js +1 -6
- package/components/ui-avatar/ui-avatar.html +1 -1
- package/components/ui-avatar/ui-avatar.js +1 -6
- package/components/ui-avatar-group/ui-avatar-group.html +1 -1
- package/components/ui-avatar-group/ui-avatar-group.js +1 -6
- package/components/ui-button/ui-button.html +1 -1
- package/components/ui-button/ui-button.js +1 -6
- package/components/ui-checkbox/ui-checkbox.html +1 -1
- package/components/ui-checkbox/ui-checkbox.js +1 -6
- package/components/ui-combobox/ui-combobox.html +1 -1
- package/components/ui-combobox/ui-combobox.js +1 -6
- package/components/ui-context-menu/ui-context-menu.html +1 -1
- package/components/ui-context-menu/ui-context-menu.js +1 -6
- package/components/ui-dialog/ui-dialog.html +1 -1
- package/components/ui-dialog/ui-dialog.js +1 -6
- package/components/ui-disclosure/ui-disclosure.html +1 -1
- package/components/ui-disclosure/ui-disclosure.js +1 -6
- package/components/ui-editable/ui-editable.html +1 -1
- package/components/ui-editable/ui-editable.js +1 -6
- package/components/ui-editor-block-actions/ui-editor-block-actions.html +1 -1
- package/components/ui-editor-block-actions/ui-editor-block-actions.js +1 -6
- package/components/ui-editor-chip-editor/ui-editor-chip-editor.html +1 -1
- package/components/ui-editor-chip-editor/ui-editor-chip-editor.js +1 -6
- package/components/ui-editor-code-language/ui-editor-code-language.html +1 -1
- package/components/ui-editor-code-language/ui-editor-code-language.js +1 -6
- package/components/ui-editor-footnote-editor/ui-editor-footnote-editor.html +57 -0
- package/components/ui-editor-footnote-editor/ui-editor-footnote-editor.js +38 -0
- package/components/ui-editor-image-toolbar/ui-editor-image-toolbar.html +1 -1
- package/components/ui-editor-image-toolbar/ui-editor-image-toolbar.js +1 -6
- package/components/ui-editor-insert-table-grid/ui-editor-insert-table-grid.html +1 -1
- package/components/ui-editor-insert-table-grid/ui-editor-insert-table-grid.js +1 -6
- package/components/ui-editor-link-card/ui-editor-link-card.html +1 -1
- package/components/ui-editor-link-card/ui-editor-link-card.js +1 -6
- package/components/ui-editor-link-form/ui-editor-link-form.html +1 -1
- package/components/ui-editor-link-form/ui-editor-link-form.js +1 -6
- package/components/ui-editor-mention-menu/ui-editor-mention-menu.html +1 -1
- package/components/ui-editor-mention-menu/ui-editor-mention-menu.js +1 -6
- package/components/ui-editor-slash-menu/ui-editor-slash-menu.html +1 -1
- package/components/ui-editor-slash-menu/ui-editor-slash-menu.js +1 -6
- package/components/ui-editor-table-context-menu/ui-editor-table-context-menu.html +1 -1
- package/components/ui-editor-table-context-menu/ui-editor-table-context-menu.js +1 -6
- package/components/ui-editor-table-overlay/ui-editor-table-overlay.html +1 -1
- package/components/ui-editor-table-overlay/ui-editor-table-overlay.js +1 -6
- package/components/ui-editor-table-toolbar/ui-editor-table-toolbar.html +1 -1
- package/components/ui-editor-table-toolbar/ui-editor-table-toolbar.js +1 -6
- package/components/ui-editor-toolbar/ui-editor-toolbar.html +1 -1
- package/components/ui-editor-toolbar/ui-editor-toolbar.js +1 -6
- package/components/ui-form-field/ui-form-field.html +1 -1
- package/components/ui-form-field/ui-form-field.js +1 -6
- package/components/ui-icon/ui-icon.html +1 -0
- package/components/ui-icon-button/ui-icon-button.html +1 -1
- package/components/ui-icon-button/ui-icon-button.js +1 -6
- package/components/ui-image/ui-image.html +1 -1
- package/components/ui-image/ui-image.js +1 -6
- package/components/ui-input/ui-input.html +1 -1
- package/components/ui-input/ui-input.js +1 -6
- package/components/ui-input-group/ui-input-group.html +1 -1
- package/components/ui-input-group/ui-input-group.js +1 -6
- package/components/ui-listbox/ui-listbox.html +1 -1
- package/components/ui-listbox/ui-listbox.js +1 -6
- package/components/ui-menu/ui-menu.html +1 -1
- package/components/ui-menu/ui-menu.js +1 -6
- package/components/ui-menu-item/ui-menu-item.html +1 -1
- package/components/ui-menu-item/ui-menu-item.js +1 -6
- package/components/ui-popover/ui-popover.html +1 -1
- package/components/ui-popover/ui-popover.js +1 -6
- package/components/ui-radio/ui-radio.html +1 -1
- package/components/ui-radio/ui-radio.js +1 -6
- package/components/ui-radio-group/ui-radio-group.html +1 -1
- package/components/ui-radio-group/ui-radio-group.js +1 -6
- package/components/ui-scroll-area/ui-scroll-area.html +1 -1
- package/components/ui-scroll-area/ui-scroll-area.js +1 -6
- package/components/ui-search-shell/ui-search-shell.html +1 -1
- package/components/ui-search-shell/ui-search-shell.js +1 -6
- package/components/ui-select/ui-select.html +1 -1
- package/components/ui-select/ui-select.js +1 -6
- package/components/ui-sidebar/ui-sidebar.html +1 -1
- package/components/ui-sidebar/ui-sidebar.js +1 -6
- package/components/ui-switch/ui-switch.html +1 -1
- package/components/ui-switch/ui-switch.js +1 -6
- package/components/ui-switcher/ui-switcher.html +1 -1
- package/components/ui-switcher/ui-switcher.js +1 -6
- package/components/ui-table/ui-table.html +1 -1
- package/components/ui-table/ui-table.js +1 -6
- package/components/ui-tabs/ui-tabs.html +1 -1
- package/components/ui-tabs/ui-tabs.js +1 -6
- package/components/ui-textarea/ui-textarea.html +1 -1
- package/components/ui-textarea/ui-textarea.js +1 -6
- package/components/ui-toast/ui-toast.html +1 -1
- package/components/ui-toast/ui-toast.js +1 -6
- package/components/ui-toast-region/ui-toast-region.html +1 -1
- package/components/ui-toast-region/ui-toast-region.js +1 -6
- package/components/ui-tooltip/ui-tooltip.html +1 -1
- package/components/ui-tooltip/ui-tooltip.js +1 -6
- package/components/ui-tree/ui-tree.html +1 -1
- package/components/ui-tree/ui-tree.js +1 -6
- package/components/ui-tree-item/ui-tree-item.html +1 -1
- package/components/ui-tree-item/ui-tree-item.js +1 -6
- package/dist/index.js +37 -36
- package/editor/chunks/extensions.js +342 -20
- package/editor/expressmark.js +1 -1
- package/editor/extensions/footnote.d.ts +40 -7
- package/editor/extensions/index.d.ts +1 -1
- package/editor/extensions/index.js +2 -2
- package/editor/footnote-editing.d.ts +46 -0
- package/editor/icons.d.ts +1 -0
- package/editor/index.js +4 -3
- package/package.json +1 -1
- package/styles/ui-editor-footnote-editor.css +1 -0
- package/vanilla/UiAffordanceScope.js +4 -4
- package/vanilla/UiAvatar.js +4 -4
- package/vanilla/UiAvatarGroup.js +4 -4
- package/vanilla/UiButton.js +4 -4
- package/vanilla/UiCheckbox.js +4 -4
- package/vanilla/UiCombobox.js +4 -4
- package/vanilla/UiContextMenu.js +4 -4
- package/vanilla/UiDialog.js +4 -4
- package/vanilla/UiDisclosure.js +4 -4
- package/vanilla/UiEditable.js +4 -4
- package/vanilla/UiEditorBlockActions.js +4 -4
- package/vanilla/UiEditorChipEditor.js +4 -4
- package/vanilla/UiEditorCodeLanguage.js +4 -4
- package/vanilla/UiEditorFootnoteEditor.d.ts +30 -0
- package/vanilla/UiEditorFootnoteEditor.js +101 -0
- package/vanilla/UiEditorImageToolbar.js +4 -4
- package/vanilla/UiEditorInsertTableGrid.js +4 -4
- package/vanilla/UiEditorLinkCard.js +4 -4
- package/vanilla/UiEditorLinkForm.js +4 -4
- package/vanilla/UiEditorMentionMenu.js +4 -4
- package/vanilla/UiEditorSlashMenu.js +4 -4
- package/vanilla/UiEditorTableContextMenu.js +4 -4
- package/vanilla/UiEditorTableOverlay.js +4 -4
- package/vanilla/UiEditorTableToolbar.js +4 -4
- package/vanilla/UiEditorToolbar.js +4 -4
- package/vanilla/UiFormField.js +4 -4
- package/vanilla/UiIcon.js +1 -1
- package/vanilla/UiIconButton.js +4 -4
- package/vanilla/UiImage.js +4 -4
- package/vanilla/UiInput.js +4 -4
- package/vanilla/UiInputGroup.js +4 -4
- package/vanilla/UiListbox.js +4 -4
- package/vanilla/UiMenu.js +4 -4
- package/vanilla/UiMenuItem.js +4 -4
- package/vanilla/UiPopover.js +4 -4
- package/vanilla/UiRadio.js +4 -4
- package/vanilla/UiRadioGroup.js +4 -4
- package/vanilla/UiScrollArea.js +4 -4
- package/vanilla/UiSearchShell.js +4 -4
- package/vanilla/UiSelect.js +4 -4
- package/vanilla/UiSidebar.js +4 -4
- package/vanilla/UiSwitch.js +4 -4
- package/vanilla/UiSwitcher.js +4 -4
- package/vanilla/UiTable.js +4 -4
- package/vanilla/UiTabs.js +4 -4
- package/vanilla/UiTextarea.js +4 -4
- package/vanilla/UiToast.js +4 -4
- package/vanilla/UiToastRegion.js +4 -4
- package/vanilla/UiTooltip.js +4 -4
- package/vanilla/UiTree.js +4 -4
- package/vanilla/UiTreeItem.js +4 -4
- package/vanilla/index.js +1 -0
- package/vue/UiAffordanceScope.vue +1 -0
- package/vue/UiAvatar.vue +1 -0
- package/vue/UiAvatarGroup.vue +1 -0
- package/vue/UiButton.vue +1 -0
- package/vue/UiCheckbox.vue +1 -0
- package/vue/UiCombobox.vue +1 -0
- package/vue/UiContextMenu.vue +1 -0
- package/vue/UiDialog.vue +1 -0
- package/vue/UiDisclosure.vue +1 -0
- package/vue/UiEditable.vue +1 -0
- package/vue/UiEditorBlockActions.vue +1 -0
- package/vue/UiEditorChipEditor.vue +1 -0
- package/vue/UiEditorCodeLanguage.vue +1 -0
- package/vue/UiEditorFootnoteEditor.d.ts +57 -0
- package/vue/UiEditorFootnoteEditor.js +2 -0
- package/vue/UiEditorFootnoteEditor.vue +304 -0
- package/vue/UiEditorImageToolbar.vue +1 -0
- package/vue/UiEditorInsertTableGrid.vue +1 -0
- package/vue/UiEditorLinkCard.vue +1 -0
- package/vue/UiEditorLinkForm.vue +1 -0
- package/vue/UiEditorMentionMenu.vue +1 -0
- package/vue/UiEditorSlashMenu.vue +1 -0
- package/vue/UiEditorTableContextMenu.vue +1 -0
- package/vue/UiEditorTableOverlay.vue +1 -0
- package/vue/UiEditorTableToolbar.vue +1 -0
- package/vue/UiEditorToolbar.vue +1 -0
- package/vue/UiFormField.vue +1 -0
- package/vue/UiIcon.vue +4 -0
- package/vue/UiIconButton.vue +1 -0
- package/vue/UiImage.vue +1 -0
- package/vue/UiInput.vue +1 -0
- package/vue/UiInputGroup.vue +1 -0
- package/vue/UiListbox.vue +1 -0
- package/vue/UiMenu.vue +1 -0
- package/vue/UiMenuItem.vue +1 -0
- package/vue/UiPopover.vue +1 -0
- package/vue/UiRadio.vue +1 -0
- package/vue/UiRadioGroup.vue +1 -0
- package/vue/UiScrollArea.vue +1 -0
- package/vue/UiSearchShell.vue +1 -0
- package/vue/UiSelect.vue +1 -0
- package/vue/UiSidebar.vue +1 -0
- package/vue/UiSwitch.vue +1 -0
- package/vue/UiSwitcher.vue +1 -0
- package/vue/UiTable.vue +1 -0
- package/vue/UiTabs.vue +1 -0
- package/vue/UiTextarea.vue +1 -0
- package/vue/UiToast.vue +1 -0
- package/vue/UiToastRegion.vue +1 -0
- package/vue/UiTooltip.vue +1 -0
- package/vue/UiTree.vue +1 -0
- package/vue/UiTreeItem.vue +1 -0
- package/vue/chunks/UiAffordanceScope.js +2 -1
- package/vue/chunks/UiAvatar.js +2 -1
- package/vue/chunks/UiAvatarGroup.js +2 -1
- package/vue/chunks/UiButton.js +2 -1
- package/vue/chunks/UiCheckbox.js +2 -1
- package/vue/chunks/UiCombobox.js +2 -1
- package/vue/chunks/UiContextMenu.js +2 -1
- package/vue/chunks/UiDialog.js +2 -1
- package/vue/chunks/UiDisclosure.js +2 -1
- package/vue/chunks/UiEditable.js +2 -1
- package/vue/chunks/UiEditorBlockActions.js +1 -0
- package/vue/chunks/UiEditorChipEditor.js +1 -0
- package/vue/chunks/UiEditorCodeLanguage.js +1 -0
- package/vue/chunks/UiEditorFootnoteEditor.js +306 -0
- package/vue/chunks/UiEditorImageToolbar.js +2 -1
- package/vue/chunks/UiEditorInsertTableGrid.js +2 -1
- package/vue/chunks/UiEditorLinkCard.js +1 -0
- package/vue/chunks/UiEditorLinkForm.js +2 -1
- package/vue/chunks/UiEditorMentionMenu.js +2 -1
- package/vue/chunks/UiEditorSlashMenu.js +2 -1
- package/vue/chunks/UiEditorTableContextMenu.js +2 -1
- package/vue/chunks/UiEditorTableOverlay.js +2 -1
- package/vue/chunks/UiEditorTableToolbar.js +2 -1
- package/vue/chunks/UiEditorToolbar.js +2 -1
- package/vue/chunks/UiFormField.js +2 -1
- package/vue/chunks/UiIcon.js +15 -1
- package/vue/chunks/UiIconButton.js +2 -1
- package/vue/chunks/UiImage.js +2 -1
- package/vue/chunks/UiInput.js +2 -1
- package/vue/chunks/UiInputGroup.js +2 -1
- package/vue/chunks/UiListbox.js +2 -1
- package/vue/chunks/UiMenu.js +2 -1
- package/vue/chunks/UiMenuItem.js +2 -1
- package/vue/chunks/UiPopover.js +2 -1
- package/vue/chunks/UiRadio.js +2 -1
- package/vue/chunks/UiRadioGroup.js +2 -1
- package/vue/chunks/UiScrollArea.js +2 -1
- package/vue/chunks/UiSearchShell.js +2 -1
- package/vue/chunks/UiSelect.js +2 -1
- package/vue/chunks/UiSidebar.js +2 -1
- package/vue/chunks/UiSwitch.js +2 -1
- package/vue/chunks/UiSwitcher.js +2 -1
- package/vue/chunks/UiTable.js +2 -1
- package/vue/chunks/UiTabs.js +2 -1
- package/vue/chunks/UiTextarea.js +2 -1
- package/vue/chunks/UiToast.js +2 -1
- package/vue/chunks/UiToastRegion.js +2 -1
- package/vue/chunks/UiTooltip.js +2 -1
- package/vue/chunks/UiTree.js +2 -1
- package/vue/chunks/UiTreeItem.js +2 -1
- package/vue/components.css +595 -595
- package/vue/editor/index.js +668 -80
- package/vue/editor/primitives.d.ts +3 -1
- package/vue/index.d.ts +1 -0
- package/vue/index.js +5 -4
package/vue/editor/index.js
CHANGED
|
@@ -1,18 +1,30 @@
|
|
|
1
1
|
import { computed, defineComponent, h, nextTick, onBeforeUnmount, onMounted, onUpdated, reactive, ref, shallowRef, useId, watch } from "vue";
|
|
2
2
|
import { DEFAULT_MENTION_RESULT_LIMIT, LOOMA_ICONS, createLoomaMentionExtension, createLoomaSlashCommandExtension, getActiveTableUiState, getDefaultEditorExtensions, getDefaultSlashCommands, getTableOfContentsEntries, getVisualViewportRect, handleTableAction, handleTableOverlayAction, measureTableOverlayGeometry, normalizeActiveTableColumnWidths, normalizeTableOfContentsConfig } from "@threadlabs/looma/editor";
|
|
3
|
-
import { Button, Card, EditorBlockActions, EditorChipEditor, EditorCodeLanguage, EditorImageToolbar, EditorInsertTableGrid, EditorLinkCard, EditorLinkForm, EditorMentionMenu, EditorMentionMenuItem, EditorSlashMenu, EditorSlashMenuGroup, EditorSlashMenuItem, EditorSurface, EditorTableContextMenu, EditorTableOverlay, EditorTableToolbar, EditorToolbar, IconButton, Popover, Stack, StatusMessage, Text, Tooltip } from "@threadlabs/looma/vue";
|
|
4
|
-
import { Editor, Extension, Node as Node$1, getText, getTextSerializersFromSchema, isNodeSelection, mergeAttributes, nodeInputRule, posToDOMRect } from "@tiptap/core";
|
|
3
|
+
import { Button, Card, EditorBlockActions, EditorChipEditor, EditorCodeLanguage, EditorFootnoteEditor, EditorImageToolbar, EditorInsertTableGrid, EditorLinkCard, EditorLinkForm, EditorMentionMenu, EditorMentionMenuItem, EditorSlashMenu, EditorSlashMenuGroup, EditorSlashMenuItem, EditorSurface, EditorTableContextMenu, EditorTableOverlay, EditorTableToolbar, EditorToolbar, IconButton, Popover, Stack, StatusMessage, Text, Tooltip } from "@threadlabs/looma/vue";
|
|
4
|
+
import { Editor, Extension, InputRule, Node as Node$1, PasteRule, getText, getTextSerializersFromSchema, isNodeSelection, mergeAttributes, nodeInputRule, posToDOMRect } from "@tiptap/core";
|
|
5
5
|
import { Editor as Editor$1 } from "@tiptap/vue-3";
|
|
6
|
-
import { AllSelection, NodeSelection, Plugin, PluginKey, TextSelection } from "@tiptap/pm/state";
|
|
6
|
+
import { AllSelection, NodeSelection, Plugin, PluginKey, Selection, TextSelection } from "@tiptap/pm/state";
|
|
7
7
|
import { Decoration, DecorationSet } from "@tiptap/pm/view";
|
|
8
8
|
import { createLowlight } from "lowlight";
|
|
9
9
|
import { RequestEvent, componentRegistry } from "@nextwebwg/html-next/runtime";
|
|
10
10
|
import "@tiptap/pm/tables";
|
|
11
|
+
import { DOMParser, DOMSerializer, Fragment as Fragment$1, Slice } from "@tiptap/pm/model";
|
|
11
12
|
import "@tiptap/pm/transform";
|
|
12
13
|
import { closeHistory } from "@tiptap/pm/history";
|
|
13
|
-
import {
|
|
14
|
-
import { IndexedList, NONCONFORMING, READY_INPUT, UNRESOLVED_INPUT, acceptProps, armElement, attachGeneratedController, awaitInput, buildTemplate, checkBoolean, checkConstrained, checkFormat, checkInteger, checkNumber, checkObject, checkSelected, checkString, clearRegion, computedCycle, defineComponent as defineComponent$1, detailCheck, dispatchDeclared, dispose, evaluateInput, fillSlot, formatOf, generatedInputs, hostState, inputRead, keywordFormat, manageProps, notifyPropertySet, project, readIndex, readMember, readonlyView, readsChanged, rec, replaceRoot, textCall, toAttribute, toText, trackContainer, truthy, writeAttribute, writeUrlAttribute } from "@nextwebwg/html-next/generated-runtime";
|
|
14
|
+
import { IndexedList, NONCONFORMING, READY_INPUT, UNRESOLVED_INPUT, acceptProps, activateModule, armElement, attachGeneratedController, awaitInput, buildTemplate, checkBoolean, checkConstrained, checkFormat, checkInteger, checkNumber, checkObject, checkSelected, checkString, clearRegion, computedCycle, defineComponent as defineComponent$1, detailCheck, dispatchDeclared, dispose, evaluateInput, fillSlot, formatOf, generatedInputs, hostState, inputRead, keywordFormat, manageProps, notifyPropertySet, project, readIndex, readMember, readonlyView, readsChanged, rec, replaceRoot, textCall, toAttribute, toText, trackContainer, truthy, writeAttribute, writeUrlAttribute } from "@nextwebwg/html-next/generated-runtime";
|
|
15
15
|
export * from "@threadlabs/looma/editor";
|
|
16
|
+
//#region \0rolldown/runtime.js
|
|
17
|
+
var __defProp = Object.defineProperty;
|
|
18
|
+
var __exportAll = (all, no_symbols) => {
|
|
19
|
+
let target = {};
|
|
20
|
+
for (var name in all) __defProp(target, name, {
|
|
21
|
+
get: all[name],
|
|
22
|
+
enumerable: true
|
|
23
|
+
});
|
|
24
|
+
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
25
|
+
return target;
|
|
26
|
+
};
|
|
27
|
+
//#endregion
|
|
16
28
|
//#region src/vue/editor/primitives.ts
|
|
17
29
|
/** Each Vue editor component's element tag, for tooling that enumerates them. */
|
|
18
30
|
var EDITOR_ADAPTER_COMPONENT_TAG_MAP = {
|
|
@@ -31,7 +43,8 @@ var EDITOR_ADAPTER_COMPONENT_TAG_MAP = {
|
|
|
31
43
|
EditorLinkForm: "ui-editor-link-form",
|
|
32
44
|
EditorBlockActions: "ui-editor-block-actions",
|
|
33
45
|
EditorCodeLanguage: "ui-editor-code-language",
|
|
34
|
-
EditorChipEditor: "ui-editor-chip-editor"
|
|
46
|
+
EditorChipEditor: "ui-editor-chip-editor",
|
|
47
|
+
EditorFootnoteEditor: "ui-editor-footnote-editor"
|
|
35
48
|
};
|
|
36
49
|
//#endregion
|
|
37
50
|
//#region src/components/shared/overlay.js
|
|
@@ -1666,6 +1679,528 @@ function createChipEditing(options) {
|
|
|
1666
1679
|
};
|
|
1667
1680
|
}
|
|
1668
1681
|
//#endregion
|
|
1682
|
+
//#region src/editor/extensions/footnote.ts
|
|
1683
|
+
var labelFrom = (href, prefix) => href?.startsWith(`#${prefix}`) ? href.slice(prefix.length + 1) : null;
|
|
1684
|
+
/** A footnote label as Looma Markdown reads it in `[^label]`: no whitespace and no `]`. */
|
|
1685
|
+
var LOOMA_FOOTNOTE_LABEL = /^[^\s\]]+$/;
|
|
1686
|
+
var REFERENCE = "loomaFootnoteReference";
|
|
1687
|
+
var NOTES = "loomaFootnotes";
|
|
1688
|
+
var NOTE = "loomaFootnote";
|
|
1689
|
+
var isLabel = (label) => LOOMA_FOOTNOTE_LABEL.test(label);
|
|
1690
|
+
/** Every label a reference or note in `doc` uses. */
|
|
1691
|
+
function usedLabels(doc) {
|
|
1692
|
+
const labels = /* @__PURE__ */ new Set();
|
|
1693
|
+
doc.descendants((node) => {
|
|
1694
|
+
if (node.type.name === REFERENCE || node.type.name === NOTE) labels.add(String(node.attrs.label));
|
|
1695
|
+
});
|
|
1696
|
+
return labels;
|
|
1697
|
+
}
|
|
1698
|
+
/**
|
|
1699
|
+
* The first note for `label` in `doc` and its position.
|
|
1700
|
+
* @failure Returns null when no note has that label.
|
|
1701
|
+
*/
|
|
1702
|
+
function findLoomaFootnote(doc, label) {
|
|
1703
|
+
let found = null;
|
|
1704
|
+
doc.descendants((node, position) => {
|
|
1705
|
+
if (found) return false;
|
|
1706
|
+
if (node.type.name === NOTE && node.attrs.label === label) {
|
|
1707
|
+
found = {
|
|
1708
|
+
node,
|
|
1709
|
+
position
|
|
1710
|
+
};
|
|
1711
|
+
return false;
|
|
1712
|
+
}
|
|
1713
|
+
});
|
|
1714
|
+
return found;
|
|
1715
|
+
}
|
|
1716
|
+
function mapReferences(node, change) {
|
|
1717
|
+
if (node.type.name === REFERENCE) return change(node);
|
|
1718
|
+
if (node.isLeaf) return node;
|
|
1719
|
+
const children = [];
|
|
1720
|
+
node.content.forEach((child) => children.push(mapReferences(child, change)));
|
|
1721
|
+
return node.copy(Fragment$1.from(children));
|
|
1722
|
+
}
|
|
1723
|
+
function noteAt(doc, position) {
|
|
1724
|
+
const $position = doc.resolve(position);
|
|
1725
|
+
for (let depth = $position.depth; depth > 0; depth--) {
|
|
1726
|
+
const node = $position.node(depth);
|
|
1727
|
+
if (node.type.name === NOTE) return {
|
|
1728
|
+
node,
|
|
1729
|
+
start: $position.before(depth)
|
|
1730
|
+
};
|
|
1731
|
+
}
|
|
1732
|
+
return null;
|
|
1733
|
+
}
|
|
1734
|
+
/**
|
|
1735
|
+
* Keeps footnotes on Looma Markdown's rule, so the saved HTML is the HTML Looma Markdown renders for
|
|
1736
|
+
* the same document. Notes are numbered by first reference, in the text and then in the notes, and
|
|
1737
|
+
* every reference carries its note's number and its place among that note's references. The notes
|
|
1738
|
+
* live in one `loomaFootnotes` section at the end of the document, in number order. A note no
|
|
1739
|
+
* reference points to leaves the document; a reference with no note gets one back, the note it last
|
|
1740
|
+
* had in this editor (so cutting a reference and pasting it keeps its note) or an empty one.
|
|
1741
|
+
* @invariant Changing nothing but text inside a note never rebuilds the section.
|
|
1742
|
+
*/
|
|
1743
|
+
function footnoteTransaction(state, known) {
|
|
1744
|
+
const { doc, schema } = state;
|
|
1745
|
+
const sections = [];
|
|
1746
|
+
const notes = /* @__PURE__ */ new Map();
|
|
1747
|
+
const body = [];
|
|
1748
|
+
doc.descendants((node, position) => {
|
|
1749
|
+
if (node.type.name === NOTES) {
|
|
1750
|
+
sections.push({
|
|
1751
|
+
node,
|
|
1752
|
+
position
|
|
1753
|
+
});
|
|
1754
|
+
node.forEach((note) => {
|
|
1755
|
+
if (!notes.has(note.attrs.label)) notes.set(note.attrs.label, note);
|
|
1756
|
+
});
|
|
1757
|
+
return false;
|
|
1758
|
+
}
|
|
1759
|
+
if (node.type.name === REFERENCE) body.push({
|
|
1760
|
+
node,
|
|
1761
|
+
position
|
|
1762
|
+
});
|
|
1763
|
+
});
|
|
1764
|
+
if (!sections.length && !body.length) return null;
|
|
1765
|
+
const order = [];
|
|
1766
|
+
const counts = /* @__PURE__ */ new Map();
|
|
1767
|
+
const numbered = (reference) => {
|
|
1768
|
+
const label = String(reference.attrs.label);
|
|
1769
|
+
if (!counts.has(label)) order.push(label);
|
|
1770
|
+
counts.set(label, (counts.get(label) ?? 0) + 1);
|
|
1771
|
+
const attrs = {
|
|
1772
|
+
...reference.attrs,
|
|
1773
|
+
number: order.indexOf(label) + 1,
|
|
1774
|
+
occurrence: counts.get(label)
|
|
1775
|
+
};
|
|
1776
|
+
return attrs.number === reference.attrs.number && attrs.occurrence === reference.attrs.occurrence ? reference : reference.type.create(attrs, null, reference.marks);
|
|
1777
|
+
};
|
|
1778
|
+
const transaction = state.tr;
|
|
1779
|
+
for (const { node, position } of body) {
|
|
1780
|
+
const next = numbered(node);
|
|
1781
|
+
if (next !== node) transaction.setNodeMarkup(position, void 0, next.attrs);
|
|
1782
|
+
}
|
|
1783
|
+
const built = [];
|
|
1784
|
+
for (let index = 0; index < order.length; index++) {
|
|
1785
|
+
const label = order[index];
|
|
1786
|
+
const note = notes.get(label) ?? known.get(label) ?? schema.nodes[NOTE].create({ label }, schema.nodes.paragraph.create());
|
|
1787
|
+
built.push(mapReferences(note, numbered));
|
|
1788
|
+
}
|
|
1789
|
+
const wanted = built.map((note) => note.attrs.count === counts.get(note.attrs.label) ? note : note.type.create({
|
|
1790
|
+
...note.attrs,
|
|
1791
|
+
count: counts.get(note.attrs.label)
|
|
1792
|
+
}, note.content));
|
|
1793
|
+
for (const note of [...notes.values(), ...wanted]) known.set(note.attrs.label, note);
|
|
1794
|
+
const section = wanted.length ? schema.nodes[NOTES].create(null, wanted) : null;
|
|
1795
|
+
const last = doc.lastChild?.type.name === NOTES ? {
|
|
1796
|
+
node: doc.lastChild,
|
|
1797
|
+
position: doc.content.size - doc.lastChild.nodeSize
|
|
1798
|
+
} : null;
|
|
1799
|
+
if (!(section && last && sections.length === 1 && last.node.eq(section)) && (sections.length || section)) {
|
|
1800
|
+
const { selection } = state;
|
|
1801
|
+
const inside = noteAt(doc, selection.from);
|
|
1802
|
+
const keep = inside && selection.to <= inside.start + inside.node.nodeSize ? {
|
|
1803
|
+
label: inside.node.attrs.label,
|
|
1804
|
+
start: inside.start
|
|
1805
|
+
} : null;
|
|
1806
|
+
for (const { node, position } of [...sections].reverse()) if (node !== last?.node) transaction.delete(position, position + node.nodeSize);
|
|
1807
|
+
if (last) {
|
|
1808
|
+
const position = transaction.mapping.map(last.position);
|
|
1809
|
+
if (section) transaction.replaceWith(position, position + last.node.nodeSize, section);
|
|
1810
|
+
else transaction.delete(position, position + last.node.nodeSize);
|
|
1811
|
+
} else if (section) transaction.insert(transaction.doc.content.size, section);
|
|
1812
|
+
const moved = keep && findLoomaFootnote(transaction.doc, keep.label);
|
|
1813
|
+
if (keep && moved) {
|
|
1814
|
+
const json = selection.toJSON();
|
|
1815
|
+
json.anchor += moved.position - keep.start;
|
|
1816
|
+
if (json.head !== void 0) json.head += moved.position - keep.start;
|
|
1817
|
+
try {
|
|
1818
|
+
transaction.setSelection(Selection.fromJSON(transaction.doc, json));
|
|
1819
|
+
} catch {}
|
|
1820
|
+
}
|
|
1821
|
+
}
|
|
1822
|
+
return transaction.docChanged ? transaction : null;
|
|
1823
|
+
}
|
|
1824
|
+
function appendBackLinks(item, label, number, count) {
|
|
1825
|
+
const document = item.ownerDocument;
|
|
1826
|
+
let paragraph = item.lastElementChild;
|
|
1827
|
+
if (paragraph?.nodeName !== "P") item.append(paragraph = document.createElement("p"));
|
|
1828
|
+
for (let occurrence = 1; occurrence <= count; occurrence++) {
|
|
1829
|
+
const link = document.createElement("a");
|
|
1830
|
+
link.setAttribute("href", `#fnref:${label}${occurrence > 1 ? `:${occurrence}` : ""}`);
|
|
1831
|
+
link.setAttribute("data-footnote-backref", "");
|
|
1832
|
+
link.setAttribute("aria-label", `Back to reference ${number}${occurrence > 1 ? `-${occurrence}` : ""}`);
|
|
1833
|
+
link.append("↩");
|
|
1834
|
+
if (occurrence > 1) link.append(Object.assign(document.createElement("sup"), { textContent: String(occurrence) }));
|
|
1835
|
+
paragraph.append(" ", link);
|
|
1836
|
+
}
|
|
1837
|
+
}
|
|
1838
|
+
var FootnoteSerializer = class extends DOMSerializer {
|
|
1839
|
+
serializeFragment(fragment, options = {}, target) {
|
|
1840
|
+
const dom = super.serializeFragment(fragment, options, target);
|
|
1841
|
+
fragment.forEach((node, _offset, index) => {
|
|
1842
|
+
if (node.type.name === NOTE) appendBackLinks(dom.childNodes[index], String(node.attrs.label), index + 1, Number(node.attrs.count) || 1);
|
|
1843
|
+
});
|
|
1844
|
+
return dom;
|
|
1845
|
+
}
|
|
1846
|
+
};
|
|
1847
|
+
function installSerializer(schema) {
|
|
1848
|
+
if (!(schema.cached.domSerializer instanceof FootnoteSerializer)) schema.cached.domSerializer = new FootnoteSerializer(DOMSerializer.nodesFromSchema(schema), DOMSerializer.marksFromSchema(schema));
|
|
1849
|
+
}
|
|
1850
|
+
Node$1.create({
|
|
1851
|
+
name: REFERENCE,
|
|
1852
|
+
group: "inline",
|
|
1853
|
+
inline: true,
|
|
1854
|
+
atom: true,
|
|
1855
|
+
selectable: true,
|
|
1856
|
+
addAttributes() {
|
|
1857
|
+
const link = (element) => element.querySelector(":scope > a[data-footnote-ref]");
|
|
1858
|
+
const label = (element) => labelFrom(link(element)?.getAttribute("href"), "fn:") ?? "";
|
|
1859
|
+
return {
|
|
1860
|
+
label: {
|
|
1861
|
+
default: "",
|
|
1862
|
+
parseHTML: label,
|
|
1863
|
+
renderHTML: () => ({})
|
|
1864
|
+
},
|
|
1865
|
+
number: {
|
|
1866
|
+
default: null,
|
|
1867
|
+
parseHTML: (element) => Number(element.textContent) || null,
|
|
1868
|
+
renderHTML: () => ({})
|
|
1869
|
+
},
|
|
1870
|
+
occurrence: {
|
|
1871
|
+
default: 1,
|
|
1872
|
+
parseHTML: (element) => Number(link(element)?.id.slice(`fnref:${label(element)}:`.length)) || 1,
|
|
1873
|
+
renderHTML: () => ({})
|
|
1874
|
+
}
|
|
1875
|
+
};
|
|
1876
|
+
},
|
|
1877
|
+
parseHTML() {
|
|
1878
|
+
return [{
|
|
1879
|
+
tag: "sup",
|
|
1880
|
+
priority: 1100,
|
|
1881
|
+
getAttrs: (element) => element.querySelector(":scope > a[data-footnote-ref]") ? null : false
|
|
1882
|
+
}];
|
|
1883
|
+
},
|
|
1884
|
+
renderHTML({ node }) {
|
|
1885
|
+
const { label, number, occurrence } = node.attrs;
|
|
1886
|
+
return ["sup", [
|
|
1887
|
+
"a",
|
|
1888
|
+
{
|
|
1889
|
+
href: `#fn:${label}`,
|
|
1890
|
+
id: `fnref:${label}${occurrence > 1 ? `:${occurrence}` : ""}`,
|
|
1891
|
+
"data-footnote-ref": "",
|
|
1892
|
+
"aria-describedby": "footnote:label"
|
|
1893
|
+
},
|
|
1894
|
+
String(number ?? label)
|
|
1895
|
+
]];
|
|
1896
|
+
},
|
|
1897
|
+
renderText({ node }) {
|
|
1898
|
+
return `[^${node.attrs.label}]`;
|
|
1899
|
+
},
|
|
1900
|
+
addInputRules() {
|
|
1901
|
+
return [new InputRule({
|
|
1902
|
+
find: /\[\^([^\s\]]+)\]$/,
|
|
1903
|
+
handler: ({ state, range, match }) => {
|
|
1904
|
+
state.tr.replaceWith(range.from, range.to, this.type.create({ label: match[1] }));
|
|
1905
|
+
}
|
|
1906
|
+
})];
|
|
1907
|
+
},
|
|
1908
|
+
addPasteRules() {
|
|
1909
|
+
return [new PasteRule({
|
|
1910
|
+
find: /\[\^([^\s\]]+)\]/g,
|
|
1911
|
+
handler: ({ state, range, match }) => {
|
|
1912
|
+
state.tr.replaceWith(range.from, range.to, this.type.create({ label: match[1] }));
|
|
1913
|
+
}
|
|
1914
|
+
})];
|
|
1915
|
+
},
|
|
1916
|
+
addNodeView() {
|
|
1917
|
+
return ({ node, editor }) => {
|
|
1918
|
+
const dom = document.createElement("sup");
|
|
1919
|
+
dom.dataset.loomaFootnoteRef = "";
|
|
1920
|
+
dom.contentEditable = "false";
|
|
1921
|
+
dom.setAttribute("role", "button");
|
|
1922
|
+
dom.setAttribute("aria-haspopup", "dialog");
|
|
1923
|
+
dom.setAttribute("aria-disabled", String(!editor.isEditable));
|
|
1924
|
+
dom.tabIndex = 0;
|
|
1925
|
+
const number = dom.appendChild(document.createElement("a"));
|
|
1926
|
+
const update = (next) => {
|
|
1927
|
+
if (next.type !== node.type) return false;
|
|
1928
|
+
const shown = String(next.attrs.number ?? next.attrs.label);
|
|
1929
|
+
dom.dataset.label = String(next.attrs.label);
|
|
1930
|
+
if (number.textContent !== shown) number.textContent = shown;
|
|
1931
|
+
dom.setAttribute("aria-label", `Footnote ${shown}`);
|
|
1932
|
+
return true;
|
|
1933
|
+
};
|
|
1934
|
+
update(node);
|
|
1935
|
+
return {
|
|
1936
|
+
dom,
|
|
1937
|
+
update,
|
|
1938
|
+
stopEvent: (event) => event.type === "click" || event.type === "keydown"
|
|
1939
|
+
};
|
|
1940
|
+
};
|
|
1941
|
+
}
|
|
1942
|
+
});
|
|
1943
|
+
Node$1.create({
|
|
1944
|
+
name: NOTES,
|
|
1945
|
+
group: "block",
|
|
1946
|
+
content: `${NOTE}+`,
|
|
1947
|
+
isolating: true,
|
|
1948
|
+
parseHTML() {
|
|
1949
|
+
return [{
|
|
1950
|
+
tag: "section[data-footnotes]",
|
|
1951
|
+
contentElement: "ol"
|
|
1952
|
+
}];
|
|
1953
|
+
},
|
|
1954
|
+
renderHTML() {
|
|
1955
|
+
return [
|
|
1956
|
+
"section",
|
|
1957
|
+
{
|
|
1958
|
+
"data-footnotes": "",
|
|
1959
|
+
class: "footnotes"
|
|
1960
|
+
},
|
|
1961
|
+
[
|
|
1962
|
+
"h2",
|
|
1963
|
+
{
|
|
1964
|
+
id: "footnote:label",
|
|
1965
|
+
class: "sr-only"
|
|
1966
|
+
},
|
|
1967
|
+
"Footnotes"
|
|
1968
|
+
],
|
|
1969
|
+
["ol", 0]
|
|
1970
|
+
];
|
|
1971
|
+
},
|
|
1972
|
+
onBeforeCreate() {
|
|
1973
|
+
installSerializer(this.editor.schema);
|
|
1974
|
+
},
|
|
1975
|
+
onCreate() {
|
|
1976
|
+
const transaction = footnoteTransaction(this.editor.state, this.storage.known);
|
|
1977
|
+
if (transaction) this.editor.view.dispatch(transaction.setMeta("addToHistory", false));
|
|
1978
|
+
},
|
|
1979
|
+
addStorage: () => ({ known: /* @__PURE__ */ new Map() }),
|
|
1980
|
+
addProseMirrorPlugins() {
|
|
1981
|
+
return [new Plugin({
|
|
1982
|
+
appendTransaction: (transactions, _oldState, state) => transactions.some((transaction) => transaction.docChanged) ? footnoteTransaction(state, this.storage.known) : null,
|
|
1983
|
+
props: { transformPasted: (slice) => {
|
|
1984
|
+
const kept = [];
|
|
1985
|
+
slice.content.forEach((node) => {
|
|
1986
|
+
if (node.type.name === NOTES) node.forEach((note) => {
|
|
1987
|
+
this.storage.known.set(note.attrs.label, note);
|
|
1988
|
+
});
|
|
1989
|
+
else kept.push(node);
|
|
1990
|
+
});
|
|
1991
|
+
if (!kept.length || kept.length === slice.content.childCount) return slice;
|
|
1992
|
+
const content = Fragment$1.from(kept);
|
|
1993
|
+
const open = Slice.maxOpen(content);
|
|
1994
|
+
return new Slice(content, kept[0] === slice.content.firstChild ? slice.openStart : open.openStart, kept.at(-1) === slice.content.lastChild ? slice.openEnd : open.openEnd);
|
|
1995
|
+
} }
|
|
1996
|
+
})];
|
|
1997
|
+
},
|
|
1998
|
+
addCommands() {
|
|
1999
|
+
return {
|
|
2000
|
+
insertLoomaFootnote: (label) => ({ state, tr, dispatch }) => {
|
|
2001
|
+
const name = label ?? (() => {
|
|
2002
|
+
const used = usedLabels(state.doc);
|
|
2003
|
+
let next = 1;
|
|
2004
|
+
while (used.has(String(next))) next++;
|
|
2005
|
+
return String(next);
|
|
2006
|
+
})();
|
|
2007
|
+
const { $from, $to } = state.selection;
|
|
2008
|
+
if (!isLabel(name) || !$from.parent.canReplaceWith($from.index(), $to.index(), state.schema.nodes[REFERENCE])) return false;
|
|
2009
|
+
if (!dispatch) return true;
|
|
2010
|
+
tr.replaceSelectionWith(state.schema.nodes[REFERENCE].create({ label: name }));
|
|
2011
|
+
if (!findLoomaFootnote(tr.doc, name)) {
|
|
2012
|
+
const note = state.schema.nodes[NOTE].create({ label: name }, state.schema.nodes.paragraph.create());
|
|
2013
|
+
if (tr.doc.lastChild?.type.name === NOTES) tr.insert(tr.doc.content.size - 1, note);
|
|
2014
|
+
else tr.insert(tr.doc.content.size, state.schema.nodes[NOTES].create(null, note));
|
|
2015
|
+
tr.setSelection(TextSelection.create(tr.doc, tr.doc.content.size - 3));
|
|
2016
|
+
}
|
|
2017
|
+
tr.scrollIntoView();
|
|
2018
|
+
return true;
|
|
2019
|
+
},
|
|
2020
|
+
renameLoomaFootnote: (from, to) => ({ state, tr, dispatch }) => {
|
|
2021
|
+
if (!isLabel(to) || usedLabels(state.doc).has(to) || !findLoomaFootnote(state.doc, from)) return false;
|
|
2022
|
+
if (dispatch) state.doc.descendants((node, position) => {
|
|
2023
|
+
if ((node.type.name === REFERENCE || node.type.name === NOTE) && node.attrs.label === from) tr.setNodeMarkup(position, void 0, {
|
|
2024
|
+
...node.attrs,
|
|
2025
|
+
label: to
|
|
2026
|
+
});
|
|
2027
|
+
});
|
|
2028
|
+
return true;
|
|
2029
|
+
},
|
|
2030
|
+
goToLoomaFootnote: () => ({ state, tr, dispatch }) => {
|
|
2031
|
+
const { selection } = state;
|
|
2032
|
+
const reference = selection instanceof NodeSelection ? selection.node : selection.empty ? selection.$from.nodeBefore : null;
|
|
2033
|
+
if (reference?.type.name === REFERENCE) {
|
|
2034
|
+
const note = findLoomaFootnote(state.doc, reference.attrs.label);
|
|
2035
|
+
if (!note) return false;
|
|
2036
|
+
if (dispatch) tr.setSelection(Selection.near(state.doc.resolve(note.position + note.node.nodeSize - 1), -1)).scrollIntoView();
|
|
2037
|
+
return true;
|
|
2038
|
+
}
|
|
2039
|
+
const note = noteAt(state.doc, selection.from);
|
|
2040
|
+
let first = -1;
|
|
2041
|
+
if (note) state.doc.descendants((node, position) => {
|
|
2042
|
+
if (first >= 0) return false;
|
|
2043
|
+
if (node.type.name === REFERENCE && node.attrs.label === note.node.attrs.label) first = position;
|
|
2044
|
+
});
|
|
2045
|
+
if (first < 0) return false;
|
|
2046
|
+
if (dispatch) tr.setSelection(TextSelection.create(state.doc, first + 1)).scrollIntoView();
|
|
2047
|
+
return true;
|
|
2048
|
+
}
|
|
2049
|
+
};
|
|
2050
|
+
},
|
|
2051
|
+
addKeyboardShortcuts() {
|
|
2052
|
+
return {
|
|
2053
|
+
"Mod-Alt-f": () => this.editor.commands.insertLoomaFootnote(),
|
|
2054
|
+
"Mod-Alt-n": () => this.editor.commands.goToLoomaFootnote()
|
|
2055
|
+
};
|
|
2056
|
+
}
|
|
2057
|
+
});
|
|
2058
|
+
Node$1.create({
|
|
2059
|
+
name: NOTE,
|
|
2060
|
+
content: "block+",
|
|
2061
|
+
defining: true,
|
|
2062
|
+
addAttributes() {
|
|
2063
|
+
return {
|
|
2064
|
+
label: {
|
|
2065
|
+
default: "",
|
|
2066
|
+
parseHTML: (element) => labelFrom(`#${element.id}`, "fn:") ?? "",
|
|
2067
|
+
renderHTML: () => ({})
|
|
2068
|
+
},
|
|
2069
|
+
count: {
|
|
2070
|
+
default: 1,
|
|
2071
|
+
parseHTML: (element) => element.querySelectorAll("a[data-footnote-backref]").length || 1,
|
|
2072
|
+
renderHTML: () => ({})
|
|
2073
|
+
}
|
|
2074
|
+
};
|
|
2075
|
+
},
|
|
2076
|
+
parseHTML() {
|
|
2077
|
+
return [{
|
|
2078
|
+
tag: "li",
|
|
2079
|
+
priority: 1100,
|
|
2080
|
+
context: `${NOTES}/`
|
|
2081
|
+
}, {
|
|
2082
|
+
tag: "a[data-footnote-backref]",
|
|
2083
|
+
priority: 1100,
|
|
2084
|
+
ignore: true
|
|
2085
|
+
}];
|
|
2086
|
+
},
|
|
2087
|
+
renderHTML({ node }) {
|
|
2088
|
+
return [
|
|
2089
|
+
"li",
|
|
2090
|
+
{ id: `fn:${node.attrs.label}` },
|
|
2091
|
+
0
|
|
2092
|
+
];
|
|
2093
|
+
}
|
|
2094
|
+
});
|
|
2095
|
+
//#endregion
|
|
2096
|
+
//#region src/editor/footnote-editing.ts
|
|
2097
|
+
var LOOMA_FOOTNOTE_EDITING_IDLE = Object.freeze({
|
|
2098
|
+
open: false,
|
|
2099
|
+
label: "",
|
|
2100
|
+
note: "",
|
|
2101
|
+
editable: false,
|
|
2102
|
+
error: ""
|
|
2103
|
+
});
|
|
2104
|
+
var plain = (note) => {
|
|
2105
|
+
const paragraph = note.firstChild;
|
|
2106
|
+
if (note.childCount !== 1 || paragraph?.type.name !== "paragraph") return false;
|
|
2107
|
+
let text = true;
|
|
2108
|
+
paragraph.forEach((child) => {
|
|
2109
|
+
if (!child.isText || child.marks.length) text = false;
|
|
2110
|
+
});
|
|
2111
|
+
return text;
|
|
2112
|
+
};
|
|
2113
|
+
function createFootnoteEditing(options) {
|
|
2114
|
+
const { editor } = options;
|
|
2115
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
2116
|
+
let state = LOOMA_FOOTNOTE_EDITING_IDLE;
|
|
2117
|
+
let element = null;
|
|
2118
|
+
const set = (next) => {
|
|
2119
|
+
state = next;
|
|
2120
|
+
listeners.forEach((listener) => listener());
|
|
2121
|
+
};
|
|
2122
|
+
const close = () => {
|
|
2123
|
+
element = null;
|
|
2124
|
+
if (state.open) set({
|
|
2125
|
+
...state,
|
|
2126
|
+
open: false
|
|
2127
|
+
});
|
|
2128
|
+
};
|
|
2129
|
+
const note = () => state.open && !editor.isDestroyed && element?.isConnected ? findLoomaFootnote(editor.state.doc, state.label) : null;
|
|
2130
|
+
return {
|
|
2131
|
+
get state() {
|
|
2132
|
+
return state;
|
|
2133
|
+
},
|
|
2134
|
+
get element() {
|
|
2135
|
+
return element;
|
|
2136
|
+
},
|
|
2137
|
+
subscribe(listener) {
|
|
2138
|
+
listeners.add(listener);
|
|
2139
|
+
return () => {
|
|
2140
|
+
listeners.delete(listener);
|
|
2141
|
+
};
|
|
2142
|
+
},
|
|
2143
|
+
open(position) {
|
|
2144
|
+
if (!options.isEditable() || editor.isDestroyed) return false;
|
|
2145
|
+
const node = editor.state.doc.nodeAt(position);
|
|
2146
|
+
const dom = editor.view.nodeDOM(position);
|
|
2147
|
+
if (node?.type.name !== "loomaFootnoteReference" || !(dom instanceof HTMLElement)) return false;
|
|
2148
|
+
const label = String(node.attrs.label);
|
|
2149
|
+
const found = findLoomaFootnote(editor.state.doc, label);
|
|
2150
|
+
if (!found) return false;
|
|
2151
|
+
element = dom;
|
|
2152
|
+
set({
|
|
2153
|
+
open: true,
|
|
2154
|
+
label,
|
|
2155
|
+
note: found.node.textBetween(0, found.node.content.size, "\n"),
|
|
2156
|
+
editable: plain(found.node),
|
|
2157
|
+
error: ""
|
|
2158
|
+
});
|
|
2159
|
+
return true;
|
|
2160
|
+
},
|
|
2161
|
+
setNote(text) {
|
|
2162
|
+
const found = note();
|
|
2163
|
+
if (!found) return close();
|
|
2164
|
+
if (!state.editable) return;
|
|
2165
|
+
const value = text.replace(/\s*\n\s*/g, " ");
|
|
2166
|
+
const start = found.position + 2;
|
|
2167
|
+
const end = start + found.node.firstChild.content.size;
|
|
2168
|
+
editor.view.dispatch(editor.state.tr.replaceWith(start, end, value ? editor.schema.text(value) : Fragment$1.empty));
|
|
2169
|
+
set({
|
|
2170
|
+
...state,
|
|
2171
|
+
note: value
|
|
2172
|
+
});
|
|
2173
|
+
},
|
|
2174
|
+
rename(label) {
|
|
2175
|
+
if (!note()) return close();
|
|
2176
|
+
if (label === state.label) return state.error ? set({
|
|
2177
|
+
...state,
|
|
2178
|
+
error: ""
|
|
2179
|
+
}) : void 0;
|
|
2180
|
+
if (!LOOMA_FOOTNOTE_LABEL.test(label)) return set({
|
|
2181
|
+
...state,
|
|
2182
|
+
error: "A label is one word, without ]."
|
|
2183
|
+
});
|
|
2184
|
+
if (!editor.commands.renameLoomaFootnote(state.label, label)) return set({
|
|
2185
|
+
...state,
|
|
2186
|
+
error: "Another footnote uses this label."
|
|
2187
|
+
});
|
|
2188
|
+
set({
|
|
2189
|
+
...state,
|
|
2190
|
+
label,
|
|
2191
|
+
error: ""
|
|
2192
|
+
});
|
|
2193
|
+
},
|
|
2194
|
+
goToNote() {
|
|
2195
|
+
const reference = element;
|
|
2196
|
+
close();
|
|
2197
|
+
if (!reference?.isConnected || editor.isDestroyed) return;
|
|
2198
|
+
editor.chain().focus().setNodeSelection(editor.view.posAtDOM(reference, 0)).goToLoomaFootnote().run();
|
|
2199
|
+
},
|
|
2200
|
+
close
|
|
2201
|
+
};
|
|
2202
|
+
}
|
|
2203
|
+
//#endregion
|
|
1669
2204
|
//#region src/editor/host-actions.ts
|
|
1670
2205
|
/** Characters of context on each side of a selected passage. */
|
|
1671
2206
|
var CONTEXT = 48;
|
|
@@ -2691,6 +3226,7 @@ function setCodeBlockLanguage(editor, pos, value, names) {
|
|
|
2691
3226
|
}
|
|
2692
3227
|
//#endregion
|
|
2693
3228
|
//#region components/ui-button/ui-button.js
|
|
3229
|
+
var ui_button_exports = /* @__PURE__ */ __exportAll({ connect: () => connect$11 });
|
|
2694
3230
|
function connect$11(host) {
|
|
2695
3231
|
const onClick = (event) => {
|
|
2696
3232
|
if (!host.props.loading.value && !host.props.pending.value) return;
|
|
@@ -2700,10 +3236,6 @@ function connect$11(host) {
|
|
|
2700
3236
|
host.element.addEventListener("click", onClick, true);
|
|
2701
3237
|
return () => host.element.removeEventListener("click", onClick, true);
|
|
2702
3238
|
}
|
|
2703
|
-
/** Keep DOM setup and its cleanup tied to each connection, including reconnects. */
|
|
2704
|
-
function controller$11(host) {
|
|
2705
|
-
host.on("connect", () => connect$11(host));
|
|
2706
|
-
}
|
|
2707
3239
|
//#endregion
|
|
2708
3240
|
//#region vanilla/UiButton.js
|
|
2709
3241
|
var T0$16 = [
|
|
@@ -2859,6 +3391,7 @@ var S$18 = {
|
|
|
2859
3391
|
t: [],
|
|
2860
3392
|
f: import.meta.url,
|
|
2861
3393
|
g: "ui-button",
|
|
3394
|
+
a: (host, I) => C$11(host, I),
|
|
2862
3395
|
b: generatedInputs
|
|
2863
3396
|
};
|
|
2864
3397
|
var A$3 = [
|
|
@@ -3130,7 +3663,7 @@ var D$18 = {
|
|
|
3130
3663
|
}
|
|
3131
3664
|
}
|
|
3132
3665
|
};
|
|
3133
|
-
var C$11 = (host) =>
|
|
3666
|
+
var C$11 = (host) => activateModule(ui_button_exports, host);
|
|
3134
3667
|
function createUiButton(options = {}, html) {
|
|
3135
3668
|
const { attributes = {}, children = [], slots = {}, ...componentProps } = options;
|
|
3136
3669
|
const v = [
|
|
@@ -3828,7 +4361,7 @@ function createUiButton(options = {}, html) {
|
|
|
3828
4361
|
};
|
|
3829
4362
|
const I = { B };
|
|
3830
4363
|
const J = project(I, children, slots);
|
|
3831
|
-
attachGeneratedController(element, S$18, v, p,
|
|
4364
|
+
attachGeneratedController(element, S$18, v, p, void 0, void 0, I);
|
|
3832
4365
|
manageProps(I);
|
|
3833
4366
|
return element;
|
|
3834
4367
|
}
|
|
@@ -4456,6 +4989,7 @@ function createIdResolver(document, onLate) {
|
|
|
4456
4989
|
}
|
|
4457
4990
|
//#endregion
|
|
4458
4991
|
//#region components/ui-affordance-scope/ui-affordance-scope.js
|
|
4992
|
+
var ui_affordance_scope_exports = /* @__PURE__ */ __exportAll({ connect: () => connect$10 });
|
|
4459
4993
|
function distance(point, rect) {
|
|
4460
4994
|
const dx = Math.max(rect.left - point.x, 0, point.x - rect.right);
|
|
4461
4995
|
const dy = Math.max(rect.top - point.y, 0, point.y - rect.bottom);
|
|
@@ -4538,10 +5072,6 @@ function connect$10(host) {
|
|
|
4538
5072
|
clear();
|
|
4539
5073
|
};
|
|
4540
5074
|
}
|
|
4541
|
-
/** Keep DOM setup and its cleanup tied to each connection, including reconnects. */
|
|
4542
|
-
function controller$10(host) {
|
|
4543
|
-
host.on("connect", () => connect$10(host));
|
|
4544
|
-
}
|
|
4545
5075
|
//#endregion
|
|
4546
5076
|
//#region vanilla/UiAffordanceScope.js
|
|
4547
5077
|
var T0$15 = [
|
|
@@ -4557,6 +5087,7 @@ var S$17 = {
|
|
|
4557
5087
|
t: ["b"],
|
|
4558
5088
|
f: import.meta.url,
|
|
4559
5089
|
g: "ui-affordance-scope",
|
|
5090
|
+
a: (host, I) => C$10(host, I),
|
|
4560
5091
|
b: generatedInputs,
|
|
4561
5092
|
i: [false]
|
|
4562
5093
|
};
|
|
@@ -4582,7 +5113,7 @@ var D$17 = {
|
|
|
4582
5113
|
}
|
|
4583
5114
|
}
|
|
4584
5115
|
};
|
|
4585
|
-
var C$10 = (host) =>
|
|
5116
|
+
var C$10 = (host) => activateModule(ui_affordance_scope_exports, host);
|
|
4586
5117
|
function createUiAffordanceScope(options = {}, html) {
|
|
4587
5118
|
const { attributes = {}, children = [], slots = {}, ...componentProps } = options;
|
|
4588
5119
|
const element = document.createElement("span");
|
|
@@ -4634,7 +5165,7 @@ function createUiAffordanceScope(options = {}, html) {
|
|
|
4634
5165
|
attachGeneratedController(element, S$17, v, (c, d) => {
|
|
4635
5166
|
((c, d) => p0(R, c, d))(c, d);
|
|
4636
5167
|
for (const f of I.R) f(c, d);
|
|
4637
|
-
},
|
|
5168
|
+
}, void 0, void 0, I);
|
|
4638
5169
|
manageProps(I);
|
|
4639
5170
|
return element;
|
|
4640
5171
|
}
|
|
@@ -4856,6 +5387,7 @@ function warnOnce(warned, problems, element) {
|
|
|
4856
5387
|
}
|
|
4857
5388
|
//#endregion
|
|
4858
5389
|
//#region components/ui-form-field/ui-form-field.js
|
|
5390
|
+
var ui_form_field_exports = /* @__PURE__ */ __exportAll({ connect: () => connect$9 });
|
|
4859
5391
|
var nextFieldId = 0;
|
|
4860
5392
|
function id(prefix) {
|
|
4861
5393
|
nextFieldId += 1;
|
|
@@ -4936,10 +5468,6 @@ function connect$9(host) {
|
|
|
4936
5468
|
removeOwned(activeInput);
|
|
4937
5469
|
};
|
|
4938
5470
|
}
|
|
4939
|
-
/** Keep DOM setup and its cleanup tied to each connection, including reconnects. */
|
|
4940
|
-
function controller$9(host) {
|
|
4941
|
-
host.on("connect", () => connect$9(host));
|
|
4942
|
-
}
|
|
4943
5471
|
//#endregion
|
|
4944
5472
|
//#region vanilla/UiFormField.js
|
|
4945
5473
|
var T0$13 = [
|
|
@@ -4991,6 +5519,7 @@ var S$15 = {
|
|
|
4991
5519
|
t: [],
|
|
4992
5520
|
f: import.meta.url,
|
|
4993
5521
|
g: "ui-form-field",
|
|
5522
|
+
a: (host, I) => C$9(host, I),
|
|
4994
5523
|
b: generatedInputs
|
|
4995
5524
|
};
|
|
4996
5525
|
var D$15 = {
|
|
@@ -5022,7 +5551,7 @@ var D$15 = {
|
|
|
5022
5551
|
}
|
|
5023
5552
|
}
|
|
5024
5553
|
};
|
|
5025
|
-
var C$9 = (host) =>
|
|
5554
|
+
var C$9 = (host) => activateModule(ui_form_field_exports, host);
|
|
5026
5555
|
function createUiFormField(options = {}, html) {
|
|
5027
5556
|
const { attributes = {}, children = [], slots = {}, ...componentProps } = options;
|
|
5028
5557
|
const element = document.createElement("div");
|
|
@@ -5152,7 +5681,7 @@ function createUiFormField(options = {}, html) {
|
|
|
5152
5681
|
};
|
|
5153
5682
|
const I = { B };
|
|
5154
5683
|
const J = project(I, children, slots);
|
|
5155
|
-
attachGeneratedController(element, S$15, v, ((c, d) => p0(R, c, d)),
|
|
5684
|
+
attachGeneratedController(element, S$15, v, ((c, d) => p0(R, c, d)), void 0, void 0, I);
|
|
5156
5685
|
manageProps(I);
|
|
5157
5686
|
return element;
|
|
5158
5687
|
}
|
|
@@ -6206,6 +6735,20 @@ function createUiIcon(options = {}, html) {
|
|
|
6206
6735
|
"y2": "12"
|
|
6207
6736
|
}
|
|
6208
6737
|
],
|
|
6738
|
+
"superscript": [
|
|
6739
|
+
{
|
|
6740
|
+
"tag": "path",
|
|
6741
|
+
"d": "m4 19 8-8"
|
|
6742
|
+
},
|
|
6743
|
+
{
|
|
6744
|
+
"tag": "path",
|
|
6745
|
+
"d": "m12 19-8-8"
|
|
6746
|
+
},
|
|
6747
|
+
{
|
|
6748
|
+
"tag": "path",
|
|
6749
|
+
"d": "M20 12h-4c0-1.5.442-2 1.5-2.5S20 8.334 20 7.002c0-.472-.17-.93-.484-1.29a2.105 2.105 0 0 0-2.617-.436c-.42.239-.738.614-.899 1.06"
|
|
6750
|
+
}
|
|
6751
|
+
],
|
|
6209
6752
|
"table": [{
|
|
6210
6753
|
"tag": "path",
|
|
6211
6754
|
"d": "M9 3H5a2 2 0 0 0-2 2v4m6-6h10a2 2 0 0 1 2 2v4M9 3v18m0 0h10a2 2 0 0 0 2-2V9M9 21H5a2 2 0 0 1-2-2V9m0 0h18"
|
|
@@ -6597,6 +7140,7 @@ function createUiIcon(options = {}, html) {
|
|
|
6597
7140
|
defineComponent$1("ui-icon", createUiIcon, ["name", "tone"]);
|
|
6598
7141
|
//#endregion
|
|
6599
7142
|
//#region components/ui-icon-button/ui-icon-button.js
|
|
7143
|
+
var ui_icon_button_exports = /* @__PURE__ */ __exportAll({ connect: () => connect$8 });
|
|
6600
7144
|
function connect$8(host) {
|
|
6601
7145
|
const stop = host.effect(() => {
|
|
6602
7146
|
if (host.props.anticipatory.value) host.element.setAttribute("data-ui-affordance", "button");
|
|
@@ -6613,10 +7157,6 @@ function connect$8(host) {
|
|
|
6613
7157
|
host.element.removeEventListener("click", onClick, true);
|
|
6614
7158
|
};
|
|
6615
7159
|
}
|
|
6616
|
-
/** Keep DOM setup and its cleanup tied to each connection, including reconnects. */
|
|
6617
|
-
function controller$8(host) {
|
|
6618
|
-
host.on("connect", () => connect$8(host));
|
|
6619
|
-
}
|
|
6620
7160
|
//#endregion
|
|
6621
7161
|
//#region vanilla/UiIconButton.js
|
|
6622
7162
|
var T0$11 = [
|
|
@@ -6642,6 +7182,7 @@ var S$13 = {
|
|
|
6642
7182
|
t: [],
|
|
6643
7183
|
f: import.meta.url,
|
|
6644
7184
|
g: "ui-icon-button",
|
|
7185
|
+
a: (host, I) => C$8(host, I),
|
|
6645
7186
|
b: generatedInputs
|
|
6646
7187
|
};
|
|
6647
7188
|
var D$13 = {
|
|
@@ -6755,7 +7296,7 @@ var D$13 = {
|
|
|
6755
7296
|
}
|
|
6756
7297
|
}
|
|
6757
7298
|
};
|
|
6758
|
-
var C$8 = (host) =>
|
|
7299
|
+
var C$8 = (host) => activateModule(ui_icon_button_exports, host);
|
|
6759
7300
|
function createUiIconButton(options = {}, html) {
|
|
6760
7301
|
const { attributes = {}, children = [], slots = {}, ...componentProps } = options;
|
|
6761
7302
|
const element = document.createElement("button");
|
|
@@ -6886,7 +7427,7 @@ function createUiIconButton(options = {}, html) {
|
|
|
6886
7427
|
};
|
|
6887
7428
|
const I = { B };
|
|
6888
7429
|
const J = project(I, children, slots);
|
|
6889
|
-
attachGeneratedController(element, S$13, v, ((c, d) => p0(R, c, d)),
|
|
7430
|
+
attachGeneratedController(element, S$13, v, ((c, d) => p0(R, c, d)), void 0, void 0, I);
|
|
6890
7431
|
manageProps(I);
|
|
6891
7432
|
return element;
|
|
6892
7433
|
}
|
|
@@ -7211,6 +7752,7 @@ function navigateMenu(event, menu) {
|
|
|
7211
7752
|
}
|
|
7212
7753
|
//#endregion
|
|
7213
7754
|
//#region components/ui-menu/ui-menu.js
|
|
7755
|
+
var ui_menu_exports = /* @__PURE__ */ __exportAll({ connect: () => connect$7 });
|
|
7214
7756
|
function triggerFor(event) {
|
|
7215
7757
|
if (event instanceof KeyboardEvent) return "keyboard";
|
|
7216
7758
|
if (event instanceof MouseEvent || event instanceof PointerEvent) return event.detail === 0 ? "keyboard" : "pointer";
|
|
@@ -7378,10 +7920,6 @@ function connect$7(host) {
|
|
|
7378
7920
|
releaseAnchor();
|
|
7379
7921
|
};
|
|
7380
7922
|
}
|
|
7381
|
-
/** Keep DOM setup and its cleanup tied to each connection, including reconnects. */
|
|
7382
|
-
function controller$7(host) {
|
|
7383
|
-
host.on("connect", () => connect$7(host));
|
|
7384
|
-
}
|
|
7385
7923
|
//#endregion
|
|
7386
7924
|
//#region vanilla/UiMenu.js
|
|
7387
7925
|
var T0$9 = [
|
|
@@ -7487,6 +8025,7 @@ var S$11 = {
|
|
|
7487
8025
|
]
|
|
7488
8026
|
},
|
|
7489
8027
|
x: dispatchDeclared,
|
|
8028
|
+
a: (host, I) => C$7(host, I),
|
|
7490
8029
|
b: generatedInputs,
|
|
7491
8030
|
i: [false]
|
|
7492
8031
|
};
|
|
@@ -7553,7 +8092,7 @@ var D$11 = {
|
|
|
7553
8092
|
}
|
|
7554
8093
|
}
|
|
7555
8094
|
};
|
|
7556
|
-
var C$7 = (host) =>
|
|
8095
|
+
var C$7 = (host) => activateModule(ui_menu_exports, host);
|
|
7557
8096
|
function createUiMenu(options = {}, html) {
|
|
7558
8097
|
const { attributes = {}, children = [], slots = {}, ...componentProps } = options;
|
|
7559
8098
|
const element = document.createElement("div");
|
|
@@ -7624,7 +8163,7 @@ function createUiMenu(options = {}, html) {
|
|
|
7624
8163
|
attachGeneratedController(element, S$11, v, (c, d) => {
|
|
7625
8164
|
((c, d) => p0(R, c, d))(c, d);
|
|
7626
8165
|
for (const f of I.R) f(c, d);
|
|
7627
|
-
},
|
|
8166
|
+
}, void 0, void 0, I);
|
|
7628
8167
|
manageProps(I);
|
|
7629
8168
|
return element;
|
|
7630
8169
|
}
|
|
@@ -7639,6 +8178,7 @@ defineComponent$1("ui-menu", createUiMenu, [
|
|
|
7639
8178
|
]);
|
|
7640
8179
|
//#endregion
|
|
7641
8180
|
//#region components/ui-menu-item/ui-menu-item.js
|
|
8181
|
+
var ui_menu_item_exports = /* @__PURE__ */ __exportAll({ connect: () => connect$6 });
|
|
7642
8182
|
function radioScope(item) {
|
|
7643
8183
|
return item.closest("[role=\"group\"]") ?? item.closest("[role=\"menu\"]");
|
|
7644
8184
|
}
|
|
@@ -7692,10 +8232,6 @@ function connect$6(host) {
|
|
|
7692
8232
|
item.removeEventListener("ui-menu-item-clear", onClear);
|
|
7693
8233
|
};
|
|
7694
8234
|
}
|
|
7695
|
-
/** Keep DOM setup and its cleanup tied to each connection, including reconnects. */
|
|
7696
|
-
function controller$6(host) {
|
|
7697
|
-
host.on("connect", () => connect$6(host));
|
|
7698
|
-
}
|
|
7699
8235
|
//#endregion
|
|
7700
8236
|
//#region vanilla/UiMenuItem.js
|
|
7701
8237
|
var T0$8 = [
|
|
@@ -7830,6 +8366,7 @@ var S$10 = {
|
|
|
7830
8366
|
false
|
|
7831
8367
|
] },
|
|
7832
8368
|
x: dispatchDeclared,
|
|
8369
|
+
a: (host, I) => C$6(host, I),
|
|
7833
8370
|
b: generatedInputs,
|
|
7834
8371
|
i: [false]
|
|
7835
8372
|
};
|
|
@@ -7934,7 +8471,7 @@ var D$10 = {
|
|
|
7934
8471
|
}
|
|
7935
8472
|
}
|
|
7936
8473
|
};
|
|
7937
|
-
var C$6 = (host) =>
|
|
8474
|
+
var C$6 = (host) => activateModule(ui_menu_item_exports, host);
|
|
7938
8475
|
function createUiMenuItem(options = {}, html) {
|
|
7939
8476
|
const { attributes = {}, children = [], slots = {}, ...componentProps } = options;
|
|
7940
8477
|
const v = [
|
|
@@ -8224,7 +8761,7 @@ function createUiMenuItem(options = {}, html) {
|
|
|
8224
8761
|
attachGeneratedController(element, S$10, v, (c, d) => {
|
|
8225
8762
|
p(c, d);
|
|
8226
8763
|
for (const f of I.R) f(c, d);
|
|
8227
|
-
},
|
|
8764
|
+
}, void 0, void 0, I);
|
|
8228
8765
|
manageProps(I);
|
|
8229
8766
|
return element;
|
|
8230
8767
|
}
|
|
@@ -8238,6 +8775,7 @@ defineComponent$1("ui-menu-item", createUiMenuItem, [
|
|
|
8238
8775
|
]);
|
|
8239
8776
|
//#endregion
|
|
8240
8777
|
//#region components/ui-popover/ui-popover.js
|
|
8778
|
+
var ui_popover_exports = /* @__PURE__ */ __exportAll({ connect: () => connect$5 });
|
|
8241
8779
|
function connect$5(host) {
|
|
8242
8780
|
const element = host.element;
|
|
8243
8781
|
const document = element.ownerDocument;
|
|
@@ -8355,10 +8893,6 @@ function connect$5(host) {
|
|
|
8355
8893
|
releaseAnchor();
|
|
8356
8894
|
};
|
|
8357
8895
|
}
|
|
8358
|
-
/** Keep DOM setup and its cleanup tied to each connection, including reconnects. */
|
|
8359
|
-
function controller$5(host) {
|
|
8360
|
-
host.on("connect", () => connect$5(host));
|
|
8361
|
-
}
|
|
8362
8896
|
//#endregion
|
|
8363
8897
|
//#region vanilla/UiPopover.js
|
|
8364
8898
|
var T0$7 = [
|
|
@@ -8443,6 +8977,7 @@ var S$9 = {
|
|
|
8443
8977
|
]
|
|
8444
8978
|
},
|
|
8445
8979
|
x: dispatchDeclared,
|
|
8980
|
+
a: (host, I) => C$5(host, I),
|
|
8446
8981
|
b: generatedInputs,
|
|
8447
8982
|
i: [false]
|
|
8448
8983
|
};
|
|
@@ -8503,7 +9038,7 @@ var D$9 = {
|
|
|
8503
9038
|
}
|
|
8504
9039
|
}
|
|
8505
9040
|
};
|
|
8506
|
-
var C$5 = (host) =>
|
|
9041
|
+
var C$5 = (host) => activateModule(ui_popover_exports, host);
|
|
8507
9042
|
function createUiPopover(options = {}, html) {
|
|
8508
9043
|
const { attributes = {}, children = [], slots = {}, ...componentProps } = options;
|
|
8509
9044
|
const element = document.createElement("span");
|
|
@@ -8557,7 +9092,7 @@ function createUiPopover(options = {}, html) {
|
|
|
8557
9092
|
attachGeneratedController(element, S$9, v, (c, d) => {
|
|
8558
9093
|
((c, d) => p0(R, c, d))(c, d);
|
|
8559
9094
|
for (const f of I.R) f(c, d);
|
|
8560
|
-
},
|
|
9095
|
+
}, void 0, void 0, I);
|
|
8561
9096
|
manageProps(I);
|
|
8562
9097
|
return element;
|
|
8563
9098
|
}
|
|
@@ -9996,6 +10531,7 @@ defineComponent$1("ui-text", createUiText, [
|
|
|
9996
10531
|
]);
|
|
9997
10532
|
//#endregion
|
|
9998
10533
|
//#region components/ui-tooltip/ui-tooltip.js
|
|
10534
|
+
var ui_tooltip_exports = /* @__PURE__ */ __exportAll({ connect: () => connect$4 });
|
|
9999
10535
|
var warmTooltips = /* @__PURE__ */ new WeakMap();
|
|
10000
10536
|
function connect$4(host) {
|
|
10001
10537
|
const element = host.element;
|
|
@@ -10232,10 +10768,6 @@ function connect$4(host) {
|
|
|
10232
10768
|
closeOverlay(document, overlayId);
|
|
10233
10769
|
};
|
|
10234
10770
|
}
|
|
10235
|
-
/** Keep DOM setup and its cleanup tied to each connection, including reconnects. */
|
|
10236
|
-
function controller$4(host) {
|
|
10237
|
-
host.on("connect", () => connect$4(host));
|
|
10238
|
-
}
|
|
10239
10771
|
//#endregion
|
|
10240
10772
|
//#region vanilla/UiTooltip.js
|
|
10241
10773
|
var T0$4 = [
|
|
@@ -10334,6 +10866,7 @@ var S$6 = {
|
|
|
10334
10866
|
]
|
|
10335
10867
|
},
|
|
10336
10868
|
x: dispatchDeclared,
|
|
10869
|
+
a: (host, I) => C$4(host, I),
|
|
10337
10870
|
b: generatedInputs,
|
|
10338
10871
|
i: [false]
|
|
10339
10872
|
};
|
|
@@ -10417,7 +10950,7 @@ var D$6 = {
|
|
|
10417
10950
|
}
|
|
10418
10951
|
}
|
|
10419
10952
|
};
|
|
10420
|
-
var C$4 = (host) =>
|
|
10953
|
+
var C$4 = (host) => activateModule(ui_tooltip_exports, host);
|
|
10421
10954
|
function createUiTooltip(options = {}, html) {
|
|
10422
10955
|
const { attributes = {}, children = [], slots = {}, ...componentProps } = options;
|
|
10423
10956
|
const element = document.createElement("span");
|
|
@@ -10502,7 +11035,7 @@ function createUiTooltip(options = {}, html) {
|
|
|
10502
11035
|
attachGeneratedController(element, S$6, v, (c, d) => {
|
|
10503
11036
|
((c, d) => p0(R, c, d))(c, d);
|
|
10504
11037
|
for (const f of I.R) f(c, d);
|
|
10505
|
-
},
|
|
11038
|
+
}, void 0, void 0, I);
|
|
10506
11039
|
manageProps(I);
|
|
10507
11040
|
return element;
|
|
10508
11041
|
}
|
|
@@ -11310,6 +11843,7 @@ function trackTrigger(host) {
|
|
|
11310
11843
|
}
|
|
11311
11844
|
//#endregion
|
|
11312
11845
|
//#region components/ui-checkbox/ui-checkbox.js
|
|
11846
|
+
var ui_checkbox_exports = /* @__PURE__ */ __exportAll({ connect: () => connect$3 });
|
|
11313
11847
|
function connect$3(host) {
|
|
11314
11848
|
const input = host.refs.input;
|
|
11315
11849
|
describeInput(input, host.refs.description);
|
|
@@ -11342,10 +11876,6 @@ function connect$3(host) {
|
|
|
11342
11876
|
input.removeEventListener("change", onChange);
|
|
11343
11877
|
};
|
|
11344
11878
|
}
|
|
11345
|
-
/** Keep DOM setup and its cleanup tied to each connection, including reconnects. */
|
|
11346
|
-
function controller$3(host) {
|
|
11347
|
-
host.on("connect", () => connect$3(host));
|
|
11348
|
-
}
|
|
11349
11879
|
//#endregion
|
|
11350
11880
|
//#region vanilla/UiCheckbox.js
|
|
11351
11881
|
var T0$3 = [
|
|
@@ -11415,6 +11945,7 @@ var S$5 = {
|
|
|
11415
11945
|
false
|
|
11416
11946
|
] },
|
|
11417
11947
|
x: dispatchDeclared,
|
|
11948
|
+
a: (host, I) => C$3(host, I),
|
|
11418
11949
|
b: generatedInputs,
|
|
11419
11950
|
i: [false]
|
|
11420
11951
|
};
|
|
@@ -11500,7 +12031,7 @@ var D$5 = {
|
|
|
11500
12031
|
}
|
|
11501
12032
|
}
|
|
11502
12033
|
};
|
|
11503
|
-
var C$3 = (host) =>
|
|
12034
|
+
var C$3 = (host) => activateModule(ui_checkbox_exports, host);
|
|
11504
12035
|
function createUiCheckbox(options = {}, html) {
|
|
11505
12036
|
const { attributes = {}, children = [], slots = {}, ...componentProps } = options;
|
|
11506
12037
|
const element = document.createElement("label");
|
|
@@ -11645,7 +12176,7 @@ function createUiCheckbox(options = {}, html) {
|
|
|
11645
12176
|
attachGeneratedController(element, S$5, v, (c, d) => {
|
|
11646
12177
|
((c, d) => p0(R, c, d))(c, d);
|
|
11647
12178
|
for (const f of I.R) f(c, d);
|
|
11648
|
-
},
|
|
12179
|
+
}, void 0, void 0, I);
|
|
11649
12180
|
manageProps(I);
|
|
11650
12181
|
I.r["input"] = t0;
|
|
11651
12182
|
I.r["description"] = t4;
|
|
@@ -11664,6 +12195,7 @@ defineComponent$1("ui-checkbox", createUiCheckbox, [
|
|
|
11664
12195
|
]);
|
|
11665
12196
|
//#endregion
|
|
11666
12197
|
//#region components/ui-disclosure/ui-disclosure.js
|
|
12198
|
+
var ui_disclosure_exports = /* @__PURE__ */ __exportAll({ connect: () => connect$2 });
|
|
11667
12199
|
var disclosures = 0;
|
|
11668
12200
|
var groups = /* @__PURE__ */ new WeakMap();
|
|
11669
12201
|
var pendingGroups = /* @__PURE__ */ new WeakSet();
|
|
@@ -11799,10 +12331,6 @@ function connect$2(host) {
|
|
|
11799
12331
|
host.refs.panel.removeEventListener("beforematch", onBeforematch);
|
|
11800
12332
|
};
|
|
11801
12333
|
}
|
|
11802
|
-
/** Keep DOM setup and its cleanup tied to each connection, including reconnects. */
|
|
11803
|
-
function controller$2(host) {
|
|
11804
|
-
host.on("connect", () => connect$2(host));
|
|
11805
|
-
}
|
|
11806
12334
|
//#endregion
|
|
11807
12335
|
//#region vanilla/UiDisclosure.js
|
|
11808
12336
|
var T0$2 = [
|
|
@@ -11957,6 +12485,7 @@ var S$4 = {
|
|
|
11957
12485
|
]
|
|
11958
12486
|
},
|
|
11959
12487
|
x: dispatchDeclared,
|
|
12488
|
+
a: (host, I) => C$2(host, I),
|
|
11960
12489
|
b: generatedInputs,
|
|
11961
12490
|
i: [
|
|
11962
12491
|
false,
|
|
@@ -12044,7 +12573,7 @@ var D$4 = {
|
|
|
12044
12573
|
}
|
|
12045
12574
|
}
|
|
12046
12575
|
};
|
|
12047
|
-
var C$2 = (host) =>
|
|
12576
|
+
var C$2 = (host) => activateModule(ui_disclosure_exports, host);
|
|
12048
12577
|
function createUiDisclosure(options = {}, html) {
|
|
12049
12578
|
const { attributes = {}, children = [], slots = {}, ...componentProps } = options;
|
|
12050
12579
|
const element = document.createElement("div");
|
|
@@ -12231,7 +12760,7 @@ function createUiDisclosure(options = {}, html) {
|
|
|
12231
12760
|
attachGeneratedController(element, S$4, v, (c, d) => {
|
|
12232
12761
|
((c, d) => p0(R, c, d))(c, d);
|
|
12233
12762
|
for (const f of I.R) f(c, d);
|
|
12234
|
-
},
|
|
12763
|
+
}, void 0, void 0, I);
|
|
12235
12764
|
manageProps(I);
|
|
12236
12765
|
I.r["heading"] = t0;
|
|
12237
12766
|
I.r["trigger"] = t1;
|
|
@@ -12251,6 +12780,7 @@ defineComponent$1("ui-disclosure", createUiDisclosure, [
|
|
|
12251
12780
|
]);
|
|
12252
12781
|
//#endregion
|
|
12253
12782
|
//#region components/ui-input/ui-input.js
|
|
12783
|
+
var ui_input_exports = /* @__PURE__ */ __exportAll({ connect: () => connect$1 });
|
|
12254
12784
|
function connect$1(host) {
|
|
12255
12785
|
return host.effect(() => {
|
|
12256
12786
|
const value = host.props.value.value;
|
|
@@ -12263,10 +12793,6 @@ function connect$1(host) {
|
|
|
12263
12793
|
input.value = text;
|
|
12264
12794
|
});
|
|
12265
12795
|
}
|
|
12266
|
-
/** Keep DOM setup and its cleanup tied to each connection, including reconnects. */
|
|
12267
|
-
function controller$1(host) {
|
|
12268
|
-
host.on("connect", () => connect$1(host));
|
|
12269
|
-
}
|
|
12270
12796
|
//#endregion
|
|
12271
12797
|
//#region vanilla/UiInput.js
|
|
12272
12798
|
var S$3 = {
|
|
@@ -12274,6 +12800,7 @@ var S$3 = {
|
|
|
12274
12800
|
t: [],
|
|
12275
12801
|
f: import.meta.url,
|
|
12276
12802
|
g: "ui-input",
|
|
12803
|
+
a: (host, I) => C$1(host, I),
|
|
12277
12804
|
b: generatedInputs
|
|
12278
12805
|
};
|
|
12279
12806
|
var D$3 = {
|
|
@@ -12464,7 +12991,7 @@ var D$3 = {
|
|
|
12464
12991
|
}
|
|
12465
12992
|
}
|
|
12466
12993
|
};
|
|
12467
|
-
var C$1 = (host) =>
|
|
12994
|
+
var C$1 = (host) => activateModule(ui_input_exports, host);
|
|
12468
12995
|
function createUiInput(options = {}, html) {
|
|
12469
12996
|
const { attributes = {}, children = [], slots = {}, ...componentProps } = options;
|
|
12470
12997
|
const element = document.createElement("input");
|
|
@@ -12613,7 +13140,7 @@ function createUiInput(options = {}, html) {
|
|
|
12613
13140
|
v6: void 0
|
|
12614
13141
|
};
|
|
12615
13142
|
const I = { B };
|
|
12616
|
-
attachGeneratedController(element, S$3, v, ((c, d) => p0(R, c, d)),
|
|
13143
|
+
attachGeneratedController(element, S$3, v, ((c, d) => p0(R, c, d)), void 0, void 0, I);
|
|
12617
13144
|
manageProps(I);
|
|
12618
13145
|
return element;
|
|
12619
13146
|
}
|
|
@@ -13434,6 +13961,7 @@ var calloutNodeView = ({ node }) => {
|
|
|
13434
13961
|
};
|
|
13435
13962
|
//#endregion
|
|
13436
13963
|
//#region components/ui-image/ui-image.js
|
|
13964
|
+
var ui_image_exports = /* @__PURE__ */ __exportAll({ connect: () => connect });
|
|
13437
13965
|
/** Owns transient resize geometry; consumers own persistence and selection.
|
|
13438
13966
|
* @lifecycle Pointer capture ends on release, Escape, cancellation, or teardown.
|
|
13439
13967
|
* Only release commits a drag, so consumers can make it one undo operation.
|
|
@@ -13575,10 +14103,6 @@ function connect(host) {
|
|
|
13575
14103
|
document.removeEventListener("keydown", onEscape, true);
|
|
13576
14104
|
};
|
|
13577
14105
|
}
|
|
13578
|
-
/** Keep DOM setup and its cleanup tied to each connection, including reconnects. */
|
|
13579
|
-
function controller(host) {
|
|
13580
|
-
host.on("connect", () => connect(host));
|
|
13581
|
-
}
|
|
13582
14106
|
//#endregion
|
|
13583
14107
|
//#region vanilla/UiImage.js
|
|
13584
14108
|
var T0 = [
|
|
@@ -13692,6 +14216,7 @@ var S = {
|
|
|
13692
14216
|
false
|
|
13693
14217
|
] },
|
|
13694
14218
|
x: dispatchDeclared,
|
|
14219
|
+
a: (host, I) => C(host, I),
|
|
13695
14220
|
b: generatedInputs
|
|
13696
14221
|
};
|
|
13697
14222
|
var D = {
|
|
@@ -13759,7 +14284,7 @@ var D = {
|
|
|
13759
14284
|
}
|
|
13760
14285
|
}
|
|
13761
14286
|
};
|
|
13762
|
-
var C = (host) =>
|
|
14287
|
+
var C = (host) => activateModule(ui_image_exports, host);
|
|
13763
14288
|
function createUiImage(options = {}, html) {
|
|
13764
14289
|
const { attributes = {}, children = [], slots = {}, ...componentProps } = options;
|
|
13765
14290
|
const element = document.createElement("figure");
|
|
@@ -13872,7 +14397,7 @@ function createUiImage(options = {}, html) {
|
|
|
13872
14397
|
};
|
|
13873
14398
|
const I = { B };
|
|
13874
14399
|
const J = project(I, children, slots);
|
|
13875
|
-
attachGeneratedController(element, S, v, ((c, d) => p0(R, c, d)),
|
|
14400
|
+
attachGeneratedController(element, S, v, ((c, d) => p0(R, c, d)), void 0, void 0, I);
|
|
13876
14401
|
manageProps(I);
|
|
13877
14402
|
I.r["frame"] = t0;
|
|
13878
14403
|
return element;
|
|
@@ -14222,6 +14747,14 @@ var LoomaEditor = defineComponent({
|
|
|
14222
14747
|
const chipInput = () => chipEditorRoot.value?.querySelector("[data-chip-label]");
|
|
14223
14748
|
let chipEditing;
|
|
14224
14749
|
const chipState = shallowRef(LOOMA_CHIP_EDITING_IDLE);
|
|
14750
|
+
const footnoteAnchorId = `looma-editor-footnote-${useId().replace(/[^a-zA-Z0-9_-]/g, "")}`;
|
|
14751
|
+
const footnoteEditorRoot = ref(null);
|
|
14752
|
+
const setFootnoteEditorRoot = (instance) => {
|
|
14753
|
+
const element = instance?.$el;
|
|
14754
|
+
footnoteEditorRoot.value = element instanceof HTMLElement ? element : null;
|
|
14755
|
+
};
|
|
14756
|
+
let footnoteEditing;
|
|
14757
|
+
const footnoteState = shallowRef(LOOMA_FOOTNOTE_EDITING_IDLE);
|
|
14225
14758
|
const toolbarScope = `looma-editor-tool-${useId().replace(/[^a-zA-Z0-9_-]/g, "")}`;
|
|
14226
14759
|
const toolbarTooltip = createToolbarTooltip((state) => {
|
|
14227
14760
|
tooltip.value = state;
|
|
@@ -14308,6 +14841,17 @@ var LoomaEditor = defineComponent({
|
|
|
14308
14841
|
chipEditing.element.id = chipAnchorId;
|
|
14309
14842
|
nextTick(() => chipInput()?.focus());
|
|
14310
14843
|
};
|
|
14844
|
+
const openFootnoteEditor = (position) => {
|
|
14845
|
+
if (!footnoteEditing?.open(position)) return;
|
|
14846
|
+
root.value?.querySelector(`#${footnoteAnchorId}`)?.removeAttribute("id");
|
|
14847
|
+
footnoteEditing.element.id = footnoteAnchorId;
|
|
14848
|
+
nextTick(() => footnoteEditorRoot.value?.querySelector("[data-footnote-note]")?.focus());
|
|
14849
|
+
};
|
|
14850
|
+
const closeFootnote = (focusReference = false) => {
|
|
14851
|
+
const element = footnoteEditing?.element;
|
|
14852
|
+
footnoteEditing?.close();
|
|
14853
|
+
if (focusReference) element?.focus();
|
|
14854
|
+
};
|
|
14311
14855
|
const closeChip = (focusChip = false) => {
|
|
14312
14856
|
const element = chipEditing?.element;
|
|
14313
14857
|
chipEditing?.close();
|
|
@@ -14537,6 +15081,14 @@ var LoomaEditor = defineComponent({
|
|
|
14537
15081
|
chipState.value = chips.state;
|
|
14538
15082
|
});
|
|
14539
15083
|
chipEditing = chips;
|
|
15084
|
+
const footnotes = createFootnoteEditing({
|
|
15085
|
+
editor: session.editor,
|
|
15086
|
+
isEditable: () => props.editable
|
|
15087
|
+
});
|
|
15088
|
+
footnotes.subscribe(() => {
|
|
15089
|
+
footnoteState.value = footnotes.state;
|
|
15090
|
+
});
|
|
15091
|
+
footnoteEditing = footnotes;
|
|
14540
15092
|
const imageUploads = createImageUploads({
|
|
14541
15093
|
editor: session.editor,
|
|
14542
15094
|
upload: () => (file, init) => ask("image-upload", { file }, init),
|
|
@@ -14563,6 +15115,7 @@ var LoomaEditor = defineComponent({
|
|
|
14563
15115
|
const content = edited ? previous.editor.getJSON() : props.modelValue;
|
|
14564
15116
|
linkEditing?.destroy();
|
|
14565
15117
|
chipEditing?.close();
|
|
15118
|
+
footnoteEditing?.close();
|
|
14566
15119
|
formatting?.destroy();
|
|
14567
15120
|
uploads?.cancel();
|
|
14568
15121
|
previous.destroy();
|
|
@@ -14685,10 +15238,11 @@ var LoomaEditor = defineComponent({
|
|
|
14685
15238
|
editor.value?.setEditable(editable, false);
|
|
14686
15239
|
if (!editable) formattingPopup?.hide();
|
|
14687
15240
|
if (editor.value) imageDelivery.reset(editor.value);
|
|
14688
|
-
root.value?.querySelectorAll("[data-looma-chip]").forEach((chip) => {
|
|
15241
|
+
root.value?.querySelectorAll("[data-looma-chip], [data-looma-footnote-ref]").forEach((chip) => {
|
|
14689
15242
|
chip.setAttribute("aria-disabled", String(!editable));
|
|
14690
15243
|
});
|
|
14691
15244
|
if (!editable) chipEditing?.close();
|
|
15245
|
+
if (!editable) footnoteEditing?.close();
|
|
14692
15246
|
});
|
|
14693
15247
|
watch([
|
|
14694
15248
|
() => linkState.value.surface === "popover",
|
|
@@ -15035,7 +15589,18 @@ var LoomaEditor = defineComponent({
|
|
|
15035
15589
|
const element = event.target instanceof Element ? event.target.closest("[data-looma-chip]") : null;
|
|
15036
15590
|
return element && root.value?.contains(element) ? element : null;
|
|
15037
15591
|
};
|
|
15592
|
+
const footnoteElementForEvent = (event) => {
|
|
15593
|
+
const element = event.target instanceof Element ? event.target.closest("[data-looma-footnote-ref]") : null;
|
|
15594
|
+
return element && root.value?.contains(element) ? element : null;
|
|
15595
|
+
};
|
|
15038
15596
|
const onChipClickCapture = (event) => {
|
|
15597
|
+
const reference = footnoteElementForEvent(event);
|
|
15598
|
+
if (reference && editor.value && props.editable) {
|
|
15599
|
+
event.preventDefault();
|
|
15600
|
+
event.stopPropagation();
|
|
15601
|
+
openFootnoteEditor(editor.value.view.posAtDOM(reference, 0));
|
|
15602
|
+
return;
|
|
15603
|
+
}
|
|
15039
15604
|
const chip = chipElementForEvent(event);
|
|
15040
15605
|
if (chip && editor.value && props.editable) {
|
|
15041
15606
|
event.preventDefault();
|
|
@@ -15053,6 +15618,12 @@ var LoomaEditor = defineComponent({
|
|
|
15053
15618
|
};
|
|
15054
15619
|
const onImageKeyDown = (event) => {
|
|
15055
15620
|
if (event.key !== "Enter" && event.key !== " ") return;
|
|
15621
|
+
const reference = footnoteElementForEvent(event);
|
|
15622
|
+
if (reference && editor.value && props.editable) {
|
|
15623
|
+
event.preventDefault();
|
|
15624
|
+
openFootnoteEditor(editor.value.view.posAtDOM(reference, 0));
|
|
15625
|
+
return;
|
|
15626
|
+
}
|
|
15056
15627
|
const chip = chipElementForEvent(event);
|
|
15057
15628
|
if (chip && editor.value && props.editable) {
|
|
15058
15629
|
event.preventDefault();
|
|
@@ -15588,6 +16159,23 @@ var LoomaEditor = defineComponent({
|
|
|
15588
16159
|
onColor: (event) => chipEditing?.setColor(event.detail.color),
|
|
15589
16160
|
onDone: () => closeChip(true)
|
|
15590
16161
|
})),
|
|
16162
|
+
h(Popover, {
|
|
16163
|
+
size: "sm",
|
|
16164
|
+
open: footnoteState.value.open,
|
|
16165
|
+
for: footnoteAnchorId,
|
|
16166
|
+
placement: mobile.value ? "top-start" : "bottom-start",
|
|
16167
|
+
onClose: () => footnoteEditing?.close()
|
|
16168
|
+
}, () => h(EditorFootnoteEditor, {
|
|
16169
|
+
ref: setFootnoteEditorRoot,
|
|
16170
|
+
label: footnoteState.value.label,
|
|
16171
|
+
note: footnoteState.value.note,
|
|
16172
|
+
editable: footnoteState.value.editable,
|
|
16173
|
+
error: footnoteState.value.error,
|
|
16174
|
+
onText: (event) => footnoteEditing?.setNote(event.detail.text),
|
|
16175
|
+
onLabel: (event) => footnoteEditing?.rename(event.detail.label),
|
|
16176
|
+
onGo: () => footnoteEditing?.goToNote(),
|
|
16177
|
+
onDone: () => closeFootnote(true)
|
|
16178
|
+
})),
|
|
15591
16179
|
h(Popover, {
|
|
15592
16180
|
class: "looma-editor__link-popover",
|
|
15593
16181
|
size: "sm",
|
|
@@ -15751,4 +16339,4 @@ var LoomaEditor = defineComponent({
|
|
|
15751
16339
|
}
|
|
15752
16340
|
});
|
|
15753
16341
|
//#endregion
|
|
15754
|
-
export { EDITOR_ADAPTER_COMPONENT_TAG_MAP, EditorBlockActions, EditorChipEditor, EditorCodeLanguage, EditorImageToolbar, EditorInsertTableGrid, EditorLinkCard, EditorLinkForm, EditorMentionMenu, EditorMentionMenuItem, EditorSlashMenu, EditorSlashMenuGroup, EditorSlashMenuItem, EditorTableContextMenu, EditorTableOverlay, EditorTableToolbar, EditorToolbar, LoomaEditor };
|
|
16342
|
+
export { EDITOR_ADAPTER_COMPONENT_TAG_MAP, EditorBlockActions, EditorChipEditor, EditorCodeLanguage, EditorFootnoteEditor, EditorImageToolbar, EditorInsertTableGrid, EditorLinkCard, EditorLinkForm, EditorMentionMenu, EditorMentionMenuItem, EditorSlashMenu, EditorSlashMenuGroup, EditorSlashMenuItem, EditorTableContextMenu, EditorTableOverlay, EditorTableToolbar, EditorToolbar, LoomaEditor };
|