mirror of https://github.com/fantasticit/think.git
Compare commits
6 Commits
3665aeea36
...
92a632fabf
Author | SHA1 | Date |
---|---|---|
fantasticit | 92a632fabf | |
fantasticit | 49c6bd86c3 | |
fantasticit | 63aff8bbdd | |
fantasticit | fe607bd43b | |
weilin1982 | ace2ab3ba8 | |
YangFong | 5e3f47564a |
|
@ -14,7 +14,7 @@
|
||||||
4. 从 office 套件粘贴到编辑器,保留格式和图片(前端可独立完成,思路可参考 TinyCME 的 PowerPaste 和 RTF)
|
4. 从 office 套件粘贴到编辑器,保留格式和图片(前端可独立完成,思路可参考 TinyCME 的 PowerPaste 和 RTF)
|
||||||
5. 基于 yjs 的版本备份和恢复(部分同学提出增量保存 diff,个人还是建议全量 snapshot)
|
5. 基于 yjs 的版本备份和恢复(部分同学提出增量保存 diff,个人还是建议全量 snapshot)
|
||||||
6. 基于 yjs 的协同开发(比如结合 luckysheet)
|
6. 基于 yjs 的协同开发(比如结合 luckysheet)
|
||||||
3. 如果有好的工作和想法,可以和作者联系(发送邮件)
|
3. 如果希望参与编辑器开发,可以到[这个仓库](https://github.com/fantasticit/sailkit)参与。
|
||||||
|
|
||||||
## 简介
|
## 简介
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||||
|
|
||||||
|
import { useIsomorphicLayoutEffect } from './use-isomorphic-layout-effect';
|
||||||
import { useToggle } from './use-toggle';
|
import { useToggle } from './use-toggle';
|
||||||
import { useIsomorphicLayoutEffect } from './user-isomorphic-layout-effect';
|
|
||||||
|
|
||||||
export const useInterval = (callback: () => void, delay: number) => {
|
export const useInterval = (callback: () => void, delay: number) => {
|
||||||
const savedCallback = useRef(callback);
|
const savedCallback = useRef(callback);
|
||||||
|
|
|
@ -17,8 +17,26 @@ import { safeJSONParse } from 'helpers/json';
|
||||||
import { toggleMark } from 'prosemirror-commands';
|
import { toggleMark } from 'prosemirror-commands';
|
||||||
import { DOMParser as PMDOMParser, Fragment, Node, Schema } from 'prosemirror-model';
|
import { DOMParser as PMDOMParser, Fragment, Node, Schema } from 'prosemirror-model';
|
||||||
import { EditorState, Plugin, PluginKey, TextSelection } from 'prosemirror-state';
|
import { EditorState, Plugin, PluginKey, TextSelection } from 'prosemirror-state';
|
||||||
|
import { uploadFile } from 'services/file';
|
||||||
|
|
||||||
const htmlToProsemirror = (editor: CoreEditor, html, isPasteMarkdown = false) => {
|
const reuploadImageAndUpdateSrc = async (img: HTMLImageElement) => {
|
||||||
|
try {
|
||||||
|
const resp = await fetch(img.src);
|
||||||
|
if (!resp.ok) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const blob = await resp.blob();
|
||||||
|
const url = await uploadFile?.(blob);
|
||||||
|
|
||||||
|
img.src = url;
|
||||||
|
return true;
|
||||||
|
} catch (error) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const htmlToProsemirror = async (editor: CoreEditor, html, isPasteMarkdown = false) => {
|
||||||
const firstNode = editor.view.state.doc.content.firstChild;
|
const firstNode = editor.view.state.doc.content.firstChild;
|
||||||
const shouldInsertTitleText = !!(firstNode?.textContent?.length <= 0 ?? true);
|
const shouldInsertTitleText = !!(firstNode?.textContent?.length <= 0 ?? true);
|
||||||
|
|
||||||
|
@ -27,6 +45,13 @@ const htmlToProsemirror = (editor: CoreEditor, html, isPasteMarkdown = false) =>
|
||||||
const parser = new window.DOMParser();
|
const parser = new window.DOMParser();
|
||||||
const { body } = parser.parseFromString(fixHTML(html), 'text/html');
|
const { body } = parser.parseFromString(fixHTML(html), 'text/html');
|
||||||
|
|
||||||
|
try {
|
||||||
|
const imgs = body.querySelectorAll('img');
|
||||||
|
await Prosemise.all([...imgs].map(reuploadImageAndUpdateSrc)
|
||||||
|
} catch (e) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
const schema = getSchema(
|
const schema = getSchema(
|
||||||
[].concat(
|
[].concat(
|
||||||
Document,
|
Document,
|
||||||
|
|
Loading…
Reference in New Issue