2022-05-26 15:18:53 +08:00
|
|
|
|
import {Constants} from "../constants";
|
|
|
|
|
|
import {Hint} from "./hint";
|
2023-06-07 10:36:20 +08:00
|
|
|
|
import {setLute} from "./render/setLute";
|
2022-05-26 15:18:53 +08:00
|
|
|
|
import {Preview} from "./preview";
|
2023-09-13 12:07:17 +08:00
|
|
|
|
import {addLoading, initUI, removeLoading} from "./ui/initUI";
|
2022-05-26 15:18:53 +08:00
|
|
|
|
import {Undo} from "./undo";
|
|
|
|
|
|
import {Upload} from "./upload";
|
|
|
|
|
|
import {Options} from "./util/Options";
|
|
|
|
|
|
import {destroy} from "./util/destroy";
|
|
|
|
|
|
import {Scroll} from "./scroll";
|
|
|
|
|
|
import {Model} from "../layout/Model";
|
|
|
|
|
|
import {genUUID} from "../util/genID";
|
|
|
|
|
|
import {WYSIWYG} from "./wysiwyg";
|
|
|
|
|
|
import {Toolbar} from "./toolbar";
|
|
|
|
|
|
import {Gutter} from "./gutter";
|
|
|
|
|
|
import {Breadcrumb} from "./breadcrumb";
|
2023-11-28 17:19:22 +08:00
|
|
|
|
import {
|
|
|
|
|
|
onTransaction,
|
|
|
|
|
|
transaction,
|
|
|
|
|
|
turnsIntoOneTransaction, turnsIntoTransaction,
|
|
|
|
|
|
updateBatchTransaction,
|
|
|
|
|
|
updateTransaction
|
|
|
|
|
|
} from "./wysiwyg/transaction";
|
2022-05-26 15:18:53 +08:00
|
|
|
|
import {fetchPost} from "../util/fetch";
|
2022-06-30 15:56:44 +08:00
|
|
|
|
/// #if !MOBILE
|
2022-06-30 18:15:13 +08:00
|
|
|
|
import {updatePanelByEditor} from "../editor/util";
|
|
|
|
|
|
import {setPanelFocus} from "../layout/util";
|
2022-06-30 15:56:44 +08:00
|
|
|
|
/// #endif
|
2024-05-29 10:53:35 +08:00
|
|
|
|
import {Title} from "./header/Title";
|
2022-05-26 15:18:53 +08:00
|
|
|
|
import {Background} from "./header/Background";
|
2023-11-28 21:17:19 +08:00
|
|
|
|
import {onGet, setReadonlyByConfig} from "./util/onGet";
|
2022-08-31 12:57:38 +08:00
|
|
|
|
import {reloadProtyle} from "./util/reload";
|
2022-09-29 22:26:55 +08:00
|
|
|
|
import {renderBacklink} from "./wysiwyg/renderBacklink";
|
2023-04-02 12:16:33 +08:00
|
|
|
|
import {setEmpty} from "../mobile/util/setEmpty";
|
2023-04-28 10:30:27 +08:00
|
|
|
|
import {resize} from "./util/resize";
|
2023-05-13 23:04:00 +08:00
|
|
|
|
import {getDocByScroll} from "./scroll/saveScroll";
|
2023-05-18 19:27:21 +08:00
|
|
|
|
import {App} from "../index";
|
2023-06-22 23:19:26 +08:00
|
|
|
|
import {insertHTML} from "./util/insertHTML";
|
2023-07-07 15:55:36 +08:00
|
|
|
|
import {avRender} from "./render/av/render";
|
2023-11-28 17:19:22 +08:00
|
|
|
|
import {focusBlock, getEditorRange} from "./util/selection";
|
|
|
|
|
|
import {hasClosestBlock} from "./util/hasClosest";
|
2023-12-09 12:09:46 +08:00
|
|
|
|
import {setStorageVal} from "./util/compatibility";
|
2024-01-06 20:41:02 +08:00
|
|
|
|
import {merge} from "./util/merge";
|
2022-05-26 15:18:53 +08:00
|
|
|
|
|
2022-10-02 20:56:48 +08:00
|
|
|
|
export class Protyle {
|
2022-05-26 15:18:53 +08:00
|
|
|
|
|
|
|
|
|
|
public readonly version: string;
|
|
|
|
|
|
public protyle: IProtyle;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @param id 要挂载 Protyle 的元素或者元素 ID。
|
|
|
|
|
|
* @param options Protyle 参数
|
|
|
|
|
|
*/
|
2023-05-18 19:27:21 +08:00
|
|
|
|
constructor(app: App, id: HTMLElement, options?: IOptions) {
|
2022-05-26 15:18:53 +08:00
|
|
|
|
this.version = Constants.SIYUAN_VERSION;
|
2024-01-06 20:41:02 +08:00
|
|
|
|
let pluginsOptions: IOptions = options;
|
|
|
|
|
|
app.plugins.forEach(item => {
|
|
|
|
|
|
if (item.protyleOptions) {
|
|
|
|
|
|
pluginsOptions = merge(pluginsOptions, item.protyleOptions);
|
|
|
|
|
|
}
|
2024-01-08 23:23:59 +08:00
|
|
|
|
});
|
2024-01-06 20:41:02 +08:00
|
|
|
|
const getOptions = new Options(pluginsOptions);
|
2022-05-26 15:18:53 +08:00
|
|
|
|
const mergedOptions = getOptions.merge();
|
|
|
|
|
|
this.protyle = {
|
2023-06-23 16:27:54 +08:00
|
|
|
|
getInstance: () => this,
|
2023-06-01 20:50:49 +08:00
|
|
|
|
app,
|
2022-05-26 15:18:53 +08:00
|
|
|
|
transactionTime: new Date().getTime(),
|
|
|
|
|
|
id: genUUID(),
|
|
|
|
|
|
disabled: false,
|
|
|
|
|
|
updated: false,
|
|
|
|
|
|
element: id,
|
|
|
|
|
|
options: mergedOptions,
|
|
|
|
|
|
block: {},
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2023-06-01 20:50:49 +08:00
|
|
|
|
this.protyle.hint = new Hint(this.protyle);
|
2022-08-31 01:14:45 +08:00
|
|
|
|
if (mergedOptions.render.breadcrumb) {
|
2023-06-01 20:50:49 +08:00
|
|
|
|
this.protyle.breadcrumb = new Breadcrumb(this.protyle);
|
2022-08-31 01:14:45 +08:00
|
|
|
|
}
|
2022-05-26 15:18:53 +08:00
|
|
|
|
if (mergedOptions.render.title) {
|
2023-06-01 20:50:49 +08:00
|
|
|
|
this.protyle.title = new Title(this.protyle);
|
2022-05-26 15:18:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
if (mergedOptions.render.background) {
|
2023-06-01 20:50:49 +08:00
|
|
|
|
this.protyle.background = new Background(this.protyle);
|
2022-05-26 15:18:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
this.protyle.element.innerHTML = "";
|
|
|
|
|
|
this.protyle.element.classList.add("protyle");
|
2022-08-31 01:14:45 +08:00
|
|
|
|
if (mergedOptions.render.breadcrumb) {
|
|
|
|
|
|
this.protyle.element.appendChild(this.protyle.breadcrumb.element.parentElement);
|
|
|
|
|
|
}
|
2022-05-26 15:18:53 +08:00
|
|
|
|
this.protyle.undo = new Undo();
|
2023-06-01 20:50:49 +08:00
|
|
|
|
this.protyle.wysiwyg = new WYSIWYG(this.protyle);
|
|
|
|
|
|
this.protyle.toolbar = new Toolbar(this.protyle);
|
|
|
|
|
|
this.protyle.scroll = new Scroll(this.protyle); // 不能使用 render.scroll 来判读是否初始化,除非重构后面用到的相关变量
|
2022-05-26 15:18:53 +08:00
|
|
|
|
if (this.protyle.options.render.gutter) {
|
2023-06-01 20:50:49 +08:00
|
|
|
|
this.protyle.gutter = new Gutter(this.protyle);
|
2022-05-26 15:18:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
if (mergedOptions.upload.url || mergedOptions.upload.handler) {
|
|
|
|
|
|
this.protyle.upload = new Upload();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
this.init();
|
2022-09-29 23:08:37 +08:00
|
|
|
|
if (!mergedOptions.action.includes(Constants.CB_GET_HISTORY)) {
|
2022-08-31 01:14:45 +08:00
|
|
|
|
this.protyle.ws = new Model({
|
2023-05-18 19:27:21 +08:00
|
|
|
|
app,
|
2022-08-31 01:14:45 +08:00
|
|
|
|
id: this.protyle.id,
|
|
|
|
|
|
type: "protyle",
|
|
|
|
|
|
msgCallback: (data) => {
|
|
|
|
|
|
switch (data.cmd) {
|
2023-05-14 10:34:48 +08:00
|
|
|
|
case "reload":
|
|
|
|
|
|
if (data.data === this.protyle.block.rootID) {
|
2023-06-01 20:50:49 +08:00
|
|
|
|
reloadProtyle(this.protyle, false);
|
2023-05-14 10:34:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
break;
|
2023-07-07 15:55:36 +08:00
|
|
|
|
case "refreshAttributeView":
|
|
|
|
|
|
Array.from(this.protyle.wysiwyg.element.querySelectorAll(`[data-av-id="${data.data.id}"]`)).forEach((item: HTMLElement) => {
|
|
|
|
|
|
item.removeAttribute("data-render");
|
2023-09-09 23:21:46 +08:00
|
|
|
|
avRender(item, this.protyle);
|
2023-07-07 15:55:36 +08:00
|
|
|
|
});
|
|
|
|
|
|
break;
|
2023-05-14 12:10:47 +08:00
|
|
|
|
case "addLoading":
|
2023-05-14 10:34:48 +08:00
|
|
|
|
if (data.data === this.protyle.block.rootID) {
|
2023-05-14 12:09:52 +08:00
|
|
|
|
addLoading(this.protyle, data.msg);
|
2023-05-14 10:34:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
break;
|
2022-08-31 01:14:45 +08:00
|
|
|
|
case "transactions":
|
|
|
|
|
|
data.data[0].doOperations.forEach((item: IOperation) => {
|
2023-10-11 23:50:28 +08:00
|
|
|
|
if (!this.protyle.preview.element.classList.contains("fn__none") &&
|
|
|
|
|
|
item.action !== "updateAttrs" // 预览模式下点击只读
|
|
|
|
|
|
) {
|
2023-09-21 16:57:34 +08:00
|
|
|
|
this.protyle.preview.render(this.protyle);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
onTransaction(this.protyle, item, false);
|
|
|
|
|
|
}
|
2022-05-26 15:18:53 +08:00
|
|
|
|
});
|
2022-08-31 01:14:45 +08:00
|
|
|
|
break;
|
2023-02-27 11:37:54 +08:00
|
|
|
|
case "readonly":
|
2023-11-25 17:08:22 +08:00
|
|
|
|
window.siyuan.config.editor.readOnly = data.data;
|
2024-01-14 22:06:03 +08:00
|
|
|
|
setReadonlyByConfig(this.protyle, true);
|
2023-02-27 11:37:54 +08:00
|
|
|
|
break;
|
2022-08-31 01:14:45 +08:00
|
|
|
|
case "heading2doc":
|
|
|
|
|
|
case "li2doc":
|
|
|
|
|
|
if (this.protyle.block.rootID === data.data.srcRootBlockID) {
|
2022-10-02 20:56:48 +08:00
|
|
|
|
if (this.protyle.block.showAll && data.cmd === "heading2doc" && !this.protyle.options.backlinkData) {
|
2022-08-31 12:57:38 +08:00
|
|
|
|
fetchPost("/api/filetree/getDoc", {
|
|
|
|
|
|
id: this.protyle.block.rootID,
|
2022-10-30 23:13:41 +08:00
|
|
|
|
size: window.siyuan.config.editor.dynamicLoadBlocks,
|
2022-08-31 12:57:38 +08:00
|
|
|
|
}, getResponse => {
|
2023-06-01 20:50:49 +08:00
|
|
|
|
onGet({data: getResponse, protyle: this.protyle});
|
2022-08-31 13:19:03 +08:00
|
|
|
|
});
|
2022-08-31 12:57:38 +08:00
|
|
|
|
} else {
|
2023-06-01 20:50:49 +08:00
|
|
|
|
reloadProtyle(this.protyle, false);
|
2022-08-31 12:57:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
/// #if !MOBILE
|
|
|
|
|
|
if (data.cmd === "heading2doc") {
|
|
|
|
|
|
// 文档标题互转后,需更新大纲
|
2023-05-10 20:18:40 +08:00
|
|
|
|
updatePanelByEditor({
|
|
|
|
|
|
protyle: this.protyle,
|
|
|
|
|
|
focus: false,
|
|
|
|
|
|
pushBackStack: false,
|
|
|
|
|
|
reload: true,
|
|
|
|
|
|
resize: false
|
|
|
|
|
|
});
|
2022-08-31 12:57:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
/// #endif
|
2022-06-27 22:20:39 +08:00
|
|
|
|
}
|
2022-08-31 01:14:45 +08:00
|
|
|
|
break;
|
|
|
|
|
|
case "rename":
|
|
|
|
|
|
if (this.protyle.path === data.data.path) {
|
|
|
|
|
|
if (this.protyle.model) {
|
|
|
|
|
|
this.protyle.model.parent.updateTitle(data.data.title);
|
|
|
|
|
|
}
|
|
|
|
|
|
if (this.protyle.background) {
|
|
|
|
|
|
this.protyle.background.ial.title = data.data.title;
|
|
|
|
|
|
}
|
2022-06-27 22:20:39 +08:00
|
|
|
|
}
|
2022-11-16 11:19:17 +08:00
|
|
|
|
if (this.protyle.options.render.title && this.protyle.block.parentID === data.data.id) {
|
2024-05-29 10:53:35 +08:00
|
|
|
|
if (!document.body.classList.contains("body--blur") && getSelection().rangeCount > 0 &&
|
|
|
|
|
|
this.protyle.title.editElement?.contains(getSelection().getRangeAt(0).startContainer)) {
|
2022-11-16 11:19:17 +08:00
|
|
|
|
// 标题编辑中的不用更新 https://github.com/siyuan-note/siyuan/issues/6565
|
|
|
|
|
|
} else {
|
|
|
|
|
|
this.protyle.title.setTitle(data.data.title);
|
|
|
|
|
|
}
|
2022-06-16 21:05:54 +08:00
|
|
|
|
}
|
2022-08-31 01:14:45 +08:00
|
|
|
|
// update ref
|
2022-09-26 20:56:22 +08:00
|
|
|
|
this.protyle.wysiwyg.element.querySelectorAll(`[data-type~="block-ref"][data-id="${data.data.id}"]`).forEach(item => {
|
2022-08-31 01:14:45 +08:00
|
|
|
|
if (item.getAttribute("data-subtype") === "d") {
|
2024-02-27 22:05:46 +08:00
|
|
|
|
// 同 updateRef 一样处理 https://github.com/siyuan-note/siyuan/issues/10458
|
|
|
|
|
|
item.innerHTML = data.data.refText;
|
2022-08-31 01:14:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
break;
|
|
|
|
|
|
case "moveDoc":
|
2022-11-04 16:28:53 +08:00
|
|
|
|
if (this.protyle.path === data.data.fromPath) {
|
2022-08-31 01:14:45 +08:00
|
|
|
|
this.protyle.path = data.data.newPath;
|
|
|
|
|
|
this.protyle.notebookId = data.data.toNotebook;
|
2022-05-26 15:18:53 +08:00
|
|
|
|
}
|
2022-08-31 01:14:45 +08:00
|
|
|
|
break;
|
|
|
|
|
|
case "unmount":
|
2023-04-02 12:16:33 +08:00
|
|
|
|
if (this.protyle.notebookId === data.data.box) {
|
|
|
|
|
|
/// #if MOBILE
|
2023-05-18 19:27:21 +08:00
|
|
|
|
setEmpty(app);
|
2023-04-02 12:16:33 +08:00
|
|
|
|
/// #else
|
|
|
|
|
|
if (this.protyle.model) {
|
2023-12-09 12:09:46 +08:00
|
|
|
|
this.protyle.model.parent.parent.removeTab(this.protyle.model.parent.id, false);
|
2023-04-02 12:16:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
/// #endif
|
2022-08-31 01:14:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
break;
|
2022-11-03 22:47:19 +08:00
|
|
|
|
case "removeDoc":
|
2023-04-02 12:16:33 +08:00
|
|
|
|
if (data.data.ids.includes(this.protyle.block.rootID)) {
|
|
|
|
|
|
/// #if MOBILE
|
2023-05-18 19:27:21 +08:00
|
|
|
|
setEmpty(app);
|
2023-04-02 12:16:33 +08:00
|
|
|
|
/// #else
|
|
|
|
|
|
if (this.protyle.model) {
|
2023-12-09 12:09:46 +08:00
|
|
|
|
this.protyle.model.parent.parent.removeTab(this.protyle.model.parent.id, false);
|
2023-04-02 12:16:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
/// #endif
|
2023-12-09 12:09:46 +08:00
|
|
|
|
delete window.siyuan.storage[Constants.LOCAL_FILEPOSITION][this.protyle.block.rootID];
|
|
|
|
|
|
setStorageVal(Constants.LOCAL_FILEPOSITION, window.siyuan.storage[Constants.LOCAL_FILEPOSITION]);
|
2022-08-31 01:14:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2022-05-26 15:18:53 +08:00
|
|
|
|
}
|
2022-08-31 01:14:45 +08:00
|
|
|
|
});
|
2022-09-29 22:26:55 +08:00
|
|
|
|
if (options.backlinkData) {
|
2022-10-09 09:31:11 +08:00
|
|
|
|
this.protyle.block.rootID = options.blockId;
|
2022-09-30 00:13:07 +08:00
|
|
|
|
renderBacklink(this.protyle, options.backlinkData);
|
2024-05-29 22:38:31 +08:00
|
|
|
|
// 为了满足 eventPath0.style.paddingLeft 从而显示块标 https://github.com/siyuan-note/siyuan/issues/11578
|
|
|
|
|
|
this.protyle.wysiwyg.element.style.paddingLeft = "16px";
|
2022-09-30 00:13:07 +08:00
|
|
|
|
return;
|
2022-09-29 22:26:55 +08:00
|
|
|
|
}
|
2022-11-27 00:01:12 +08:00
|
|
|
|
if (!options.blockId) {
|
|
|
|
|
|
// 搜索页签需提前初始化
|
|
|
|
|
|
removeLoading(this.protyle);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2023-12-09 22:58:33 +08:00
|
|
|
|
|
2023-12-09 17:52:10 +08:00
|
|
|
|
if (this.protyle.options.mode !== "preview" &&
|
2023-12-09 22:58:33 +08:00
|
|
|
|
options.rootId && window.siyuan.storage[Constants.LOCAL_FILEPOSITION][options.rootId] &&
|
|
|
|
|
|
(
|
|
|
|
|
|
mergedOptions.action.includes(Constants.CB_GET_SCROLL) ||
|
|
|
|
|
|
(mergedOptions.action.includes(Constants.CB_GET_ROOTSCROLL) && options.rootId === options.blockId)
|
|
|
|
|
|
)
|
|
|
|
|
|
) {
|
2023-09-17 22:26:30 +08:00
|
|
|
|
getDocByScroll({
|
|
|
|
|
|
protyle: this.protyle,
|
2023-12-09 22:58:33 +08:00
|
|
|
|
scrollAttr: window.siyuan.storage[Constants.LOCAL_FILEPOSITION][options.rootId],
|
2023-09-17 22:26:30 +08:00
|
|
|
|
mergedOptions,
|
|
|
|
|
|
cb: () => {
|
|
|
|
|
|
this.afterOnGet(mergedOptions);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
2023-05-13 22:16:22 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
this.getDoc(mergedOptions);
|
|
|
|
|
|
}
|
2023-09-30 20:46:00 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
this.protyle.contentElement.classList.add("protyle-content--transition");
|
2023-05-13 22:16:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2022-05-26 15:18:53 +08:00
|
|
|
|
|
2023-05-13 22:16:22 +08:00
|
|
|
|
private getDoc(mergedOptions: IOptions) {
|
|
|
|
|
|
fetchPost("/api/filetree/getDoc", {
|
|
|
|
|
|
id: mergedOptions.blockId,
|
|
|
|
|
|
isBacklink: mergedOptions.action.includes(Constants.CB_GET_BACKLINK),
|
|
|
|
|
|
// 0: 仅当前 ID(默认值),1:向上 2:向下,3:上下都加载,4:加载最后
|
|
|
|
|
|
mode: (mergedOptions.action && mergedOptions.action.includes(Constants.CB_GET_CONTEXT)) ? 3 : 0,
|
|
|
|
|
|
size: mergedOptions.action?.includes(Constants.CB_GET_ALL) ? Constants.SIZE_GET_MAX : window.siyuan.config.editor.dynamicLoadBlocks,
|
|
|
|
|
|
}, getResponse => {
|
2023-07-18 23:46:08 +08:00
|
|
|
|
onGet({
|
|
|
|
|
|
data: getResponse,
|
|
|
|
|
|
protyle: this.protyle,
|
|
|
|
|
|
action: mergedOptions.action,
|
|
|
|
|
|
afterCB: () => {
|
|
|
|
|
|
this.afterOnGet(mergedOptions);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
2023-05-13 22:16:22 +08:00
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private afterOnGet(mergedOptions: IOptions) {
|
|
|
|
|
|
if (this.protyle.model) {
|
|
|
|
|
|
/// #if !MOBILE
|
2024-08-09 22:14:32 +08:00
|
|
|
|
if (mergedOptions.action?.includes(Constants.CB_GET_FOCUS) || mergedOptions.action?.includes(Constants.CB_GET_OPENNEW)) {
|
2023-05-13 22:16:22 +08:00
|
|
|
|
setPanelFocus(this.protyle.model.element.parentElement.parentElement);
|
|
|
|
|
|
}
|
|
|
|
|
|
updatePanelByEditor({
|
|
|
|
|
|
protyle: this.protyle,
|
|
|
|
|
|
focus: false,
|
|
|
|
|
|
pushBackStack: false,
|
|
|
|
|
|
reload: false,
|
|
|
|
|
|
resize: false
|
2022-05-26 15:18:53 +08:00
|
|
|
|
});
|
2023-05-13 22:16:22 +08:00
|
|
|
|
/// #endif
|
|
|
|
|
|
}
|
2023-09-13 12:10:58 +08:00
|
|
|
|
resize(this.protyle); // 需等待 fullwidth 获取后设定完毕再重新计算 padding 和元素
|
2023-05-13 22:16:22 +08:00
|
|
|
|
// 需等待 getDoc 完成后再执行,否则在无页签的时候 updatePanelByEditor 会执行2次
|
|
|
|
|
|
// 只能用 focusin,否则点击表格无法执行
|
|
|
|
|
|
this.protyle.wysiwyg.element.addEventListener("focusin", () => {
|
|
|
|
|
|
/// #if !MOBILE
|
|
|
|
|
|
if (this.protyle && this.protyle.model) {
|
|
|
|
|
|
let needUpdate = true;
|
|
|
|
|
|
if (this.protyle.model.element.parentElement.parentElement.classList.contains("layout__wnd--active") && this.protyle.model.headElement.classList.contains("item--focus")) {
|
|
|
|
|
|
needUpdate = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!needUpdate) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
setPanelFocus(this.protyle.model.element.parentElement.parentElement);
|
|
|
|
|
|
updatePanelByEditor({
|
|
|
|
|
|
protyle: this.protyle,
|
|
|
|
|
|
focus: false,
|
|
|
|
|
|
pushBackStack: false,
|
|
|
|
|
|
reload: false,
|
|
|
|
|
|
resize: false,
|
|
|
|
|
|
});
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 悬浮层应移除其余面板高亮,否则按键会被面板监听到
|
|
|
|
|
|
document.querySelectorAll(".layout__tab--active").forEach(item => {
|
|
|
|
|
|
item.classList.remove("layout__tab--active");
|
|
|
|
|
|
});
|
|
|
|
|
|
document.querySelectorAll(".layout__wnd--active").forEach(item => {
|
|
|
|
|
|
item.classList.remove("layout__wnd--active");
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
/// #endif
|
|
|
|
|
|
});
|
|
|
|
|
|
// 需等渲染完后再回调,用于定位搜索字段 https://github.com/siyuan-note/siyuan/issues/3171
|
|
|
|
|
|
if (mergedOptions.after) {
|
|
|
|
|
|
mergedOptions.after(this);
|
2022-08-31 01:14:45 +08:00
|
|
|
|
}
|
2023-09-30 20:46:00 +08:00
|
|
|
|
this.protyle.contentElement.classList.add("protyle-content--transition");
|
2022-05-26 15:18:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private init() {
|
|
|
|
|
|
this.protyle.lute = setLute({
|
|
|
|
|
|
emojiSite: this.protyle.options.hint.emojiPath,
|
|
|
|
|
|
emojis: this.protyle.options.hint.emoji,
|
|
|
|
|
|
headingAnchor: false,
|
|
|
|
|
|
listStyle: this.protyle.options.preview.markdown.listStyle,
|
|
|
|
|
|
paragraphBeginningSpace: this.protyle.options.preview.markdown.paragraphBeginningSpace,
|
|
|
|
|
|
sanitize: this.protyle.options.preview.markdown.sanitize,
|
|
|
|
|
|
});
|
|
|
|
|
|
|
2023-06-01 20:50:49 +08:00
|
|
|
|
this.protyle.preview = new Preview(this.protyle);
|
2022-05-26 15:18:53 +08:00
|
|
|
|
|
2023-06-01 20:50:49 +08:00
|
|
|
|
initUI(this.protyle);
|
2022-05-26 15:18:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** 聚焦到编辑器 */
|
|
|
|
|
|
public focus() {
|
|
|
|
|
|
this.protyle.wysiwyg.element.focus();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** 上传是否还在进行中 */
|
|
|
|
|
|
public isUploading() {
|
|
|
|
|
|
return this.protyle.upload.isUploading;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** 清空 undo & redo 栈 */
|
|
|
|
|
|
public clearStack() {
|
|
|
|
|
|
this.protyle.undo.clear();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** 销毁编辑器 */
|
|
|
|
|
|
public destroy() {
|
|
|
|
|
|
destroy(this.protyle);
|
|
|
|
|
|
}
|
2023-04-28 10:30:27 +08:00
|
|
|
|
|
|
|
|
|
|
public resize() {
|
|
|
|
|
|
resize(this.protyle);
|
|
|
|
|
|
}
|
2023-06-22 23:19:26 +08:00
|
|
|
|
|
|
|
|
|
|
public reload(focus: boolean) {
|
|
|
|
|
|
reloadProtyle(this.protyle, focus);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public insert(html: string, isBlock = false, useProtyleRange = false) {
|
|
|
|
|
|
insertHTML(html, this.protyle, isBlock, useProtyleRange);
|
|
|
|
|
|
}
|
2023-09-17 23:38:04 +08:00
|
|
|
|
|
2023-11-25 17:08:22 +08:00
|
|
|
|
public transaction(doOperations: IOperation[], undoOperations?: IOperation[]) {
|
|
|
|
|
|
transaction(this.protyle, doOperations, undoOperations);
|
2023-09-17 23:38:04 +08:00
|
|
|
|
}
|
2023-11-28 17:19:22 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 多个块转换为一个块
|
|
|
|
|
|
* @param {TTurnIntoOneSub} [subType] type 为 "BlocksMergeSuperBlock" 时必传
|
|
|
|
|
|
*/
|
|
|
|
|
|
public turnIntoOneTransaction(selectsElement: Element[], type: TTurnIntoOne, subType?: TTurnIntoOneSub) {
|
|
|
|
|
|
turnsIntoOneTransaction({
|
|
|
|
|
|
protyle: this.protyle,
|
|
|
|
|
|
selectsElement,
|
|
|
|
|
|
type,
|
|
|
|
|
|
level: subType
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 多个块转换
|
|
|
|
|
|
* @param {Element} [nodeElement] 优先使用包含 protyle-wysiwyg--select 的块,否则使用 nodeElement 单块
|
|
|
|
|
|
* @param {number} [subType] type 为 "Blocks2Hs" 时必传
|
|
|
|
|
|
*/
|
|
|
|
|
|
public turnIntoTransaction(nodeElement: Element, type: TTurnInto, subType?: number) {
|
|
|
|
|
|
turnsIntoTransaction({
|
|
|
|
|
|
protyle: this.protyle,
|
|
|
|
|
|
nodeElement,
|
|
|
|
|
|
type,
|
|
|
|
|
|
level: subType,
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public updateTransaction(id: string, newHTML: string, html: string) {
|
|
|
|
|
|
updateTransaction(this.protyle, id, newHTML, html);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public updateBatchTransaction(nodeElements: Element[], cb: (e: HTMLElement) => void) {
|
|
|
|
|
|
updateBatchTransaction(nodeElements, this.protyle, cb);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public getRange(element: Element) {
|
2023-11-28 17:25:25 +08:00
|
|
|
|
return getEditorRange(element);
|
2023-11-28 17:19:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public hasClosestBlock(element: Node) {
|
|
|
|
|
|
return hasClosestBlock(element);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public focusBlock(element: Element, toStart = true) {
|
|
|
|
|
|
return focusBlock(element, undefined, toStart);
|
|
|
|
|
|
}
|
2022-05-26 15:18:53 +08:00
|
|
|
|
}
|