@4399ywkf/editor 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +114 -0
- package/dist/DocView-5KS7B4DA.js +18 -0
- package/dist/DocView-5KS7B4DA.js.map +1 -0
- package/dist/PdfView-JDCHTG7Y.js +3 -0
- package/dist/PdfView-JDCHTG7Y.js.map +1 -0
- package/dist/SheetView-2EID6B2I.js +3 -0
- package/dist/SheetView-2EID6B2I.js.map +1 -0
- package/dist/chunk-G6WM2PSU.js +21838 -0
- package/dist/chunk-G6WM2PSU.js.map +1 -0
- package/dist/chunk-IRALXCLP.js +55 -0
- package/dist/chunk-IRALXCLP.js.map +1 -0
- package/dist/chunk-RJUDOUEZ.js +56 -0
- package/dist/chunk-RJUDOUEZ.js.map +1 -0
- package/dist/doc.d.ts +1108 -0
- package/dist/doc.js +39 -0
- package/dist/doc.js.map +1 -0
- package/dist/docx.d.ts +184 -0
- package/dist/docx.js +1181 -0
- package/dist/docx.js.map +1 -0
- package/dist/index.d.ts +47 -0
- package/dist/index.js +95 -0
- package/dist/index.js.map +1 -0
- package/dist/pdf.d.ts +13 -0
- package/dist/pdf.js +3 -0
- package/dist/pdf.js.map +1 -0
- package/dist/registry-CvGg65s9.d.ts +68 -0
- package/dist/sheet.d.ts +16 -0
- package/dist/sheet.js +3 -0
- package/dist/sheet.js.map +1 -0
- package/dist/style.css +5689 -0
- package/package.json +125 -0
package/dist/doc.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export { ArticleViewer, Audio, Button, CollabContext, CollabProvider, Column, Columns, DEFAULT_MAX_FILE_SIZES, DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EditorConfigProvider, EditorContentArea, FileAttachment, FloatingElement, HIDE_FLOATING_META, LoadingSpinner, MAC_SYMBOLS, MAX_FILE_SIZE, MediaUploadButton, MediaUploadPlaceholder, NotionEditor, NotionEditorContent, EditorProvider as NotionEditorInner, PasteDropMedia, Popover, PopoverContent, PopoverTrigger, SR_ONLY, Separator, Spacer, Toolbar, ToolbarGroup, ToolbarSeparator, UiState, UserContext, UserProvider, Video, clamp, cn, defaultUiState, detectMediaKind, findNodeAtPosition, findNodePosition, findSelectionPosition, focusNextNode, formatShortcutKey, getAvatar, getElementOverflowPosition, getNodeDisplayName, getSelectedBlockNodes, getSelectedNodesOfType, getSelectionBoundingRect, getUrlParam, handleImageUpload, hasContentAbove, isAllowedUri, isExtensionAvailable, isMac, isMarkInSchema, isNodeInSchema, isNodeTypeSelected, isSelectionValid, isTextSelectionValid, isValidPosition, markHideFloatingOnNext, parseShortcutKeys, pickFile, removeEmptyParagraphs, resolveMaxSize, runMediaUpload, sanitizeUrl, selectCurrentBlockContent, selectNodeAndHideFloating, selectionWithinConvertibleTypes, updateNodesAttr, useCollab, useCollaboration, useComposedRef, useCursorVisibility, useEditorConfig, useElementRect, useFloatingElement, useFloatingToolbarVisibility, useIsBreakpoint, useIsomorphicLayoutEffect, useMenuNavigation, useOnClickOutside, useThrottledCallback, useTiptapEditor, useUiEditorState, use_ui_editor_state_default as useUiEditorStateDefault, useUnmount, useUser, useWindowSize } from './chunk-G6WM2PSU.js';
|
|
2
|
+
import { useState, useEffect } from 'react';
|
|
3
|
+
|
|
4
|
+
function useScrolling(target, options = {}) {
|
|
5
|
+
const { debounce = 150, fallbackToDocument = true } = options;
|
|
6
|
+
const [isScrolling, setIsScrolling] = useState(false);
|
|
7
|
+
useEffect(() => {
|
|
8
|
+
const element = target && typeof Window !== "undefined" && target instanceof Window ? target : target?.current ?? window;
|
|
9
|
+
const eventTarget = fallbackToDocument && element === window && typeof document !== "undefined" ? document : element;
|
|
10
|
+
const on = (el, event, handler) => el.addEventListener(event, handler, true);
|
|
11
|
+
const off = (el, event, handler) => el.removeEventListener(event, handler);
|
|
12
|
+
let timeout;
|
|
13
|
+
const supportsScrollEnd = element === window && "onscrollend" in window;
|
|
14
|
+
const handleScroll = () => {
|
|
15
|
+
if (!isScrolling) setIsScrolling(true);
|
|
16
|
+
if (!supportsScrollEnd) {
|
|
17
|
+
clearTimeout(timeout);
|
|
18
|
+
timeout = setTimeout(() => setIsScrolling(false), debounce);
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
const handleScrollEnd = () => setIsScrolling(false);
|
|
22
|
+
on(eventTarget, "scroll", handleScroll);
|
|
23
|
+
if (supportsScrollEnd) {
|
|
24
|
+
on(eventTarget, "scrollend", handleScrollEnd);
|
|
25
|
+
}
|
|
26
|
+
return () => {
|
|
27
|
+
off(eventTarget, "scroll", handleScroll);
|
|
28
|
+
if (supportsScrollEnd) {
|
|
29
|
+
off(eventTarget, "scrollend", handleScrollEnd);
|
|
30
|
+
}
|
|
31
|
+
clearTimeout(timeout);
|
|
32
|
+
};
|
|
33
|
+
}, [target, debounce, fallbackToDocument, isScrolling]);
|
|
34
|
+
return isScrolling;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export { useScrolling };
|
|
38
|
+
//# sourceMappingURL=doc.js.map
|
|
39
|
+
//# sourceMappingURL=doc.js.map
|
package/dist/doc.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/hooks/use-scrolling.ts"],"names":[],"mappings":";;;AAWO,SAAS,YAAA,CACd,MAAA,EACA,OAAA,GAA+B,EAAC,EACvB;AACT,EAAA,MAAM,EAAE,QAAA,GAAW,GAAA,EAAK,kBAAA,GAAqB,MAAK,GAAI,OAAA;AACtD,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAI,SAAS,KAAK,CAAA;AAEpD,EAAA,SAAA,CAAU,MAAM;AAEd,IAAA,MAAM,OAAA,GACJ,UAAU,OAAO,MAAA,KAAW,eAAe,MAAA,YAAkB,MAAA,GACzD,MAAA,GACE,MAAA,EAAmC,OAAA,IAAW,MAAA;AAGtD,IAAA,MAAM,cACJ,kBAAA,IACA,OAAA,KAAY,UACZ,OAAO,QAAA,KAAa,cAChB,QAAA,GACA,OAAA;AAEN,IAAA,MAAM,EAAA,GAAK,CACT,EAAA,EACA,KAAA,EACA,YACG,EAAA,CAAG,gBAAA,CAAiB,KAAA,EAAO,OAAA,EAAS,IAAI,CAAA;AAE7C,IAAA,MAAM,GAAA,GAAM,CACV,EAAA,EACA,KAAA,EACA,YACG,EAAA,CAAG,mBAAA,CAAoB,OAAO,OAAO,CAAA;AAE1C,IAAA,IAAI,OAAA;AACJ,IAAA,MAAM,iBAAA,GAAoB,OAAA,KAAY,MAAA,IAAU,aAAA,IAAiB,MAAA;AAEjE,IAAA,MAAM,eAA8B,MAAM;AACxC,MAAA,IAAI,CAAC,WAAA,EAAa,cAAA,CAAe,IAAI,CAAA;AAErC,MAAA,IAAI,CAAC,iBAAA,EAAmB;AACtB,QAAA,YAAA,CAAa,OAAO,CAAA;AACpB,QAAA,OAAA,GAAU,UAAA,CAAW,MAAM,cAAA,CAAe,KAAK,GAAG,QAAQ,CAAA;AAAA,MAC5D;AAAA,IACF,CAAA;AAEA,IAAA,MAAM,eAAA,GAAiC,MAAM,cAAA,CAAe,KAAK,CAAA;AAEjE,IAAA,EAAA,CAAG,WAAA,EAAa,UAAU,YAAY,CAAA;AACtC,IAAA,IAAI,iBAAA,EAAmB;AACrB,MAAA,EAAA,CAAG,WAAA,EAAa,aAAa,eAAe,CAAA;AAAA,IAC9C;AAEA,IAAA,OAAO,MAAM;AACX,MAAA,GAAA,CAAI,WAAA,EAAa,UAAU,YAAY,CAAA;AACvC,MAAA,IAAI,iBAAA,EAAmB;AACrB,QAAA,GAAA,CAAI,WAAA,EAAa,aAAa,eAAe,CAAA;AAAA,MAC/C;AACA,MAAA,YAAA,CAAa,OAAO,CAAA;AAAA,IACtB,CAAA;AAAA,EACF,GAAG,CAAC,MAAA,EAAQ,QAAA,EAAU,kBAAA,EAAoB,WAAW,CAAC,CAAA;AAEtD,EAAA,OAAO,WAAA;AACT","file":"doc.js","sourcesContent":["import type { RefObject } from \"react\"\nimport { useEffect, useState } from \"react\"\n\ntype ScrollTarget = RefObject<HTMLElement> | Window | null | undefined\ntype EventTargetWithScroll = Window | HTMLElement | Document\n\ninterface UseScrollingOptions {\n debounce?: number\n fallbackToDocument?: boolean\n}\n\nexport function useScrolling(\n target?: ScrollTarget,\n options: UseScrollingOptions = {}\n): boolean {\n const { debounce = 150, fallbackToDocument = true } = options\n const [isScrolling, setIsScrolling] = useState(false)\n\n useEffect(() => {\n // Resolve element or window\n const element: EventTargetWithScroll =\n target && typeof Window !== \"undefined\" && target instanceof Window\n ? target\n : ((target as RefObject<HTMLElement>)?.current ?? window)\n\n // Mobile: fallback to document when using window\n const eventTarget: EventTargetWithScroll =\n fallbackToDocument &&\n element === window &&\n typeof document !== \"undefined\"\n ? document\n : element\n\n const on = (\n el: EventTargetWithScroll,\n event: string,\n handler: EventListener\n ) => el.addEventListener(event, handler, true)\n\n const off = (\n el: EventTargetWithScroll,\n event: string,\n handler: EventListener\n ) => el.removeEventListener(event, handler)\n\n let timeout: ReturnType<typeof setTimeout>\n const supportsScrollEnd = element === window && \"onscrollend\" in window\n\n const handleScroll: EventListener = () => {\n if (!isScrolling) setIsScrolling(true)\n\n if (!supportsScrollEnd) {\n clearTimeout(timeout)\n timeout = setTimeout(() => setIsScrolling(false), debounce)\n }\n }\n\n const handleScrollEnd: EventListener = () => setIsScrolling(false)\n\n on(eventTarget, \"scroll\", handleScroll)\n if (supportsScrollEnd) {\n on(eventTarget, \"scrollend\", handleScrollEnd)\n }\n\n return () => {\n off(eventTarget, \"scroll\", handleScroll)\n if (supportsScrollEnd) {\n off(eventTarget, \"scrollend\", handleScrollEnd)\n }\n clearTimeout(timeout)\n }\n }, [target, debounce, fallbackToDocument, isScrolling])\n\n return isScrolling\n}\n"]}
|
package/dist/docx.d.ts
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { Node, Extension, JSONContent } from '@tiptap/core';
|
|
2
|
+
|
|
3
|
+
declare const DocxField: Node<any, any>;
|
|
4
|
+
|
|
5
|
+
declare const DocxInk: Node<any, any>;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* OOXML → tiptap JSONContent。
|
|
9
|
+
*
|
|
10
|
+
* 同构:解压和 XML 解析都由调用方注入,所以浏览器(fflate + 原生 DOMParser)
|
|
11
|
+
* 和 Node(任意 zip 库 + @xmldom/xmldom)共用这一份实现,不存在两份真相。
|
|
12
|
+
*
|
|
13
|
+
* 覆盖范围刻意窄 —— 只做「通用转换器会丢、而我们在意」的那几类:
|
|
14
|
+
* · 样式定义里的字符格式(大多数 Word 文档的视觉身份住在这里,不在 run 上)
|
|
15
|
+
* · 域(保代码 + 缓存值)
|
|
16
|
+
* · 墨迹(保位图回退 + 矢量引用 + 浮动定位)
|
|
17
|
+
* · 浮动锚定的几何信息
|
|
18
|
+
*
|
|
19
|
+
* 常规内容(段落/标题/列表/表格/图片)本来就有成熟方案,这里做的是最小可用版本。
|
|
20
|
+
*/
|
|
21
|
+
interface DocxEntries {
|
|
22
|
+
/** 读取 docx 包内某个条目;不存在返回 null */
|
|
23
|
+
read(entryPath: string): Uint8Array | null;
|
|
24
|
+
}
|
|
25
|
+
interface ParseDocxOptions {
|
|
26
|
+
/** 浏览器传原生 DOMParser,Node 传 @xmldom/xmldom 的 */
|
|
27
|
+
DOMParser: {
|
|
28
|
+
new (): {
|
|
29
|
+
parseFromString(s: string, t: string): Document;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* 把包内的图片交给宿主落盘/上传,返回可访问的 URL。
|
|
34
|
+
* 不提供则退化成 data: URI(小文档可以,大文档会撑爆)。
|
|
35
|
+
*/
|
|
36
|
+
resolveMedia?: (bytes: Uint8Array, entryPath: string) => string;
|
|
37
|
+
/**
|
|
38
|
+
* 重命名导入产出的节点类型,对齐官方 `prosemirrorNodes`。
|
|
39
|
+
* 例:`{ image: 'customImage' }` —— 宿主 schema 里叫别的名字时用。
|
|
40
|
+
*/
|
|
41
|
+
prosemirrorNodes?: Record<string, string>;
|
|
42
|
+
/** 重命名产出的标记类型,对齐官方 `prosemirrorMarks` */
|
|
43
|
+
prosemirrorMarks?: Record<string, string>;
|
|
44
|
+
/** 抽取文档默认样式为 CSS 字符串,对齐官方 `cssStyles` */
|
|
45
|
+
cssStyles?: boolean;
|
|
46
|
+
}
|
|
47
|
+
interface ParseDocxResult {
|
|
48
|
+
doc: Record<string, unknown>;
|
|
49
|
+
/** 各类恢复项的计数,用于量化「补这一层救回了多少」 */
|
|
50
|
+
recovered: Record<string, number>;
|
|
51
|
+
warnings: string[];
|
|
52
|
+
/** `cssStyles: true` 时给出的文档默认样式 */
|
|
53
|
+
css?: string;
|
|
54
|
+
}
|
|
55
|
+
declare function parseDocx(entries: DocxEntries, opts: ParseDocxOptions): ParseDocxResult;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* tiptap JSONContent → .docx(OOXML)。
|
|
59
|
+
*
|
|
60
|
+
* 和 parse.ts 对称:同构、纯函数、不碰 DOM。zip 由调用方注入,
|
|
61
|
+
* 所以浏览器(fflate)和 Node(任意 zip 库)共用同一份。
|
|
62
|
+
*
|
|
63
|
+
* 往返是这里的主要价值:`docxField` 写回真正的 `w:fldSimple`(域代码 + 缓存值),
|
|
64
|
+
* `docxInk` 写回 `w14:contentPart` + 位图回退 —— 这两样在导入时被保住,
|
|
65
|
+
* 导出时才有东西可写。
|
|
66
|
+
*/
|
|
67
|
+
interface SerializeOptions {
|
|
68
|
+
/** 把图片 src 换成字节。返回 null 则该图片跳过并记警告 */
|
|
69
|
+
resolveImage?: (src: string) => Uint8Array | null;
|
|
70
|
+
/** 文档级样式覆盖,对齐官方 styleOverrides */
|
|
71
|
+
styleOverrides?: {
|
|
72
|
+
defaultFont?: string;
|
|
73
|
+
defaultSizePt?: number;
|
|
74
|
+
};
|
|
75
|
+
/** 逐段落覆盖,对齐官方 paragraphOverrides */
|
|
76
|
+
paragraphOverrides?: (node: Node_) => Record<string, string> | undefined;
|
|
77
|
+
}
|
|
78
|
+
interface SerializeResult {
|
|
79
|
+
/** docx 包内的所有条目,交给 zip 打包 */
|
|
80
|
+
files: Record<string, Uint8Array>;
|
|
81
|
+
warnings: string[];
|
|
82
|
+
stats: Record<string, number>;
|
|
83
|
+
}
|
|
84
|
+
type Node_ = Record<string, any>;
|
|
85
|
+
declare function serializeDocx(doc: Node_, opts?: SerializeOptions): SerializeResult;
|
|
86
|
+
|
|
87
|
+
type ExportType = 'blob' | 'buffer' | 'string';
|
|
88
|
+
interface ExportDocxOptions extends SerializeOptions {
|
|
89
|
+
onCompleteExport: ((result: Blob | Uint8Array | string) => void) | null;
|
|
90
|
+
exportType: ExportType;
|
|
91
|
+
/** 诊断级别,同导入侧 */
|
|
92
|
+
verbose: number;
|
|
93
|
+
}
|
|
94
|
+
declare module '@tiptap/core' {
|
|
95
|
+
interface Commands<ReturnType> {
|
|
96
|
+
exportDocx: {
|
|
97
|
+
exportDocx: (options?: Partial<ExportDocxOptions>) => ReturnType;
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/** 纯函数:tiptap JSON → .docx 字节。不依赖 editor,服务端 / 测试可直接用。 */
|
|
102
|
+
declare function docxFromJSON(doc: Record<string, unknown>, opts?: SerializeOptions): {
|
|
103
|
+
bytes: Uint8Array;
|
|
104
|
+
warnings: string[];
|
|
105
|
+
stats: Record<string, number>;
|
|
106
|
+
};
|
|
107
|
+
declare const ExportDocx: Extension<ExportDocxOptions, any>;
|
|
108
|
+
/** 便捷方法:导出并触发浏览器下载 */
|
|
109
|
+
declare function downloadDocx(editor: {
|
|
110
|
+
getJSON: () => unknown;
|
|
111
|
+
}, filename?: string, opts?: SerializeOptions): void;
|
|
112
|
+
|
|
113
|
+
interface ImageUploadConfig {
|
|
114
|
+
/** 上传端点 */
|
|
115
|
+
url: string;
|
|
116
|
+
headers?: HeadersInit;
|
|
117
|
+
method?: string;
|
|
118
|
+
queryParams?: Record<string, string>;
|
|
119
|
+
/**
|
|
120
|
+
* 从上传响应里取出可访问 URL。默认依次尝试 `url` / `data.url` / `src`,
|
|
121
|
+
* 响应是纯文本时直接当 URL 用。
|
|
122
|
+
*/
|
|
123
|
+
extractUrl?: (response: unknown) => string;
|
|
124
|
+
}
|
|
125
|
+
interface ImportDocxOptions {
|
|
126
|
+
/** 图片上传配置,对齐官方 `imageUploadConfig` */
|
|
127
|
+
imageUploadConfig: ImageUploadConfig | null;
|
|
128
|
+
/**
|
|
129
|
+
* 函数式逃生舱:直接把字节换成 URL(同步)。
|
|
130
|
+
* 和 imageUploadConfig 二选一,两者都给时以本项优先。
|
|
131
|
+
*/
|
|
132
|
+
resolveMedia: ((bytes: Uint8Array, entryPath: string) => string) | null;
|
|
133
|
+
/** 重命名产出的节点类型,对齐官方 `prosemirrorNodes` */
|
|
134
|
+
prosemirrorNodes: Record<string, string> | null;
|
|
135
|
+
/** 重命名产出的标记类型,对齐官方 `prosemirrorMarks` */
|
|
136
|
+
prosemirrorMarks: Record<string, string> | null;
|
|
137
|
+
/** 抽取文档默认样式为 CSS,对齐官方 `cssStyles` */
|
|
138
|
+
cssStyles: boolean;
|
|
139
|
+
/** 诊断输出级别,对齐官方 `verbose`。0=静默 1=汇总 2=逐条警告 */
|
|
140
|
+
verbose: number;
|
|
141
|
+
/**
|
|
142
|
+
* 保留 ProseMirror schema 本来表达不了的 OOXML 结构(域 / 墨迹 / 浮动定位)。
|
|
143
|
+
* 这是本扩展相对官方的增量 —— 官方能力矩阵里这几项是 ✕。
|
|
144
|
+
* 关掉则域降级成纯文本、墨迹降级成普通图片。
|
|
145
|
+
*/
|
|
146
|
+
preserveUnsupported: boolean;
|
|
147
|
+
/** 是否注入浮动定位所需样式,默认 true */
|
|
148
|
+
injectStyles: boolean;
|
|
149
|
+
}
|
|
150
|
+
/** onImport 回调拿到的上下文,字段对齐官方 */
|
|
151
|
+
interface ImportDocxContext {
|
|
152
|
+
error?: Error;
|
|
153
|
+
/** 转换出来的 tiptap JSON */
|
|
154
|
+
content: JSONContent | null;
|
|
155
|
+
/** 把内容写进编辑器 */
|
|
156
|
+
setEditorContent: (content?: JSONContent) => void;
|
|
157
|
+
/** 各类恢复项计数(本扩展独有,用于量化保真度) */
|
|
158
|
+
recovered: Record<string, number>;
|
|
159
|
+
warnings: string[];
|
|
160
|
+
/** cssStyles:true 时的文档默认样式 */
|
|
161
|
+
css?: string;
|
|
162
|
+
header: JSONContent | null;
|
|
163
|
+
footer: JSONContent | null;
|
|
164
|
+
footnotes: Record<string, JSONContent>;
|
|
165
|
+
endnotes: Record<string, JSONContent>;
|
|
166
|
+
}
|
|
167
|
+
interface ImportDocxCommandArgs {
|
|
168
|
+
/** .docx 内容。File / Blob / ArrayBuffer / Uint8Array 都收 */
|
|
169
|
+
file: File | Blob | ArrayBuffer | Uint8Array;
|
|
170
|
+
/** 不传则直接替换编辑器内容;传了则由你决定怎么落 */
|
|
171
|
+
onImport?: (context: ImportDocxContext) => void;
|
|
172
|
+
/** 对齐官方:false 时不插入占位内容。本地解析是同步的,占位意义不大 */
|
|
173
|
+
placeholders?: boolean;
|
|
174
|
+
}
|
|
175
|
+
declare module '@tiptap/core' {
|
|
176
|
+
interface Commands<ReturnType> {
|
|
177
|
+
importDocx: {
|
|
178
|
+
importDocx: (args: ImportDocxCommandArgs) => ReturnType;
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
declare const ImportDocx: Extension<ImportDocxOptions, any>;
|
|
183
|
+
|
|
184
|
+
export { type DocxEntries, DocxField, DocxInk, ExportDocx, type ExportDocxOptions, type ExportType, type ImageUploadConfig, ImportDocx, type ImportDocxCommandArgs, type ImportDocxContext, type ImportDocxOptions, type ParseDocxOptions, type ParseDocxResult, type SerializeOptions, type SerializeResult, docxFromJSON, downloadDocx, parseDocx, serializeDocx };
|