@meowdown/core 0.67.1 → 0.68.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.d.ts +51 -5
- package/dist/index.js +101 -85
- package/dist/style.css +4 -0
- package/package.json +9 -8
package/README.md
CHANGED
|
@@ -31,7 +31,7 @@ const markdown = docToMarkdown(editor.state.doc)
|
|
|
31
31
|
|
|
32
32
|
[CommonMark](https://commonmark.org/) and [GFM](https://github.github.com/gfm/), plus:
|
|
33
33
|
|
|
34
|
-
- Wikilinks (`[[target]]
|
|
34
|
+
- Wikilinks (`[[target]]`; alias forms such as `[[target|alias]]` are the host's to split via `resolveWikilink`)
|
|
35
35
|
- Wiki embeds (`![[path]]`)
|
|
36
36
|
- Tags (`#tag`)
|
|
37
37
|
- Highlight (`==highlight==`)
|
package/dist/index.d.ts
CHANGED
|
@@ -215,7 +215,14 @@ interface MdLinkTextAttrs {
|
|
|
215
215
|
href: string;
|
|
216
216
|
}
|
|
217
217
|
interface MdWikilinkAttrs {
|
|
218
|
+
/**
|
|
219
|
+
* Target passed to click and hover handlers: the bracketed text unless the
|
|
220
|
+
* host's `resolveWikilink` replaced it.
|
|
221
|
+
*/
|
|
218
222
|
target: string;
|
|
223
|
+
/**
|
|
224
|
+
* Label shown in place of the source, or `''` to show the target.
|
|
225
|
+
*/
|
|
219
226
|
display: string;
|
|
220
227
|
}
|
|
221
228
|
/**
|
|
@@ -593,6 +600,45 @@ export declare function formatSizedWikiEmbed(target: string, width: number, heig
|
|
|
593
600
|
*/
|
|
594
601
|
export declare function wikiEmbedBasename(target: string): string;
|
|
595
602
|
//#endregion
|
|
603
|
+
//#region src/extensions/wikilink.d.ts
|
|
604
|
+
/**
|
|
605
|
+
* What {@link WikilinkResolver} sees for one `[[...]]` wikilink.
|
|
606
|
+
*/
|
|
607
|
+
interface WikilinkPayload {
|
|
608
|
+
/**
|
|
609
|
+
* The text between the brackets, trimmed. Meowdown reads no syntax inside
|
|
610
|
+
* it: an alias form such as `[[target|alias]]` arrives here whole.
|
|
611
|
+
*/
|
|
612
|
+
target: string;
|
|
613
|
+
}
|
|
614
|
+
/**
|
|
615
|
+
* A resolved wikilink.
|
|
616
|
+
*/
|
|
617
|
+
interface WikilinkResolution {
|
|
618
|
+
/**
|
|
619
|
+
* Target passed to click and hover handlers. Defaults to the bracketed text.
|
|
620
|
+
*/
|
|
621
|
+
target?: string;
|
|
622
|
+
/**
|
|
623
|
+
* Label shown in place of the source. Defaults to the target.
|
|
624
|
+
*/
|
|
625
|
+
display?: string;
|
|
626
|
+
}
|
|
627
|
+
/**
|
|
628
|
+
* Resolves one `[[...]]` wikilink into the target its handlers receive and
|
|
629
|
+
* the label its chip shows; the Markdown source stays as written. Return
|
|
630
|
+
* `undefined` to use the bracketed text as both. The resolver participates
|
|
631
|
+
* in the parse cache, so it must be pure: the same payload must always
|
|
632
|
+
* return the same result.
|
|
633
|
+
*/
|
|
634
|
+
type WikilinkResolver = (link: WikilinkPayload) => WikilinkResolution | undefined;
|
|
635
|
+
/**
|
|
636
|
+
* Host options for wikilink parsing.
|
|
637
|
+
*/
|
|
638
|
+
interface WikilinkOptions {
|
|
639
|
+
resolveWikilink?: WikilinkResolver;
|
|
640
|
+
}
|
|
641
|
+
//#endregion
|
|
596
642
|
//#region src/extensions/inline-text-to-mark-chunks.d.ts
|
|
597
643
|
/**
|
|
598
644
|
* What {@link FileLinkResolver} sees for one `[label](url)` link.
|
|
@@ -632,7 +678,7 @@ interface FileLinkOptions {
|
|
|
632
678
|
/**
|
|
633
679
|
* Host options that influence source-backed inline atom parsing.
|
|
634
680
|
*/
|
|
635
|
-
type InlineMarkOptions = FileLinkOptions & WikiEmbedOptions;
|
|
681
|
+
type InlineMarkOptions = FileLinkOptions & WikiEmbedOptions & WikilinkOptions;
|
|
636
682
|
interface InlineMarkContext {
|
|
637
683
|
/**
|
|
638
684
|
* Effective document-wide definitions, keyed by normalized reference label.
|
|
@@ -861,9 +907,9 @@ declare function defineEditorExtensionImpl(options: EditorExtensionOptions): imp
|
|
|
861
907
|
type EditorExtension = ReturnType<typeof defineEditorExtensionImpl>;
|
|
862
908
|
/**
|
|
863
909
|
* Options for {@link defineEditorExtension}. Creation-time configuration:
|
|
864
|
-
* `resolveFileLink` and `
|
|
865
|
-
* pipeline, so changing them requires rebuilding the
|
|
866
|
-
* only the initial value.
|
|
910
|
+
* `resolveFileLink`, `resolveWikiEmbed`, and `resolveWikilink` are baked into
|
|
911
|
+
* the editor's parse pipeline, so changing them requires rebuilding the
|
|
912
|
+
* editor; `markMode` is only the initial value.
|
|
867
913
|
*/
|
|
868
914
|
type EditorExtensionOptions = InlineMarkOptions & {
|
|
869
915
|
/**
|
|
@@ -1594,4 +1640,4 @@ export declare function getSelectedText(state: EditorState): string;
|
|
|
1594
1640
|
*/
|
|
1595
1641
|
export declare function getVirtualElementFromRange(view: EditorView, range: PositionRange): VirtualElement;
|
|
1596
1642
|
//#endregion
|
|
1597
|
-
export { type AcceptPendingReplacementOptions, type CheckRoundTripOptions, type CodeBlockAttrs, type CodeBlockFenceStyle, type CodeToken, type DocToMarkdownOptions, type EditorExtension, type EditorExtensionOptions, type EmbedDescriptor, type ExitBoundaryHandler, type ExitBoundaryOptions, type FileClickHandler, type FileClickPayload, type FileInfo, type FileInfoResolver, type FileLinkOptions, type FileLinkPayload, type FileLinkResolver, type FilePasteHandler, type FilePasteOptions, type FileSaveErrorHandler, type FileViewOptions, type FollowLinkHandlers, type ImageClickHandler, type ImageClickPayload, type ImageOptions, type InlineMarkContext, type InlineMarkOptions, type KaTeXRender, type LanguageItem, type LinkAttrs, type LinkClickHandler, type LinkClickPayload, type LinkCopyHandler, type LinkCopyPayload, type LinkEditHandler, type LinkEditOptions, type LinkHoverHandler, type LinkHoverOptions, type LinkPreview, type LinkPreviewResolver, type LinkUnit, type ListMarker, type MarkChunk, type MarkMode, type MarkName, type MarkdownToDocOptions, type MdFileAttrs, type MdImageAttrs, type MdLinkTextAttrs, type MdMathAttrs, type MdWikilinkAttrs, type MeowdownCodeBlockAttrs, type MeowdownHTMLCommentAttrs, type MeowdownListAttrs, type MeowdownTableCellAttrs, type NodeName, type ParsedWikiEmbed, type PendingReplacement, type PendingReplacementEvent, type PendingReplacementHandler, type PendingReplacementMode, type PendingReplacementOutcome, type PlaceholderOptions, type PositionRange, Priority, type ReferenceDefinition, type ReferenceDefinitionIndex, type ReferenceDefinitions, type RoundTripFidelity, type SearchStatus, type SearchStatusHandler, type StartPendingReplacementOptions, type TableColumnAlign, type TagClickHandler, type TagClickPayload, type TypedEditor, type TypedMarkBuilders, type VirtualElement, type WikiEmbedOptions, type WikiEmbedResolution, type WikiEmbedResolver, type WikilinkClickHandler, type WikilinkClickPayload, type WikilinkHoverHandler, type WikilinkHoverHit, defineCodeBlockPreviewPlugin, definePlaceholder, defineReadonly, defineSearchStatusHandler, getSearchStatus, isCodeBlockPreviewHiddenDecoration, withPriority };
|
|
1643
|
+
export { type AcceptPendingReplacementOptions, type CheckRoundTripOptions, type CodeBlockAttrs, type CodeBlockFenceStyle, type CodeToken, type DocToMarkdownOptions, type EditorExtension, type EditorExtensionOptions, type EmbedDescriptor, type ExitBoundaryHandler, type ExitBoundaryOptions, type FileClickHandler, type FileClickPayload, type FileInfo, type FileInfoResolver, type FileLinkOptions, type FileLinkPayload, type FileLinkResolver, type FilePasteHandler, type FilePasteOptions, type FileSaveErrorHandler, type FileViewOptions, type FollowLinkHandlers, type ImageClickHandler, type ImageClickPayload, type ImageOptions, type InlineMarkContext, type InlineMarkOptions, type KaTeXRender, type LanguageItem, type LinkAttrs, type LinkClickHandler, type LinkClickPayload, type LinkCopyHandler, type LinkCopyPayload, type LinkEditHandler, type LinkEditOptions, type LinkHoverHandler, type LinkHoverOptions, type LinkPreview, type LinkPreviewResolver, type LinkUnit, type ListMarker, type MarkChunk, type MarkMode, type MarkName, type MarkdownToDocOptions, type MdFileAttrs, type MdImageAttrs, type MdLinkTextAttrs, type MdMathAttrs, type MdWikilinkAttrs, type MeowdownCodeBlockAttrs, type MeowdownHTMLCommentAttrs, type MeowdownListAttrs, type MeowdownTableCellAttrs, type NodeName, type ParsedWikiEmbed, type PendingReplacement, type PendingReplacementEvent, type PendingReplacementHandler, type PendingReplacementMode, type PendingReplacementOutcome, type PlaceholderOptions, type PositionRange, Priority, type ReferenceDefinition, type ReferenceDefinitionIndex, type ReferenceDefinitions, type RoundTripFidelity, type SearchStatus, type SearchStatusHandler, type StartPendingReplacementOptions, type TableColumnAlign, type TagClickHandler, type TagClickPayload, type TypedEditor, type TypedMarkBuilders, type VirtualElement, type WikiEmbedOptions, type WikiEmbedResolution, type WikiEmbedResolver, type WikilinkClickHandler, type WikilinkClickPayload, type WikilinkHoverHandler, type WikilinkHoverHit, type WikilinkOptions, type WikilinkPayload, type WikilinkResolution, type WikilinkResolver, defineCodeBlockPreviewPlugin, definePlaceholder, defineReadonly, defineSearchStatusHandler, getSearchStatus, isCodeBlockPreviewHiddenDecoration, withPriority };
|
package/dist/index.js
CHANGED
|
@@ -190,7 +190,9 @@ function computeRevealDecorations(state, mode) {
|
|
|
190
190
|
});
|
|
191
191
|
}
|
|
192
192
|
if (ranges.length === 0) return;
|
|
193
|
-
const decorations = ranges.map((range) =>
|
|
193
|
+
const decorations = ranges.map((range) => {
|
|
194
|
+
return Decoration.inline(range.from, range.to, { class: "show" });
|
|
195
|
+
});
|
|
194
196
|
return DecorationSet.create(state.doc, decorations);
|
|
195
197
|
}
|
|
196
198
|
function defineMarkMode(mode) {
|
|
@@ -962,11 +964,13 @@ function headingFromDOM() {
|
|
|
962
964
|
4,
|
|
963
965
|
5,
|
|
964
966
|
6
|
|
965
|
-
].map((level) =>
|
|
966
|
-
level,
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
967
|
+
].map((level) => {
|
|
968
|
+
return createSourceTextRule(`h${level}`, "heading", (dom) => ({
|
|
969
|
+
level,
|
|
970
|
+
setextUnderline: parsePositiveInteger(dom.getAttribute("data-setext-underline")) ?? null,
|
|
971
|
+
closingHashes: parsePositiveInteger(dom.getAttribute("data-closing-hashes")) ?? null
|
|
972
|
+
}));
|
|
973
|
+
});
|
|
970
974
|
}
|
|
971
975
|
function defineSetextUnderlineAttr() {
|
|
972
976
|
return defineNodeAttr({
|
|
@@ -3038,67 +3042,6 @@ function wikiEmbedBasename(target) {
|
|
|
3038
3042
|
}
|
|
3039
3043
|
}
|
|
3040
3044
|
|
|
3041
|
-
//#endregion
|
|
3042
|
-
//#region src/extensions/wikilink.ts
|
|
3043
|
-
/**
|
|
3044
|
-
* Splits `[[target]]`/`[[target|alias]]` into its target and display label (the alias, or empty).
|
|
3045
|
-
*/
|
|
3046
|
-
function parseWikilink(text) {
|
|
3047
|
-
const inner = text.replace(/^\[\[/, "").replace(/\]\]$/, "");
|
|
3048
|
-
const pipe = inner.indexOf("|");
|
|
3049
|
-
if (pipe < 0) return {
|
|
3050
|
-
target: inner.trim(),
|
|
3051
|
-
display: ""
|
|
3052
|
-
};
|
|
3053
|
-
return {
|
|
3054
|
-
target: inner.slice(0, pipe).trim(),
|
|
3055
|
-
display: inner.slice(pipe + 1).trim()
|
|
3056
|
-
};
|
|
3057
|
-
}
|
|
3058
|
-
/**
|
|
3059
|
-
* Render `mdWikilink` as a non-editable label standing in for the raw source.
|
|
3060
|
-
* The source stays in `contentDOM` after the label, hidden by `style.css`
|
|
3061
|
-
* (`.md-atom-view-content`); the whole wikilink is one caret stop owned by
|
|
3062
|
-
* `defineAtomMarkNavigation`.
|
|
3063
|
-
*/
|
|
3064
|
-
function createWikilinkMarkView() {
|
|
3065
|
-
return (mark) => {
|
|
3066
|
-
const attrs = mark.attrs;
|
|
3067
|
-
const dom = document.createElement("span");
|
|
3068
|
-
dom.className = "md-wikilink-view md-atom-view";
|
|
3069
|
-
const preview = document.createElement("span");
|
|
3070
|
-
preview.className = "md-wikilink-view-preview md-atom-view-preview";
|
|
3071
|
-
preview.contentEditable = "false";
|
|
3072
|
-
preview.dataset.testid = "wikilink";
|
|
3073
|
-
dom.appendChild(preview);
|
|
3074
|
-
const label = document.createElement("span");
|
|
3075
|
-
label.className = "md-wikilink-view-label";
|
|
3076
|
-
label.contentEditable = "false";
|
|
3077
|
-
label.textContent = attrs.display || attrs.target;
|
|
3078
|
-
preview.appendChild(label);
|
|
3079
|
-
const contentDOM = document.createElement("span");
|
|
3080
|
-
contentDOM.className = "md-wikilink-view-content md-atom-view-content";
|
|
3081
|
-
dom.appendChild(contentDOM);
|
|
3082
|
-
return {
|
|
3083
|
-
dom,
|
|
3084
|
-
contentDOM,
|
|
3085
|
-
ignoreMutation: (mutation) => !contentDOM.contains(mutation.target)
|
|
3086
|
-
};
|
|
3087
|
-
};
|
|
3088
|
-
}
|
|
3089
|
-
/**
|
|
3090
|
-
* Render `[[target]]`/`[[target|alias]]` as an immutable inline label (a mark
|
|
3091
|
-
* view) standing in for the raw source. The single-caret-stop behavior comes
|
|
3092
|
-
* from the shared `defineAtomMarkNavigation` in the editor extension, which
|
|
3093
|
-
* treats `mdWikilink` (and `mdImage`) as one unit.
|
|
3094
|
-
*/
|
|
3095
|
-
function defineWikilink() {
|
|
3096
|
-
return defineMarkView({
|
|
3097
|
-
name: "mdWikilink",
|
|
3098
|
-
constructor: createWikilinkMarkView()
|
|
3099
|
-
});
|
|
3100
|
-
}
|
|
3101
|
-
|
|
3102
3045
|
//#endregion
|
|
3103
3046
|
//#region src/extensions/inline-text-to-mark-chunks.ts
|
|
3104
3047
|
/**
|
|
@@ -3221,7 +3164,7 @@ function walkAtomChild(nodes, index, parentMarks, text, marks, out, options, con
|
|
|
3221
3164
|
const node = nodes[index];
|
|
3222
3165
|
switch (node.type) {
|
|
3223
3166
|
case LEZER_NODE_IDS.Wikilink:
|
|
3224
|
-
walkWikilink(node, parentMarks, text, marks, out);
|
|
3167
|
+
walkWikilink(node, parentMarks, text, marks, out, options);
|
|
3225
3168
|
return node.to;
|
|
3226
3169
|
case LEZER_NODE_IDS.WikiEmbed:
|
|
3227
3170
|
walkWikiEmbed(node, parentMarks, text, marks, out, options);
|
|
@@ -3577,16 +3520,18 @@ function walkMath(node, parentMarks, text, marks, out) {
|
|
|
3577
3520
|
emit(out, markNodes[1].from, node.to, [...base, marks.mdMark.create()]);
|
|
3578
3521
|
}
|
|
3579
3522
|
/**
|
|
3580
|
-
* Special walker for a wikilink `[[
|
|
3523
|
+
* Special walker for a wikilink `[[...]]`. The bracketed text is the target
|
|
3524
|
+
* and the label unless the host's `resolveWikilink` replaces either.
|
|
3581
3525
|
*/
|
|
3582
|
-
function walkWikilink(node, parentMarks, text, marks, out) {
|
|
3583
|
-
const
|
|
3526
|
+
function walkWikilink(node, parentMarks, text, marks, out, options) {
|
|
3527
|
+
const source = text.slice(node.from + 2, node.to - 2).trim();
|
|
3528
|
+
const resolution = options?.resolveWikilink?.({ target: source });
|
|
3584
3529
|
emit(out, node.from, node.to, [
|
|
3585
3530
|
...parentMarks,
|
|
3586
3531
|
createUnitPack(marks, out, parentMarks, node.from, { key: "wikilink" }),
|
|
3587
3532
|
marks.mdWikilink.create({
|
|
3588
|
-
target,
|
|
3589
|
-
display
|
|
3533
|
+
target: resolution?.target ?? source,
|
|
3534
|
+
display: resolution?.display ?? ""
|
|
3590
3535
|
})
|
|
3591
3536
|
]);
|
|
3592
3537
|
}
|
|
@@ -4041,7 +3986,7 @@ function defineMdTag() {
|
|
|
4041
3986
|
});
|
|
4042
3987
|
}
|
|
4043
3988
|
/**
|
|
4044
|
-
* Covers the whole `[[
|
|
3989
|
+
* Covers the whole `[[...]]` source.
|
|
4045
3990
|
*/
|
|
4046
3991
|
function defineMdWikilink() {
|
|
4047
3992
|
return defineMarkSpec({
|
|
@@ -4428,11 +4373,13 @@ function toggleInline(spec) {
|
|
|
4428
4373
|
return false;
|
|
4429
4374
|
});
|
|
4430
4375
|
const remove = segments.length > 0 && segments.every((segment) => segment.active);
|
|
4431
|
-
const edits = segments.filter((segment) => remove || !segment.active).flatMap((segment) =>
|
|
4432
|
-
|
|
4433
|
-
|
|
4434
|
-
|
|
4435
|
-
|
|
4376
|
+
const edits = segments.filter((segment) => remove || !segment.active).flatMap((segment) => {
|
|
4377
|
+
return toggleInlineEdits(segment.text, segment.from, segment.to, spec, remove).map((edit) => ({
|
|
4378
|
+
from: edit.from + segment.base,
|
|
4379
|
+
to: edit.to + segment.base,
|
|
4380
|
+
insert: edit.insert
|
|
4381
|
+
}));
|
|
4382
|
+
});
|
|
4436
4383
|
if (edits.length === 0) return false;
|
|
4437
4384
|
if (dispatch) {
|
|
4438
4385
|
const tr = state.tr;
|
|
@@ -4513,7 +4460,9 @@ function lastMarkRunIn(state, range, markName) {
|
|
|
4513
4460
|
* the `mdLinkUri` run locates the `( )` body.
|
|
4514
4461
|
*/
|
|
4515
4462
|
function getLinkUnitAt(state, pos) {
|
|
4516
|
-
const unit = getMarkRangeAt(state, pos, "mdPack", (mark) =>
|
|
4463
|
+
const unit = getMarkRangeAt(state, pos, "mdPack", (mark) => {
|
|
4464
|
+
return mark.attrs.key.startsWith("link-");
|
|
4465
|
+
});
|
|
4517
4466
|
if (!unit) return;
|
|
4518
4467
|
const attrs = unit.mark.attrs;
|
|
4519
4468
|
const unitRange = {
|
|
@@ -5737,7 +5686,8 @@ function tryCoordsAtPos(view, pos, side) {
|
|
|
5737
5686
|
let coords;
|
|
5738
5687
|
try {
|
|
5739
5688
|
coords = view.coordsAtPos(pos, side);
|
|
5740
|
-
} catch {
|
|
5689
|
+
} catch (error) {
|
|
5690
|
+
console.warn(`[meowdown] Failed to get caret coords at pos ${pos}:`, error);
|
|
5741
5691
|
return;
|
|
5742
5692
|
}
|
|
5743
5693
|
return isPointRect(coords) ? void 0 : coords;
|
|
@@ -5758,9 +5708,12 @@ function findNativeCaretRect(view) {
|
|
|
5758
5708
|
if (!view.dom.contains(selection.anchorNode)) return void 0;
|
|
5759
5709
|
const range = selection.getRangeAt(0).cloneRange();
|
|
5760
5710
|
range.collapse(true);
|
|
5711
|
+
return findLastRangeRect(range);
|
|
5712
|
+
}
|
|
5713
|
+
function findLastRangeRect(range) {
|
|
5761
5714
|
const rects = Array.from(range.getClientRects()).filter((rect) => rect.height > 0);
|
|
5762
|
-
if (rects.length === 0) return void 0;
|
|
5763
5715
|
const rect = rects[rects.length - 1];
|
|
5716
|
+
if (rect == null) return void 0;
|
|
5764
5717
|
return {
|
|
5765
5718
|
left: rect.left,
|
|
5766
5719
|
top: rect.top,
|
|
@@ -5773,18 +5726,35 @@ function findCoordsCaretRect(view) {
|
|
|
5773
5726
|
const runBefore = getHiddenRunBefore(state, head);
|
|
5774
5727
|
const runAfter = getHiddenRunAfter(state, head);
|
|
5775
5728
|
const afterLineBreak = isAfterLineBreak($head);
|
|
5776
|
-
const
|
|
5777
|
-
const probes = [[head,
|
|
5729
|
+
const previousLineTop = afterLineBreak ? tryCoordsAtPos(view, head, -1)?.top : void 0;
|
|
5730
|
+
const probes = afterLineBreak ? [[head, false]] : [[head, runBefore == null], [head, runBefore != null]];
|
|
5778
5731
|
if (runBefore != null) probes.push([runBefore.from, true]);
|
|
5779
5732
|
if (runAfter != null) probes.push([runAfter.to, false]);
|
|
5780
5733
|
for (const [pos, beforeSide] of probes) {
|
|
5781
5734
|
const coords = tryCoordsAtPos(view, pos, beforeSide ? -1 : 1);
|
|
5782
|
-
if (coords
|
|
5735
|
+
if (coords == null || coords.bottom <= coords.top) continue;
|
|
5736
|
+
if (pos === head && previousLineTop != null && coords.top <= previousLineTop) continue;
|
|
5737
|
+
return {
|
|
5783
5738
|
left: coords.left,
|
|
5784
5739
|
top: coords.top,
|
|
5785
5740
|
height: coords.bottom - coords.top
|
|
5786
5741
|
};
|
|
5787
5742
|
}
|
|
5743
|
+
if (previousLineTop != null) {
|
|
5744
|
+
const collapsed = findCollapsedRangeRect(view, head);
|
|
5745
|
+
if (collapsed != null && collapsed.top > previousLineTop) return collapsed;
|
|
5746
|
+
}
|
|
5747
|
+
}
|
|
5748
|
+
function findCollapsedRangeRect(view, pos) {
|
|
5749
|
+
try {
|
|
5750
|
+
const { node, offset } = view.domAtPos(pos, 0);
|
|
5751
|
+
const range = view.dom.ownerDocument.createRange();
|
|
5752
|
+
range.setStart(node, offset);
|
|
5753
|
+
range.collapse(true);
|
|
5754
|
+
return findLastRangeRect(range);
|
|
5755
|
+
} catch {
|
|
5756
|
+
return;
|
|
5757
|
+
}
|
|
5788
5758
|
}
|
|
5789
5759
|
function findAtomCaretRect(view) {
|
|
5790
5760
|
const state = view.state;
|
|
@@ -6055,6 +6025,52 @@ function defineViewAttributes(attributes) {
|
|
|
6055
6025
|
return definePlugin(new Plugin({ props: { attributes } }));
|
|
6056
6026
|
}
|
|
6057
6027
|
|
|
6028
|
+
//#endregion
|
|
6029
|
+
//#region src/extensions/wikilink.ts
|
|
6030
|
+
/**
|
|
6031
|
+
* Render `mdWikilink` as a non-editable label standing in for the raw source.
|
|
6032
|
+
* The source stays in `contentDOM` after the label, hidden by `style.css`
|
|
6033
|
+
* (`.md-atom-view-content`); the whole wikilink is one caret stop owned by
|
|
6034
|
+
* `defineAtomMarkNavigation`.
|
|
6035
|
+
*/
|
|
6036
|
+
function createWikilinkMarkView() {
|
|
6037
|
+
return (mark) => {
|
|
6038
|
+
const attrs = mark.attrs;
|
|
6039
|
+
const dom = document.createElement("span");
|
|
6040
|
+
dom.className = "md-wikilink-view md-atom-view";
|
|
6041
|
+
const preview = document.createElement("span");
|
|
6042
|
+
preview.className = "md-wikilink-view-preview md-atom-view-preview";
|
|
6043
|
+
preview.contentEditable = "false";
|
|
6044
|
+
preview.dataset.testid = "wikilink";
|
|
6045
|
+
dom.appendChild(preview);
|
|
6046
|
+
const label = document.createElement("span");
|
|
6047
|
+
label.className = "md-wikilink-view-label";
|
|
6048
|
+
label.contentEditable = "false";
|
|
6049
|
+
label.textContent = attrs.display || attrs.target;
|
|
6050
|
+
preview.appendChild(label);
|
|
6051
|
+
const contentDOM = document.createElement("span");
|
|
6052
|
+
contentDOM.className = "md-wikilink-view-content md-atom-view-content";
|
|
6053
|
+
dom.appendChild(contentDOM);
|
|
6054
|
+
return {
|
|
6055
|
+
dom,
|
|
6056
|
+
contentDOM,
|
|
6057
|
+
ignoreMutation: (mutation) => !contentDOM.contains(mutation.target)
|
|
6058
|
+
};
|
|
6059
|
+
};
|
|
6060
|
+
}
|
|
6061
|
+
/**
|
|
6062
|
+
* Render `[[...]]` as an immutable inline label (a mark
|
|
6063
|
+
* view) standing in for the raw source. The single-caret-stop behavior comes
|
|
6064
|
+
* from the shared `defineAtomMarkNavigation` in the editor extension, which
|
|
6065
|
+
* treats `mdWikilink` (and `mdImage`) as one unit.
|
|
6066
|
+
*/
|
|
6067
|
+
function defineWikilink() {
|
|
6068
|
+
return defineMarkView({
|
|
6069
|
+
name: "mdWikilink",
|
|
6070
|
+
constructor: createWikilinkMarkView()
|
|
6071
|
+
});
|
|
6072
|
+
}
|
|
6073
|
+
|
|
6058
6074
|
//#endregion
|
|
6059
6075
|
//#region src/extensions/extension.ts
|
|
6060
6076
|
function defineEditorExtensionImpl(options) {
|
package/dist/style.css
CHANGED
|
@@ -691,6 +691,10 @@
|
|
|
691
691
|
display: contents;
|
|
692
692
|
}
|
|
693
693
|
|
|
694
|
+
.ProseMirror .md-pack[data-key="noLink"] {
|
|
695
|
+
display: inline;
|
|
696
|
+
}
|
|
697
|
+
|
|
694
698
|
.ProseMirror[data-mark-mode="hide"], .ProseMirror[data-mark-mode="focus"] {
|
|
695
699
|
& .md-mark, & .md-link-uri, & .md-link-title {
|
|
696
700
|
letter-spacing: 0;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meowdown/core",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.68.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -26,12 +26,12 @@
|
|
|
26
26
|
"@floating-ui/dom": "^1.8.0",
|
|
27
27
|
"@lezer/highlight": "^1.2.3",
|
|
28
28
|
"@ocavue/utils": "^1.7.0",
|
|
29
|
-
"@prosekit/core": "^0.13.
|
|
30
|
-
"@prosekit/extensions": "^0.18.
|
|
29
|
+
"@prosekit/core": "^0.13.2",
|
|
30
|
+
"@prosekit/extensions": "^0.18.2",
|
|
31
31
|
"@prosekit/pm": "^0.1.19",
|
|
32
|
-
"@prosekit/web": "^0.9.
|
|
32
|
+
"@prosekit/web": "^0.9.2",
|
|
33
33
|
"hast-util-to-mdast": "^10.1.2",
|
|
34
|
-
"katex": "^0.18.
|
|
34
|
+
"katex": "^0.18.5",
|
|
35
35
|
"mdast-util-to-markdown": "^2.1.2",
|
|
36
36
|
"micromark-util-decode-string": "^2.0.1",
|
|
37
37
|
"micromark-util-normalize-identifier": "^2.0.1",
|
|
@@ -43,19 +43,20 @@
|
|
|
43
43
|
"remark-stringify": "^11.0.0",
|
|
44
44
|
"unicode-by-name": "^0.2.0",
|
|
45
45
|
"unified": "^11.0.5",
|
|
46
|
-
"@meowdown/markdown": "^0.
|
|
46
|
+
"@meowdown/markdown": "^0.68.0"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@ocavue/tsconfig": "^0.7.1",
|
|
50
|
-
"@tsdown/css": "^0.23.0-
|
|
50
|
+
"@tsdown/css": "^0.23.0-rc.1",
|
|
51
51
|
"@types/hast": "^3.0.5",
|
|
52
52
|
"@types/mdast": "^4.0.4",
|
|
53
53
|
"@vitest/browser-playwright": "^4.1.11",
|
|
54
54
|
"commonmark.json": "^0.31.0",
|
|
55
55
|
"dedent": "^1.7.2",
|
|
56
56
|
"diffable-html-snapshot": "^0.3.0",
|
|
57
|
-
"tsdown": "^0.23.0-
|
|
57
|
+
"tsdown": "^0.23.0-rc.1",
|
|
58
58
|
"vitest": "^4.1.11",
|
|
59
|
+
"vitest-browser-commands": "^0.4.1",
|
|
59
60
|
"@meowdown/vitest": "0.0.0"
|
|
60
61
|
},
|
|
61
62
|
"publishConfig": {
|