@meowdown/core 0.66.0 → 0.67.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/dist/index.d.ts +66 -10
- package/dist/index.js +261 -79
- package/dist/style.css +4 -0
- package/package.json +7 -8
package/dist/index.d.ts
CHANGED
|
@@ -267,27 +267,36 @@ type MdPackAttrs = {
|
|
|
267
267
|
revealInFocus: true;
|
|
268
268
|
revealInHide?: null;
|
|
269
269
|
} | {
|
|
270
|
-
key: 'link';
|
|
270
|
+
key: 'link-inline' | 'link-reference';
|
|
271
271
|
data: {
|
|
272
|
-
form: 'inline' | 'reference';
|
|
273
272
|
href: string;
|
|
274
273
|
title: string;
|
|
275
|
-
}
|
|
276
|
-
|
|
274
|
+
};
|
|
275
|
+
slot?: 1 | null;
|
|
276
|
+
revealInFocus: true;
|
|
277
|
+
revealInHide?: null;
|
|
278
|
+
} | {
|
|
279
|
+
key: 'link-angle';
|
|
280
|
+
data: {
|
|
277
281
|
href: string;
|
|
278
282
|
};
|
|
279
283
|
slot?: 1 | null;
|
|
280
284
|
revealInFocus: true;
|
|
281
285
|
revealInHide?: null;
|
|
282
286
|
} | {
|
|
283
|
-
key: 'link';
|
|
287
|
+
key: 'link-bare';
|
|
284
288
|
data: {
|
|
285
|
-
form: 'bare';
|
|
286
289
|
href: string;
|
|
287
290
|
};
|
|
288
291
|
slot?: 1 | null;
|
|
289
292
|
revealInFocus?: null;
|
|
290
293
|
revealInHide?: null;
|
|
294
|
+
} | {
|
|
295
|
+
key: 'noLink';
|
|
296
|
+
data?: null;
|
|
297
|
+
slot?: 1 | null;
|
|
298
|
+
revealInFocus: true;
|
|
299
|
+
revealInHide?: null;
|
|
291
300
|
} | {
|
|
292
301
|
key: 'math';
|
|
293
302
|
data?: null;
|
|
@@ -310,6 +319,7 @@ interface PositionRange {
|
|
|
310
319
|
//#endregion
|
|
311
320
|
//#region src/extensions/get-link-unit-at.d.ts
|
|
312
321
|
interface LinkUnitBase {
|
|
322
|
+
state: EditorState;
|
|
313
323
|
/**
|
|
314
324
|
* Whole inline link, reference link, or autolink range.
|
|
315
325
|
*/
|
|
@@ -364,15 +374,30 @@ export declare function getLinkUnitAt(state: EditorState, pos: number): LinkUnit
|
|
|
364
374
|
interface LinkAttrs {
|
|
365
375
|
href?: string;
|
|
366
376
|
title?: string;
|
|
377
|
+
text?: string;
|
|
367
378
|
}
|
|
379
|
+
/**
|
|
380
|
+
* Normalize a typed URL with the existing autolink logic, else keep it verbatim.
|
|
381
|
+
*/
|
|
382
|
+
export declare function normalizeHref(raw: string): string;
|
|
383
|
+
/**
|
|
384
|
+
* Get a link's plain visible text.
|
|
385
|
+
*/
|
|
386
|
+
export declare function getLinkText(link: LinkUnit): string;
|
|
387
|
+
/**
|
|
388
|
+
* Whether plain visible link text names the same destination as the link.
|
|
389
|
+
*/
|
|
390
|
+
export declare function isLinkTextForHref(text: string, href: string): boolean;
|
|
368
391
|
interface InsertLinkOptions {
|
|
369
392
|
href?: string;
|
|
370
393
|
title?: string;
|
|
394
|
+
text?: string;
|
|
371
395
|
wrapText?: boolean;
|
|
372
396
|
}
|
|
373
|
-
export declare function insertLink({ href, title, wrapText }?: InsertLinkOptions): Command;
|
|
397
|
+
export declare function insertLink({ href, title, text, wrapText }?: InsertLinkOptions): Command;
|
|
374
398
|
/**
|
|
375
|
-
* Rewrite
|
|
399
|
+
* Rewrite a mutable link. Autolinks are promoted to inline Markdown when
|
|
400
|
+
* their visible text or destination changes.
|
|
376
401
|
*/
|
|
377
402
|
export declare function updateLink(attrs: LinkAttrs): Command;
|
|
378
403
|
/**
|
|
@@ -390,6 +415,7 @@ interface LinkEditOptions {
|
|
|
390
415
|
from: number;
|
|
391
416
|
to: number;
|
|
392
417
|
link: LinkUnit | undefined;
|
|
418
|
+
text: string;
|
|
393
419
|
}
|
|
394
420
|
type LinkEditHandler = (options: LinkEditOptions) => void;
|
|
395
421
|
export declare function defineLinkEditKeymap(onLinkEdit: LinkEditHandler): PlainExtension;
|
|
@@ -1364,7 +1390,21 @@ interface MarkHoverHit<Payload> {
|
|
|
1364
1390
|
//#endregion
|
|
1365
1391
|
//#region src/extensions/link-hover.d.ts
|
|
1366
1392
|
type LinkHoverHandler = (hit: MarkHoverHit<LinkUnit> | undefined) => void;
|
|
1367
|
-
|
|
1393
|
+
interface LinkHoverOptions {
|
|
1394
|
+
/**
|
|
1395
|
+
* Return `false` while the pointer is on the popup the link opened: a
|
|
1396
|
+
* pending leave then re-checks later instead of firing.
|
|
1397
|
+
*/
|
|
1398
|
+
canLeave?: () => boolean;
|
|
1399
|
+
}
|
|
1400
|
+
/**
|
|
1401
|
+
* Track the link under the user's attention: a mouse hover after a short
|
|
1402
|
+
* dwell, or a touch tap immediately, since touch has no hover. Without the
|
|
1403
|
+
* tap entry, the popup's preview and actions would stay unreachable on
|
|
1404
|
+
* phones, where a tap on a link only places the caret and raises the
|
|
1405
|
+
* software keyboard.
|
|
1406
|
+
*/
|
|
1407
|
+
export declare function defineLinkHoverHandler(onHoverChange: LinkHoverHandler, { canLeave }?: LinkHoverOptions): PlainExtension;
|
|
1368
1408
|
//#endregion
|
|
1369
1409
|
//#region src/extensions/link-paste.d.ts
|
|
1370
1410
|
/**
|
|
@@ -1382,6 +1422,22 @@ export declare function defineLinkHoverHandler(onHoverChange: LinkHoverHandler):
|
|
|
1382
1422
|
*/
|
|
1383
1423
|
export declare function defineLinkPaste(): PlainExtension;
|
|
1384
1424
|
//#endregion
|
|
1425
|
+
//#region src/extensions/link-preview.d.ts
|
|
1426
|
+
/**
|
|
1427
|
+
* Metadata a host application can supply for a web link.
|
|
1428
|
+
*/
|
|
1429
|
+
interface LinkPreview {
|
|
1430
|
+
readonly title: string;
|
|
1431
|
+
readonly description?: string;
|
|
1432
|
+
readonly iconSrc?: string;
|
|
1433
|
+
}
|
|
1434
|
+
/**
|
|
1435
|
+
* Resolve display metadata for a link, or return `undefined` when unavailable.
|
|
1436
|
+
* Deliberately signal-free to keep the API simple: callers drop stale results
|
|
1437
|
+
* instead of cancelling in-flight work.
|
|
1438
|
+
*/
|
|
1439
|
+
type LinkPreviewResolver = (href: string) => LinkPreview | undefined | Promise<LinkPreview | undefined>;
|
|
1440
|
+
//#endregion
|
|
1385
1441
|
//#region src/extensions/mark-names.d.ts
|
|
1386
1442
|
declare const MARK_NAMES: readonly ["mdWikilink", "mdImage", "mdFile", "mdMath", "mdMark", "mdEm", "mdStrong", "mdCode", "mdLinkText", "mdLinkUri", "mdLinkTitle", "mdDel", "mdHighlight", "mdTag", "mdPack"];
|
|
1387
1443
|
type MarkName = (typeof MARK_NAMES)[number];
|
|
@@ -1538,4 +1594,4 @@ export declare function getSelectedText(state: EditorState): string;
|
|
|
1538
1594
|
*/
|
|
1539
1595
|
export declare function getVirtualElementFromRange(view: EditorView, range: PositionRange): VirtualElement;
|
|
1540
1596
|
//#endregion
|
|
1541
|
-
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 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 };
|
|
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 };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Priority, Priority as Priority$1, createMarkBuilders, createNodeBuilders, defineBaseCommands, defineBaseKeymap, defineClipboardSerializer, defineCommands, defineHistory, defineKeymap, defineMarkSpec, defineMarkView, defineNodeAttr, defineNodeSpec, definePlugin, getMarkRange, getMarkType, getNodeType, isAllSelection, isApple, isAtBlockStart, isNodeSelection, isTextSelection, setBlockType, toggleNode, union, unsetBlockType, withPriority, withPriority as withPriority$1, withSkipCodeBlock } from "@prosekit/core";
|
|
1
|
+
import { Priority, Priority as Priority$1, createMarkBuilders, createNodeBuilders, defineBaseCommands, defineBaseKeymap, defineClipboardSerializer, defineCommands, defineHistory, defineKeymap, defineMarkSpec, defineMarkView, defineNodeAttr, defineNodeSpec, definePlugin, findMarkRange, getMarkRange, getMarkType, getNodeType, isAllSelection, isApple, isAtBlockStart, isNodeSelection, isTextSelection, setBlockType, toggleNode, union, unsetBlockType, withPriority, withPriority as withPriority$1, withSkipCodeBlock } from "@prosekit/core";
|
|
2
2
|
import { defineCodeBlock, defineCodeBlockHighlight, defineCodeBlockPreviewPlugin, isCodeBlockPreviewHiddenDecoration } from "@prosekit/extensions/code-block";
|
|
3
3
|
import { definePlaceholder } from "@prosekit/extensions/placeholder";
|
|
4
4
|
import { defineReadonly } from "@prosekit/extensions/readonly";
|
|
@@ -354,13 +354,13 @@ function resolvePosition(state, pos) {
|
|
|
354
354
|
}
|
|
355
355
|
/**
|
|
356
356
|
* Returns the run of the mark covering `pos`, or `undefined` when none covers
|
|
357
|
-
* it. `
|
|
358
|
-
*
|
|
357
|
+
* it. `predicate` narrows the match to marks it accepts, which is how a
|
|
358
|
+
* caller picks one level out of a nested stack of the same mark.
|
|
359
359
|
*/
|
|
360
|
-
function getMarkRangeAt(state, pos, markName,
|
|
360
|
+
function getMarkRangeAt(state, pos, markName, predicate) {
|
|
361
361
|
const $pos = resolvePosition(state, pos);
|
|
362
362
|
if (!$pos) return;
|
|
363
|
-
return ATOM_MARK_NAMES.includes(markName) ? getAtomUnitRange(state, $pos, markName) :
|
|
363
|
+
return ATOM_MARK_NAMES.includes(markName) ? getAtomUnitRange(state, $pos, markName) : findMarkRange($pos, (mark) => isMarkOfType(mark, markName) && (!predicate || predicate(mark)));
|
|
364
364
|
}
|
|
365
365
|
/**
|
|
366
366
|
* The range of the atom unit touching `$pos`, preferring the child to the
|
|
@@ -368,7 +368,7 @@ function getMarkRangeAt(state, pos, markName, attrs) {
|
|
|
368
368
|
* marks, so eq-based expansion would run across both; the unit boundary comes
|
|
369
369
|
* from the innermost pack instead, which `slot` keeps distinct. A text node
|
|
370
370
|
* without a pack (a document not produced by the inline parser) falls back to
|
|
371
|
-
* the eq-based range. Does not support `
|
|
371
|
+
* the eq-based range. Does not support `predicate` filtering.
|
|
372
372
|
*/
|
|
373
373
|
function getAtomUnitRange(state, $pos, name) {
|
|
374
374
|
const parent = $pos.parent;
|
|
@@ -2843,10 +2843,12 @@ function parseMagicComment(comment) {
|
|
|
2843
2843
|
if (!isObject(data)) return;
|
|
2844
2844
|
const width = toPositiveNumber(data.width);
|
|
2845
2845
|
const height = toPositiveNumber(data.height);
|
|
2846
|
-
|
|
2846
|
+
const noLink = data.noLink === true ? true : void 0;
|
|
2847
|
+
if (!width && !height && !noLink) return;
|
|
2847
2848
|
return {
|
|
2848
2849
|
width,
|
|
2849
|
-
height
|
|
2850
|
+
height,
|
|
2851
|
+
noLink
|
|
2850
2852
|
};
|
|
2851
2853
|
}
|
|
2852
2854
|
function toPositiveNumber(value) {
|
|
@@ -3185,6 +3187,14 @@ function walk(nodes, parentMarks, rangeStart, rangeEnd, text, marks, out, option
|
|
|
3185
3187
|
pos = atomEnd;
|
|
3186
3188
|
continue;
|
|
3187
3189
|
}
|
|
3190
|
+
if (node.type === LEZER_NODE_IDS.URL) {
|
|
3191
|
+
const trailing = takeMagicComments(nodes, index, text);
|
|
3192
|
+
if (trailing?.magic.noLink) {
|
|
3193
|
+
walkUnlinkedURL(node, trailing, parentMarks, marks, out);
|
|
3194
|
+
pos = trailing.to;
|
|
3195
|
+
continue;
|
|
3196
|
+
}
|
|
3197
|
+
}
|
|
3188
3198
|
walkNode(node, parentMarks, text, marks, out, options, context);
|
|
3189
3199
|
pos = node.to;
|
|
3190
3200
|
}
|
|
@@ -3251,11 +3261,8 @@ function walkAutolink(node, parentMarks, text, marks, out) {
|
|
|
3251
3261
|
const urlNode = node.children.find((child) => child.type === LEZER_NODE_IDS.URL);
|
|
3252
3262
|
const href = urlNode ? getAutolinkHref(text.slice(urlNode.from, urlNode.to)) ?? "" : "";
|
|
3253
3263
|
const base = [...parentMarks, createUnitPack(marks, out, parentMarks, node.from, {
|
|
3254
|
-
key: "link",
|
|
3255
|
-
data: {
|
|
3256
|
-
form: "angle",
|
|
3257
|
-
href
|
|
3258
|
-
},
|
|
3264
|
+
key: "link-angle",
|
|
3265
|
+
data: { href },
|
|
3259
3266
|
revealInFocus: true
|
|
3260
3267
|
})];
|
|
3261
3268
|
let pos = node.from;
|
|
@@ -3282,15 +3289,26 @@ function walkURL(node, parentMarks, text, marks, out) {
|
|
|
3282
3289
|
emit(out, node.from, node.to, [
|
|
3283
3290
|
...parentMarks,
|
|
3284
3291
|
createUnitPack(marks, out, parentMarks, node.from, {
|
|
3285
|
-
key: "link",
|
|
3286
|
-
data: {
|
|
3287
|
-
form: "bare",
|
|
3288
|
-
href
|
|
3289
|
-
}
|
|
3292
|
+
key: "link-bare",
|
|
3293
|
+
data: { href }
|
|
3290
3294
|
}),
|
|
3291
3295
|
marks.mdLinkText.create({ href })
|
|
3292
3296
|
]);
|
|
3293
3297
|
}
|
|
3298
|
+
/**
|
|
3299
|
+
* A URL followed directly by a `<!-- {"noLink":true} -->` magic comment
|
|
3300
|
+
* stays plain text instead of autolinking. The comment rides behind the
|
|
3301
|
+
* address as hidden syntax that reveals in focus, so it can be edited or
|
|
3302
|
+
* deleted in place.
|
|
3303
|
+
*/
|
|
3304
|
+
function walkUnlinkedURL(node, trailing, parentMarks, marks, out) {
|
|
3305
|
+
const base = [...parentMarks, createUnitPack(marks, out, parentMarks, node.from, {
|
|
3306
|
+
key: "noLink",
|
|
3307
|
+
revealInFocus: true
|
|
3308
|
+
})];
|
|
3309
|
+
emit(out, node.from, node.to, base);
|
|
3310
|
+
emit(out, node.to, trailing.to, [...base, marks.mdMark.create()]);
|
|
3311
|
+
}
|
|
3294
3312
|
function walkLink(node, parentMarks, text, marks, out, options, context) {
|
|
3295
3313
|
const parts = scanLinkParts(node);
|
|
3296
3314
|
const resolution = resolveLink(parts, text, context);
|
|
@@ -3432,9 +3450,8 @@ function walkResolvedLink(node, parts, resolution, parentMarks, text, marks, out
|
|
|
3432
3450
|
const linkTextMark = marks.mdLinkText.create({ href });
|
|
3433
3451
|
const inLabel = (pos) => labelEnd >= 0 && pos < labelEnd;
|
|
3434
3452
|
const pack = createUnitPack(marks, out, parentMarks, node.from, {
|
|
3435
|
-
key: "link",
|
|
3453
|
+
key: isReference ? "link-reference" : "link-inline",
|
|
3436
3454
|
data: {
|
|
3437
|
-
form: isReference ? "reference" : "inline",
|
|
3438
3455
|
href,
|
|
3439
3456
|
title
|
|
3440
3457
|
},
|
|
@@ -3475,9 +3492,9 @@ function walkResolvedLink(node, parts, resolution, parentMarks, text, marks, out
|
|
|
3475
3492
|
}
|
|
3476
3493
|
/**
|
|
3477
3494
|
* The run of magic comments chained immediately behind `nodes[index]` (an
|
|
3478
|
-
* image), or undefined when no magic comment directly abuts it. The
|
|
3479
|
-
* comment's data wins: a rewrite of an unfolded image inserted the
|
|
3480
|
-
* comment right at the image's end, so in a stacked run left is newest.
|
|
3495
|
+
* image or a URL), or undefined when no magic comment directly abuts it. The
|
|
3496
|
+
* first comment's data wins: a rewrite of an unfolded image inserted the
|
|
3497
|
+
* fresh comment right at the image's end, so in a stacked run left is newest.
|
|
3481
3498
|
*/
|
|
3482
3499
|
function takeMagicComments(nodes, index, text) {
|
|
3483
3500
|
let magic;
|
|
@@ -4496,45 +4513,48 @@ function lastMarkRunIn(state, range, markName) {
|
|
|
4496
4513
|
* the `mdLinkUri` run locates the `( )` body.
|
|
4497
4514
|
*/
|
|
4498
4515
|
function getLinkUnitAt(state, pos) {
|
|
4499
|
-
const unit = getMarkRangeAt(state, pos, "mdPack",
|
|
4516
|
+
const unit = getMarkRangeAt(state, pos, "mdPack", (mark) => mark.attrs.key.startsWith("link-"));
|
|
4500
4517
|
if (!unit) return;
|
|
4501
|
-
const
|
|
4518
|
+
const attrs = unit.mark.attrs;
|
|
4502
4519
|
const unitRange = {
|
|
4503
4520
|
from: unit.from,
|
|
4504
4521
|
to: unit.to
|
|
4505
4522
|
};
|
|
4506
|
-
switch (
|
|
4507
|
-
case "bare": return {
|
|
4523
|
+
switch (attrs.key) {
|
|
4524
|
+
case "link-bare": return {
|
|
4525
|
+
state,
|
|
4508
4526
|
form: "bare",
|
|
4509
4527
|
unit: unitRange,
|
|
4510
4528
|
text: unitRange,
|
|
4511
|
-
href: data.href,
|
|
4529
|
+
href: attrs.data.href,
|
|
4512
4530
|
title: ""
|
|
4513
4531
|
};
|
|
4514
|
-
case "angle": return {
|
|
4532
|
+
case "link-angle": return {
|
|
4533
|
+
state,
|
|
4515
4534
|
form: "angle",
|
|
4516
4535
|
unit: unitRange,
|
|
4517
4536
|
text: {
|
|
4518
4537
|
from: unit.from + 1,
|
|
4519
4538
|
to: unit.to - 1
|
|
4520
4539
|
},
|
|
4521
|
-
href: data.href,
|
|
4540
|
+
href: attrs.data.href,
|
|
4522
4541
|
title: ""
|
|
4523
4542
|
};
|
|
4524
|
-
case "reference": {
|
|
4543
|
+
case "link-reference": {
|
|
4525
4544
|
const linkText = getMarkRangeAt(state, pos, "mdLinkText");
|
|
4526
4545
|
return {
|
|
4546
|
+
state,
|
|
4527
4547
|
form: "reference",
|
|
4528
4548
|
unit: unitRange,
|
|
4529
4549
|
text: linkText == null ? unitRange : {
|
|
4530
4550
|
from: linkText.from + 1,
|
|
4531
4551
|
to: linkText.to
|
|
4532
4552
|
},
|
|
4533
|
-
href: data.href,
|
|
4534
|
-
title: data.title
|
|
4553
|
+
href: attrs.data.href,
|
|
4554
|
+
title: attrs.data.title
|
|
4535
4555
|
};
|
|
4536
4556
|
}
|
|
4537
|
-
case "inline": {
|
|
4557
|
+
case "link-inline": {
|
|
4538
4558
|
const uri = lastMarkRunIn(state, unitRange, "mdLinkUri");
|
|
4539
4559
|
const closeBracket = uri ? uri.from - 2 : unit.to - 3;
|
|
4540
4560
|
const destFrom = uri ? uri.from : unit.to - 1;
|
|
@@ -4543,6 +4563,7 @@ function getLinkUnitAt(state, pos) {
|
|
|
4543
4563
|
to: closeBracket
|
|
4544
4564
|
};
|
|
4545
4565
|
return {
|
|
4566
|
+
state,
|
|
4546
4567
|
form: "inline",
|
|
4547
4568
|
unit: unitRange,
|
|
4548
4569
|
text: label,
|
|
@@ -4551,8 +4572,8 @@ function getLinkUnitAt(state, pos) {
|
|
|
4551
4572
|
from: destFrom,
|
|
4552
4573
|
to: unit.to - 1
|
|
4553
4574
|
},
|
|
4554
|
-
href: data.href,
|
|
4555
|
-
title: data.title
|
|
4575
|
+
href: attrs.data.href,
|
|
4576
|
+
title: attrs.data.title
|
|
4556
4577
|
};
|
|
4557
4578
|
}
|
|
4558
4579
|
}
|
|
@@ -4574,6 +4595,39 @@ function destText(href, title) {
|
|
|
4574
4595
|
return href + (title ? ` "${title.replaceAll(/(["\\])/g, String.raw`\$1`)}"` : "");
|
|
4575
4596
|
}
|
|
4576
4597
|
/**
|
|
4598
|
+
* Escape a plain-text label so it cannot pick up inline semantics: the
|
|
4599
|
+
* CommonMark delimiters plus meowdown's `==highlight==`, `$math$`, and `#tag`.
|
|
4600
|
+
*/
|
|
4601
|
+
function linkLabelText(text) {
|
|
4602
|
+
return text.replaceAll(/([&<\\[\]_*`~=$#])/g, String.raw`\$1`);
|
|
4603
|
+
}
|
|
4604
|
+
/**
|
|
4605
|
+
* Get a range's plain visible text, skipping hidden syntax runs.
|
|
4606
|
+
*/
|
|
4607
|
+
function getVisibleText(state, range) {
|
|
4608
|
+
let text = "";
|
|
4609
|
+
state.doc.nodesBetween(range.from, range.to, (node, pos) => {
|
|
4610
|
+
if (!node.isText || !node.text || hasSyntaxMark(node.marks)) return;
|
|
4611
|
+
const from = Math.max(range.from, pos) - pos;
|
|
4612
|
+
const to = Math.min(range.to, pos + node.nodeSize) - pos;
|
|
4613
|
+
text += node.text.slice(from, to);
|
|
4614
|
+
});
|
|
4615
|
+
return text;
|
|
4616
|
+
}
|
|
4617
|
+
/**
|
|
4618
|
+
* Get a link's plain visible text.
|
|
4619
|
+
*/
|
|
4620
|
+
function getLinkText(link) {
|
|
4621
|
+
return getVisibleText(link.state, link.text);
|
|
4622
|
+
}
|
|
4623
|
+
/**
|
|
4624
|
+
* Whether plain visible link text names the same destination as the link.
|
|
4625
|
+
*/
|
|
4626
|
+
function isLinkTextForHref(text, href) {
|
|
4627
|
+
const value = text.trim();
|
|
4628
|
+
return value === href || getAutolinkHref(value) === href;
|
|
4629
|
+
}
|
|
4630
|
+
/**
|
|
4577
4631
|
* The range a new link would wrap: the current selection when it is a
|
|
4578
4632
|
* non-empty text selection inside a single non-code textblock, trimmed of
|
|
4579
4633
|
* surrounding whitespace. `undefined` when there is nothing to wrap.
|
|
@@ -4592,16 +4646,24 @@ function getWrapRange(state) {
|
|
|
4592
4646
|
to: base + to
|
|
4593
4647
|
};
|
|
4594
4648
|
}
|
|
4595
|
-
function insertLink({ href, title, wrapText = true } = {}) {
|
|
4649
|
+
function insertLink({ href, title, text, wrapText = true } = {}) {
|
|
4596
4650
|
return (state, dispatch) => {
|
|
4597
4651
|
const range = getWrapRange(state);
|
|
4598
4652
|
if (!range) return false;
|
|
4599
4653
|
if (dispatch) {
|
|
4600
4654
|
const { from, to } = range;
|
|
4601
4655
|
const tr = state.tr;
|
|
4602
|
-
const
|
|
4603
|
-
|
|
4604
|
-
|
|
4656
|
+
const dest = destText(normalizeHref(href ?? ""), title ?? "");
|
|
4657
|
+
let linkTo;
|
|
4658
|
+
if (text !== void 0 && text !== getVisibleText(state, range)) {
|
|
4659
|
+
const markdown = `[${linkLabelText(text)}](${dest})`;
|
|
4660
|
+
tr.insertText(markdown, from, to);
|
|
4661
|
+
linkTo = from + markdown.length;
|
|
4662
|
+
} else {
|
|
4663
|
+
const close = `](${dest})`;
|
|
4664
|
+
tr.insertText(close, to).insertText("[", from);
|
|
4665
|
+
linkTo = to + 1 + close.length;
|
|
4666
|
+
}
|
|
4605
4667
|
tr.setSelection(wrapText ? TextSelection.create(tr.doc, from, linkTo) : TextSelection.create(tr.doc, linkTo));
|
|
4606
4668
|
tr.scrollIntoView();
|
|
4607
4669
|
dispatch(tr);
|
|
@@ -4610,14 +4672,18 @@ function insertLink({ href, title, wrapText = true } = {}) {
|
|
|
4610
4672
|
};
|
|
4611
4673
|
}
|
|
4612
4674
|
/**
|
|
4613
|
-
* Rewrite
|
|
4675
|
+
* Rewrite a mutable link. Autolinks are promoted to inline Markdown when
|
|
4676
|
+
* their visible text or destination changes.
|
|
4614
4677
|
*/
|
|
4615
4678
|
function updateLink(attrs) {
|
|
4616
4679
|
return (state, dispatch) => {
|
|
4617
4680
|
const link = getLinkUnitAt(state, state.selection.from);
|
|
4618
|
-
if (link
|
|
4619
|
-
const
|
|
4620
|
-
|
|
4681
|
+
if (!link || link.form === "reference") return false;
|
|
4682
|
+
const href = normalizeHref(attrs.href ?? link.href);
|
|
4683
|
+
const title = attrs.title ?? link.title;
|
|
4684
|
+
const text = attrs.text ?? getLinkText(link);
|
|
4685
|
+
const replacingUnit = attrs.text !== void 0 || link.form !== "inline";
|
|
4686
|
+
if (dispatch) dispatch((replacingUnit ? state.tr.insertText(`[${linkLabelText(text)}](${destText(href, title)})`, link.unit.from, link.unit.to) : state.tr.insertText(destText(href, title), link.dest.from, link.dest.to)).scrollIntoView());
|
|
4621
4687
|
return true;
|
|
4622
4688
|
};
|
|
4623
4689
|
}
|
|
@@ -4627,8 +4693,11 @@ function updateLink(attrs) {
|
|
|
4627
4693
|
function removeLink() {
|
|
4628
4694
|
return (state, dispatch) => {
|
|
4629
4695
|
const link = getLinkUnitAt(state, state.selection.from);
|
|
4630
|
-
if (link
|
|
4631
|
-
if (dispatch)
|
|
4696
|
+
if (!link || link.form === "reference") return false;
|
|
4697
|
+
if (dispatch) {
|
|
4698
|
+
const text = getLinkText(link);
|
|
4699
|
+
dispatch((link.form === "inline" && !getAutolinkHref(text) ? state.tr.delete(link.label.to, link.unit.to).delete(link.unit.from, link.label.from) : state.tr.insertText(text + formatMagicComment({ noLink: true }), link.unit.from, link.unit.to)).scrollIntoView());
|
|
4700
|
+
}
|
|
4632
4701
|
return true;
|
|
4633
4702
|
};
|
|
4634
4703
|
}
|
|
@@ -4643,7 +4712,7 @@ function openLinkEdit(onLinkEdit) {
|
|
|
4643
4712
|
return (state, dispatch, view) => {
|
|
4644
4713
|
const link = getLinkUnitAt(state, state.selection.from);
|
|
4645
4714
|
if (link) {
|
|
4646
|
-
if (link.form
|
|
4715
|
+
if (link.form === "reference") return false;
|
|
4647
4716
|
if (dispatch && view) {
|
|
4648
4717
|
const { unit: { from, to } } = link;
|
|
4649
4718
|
dispatch(state.tr.setSelection(TextSelection.create(state.doc, from, to)).scrollIntoView());
|
|
@@ -4651,7 +4720,8 @@ function openLinkEdit(onLinkEdit) {
|
|
|
4651
4720
|
onLinkEdit({
|
|
4652
4721
|
from,
|
|
4653
4722
|
to,
|
|
4654
|
-
link
|
|
4723
|
+
link,
|
|
4724
|
+
text: getLinkText(link)
|
|
4655
4725
|
});
|
|
4656
4726
|
}
|
|
4657
4727
|
return true;
|
|
@@ -4665,7 +4735,8 @@ function openLinkEdit(onLinkEdit) {
|
|
|
4665
4735
|
onLinkEdit({
|
|
4666
4736
|
from,
|
|
4667
4737
|
to,
|
|
4668
|
-
link: void 0
|
|
4738
|
+
link: void 0,
|
|
4739
|
+
text: getVisibleText(state, wrapRange)
|
|
4669
4740
|
});
|
|
4670
4741
|
}
|
|
4671
4742
|
return true;
|
|
@@ -7986,36 +8057,98 @@ function defineLinkClickHandler(onClick) {
|
|
|
7986
8057
|
* after every editor update, so deleting, replacing, or rewriting a hovered
|
|
7987
8058
|
* mark emits leave even when the pointer itself never moves. Destroying the
|
|
7988
8059
|
* editor or removing the extension emits leave as well.
|
|
8060
|
+
*
|
|
8061
|
+
* With `tap`, a touch tap enters too. The browser is the tap recognizer:
|
|
8062
|
+
* only a recognized stationary single-finger tap synthesizes the
|
|
8063
|
+
* compatibility mouse events and the trailing `click`; scrolls, drags,
|
|
8064
|
+
* long-presses, and multi-finger gestures never produce them.
|
|
7989
8065
|
*/
|
|
7990
8066
|
function defineMarkHoverHandler(config) {
|
|
7991
|
-
|
|
8067
|
+
const { openDelay, closeDelay, tap } = config;
|
|
8068
|
+
/**
|
|
8069
|
+
* What `onHoverChange` last received, while that is a hit.
|
|
8070
|
+
*/
|
|
8071
|
+
let emitted;
|
|
8072
|
+
let timer;
|
|
8073
|
+
/**
|
|
8074
|
+
* The element of a scheduled enter, `null` for a scheduled leave,
|
|
8075
|
+
* `undefined` when nothing is scheduled.
|
|
8076
|
+
*/
|
|
8077
|
+
let scheduledElement;
|
|
8078
|
+
/**
|
|
8079
|
+
* The type of the pointer that spawned the current event sequence:
|
|
8080
|
+
* compatibility mouse events carry no pointer type of their own.
|
|
8081
|
+
*/
|
|
8082
|
+
let lastPointerType = "";
|
|
8083
|
+
const findClosestMark = (target) => {
|
|
8084
|
+
return isElementLike(target) ? target.closest(config.selector) : null;
|
|
8085
|
+
};
|
|
7992
8086
|
const findPayloadForElement = (view, element) => {
|
|
7993
8087
|
return config.findPayloadForElement ? config.findPayloadForElement(view, element) : config.findPayloadAt(view.state, view.posAtDOM(element, 0));
|
|
7994
8088
|
};
|
|
7995
|
-
const
|
|
7996
|
-
|
|
7997
|
-
|
|
7998
|
-
config.onHoverChange(void 0);
|
|
8089
|
+
const cancel = () => {
|
|
8090
|
+
clearTimeout(timer);
|
|
8091
|
+
scheduledElement = void 0;
|
|
7999
8092
|
};
|
|
8000
|
-
const
|
|
8001
|
-
|
|
8002
|
-
if (!
|
|
8003
|
-
|
|
8004
|
-
|
|
8005
|
-
|
|
8093
|
+
const emit = (hit) => {
|
|
8094
|
+
cancel();
|
|
8095
|
+
if (!hit && !emitted) return;
|
|
8096
|
+
emitted = hit;
|
|
8097
|
+
config.onHoverChange(hit);
|
|
8098
|
+
};
|
|
8099
|
+
const scheduleLeave = () => {
|
|
8100
|
+
cancel();
|
|
8101
|
+
scheduledElement = null;
|
|
8102
|
+
const fire = () => {
|
|
8103
|
+
if (config.canLeave?.() === false) {
|
|
8104
|
+
timer = setTimeout(fire, closeDelay);
|
|
8105
|
+
return;
|
|
8106
|
+
}
|
|
8107
|
+
emit(void 0);
|
|
8108
|
+
};
|
|
8109
|
+
timer = setTimeout(fire, closeDelay);
|
|
8110
|
+
};
|
|
8111
|
+
const enter = (view, element) => {
|
|
8006
8112
|
const payload = findPayloadForElement(view, element);
|
|
8007
8113
|
if (payload == null) return;
|
|
8008
|
-
|
|
8009
|
-
|
|
8010
|
-
|
|
8011
|
-
|
|
8012
|
-
|
|
8114
|
+
if (emitted) {
|
|
8115
|
+
emit({
|
|
8116
|
+
payload,
|
|
8117
|
+
element
|
|
8118
|
+
});
|
|
8119
|
+
return;
|
|
8120
|
+
}
|
|
8121
|
+
cancel();
|
|
8122
|
+
scheduledElement = element;
|
|
8123
|
+
timer = setTimeout(() => {
|
|
8124
|
+
const fresh = element.isConnected ? findPayloadForElement(view, element) : void 0;
|
|
8125
|
+
if (fresh == null) {
|
|
8126
|
+
cancel();
|
|
8127
|
+
return;
|
|
8128
|
+
}
|
|
8129
|
+
emit({
|
|
8130
|
+
payload: fresh,
|
|
8131
|
+
element
|
|
8132
|
+
});
|
|
8133
|
+
}, openDelay);
|
|
8134
|
+
};
|
|
8135
|
+
const handleOver = (view, event) => {
|
|
8136
|
+
const element = findClosestMark(event.target);
|
|
8137
|
+
if (!element || !view.dom.contains(element)) return;
|
|
8138
|
+
if (element === emitted?.element) {
|
|
8139
|
+
if (scheduledElement === null) cancel();
|
|
8140
|
+
return;
|
|
8141
|
+
}
|
|
8142
|
+
if (element === scheduledElement) return;
|
|
8143
|
+
enter(view, element);
|
|
8013
8144
|
};
|
|
8014
8145
|
const handleOut = (event) => {
|
|
8015
|
-
|
|
8146
|
+
const active = emitted?.element ?? scheduledElement;
|
|
8147
|
+
if (!active) return;
|
|
8016
8148
|
const related = event.relatedTarget;
|
|
8017
|
-
if (related instanceof Node &&
|
|
8018
|
-
|
|
8149
|
+
if (related instanceof Node && active.contains(related)) return;
|
|
8150
|
+
if (emitted) scheduleLeave();
|
|
8151
|
+
else cancel();
|
|
8019
8152
|
};
|
|
8020
8153
|
return definePlugin(new Plugin({
|
|
8021
8154
|
key: config.key,
|
|
@@ -8027,26 +8160,52 @@ function defineMarkHoverHandler(config) {
|
|
|
8027
8160
|
mouseout: (_view, event) => {
|
|
8028
8161
|
handleOut(event);
|
|
8029
8162
|
return false;
|
|
8163
|
+
},
|
|
8164
|
+
...tap && {
|
|
8165
|
+
pointerdown: (_view, event) => {
|
|
8166
|
+
lastPointerType = event.pointerType;
|
|
8167
|
+
return false;
|
|
8168
|
+
},
|
|
8169
|
+
mousedown: (_view, event) => {
|
|
8170
|
+
if (lastPointerType !== "touch" || !findClosestMark(event.target)) return false;
|
|
8171
|
+
event.preventDefault();
|
|
8172
|
+
return true;
|
|
8173
|
+
},
|
|
8174
|
+
click: (view, event) => {
|
|
8175
|
+
if (lastPointerType !== "touch") return false;
|
|
8176
|
+
const element = findClosestMark(event.target);
|
|
8177
|
+
if (!element || !view.dom.contains(element)) {
|
|
8178
|
+
emit(void 0);
|
|
8179
|
+
return false;
|
|
8180
|
+
}
|
|
8181
|
+
event.preventDefault();
|
|
8182
|
+
const payload = findPayloadForElement(view, element);
|
|
8183
|
+
if (payload != null) emit({
|
|
8184
|
+
payload,
|
|
8185
|
+
element
|
|
8186
|
+
});
|
|
8187
|
+
return true;
|
|
8188
|
+
}
|
|
8030
8189
|
}
|
|
8031
8190
|
} },
|
|
8032
8191
|
view: () => ({
|
|
8033
8192
|
update: (view) => {
|
|
8034
|
-
if (!
|
|
8035
|
-
if (!
|
|
8036
|
-
|
|
8193
|
+
if (!emitted) return;
|
|
8194
|
+
if (!emitted.element.isConnected || !view.dom.contains(emitted.element)) {
|
|
8195
|
+
emit(void 0);
|
|
8037
8196
|
return;
|
|
8038
8197
|
}
|
|
8039
|
-
const payload = findPayloadForElement(view,
|
|
8040
|
-
if (payload == null || !config.isSamePayload(
|
|
8041
|
-
|
|
8198
|
+
const payload = findPayloadForElement(view, emitted.element);
|
|
8199
|
+
if (payload == null || !config.isSamePayload(emitted.payload, payload)) {
|
|
8200
|
+
emit(void 0);
|
|
8042
8201
|
return;
|
|
8043
8202
|
}
|
|
8044
|
-
|
|
8045
|
-
...
|
|
8203
|
+
emitted = {
|
|
8204
|
+
...emitted,
|
|
8046
8205
|
payload
|
|
8047
8206
|
};
|
|
8048
8207
|
},
|
|
8049
|
-
destroy:
|
|
8208
|
+
destroy: () => emit(void 0)
|
|
8050
8209
|
})
|
|
8051
8210
|
}));
|
|
8052
8211
|
}
|
|
@@ -8054,10 +8213,30 @@ function defineMarkHoverHandler(config) {
|
|
|
8054
8213
|
//#endregion
|
|
8055
8214
|
//#region src/extensions/link-hover.ts
|
|
8056
8215
|
const linkHoverKey = new PluginKey("meowdown-link-hover");
|
|
8057
|
-
|
|
8216
|
+
/**
|
|
8217
|
+
* Dwell before a cold hover enters, in ms.
|
|
8218
|
+
*/
|
|
8219
|
+
const OPEN_DELAY = 300;
|
|
8220
|
+
/**
|
|
8221
|
+
* Grace before a leave fires, in ms. The window lets a pointer travel from
|
|
8222
|
+
* the hovered link onto the popup it anchors.
|
|
8223
|
+
*/
|
|
8224
|
+
const CLOSE_DELAY = 100;
|
|
8225
|
+
/**
|
|
8226
|
+
* Track the link under the user's attention: a mouse hover after a short
|
|
8227
|
+
* dwell, or a touch tap immediately, since touch has no hover. Without the
|
|
8228
|
+
* tap entry, the popup's preview and actions would stay unreachable on
|
|
8229
|
+
* phones, where a tap on a link only places the caret and raises the
|
|
8230
|
+
* software keyboard.
|
|
8231
|
+
*/
|
|
8232
|
+
function defineLinkHoverHandler(onHoverChange, { canLeave } = {}) {
|
|
8058
8233
|
return defineMarkHoverHandler({
|
|
8059
8234
|
key: linkHoverKey,
|
|
8060
8235
|
selector: ".md-link",
|
|
8236
|
+
openDelay: OPEN_DELAY,
|
|
8237
|
+
closeDelay: CLOSE_DELAY,
|
|
8238
|
+
tap: true,
|
|
8239
|
+
canLeave,
|
|
8061
8240
|
findPayloadAt: (state, pos) => {
|
|
8062
8241
|
return getLinkUnitAt(state, pos);
|
|
8063
8242
|
},
|
|
@@ -8444,6 +8623,9 @@ function defineWikilinkHoverHandler(onHoverChange) {
|
|
|
8444
8623
|
return defineMarkHoverHandler({
|
|
8445
8624
|
key: wikilinkHoverKey,
|
|
8446
8625
|
selector: ".md-wikilink-view-preview",
|
|
8626
|
+
openDelay: 0,
|
|
8627
|
+
closeDelay: 0,
|
|
8628
|
+
tap: false,
|
|
8447
8629
|
findPayloadAt: findWikilinkAt,
|
|
8448
8630
|
findPayloadForElement: findWikilinkForElement,
|
|
8449
8631
|
isSamePayload: (previous, next) => previous.target === next.target,
|
|
@@ -8611,4 +8793,4 @@ function getVirtualElementFromRange(view, range) {
|
|
|
8611
8793
|
}
|
|
8612
8794
|
|
|
8613
8795
|
//#endregion
|
|
8614
|
-
export { EDITOR_KEY_BINDINGS, Priority, buildFileMarkdown, checkRoundTrip, codeBlockLanguages, collectReferenceDefinitions, defaultResolveImageUrl, 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, getFileKind, getIsComposing, getLinkUnitAt, getMarkBuilders, getPendingReplacement, getSearchStatus, getSelectedText, getTableColumnAlign, getTextblockDisplayText, getVirtualElementFromRange, inlineTextToMarkChunks, inlineTextToMarkChunksWithContext, insertLink, isCodeBlockPreviewHiddenDecoration, isMarkOfType, isModEvent, isNodeOfType, isSelectionInTableCell, listenForTweetHeight, loadKaTeX, markdownToDoc, matchEmbed, parseWikiEmbed, removeLink, renderMathInto, updateLink, wikiEmbedBasename, withPriority };
|
|
8796
|
+
export { EDITOR_KEY_BINDINGS, Priority, buildFileMarkdown, checkRoundTrip, codeBlockLanguages, collectReferenceDefinitions, defaultResolveImageUrl, 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, getFileKind, getIsComposing, getLinkText, getLinkUnitAt, getMarkBuilders, getPendingReplacement, getSearchStatus, getSelectedText, getTableColumnAlign, getTextblockDisplayText, getVirtualElementFromRange, inlineTextToMarkChunks, inlineTextToMarkChunksWithContext, insertLink, isCodeBlockPreviewHiddenDecoration, isLinkTextForHref, isMarkOfType, isModEvent, isNodeOfType, isSelectionInTableCell, listenForTweetHeight, loadKaTeX, markdownToDoc, matchEmbed, normalizeHref, parseWikiEmbed, removeLink, renderMathInto, updateLink, wikiEmbedBasename, withPriority };
|
package/dist/style.css
CHANGED
|
@@ -155,6 +155,7 @@
|
|
|
155
155
|
--meowdown-heading: light-dark(oklch(21% .006 286), oklch(98.5% 0 0));
|
|
156
156
|
--meowdown-muted: light-dark(oklch(44.2% .015 286), oklch(71.2% .013 286));
|
|
157
157
|
--meowdown-accent: light-dark(oklch(64.6% .194 41), oklch(75.8% .159 56));
|
|
158
|
+
--meowdown-accent-contrast: light-dark(oklch(100% 0 0), oklch(21% .006 286));
|
|
158
159
|
--meowdown-caret: var(--meowdown-accent);
|
|
159
160
|
--meowdown-caret-glide: 80ms;
|
|
160
161
|
--meowdown-mark: var(--meowdown-muted);
|
|
@@ -189,6 +190,9 @@
|
|
|
189
190
|
--meowdown-table-header-bg: light-dark(oklch(98.5% 0 0), oklch(27.4% .005 286));
|
|
190
191
|
--meowdown-popover-bg: light-dark(oklch(100% 0 0), oklch(21% .006 286));
|
|
191
192
|
--meowdown-popover-hover-bg: light-dark(oklch(96.7% 0 0), oklch(27.4% .005 286));
|
|
193
|
+
--meowdown-hover-card-border: var(--meowdown-border);
|
|
194
|
+
--meowdown-hover-card-radius: .75rem;
|
|
195
|
+
--meowdown-hover-card-shadow: 0 10px 15px -3px #0000001a, 0 4px 6px -4px #0000001a;
|
|
192
196
|
--meowdown-danger: light-dark(oklch(63.7% .208 25), oklch(71.1% .166 22));
|
|
193
197
|
--meowdown-placeholder: var(--meowdown-muted);
|
|
194
198
|
--meowdown-font-mono: ui-monospace, SFMono-Regular, Menlo, monospace;
|
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.67.1",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -26,10 +26,10 @@
|
|
|
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.1",
|
|
30
|
+
"@prosekit/extensions": "^0.18.1",
|
|
31
31
|
"@prosekit/pm": "^0.1.19",
|
|
32
|
-
"@prosekit/web": "^0.9.
|
|
32
|
+
"@prosekit/web": "^0.9.1",
|
|
33
33
|
"hast-util-to-mdast": "^10.1.2",
|
|
34
34
|
"katex": "^0.18.1",
|
|
35
35
|
"mdast-util-to-markdown": "^2.1.2",
|
|
@@ -43,20 +43,19 @@
|
|
|
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.67.1"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@ocavue/tsconfig": "^0.7.1",
|
|
50
50
|
"@tsdown/css": "^0.23.0-beta.2",
|
|
51
51
|
"@types/hast": "^3.0.5",
|
|
52
52
|
"@types/mdast": "^4.0.4",
|
|
53
|
-
"@vitest/browser-playwright": "^4.1.
|
|
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
|
-
"fast-check": "^4.9.0",
|
|
58
57
|
"tsdown": "^0.23.0-beta.2",
|
|
59
|
-
"vitest": "^4.1.
|
|
58
|
+
"vitest": "^4.1.11",
|
|
60
59
|
"@meowdown/vitest": "0.0.0"
|
|
61
60
|
},
|
|
62
61
|
"publishConfig": {
|