@meowdown/core 0.64.3 → 0.65.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 +82 -39
- package/dist/index.js +218 -168
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1055,6 +1055,11 @@ interface FileClickPayload {
|
|
|
1055
1055
|
* pill. Read modifier keys or position a popover from it.
|
|
1056
1056
|
*/
|
|
1057
1057
|
event: MouseEvent | KeyboardEvent;
|
|
1058
|
+
/**
|
|
1059
|
+
* Whether the platform's mod key (`Command` on Apple, `Ctrl` elsewhere) was held
|
|
1060
|
+
* beyond the gesture that triggered the activation.
|
|
1061
|
+
*/
|
|
1062
|
+
mod: boolean;
|
|
1058
1063
|
}
|
|
1059
1064
|
type FileClickHandler = (payload: FileClickPayload) => void;
|
|
1060
1065
|
/**
|
|
@@ -1140,6 +1145,45 @@ declare function getFileKind(href: string): string;
|
|
|
1140
1145
|
*/
|
|
1141
1146
|
declare function defineFileView(options?: FileViewOptions): PlainExtension;
|
|
1142
1147
|
//#endregion
|
|
1148
|
+
//#region src/extensions/image-click.d.ts
|
|
1149
|
+
/**
|
|
1150
|
+
* Payload for {@link ImageClickHandler}.
|
|
1151
|
+
*/
|
|
1152
|
+
interface ImageClickPayload {
|
|
1153
|
+
/**
|
|
1154
|
+
* The resolved source from `` or a claimed `![[target]]`.
|
|
1155
|
+
*/
|
|
1156
|
+
src: string;
|
|
1157
|
+
/**
|
|
1158
|
+
* The image alt text.
|
|
1159
|
+
*/
|
|
1160
|
+
alt: string;
|
|
1161
|
+
/**
|
|
1162
|
+
* The originating click or touch tap, or the `Enter`/`Mod-Enter` key press
|
|
1163
|
+
* that followed the selected image. Read the target or position a popover
|
|
1164
|
+
* from it; a touch surface delivers the `touchend` instead of a click.
|
|
1165
|
+
*/
|
|
1166
|
+
event: MouseEvent | TouchEvent | KeyboardEvent;
|
|
1167
|
+
/**
|
|
1168
|
+
* Whether the platform's mod key (`Command` on Apple, `Ctrl` elsewhere) was held
|
|
1169
|
+
* beyond the gesture that triggered the activation.
|
|
1170
|
+
*/
|
|
1171
|
+
mod: boolean;
|
|
1172
|
+
}
|
|
1173
|
+
type ImageClickHandler = (payload: ImageClickPayload) => void;
|
|
1174
|
+
/**
|
|
1175
|
+
* Call `onClick` when the user clicks or taps a rendered image preview, with
|
|
1176
|
+
* the image's markdown `src`, `alt`, and the originating event.
|
|
1177
|
+
*
|
|
1178
|
+
* Touch taps are handled from `touchend` rather than the synthetic click:
|
|
1179
|
+
* previews live inside the editor contenteditable, and iOS WebKit's
|
|
1180
|
+
* tap-to-focus is a native gesture default action that only cancelling the
|
|
1181
|
+
* `touchend` can suppress — otherwise a tap briefly focuses the editor and
|
|
1182
|
+
* raises the software keyboard before the handler opens its own surface
|
|
1183
|
+
* (such as a lightbox).
|
|
1184
|
+
*/
|
|
1185
|
+
declare function defineImageClickHandler(onClick: ImageClickHandler): PlainExtension;
|
|
1186
|
+
//#endregion
|
|
1143
1187
|
//#region src/extensions/link-click.d.ts
|
|
1144
1188
|
interface LinkClickPayload {
|
|
1145
1189
|
href: string;
|
|
@@ -1147,6 +1191,11 @@ interface LinkClickPayload {
|
|
|
1147
1191
|
* The originating click, or the `Enter`/`Mod-Enter` key press that followed the link.
|
|
1148
1192
|
*/
|
|
1149
1193
|
event: MouseEvent | KeyboardEvent;
|
|
1194
|
+
/**
|
|
1195
|
+
* Whether the platform's mod key (`Command` on Apple, `Ctrl` elsewhere) was held
|
|
1196
|
+
* beyond the gesture that triggered the activation.
|
|
1197
|
+
*/
|
|
1198
|
+
mod: boolean;
|
|
1150
1199
|
}
|
|
1151
1200
|
type LinkClickHandler = (payload: LinkClickPayload) => void;
|
|
1152
1201
|
interface LinkCopyPayload {
|
|
@@ -1171,6 +1220,11 @@ interface TagClickPayload {
|
|
|
1171
1220
|
* Read modifier keys or position a popover from it.
|
|
1172
1221
|
*/
|
|
1173
1222
|
event: MouseEvent | KeyboardEvent;
|
|
1223
|
+
/**
|
|
1224
|
+
* Whether the platform's mod key (`Command` on Apple, `Ctrl` elsewhere) was held
|
|
1225
|
+
* beyond the gesture that triggered the activation.
|
|
1226
|
+
*/
|
|
1227
|
+
mod: boolean;
|
|
1174
1228
|
}
|
|
1175
1229
|
type TagClickHandler = (payload: TagClickPayload) => void;
|
|
1176
1230
|
/**
|
|
@@ -1192,6 +1246,11 @@ interface WikilinkClickPayload {
|
|
|
1192
1246
|
* The originating click, or the `Enter`/`Mod-Enter` key press that followed the link.
|
|
1193
1247
|
*/
|
|
1194
1248
|
event: MouseEvent | KeyboardEvent;
|
|
1249
|
+
/**
|
|
1250
|
+
* Whether the platform's mod key (`Command` on Apple, `Ctrl` elsewhere) was held
|
|
1251
|
+
* beyond the gesture that triggered the activation.
|
|
1252
|
+
*/
|
|
1253
|
+
mod: boolean;
|
|
1195
1254
|
}
|
|
1196
1255
|
type WikilinkClickHandler = (payload: WikilinkClickPayload) => void;
|
|
1197
1256
|
/**
|
|
@@ -1207,49 +1266,24 @@ interface FollowLinkHandlers {
|
|
|
1207
1266
|
onTagClick?: TagClickHandler;
|
|
1208
1267
|
onFileClick?: FileClickHandler;
|
|
1209
1268
|
onLinkClick?: LinkClickHandler;
|
|
1269
|
+
onImageClick?: ImageClickHandler;
|
|
1210
1270
|
}
|
|
1211
1271
|
/**
|
|
1212
1272
|
* Binds `Mod-Enter` to follow the wikilink, tag, file pill, or Markdown link
|
|
1213
|
-
* under the caret, and plain `Enter` to follow a selected atom unit
|
|
1214
|
-
* the same handlers a click does.
|
|
1215
|
-
* the
|
|
1216
|
-
*
|
|
1217
|
-
* keymap
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
//#endregion
|
|
1221
|
-
//#region src/extensions/image-click.d.ts
|
|
1222
|
-
/**
|
|
1223
|
-
* Payload for {@link ImageClickHandler}.
|
|
1224
|
-
*/
|
|
1225
|
-
interface ImageClickPayload {
|
|
1226
|
-
/**
|
|
1227
|
-
* The resolved source from `` or a claimed `![[target]]`.
|
|
1228
|
-
*/
|
|
1229
|
-
src: string;
|
|
1230
|
-
/**
|
|
1231
|
-
* The image alt text.
|
|
1232
|
-
*/
|
|
1233
|
-
alt: string;
|
|
1234
|
-
/**
|
|
1235
|
-
* The originating click or touch tap. Read the target or position a popover
|
|
1236
|
-
* from it; a touch surface delivers the `touchend` instead of a click.
|
|
1237
|
-
*/
|
|
1238
|
-
event: MouseEvent | TouchEvent;
|
|
1239
|
-
}
|
|
1240
|
-
type ImageClickHandler = (payload: ImageClickPayload) => void;
|
|
1241
|
-
/**
|
|
1242
|
-
* Call `onClick` when the user clicks or taps a rendered image preview, with
|
|
1243
|
-
* the image's markdown `src`, `alt`, and the originating event.
|
|
1273
|
+
* under the caret, and plain `Enter` to follow a selected atom unit (a
|
|
1274
|
+
* wikilink, file pill, or image), firing the same handlers a click does.
|
|
1275
|
+
* "Under the caret" means strictly inside the unit: a caret merely touching
|
|
1276
|
+
* a unit's edge is next to it, not on it.
|
|
1277
|
+
* Off a link, `Mod-Enter` falls through so the list keymap keeps cycling
|
|
1278
|
+
* checkbox tasks; off a selected unit, `Enter` falls through to the regular
|
|
1279
|
+
* split. High priority puts this ahead of every keymap binding.
|
|
1244
1280
|
*
|
|
1245
|
-
*
|
|
1246
|
-
*
|
|
1247
|
-
*
|
|
1248
|
-
*
|
|
1249
|
-
* raises the software keyboard before the handler opens its own surface
|
|
1250
|
-
* (such as a lightbox).
|
|
1281
|
+
* A selected-unit follow reports `mod: true` when the platform's mod key
|
|
1282
|
+
* (`⌘` on Apple, `Ctrl` elsewhere) was held beyond its plain-`Enter` trigger;
|
|
1283
|
+
* a caret follow always reports `mod: false`, its mod key being the trigger
|
|
1284
|
+
* itself.
|
|
1251
1285
|
*/
|
|
1252
|
-
declare function
|
|
1286
|
+
declare function defineFollowLinkHandler(handlers: FollowLinkHandlers): PlainExtension;
|
|
1253
1287
|
//#endregion
|
|
1254
1288
|
//#region src/extensions/image.d.ts
|
|
1255
1289
|
type ImageUrlResolver = (src: string) => string | undefined;
|
|
@@ -1455,6 +1489,15 @@ declare function getTextblockDisplayText(textblock: ProseMirrorNode): string;
|
|
|
1455
1489
|
*/
|
|
1456
1490
|
declare function formatFileSize(bytes: number): string;
|
|
1457
1491
|
//#endregion
|
|
1492
|
+
//#region src/utils/is-mod-event.d.ts
|
|
1493
|
+
/**
|
|
1494
|
+
* Whether the platform's mod key is held on `event`: `Command` on Apple, `Ctrl` elsewhere.
|
|
1495
|
+
*/
|
|
1496
|
+
declare function isModEvent(event: MouseEvent | KeyboardEvent | TouchEvent | {
|
|
1497
|
+
metaKey: boolean;
|
|
1498
|
+
ctrlKey: boolean;
|
|
1499
|
+
}): boolean;
|
|
1500
|
+
//#endregion
|
|
1458
1501
|
//#region src/utils/katex-chunk.d.ts
|
|
1459
1502
|
type KaTeXRender = typeof render;
|
|
1460
1503
|
//#endregion
|
|
@@ -1492,4 +1535,4 @@ declare function getSelectedText(state: EditorState): string;
|
|
|
1492
1535
|
*/
|
|
1493
1536
|
declare function getVirtualElementFromRange(view: EditorView, range: PositionRange): VirtualElement;
|
|
1494
1537
|
//#endregion
|
|
1495
|
-
export { type AcceptPendingReplacementOptions, type CheckRoundTripOptions, type CodeBlockAttrs, type CodeBlockFenceStyle, type CodeToken, type DocToMarkdownOptions, EDITOR_KEY_BINDINGS, 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, 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, defineSpellCheckPlugin, 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, isNodeOfType, isSelectionInTableCell, listenForTweetHeight, loadKaTeX, markdownToDoc, matchEmbed, parseWikiEmbed, removeLink, renderMathInto, updateLink, wikiEmbedBasename, withPriority };
|
|
1538
|
+
export { type AcceptPendingReplacementOptions, type CheckRoundTripOptions, type CodeBlockAttrs, type CodeBlockFenceStyle, type CodeToken, type DocToMarkdownOptions, EDITOR_KEY_BINDINGS, 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, 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, defineSpellCheckPlugin, 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 };
|
package/dist/index.js
CHANGED
|
@@ -4428,11 +4428,13 @@ function defineMeowdownListSerializer() {
|
|
|
4428
4428
|
return (...args) => {
|
|
4429
4429
|
return {
|
|
4430
4430
|
...nodesFromSchema(...args),
|
|
4431
|
-
list: (node) =>
|
|
4432
|
-
|
|
4433
|
-
|
|
4434
|
-
|
|
4435
|
-
|
|
4431
|
+
list: (node) => {
|
|
4432
|
+
return listToDOM({
|
|
4433
|
+
node,
|
|
4434
|
+
nativeList: true,
|
|
4435
|
+
getAttributes: getListClipboardAttributes
|
|
4436
|
+
});
|
|
4437
|
+
}
|
|
4436
4438
|
};
|
|
4437
4439
|
};
|
|
4438
4440
|
}
|
|
@@ -6430,6 +6432,15 @@ function defineExitBoundaryHandler(onExitBoundary) {
|
|
|
6430
6432
|
return withPriority$1(definePlugin(createExitBoundaryPlugin(onExitBoundary)), Priority$1.low);
|
|
6431
6433
|
}
|
|
6432
6434
|
|
|
6435
|
+
//#endregion
|
|
6436
|
+
//#region src/utils/is-mod-event.ts
|
|
6437
|
+
/**
|
|
6438
|
+
* Whether the platform's mod key is held on `event`: `Command` on Apple, `Ctrl` elsewhere.
|
|
6439
|
+
*/
|
|
6440
|
+
function isModEvent(event) {
|
|
6441
|
+
return isApple ? event.metaKey : event.ctrlKey;
|
|
6442
|
+
}
|
|
6443
|
+
|
|
6433
6444
|
//#endregion
|
|
6434
6445
|
//#region src/extensions/file-click.ts
|
|
6435
6446
|
const fileClickKey = new PluginKey("meowdown-file-click");
|
|
@@ -6438,6 +6449,8 @@ function findFileAt(state, pos) {
|
|
|
6438
6449
|
if (!range) return;
|
|
6439
6450
|
const { href, name } = range.mark.attrs;
|
|
6440
6451
|
return {
|
|
6452
|
+
from: range.from,
|
|
6453
|
+
to: range.to,
|
|
6441
6454
|
href,
|
|
6442
6455
|
name
|
|
6443
6456
|
};
|
|
@@ -6460,7 +6473,8 @@ function defineFileClickHandler(onClick) {
|
|
|
6460
6473
|
onClick({
|
|
6461
6474
|
href: hit.href,
|
|
6462
6475
|
name: hit.name,
|
|
6463
|
-
event
|
|
6476
|
+
event,
|
|
6477
|
+
mod: isModEvent(event)
|
|
6464
6478
|
});
|
|
6465
6479
|
return true;
|
|
6466
6480
|
} }
|
|
@@ -6748,6 +6762,126 @@ function defineFileView(options = {}) {
|
|
|
6748
6762
|
});
|
|
6749
6763
|
}
|
|
6750
6764
|
|
|
6765
|
+
//#endregion
|
|
6766
|
+
//#region src/extensions/image-click.ts
|
|
6767
|
+
const imageClickKey = new PluginKey("meowdown-image-click");
|
|
6768
|
+
function getClosestImagePreview(target) {
|
|
6769
|
+
return target instanceof HTMLElement && target.closest(".md-image-view-preview");
|
|
6770
|
+
}
|
|
6771
|
+
function findImageAt(state, pos) {
|
|
6772
|
+
const range = getMarkRangeAt(state, pos, "mdImage");
|
|
6773
|
+
if (!range) return;
|
|
6774
|
+
const { src, alt } = range.mark.attrs;
|
|
6775
|
+
return {
|
|
6776
|
+
from: range.from,
|
|
6777
|
+
to: range.to,
|
|
6778
|
+
src,
|
|
6779
|
+
alt
|
|
6780
|
+
};
|
|
6781
|
+
}
|
|
6782
|
+
/**
|
|
6783
|
+
* Resolve the image hit for a preview element via its content holder, not the
|
|
6784
|
+
* event's document position: an event on the non-editable preview lands on the
|
|
6785
|
+
* run boundary, where `getMarkRange` would pick the next adjacent image.
|
|
6786
|
+
*/
|
|
6787
|
+
function findImageForPreview(view, preview) {
|
|
6788
|
+
const content = preview.closest(".md-image-view")?.querySelector(".md-image-view-content");
|
|
6789
|
+
if (!content) return;
|
|
6790
|
+
return findImageAt(view.state, view.posAtDOM(content, 0));
|
|
6791
|
+
}
|
|
6792
|
+
/**
|
|
6793
|
+
* Fingers wander a little during a tap; past this it is a scroll or a drag.
|
|
6794
|
+
*/
|
|
6795
|
+
const TAP_MOVE_TOLERANCE = 10;
|
|
6796
|
+
function findTouch(touches, identifier) {
|
|
6797
|
+
return Array.from(touches).find((touch) => touch.identifier === identifier);
|
|
6798
|
+
}
|
|
6799
|
+
function isWithinTapTolerance(pending, touch) {
|
|
6800
|
+
return Math.abs(touch.clientX - pending.clientX) <= TAP_MOVE_TOLERANCE && Math.abs(touch.clientY - pending.clientY) <= TAP_MOVE_TOLERANCE;
|
|
6801
|
+
}
|
|
6802
|
+
/**
|
|
6803
|
+
* Call `onClick` when the user clicks or taps a rendered image preview, with
|
|
6804
|
+
* the image's markdown `src`, `alt`, and the originating event.
|
|
6805
|
+
*
|
|
6806
|
+
* Touch taps are handled from `touchend` rather than the synthetic click:
|
|
6807
|
+
* previews live inside the editor contenteditable, and iOS WebKit's
|
|
6808
|
+
* tap-to-focus is a native gesture default action that only cancelling the
|
|
6809
|
+
* `touchend` can suppress — otherwise a tap briefly focuses the editor and
|
|
6810
|
+
* raises the software keyboard before the handler opens its own surface
|
|
6811
|
+
* (such as a lightbox).
|
|
6812
|
+
*/
|
|
6813
|
+
function defineImageClickHandler(onClick) {
|
|
6814
|
+
const pendingTaps = /* @__PURE__ */ new WeakMap();
|
|
6815
|
+
const handleTouchEnd = (view, event) => {
|
|
6816
|
+
const pending = pendingTaps.get(view);
|
|
6817
|
+
pendingTaps.delete(view);
|
|
6818
|
+
if (!pending || event.touches.length > 0) return false;
|
|
6819
|
+
const touch = findTouch(event.changedTouches, pending.identifier);
|
|
6820
|
+
if (!touch || !isWithinTapTolerance(pending, touch)) return false;
|
|
6821
|
+
const preview = getClosestImagePreview(event.target);
|
|
6822
|
+
if (!preview) return false;
|
|
6823
|
+
event.preventDefault();
|
|
6824
|
+
const hit = findImageForPreview(view, preview);
|
|
6825
|
+
if (hit) onClick({
|
|
6826
|
+
src: hit.src,
|
|
6827
|
+
alt: hit.alt,
|
|
6828
|
+
event,
|
|
6829
|
+
mod: isModEvent(event)
|
|
6830
|
+
});
|
|
6831
|
+
return true;
|
|
6832
|
+
};
|
|
6833
|
+
return definePlugin(new Plugin({
|
|
6834
|
+
key: imageClickKey,
|
|
6835
|
+
props: {
|
|
6836
|
+
handleDOMEvents: {
|
|
6837
|
+
pointerdown: (view, event) => {
|
|
6838
|
+
if (getClosestImagePreview(event.target) && event.pointerType !== "mouse") event.preventDefault();
|
|
6839
|
+
return false;
|
|
6840
|
+
},
|
|
6841
|
+
touchstart: (view, event) => {
|
|
6842
|
+
pendingTaps.delete(view);
|
|
6843
|
+
if (event.touches.length !== 1) return false;
|
|
6844
|
+
if (!getClosestImagePreview(event.target)) return false;
|
|
6845
|
+
if (event.target instanceof HTMLElement && event.target.closest(".md-image-resize-handle")) return false;
|
|
6846
|
+
const touch = event.changedTouches[0];
|
|
6847
|
+
if (!touch) return false;
|
|
6848
|
+
pendingTaps.set(view, {
|
|
6849
|
+
identifier: touch.identifier,
|
|
6850
|
+
clientX: touch.clientX,
|
|
6851
|
+
clientY: touch.clientY
|
|
6852
|
+
});
|
|
6853
|
+
return false;
|
|
6854
|
+
},
|
|
6855
|
+
touchmove: (view, event) => {
|
|
6856
|
+
const pending = pendingTaps.get(view);
|
|
6857
|
+
if (!pending) return false;
|
|
6858
|
+
const touch = findTouch(event.changedTouches, pending.identifier);
|
|
6859
|
+
if (touch && !isWithinTapTolerance(pending, touch)) pendingTaps.delete(view);
|
|
6860
|
+
return false;
|
|
6861
|
+
},
|
|
6862
|
+
touchcancel: (view) => {
|
|
6863
|
+
pendingTaps.delete(view);
|
|
6864
|
+
return false;
|
|
6865
|
+
},
|
|
6866
|
+
touchend: handleTouchEnd
|
|
6867
|
+
},
|
|
6868
|
+
handleClick: (view, _pos, event) => {
|
|
6869
|
+
const preview = getClosestImagePreview(event.target);
|
|
6870
|
+
if (!preview) return false;
|
|
6871
|
+
const hit = findImageForPreview(view, preview);
|
|
6872
|
+
if (!hit) return false;
|
|
6873
|
+
onClick({
|
|
6874
|
+
src: hit.src,
|
|
6875
|
+
alt: hit.alt,
|
|
6876
|
+
event,
|
|
6877
|
+
mod: isModEvent(event)
|
|
6878
|
+
});
|
|
6879
|
+
return true;
|
|
6880
|
+
}
|
|
6881
|
+
}
|
|
6882
|
+
}));
|
|
6883
|
+
}
|
|
6884
|
+
|
|
6751
6885
|
//#endregion
|
|
6752
6886
|
//#region src/extensions/mark-click.ts
|
|
6753
6887
|
/**
|
|
@@ -6801,7 +6935,8 @@ function defineTagClickHandler(onClick) {
|
|
|
6801
6935
|
findPayloadAt: (state, pos) => findTagAt(state, pos)?.tag,
|
|
6802
6936
|
onClick: (tag, event) => onClick({
|
|
6803
6937
|
tag,
|
|
6804
|
-
event
|
|
6938
|
+
event,
|
|
6939
|
+
mod: isModEvent(event)
|
|
6805
6940
|
})
|
|
6806
6941
|
});
|
|
6807
6942
|
}
|
|
@@ -6848,7 +6983,8 @@ function defineWikilinkClickHandler(onClick) {
|
|
|
6848
6983
|
findPayloadForElement: (view, element) => findWikilinkForElement(view, element)?.target,
|
|
6849
6984
|
onClick: (target, event) => onClick({
|
|
6850
6985
|
target,
|
|
6851
|
-
event
|
|
6986
|
+
event,
|
|
6987
|
+
mod: isModEvent(event)
|
|
6852
6988
|
})
|
|
6853
6989
|
});
|
|
6854
6990
|
}
|
|
@@ -6863,173 +6999,86 @@ function createFollowLinkPlugin(handlers) {
|
|
|
6863
6999
|
if (getIsComposing() || event.key !== "Enter" || event.shiftKey) return false;
|
|
6864
7000
|
const { state } = view;
|
|
6865
7001
|
const selectedAtom = getSelectedAtomRange(state);
|
|
6866
|
-
|
|
6867
|
-
|
|
6868
|
-
|
|
6869
|
-
if (
|
|
6870
|
-
handlers.onWikilinkClick?.({
|
|
6871
|
-
target: wikilink.target,
|
|
6872
|
-
event
|
|
6873
|
-
});
|
|
6874
|
-
return true;
|
|
6875
|
-
}
|
|
6876
|
-
const tag = handlers.onTagClick && findTagAt(state, pos);
|
|
6877
|
-
if (tag) {
|
|
6878
|
-
handlers.onTagClick?.({
|
|
6879
|
-
tag: tag.tag,
|
|
6880
|
-
event
|
|
6881
|
-
});
|
|
6882
|
-
return true;
|
|
6883
|
-
}
|
|
6884
|
-
const file = handlers.onFileClick && findFileAt(state, pos);
|
|
6885
|
-
if (file) {
|
|
6886
|
-
handlers.onFileClick?.({
|
|
6887
|
-
href: file.href,
|
|
6888
|
-
name: file.name,
|
|
6889
|
-
event
|
|
6890
|
-
});
|
|
6891
|
-
return true;
|
|
6892
|
-
}
|
|
6893
|
-
const link = handlers.onLinkClick && getLinkUnitAt(state, pos);
|
|
6894
|
-
if (link) {
|
|
6895
|
-
handlers.onLinkClick?.({
|
|
6896
|
-
href: link.href,
|
|
6897
|
-
event
|
|
6898
|
-
});
|
|
6899
|
-
return true;
|
|
6900
|
-
}
|
|
7002
|
+
const mod = isModEvent(event);
|
|
7003
|
+
if (!selectedAtom && !mod) return;
|
|
7004
|
+
if (selectedAtom && handlerAtomMarkTrigger(state, event, handlers, mod, selectedAtom)) return true;
|
|
7005
|
+
if (handlerTextMarkTrigger(state, event, handlers, mod)) return true;
|
|
6901
7006
|
return false;
|
|
6902
7007
|
} }
|
|
6903
7008
|
});
|
|
6904
7009
|
}
|
|
6905
|
-
|
|
6906
|
-
|
|
6907
|
-
|
|
6908
|
-
|
|
6909
|
-
|
|
6910
|
-
|
|
6911
|
-
|
|
6912
|
-
|
|
6913
|
-
|
|
6914
|
-
|
|
6915
|
-
|
|
6916
|
-
|
|
6917
|
-
|
|
6918
|
-
|
|
6919
|
-
|
|
6920
|
-
|
|
6921
|
-
|
|
6922
|
-
|
|
6923
|
-
|
|
6924
|
-
|
|
6925
|
-
|
|
6926
|
-
|
|
6927
|
-
|
|
6928
|
-
|
|
6929
|
-
|
|
6930
|
-
|
|
6931
|
-
|
|
6932
|
-
|
|
6933
|
-
|
|
6934
|
-
|
|
6935
|
-
|
|
6936
|
-
|
|
6937
|
-
* run boundary, where `getMarkRange` would pick the next adjacent image.
|
|
6938
|
-
*/
|
|
6939
|
-
function findImageForPreview(view, preview) {
|
|
6940
|
-
const content = preview.closest(".md-image-view")?.querySelector(".md-image-view-content");
|
|
6941
|
-
if (!content) return;
|
|
6942
|
-
return findImageAt(view.state, view.posAtDOM(content, 0));
|
|
6943
|
-
}
|
|
6944
|
-
/**
|
|
6945
|
-
* Fingers wander a little during a tap; past this it is a scroll or a drag.
|
|
6946
|
-
*/
|
|
6947
|
-
const TAP_MOVE_TOLERANCE = 10;
|
|
6948
|
-
function findTouch(touches, identifier) {
|
|
6949
|
-
return Array.from(touches).find((touch) => touch.identifier === identifier);
|
|
7010
|
+
function handlerAtomMarkTrigger(state, event, handlers, mod, selectedAtom) {
|
|
7011
|
+
const pos = selectedAtom.from + 1;
|
|
7012
|
+
const { onWikilinkClick, onFileClick, onImageClick } = handlers;
|
|
7013
|
+
const wikilink = onWikilinkClick && findWikilinkAt(state, pos);
|
|
7014
|
+
if (wikilink) {
|
|
7015
|
+
onWikilinkClick({
|
|
7016
|
+
target: wikilink.target,
|
|
7017
|
+
event,
|
|
7018
|
+
mod
|
|
7019
|
+
});
|
|
7020
|
+
return true;
|
|
7021
|
+
}
|
|
7022
|
+
const file = onFileClick && findFileAt(state, pos);
|
|
7023
|
+
if (file) {
|
|
7024
|
+
onFileClick({
|
|
7025
|
+
href: file.href,
|
|
7026
|
+
name: file.name,
|
|
7027
|
+
event,
|
|
7028
|
+
mod
|
|
7029
|
+
});
|
|
7030
|
+
return true;
|
|
7031
|
+
}
|
|
7032
|
+
const image = onImageClick && findImageAt(state, pos);
|
|
7033
|
+
if (image) {
|
|
7034
|
+
onImageClick({
|
|
7035
|
+
src: image.src,
|
|
7036
|
+
alt: image.alt,
|
|
7037
|
+
event,
|
|
7038
|
+
mod
|
|
7039
|
+
});
|
|
7040
|
+
return true;
|
|
7041
|
+
}
|
|
6950
7042
|
}
|
|
6951
|
-
function
|
|
6952
|
-
|
|
7043
|
+
function handlerTextMarkTrigger(state, event, handlers, mod) {
|
|
7044
|
+
const pos = state.selection.head;
|
|
7045
|
+
const { onTagClick, onLinkClick } = handlers;
|
|
7046
|
+
const tag = onTagClick && findTagAt(state, pos);
|
|
7047
|
+
if (tag && tag.from < pos && pos < tag.to) {
|
|
7048
|
+
onTagClick({
|
|
7049
|
+
tag: tag.tag,
|
|
7050
|
+
event,
|
|
7051
|
+
mod
|
|
7052
|
+
});
|
|
7053
|
+
return true;
|
|
7054
|
+
}
|
|
7055
|
+
const link = onLinkClick && getLinkUnitAt(state, pos);
|
|
7056
|
+
if (link && link.unit.from < pos && pos < link.unit.to) {
|
|
7057
|
+
onLinkClick({
|
|
7058
|
+
href: link.href,
|
|
7059
|
+
event,
|
|
7060
|
+
mod
|
|
7061
|
+
});
|
|
7062
|
+
return true;
|
|
7063
|
+
}
|
|
6953
7064
|
}
|
|
6954
7065
|
/**
|
|
6955
|
-
*
|
|
6956
|
-
* the
|
|
7066
|
+
* Binds `Mod-Enter` to follow the wikilink, tag, file pill, or Markdown link
|
|
7067
|
+
* under the caret, and plain `Enter` to follow a selected atom unit (a
|
|
7068
|
+
* wikilink, file pill, or image), firing the same handlers a click does.
|
|
7069
|
+
* "Under the caret" means strictly inside the unit: a caret merely touching
|
|
7070
|
+
* a unit's edge is next to it, not on it.
|
|
7071
|
+
* Off a link, `Mod-Enter` falls through so the list keymap keeps cycling
|
|
7072
|
+
* checkbox tasks; off a selected unit, `Enter` falls through to the regular
|
|
7073
|
+
* split. High priority puts this ahead of every keymap binding.
|
|
6957
7074
|
*
|
|
6958
|
-
*
|
|
6959
|
-
*
|
|
6960
|
-
*
|
|
6961
|
-
*
|
|
6962
|
-
* raises the software keyboard before the handler opens its own surface
|
|
6963
|
-
* (such as a lightbox).
|
|
7075
|
+
* A selected-unit follow reports `mod: true` when the platform's mod key
|
|
7076
|
+
* (`⌘` on Apple, `Ctrl` elsewhere) was held beyond its plain-`Enter` trigger;
|
|
7077
|
+
* a caret follow always reports `mod: false`, its mod key being the trigger
|
|
7078
|
+
* itself.
|
|
6964
7079
|
*/
|
|
6965
|
-
function
|
|
6966
|
-
|
|
6967
|
-
const handleTouchEnd = (view, event) => {
|
|
6968
|
-
const pending = pendingTaps.get(view);
|
|
6969
|
-
pendingTaps.delete(view);
|
|
6970
|
-
if (!pending || event.touches.length > 0) return false;
|
|
6971
|
-
const touch = findTouch(event.changedTouches, pending.identifier);
|
|
6972
|
-
if (!touch || !isWithinTapTolerance(pending, touch)) return false;
|
|
6973
|
-
const preview = getClosestImagePreview(event.target);
|
|
6974
|
-
if (!preview) return false;
|
|
6975
|
-
event.preventDefault();
|
|
6976
|
-
const hit = findImageForPreview(view, preview);
|
|
6977
|
-
if (hit) onClick({
|
|
6978
|
-
src: hit.src,
|
|
6979
|
-
alt: hit.alt,
|
|
6980
|
-
event
|
|
6981
|
-
});
|
|
6982
|
-
return true;
|
|
6983
|
-
};
|
|
6984
|
-
return definePlugin(new Plugin({
|
|
6985
|
-
key: imageClickKey,
|
|
6986
|
-
props: {
|
|
6987
|
-
handleDOMEvents: {
|
|
6988
|
-
pointerdown: (view, event) => {
|
|
6989
|
-
if (getClosestImagePreview(event.target) && event.pointerType !== "mouse") event.preventDefault();
|
|
6990
|
-
return false;
|
|
6991
|
-
},
|
|
6992
|
-
touchstart: (view, event) => {
|
|
6993
|
-
pendingTaps.delete(view);
|
|
6994
|
-
if (event.touches.length !== 1) return false;
|
|
6995
|
-
if (!getClosestImagePreview(event.target)) return false;
|
|
6996
|
-
if (event.target instanceof HTMLElement && event.target.closest(".md-image-resize-handle")) return false;
|
|
6997
|
-
const touch = event.changedTouches[0];
|
|
6998
|
-
if (!touch) return false;
|
|
6999
|
-
pendingTaps.set(view, {
|
|
7000
|
-
identifier: touch.identifier,
|
|
7001
|
-
clientX: touch.clientX,
|
|
7002
|
-
clientY: touch.clientY
|
|
7003
|
-
});
|
|
7004
|
-
return false;
|
|
7005
|
-
},
|
|
7006
|
-
touchmove: (view, event) => {
|
|
7007
|
-
const pending = pendingTaps.get(view);
|
|
7008
|
-
if (!pending) return false;
|
|
7009
|
-
const touch = findTouch(event.changedTouches, pending.identifier);
|
|
7010
|
-
if (touch && !isWithinTapTolerance(pending, touch)) pendingTaps.delete(view);
|
|
7011
|
-
return false;
|
|
7012
|
-
},
|
|
7013
|
-
touchcancel: (view) => {
|
|
7014
|
-
pendingTaps.delete(view);
|
|
7015
|
-
return false;
|
|
7016
|
-
},
|
|
7017
|
-
touchend: handleTouchEnd
|
|
7018
|
-
},
|
|
7019
|
-
handleClick: (view, _pos, event) => {
|
|
7020
|
-
const preview = getClosestImagePreview(event.target);
|
|
7021
|
-
if (!preview) return false;
|
|
7022
|
-
const hit = findImageForPreview(view, preview);
|
|
7023
|
-
if (!hit) return false;
|
|
7024
|
-
onClick({
|
|
7025
|
-
src: hit.src,
|
|
7026
|
-
alt: hit.alt,
|
|
7027
|
-
event
|
|
7028
|
-
});
|
|
7029
|
-
return true;
|
|
7030
|
-
}
|
|
7031
|
-
}
|
|
7032
|
-
}));
|
|
7080
|
+
function defineFollowLinkHandler(handlers) {
|
|
7081
|
+
return withPriority$1(definePlugin(createFollowLinkPlugin(handlers)), Priority$1.high);
|
|
7033
7082
|
}
|
|
7034
7083
|
|
|
7035
7084
|
//#endregion
|
|
@@ -7359,7 +7408,8 @@ function defineLinkClickHandler(onClick) {
|
|
|
7359
7408
|
findPayloadAt: (state, pos) => getLinkUnitAt(state, pos)?.href,
|
|
7360
7409
|
onClick: (href, event) => onClick({
|
|
7361
7410
|
href,
|
|
7362
|
-
event
|
|
7411
|
+
event,
|
|
7412
|
+
mod: isModEvent(event)
|
|
7363
7413
|
})
|
|
7364
7414
|
});
|
|
7365
7415
|
}
|
|
@@ -8087,4 +8137,4 @@ function getVirtualElementFromRange(view, range) {
|
|
|
8087
8137
|
}
|
|
8088
8138
|
|
|
8089
8139
|
//#endregion
|
|
8090
|
-
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, defineSpellCheckPlugin, 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, isNodeOfType, isSelectionInTableCell, listenForTweetHeight, loadKaTeX, markdownToDoc, matchEmbed, parseWikiEmbed, removeLink, renderMathInto, updateLink, wikiEmbedBasename, withPriority };
|
|
8140
|
+
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, defineSpellCheckPlugin, 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 };
|
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.65.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -43,7 +43,7 @@
|
|
|
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.65.0"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@ocavue/tsconfig": "^0.7.1",
|