@threadlabs/looma 0.31.0 → 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-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-icon/ui-icon.html +1 -0
- 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/UiEditorFootnoteEditor.d.ts +30 -0
- package/vanilla/UiEditorFootnoteEditor.js +101 -0
- package/vanilla/UiIcon.js +1 -1
- package/vanilla/index.js +1 -0
- package/vue/UiEditorFootnoteEditor.d.ts +57 -0
- package/vue/UiEditorFootnoteEditor.js +2 -0
- package/vue/UiEditorFootnoteEditor.vue +304 -0
- package/vue/UiIcon.vue +4 -0
- package/vue/chunks/UiEditorFootnoteEditor.js +306 -0
- package/vue/chunks/UiEditorImageToolbar.js +1 -1
- package/vue/chunks/UiEditorLinkForm.js +1 -1
- package/vue/chunks/UiIcon.js +15 -1
- package/vue/components.css +579 -579
- package/vue/editor/index.js +607 -7
- package/vue/editor/primitives.d.ts +3 -1
- package/vue/index.d.ts +1 -0
- package/vue/index.js +5 -4
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { n as TABLE_CELL_BACKGROUND_PRESETS } from "./table-backgrounds.js";
|
|
2
2
|
import { _ as parseLoomaAttributes, b as splitLoomaFrontmatter, c as LOOMA_CONTAINER_NAMES, d as formatLoomaAttributes, f as loomaCodeFence, g as normalizeLoomaChipTone, h as normalizeLoomaCalloutTone, i as referenceDisplay, l as applyLoomaCodeNotation, m as loomaHeadingSlug, n as LoomaReferencePresentation, p as loomaContainerMarker, r as getReferenceDisplay, s as LOOMA_CHIP_TONES, t as LoomaReference, u as assignLoomaHeadingIds, v as parseLoomaFenceInfo, y as readLoomaAttributes } from "./reference-display.js";
|
|
3
|
-
import { Extension, Mark, Node as Node$1, callOrReturn, canInsertNode, combineTransactionSteps, escapeForRegEx, findChildren, findChildrenInRange, findParentNodeClosestToPos, getAttributes, getChangedRanges, getExtensionField, getMarksBetween, getText, getTextSerializersFromSchema, isNodeEmpty, isNodeSelection, markInputRule, markPasteRule, mergeAttributes, nodeInputRule, textInputRule, textblockTypeInputRule, wrappingInputRule } from "@tiptap/core";
|
|
3
|
+
import { Extension, InputRule, Mark, Node as Node$1, PasteRule, callOrReturn, canInsertNode, combineTransactionSteps, escapeForRegEx, findChildren, findChildrenInRange, findParentNodeClosestToPos, getAttributes, getChangedRanges, getExtensionField, getMarksBetween, getText, getTextSerializersFromSchema, isNodeEmpty, isNodeSelection, markInputRule, markPasteRule, mergeAttributes, nodeInputRule, textInputRule, textblockTypeInputRule, wrappingInputRule } from "@tiptap/core";
|
|
4
4
|
import { NodeSelection, Plugin, PluginKey, Selection, TextSelection } from "@tiptap/pm/state";
|
|
5
5
|
import { Decoration, DecorationSet } from "@tiptap/pm/view";
|
|
6
6
|
import { DOMParser, DOMSerializer, Fragment, Node as Node$2, Slice } from "@tiptap/pm/model";
|
|
@@ -477,13 +477,180 @@ var LoomaFigcaption = Node$1.create({
|
|
|
477
477
|
//#endregion
|
|
478
478
|
//#region src/editor/extensions/footnote.ts
|
|
479
479
|
var labelFrom = (href, prefix) => href?.startsWith(`#${prefix}`) ? href.slice(prefix.length + 1) : null;
|
|
480
|
+
/** A footnote label as Looma Markdown reads it in `[^label]`: no whitespace and no `]`. */
|
|
481
|
+
var LOOMA_FOOTNOTE_LABEL = /^[^\s\]]+$/;
|
|
482
|
+
var REFERENCE = "loomaFootnoteReference";
|
|
483
|
+
var NOTES = "loomaFootnotes";
|
|
484
|
+
var NOTE = "loomaFootnote";
|
|
485
|
+
var isLabel = (label) => LOOMA_FOOTNOTE_LABEL.test(label);
|
|
486
|
+
/** Every label a reference or note in `doc` uses. */
|
|
487
|
+
function usedLabels(doc) {
|
|
488
|
+
const labels = /* @__PURE__ */ new Set();
|
|
489
|
+
doc.descendants((node) => {
|
|
490
|
+
if (node.type.name === REFERENCE || node.type.name === NOTE) labels.add(String(node.attrs.label));
|
|
491
|
+
});
|
|
492
|
+
return labels;
|
|
493
|
+
}
|
|
494
|
+
/**
|
|
495
|
+
* The first note for `label` in `doc` and its position.
|
|
496
|
+
* @failure Returns null when no note has that label.
|
|
497
|
+
*/
|
|
498
|
+
function findLoomaFootnote(doc, label) {
|
|
499
|
+
let found = null;
|
|
500
|
+
doc.descendants((node, position) => {
|
|
501
|
+
if (found) return false;
|
|
502
|
+
if (node.type.name === NOTE && node.attrs.label === label) {
|
|
503
|
+
found = {
|
|
504
|
+
node,
|
|
505
|
+
position
|
|
506
|
+
};
|
|
507
|
+
return false;
|
|
508
|
+
}
|
|
509
|
+
});
|
|
510
|
+
return found;
|
|
511
|
+
}
|
|
512
|
+
function mapReferences(node, change) {
|
|
513
|
+
if (node.type.name === REFERENCE) return change(node);
|
|
514
|
+
if (node.isLeaf) return node;
|
|
515
|
+
const children = [];
|
|
516
|
+
node.content.forEach((child) => children.push(mapReferences(child, change)));
|
|
517
|
+
return node.copy(Fragment.from(children));
|
|
518
|
+
}
|
|
519
|
+
function noteAt(doc, position) {
|
|
520
|
+
const $position = doc.resolve(position);
|
|
521
|
+
for (let depth = $position.depth; depth > 0; depth--) {
|
|
522
|
+
const node = $position.node(depth);
|
|
523
|
+
if (node.type.name === NOTE) return {
|
|
524
|
+
node,
|
|
525
|
+
start: $position.before(depth)
|
|
526
|
+
};
|
|
527
|
+
}
|
|
528
|
+
return null;
|
|
529
|
+
}
|
|
530
|
+
/**
|
|
531
|
+
* Keeps footnotes on Looma Markdown's rule, so the saved HTML is the HTML Looma Markdown renders for
|
|
532
|
+
* the same document. Notes are numbered by first reference, in the text and then in the notes, and
|
|
533
|
+
* every reference carries its note's number and its place among that note's references. The notes
|
|
534
|
+
* live in one `loomaFootnotes` section at the end of the document, in number order. A note no
|
|
535
|
+
* reference points to leaves the document; a reference with no note gets one back, the note it last
|
|
536
|
+
* had in this editor (so cutting a reference and pasting it keeps its note) or an empty one.
|
|
537
|
+
* @invariant Changing nothing but text inside a note never rebuilds the section.
|
|
538
|
+
*/
|
|
539
|
+
function footnoteTransaction(state, known) {
|
|
540
|
+
const { doc, schema } = state;
|
|
541
|
+
const sections = [];
|
|
542
|
+
const notes = /* @__PURE__ */ new Map();
|
|
543
|
+
const body = [];
|
|
544
|
+
doc.descendants((node, position) => {
|
|
545
|
+
if (node.type.name === NOTES) {
|
|
546
|
+
sections.push({
|
|
547
|
+
node,
|
|
548
|
+
position
|
|
549
|
+
});
|
|
550
|
+
node.forEach((note) => {
|
|
551
|
+
if (!notes.has(note.attrs.label)) notes.set(note.attrs.label, note);
|
|
552
|
+
});
|
|
553
|
+
return false;
|
|
554
|
+
}
|
|
555
|
+
if (node.type.name === REFERENCE) body.push({
|
|
556
|
+
node,
|
|
557
|
+
position
|
|
558
|
+
});
|
|
559
|
+
});
|
|
560
|
+
if (!sections.length && !body.length) return null;
|
|
561
|
+
const order = [];
|
|
562
|
+
const counts = /* @__PURE__ */ new Map();
|
|
563
|
+
const numbered = (reference) => {
|
|
564
|
+
const label = String(reference.attrs.label);
|
|
565
|
+
if (!counts.has(label)) order.push(label);
|
|
566
|
+
counts.set(label, (counts.get(label) ?? 0) + 1);
|
|
567
|
+
const attrs = {
|
|
568
|
+
...reference.attrs,
|
|
569
|
+
number: order.indexOf(label) + 1,
|
|
570
|
+
occurrence: counts.get(label)
|
|
571
|
+
};
|
|
572
|
+
return attrs.number === reference.attrs.number && attrs.occurrence === reference.attrs.occurrence ? reference : reference.type.create(attrs, null, reference.marks);
|
|
573
|
+
};
|
|
574
|
+
const transaction = state.tr;
|
|
575
|
+
for (const { node, position } of body) {
|
|
576
|
+
const next = numbered(node);
|
|
577
|
+
if (next !== node) transaction.setNodeMarkup(position, void 0, next.attrs);
|
|
578
|
+
}
|
|
579
|
+
const built = [];
|
|
580
|
+
for (let index = 0; index < order.length; index++) {
|
|
581
|
+
const label = order[index];
|
|
582
|
+
const note = notes.get(label) ?? known.get(label) ?? schema.nodes[NOTE].create({ label }, schema.nodes.paragraph.create());
|
|
583
|
+
built.push(mapReferences(note, numbered));
|
|
584
|
+
}
|
|
585
|
+
const wanted = built.map((note) => note.attrs.count === counts.get(note.attrs.label) ? note : note.type.create({
|
|
586
|
+
...note.attrs,
|
|
587
|
+
count: counts.get(note.attrs.label)
|
|
588
|
+
}, note.content));
|
|
589
|
+
for (const note of [...notes.values(), ...wanted]) known.set(note.attrs.label, note);
|
|
590
|
+
const section = wanted.length ? schema.nodes[NOTES].create(null, wanted) : null;
|
|
591
|
+
const last = doc.lastChild?.type.name === NOTES ? {
|
|
592
|
+
node: doc.lastChild,
|
|
593
|
+
position: doc.content.size - doc.lastChild.nodeSize
|
|
594
|
+
} : null;
|
|
595
|
+
if (!(section && last && sections.length === 1 && last.node.eq(section)) && (sections.length || section)) {
|
|
596
|
+
const { selection } = state;
|
|
597
|
+
const inside = noteAt(doc, selection.from);
|
|
598
|
+
const keep = inside && selection.to <= inside.start + inside.node.nodeSize ? {
|
|
599
|
+
label: inside.node.attrs.label,
|
|
600
|
+
start: inside.start
|
|
601
|
+
} : null;
|
|
602
|
+
for (const { node, position } of [...sections].reverse()) if (node !== last?.node) transaction.delete(position, position + node.nodeSize);
|
|
603
|
+
if (last) {
|
|
604
|
+
const position = transaction.mapping.map(last.position);
|
|
605
|
+
if (section) transaction.replaceWith(position, position + last.node.nodeSize, section);
|
|
606
|
+
else transaction.delete(position, position + last.node.nodeSize);
|
|
607
|
+
} else if (section) transaction.insert(transaction.doc.content.size, section);
|
|
608
|
+
const moved = keep && findLoomaFootnote(transaction.doc, keep.label);
|
|
609
|
+
if (keep && moved) {
|
|
610
|
+
const json = selection.toJSON();
|
|
611
|
+
json.anchor += moved.position - keep.start;
|
|
612
|
+
if (json.head !== void 0) json.head += moved.position - keep.start;
|
|
613
|
+
try {
|
|
614
|
+
transaction.setSelection(Selection.fromJSON(transaction.doc, json));
|
|
615
|
+
} catch {}
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
return transaction.docChanged ? transaction : null;
|
|
619
|
+
}
|
|
620
|
+
function appendBackLinks(item, label, number, count) {
|
|
621
|
+
const document = item.ownerDocument;
|
|
622
|
+
let paragraph = item.lastElementChild;
|
|
623
|
+
if (paragraph?.nodeName !== "P") item.append(paragraph = document.createElement("p"));
|
|
624
|
+
for (let occurrence = 1; occurrence <= count; occurrence++) {
|
|
625
|
+
const link = document.createElement("a");
|
|
626
|
+
link.setAttribute("href", `#fnref:${label}${occurrence > 1 ? `:${occurrence}` : ""}`);
|
|
627
|
+
link.setAttribute("data-footnote-backref", "");
|
|
628
|
+
link.setAttribute("aria-label", `Back to reference ${number}${occurrence > 1 ? `-${occurrence}` : ""}`);
|
|
629
|
+
link.append("↩");
|
|
630
|
+
if (occurrence > 1) link.append(Object.assign(document.createElement("sup"), { textContent: String(occurrence) }));
|
|
631
|
+
paragraph.append(" ", link);
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
var FootnoteSerializer = class extends DOMSerializer {
|
|
635
|
+
serializeFragment(fragment, options = {}, target) {
|
|
636
|
+
const dom = super.serializeFragment(fragment, options, target);
|
|
637
|
+
fragment.forEach((node, _offset, index) => {
|
|
638
|
+
if (node.type.name === NOTE) appendBackLinks(dom.childNodes[index], String(node.attrs.label), index + 1, Number(node.attrs.count) || 1);
|
|
639
|
+
});
|
|
640
|
+
return dom;
|
|
641
|
+
}
|
|
642
|
+
};
|
|
643
|
+
function installSerializer(schema) {
|
|
644
|
+
if (!(schema.cached.domSerializer instanceof FootnoteSerializer)) schema.cached.domSerializer = new FootnoteSerializer(DOMSerializer.nodesFromSchema(schema), DOMSerializer.marksFromSchema(schema));
|
|
645
|
+
}
|
|
480
646
|
/**
|
|
481
|
-
* A footnote reference, `[^label]`, saved as `<sup><a data-footnote-ref>`.
|
|
482
|
-
*
|
|
483
|
-
*
|
|
647
|
+
* A footnote reference, `[^label]`, saved as `<sup><a data-footnote-ref>`. Typing or pasting
|
|
648
|
+
* `[^label]` makes one; the note it needs is created with it.
|
|
649
|
+
* @invariant `label` names its note. `number` and `occurrence`, the note's number and this
|
|
650
|
+
* reference's place among the note's references, follow the document's order on every change.
|
|
484
651
|
*/
|
|
485
652
|
var LoomaFootnoteReference = Node$1.create({
|
|
486
|
-
name:
|
|
653
|
+
name: REFERENCE,
|
|
487
654
|
group: "inline",
|
|
488
655
|
inline: true,
|
|
489
656
|
atom: true,
|
|
@@ -531,16 +698,59 @@ var LoomaFootnoteReference = Node$1.create({
|
|
|
531
698
|
},
|
|
532
699
|
renderText({ node }) {
|
|
533
700
|
return `[^${node.attrs.label}]`;
|
|
701
|
+
},
|
|
702
|
+
addInputRules() {
|
|
703
|
+
return [new InputRule({
|
|
704
|
+
find: /\[\^([^\s\]]+)\]$/,
|
|
705
|
+
handler: ({ state, range, match }) => {
|
|
706
|
+
state.tr.replaceWith(range.from, range.to, this.type.create({ label: match[1] }));
|
|
707
|
+
}
|
|
708
|
+
})];
|
|
709
|
+
},
|
|
710
|
+
addPasteRules() {
|
|
711
|
+
return [new PasteRule({
|
|
712
|
+
find: /\[\^([^\s\]]+)\]/g,
|
|
713
|
+
handler: ({ state, range, match }) => {
|
|
714
|
+
state.tr.replaceWith(range.from, range.to, this.type.create({ label: match[1] }));
|
|
715
|
+
}
|
|
716
|
+
})];
|
|
717
|
+
},
|
|
718
|
+
addNodeView() {
|
|
719
|
+
return ({ node, editor }) => {
|
|
720
|
+
const dom = document.createElement("sup");
|
|
721
|
+
dom.dataset.loomaFootnoteRef = "";
|
|
722
|
+
dom.contentEditable = "false";
|
|
723
|
+
dom.setAttribute("role", "button");
|
|
724
|
+
dom.setAttribute("aria-haspopup", "dialog");
|
|
725
|
+
dom.setAttribute("aria-disabled", String(!editor.isEditable));
|
|
726
|
+
dom.tabIndex = 0;
|
|
727
|
+
const number = dom.appendChild(document.createElement("a"));
|
|
728
|
+
const update = (next) => {
|
|
729
|
+
if (next.type !== node.type) return false;
|
|
730
|
+
const shown = String(next.attrs.number ?? next.attrs.label);
|
|
731
|
+
dom.dataset.label = String(next.attrs.label);
|
|
732
|
+
if (number.textContent !== shown) number.textContent = shown;
|
|
733
|
+
dom.setAttribute("aria-label", `Footnote ${shown}`);
|
|
734
|
+
return true;
|
|
735
|
+
};
|
|
736
|
+
update(node);
|
|
737
|
+
return {
|
|
738
|
+
dom,
|
|
739
|
+
update,
|
|
740
|
+
stopEvent: (event) => event.type === "click" || event.type === "keydown"
|
|
741
|
+
};
|
|
742
|
+
};
|
|
534
743
|
}
|
|
535
744
|
});
|
|
536
745
|
/**
|
|
537
746
|
* The document's notes, saved as `<section data-footnotes>` with its `<ol>`.
|
|
538
|
-
* @invariant It holds only footnotes
|
|
747
|
+
* @invariant It holds only footnotes and stays the document's last block, one section in number order.
|
|
748
|
+
* @ownership It owns footnote numbering and the back-links in serialized HTML for the whole editor.
|
|
539
749
|
*/
|
|
540
750
|
var LoomaFootnotes = Node$1.create({
|
|
541
|
-
name:
|
|
751
|
+
name: NOTES,
|
|
542
752
|
group: "block",
|
|
543
|
-
content:
|
|
753
|
+
content: `${NOTE}+`,
|
|
544
754
|
isolating: true,
|
|
545
755
|
parseHTML() {
|
|
546
756
|
return [{
|
|
@@ -565,29 +775,121 @@ var LoomaFootnotes = Node$1.create({
|
|
|
565
775
|
],
|
|
566
776
|
["ol", 0]
|
|
567
777
|
];
|
|
778
|
+
},
|
|
779
|
+
onBeforeCreate() {
|
|
780
|
+
installSerializer(this.editor.schema);
|
|
781
|
+
},
|
|
782
|
+
onCreate() {
|
|
783
|
+
const transaction = footnoteTransaction(this.editor.state, this.storage.known);
|
|
784
|
+
if (transaction) this.editor.view.dispatch(transaction.setMeta("addToHistory", false));
|
|
785
|
+
},
|
|
786
|
+
addStorage: () => ({ known: /* @__PURE__ */ new Map() }),
|
|
787
|
+
addProseMirrorPlugins() {
|
|
788
|
+
return [new Plugin({
|
|
789
|
+
appendTransaction: (transactions, _oldState, state) => transactions.some((transaction) => transaction.docChanged) ? footnoteTransaction(state, this.storage.known) : null,
|
|
790
|
+
props: { transformPasted: (slice) => {
|
|
791
|
+
const kept = [];
|
|
792
|
+
slice.content.forEach((node) => {
|
|
793
|
+
if (node.type.name === NOTES) node.forEach((note) => {
|
|
794
|
+
this.storage.known.set(note.attrs.label, note);
|
|
795
|
+
});
|
|
796
|
+
else kept.push(node);
|
|
797
|
+
});
|
|
798
|
+
if (!kept.length || kept.length === slice.content.childCount) return slice;
|
|
799
|
+
const content = Fragment.from(kept);
|
|
800
|
+
const open = Slice.maxOpen(content);
|
|
801
|
+
return new Slice(content, kept[0] === slice.content.firstChild ? slice.openStart : open.openStart, kept.at(-1) === slice.content.lastChild ? slice.openEnd : open.openEnd);
|
|
802
|
+
} }
|
|
803
|
+
})];
|
|
804
|
+
},
|
|
805
|
+
addCommands() {
|
|
806
|
+
return {
|
|
807
|
+
insertLoomaFootnote: (label) => ({ state, tr, dispatch }) => {
|
|
808
|
+
const name = label ?? (() => {
|
|
809
|
+
const used = usedLabels(state.doc);
|
|
810
|
+
let next = 1;
|
|
811
|
+
while (used.has(String(next))) next++;
|
|
812
|
+
return String(next);
|
|
813
|
+
})();
|
|
814
|
+
const { $from, $to } = state.selection;
|
|
815
|
+
if (!isLabel(name) || !$from.parent.canReplaceWith($from.index(), $to.index(), state.schema.nodes[REFERENCE])) return false;
|
|
816
|
+
if (!dispatch) return true;
|
|
817
|
+
tr.replaceSelectionWith(state.schema.nodes[REFERENCE].create({ label: name }));
|
|
818
|
+
if (!findLoomaFootnote(tr.doc, name)) {
|
|
819
|
+
const note = state.schema.nodes[NOTE].create({ label: name }, state.schema.nodes.paragraph.create());
|
|
820
|
+
if (tr.doc.lastChild?.type.name === NOTES) tr.insert(tr.doc.content.size - 1, note);
|
|
821
|
+
else tr.insert(tr.doc.content.size, state.schema.nodes[NOTES].create(null, note));
|
|
822
|
+
tr.setSelection(TextSelection.create(tr.doc, tr.doc.content.size - 3));
|
|
823
|
+
}
|
|
824
|
+
tr.scrollIntoView();
|
|
825
|
+
return true;
|
|
826
|
+
},
|
|
827
|
+
renameLoomaFootnote: (from, to) => ({ state, tr, dispatch }) => {
|
|
828
|
+
if (!isLabel(to) || usedLabels(state.doc).has(to) || !findLoomaFootnote(state.doc, from)) return false;
|
|
829
|
+
if (dispatch) state.doc.descendants((node, position) => {
|
|
830
|
+
if ((node.type.name === REFERENCE || node.type.name === NOTE) && node.attrs.label === from) tr.setNodeMarkup(position, void 0, {
|
|
831
|
+
...node.attrs,
|
|
832
|
+
label: to
|
|
833
|
+
});
|
|
834
|
+
});
|
|
835
|
+
return true;
|
|
836
|
+
},
|
|
837
|
+
goToLoomaFootnote: () => ({ state, tr, dispatch }) => {
|
|
838
|
+
const { selection } = state;
|
|
839
|
+
const reference = selection instanceof NodeSelection ? selection.node : selection.empty ? selection.$from.nodeBefore : null;
|
|
840
|
+
if (reference?.type.name === REFERENCE) {
|
|
841
|
+
const note = findLoomaFootnote(state.doc, reference.attrs.label);
|
|
842
|
+
if (!note) return false;
|
|
843
|
+
if (dispatch) tr.setSelection(Selection.near(state.doc.resolve(note.position + note.node.nodeSize - 1), -1)).scrollIntoView();
|
|
844
|
+
return true;
|
|
845
|
+
}
|
|
846
|
+
const note = noteAt(state.doc, selection.from);
|
|
847
|
+
let first = -1;
|
|
848
|
+
if (note) state.doc.descendants((node, position) => {
|
|
849
|
+
if (first >= 0) return false;
|
|
850
|
+
if (node.type.name === REFERENCE && node.attrs.label === note.node.attrs.label) first = position;
|
|
851
|
+
});
|
|
852
|
+
if (first < 0) return false;
|
|
853
|
+
if (dispatch) tr.setSelection(TextSelection.create(state.doc, first + 1)).scrollIntoView();
|
|
854
|
+
return true;
|
|
855
|
+
}
|
|
856
|
+
};
|
|
857
|
+
},
|
|
858
|
+
addKeyboardShortcuts() {
|
|
859
|
+
return {
|
|
860
|
+
"Mod-Alt-f": () => this.editor.commands.insertLoomaFootnote(),
|
|
861
|
+
"Mod-Alt-n": () => this.editor.commands.goToLoomaFootnote()
|
|
862
|
+
};
|
|
568
863
|
}
|
|
569
864
|
});
|
|
570
865
|
/**
|
|
571
866
|
* One note, `[^label]: …`, saved as `<li id="fn:label">`.
|
|
572
|
-
* @invariant It exists only inside `LoomaFootnotes`.
|
|
573
|
-
*
|
|
867
|
+
* @invariant It exists only inside `LoomaFootnotes`. `count` is how many references point to it. Its
|
|
868
|
+
* back-links are presentation: the editor reads past them and writes them only into saved HTML.
|
|
574
869
|
*/
|
|
575
870
|
var LoomaFootnote = Node$1.create({
|
|
576
|
-
name:
|
|
871
|
+
name: NOTE,
|
|
577
872
|
content: "block+",
|
|
578
873
|
defining: true,
|
|
579
874
|
addAttributes() {
|
|
580
|
-
return {
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
875
|
+
return {
|
|
876
|
+
label: {
|
|
877
|
+
default: "",
|
|
878
|
+
parseHTML: (element) => labelFrom(`#${element.id}`, "fn:") ?? "",
|
|
879
|
+
renderHTML: () => ({})
|
|
880
|
+
},
|
|
881
|
+
count: {
|
|
882
|
+
default: 1,
|
|
883
|
+
parseHTML: (element) => element.querySelectorAll("a[data-footnote-backref]").length || 1,
|
|
884
|
+
renderHTML: () => ({})
|
|
885
|
+
}
|
|
886
|
+
};
|
|
585
887
|
},
|
|
586
888
|
parseHTML() {
|
|
587
889
|
return [{
|
|
588
890
|
tag: "li",
|
|
589
891
|
priority: 1100,
|
|
590
|
-
context:
|
|
892
|
+
context: `${NOTES}/`
|
|
591
893
|
}, {
|
|
592
894
|
tag: "a[data-footnote-backref]",
|
|
593
895
|
priority: 1100,
|
|
@@ -10392,7 +10694,8 @@ function looksLikeMarkdown(value) {
|
|
|
10392
10694
|
"image",
|
|
10393
10695
|
"strong_open",
|
|
10394
10696
|
"looma_chip",
|
|
10395
|
-
"looma_mention"
|
|
10697
|
+
"looma_mention",
|
|
10698
|
+
"looma_footnote_ref"
|
|
10396
10699
|
].includes(child.type)));
|
|
10397
10700
|
});
|
|
10398
10701
|
}
|
|
@@ -10476,8 +10779,11 @@ var LoomaSmartPaste = Extension.create({
|
|
|
10476
10779
|
const plainText = event.clipboardData.getData("text/plain");
|
|
10477
10780
|
if (!plainText.trim()) return false;
|
|
10478
10781
|
if (hasRichClipboardStructure(event.clipboardData.getData("text/html"))) return false;
|
|
10479
|
-
|
|
10782
|
+
let slice = documentSlice(view.state.schema, plainText);
|
|
10480
10783
|
if (!slice) return false;
|
|
10784
|
+
view.someProp("transformPasted", (transform) => {
|
|
10785
|
+
slice = transform(slice, view, true);
|
|
10786
|
+
});
|
|
10481
10787
|
if (slice.size === 0) return true;
|
|
10482
10788
|
const transaction = view.state.tr.replaceSelection(slice).scrollIntoView().setMeta("paste", true).setMeta("uiEvent", "paste");
|
|
10483
10789
|
view.dispatch(transaction);
|
|
@@ -11785,6 +12091,20 @@ function getDefaultSlashCommands(onOpenImagePicker, onOpenChipEditor, onOpenLink
|
|
|
11785
12091
|
editor.chain().focus().deleteRange(range).insertLoomaTableOfContents().run();
|
|
11786
12092
|
}
|
|
11787
12093
|
},
|
|
12094
|
+
{
|
|
12095
|
+
title: "Footnote",
|
|
12096
|
+
description: "Numbered note at the end of the document",
|
|
12097
|
+
icon: "superscript",
|
|
12098
|
+
keywords: [
|
|
12099
|
+
"footnote",
|
|
12100
|
+
"note",
|
|
12101
|
+
"reference",
|
|
12102
|
+
"citation"
|
|
12103
|
+
],
|
|
12104
|
+
command: ({ editor, range }) => {
|
|
12105
|
+
editor.chain().focus().deleteRange(range).insertLoomaFootnote().run();
|
|
12106
|
+
}
|
|
12107
|
+
},
|
|
11788
12108
|
{
|
|
11789
12109
|
title: "Expand",
|
|
11790
12110
|
description: "Collapsible section with a summary",
|
|
@@ -11852,6 +12172,7 @@ function getDefaultSlashCommands(onOpenImagePicker, onOpenChipEditor, onOpenLink
|
|
|
11852
12172
|
"Image",
|
|
11853
12173
|
"Table",
|
|
11854
12174
|
"Table of contents",
|
|
12175
|
+
"Footnote",
|
|
11855
12176
|
"Expand"
|
|
11856
12177
|
].includes(command.title) ? "Insertions" : "Basic blocks",
|
|
11857
12178
|
isAvailable: (context) => canRunDefaultCommand(command.title, context)
|
|
@@ -11887,6 +12208,7 @@ function canRunDefaultCommand(title, { editor, range }) {
|
|
|
11887
12208
|
withHeaderRow: true
|
|
11888
12209
|
}).run();
|
|
11889
12210
|
case "Table of contents": return chain.insertLoomaTableOfContents().run();
|
|
12211
|
+
case "Footnote": return chain.insertLoomaFootnote().run();
|
|
11890
12212
|
case "Expand": return chain.insertLoomaExpand().run();
|
|
11891
12213
|
case "Divider": return chain.setHorizontalRule().run();
|
|
11892
12214
|
default: return chain.run();
|
|
@@ -12093,4 +12415,4 @@ function createLoomaSlashCommandExtension(options = {}) {
|
|
|
12093
12415
|
});
|
|
12094
12416
|
}
|
|
12095
12417
|
//#endregion
|
|
12096
|
-
export {
|
|
12418
|
+
export { LOOMA_ACTIVE_BLOCK_BLUR_GRACE_MS as $, filterLoomaMentionItems as A, LOOMA_FOOTNOTE_LABEL as B, loomaMarkdownToHtml as C, createLoomaMentionExtension as D, LoomaMentionSuggestionPluginKey as E, LoomaTableOfContents as F, LoomaFigcaption as G, LoomaFootnoteReference as H, getTableOfContentsEntries as I, revealLoomaExpandAt as J, LoomaFigure as K, normalizeTableOfContentsConfig as L, LoomaImage as M, normalizeImageDimension as N, DEFAULT_MENTION_RESULT_LIMIT as O, normalizeImagePlacement as P, LoomaCallout as Q, LoomaTab as R, loomaMarkdownFromDoc as S, siteRelativeHref as T, LoomaFootnotes as U, LoomaFootnote as V, findLoomaFootnote as W, LoomaChip as X, LOOMA_CHIP_COLORS as Y, normalizeLoomaChipColor as Z, getActiveTableCellAlignment as _, getActiveTableUiState as a, setActiveTableCellBackground as b, insertTableAtRange as c, LoomaTableKit as d, LOOMA_ACTIVE_BLOCK_CLASS as et, getDefaultEditorExtensions as f, LoomaTableHeader as g, LoomaTableCell as h, getDefaultSlashCommands as i, normalizeMentionResultLimit as j, MAX_MENTION_RESULT_LIMIT as k, normalizeActiveTableColumnWidths as l, LoomaTable as m, createLoomaSlashCommandExtension as n, LoomaActiveBlock as nt, handleTableAction as o, getLoomaTableExtensions as p, LoomaExpand as q, filterLoomaSlashCommands as r, LoomaActiveBlockPluginKey as rt, handleTableOverlayAction as s, LoomaSlashCommand as t, LOOMA_ACTIVE_BLOCK_TYPING_IDLE_MS as tt, shouldShowTextFormattingToolbar as u, getActiveTableCellBackground as v, createSiteRelativeLinks as w, LoomaSmartPaste as x, setActiveTableCellAlignment as y, LoomaTabs as z };
|
package/editor/expressmark.js
CHANGED
|
@@ -408,7 +408,7 @@ function toBareNode(node, path, context) {
|
|
|
408
408
|
value: string(attrs.label)
|
|
409
409
|
};
|
|
410
410
|
case "loomaFootnotes": return block("container", [], { subType: "footnotes" });
|
|
411
|
-
case "loomaFootnote": return block("container", ["label"], {
|
|
411
|
+
case "loomaFootnote": return block("container", ["label", "count"], {
|
|
412
412
|
subType: "footnote",
|
|
413
413
|
title: title(string(attrs.label))
|
|
414
414
|
});
|
|
@@ -1,18 +1,51 @@
|
|
|
1
1
|
import { Node } from "@tiptap/core";
|
|
2
|
+
import { type Node as ProseMirrorNode } from "@tiptap/pm/model";
|
|
3
|
+
/** A footnote label as Looma Markdown reads it in `[^label]`: no whitespace and no `]`. */
|
|
4
|
+
export declare const LOOMA_FOOTNOTE_LABEL: RegExp;
|
|
2
5
|
/**
|
|
3
|
-
*
|
|
4
|
-
* @
|
|
5
|
-
|
|
6
|
+
* The first note for `label` in `doc` and its position.
|
|
7
|
+
* @failure Returns null when no note has that label.
|
|
8
|
+
*/
|
|
9
|
+
export declare function findLoomaFootnote(doc: ProseMirrorNode, label: string): {
|
|
10
|
+
node: ProseMirrorNode;
|
|
11
|
+
position: number;
|
|
12
|
+
} | null;
|
|
13
|
+
/**
|
|
14
|
+
* A footnote reference, `[^label]`, saved as `<sup><a data-footnote-ref>`. Typing or pasting
|
|
15
|
+
* `[^label]` makes one; the note it needs is created with it.
|
|
16
|
+
* @invariant `label` names its note. `number` and `occurrence`, the note's number and this
|
|
17
|
+
* reference's place among the note's references, follow the document's order on every change.
|
|
6
18
|
*/
|
|
7
19
|
export declare const LoomaFootnoteReference: Node<any, any>;
|
|
20
|
+
declare module "@tiptap/core" {
|
|
21
|
+
interface Commands<ReturnType> {
|
|
22
|
+
loomaFootnotes: {
|
|
23
|
+
/**
|
|
24
|
+
* Inserts a reference at the selection. A new label (the next free number when none is given)
|
|
25
|
+
* also gets an empty note, and the caret moves into it.
|
|
26
|
+
*/
|
|
27
|
+
insertLoomaFootnote: (label?: string) => ReturnType;
|
|
28
|
+
/** Gives a footnote's note and every reference to it a new, unused label. */
|
|
29
|
+
renameLoomaFootnote: (from: string, to: string) => ReturnType;
|
|
30
|
+
/**
|
|
31
|
+
* From a reference (selected, or just before the caret) to the end of its note; from inside a
|
|
32
|
+
* note to just after its first reference.
|
|
33
|
+
*/
|
|
34
|
+
goToLoomaFootnote: () => ReturnType;
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
}
|
|
8
38
|
/**
|
|
9
39
|
* The document's notes, saved as `<section data-footnotes>` with its `<ol>`.
|
|
10
|
-
* @invariant It holds only footnotes
|
|
40
|
+
* @invariant It holds only footnotes and stays the document's last block, one section in number order.
|
|
41
|
+
* @ownership It owns footnote numbering and the back-links in serialized HTML for the whole editor.
|
|
11
42
|
*/
|
|
12
|
-
export declare const LoomaFootnotes: Node<any,
|
|
43
|
+
export declare const LoomaFootnotes: Node<any, {
|
|
44
|
+
known: Map<string, ProseMirrorNode>;
|
|
45
|
+
}>;
|
|
13
46
|
/**
|
|
14
47
|
* One note, `[^label]: …`, saved as `<li id="fn:label">`.
|
|
15
|
-
* @invariant It exists only inside `LoomaFootnotes`.
|
|
16
|
-
*
|
|
48
|
+
* @invariant It exists only inside `LoomaFootnotes`. `count` is how many references point to it. Its
|
|
49
|
+
* back-links are presentation: the editor reads past them and writes them only into saved HTML.
|
|
17
50
|
*/
|
|
18
51
|
export declare const LoomaFootnote: Node<any, any>;
|
|
@@ -11,7 +11,7 @@ export { LoomaCallout, LOOMA_CALLOUT_TONES, type LoomaCalloutTone, } from "./cal
|
|
|
11
11
|
export { LoomaChip, LOOMA_CHIP_COLORS, normalizeLoomaChipColor, type LoomaChipColor } from "./chip.js";
|
|
12
12
|
export { LoomaExpand, revealLoomaExpandAt, type LoomaExpandAttributes } from "./expand.js";
|
|
13
13
|
export { LoomaFigcaption, LoomaFigure } from "./figure.js";
|
|
14
|
-
export { LoomaFootnote, LoomaFootnoteReference, LoomaFootnotes } from "./footnote.js";
|
|
14
|
+
export { findLoomaFootnote, LOOMA_FOOTNOTE_LABEL, LoomaFootnote, LoomaFootnoteReference, LoomaFootnotes } from "./footnote.js";
|
|
15
15
|
export { LoomaTab, LoomaTabs } from "./tabs.js";
|
|
16
16
|
export { LoomaTableOfContents, getTableOfContentsEntries, normalizeTableOfContentsConfig, type LoomaTableOfContentsConfig, type LoomaTableOfContentsEntry, type LoomaTableOfContentsFormat, } from "./table-of-contents.js";
|
|
17
17
|
export { getDefaultEditorExtensions, getLoomaTableExtensions, LoomaTableKit, type DefaultEditorExtensionsOptions, type LoomaCodeLanguages, } from "./preset.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { n as TABLE_CELL_BACKGROUND_PRESETS } from "../chunks/table-backgrounds.js";
|
|
2
|
-
import { $ as
|
|
2
|
+
import { $ as LOOMA_ACTIVE_BLOCK_BLUR_GRACE_MS, A as filterLoomaMentionItems, B as LOOMA_FOOTNOTE_LABEL, C as loomaMarkdownToHtml, D as createLoomaMentionExtension, E as LoomaMentionSuggestionPluginKey, F as LoomaTableOfContents, G as LoomaFigcaption, H as LoomaFootnoteReference, I as getTableOfContentsEntries, J as revealLoomaExpandAt, K as LoomaFigure, L as normalizeTableOfContentsConfig, M as LoomaImage, N as normalizeImageDimension, O as DEFAULT_MENTION_RESULT_LIMIT, P as normalizeImagePlacement, Q as LoomaCallout, R as LoomaTab, S as loomaMarkdownFromDoc, T as siteRelativeHref, U as LoomaFootnotes, V as LoomaFootnote, W as findLoomaFootnote, X as LoomaChip, Y as LOOMA_CHIP_COLORS, Z as normalizeLoomaChipColor, _ as getActiveTableCellAlignment, a as getActiveTableUiState, b as setActiveTableCellBackground, c as insertTableAtRange, d as LoomaTableKit, et as LOOMA_ACTIVE_BLOCK_CLASS, f as getDefaultEditorExtensions, g as LoomaTableHeader, h as LoomaTableCell, i as getDefaultSlashCommands, j as normalizeMentionResultLimit, k as MAX_MENTION_RESULT_LIMIT, l as normalizeActiveTableColumnWidths, m as LoomaTable, n as createLoomaSlashCommandExtension, nt as LoomaActiveBlock, o as handleTableAction, p as getLoomaTableExtensions, q as LoomaExpand, r as filterLoomaSlashCommands, rt as LoomaActiveBlockPluginKey, s as handleTableOverlayAction, t as LoomaSlashCommand, tt as LOOMA_ACTIVE_BLOCK_TYPING_IDLE_MS, u as shouldShowTextFormattingToolbar, v as getActiveTableCellBackground, w as createSiteRelativeLinks, x as LoomaSmartPaste, y as setActiveTableCellAlignment, z as LoomaTabs } from "../chunks/extensions.js";
|
|
3
3
|
import { a as setReferenceDisplay, i as referenceDisplay, n as LoomaReferencePresentation, o as LOOMA_CALLOUT_TONES, r as getReferenceDisplay, t as LoomaReference } from "../chunks/reference-display.js";
|
|
4
|
-
export { DEFAULT_MENTION_RESULT_LIMIT, LOOMA_ACTIVE_BLOCK_BLUR_GRACE_MS, LOOMA_ACTIVE_BLOCK_CLASS, LOOMA_ACTIVE_BLOCK_TYPING_IDLE_MS, LOOMA_CALLOUT_TONES, LOOMA_CHIP_COLORS, LoomaActiveBlock, LoomaActiveBlockPluginKey, LoomaCallout, LoomaChip, LoomaExpand, LoomaFigcaption, LoomaFigure, LoomaFootnote, LoomaFootnoteReference, LoomaFootnotes, LoomaImage, LoomaMentionSuggestionPluginKey, LoomaReference, LoomaReferencePresentation, LoomaSlashCommand, LoomaSmartPaste, LoomaTab, LoomaTable, LoomaTableCell, LoomaTableHeader, LoomaTableKit, LoomaTableOfContents, LoomaTabs, MAX_MENTION_RESULT_LIMIT, TABLE_CELL_BACKGROUND_PRESETS, createLoomaMentionExtension, createLoomaSlashCommandExtension, createSiteRelativeLinks, filterLoomaMentionItems, filterLoomaSlashCommands, getActiveTableCellAlignment, getActiveTableCellBackground, getActiveTableUiState, getDefaultEditorExtensions, getDefaultSlashCommands, getLoomaTableExtensions, getReferenceDisplay, getTableOfContentsEntries, handleTableAction, handleTableOverlayAction, insertTableAtRange, loomaMarkdownFromDoc, loomaMarkdownToHtml, normalizeActiveTableColumnWidths, normalizeImageDimension, normalizeImagePlacement, normalizeLoomaChipColor, normalizeMentionResultLimit, normalizeTableOfContentsConfig, referenceDisplay, revealLoomaExpandAt, setActiveTableCellAlignment, setActiveTableCellBackground, setReferenceDisplay, shouldShowTextFormattingToolbar, siteRelativeHref };
|
|
4
|
+
export { DEFAULT_MENTION_RESULT_LIMIT, LOOMA_ACTIVE_BLOCK_BLUR_GRACE_MS, LOOMA_ACTIVE_BLOCK_CLASS, LOOMA_ACTIVE_BLOCK_TYPING_IDLE_MS, LOOMA_CALLOUT_TONES, LOOMA_CHIP_COLORS, LOOMA_FOOTNOTE_LABEL, LoomaActiveBlock, LoomaActiveBlockPluginKey, LoomaCallout, LoomaChip, LoomaExpand, LoomaFigcaption, LoomaFigure, LoomaFootnote, LoomaFootnoteReference, LoomaFootnotes, LoomaImage, LoomaMentionSuggestionPluginKey, LoomaReference, LoomaReferencePresentation, LoomaSlashCommand, LoomaSmartPaste, LoomaTab, LoomaTable, LoomaTableCell, LoomaTableHeader, LoomaTableKit, LoomaTableOfContents, LoomaTabs, MAX_MENTION_RESULT_LIMIT, TABLE_CELL_BACKGROUND_PRESETS, createLoomaMentionExtension, createLoomaSlashCommandExtension, createSiteRelativeLinks, filterLoomaMentionItems, filterLoomaSlashCommands, findLoomaFootnote, getActiveTableCellAlignment, getActiveTableCellBackground, getActiveTableUiState, getDefaultEditorExtensions, getDefaultSlashCommands, getLoomaTableExtensions, getReferenceDisplay, getTableOfContentsEntries, handleTableAction, handleTableOverlayAction, insertTableAtRange, loomaMarkdownFromDoc, loomaMarkdownToHtml, normalizeActiveTableColumnWidths, normalizeImageDimension, normalizeImagePlacement, normalizeLoomaChipColor, normalizeMentionResultLimit, normalizeTableOfContentsConfig, referenceDisplay, revealLoomaExpandAt, setActiveTableCellAlignment, setActiveTableCellBackground, setReferenceDisplay, shouldShowTextFormattingToolbar, siteRelativeHref };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { Editor } from "@tiptap/core";
|
|
2
|
+
/** The footnote editor's state: the edited reference's label and its note's text. */
|
|
3
|
+
export interface LoomaFootnoteEditingState {
|
|
4
|
+
readonly open: boolean;
|
|
5
|
+
readonly label: string;
|
|
6
|
+
/** The note's text, its blocks on separate lines. */
|
|
7
|
+
readonly note: string;
|
|
8
|
+
/** Whether `note` can be edited as text: the note is one paragraph of unformatted text. */
|
|
9
|
+
readonly editable: boolean;
|
|
10
|
+
/** Why the last label offered was not used, or empty. */
|
|
11
|
+
readonly error: string;
|
|
12
|
+
}
|
|
13
|
+
export declare const LOOMA_FOOTNOTE_EDITING_IDLE: LoomaFootnoteEditingState;
|
|
14
|
+
/**
|
|
15
|
+
* The footnote editor as a state machine: it opens on one reference, writes the note's text as the
|
|
16
|
+
* author types it, and renames the footnote everywhere when a new label is committed.
|
|
17
|
+
*
|
|
18
|
+
* @ownership The host owns presentation: the popover, its anchor, and focus. This owns which footnote
|
|
19
|
+
* is edited and the document changes it makes.
|
|
20
|
+
* @failure A change after the footnote was deleted closes the editor and writes nothing. A label with
|
|
21
|
+
* a space or `]`, or one another footnote uses, is not applied; `error` says why.
|
|
22
|
+
*/
|
|
23
|
+
export interface LoomaFootnoteEditing {
|
|
24
|
+
readonly state: LoomaFootnoteEditingState;
|
|
25
|
+
/** The edited reference's element, for anchoring the editor, or null while it is closed. */
|
|
26
|
+
readonly element: HTMLElement | null;
|
|
27
|
+
/** Calls `listener` after every state change; returns the unsubscribe function. */
|
|
28
|
+
subscribe(listener: () => void): () => void;
|
|
29
|
+
/**
|
|
30
|
+
* Opens on the reference at `position`.
|
|
31
|
+
* @failure Returns false, and stays as it was, when the editor is read-only or no reference is there.
|
|
32
|
+
*/
|
|
33
|
+
open(position: number): boolean;
|
|
34
|
+
/** Replaces the note's text; ignored unless `state.editable`. */
|
|
35
|
+
setNote(note: string): void;
|
|
36
|
+
rename(label: string): void;
|
|
37
|
+
/** Closes the editor and moves the caret to the end of the note. */
|
|
38
|
+
goToNote(): void;
|
|
39
|
+
close(): void;
|
|
40
|
+
}
|
|
41
|
+
export interface LoomaFootnoteEditingOptions {
|
|
42
|
+
editor: Editor;
|
|
43
|
+
/** Read on each opening, so a host can change it while the editor runs. */
|
|
44
|
+
isEditable: () => boolean;
|
|
45
|
+
}
|
|
46
|
+
export declare function createFootnoteEditing(options: LoomaFootnoteEditingOptions): LoomaFootnoteEditing;
|
package/editor/icons.d.ts
CHANGED
package/editor/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { n as TABLE_CELL_BACKGROUND_PRESETS, t as TABLE_CELL_BACKGROUND_OPTIONS } from "./chunks/table-backgrounds.js";
|
|
2
2
|
import { n as resolveTableCellAt, t as measureTableOverlayGeometry } from "./chunks/ui.js";
|
|
3
|
-
import { $ as
|
|
3
|
+
import { $ as LOOMA_ACTIVE_BLOCK_BLUR_GRACE_MS, A as filterLoomaMentionItems, B as LOOMA_FOOTNOTE_LABEL, C as loomaMarkdownToHtml, D as createLoomaMentionExtension, E as LoomaMentionSuggestionPluginKey, F as LoomaTableOfContents, G as LoomaFigcaption, H as LoomaFootnoteReference, I as getTableOfContentsEntries, J as revealLoomaExpandAt, K as LoomaFigure, L as normalizeTableOfContentsConfig, M as LoomaImage, N as normalizeImageDimension, O as DEFAULT_MENTION_RESULT_LIMIT, P as normalizeImagePlacement, Q as LoomaCallout, R as LoomaTab, S as loomaMarkdownFromDoc, T as siteRelativeHref, U as LoomaFootnotes, V as LoomaFootnote, W as findLoomaFootnote, X as LoomaChip, Y as LOOMA_CHIP_COLORS, Z as normalizeLoomaChipColor, _ as getActiveTableCellAlignment, a as getActiveTableUiState, b as setActiveTableCellBackground, c as insertTableAtRange, d as LoomaTableKit, et as LOOMA_ACTIVE_BLOCK_CLASS, f as getDefaultEditorExtensions, g as LoomaTableHeader, h as LoomaTableCell, i as getDefaultSlashCommands, j as normalizeMentionResultLimit, k as MAX_MENTION_RESULT_LIMIT, l as normalizeActiveTableColumnWidths, m as LoomaTable, n as createLoomaSlashCommandExtension, nt as LoomaActiveBlock, o as handleTableAction, p as getLoomaTableExtensions, q as LoomaExpand, r as filterLoomaSlashCommands, rt as LoomaActiveBlockPluginKey, s as handleTableOverlayAction, t as LoomaSlashCommand, tt as LOOMA_ACTIVE_BLOCK_TYPING_IDLE_MS, u as shouldShowTextFormattingToolbar, v as getActiveTableCellBackground, w as createSiteRelativeLinks, x as LoomaSmartPaste, y as setActiveTableCellAlignment, z as LoomaTabs } from "./chunks/extensions.js";
|
|
4
4
|
import { a as setReferenceDisplay, i as referenceDisplay, n as LoomaReferencePresentation, o as LOOMA_CALLOUT_TONES, r as getReferenceDisplay, t as LoomaReference } from "./chunks/reference-display.js";
|
|
5
|
-
import { AlignCenter, AlignLeft, AlignRight, ArrowLeft, Bell, Bold, BookUser, Braces, Calculator, Check, ChevronDown, ChevronLeft, ChevronRight, CircleCheck, CircleDot, CircleQuestionMark, CircleX, CodeXml, Columns3, Compass, CreditCard, Ellipsis, Eraser, ExternalLink, FileText, Folder, GripHorizontal, GripVertical, Heading1, Heading2, Heading3, Highlighter, History, Image, Info, Italic, LayoutDashboard, Lightbulb, Link, List, ListOrdered, ListTodo, LoaderCircle, Merge, MessageSquareWarning, Minus, NotebookPen, PaintBucket, PanelBottom, PanelLeft, PanelRight, PanelTop, Pencil, Pilcrow, Plus, Quote, Receipt, Redo2, Rows3, Search, Settings, Split, Strikethrough, Table2, Tag, Trash2, TriangleAlert, Truck, Underline, Undo2, Unlink, UserRound, Users, X } from "lucide";
|
|
5
|
+
import { AlignCenter, AlignLeft, AlignRight, ArrowLeft, Bell, Bold, BookUser, Braces, Calculator, Check, ChevronDown, ChevronLeft, ChevronRight, CircleCheck, CircleDot, CircleQuestionMark, CircleX, CodeXml, Columns3, Compass, CreditCard, Ellipsis, Eraser, ExternalLink, FileText, Folder, GripHorizontal, GripVertical, Heading1, Heading2, Heading3, Highlighter, History, Image, Info, Italic, LayoutDashboard, Lightbulb, Link, List, ListOrdered, ListTodo, LoaderCircle, Merge, MessageSquareWarning, Minus, NotebookPen, PaintBucket, PanelBottom, PanelLeft, PanelRight, PanelTop, Pencil, Pilcrow, Plus, Quote, Receipt, Redo2, Rows3, Search, Settings, Split, Strikethrough, Superscript, Table2, Tag, Trash2, TriangleAlert, Truck, Underline, Undo2, Unlink, UserRound, Users, X } from "lucide";
|
|
6
6
|
//#region src/editor/icons.ts
|
|
7
7
|
/** The opinionated Lucide set used by Looma's shipped interaction surfaces. */
|
|
8
8
|
var LOOMA_ICONS = {
|
|
@@ -70,6 +70,7 @@ var LOOMA_ICONS = {
|
|
|
70
70
|
settings: Settings,
|
|
71
71
|
split: Split,
|
|
72
72
|
strikethrough: Strikethrough,
|
|
73
|
+
superscript: Superscript,
|
|
73
74
|
tag: Tag,
|
|
74
75
|
table: Table2,
|
|
75
76
|
trash: Trash2,
|
|
@@ -124,4 +125,4 @@ function getVisualViewportRect(owner = window) {
|
|
|
124
125
|
};
|
|
125
126
|
}
|
|
126
127
|
//#endregion
|
|
127
|
-
export { DEFAULT_MENTION_RESULT_LIMIT, LOOMA_ACTIVE_BLOCK_BLUR_GRACE_MS, LOOMA_ACTIVE_BLOCK_CLASS, LOOMA_ACTIVE_BLOCK_TYPING_IDLE_MS, LOOMA_CALLOUT_TONES, LOOMA_CHIP_COLORS, LOOMA_ICONS, LoomaActiveBlock, LoomaActiveBlockPluginKey, LoomaCallout, LoomaChip, LoomaExpand, LoomaFigcaption, LoomaFigure, LoomaFootnote, LoomaFootnoteReference, LoomaFootnotes, LoomaImage, LoomaMentionSuggestionPluginKey, LoomaReference, LoomaReferencePresentation, LoomaSlashCommand, LoomaSmartPaste, LoomaTab, LoomaTable, LoomaTableCell, LoomaTableHeader, LoomaTableKit, LoomaTableOfContents, LoomaTabs, MAX_MENTION_RESULT_LIMIT, TABLE_CELL_BACKGROUND_OPTIONS, TABLE_CELL_BACKGROUND_PRESETS, createLoomaMentionExtension, createLoomaSlashCommandExtension, createSiteRelativeLinks, filterLoomaMentionItems, filterLoomaSlashCommands, getActiveTableCellAlignment, getActiveTableCellBackground, getActiveTableUiState, getDefaultEditorExtensions, getDefaultSlashCommands, getLoomaTableExtensions, getReferenceDisplay, getTableOfContentsEntries, getVisualViewportRect, handleTableAction, handleTableOverlayAction, insertTableAtRange, loomaIconMarkup, loomaMarkdownFromDoc, loomaMarkdownToHtml, measureTableOverlayGeometry, normalizeActiveTableColumnWidths, normalizeImageDimension, normalizeImagePlacement, normalizeLoomaChipColor, normalizeMentionResultLimit, normalizeTableOfContentsConfig, referenceDisplay, resolveTableCellAt, revealLoomaExpandAt, setActiveTableCellAlignment, setActiveTableCellBackground, setReferenceDisplay, shouldShowTextFormattingToolbar, siteRelativeHref };
|
|
128
|
+
export { DEFAULT_MENTION_RESULT_LIMIT, LOOMA_ACTIVE_BLOCK_BLUR_GRACE_MS, LOOMA_ACTIVE_BLOCK_CLASS, LOOMA_ACTIVE_BLOCK_TYPING_IDLE_MS, LOOMA_CALLOUT_TONES, LOOMA_CHIP_COLORS, LOOMA_FOOTNOTE_LABEL, LOOMA_ICONS, LoomaActiveBlock, LoomaActiveBlockPluginKey, LoomaCallout, LoomaChip, LoomaExpand, LoomaFigcaption, LoomaFigure, LoomaFootnote, LoomaFootnoteReference, LoomaFootnotes, LoomaImage, LoomaMentionSuggestionPluginKey, LoomaReference, LoomaReferencePresentation, LoomaSlashCommand, LoomaSmartPaste, LoomaTab, LoomaTable, LoomaTableCell, LoomaTableHeader, LoomaTableKit, LoomaTableOfContents, LoomaTabs, MAX_MENTION_RESULT_LIMIT, TABLE_CELL_BACKGROUND_OPTIONS, TABLE_CELL_BACKGROUND_PRESETS, createLoomaMentionExtension, createLoomaSlashCommandExtension, createSiteRelativeLinks, filterLoomaMentionItems, filterLoomaSlashCommands, findLoomaFootnote, getActiveTableCellAlignment, getActiveTableCellBackground, getActiveTableUiState, getDefaultEditorExtensions, getDefaultSlashCommands, getLoomaTableExtensions, getReferenceDisplay, getTableOfContentsEntries, getVisualViewportRect, handleTableAction, handleTableOverlayAction, insertTableAtRange, loomaIconMarkup, loomaMarkdownFromDoc, loomaMarkdownToHtml, measureTableOverlayGeometry, normalizeActiveTableColumnWidths, normalizeImageDimension, normalizeImagePlacement, normalizeLoomaChipColor, normalizeMentionResultLimit, normalizeTableOfContentsConfig, referenceDisplay, resolveTableCellAt, revealLoomaExpandAt, setActiveTableCellAlignment, setActiveTableCellBackground, setReferenceDisplay, shouldShowTextFormattingToolbar, siteRelativeHref };
|