commit
e849287222
10 changed files with 825 additions and 559 deletions
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
|
@ -57,6 +57,6 @@ jobs:
|
||||||
with:
|
with:
|
||||||
allowUpdates: true
|
allowUpdates: true
|
||||||
artifactErrorsFailBuild: true
|
artifactErrorsFailBuild: true
|
||||||
artifacts: 'package.zip'
|
artifacts: "package.zip"
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
prerelease: true
|
prerelease: true
|
||||||
|
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -7,3 +7,4 @@ node_modules
|
||||||
dev
|
dev
|
||||||
dist
|
dist
|
||||||
build
|
build
|
||||||
|
tmp
|
||||||
|
|
38
README.md
38
README.md
|
@ -3,7 +3,8 @@
|
||||||
|
|
||||||
[中文版](./README_zh_CN.md)
|
[中文版](./README_zh_CN.md)
|
||||||
|
|
||||||
> Consistent with [siyuan/plugin-sample](https://github.com/siyuan-note/plugin-sample) [v0.0.6](https://github.com/siyuan-note/plugin-sample/tree/v0.0.6).
|
> Consistent with [siyuan/plugin-sample](https://github.com/siyuan-note/plugin-sample) [v0.1.3](https://github.com/siyuan-note/plugin-sample/tree/v0.1.3).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
1. Using vite for packaging
|
1. Using vite for packaging
|
||||||
|
@ -62,7 +63,6 @@ complete the following tasks:
|
||||||
* Text used in the plugin, such as button text and tooltips
|
* Text used in the plugin, such as button text and tooltips
|
||||||
* src/i18n/*.json language configuration files
|
* src/i18n/*.json language configuration files
|
||||||
* Use `this.i18.key` to get the text in the code
|
* Use `this.i18.key` to get the text in the code
|
||||||
* Finally, declare the language supported by the plugin in the `i18n` field in plugin.json
|
|
||||||
|
|
||||||
It is recommended that the plugin supports at least English and Simplified Chinese, so that more people can use it more
|
It is recommended that the plugin supports at least English and Simplified Chinese, so that more people can use it more
|
||||||
conveniently.
|
conveniently.
|
||||||
|
@ -74,8 +74,10 @@ conveniently.
|
||||||
"name": "plugin-sample-vite-svelte",
|
"name": "plugin-sample-vite-svelte",
|
||||||
"author": "frostime",
|
"author": "frostime",
|
||||||
"url": "https://github.com/siyuan-note/plugin-sample-vite-svelte",
|
"url": "https://github.com/siyuan-note/plugin-sample-vite-svelte",
|
||||||
"version": "0.0.1",
|
"version": "0.1.3",
|
||||||
"minAppVersion": "2.9.0",
|
"minAppVersion": "2.8.8",
|
||||||
|
"backends": ["windows", "linux", "darwin"],
|
||||||
|
"frontends": ["desktop"],
|
||||||
"displayName": {
|
"displayName": {
|
||||||
"en_US": "Plugin sample with vite and svelte",
|
"en_US": "Plugin sample with vite and svelte",
|
||||||
"zh_CN": "插件样例 vite + svelte 版"
|
"zh_CN": "插件样例 vite + svelte 版"
|
||||||
|
@ -89,8 +91,11 @@ conveniently.
|
||||||
"zh_CN": "README.md"
|
"zh_CN": "README.md"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
|
"openCollective": "",
|
||||||
|
"patreon": "",
|
||||||
|
"github": "",
|
||||||
"custom": [
|
"custom": [
|
||||||
""
|
"https://ld246.com/sponsor"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -102,6 +107,21 @@ conveniently.
|
||||||
* `url`: Plugin repo URL
|
* `url`: Plugin repo URL
|
||||||
* `version`: Plugin version number, it is recommended to follow the [semver](https://semver.org/) specification
|
* `version`: Plugin version number, it is recommended to follow the [semver](https://semver.org/) specification
|
||||||
* `minAppVersion`: Minimum version number of SiYuan required to use this plugin
|
* `minAppVersion`: Minimum version number of SiYuan required to use this plugin
|
||||||
|
* `backends`: Backend environment required by the plugin, optional values are `windows`, `linux`, `darwin`, `docker`, `android`, `ios` and `all`
|
||||||
|
* `windows`: Windows desktop
|
||||||
|
* `linux`: Linux desktop
|
||||||
|
* `darwin`: macOS desktop
|
||||||
|
* `docker`: Docker
|
||||||
|
* `android`: Android APP
|
||||||
|
* `ios`: iOS APP
|
||||||
|
* `all`: All environments
|
||||||
|
* `frontends`: Frontend environment required by the plugin, optional values are `desktop`, `desktop-window`, `mobile`, `browser-desktop`, `browser-mobile` and `all`
|
||||||
|
* `desktop`: Desktop
|
||||||
|
* `desktop-window`: Desktop window converted from tab
|
||||||
|
* `mobile`: Mobile APP
|
||||||
|
* `browser-desktop`: Desktop browser
|
||||||
|
* `browser-mobile`: Mobile browser
|
||||||
|
* `all`: All environments
|
||||||
* `displayName`: Template display name, mainly used for display in the marketplace list, supports multiple languages
|
* `displayName`: Template display name, mainly used for display in the marketplace list, supports multiple languages
|
||||||
* `default`: Default language, must exist
|
* `default`: Default language, must exist
|
||||||
* `zh_CN`, `en_US` and other languages: optional, it is recommended to provide at least Chinese and English
|
* `zh_CN`, `en_US` and other languages: optional, it is recommended to provide at least Chinese and English
|
||||||
|
@ -122,13 +142,13 @@ conveniently.
|
||||||
No matter which method is used to compile and package, we finally need to generate a package.zip, which contains at
|
No matter which method is used to compile and package, we finally need to generate a package.zip, which contains at
|
||||||
least the following files:
|
least the following files:
|
||||||
|
|
||||||
* icon.png
|
* i18n/*
|
||||||
|
* icon.png (160*160)
|
||||||
|
* index.css
|
||||||
* index.js
|
* index.js
|
||||||
* plugin.json
|
* plugin.json
|
||||||
* preview.png
|
* preview.png (1024*768)
|
||||||
* README*.md
|
* README*.md
|
||||||
* index.css (optional)
|
|
||||||
* i18n/* (optional)
|
|
||||||
|
|
||||||
## List on the marketplace
|
## List on the marketplace
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
[English](./README.md)
|
[English](./README.md)
|
||||||
|
|
||||||
|
|
||||||
> 本例和 [siyuan/plugin-sample](https://github.com/siyuan-note/plugin-sample) [v0.0.6](https://github.com/siyuan-note/plugin-sample/tree/v0.0.6) 基本保持一致。
|
> 本例和 [siyuan/plugin-sample](https://github.com/siyuan-note/plugin-sample) [v0.1.3](https://github.com/siyuan-note/plugin-sample/tree/v0.1.3) 基本保持一致。
|
||||||
|
|
||||||
1. 使用 vite 打包
|
1. 使用 vite 打包
|
||||||
2. 使用符号链接、而不是把项目放到插件目录下的模式进行开发
|
2. 使用符号链接、而不是把项目放到插件目录下的模式进行开发
|
||||||
|
@ -59,7 +59,6 @@
|
||||||
* 插件中使用的文本,比如按钮文字和提示信息
|
* 插件中使用的文本,比如按钮文字和提示信息
|
||||||
* src/i18n/*.json 语言配置文件
|
* src/i18n/*.json 语言配置文件
|
||||||
* 代码中使用 `this.i18.key` 获取文本
|
* 代码中使用 `this.i18.key` 获取文本
|
||||||
* 最后在 plugin.json 中的 `i18n` 字段中声明该插件支持的语言
|
|
||||||
|
|
||||||
建议插件至少支持英文和简体中文,这样可以方便更多人使用。
|
建议插件至少支持英文和简体中文,这样可以方便更多人使用。
|
||||||
|
|
||||||
|
@ -70,8 +69,10 @@
|
||||||
"name": "plugin-sample-vite-svelte",
|
"name": "plugin-sample-vite-svelte",
|
||||||
"author": "frostime",
|
"author": "frostime",
|
||||||
"url": "https://github.com/siyuan-note/plugin-sample-vite-svelte",
|
"url": "https://github.com/siyuan-note/plugin-sample-vite-svelte",
|
||||||
"version": "0.0.1",
|
"version": "0.1.3",
|
||||||
"minAppVersion": "2.9.0",
|
"minAppVersion": "2.8.8",
|
||||||
|
"backends": ["windows", "linux", "darwin"],
|
||||||
|
"frontends": ["desktop"],
|
||||||
"displayName": {
|
"displayName": {
|
||||||
"en_US": "Plugin sample with vite and svelte",
|
"en_US": "Plugin sample with vite and svelte",
|
||||||
"zh_CN": "插件样例 vite + svelte 版"
|
"zh_CN": "插件样例 vite + svelte 版"
|
||||||
|
@ -85,8 +86,11 @@
|
||||||
"zh_CN": "README.md"
|
"zh_CN": "README.md"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
|
"openCollective": "",
|
||||||
|
"patreon": "",
|
||||||
|
"github": "",
|
||||||
"custom": [
|
"custom": [
|
||||||
""
|
"https://ld246.com/sponsor"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -97,6 +101,21 @@
|
||||||
* `url`:插件仓库地址
|
* `url`:插件仓库地址
|
||||||
* `version`:插件版本号,建议遵循 [semver](https://semver.org/lang/zh-CN/) 规范
|
* `version`:插件版本号,建议遵循 [semver](https://semver.org/lang/zh-CN/) 规范
|
||||||
* `minAppVersion`:插件支持的最低思源笔记版本号
|
* `minAppVersion`:插件支持的最低思源笔记版本号
|
||||||
|
* `backends`:插件需要的后端环境,可选值为 `windows`, `linux`, `darwin`, `docker`, `android`, `ios` and `all`
|
||||||
|
* `windows`:Windows 桌面端
|
||||||
|
* `linux`:Linux 桌面端
|
||||||
|
* `darwin`:macOS 桌面端
|
||||||
|
* `docker`:Docker 端
|
||||||
|
* `android`:Android 端
|
||||||
|
* `ios`:iOS 端
|
||||||
|
* `all`:所有环境
|
||||||
|
* `frontends`:插件需要的前端环境,可选值为 `desktop`, `desktop-window`, `mobile`, `browser-desktop`, `browser-mobile` and `all`
|
||||||
|
* `desktop`:桌面端
|
||||||
|
* `desktop-window`:桌面端页签转换的独立窗口
|
||||||
|
* `mobile`:移动端
|
||||||
|
* `browser-desktop`:桌面端浏览器
|
||||||
|
* `browser-mobile`:移动端浏览器
|
||||||
|
* `all`:所有环境
|
||||||
* `displayName`:模板显示名称,主要用于模板集市列表中显示,支持多语言
|
* `displayName`:模板显示名称,主要用于模板集市列表中显示,支持多语言
|
||||||
* `default`:默认语言,必须存在
|
* `default`:默认语言,必须存在
|
||||||
* `zh_CN`、`en_US` 等其他语言:可选,建议至少提供中文和英文
|
* `zh_CN`、`en_US` 等其他语言:可选,建议至少提供中文和英文
|
||||||
|
@ -116,13 +135,13 @@
|
||||||
|
|
||||||
无论使用何种方式编译打包,我们最终需要生成一个 package.zip,它至少包含如下文件:
|
无论使用何种方式编译打包,我们最终需要生成一个 package.zip,它至少包含如下文件:
|
||||||
|
|
||||||
* icon.png
|
* i18n/*
|
||||||
|
* icon.png (160*160)
|
||||||
|
* index.css
|
||||||
* index.js
|
* index.js
|
||||||
* plugin.json
|
* plugin.json
|
||||||
* preview.png
|
* preview.png (1024*768)
|
||||||
* README*.md
|
* README*.md
|
||||||
* index.css (optional)
|
|
||||||
* i18n/* (optional)
|
|
||||||
|
|
||||||
## 上架集市
|
## 上架集市
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
"minimist": "^1.2.8",
|
"minimist": "^1.2.8",
|
||||||
"rollup-plugin-livereload": "^2.0.5",
|
"rollup-plugin-livereload": "^2.0.5",
|
||||||
"sass": "^1.62.1",
|
"sass": "^1.62.1",
|
||||||
"siyuan": "^0.7.1",
|
"siyuan": "^0.7.2",
|
||||||
"svelte": "^3.57.0",
|
"svelte": "^3.57.0",
|
||||||
"ts-node": "^10.9.1",
|
"ts-node": "^10.9.1",
|
||||||
"typescript": "^5.0.4",
|
"typescript": "^5.0.4",
|
||||||
|
|
|
@ -2,8 +2,10 @@
|
||||||
"name": "plugin-sample-vite-svelte",
|
"name": "plugin-sample-vite-svelte",
|
||||||
"author": "frostime",
|
"author": "frostime",
|
||||||
"url": "https://github.com/siyuan-note/plugin-sample-vite-svelte",
|
"url": "https://github.com/siyuan-note/plugin-sample-vite-svelte",
|
||||||
"version": "0.0.6",
|
"version": "0.1.3",
|
||||||
"minAppVersion": "2.9.0",
|
"minAppVersion": "2.9.0",
|
||||||
|
"backends": ["windows", "linux", "darwin"],
|
||||||
|
"frontends": ["desktop"],
|
||||||
"displayName": {
|
"displayName": {
|
||||||
"en_US": "Plugin sample with vite and svelte",
|
"en_US": "Plugin sample with vite and svelte",
|
||||||
"zh_CN": "插件样例 vite + svelte 版"
|
"zh_CN": "插件样例 vite + svelte 版"
|
||||||
|
|
|
@ -5,6 +5,9 @@
|
||||||
"byeMenu": "Bye, Menu!",
|
"byeMenu": "Bye, Menu!",
|
||||||
"helloPlugin": "Hello, Plugin!",
|
"helloPlugin": "Hello, Plugin!",
|
||||||
"byePlugin": "Bye, Plugin!",
|
"byePlugin": "Bye, Plugin!",
|
||||||
|
"showDialog": "Show dialog",
|
||||||
|
"removedData": "Data deleted",
|
||||||
|
"confirmRemove": "Confirm to delete the data in ${name}?",
|
||||||
"name": "SiYuan",
|
"name": "SiYuan",
|
||||||
"hello": {
|
"hello": {
|
||||||
"makesure": "Before using this template, please read the <a href=\"https://github.com/siyuan-note/plugin-sample\">offical sample</a>, make sure that you've known about the pipeline for plugin developing."
|
"makesure": "Before using this template, please read the <a href=\"https://github.com/siyuan-note/plugin-sample\">offical sample</a>, make sure that you've known about the pipeline for plugin developing."
|
||||||
|
|
|
@ -5,6 +5,9 @@
|
||||||
"byeMenu": "再见,菜单!",
|
"byeMenu": "再见,菜单!",
|
||||||
"helloPlugin": "你好,插件!",
|
"helloPlugin": "你好,插件!",
|
||||||
"byePlugin": "再见,插件!",
|
"byePlugin": "再见,插件!",
|
||||||
|
"showDialog": "弹出一个对话框",
|
||||||
|
"removedData": "数据已删除",
|
||||||
|
"confirmRemove": "确认删除 ${name} 中的数据?",
|
||||||
"name": "思源",
|
"name": "思源",
|
||||||
"hello": {
|
"hello": {
|
||||||
"makesure": "使用这个模板之前,请阅读<a href=\"https://github.com/siyuan-note/plugin-sample\">官方教程</a>, 确保自己已经理解了插件的基本开发流程。"
|
"makesure": "使用这个模板之前,请阅读<a href=\"https://github.com/siyuan-note/plugin-sample\">官方教程</a>, 确保自己已经理解了插件的基本开发流程。"
|
||||||
|
|
446
src/index.ts
446
src/index.ts
|
@ -1,4 +1,15 @@
|
||||||
import { Plugin, showMessage, confirm, Dialog, Menu, isMobile, openTab, adaptHotkey } from "siyuan";
|
import {
|
||||||
|
Plugin,
|
||||||
|
showMessage,
|
||||||
|
confirm,
|
||||||
|
Dialog,
|
||||||
|
Menu,
|
||||||
|
openTab,
|
||||||
|
adaptHotkey,
|
||||||
|
getFrontend,
|
||||||
|
getBackend,
|
||||||
|
IModel
|
||||||
|
} from "siyuan";
|
||||||
import "./index.scss";
|
import "./index.scss";
|
||||||
|
|
||||||
import HelloExample from "./hello.svelte";
|
import HelloExample from "./hello.svelte";
|
||||||
|
@ -8,26 +19,61 @@ const STORAGE_NAME = "menu-config";
|
||||||
const TAB_TYPE = "custom_tab";
|
const TAB_TYPE = "custom_tab";
|
||||||
const DOCK_TYPE = "dock_tab";
|
const DOCK_TYPE = "dock_tab";
|
||||||
|
|
||||||
export default class SamplePlugin extends Plugin {
|
export default class PluginSample extends Plugin {
|
||||||
|
|
||||||
private customTab: () => any;
|
private customTab: () => IModel;
|
||||||
|
private isMobile: boolean;
|
||||||
|
|
||||||
async onload() {
|
async onload() {
|
||||||
showMessage("Hello SiYuan Plugin");
|
|
||||||
this.data[STORAGE_NAME] = {readonlyText: "Readonly"};
|
this.data[STORAGE_NAME] = {readonlyText: "Readonly"};
|
||||||
|
|
||||||
|
console.log("loading plugin-sample", this.i18n);
|
||||||
|
|
||||||
|
const frontEnd = getFrontend();
|
||||||
|
this.isMobile = frontEnd === "mobile" || frontEnd === "browser-mobile";
|
||||||
|
// 图标的制作参见帮助文档
|
||||||
|
this.addIcons(`<symbol id="iconFace" viewBox="0 0 32 32">
|
||||||
|
<path d="M13.667 17.333c0 0.92-0.747 1.667-1.667 1.667s-1.667-0.747-1.667-1.667 0.747-1.667 1.667-1.667 1.667 0.747 1.667 1.667zM20 15.667c-0.92 0-1.667 0.747-1.667 1.667s0.747 1.667 1.667 1.667 1.667-0.747 1.667-1.667-0.747-1.667-1.667-1.667zM29.333 16c0 7.36-5.973 13.333-13.333 13.333s-13.333-5.973-13.333-13.333 5.973-13.333 13.333-13.333 13.333 5.973 13.333 13.333zM14.213 5.493c1.867 3.093 5.253 5.173 9.12 5.173 0.613 0 1.213-0.067 1.787-0.16-1.867-3.093-5.253-5.173-9.12-5.173-0.613 0-1.213 0.067-1.787 0.16zM5.893 12.627c2.28-1.293 4.040-3.4 4.88-5.92-2.28 1.293-4.040 3.4-4.88 5.92zM26.667 16c0-1.040-0.16-2.040-0.44-2.987-0.933 0.2-1.893 0.32-2.893 0.32-4.173 0-7.893-1.92-10.347-4.92-1.4 3.413-4.187 6.093-7.653 7.4 0.013 0.053 0 0.12 0 0.187 0 5.88 4.787 10.667 10.667 10.667s10.667-4.787 10.667-10.667z"></path>
|
||||||
|
</symbol>
|
||||||
|
<symbol id="iconSaving" viewBox="0 0 32 32">
|
||||||
|
<path d="M20 13.333c0-0.733 0.6-1.333 1.333-1.333s1.333 0.6 1.333 1.333c0 0.733-0.6 1.333-1.333 1.333s-1.333-0.6-1.333-1.333zM10.667 12h6.667v-2.667h-6.667v2.667zM29.333 10v9.293l-3.76 1.253-2.24 7.453h-7.333v-2.667h-2.667v2.667h-7.333c0 0-3.333-11.28-3.333-15.333s3.28-7.333 7.333-7.333h6.667c1.213-1.613 3.147-2.667 5.333-2.667 1.107 0 2 0.893 2 2 0 0.28-0.053 0.533-0.16 0.773-0.187 0.453-0.347 0.973-0.427 1.533l3.027 3.027h2.893zM26.667 12.667h-1.333l-4.667-4.667c0-0.867 0.12-1.72 0.347-2.547-1.293 0.333-2.347 1.293-2.787 2.547h-8.227c-2.573 0-4.667 2.093-4.667 4.667 0 2.507 1.627 8.867 2.68 12.667h2.653v-2.667h8v2.667h2.68l2.067-6.867 3.253-1.093v-4.707z"></path>
|
||||||
|
</symbol>`);
|
||||||
|
|
||||||
const topBarElement = this.addTopBar({
|
const topBarElement = this.addTopBar({
|
||||||
icon: "iconEmoji",
|
icon: "iconFace",
|
||||||
title: this.i18n.addTopBarIcon,
|
title: this.i18n.addTopBarIcon,
|
||||||
position: "left",
|
position: "right",
|
||||||
callback: () => {
|
callback: () => {
|
||||||
this.addMenu(topBarElement.getBoundingClientRect());
|
let rect = topBarElement.getBoundingClientRect();
|
||||||
|
// 如果被隐藏,则使用更多按钮
|
||||||
|
if (rect.width === 0) {
|
||||||
|
rect = document.querySelector("#barMore").getBoundingClientRect();
|
||||||
|
}
|
||||||
|
this.addMenu(rect);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let div = document.createElement("div");
|
const statusIconTemp = document.createElement("template");
|
||||||
|
statusIconTemp.innerHTML = `<div class="toolbar__item b3-tooltips b3-tooltips__w" aria-label="Remove plugin-sample Data">
|
||||||
|
<svg>
|
||||||
|
<use xlink:href="#iconTrashcan"></use>
|
||||||
|
</svg>
|
||||||
|
</div>`;
|
||||||
|
statusIconTemp.content.firstElementChild.addEventListener("click", () => {
|
||||||
|
confirm("⚠️", this.i18n.confirmRemove.replace("${name}", this.name), () => {
|
||||||
|
this.removeData(STORAGE_NAME).then(() => {
|
||||||
|
this.data[STORAGE_NAME] = {readonlyText: "Readonly"};
|
||||||
|
showMessage(`[${this.name}]: ${this.i18n.removedData}`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
this.addStatusBar({
|
||||||
|
element: statusIconTemp.content.firstElementChild as HTMLElement,
|
||||||
|
});
|
||||||
|
|
||||||
|
let tabDiv = document.createElement("div");
|
||||||
new HelloExample({
|
new HelloExample({
|
||||||
target: div,
|
target: tabDiv,
|
||||||
props: {
|
props: {
|
||||||
name: this.i18n.name,
|
name: this.i18n.name,
|
||||||
i18n: this.i18n.hello
|
i18n: this.i18n.hello
|
||||||
|
@ -36,7 +82,7 @@ export default class SamplePlugin extends Plugin {
|
||||||
this.customTab = this.addTab({
|
this.customTab = this.addTab({
|
||||||
type: TAB_TYPE,
|
type: TAB_TYPE,
|
||||||
init() {
|
init() {
|
||||||
this.element.appendChild(div);
|
this.element.appendChild(tabDiv);
|
||||||
console.log(this.element);
|
console.log(this.element);
|
||||||
},
|
},
|
||||||
destroy() {
|
destroy() {
|
||||||
|
@ -44,11 +90,19 @@ export default class SamplePlugin extends Plugin {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.addCommand({
|
||||||
|
langKey: "showDialog",
|
||||||
|
hotkey: "⇧⌘M",
|
||||||
|
callback: () => {
|
||||||
|
this.showDialog();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
this.addDock({
|
this.addDock({
|
||||||
config: {
|
config: {
|
||||||
position: "LeftBottom",
|
position: "LeftBottom",
|
||||||
size: {width: 200, height: 0},
|
size: {width: 200, height: 0},
|
||||||
icon: "iconEmoji",
|
icon: "iconSaving",
|
||||||
title: "Custom Dock",
|
title: "Custom Dock",
|
||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
|
@ -75,10 +129,12 @@ export default class SamplePlugin extends Plugin {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.log(this.i18n.helloPlugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
onLayoutReady() {
|
onLayoutReady() {
|
||||||
this.loadData(STORAGE_NAME);
|
this.loadData(STORAGE_NAME);
|
||||||
|
console.log(`frontend: ${getFrontend()}; backend: ${getBackend()}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
onunload() {
|
onunload() {
|
||||||
|
@ -87,160 +143,6 @@ export default class SamplePlugin extends Plugin {
|
||||||
console.log("onunload");
|
console.log("onunload");
|
||||||
}
|
}
|
||||||
|
|
||||||
private wsEvent({ detail }: any) {
|
|
||||||
console.log(detail);
|
|
||||||
}
|
|
||||||
|
|
||||||
private blockIconEvent({detail}: any) {
|
|
||||||
console.log(detail);
|
|
||||||
detail.menu.addSeparator(0);
|
|
||||||
const ids: string[] = [];
|
|
||||||
detail.blockElements.forEach((item: HTMLElement) => {
|
|
||||||
ids.push(item.getAttribute("data-node-id"));
|
|
||||||
});
|
|
||||||
detail.menu.addItem({
|
|
||||||
index: 1,
|
|
||||||
iconHTML: "",
|
|
||||||
type: "readonly",
|
|
||||||
label: "IDs<br>" + ids.join("<br>"),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private async addMenu(rect: DOMRect) {
|
|
||||||
const menu = new Menu("topBarSample", () => {
|
|
||||||
console.log(this.i18n.byeMenu);
|
|
||||||
});
|
|
||||||
menu.addItem({
|
|
||||||
icon: "iconHelp",
|
|
||||||
label: "Confirm",
|
|
||||||
click() {
|
|
||||||
confirm("Confirm", "Is this a confirm?", () => {
|
|
||||||
showMessage("confirm");
|
|
||||||
}, () => {
|
|
||||||
showMessage("cancel");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
menu.addItem({
|
|
||||||
icon: "iconFeedback",
|
|
||||||
label: "Message",
|
|
||||||
click: () => {
|
|
||||||
showMessage(this.i18n.helloPlugin);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
menu.addItem({
|
|
||||||
icon: "iconInfo",
|
|
||||||
label: "Dialog",
|
|
||||||
click: () => this.openHelloInDialog()
|
|
||||||
});
|
|
||||||
menu.addItem({
|
|
||||||
icon: "iconLayoutBottom",
|
|
||||||
label: "Open Tab",
|
|
||||||
click: () => {
|
|
||||||
openTab({
|
|
||||||
custom: {
|
|
||||||
icon: "iconEmoji",
|
|
||||||
title: "Custom Tab",
|
|
||||||
data: {
|
|
||||||
text: "This is my custom tab",
|
|
||||||
},
|
|
||||||
fn: this.customTab
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
menu.addItem({
|
|
||||||
icon: "iconLayout",
|
|
||||||
label: "Open Float Layer(open help)",
|
|
||||||
click: () => {
|
|
||||||
this.addFloatLayer({
|
|
||||||
ids: ["20230523173319-xj1l3qu", "20230523173321-55o0w2n"],
|
|
||||||
defIds: ["20230523173323-imgm9tp", "20230523173324-cxu98t3"],
|
|
||||||
x: window.innerWidth - 768 - 120,
|
|
||||||
y: 32
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
menu.addItem({
|
|
||||||
icon: "iconTrashcan",
|
|
||||||
label: "Remove Data",
|
|
||||||
click: () => {
|
|
||||||
this.removeData(STORAGE_NAME).then(() => {
|
|
||||||
this.data[STORAGE_NAME] = {readonlyText: "Readonly"};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
menu.addItem({
|
|
||||||
icon: "iconScrollHoriz",
|
|
||||||
label: "Event Bus",
|
|
||||||
type: "submenu",
|
|
||||||
submenu: [{
|
|
||||||
icon: "iconSelect",
|
|
||||||
label: "On ws-main",
|
|
||||||
click: () => {
|
|
||||||
this.eventBus.on("ws-main", this.wsEvent);
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
icon: "iconClose",
|
|
||||||
label: "Off ws-main",
|
|
||||||
click: () => {
|
|
||||||
this.eventBus.off("ws-main", this.wsEvent);
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
icon: "iconSelect",
|
|
||||||
label: "On click-blockicon",
|
|
||||||
click: () => {
|
|
||||||
this.eventBus.on("click-blockicon", this.blockIconEvent);
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
icon: "iconClose",
|
|
||||||
label: "Off click-blockicon",
|
|
||||||
click: () => {
|
|
||||||
this.eventBus.off("click-blockicon", this.blockIconEvent);
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
icon: "iconSelect",
|
|
||||||
label: "On click-pdf",
|
|
||||||
click: () => {
|
|
||||||
this.eventBus.on("click-pdf", this.wsEvent);
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
icon: "iconClose",
|
|
||||||
label: "Off click-pdf",
|
|
||||||
click: () => {
|
|
||||||
this.eventBus.off("click-pdf", this.wsEvent);
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
icon: "iconSelect",
|
|
||||||
label: "On click-editorcontent",
|
|
||||||
click: () => {
|
|
||||||
this.eventBus.on("click-editorcontent", this.wsEvent);
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
icon: "iconClose",
|
|
||||||
label: "Off click-editorcontent",
|
|
||||||
click: () => {
|
|
||||||
this.eventBus.off("click-editorcontent", this.wsEvent);
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
});
|
|
||||||
menu.addSeparator();
|
|
||||||
menu.addItem({
|
|
||||||
icon: "iconSparkles",
|
|
||||||
label: this.data[STORAGE_NAME] || "Readonly",
|
|
||||||
type: "readonly",
|
|
||||||
});
|
|
||||||
if (isMobile()) {
|
|
||||||
menu.fullscreen();
|
|
||||||
} else {
|
|
||||||
menu.open({
|
|
||||||
x: rect.right,
|
|
||||||
y: rect.bottom,
|
|
||||||
isLeft: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
openSetting(): void {
|
openSetting(): void {
|
||||||
let dialog = new Dialog({
|
let dialog = new Dialog({
|
||||||
title: "SettingPannel",
|
title: "SettingPannel",
|
||||||
|
@ -257,13 +159,30 @@ export default class SamplePlugin extends Plugin {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private openHelloInDialog() {
|
private eventBusLog({detail}: any) {
|
||||||
|
console.log(detail);
|
||||||
|
}
|
||||||
|
|
||||||
|
private blockIconEvent({detail}: any) {
|
||||||
|
const ids: string[] = [];
|
||||||
|
detail.blockElements.forEach((item: HTMLElement) => {
|
||||||
|
ids.push(item.getAttribute("data-node-id"));
|
||||||
|
});
|
||||||
|
detail.menu.addItem({
|
||||||
|
iconHTML: "",
|
||||||
|
type: "readonly",
|
||||||
|
label: "IDs<br>" + ids.join("<br>"),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private showDialog() {
|
||||||
let dialog = new Dialog({
|
let dialog = new Dialog({
|
||||||
title: "Hello World",
|
title: "Hello World",
|
||||||
content: `<div id="helloPanel"></div>`,
|
content: `<div id="helloPanel" class="b3-dialog__content"></div>`,
|
||||||
|
width: this.isMobile ? "92vw" : "720px",
|
||||||
destroyCallback(options) {
|
destroyCallback(options) {
|
||||||
//You must destroy the component when the dialog is closed
|
//Destroy the component when the dialog is closed
|
||||||
hello.$destroy();
|
// hello.$destroy();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
let hello = new HelloExample({
|
let hello = new HelloExample({
|
||||||
|
@ -274,4 +193,193 @@ export default class SamplePlugin extends Plugin {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private addMenu(rect: DOMRect) {
|
||||||
|
const menu = new Menu("topBarSample", () => {
|
||||||
|
console.log(this.i18n.byeMenu);
|
||||||
|
});
|
||||||
|
menu.addItem({
|
||||||
|
icon: "iconInfo",
|
||||||
|
label: "Dialog",
|
||||||
|
accelerator: this.commands[0].customHotkey,
|
||||||
|
click: () => this.showDialog()
|
||||||
|
});
|
||||||
|
if (!this.isMobile) {
|
||||||
|
menu.addItem({
|
||||||
|
icon: "iconLayoutBottom",
|
||||||
|
label: "Open Custom Tab",
|
||||||
|
click: () => {
|
||||||
|
const tab = openTab({
|
||||||
|
app: this.app,
|
||||||
|
custom: {
|
||||||
|
icon: "iconFace",
|
||||||
|
title: "Custom Tab",
|
||||||
|
data: {
|
||||||
|
text: "This is my custom tab",
|
||||||
|
},
|
||||||
|
fn: this.customTab
|
||||||
|
},
|
||||||
|
});
|
||||||
|
console.log(tab)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
menu.addItem({
|
||||||
|
icon: "iconLayoutBottom",
|
||||||
|
label: "Open Asset Tab(open help first)",
|
||||||
|
click: () => {
|
||||||
|
const tab = openTab({
|
||||||
|
app: this.app,
|
||||||
|
asset: {
|
||||||
|
path: "assets/paragraph-20210512165953-ag1nib4.svg"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
console.log(tab)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
menu.addItem({
|
||||||
|
icon: "iconLayoutBottom",
|
||||||
|
label: "Open Doc Tab(open help first)",
|
||||||
|
click: async () => {
|
||||||
|
const tab = await openTab({
|
||||||
|
app: this.app,
|
||||||
|
doc: {
|
||||||
|
id: "20200812220555-lj3enxa",
|
||||||
|
}
|
||||||
|
});
|
||||||
|
console.log(tab)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
menu.addItem({
|
||||||
|
icon: "iconLayoutBottom",
|
||||||
|
label: "Open Search Tab",
|
||||||
|
click: () => {
|
||||||
|
const tab = openTab({
|
||||||
|
app: this.app,
|
||||||
|
search: {
|
||||||
|
k: "SiYuan"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
console.log(tab)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
menu.addItem({
|
||||||
|
icon: "iconLayoutBottom",
|
||||||
|
label: "Open Card Tab",
|
||||||
|
click: () => {
|
||||||
|
const tab = openTab({
|
||||||
|
app: this.app,
|
||||||
|
card: {
|
||||||
|
type: "all"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
console.log(tab)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
menu.addItem({
|
||||||
|
icon: "iconLayout",
|
||||||
|
label: "Open Float Layer(open help first)",
|
||||||
|
click: () => {
|
||||||
|
this.addFloatLayer({
|
||||||
|
ids: ["20210428212840-8rqwn5o", "20201225220955-l154bn4"],
|
||||||
|
defIds: ["20230415111858-vgohvf3", "20200813131152-0wk5akh"],
|
||||||
|
x: window.innerWidth - 768 - 120,
|
||||||
|
y: 32
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
menu.addItem({
|
||||||
|
icon: "iconScrollHoriz",
|
||||||
|
label: "Event Bus",
|
||||||
|
type: "submenu",
|
||||||
|
submenu: [{
|
||||||
|
icon: "iconSelect",
|
||||||
|
label: "On ws-main",
|
||||||
|
click: () => {
|
||||||
|
this.eventBus.on("ws-main", this.eventBusLog);
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
icon: "iconClose",
|
||||||
|
label: "Off ws-main",
|
||||||
|
click: () => {
|
||||||
|
this.eventBus.off("ws-main", this.eventBusLog);
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
icon: "iconSelect",
|
||||||
|
label: "On click-blockicon",
|
||||||
|
click: () => {
|
||||||
|
this.eventBus.on("click-blockicon", this.blockIconEvent);
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
icon: "iconClose",
|
||||||
|
label: "Off click-blockicon",
|
||||||
|
click: () => {
|
||||||
|
this.eventBus.off("click-blockicon", this.blockIconEvent);
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
icon: "iconSelect",
|
||||||
|
label: "On click-pdf",
|
||||||
|
click: () => {
|
||||||
|
this.eventBus.on("click-pdf", this.eventBusLog);
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
icon: "iconClose",
|
||||||
|
label: "Off click-pdf",
|
||||||
|
click: () => {
|
||||||
|
this.eventBus.off("click-pdf", this.eventBusLog);
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
icon: "iconSelect",
|
||||||
|
label: "On click-editorcontent",
|
||||||
|
click: () => {
|
||||||
|
this.eventBus.on("click-editorcontent", this.eventBusLog);
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
icon: "iconClose",
|
||||||
|
label: "Off click-editorcontent",
|
||||||
|
click: () => {
|
||||||
|
this.eventBus.off("click-editorcontent", this.eventBusLog);
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
icon: "iconSelect",
|
||||||
|
label: "On click-editortitleicon",
|
||||||
|
click: () => {
|
||||||
|
this.eventBus.on("click-editortitleicon", this.eventBusLog);
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
icon: "iconClose",
|
||||||
|
label: "Off click-editortitleicon",
|
||||||
|
click: () => {
|
||||||
|
this.eventBus.off("click-editortitleicon", this.eventBusLog);
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
icon: "iconSelect",
|
||||||
|
label: "On open-noneditableblock",
|
||||||
|
click: () => {
|
||||||
|
this.eventBus.on("open-noneditableblock", this.eventBusLog);
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
icon: "iconClose",
|
||||||
|
label: "Off open-noneditableblock",
|
||||||
|
click: () => {
|
||||||
|
this.eventBus.off("open-noneditableblock", this.eventBusLog);
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
menu.addSeparator();
|
||||||
|
menu.addItem({
|
||||||
|
icon: "iconSparkles",
|
||||||
|
label: this.data[STORAGE_NAME].readonlyText || "Readonly",
|
||||||
|
type: "readonly",
|
||||||
|
});
|
||||||
|
if (this.isMobile) {
|
||||||
|
menu.fullscreen();
|
||||||
|
} else {
|
||||||
|
menu.open({
|
||||||
|
x: rect.right,
|
||||||
|
y: rect.bottom,
|
||||||
|
isLeft: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
212
src/siyuan.d.ts
vendored
212
src/siyuan.d.ts
vendored
|
@ -1,18 +1,41 @@
|
||||||
declare module "siyuan" {
|
type TEventBus = "ws-main" | "click-blockicon" | "click-editorcontent" | "click-pdf" |
|
||||||
type TEventBus = "ws-main" | "click-blockicon" | "click-editorcontent" | "click-pdf" | "click-editortitleicon"
|
"click-editortitleicon" | "open-noneditableblock"
|
||||||
|
|
||||||
declare global {
|
type TCardType = "doc" | "notebook" | "all"
|
||||||
|
|
||||||
|
declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
Lute: Lute
|
Lute: Lute
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface ITab {
|
||||||
|
id: string;
|
||||||
|
headElement: HTMLElement;
|
||||||
|
panelElement: HTMLElement;
|
||||||
|
model: IModel;
|
||||||
|
title: string;
|
||||||
|
icon: string;
|
||||||
|
docIcon: string;
|
||||||
|
updateTitle: (title: string) => void;
|
||||||
|
pin: () => void;
|
||||||
|
unpin: () => void;
|
||||||
|
setDocIcon: (icon: string) => void;
|
||||||
|
close: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
interface IObject {
|
interface IModel {
|
||||||
|
element: Element;
|
||||||
|
tab: ITab;
|
||||||
|
data: any;
|
||||||
|
type: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IObject {
|
||||||
[key: string]: string;
|
[key: string]: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ILuteNode {
|
interface ILuteNode {
|
||||||
TokensStr: () => string;
|
TokensStr: () => string;
|
||||||
__internal_object__: {
|
__internal_object__: {
|
||||||
Parent: {
|
Parent: {
|
||||||
|
@ -20,26 +43,53 @@ declare module "siyuan" {
|
||||||
},
|
},
|
||||||
HeadingLevel: string,
|
HeadingLevel: string,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IWebSocketData {
|
interface ISearchOption {
|
||||||
|
page?: number
|
||||||
|
group?: number, // 0:不分组,1:按文档分组
|
||||||
|
hasReplace?: boolean,
|
||||||
|
method?: number // 0:文本,1:查询语法,2:SQL,3:正则表达式
|
||||||
|
hPath?: string
|
||||||
|
idPath?: string[]
|
||||||
|
k: string
|
||||||
|
r?: string
|
||||||
|
types?: {
|
||||||
|
mathBlock: boolean
|
||||||
|
table: boolean
|
||||||
|
blockquote: boolean
|
||||||
|
superBlock: boolean
|
||||||
|
paragraph: boolean
|
||||||
|
document: boolean
|
||||||
|
heading: boolean
|
||||||
|
list: boolean
|
||||||
|
listItem: boolean
|
||||||
|
codeBlock: boolean
|
||||||
|
htmlBlock: boolean
|
||||||
|
embedBlock: boolean
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IWebSocketData {
|
||||||
cmd: string
|
cmd: string
|
||||||
callback?: string
|
callback?: string
|
||||||
data: any
|
data: any
|
||||||
msg: string
|
msg: string
|
||||||
code: number
|
code: number
|
||||||
sid: string
|
sid: string
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IPluginDockTab {
|
declare interface IPluginDockTab {
|
||||||
position: "LeftTop" | "LeftBottom" | "RightTop" | "RightBottom" | "BottomLeft" | "BottomRight",
|
position: "LeftTop" | "LeftBottom" | "RightTop" | "RightBottom" | "BottomLeft" | "BottomRight",
|
||||||
size: { width: number, height: number },
|
size: { width: number, height: number },
|
||||||
icon: string,
|
icon: string,
|
||||||
hotkey?: string,
|
hotkey?: string,
|
||||||
title: string,
|
title: string,
|
||||||
}
|
index?: number,
|
||||||
|
show?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
interface IMenuItemOption {
|
interface IMenuItemOption {
|
||||||
label?: string,
|
label?: string,
|
||||||
click?: (element: HTMLElement) => void,
|
click?: (element: HTMLElement) => void,
|
||||||
type?: "separator" | "submenu" | "readonly",
|
type?: "separator" | "submenu" | "readonly",
|
||||||
|
@ -52,52 +102,97 @@ declare module "siyuan" {
|
||||||
iconHTML?: string
|
iconHTML?: string
|
||||||
current?: boolean
|
current?: boolean
|
||||||
bind?: (element: HTMLElement) => void
|
bind?: (element: HTMLElement) => void
|
||||||
}
|
index?: number
|
||||||
|
element?: HTMLElement
|
||||||
|
}
|
||||||
|
|
||||||
export function fetchPost(url: string, data?: any, cb?: (response: IWebSocketData) => void, headers?: IObject): void;
|
interface ICommandOption {
|
||||||
|
langKey: string, // 多语言 key
|
||||||
|
/**
|
||||||
|
* 目前需使用 MacOS 符号标识,顺序按照 ⌥⇧⌘,入 ⌥⇧⌘A
|
||||||
|
* "Ctrl": "⌘",
|
||||||
|
* "Shift": "⇧",
|
||||||
|
* "Alt": "⌥",
|
||||||
|
* "Tab": "⇥",
|
||||||
|
* "Backspace": "⌫",
|
||||||
|
* "Delete": "⌦",
|
||||||
|
* "Enter": "↩",
|
||||||
|
*/
|
||||||
|
hotkey: string,
|
||||||
|
customHotkey?: string,
|
||||||
|
callback?: () => void
|
||||||
|
fileTreeCallback?: (file: any) => void
|
||||||
|
editorCallback?: (protyle: any) => void
|
||||||
|
dockCallback?: (element: HTMLElement) => void
|
||||||
|
}
|
||||||
|
|
||||||
export function fetchSyncPost(url: string, data?: any): Promise<IWebSocketData>;
|
export function fetchPost(url: string, data?: any, callback?: (response: IWebSocketData) => void, headers?: IObject): void;
|
||||||
|
|
||||||
export function fetchGet(url: string, cb: (response: IWebSocketData) => void): void;
|
export function fetchSyncPost(url: string, data?: any): Promise<IWebSocketData>;
|
||||||
|
|
||||||
export function openTab(options: {
|
export function fetchGet(url: string, callback: (response: IWebSocketData) => void): void;
|
||||||
|
|
||||||
|
export function openTab(options: {
|
||||||
|
app: App,
|
||||||
|
doc?: {
|
||||||
|
id: string, // 块 id
|
||||||
|
action?: string [] // cb-get-all:获取所有内容;cb-get-focus:打开后光标定位在 id 所在的块;cb-get-hl: 打开后 id 块高亮
|
||||||
|
zoomIn?: boolean // 是否缩放
|
||||||
|
},
|
||||||
|
pdf?: {
|
||||||
|
path: string,
|
||||||
|
page?: number, // pdf 页码
|
||||||
|
id?: string, // File Annotation id
|
||||||
|
},
|
||||||
|
asset?: {
|
||||||
|
path: string,
|
||||||
|
},
|
||||||
|
search?: ISearchOption
|
||||||
|
card?: {
|
||||||
|
type: TCardType,
|
||||||
|
id?: string, // cardType 为 all 时不传,否则传文档或笔记本 id
|
||||||
|
title?: string // cardType 为 all 时不传,否则传文档或笔记本名称
|
||||||
|
},
|
||||||
custom?: {
|
custom?: {
|
||||||
title: string,
|
title: string,
|
||||||
icon: string,
|
icon: string,
|
||||||
data?: any
|
data?: any
|
||||||
fn?: () => any,
|
fn?: () => IModel,
|
||||||
} // card 和自定义页签 必填
|
}
|
||||||
position?: "right" | "bottom",
|
position?: "right" | "bottom",
|
||||||
keepCursor?: boolean // 是否跳转到新 tab 上
|
keepCursor?: boolean // 是否跳转到新 tab 上
|
||||||
removeCurrentTab?: boolean // 在当前页签打开时需移除原有页签
|
removeCurrentTab?: boolean // 在当前页签打开时需移除原有页签
|
||||||
afterOpen?: () => void // 打开后回调
|
afterOpen?: () => void // 打开后回调
|
||||||
}): void
|
}): ITab
|
||||||
|
|
||||||
export function isMobile(): boolean;
|
export function getFrontend(): "desktop" | "desktop-window" | "mobile" | "browser-desktop" | "browser-mobile";
|
||||||
|
|
||||||
export function adaptHotkey(hotkey: string): string;
|
export function getBackend(): "windows" | "linux" | "darwin" | "docker" | "android" | "ios"
|
||||||
|
|
||||||
export function confirm(title: string, text: string, confirmCB?: () => void, cancelCB?: () => void): void;
|
export function adaptHotkey(hotkey: string): string;
|
||||||
|
|
||||||
/**
|
export function confirm(title: string, text: string, confirmCallback?: () => void, cancelCallback?: () => void): void;
|
||||||
|
|
||||||
|
/**
|
||||||
* @param timeout - ms. 0: manual close;-1: always show; 6000: default
|
* @param timeout - ms. 0: manual close;-1: always show; 6000: default
|
||||||
* @param {string} [type=info]
|
* @param {string} [type=info]
|
||||||
*/
|
*/
|
||||||
export function showMessage(text: string, timeout?: number, type?: "info" | "error", id?: string): void;
|
export function showMessage(text: string, timeout?: number, type?: "info" | "error", id?: string): void;
|
||||||
|
|
||||||
export class App {
|
export class App {
|
||||||
plugins: Plugin[];
|
plugins: Plugin[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export abstract class Plugin {
|
export abstract class Plugin {
|
||||||
eventBus: EventBus;
|
eventBus: EventBus;
|
||||||
i18n: IObject;
|
i18n: IObject;
|
||||||
data: any;
|
data: any;
|
||||||
name: string;
|
name: string;
|
||||||
|
app: App;
|
||||||
|
commands: ICommandOption[];
|
||||||
|
|
||||||
constructor(options: {
|
constructor(options: {
|
||||||
app: App,
|
app: App,
|
||||||
id: string,
|
|
||||||
name: string,
|
name: string,
|
||||||
i18n: IObject
|
i18n: IObject
|
||||||
})
|
})
|
||||||
|
@ -108,36 +203,50 @@ declare module "siyuan" {
|
||||||
|
|
||||||
onLayoutReady(): void;
|
onLayoutReady(): void;
|
||||||
|
|
||||||
/*
|
/**
|
||||||
|
* Must be executed before the synchronous function.
|
||||||
* @param {string} [options.position=right]
|
* @param {string} [options.position=right]
|
||||||
*/
|
*/
|
||||||
addTopBar(options: {
|
addTopBar(options: {
|
||||||
icon: string,
|
icon: string,
|
||||||
title: string,
|
title: string,
|
||||||
callback: (evt: MouseEvent) => void
|
callback: (event: MouseEvent) => void
|
||||||
position?: "right" | "left"
|
position?: "right" | "left"
|
||||||
}): HTMLDivElement;
|
}): HTMLElement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Must be executed before the synchronous function.
|
||||||
|
* @param {string} [options.position=right]
|
||||||
|
*/
|
||||||
|
addStatusBar(options: {
|
||||||
|
element: HTMLElement,
|
||||||
|
position?: "right" | "left"
|
||||||
|
}): HTMLElement
|
||||||
|
|
||||||
openSetting(): void
|
openSetting(): void
|
||||||
|
|
||||||
// registerCommand(command: IPluginCommand): void;
|
|
||||||
|
|
||||||
// registerSettingRender(settingRender: SettingRender): void;
|
|
||||||
|
|
||||||
loadData(storageName: string): Promise<any>;
|
loadData(storageName: string): Promise<any>;
|
||||||
|
|
||||||
saveData(storageName: string, content: any): Promise<void>;
|
saveData(storageName: string, content: any): Promise<void>;
|
||||||
|
|
||||||
removeData(storageName: string): Promise<any>;
|
removeData(storageName: string): Promise<any>;
|
||||||
|
|
||||||
|
addIcons(svg: string): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Must be executed before the synchronous function.
|
||||||
|
*/
|
||||||
addTab(options: {
|
addTab(options: {
|
||||||
type: string,
|
type: string,
|
||||||
destroy?: () => void,
|
destroy?: () => void,
|
||||||
resize?: () => void,
|
resize?: () => void,
|
||||||
update?: () => void,
|
update?: () => void,
|
||||||
init: () => void
|
init: () => void
|
||||||
}): () => any
|
}): () => IModel
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Must be executed before the synchronous function.
|
||||||
|
*/
|
||||||
addDock(options: {
|
addDock(options: {
|
||||||
config: IPluginDockTab,
|
config: IPluginDockTab,
|
||||||
data: any,
|
data: any,
|
||||||
|
@ -146,7 +255,9 @@ declare module "siyuan" {
|
||||||
resize?: () => void,
|
resize?: () => void,
|
||||||
update?: () => void,
|
update?: () => void,
|
||||||
init: () => void
|
init: () => void
|
||||||
}): any
|
}): { config: IPluginDockTab, model: IModel }
|
||||||
|
|
||||||
|
addCommand(options: ICommandOption): void
|
||||||
|
|
||||||
addFloatLayer(options: {
|
addFloatLayer(options: {
|
||||||
ids: string[],
|
ids: string[],
|
||||||
|
@ -155,9 +266,9 @@ declare module "siyuan" {
|
||||||
y?: number,
|
y?: number,
|
||||||
targetElement?: HTMLElement
|
targetElement?: HTMLElement
|
||||||
}): void
|
}): void
|
||||||
}
|
}
|
||||||
|
|
||||||
export class EventBus {
|
export class EventBus {
|
||||||
on(type: TEventBus, listener: (event: CustomEvent<any>) => void): void;
|
on(type: TEventBus, listener: (event: CustomEvent<any>) => void): void;
|
||||||
|
|
||||||
once(type: TEventBus, listener: (event: CustomEvent<any>) => void): void;
|
once(type: TEventBus, listener: (event: CustomEvent<any>) => void): void;
|
||||||
|
@ -165,9 +276,9 @@ declare module "siyuan" {
|
||||||
off(type: TEventBus, listener: (event: CustomEvent<any>) => void): void;
|
off(type: TEventBus, listener: (event: CustomEvent<any>) => void): void;
|
||||||
|
|
||||||
emit(type: TEventBus, detail?: any): boolean;
|
emit(type: TEventBus, detail?: any): boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Dialog {
|
export class Dialog {
|
||||||
|
|
||||||
element: HTMLElement;
|
element: HTMLElement;
|
||||||
|
|
||||||
|
@ -185,28 +296,28 @@ declare module "siyuan" {
|
||||||
destroy(options?: IObject): void;
|
destroy(options?: IObject): void;
|
||||||
|
|
||||||
bindInput(inputElement: HTMLInputElement | HTMLTextAreaElement, enterEvent?: () => void): void;
|
bindInput(inputElement: HTMLInputElement | HTMLTextAreaElement, enterEvent?: () => void): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Menu {
|
export class Menu {
|
||||||
constructor(id?: string, closeCB?: () => void);
|
constructor(id?: string, closeCallback?: () => void);
|
||||||
|
|
||||||
showSubMenu(subMenuElement: HTMLElement): void;
|
showSubMenu(subMenuElement: HTMLElement): void;
|
||||||
|
|
||||||
addItem(options: IMenuItemOption): HTMLElement;
|
addItem(options: IMenuItemOption): HTMLElement;
|
||||||
|
|
||||||
addSeparator(): void;
|
addSeparator(index?: number): void;
|
||||||
|
|
||||||
open(options: { x: number, y: number, h?: number, w?: number, isLeft?: boolean }): void;
|
open(options: { x: number, y: number, h?: number, w?: number, isLeft?: boolean }): void;
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* @param {string} [position=all]
|
* @param {string} [position=all]
|
||||||
*/
|
*/
|
||||||
fullscreen(position?: "bottom" | "all"): void;
|
fullscreen(position?: "bottom" | "all"): void;
|
||||||
|
|
||||||
close(): void;
|
close(): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare class Lute {
|
declare class Lute {
|
||||||
public static WalkStop: number;
|
public static WalkStop: number;
|
||||||
public static WalkSkipChildren: number;
|
public static WalkSkipChildren: number;
|
||||||
public static WalkContinue: number;
|
public static WalkContinue: number;
|
||||||
|
@ -310,5 +421,4 @@ declare module "siyuan" {
|
||||||
public BlockDOM2InlineBlockDOM(html: string): string;
|
public BlockDOM2InlineBlockDOM(html: string): string;
|
||||||
|
|
||||||
public BlockDOM2HTML(html: string): string;
|
public BlockDOM2HTML(html: string): string;
|
||||||
}
|
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue