@meowdown/core 0.71.2 → 0.72.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/dist/index.d.ts +10 -13
- package/dist/index.js +90 -107
- package/package.json +7 -7
package/dist/index.d.ts
CHANGED
|
@@ -6,7 +6,6 @@ import { SearchStatus, SearchStatusHandler, defineSearchStatusHandler, getSearch
|
|
|
6
6
|
import { EditorView } from "@prosekit/pm/view";
|
|
7
7
|
import { EditorNode, Mark, ProseMirrorNode } from "@prosekit/pm/model";
|
|
8
8
|
import { ListAttrs } from "@prosekit/extensions/list";
|
|
9
|
-
import { parseXPostId } from "@post-embed/schema";
|
|
10
9
|
import { HorizontalRuleExtension } from "@prosekit/extensions/horizontal-rule";
|
|
11
10
|
import { Resolver } from "@post-embed/elements/x";
|
|
12
11
|
import { render } from "katex";
|
|
@@ -781,11 +780,6 @@ export declare function defineFollowLinkHandler(getHandlers?: (state: EditorStat
|
|
|
781
780
|
//#region src/extensions/post-embed.d.ts
|
|
782
781
|
type XPostResolver = Resolver<XPost>;
|
|
783
782
|
type YouTubeVideoResolver = Resolver<YouTubeVideo>;
|
|
784
|
-
type PostEmbedKind = 'x-post' | 'youtube-video';
|
|
785
|
-
/**
|
|
786
|
-
* The post-embed card an image `src` renders as, or `undefined` for a plain image.
|
|
787
|
-
*/
|
|
788
|
-
export declare function matchPostEmbed(src: string): PostEmbedKind | undefined;
|
|
789
783
|
export declare const defaultResolveXPost: XPostResolver;
|
|
790
784
|
export declare const defaultResolveYouTubeVideo: YouTubeVideoResolver;
|
|
791
785
|
/**
|
|
@@ -1447,7 +1441,7 @@ interface LinkHoverOptions {
|
|
|
1447
1441
|
}
|
|
1448
1442
|
/**
|
|
1449
1443
|
* Track the link under the user's attention: a mouse hover after a short
|
|
1450
|
-
*
|
|
1444
|
+
* delay, or a touch tap immediately, since touch has no hover. Without the
|
|
1451
1445
|
* tap entry, the popup's preview and actions would stay unreachable on
|
|
1452
1446
|
* phones, where a tap on a link only places the caret and raises the
|
|
1453
1447
|
* software keyboard.
|
|
@@ -1564,13 +1558,16 @@ interface WikilinkHoverHit extends WikilinkHit {
|
|
|
1564
1558
|
*/
|
|
1565
1559
|
type WikilinkHoverHandler = (hit: WikilinkHoverHit | undefined) => void;
|
|
1566
1560
|
/**
|
|
1567
|
-
* Track the wikilink
|
|
1561
|
+
* Track the wikilink the pointer rests on without attaching per-link
|
|
1562
|
+
* listeners.
|
|
1568
1563
|
*
|
|
1569
|
-
*
|
|
1570
|
-
*
|
|
1571
|
-
*
|
|
1564
|
+
* A cold pointer must rest on a link for `openDelay` ms before enter fires.
|
|
1565
|
+
* Moving to an adjacent link restarts the delay, or switches at once when a
|
|
1566
|
+
* link is already entered. Leave fires `closeDelay` ms after the pointer
|
|
1567
|
+
* leaves, and immediately when the hovered link is deleted, replaced, or
|
|
1568
|
+
* changes target. Moving among descendants of one label is de-duplicated.
|
|
1572
1569
|
*/
|
|
1573
|
-
export declare function defineWikilinkHoverHandler(onHoverChange: WikilinkHoverHandler): PlainExtension;
|
|
1570
|
+
export declare function defineWikilinkHoverHandler(onHoverChange: WikilinkHoverHandler, openDelay?: number, closeDelay?: number): PlainExtension;
|
|
1574
1571
|
//#endregion
|
|
1575
1572
|
//#region src/extensions/wikilink-trigger.d.ts
|
|
1576
1573
|
/**
|
|
@@ -1642,4 +1639,4 @@ export declare function getSelectedText(state: EditorState): string;
|
|
|
1642
1639
|
*/
|
|
1643
1640
|
export declare function getVirtualElementFromRange(view: EditorView, range: PositionRange): VirtualElement;
|
|
1644
1641
|
//#endregion
|
|
1645
|
-
export { type AcceptPendingReplacementOptions, type CheckRoundTripOptions, type CodeBlockAttrs, type CodeBlockFenceStyle, type CodeToken, type DocToMarkdownOptions, type EditorConfig, type EditorExtension, type EditorExtensionOptions, 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, type
|
|
1642
|
+
export { type AcceptPendingReplacementOptions, type CheckRoundTripOptions, type CodeBlockAttrs, type CodeBlockFenceStyle, type CodeToken, type DocToMarkdownOptions, type EditorConfig, type EditorExtension, type EditorExtensionOptions, 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, type PostEmbedSnapshot, 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, type XPostResolver, type YouTubeVideoResolver, defineCodeBlockPreviewPlugin, definePlaceholder, defineSearchStatusHandler, getSearchStatus, isCodeBlockPreviewHiddenDecoration, withPriority };
|
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import { defineCodeBlock, defineCodeBlockHighlight, defineCodeBlockPreviewPlugin
|
|
|
3
3
|
import { definePlaceholder, definePlaceholder as definePlaceholder$1 } from "@prosekit/extensions/placeholder";
|
|
4
4
|
import { NodeSelection, Plugin, PluginKey, Selection, TextSelection } from "@prosekit/pm/state";
|
|
5
5
|
import { defineSearchCommands, defineSearchQuery, defineSearchStatusHandler, getSearchStatus, getSearchStatus as getSearchStatus$1 } from "@prosekit/extensions/search";
|
|
6
|
-
import { LEZER_NODE_IDS, collectInlineElements, getAutolinkHref, gfmBlockOnlyParser, gfmParser, isSpaceChar, parseInline } from "@meowdown/markdown";
|
|
6
|
+
import { LEZER_NODE_IDS, collectInlineElements, getAutolinkHref, gfmBlockOnlyParser, gfmParser, isSpaceChar, matchEmbed, parseInline, parseXPostId } from "@meowdown/markdown";
|
|
7
7
|
import { isElementLike, isHTMLElement, isObject, once } from "@ocavue/utils";
|
|
8
8
|
import { defineBlockquote } from "@prosekit/extensions/blockquote";
|
|
9
9
|
import { defineDoc } from "@prosekit/extensions/doc";
|
|
@@ -33,14 +33,14 @@ import { triggerAutocomplete } from "@prosekit/extensions/autocomplete";
|
|
|
33
33
|
import { defineListCommands, defineListDropIndicator, defineListKeymap, defineListSpec, moveList, toggleList, unwrapList, wrapInList } from "@prosekit/extensions/list";
|
|
34
34
|
import { chainCommands, lift, newlineInCode, splitBlock } from "@prosekit/pm/commands";
|
|
35
35
|
import { closeHistory } from "@prosekit/pm/history";
|
|
36
|
-
import { fromSyndication } from "@post-embed/exporter/x/syndication";
|
|
37
|
-
import { XPostSchema, YouTubeVideoSchema, parseXPostId } from "@post-embed/schema";
|
|
38
|
-
import { createLRU } from "lru.min";
|
|
39
|
-
import * as v from "valibot";
|
|
40
36
|
import { defineHorizontalRule } from "@prosekit/extensions/horizontal-rule";
|
|
41
37
|
import { registerXPost } from "@post-embed/elements/x";
|
|
42
38
|
import { registerYouTubeVideo } from "@post-embed/elements/youtube";
|
|
43
39
|
import { registerResizableHandleElement, registerResizableRootElement } from "@prosekit/web/resizable";
|
|
40
|
+
import { fromSyndication } from "@post-embed/exporter/x/syndication";
|
|
41
|
+
import { XPostSchema, YouTubeVideoSchema } from "@post-embed/schema";
|
|
42
|
+
import { createLRU } from "lru.min";
|
|
43
|
+
import * as v from "valibot";
|
|
44
44
|
import { AttrStep, ReplaceStep, Step, StepResult, Transform } from "@prosekit/pm/transform";
|
|
45
45
|
import { decodeString } from "micromark-util-decode-string";
|
|
46
46
|
import { normalizeIdentifier } from "micromark-util-normalize-identifier";
|
|
@@ -2478,99 +2478,13 @@ function getPastedText(event, slice) {
|
|
|
2478
2478
|
return slice.content.textBetween(0, slice.content.size, "\n");
|
|
2479
2479
|
}
|
|
2480
2480
|
|
|
2481
|
-
//#endregion
|
|
2482
|
-
//#region src/extensions/post-embed.ts
|
|
2483
|
-
const YOUTUBE_HOSTS = /^(?:www\.|m\.)?(?:youtube\.com|youtube-nocookie\.com)$/i;
|
|
2484
|
-
const YOUTU_BE_HOST = /^(?:www\.)?youtu\.be$/i;
|
|
2485
|
-
const VIDEO_ID = /^[\w-]{11}$/;
|
|
2486
|
-
function parseURL(src) {
|
|
2487
|
-
try {
|
|
2488
|
-
return new URL(src);
|
|
2489
|
-
} catch {
|
|
2490
|
-
return;
|
|
2491
|
-
}
|
|
2492
|
-
}
|
|
2493
|
-
function isYouTubeVideo(src) {
|
|
2494
|
-
const url = parseURL(src);
|
|
2495
|
-
if (!url) return false;
|
|
2496
|
-
let videoId = null;
|
|
2497
|
-
if (YOUTU_BE_HOST.test(url.hostname)) videoId = url.pathname.slice(1);
|
|
2498
|
-
else if (YOUTUBE_HOSTS.test(url.hostname)) {
|
|
2499
|
-
const [, firstSegment, secondSegment] = url.pathname.split("/");
|
|
2500
|
-
if (url.pathname === "/watch") videoId = url.searchParams.get("v");
|
|
2501
|
-
else if (firstSegment === "shorts" || firstSegment === "embed" || firstSegment === "live") videoId = secondSegment ?? null;
|
|
2502
|
-
}
|
|
2503
|
-
return videoId !== null && VIDEO_ID.test(videoId);
|
|
2504
|
-
}
|
|
2505
|
-
/**
|
|
2506
|
-
* The post-embed card an image `src` renders as, or `undefined` for a plain image.
|
|
2507
|
-
*/
|
|
2508
|
-
function matchPostEmbed(src) {
|
|
2509
|
-
if (parseXPostId(src) !== void 0) return "x-post";
|
|
2510
|
-
if (isYouTubeVideo(src)) return "youtube-video";
|
|
2511
|
-
}
|
|
2512
|
-
/**
|
|
2513
|
-
* Wrap a loader in a 64-entry LRU keyed by URL. A settled URL answers
|
|
2514
|
-
* synchronously, so a revisited document renders its cards in the first
|
|
2515
|
-
* frame; the first visit returns the in-flight load.
|
|
2516
|
-
*/
|
|
2517
|
-
function cached(load) {
|
|
2518
|
-
const cache = createLRU({ max: 64 });
|
|
2519
|
-
return (url) => {
|
|
2520
|
-
if (cache.has(url)) return cache.get(url);
|
|
2521
|
-
const pending = load(url).then((value) => {
|
|
2522
|
-
cache.set(url, value);
|
|
2523
|
-
return value;
|
|
2524
|
-
}, (error) => {
|
|
2525
|
-
cache.delete(url);
|
|
2526
|
-
throw error;
|
|
2527
|
-
});
|
|
2528
|
-
cache.set(url, pending);
|
|
2529
|
-
return pending;
|
|
2530
|
-
};
|
|
2531
|
-
}
|
|
2532
|
-
const X_POST_API = "https://react-tweet.vercel.app/api/tweet/";
|
|
2533
|
-
const defaultResolveXPost = cached(async (url) => {
|
|
2534
|
-
const id = parseXPostId(url);
|
|
2535
|
-
if (id === void 0) return;
|
|
2536
|
-
const response = await fetch(X_POST_API + id);
|
|
2537
|
-
if (!response.ok) return;
|
|
2538
|
-
const json = await response.json();
|
|
2539
|
-
return fromSyndication(json.data);
|
|
2540
|
-
});
|
|
2541
|
-
const YOUTUBE_OEMBED_API = "https://www.youtube.com/oembed?format=json&url=";
|
|
2542
|
-
const defaultResolveYouTubeVideo = cached(async (url) => {
|
|
2543
|
-
const response = await fetch(YOUTUBE_OEMBED_API + encodeURIComponent(url));
|
|
2544
|
-
if (!response.ok) return;
|
|
2545
|
-
return {
|
|
2546
|
-
url,
|
|
2547
|
-
...await response.json()
|
|
2548
|
-
};
|
|
2549
|
-
});
|
|
2550
|
-
const PostEmbedSnapshotSchema = v.variant("kind", [v.object({
|
|
2551
|
-
kind: v.literal("x-post"),
|
|
2552
|
-
data: XPostSchema
|
|
2553
|
-
}), v.object({
|
|
2554
|
-
kind: v.literal("youtube-video"),
|
|
2555
|
-
data: YouTubeVideoSchema
|
|
2556
|
-
})]);
|
|
2557
|
-
/**
|
|
2558
|
-
* The snapshot a card renders from a saved JSON object, or `undefined` when
|
|
2559
|
-
* the object does not validate. Unknown fields are dropped, so a persisted
|
|
2560
|
-
* snapshot is exactly what the card needs.
|
|
2561
|
-
*/
|
|
2562
|
-
function parsePostEmbedSnapshot(value) {
|
|
2563
|
-
const result = v.safeParse(PostEmbedSnapshotSchema, value);
|
|
2564
|
-
return result.success ? result.output : void 0;
|
|
2565
|
-
}
|
|
2566
|
-
|
|
2567
2481
|
//#endregion
|
|
2568
2482
|
//#region src/extensions/embed-paste.ts
|
|
2569
2483
|
const embedPasteKey = new PluginKey("meowdown-embed-paste");
|
|
2570
2484
|
function detectEmbedUrl(text) {
|
|
2571
2485
|
const trimmed = text.trim();
|
|
2572
2486
|
if (!trimmed || /\s/.test(trimmed)) return void 0;
|
|
2573
|
-
return
|
|
2487
|
+
return matchEmbed(trimmed) ? trimmed : void 0;
|
|
2574
2488
|
}
|
|
2575
2489
|
function insertEmbedFromPaste(view, url) {
|
|
2576
2490
|
const { from, to } = view.state.selection;
|
|
@@ -3663,6 +3577,63 @@ function stripMagicComment(source) {
|
|
|
3663
3577
|
return source.replace(TRAILING_MAGIC_COMMENT_RE, "");
|
|
3664
3578
|
}
|
|
3665
3579
|
|
|
3580
|
+
//#endregion
|
|
3581
|
+
//#region src/extensions/post-embed.ts
|
|
3582
|
+
/**
|
|
3583
|
+
* Wrap a loader in a 64-entry LRU keyed by URL. A settled URL answers
|
|
3584
|
+
* synchronously, so a revisited document renders its cards in the first
|
|
3585
|
+
* frame; the first visit returns the in-flight load.
|
|
3586
|
+
*/
|
|
3587
|
+
function cached(load) {
|
|
3588
|
+
const cache = createLRU({ max: 64 });
|
|
3589
|
+
return (url) => {
|
|
3590
|
+
if (cache.has(url)) return cache.get(url);
|
|
3591
|
+
const pending = load(url).then((value) => {
|
|
3592
|
+
cache.set(url, value);
|
|
3593
|
+
return value;
|
|
3594
|
+
}, (error) => {
|
|
3595
|
+
cache.delete(url);
|
|
3596
|
+
throw error;
|
|
3597
|
+
});
|
|
3598
|
+
cache.set(url, pending);
|
|
3599
|
+
return pending;
|
|
3600
|
+
};
|
|
3601
|
+
}
|
|
3602
|
+
const X_POST_API = "https://react-tweet.vercel.app/api/tweet/";
|
|
3603
|
+
const defaultResolveXPost = cached(async (url) => {
|
|
3604
|
+
const id = parseXPostId(url);
|
|
3605
|
+
if (id === void 0) return;
|
|
3606
|
+
const response = await fetch(X_POST_API + id);
|
|
3607
|
+
if (!response.ok) return;
|
|
3608
|
+
const json = await response.json();
|
|
3609
|
+
return fromSyndication(json.data);
|
|
3610
|
+
});
|
|
3611
|
+
const YOUTUBE_OEMBED_API = "https://www.youtube.com/oembed?format=json&url=";
|
|
3612
|
+
const defaultResolveYouTubeVideo = cached(async (url) => {
|
|
3613
|
+
const response = await fetch(YOUTUBE_OEMBED_API + encodeURIComponent(url));
|
|
3614
|
+
if (!response.ok) return;
|
|
3615
|
+
return {
|
|
3616
|
+
url,
|
|
3617
|
+
...await response.json()
|
|
3618
|
+
};
|
|
3619
|
+
});
|
|
3620
|
+
const PostEmbedSnapshotSchema = v.variant("kind", [v.object({
|
|
3621
|
+
kind: v.literal("x-post"),
|
|
3622
|
+
data: XPostSchema
|
|
3623
|
+
}), v.object({
|
|
3624
|
+
kind: v.literal("youtube-video"),
|
|
3625
|
+
data: YouTubeVideoSchema
|
|
3626
|
+
})]);
|
|
3627
|
+
/**
|
|
3628
|
+
* The snapshot a card renders from a saved JSON object, or `undefined` when
|
|
3629
|
+
* the object does not validate. Unknown fields are dropped, so a persisted
|
|
3630
|
+
* snapshot is exactly what the card needs.
|
|
3631
|
+
*/
|
|
3632
|
+
function parsePostEmbedSnapshot(value) {
|
|
3633
|
+
const result = v.safeParse(PostEmbedSnapshotSchema, value);
|
|
3634
|
+
return result.success ? result.output : void 0;
|
|
3635
|
+
}
|
|
3636
|
+
|
|
3666
3637
|
//#endregion
|
|
3667
3638
|
//#region src/extensions/wiki-embed.ts
|
|
3668
3639
|
const WIKI_EMBED_SIZE = /^(\d+)(?:x(\d+))?$/i;
|
|
@@ -3906,7 +3877,7 @@ var ImageMarkView = class {
|
|
|
3906
3877
|
const { src } = this.#attrs;
|
|
3907
3878
|
const wrapper = document.createElement("span");
|
|
3908
3879
|
wrapper.className = "md-image-view-preview md-atom-view-preview";
|
|
3909
|
-
const kind =
|
|
3880
|
+
const kind = matchEmbed(src);
|
|
3910
3881
|
if (kind) {
|
|
3911
3882
|
wrapper.dataset.testid = `${kind}-embed`;
|
|
3912
3883
|
wrapper.dataset.postEmbed = kind;
|
|
@@ -8550,17 +8521,17 @@ function defineMarkHoverHandler(config) {
|
|
|
8550
8521
|
//#region src/extensions/link-hover.ts
|
|
8551
8522
|
const linkHoverKey = new PluginKey("meowdown-link-hover");
|
|
8552
8523
|
/**
|
|
8553
|
-
*
|
|
8524
|
+
* Delay before a cold hover enters, in ms.
|
|
8554
8525
|
*/
|
|
8555
|
-
const OPEN_DELAY = 300;
|
|
8526
|
+
const OPEN_DELAY$1 = 300;
|
|
8556
8527
|
/**
|
|
8557
8528
|
* Grace before a leave fires, in ms. The window lets a pointer travel from
|
|
8558
8529
|
* the hovered link onto the popup it anchors.
|
|
8559
8530
|
*/
|
|
8560
|
-
const CLOSE_DELAY = 100;
|
|
8531
|
+
const CLOSE_DELAY$1 = 100;
|
|
8561
8532
|
/**
|
|
8562
8533
|
* Track the link under the user's attention: a mouse hover after a short
|
|
8563
|
-
*
|
|
8534
|
+
* delay, or a touch tap immediately, since touch has no hover. Without the
|
|
8564
8535
|
* tap entry, the popup's preview and actions would stay unreachable on
|
|
8565
8536
|
* phones, where a tap on a link only places the caret and raises the
|
|
8566
8537
|
* software keyboard.
|
|
@@ -8569,8 +8540,8 @@ function defineLinkHoverHandler(onHoverChange, { canLeave } = {}) {
|
|
|
8569
8540
|
return defineMarkHoverHandler({
|
|
8570
8541
|
key: linkHoverKey,
|
|
8571
8542
|
selector: ".md-link",
|
|
8572
|
-
openDelay: OPEN_DELAY,
|
|
8573
|
-
closeDelay: CLOSE_DELAY,
|
|
8543
|
+
openDelay: OPEN_DELAY$1,
|
|
8544
|
+
closeDelay: CLOSE_DELAY$1,
|
|
8574
8545
|
tap: true,
|
|
8575
8546
|
canLeave,
|
|
8576
8547
|
findPayloadAt: (state, pos) => {
|
|
@@ -8821,18 +8792,30 @@ function defineVirtualCaret(layer) {
|
|
|
8821
8792
|
//#region src/extensions/wikilink-hover.ts
|
|
8822
8793
|
const wikilinkHoverKey = new PluginKey("meowdown-wikilink-hover");
|
|
8823
8794
|
/**
|
|
8824
|
-
*
|
|
8795
|
+
* Delay before a cold hover enters, in ms.
|
|
8796
|
+
*/
|
|
8797
|
+
const OPEN_DELAY = 300;
|
|
8798
|
+
/**
|
|
8799
|
+
* Grace before a leave fires, in ms. Returning within it re-enters without
|
|
8800
|
+
* a new delay.
|
|
8801
|
+
*/
|
|
8802
|
+
const CLOSE_DELAY = 100;
|
|
8803
|
+
/**
|
|
8804
|
+
* Track the wikilink the pointer rests on without attaching per-link
|
|
8805
|
+
* listeners.
|
|
8825
8806
|
*
|
|
8826
|
-
*
|
|
8827
|
-
*
|
|
8828
|
-
*
|
|
8807
|
+
* A cold pointer must rest on a link for `openDelay` ms before enter fires.
|
|
8808
|
+
* Moving to an adjacent link restarts the delay, or switches at once when a
|
|
8809
|
+
* link is already entered. Leave fires `closeDelay` ms after the pointer
|
|
8810
|
+
* leaves, and immediately when the hovered link is deleted, replaced, or
|
|
8811
|
+
* changes target. Moving among descendants of one label is de-duplicated.
|
|
8829
8812
|
*/
|
|
8830
|
-
function defineWikilinkHoverHandler(onHoverChange) {
|
|
8813
|
+
function defineWikilinkHoverHandler(onHoverChange, openDelay = OPEN_DELAY, closeDelay = CLOSE_DELAY) {
|
|
8831
8814
|
return defineMarkHoverHandler({
|
|
8832
8815
|
key: wikilinkHoverKey,
|
|
8833
8816
|
selector: ".md-wikilink-view-preview",
|
|
8834
|
-
openDelay
|
|
8835
|
-
closeDelay
|
|
8817
|
+
openDelay,
|
|
8818
|
+
closeDelay,
|
|
8836
8819
|
tap: false,
|
|
8837
8820
|
findPayloadAt: findWikilinkAt,
|
|
8838
8821
|
findPayloadForElement: findWikilinkForElement,
|
|
@@ -8937,4 +8920,4 @@ function getVirtualElementFromRange(view, range) {
|
|
|
8937
8920
|
}
|
|
8938
8921
|
|
|
8939
8922
|
//#endregion
|
|
8940
|
-
export { EDITOR_KEY_BINDINGS, Priority, buildFileMarkdown, checkRoundTrip, codeBlockLanguages, collectReferenceDefinitions, defaultResolveImageUrl, defaultResolveXPost, defaultResolveYouTubeVideo, defineBulletAfterHeading, defineCodeBlockPreviewPlugin, defineCodeBlockSyntaxHighlight, defineEditorExtension, defineEmbedPaste, defineExitBoundaryHandler, defineFileClickHandler, defineFilePaste, defineFileView, defineFollowLinkHandler, defineHTMLComment, defineImage, defineImageClickHandler, defineLinkClickHandler, defineLinkCommands, defineLinkEditKeymap, defineLinkHoverHandler, defineLinkPaste, defineMath, definePendingReplacementHandler, definePlaceholder, defineReadonly, defineSearchStatusHandler, defineSubstitution, defineTagClickHandler, defineViewAttributes, defineVirtualCaret, defineWikilinkClickHandler, defineWikilinkHoverHandler, defineWikilinkTrigger, docToMarkdown, formatFileSize, formatSizedWikiEmbed, getCodeTokens, getEditorConfig, getFileKind, getIsComposing, getLinkText, getLinkUnitAt, getMarkBuilders, getPendingReplacement, getSearchStatus, getSelectedText, getTableColumnAlign, getTextblockDisplayText, getVirtualElementFromRange, inlineTextToMarkChunks, inlineTextToMarkChunksWithContext, insertLink, isCodeBlockPreviewHiddenDecoration, isLinkTextForHref, isMarkOfType, isModEvent, isNodeOfType, isReferenceDefinitionNode, isSelectionInTableCell, loadKaTeX, markdownToDoc,
|
|
8923
|
+
export { EDITOR_KEY_BINDINGS, Priority, buildFileMarkdown, checkRoundTrip, codeBlockLanguages, collectReferenceDefinitions, defaultResolveImageUrl, defaultResolveXPost, defaultResolveYouTubeVideo, defineBulletAfterHeading, defineCodeBlockPreviewPlugin, defineCodeBlockSyntaxHighlight, defineEditorExtension, defineEmbedPaste, defineExitBoundaryHandler, defineFileClickHandler, defineFilePaste, defineFileView, defineFollowLinkHandler, defineHTMLComment, defineImage, defineImageClickHandler, defineLinkClickHandler, defineLinkCommands, defineLinkEditKeymap, defineLinkHoverHandler, defineLinkPaste, defineMath, definePendingReplacementHandler, definePlaceholder, defineReadonly, defineSearchStatusHandler, defineSubstitution, defineTagClickHandler, defineViewAttributes, defineVirtualCaret, defineWikilinkClickHandler, defineWikilinkHoverHandler, defineWikilinkTrigger, docToMarkdown, formatFileSize, formatSizedWikiEmbed, getCodeTokens, getEditorConfig, getFileKind, getIsComposing, getLinkText, getLinkUnitAt, getMarkBuilders, getPendingReplacement, getSearchStatus, getSelectedText, getTableColumnAlign, getTextblockDisplayText, getVirtualElementFromRange, inlineTextToMarkChunks, inlineTextToMarkChunksWithContext, insertLink, isCodeBlockPreviewHiddenDecoration, isLinkTextForHref, isMarkOfType, isModEvent, isNodeOfType, isReferenceDefinitionNode, isSelectionInTableCell, loadKaTeX, markdownToDoc, normalizeHref, parsePostEmbedSnapshot, parseWikiEmbed, removeLink, renderMathInto, updateEditorConfig, updateLink, wikiEmbedBasename, withPriority };
|
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.72.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"@prosekit/pm": "^0.1.19",
|
|
36
36
|
"@prosekit/web": "^0.9.2",
|
|
37
37
|
"hast-util-to-mdast": "^10.1.2",
|
|
38
|
-
"katex": "^0.18.
|
|
38
|
+
"katex": "^0.18.7",
|
|
39
39
|
"lru.min": "^1.1.5",
|
|
40
40
|
"mdast-util-to-markdown": "^2.1.2",
|
|
41
41
|
"micromark-util-decode-string": "^2.0.1",
|
|
@@ -49,19 +49,19 @@
|
|
|
49
49
|
"unicode-by-name": "^0.2.0",
|
|
50
50
|
"unified": "^11.0.5",
|
|
51
51
|
"valibot": "^1.5.0",
|
|
52
|
-
"@meowdown/markdown": "^0.
|
|
52
|
+
"@meowdown/markdown": "^0.72.0"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
55
|
"@ocavue/tsconfig": "^0.7.1",
|
|
56
|
-
"@tsdown/css": "^0.23.0
|
|
56
|
+
"@tsdown/css": "^0.23.0",
|
|
57
57
|
"@types/hast": "^3.0.5",
|
|
58
58
|
"@types/mdast": "^4.0.4",
|
|
59
|
-
"@vitest/browser-playwright": "^5.0.
|
|
59
|
+
"@vitest/browser-playwright": "^5.0.1",
|
|
60
60
|
"commonmark.json": "^0.31.0",
|
|
61
61
|
"dedent": "^1.7.2",
|
|
62
62
|
"diffable-html-snapshot": "^0.3.0",
|
|
63
|
-
"tsdown": "^0.23.0
|
|
64
|
-
"vitest": "^5.0.
|
|
63
|
+
"tsdown": "^0.23.0",
|
|
64
|
+
"vitest": "^5.0.1",
|
|
65
65
|
"vitest-browser-commands": "^0.4.1",
|
|
66
66
|
"@meowdown/vitest": "0.0.0"
|
|
67
67
|
},
|