@meowdown/core 0.74.2 → 0.75.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 +12 -3
- package/dist/index.js +74 -25
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -808,14 +808,23 @@ type PostEmbedSnapshot = {
|
|
|
808
808
|
export declare function parsePostEmbedSnapshot(value: unknown): PostEmbedSnapshot | undefined;
|
|
809
809
|
//#endregion
|
|
810
810
|
//#region src/extensions/image.d.ts
|
|
811
|
-
|
|
811
|
+
/**
|
|
812
|
+
* Maps a markdown `src` to a displayable URL, or `undefined` to skip rendering
|
|
813
|
+
* that image. May return a `Promise` when the answer needs data that is not
|
|
814
|
+
* loaded yet: the image appears once it resolves, and a rejection or an
|
|
815
|
+
* `undefined` result leaves the source without a preview.
|
|
816
|
+
*/
|
|
817
|
+
type ImageUrlResolver = (src: string) => string | undefined | Promise<string | undefined>;
|
|
812
818
|
/**
|
|
813
819
|
* Options for {@link defineImage}.
|
|
814
820
|
*/
|
|
815
821
|
interface ImageOptions {
|
|
816
822
|
/**
|
|
817
823
|
* Map a markdown `src` to a displayable URL, or `undefined` to skip rendering
|
|
818
|
-
* that image.
|
|
824
|
+
* that image. May return a `Promise`; while it is pending, an image whose
|
|
825
|
+
* `width` and `height` are both persisted shows a sized placeholder so the
|
|
826
|
+
* resolved image does not shift the layout. Defaults to
|
|
827
|
+
* `defaultResolveImageUrl`.
|
|
819
828
|
*/
|
|
820
829
|
resolveImageUrl?: ImageUrlResolver;
|
|
821
830
|
/**
|
|
@@ -1680,4 +1689,4 @@ export declare function getSelectedText(state: EditorState): string;
|
|
|
1680
1689
|
*/
|
|
1681
1690
|
export declare function getVirtualElementFromRange(view: EditorView, range: PositionRange): VirtualElement;
|
|
1682
1691
|
//#endregion
|
|
1683
|
-
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 XPostMediaClickHandler, type XPostResolver, type YouTubeVideoClickHandler, type YouTubeVideoResolver, defineCodeBlockPreviewPlugin, definePlaceholder, defineSearchStatusHandler, getSearchStatus, isCodeBlockPreviewHiddenDecoration, withPriority };
|
|
1692
|
+
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 ImageUrlResolver, 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 XPostMediaClickHandler, type XPostResolver, type YouTubeVideoClickHandler, type YouTubeVideoResolver, defineCodeBlockPreviewPlugin, definePlaceholder, defineSearchStatusHandler, getSearchStatus, isCodeBlockPreviewHiddenDecoration, withPriority };
|
package/dist/index.js
CHANGED
|
@@ -3992,12 +3992,8 @@ var ImageMarkView = class {
|
|
|
3992
3992
|
this.#contentDOM.className = "md-image-view-content md-atom-view-content";
|
|
3993
3993
|
this.#contentDOM.dataset.testid = "image-source";
|
|
3994
3994
|
for (const [name, value] of Object.entries(NON_PROSE_ATTRS)) this.#contentDOM.setAttribute(name, value);
|
|
3995
|
-
const preview = this.#renderPreview();
|
|
3996
|
-
if (preview) {
|
|
3997
|
-
preview.contentEditable = "false";
|
|
3998
|
-
this.#dom.appendChild(preview);
|
|
3999
|
-
}
|
|
4000
3995
|
this.#dom.appendChild(this.#contentDOM);
|
|
3996
|
+
this.#mountPreview();
|
|
4001
3997
|
}
|
|
4002
3998
|
get dom() {
|
|
4003
3999
|
return this.#dom;
|
|
@@ -4024,22 +4020,67 @@ var ImageMarkView = class {
|
|
|
4024
4020
|
this.#destroyed = true;
|
|
4025
4021
|
}
|
|
4026
4022
|
/**
|
|
4027
|
-
*
|
|
4028
|
-
* resizable `<img
|
|
4023
|
+
* Mount the inline preview for the image `src`, if any: a post-embed card, a
|
|
4024
|
+
* resizable `<img>`, or, while an asynchronous resolver is pending and the
|
|
4025
|
+
* size is persisted, an empty box of that size that the image later fills.
|
|
4029
4026
|
*/
|
|
4030
|
-
#
|
|
4027
|
+
#mountPreview() {
|
|
4031
4028
|
const { src } = this.#attrs;
|
|
4032
|
-
const wrapper = document.createElement("span");
|
|
4033
|
-
wrapper.className = "md-image-view-preview md-atom-view-preview";
|
|
4034
4029
|
const kind = matchEmbed(src);
|
|
4035
4030
|
if (kind) {
|
|
4031
|
+
const wrapper = this.#createWrapper();
|
|
4036
4032
|
wrapper.dataset.testid = `${kind}-embed`;
|
|
4037
4033
|
wrapper.dataset.postEmbed = kind;
|
|
4038
4034
|
wrapper.appendChild(this.#buildPostEmbed(kind, src));
|
|
4039
|
-
|
|
4035
|
+
this.#insertPreview(wrapper);
|
|
4036
|
+
return;
|
|
4037
|
+
}
|
|
4038
|
+
const resolved = (this.#resolveImageUrl ?? defaultResolveImageUrl)(src);
|
|
4039
|
+
if (resolved instanceof Promise) {
|
|
4040
|
+
const placeholder = this.#hasPersistedSize() ? this.#renderImage(null) : void 0;
|
|
4041
|
+
if (placeholder) this.#insertPreview(placeholder);
|
|
4042
|
+
resolved.then((url) => this.#settle(placeholder, url), () => this.#settle(placeholder, void 0));
|
|
4043
|
+
return;
|
|
4044
|
+
}
|
|
4045
|
+
if (resolved) this.#insertPreview(this.#renderImage(resolved));
|
|
4046
|
+
}
|
|
4047
|
+
#hasPersistedSize() {
|
|
4048
|
+
return this.#attrs.width != null && this.#attrs.height != null;
|
|
4049
|
+
}
|
|
4050
|
+
/**
|
|
4051
|
+
* Apply a resolver's asynchronous answer: fill the placeholder with the
|
|
4052
|
+
* image, mount the image from scratch, or drop the placeholder when there is
|
|
4053
|
+
* nothing to show. A view destroyed in the meantime (its `src` changed, or it
|
|
4054
|
+
* left the document) ignores the answer.
|
|
4055
|
+
*/
|
|
4056
|
+
#settle(placeholder, url) {
|
|
4057
|
+
if (this.#destroyed) return;
|
|
4058
|
+
if (!url) {
|
|
4059
|
+
placeholder?.remove();
|
|
4060
|
+
this.#resizableRoot = void 0;
|
|
4061
|
+
return;
|
|
4040
4062
|
}
|
|
4041
|
-
|
|
4042
|
-
|
|
4063
|
+
if (placeholder && this.#resizableRoot) this.#attachImage(this.#resizableRoot, url);
|
|
4064
|
+
else this.#insertPreview(this.#renderImage(url));
|
|
4065
|
+
}
|
|
4066
|
+
#createWrapper() {
|
|
4067
|
+
const wrapper = document.createElement("span");
|
|
4068
|
+
wrapper.className = "md-image-view-preview md-atom-view-preview";
|
|
4069
|
+
return wrapper;
|
|
4070
|
+
}
|
|
4071
|
+
/**
|
|
4072
|
+
* Insert a preview in front of the source text.
|
|
4073
|
+
*/
|
|
4074
|
+
#insertPreview(preview) {
|
|
4075
|
+
preview.contentEditable = "false";
|
|
4076
|
+
this.#dom.insertBefore(preview, this.#contentDOM);
|
|
4077
|
+
}
|
|
4078
|
+
/**
|
|
4079
|
+
* The resizable image preview. `null` builds the sized box without its
|
|
4080
|
+
* `<img>`, for an asynchronous resolver to fill through `#attachImage`.
|
|
4081
|
+
*/
|
|
4082
|
+
#renderImage(url) {
|
|
4083
|
+
const wrapper = this.#createWrapper();
|
|
4043
4084
|
wrapper.dataset.testid = "image-preview";
|
|
4044
4085
|
wrapper.appendChild(this.#buildResizableImage(url));
|
|
4045
4086
|
return wrapper;
|
|
@@ -4122,6 +4163,25 @@ var ImageMarkView = class {
|
|
|
4122
4163
|
root.className = "md-image-resizable";
|
|
4123
4164
|
root.dataset.testid = "image-resizable";
|
|
4124
4165
|
root.setAttribute("data-loading", "");
|
|
4166
|
+
applySize(root, this.#attrs.width, this.#attrs.height);
|
|
4167
|
+
const handle = document.createElement("prosekit-resizable-handle");
|
|
4168
|
+
handle.className = "md-image-resize-handle";
|
|
4169
|
+
handle.setAttribute("position", "bottom-right");
|
|
4170
|
+
handle.addEventListener("click", (event) => event.stopPropagation());
|
|
4171
|
+
root.appendChild(handle);
|
|
4172
|
+
root.addEventListener("resizeEnd", (event) => {
|
|
4173
|
+
const { width: nextWidth, height: nextHeight } = event.detail;
|
|
4174
|
+
commitImageSize(this.#view, this.#contentDOM, nextWidth, nextHeight);
|
|
4175
|
+
});
|
|
4176
|
+
this.#resizableRoot = root;
|
|
4177
|
+
if (url != null) this.#attachImage(root, url);
|
|
4178
|
+
return root;
|
|
4179
|
+
}
|
|
4180
|
+
/**
|
|
4181
|
+
* Put the `<img>` for `url` into a resizable root built by
|
|
4182
|
+
* `#buildResizableImage`, in front of its handle.
|
|
4183
|
+
*/
|
|
4184
|
+
#attachImage(root, url) {
|
|
4125
4185
|
const image = document.createElement("img");
|
|
4126
4186
|
image.src = url;
|
|
4127
4187
|
image.alt = this.#attrs.alt;
|
|
@@ -4137,19 +4197,8 @@ var ImageMarkView = class {
|
|
|
4137
4197
|
image.addEventListener("error", () => {
|
|
4138
4198
|
root.removeAttribute("data-loading");
|
|
4139
4199
|
});
|
|
4140
|
-
root.
|
|
4141
|
-
const handle = document.createElement("prosekit-resizable-handle");
|
|
4142
|
-
handle.className = "md-image-resize-handle";
|
|
4143
|
-
handle.setAttribute("position", "bottom-right");
|
|
4144
|
-
handle.addEventListener("click", (event) => event.stopPropagation());
|
|
4145
|
-
root.appendChild(handle);
|
|
4146
|
-
root.addEventListener("resizeEnd", (event) => {
|
|
4147
|
-
const { width: nextWidth, height: nextHeight } = event.detail;
|
|
4148
|
-
commitImageSize(this.#view, this.#contentDOM, nextWidth, nextHeight);
|
|
4149
|
-
});
|
|
4150
|
-
this.#resizableRoot = root;
|
|
4200
|
+
root.prepend(image);
|
|
4151
4201
|
this.#image = image;
|
|
4152
|
-
return root;
|
|
4153
4202
|
}
|
|
4154
4203
|
};
|
|
4155
4204
|
/**
|