diff --git a/build.gradle b/build.gradle
index 836edad..82fb07f 100644
--- a/build.gradle
+++ b/build.gradle
@@ -16,7 +16,7 @@ repositories {
}
dependencies {
- implementation platform('run.halo.tools.platform:plugin:2.8.0-SNAPSHOT')
+ implementation platform('run.halo.tools.platform:plugin:2.11.0-SNAPSHOT')
compileOnly 'run.halo.app:api'
testImplementation 'run.halo.app:api'
diff --git a/console/package.json b/console/package.json
index f144bf7..7edc121 100644
--- a/console/package.json
+++ b/console/package.json
@@ -11,10 +11,11 @@
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore"
},
"dependencies": {
- "@halo-dev/components": "^1.7.0",
- "@halo-dev/console-shared": "^2.8.0",
+ "@halo-dev/api-client": "^2.11.0",
+ "@halo-dev/components": "^1.10.0",
+ "@halo-dev/console-shared": "^2.11.0",
"canvas-confetti": "^1.6.0",
- "@zhengyi/vditor": "^3.9.8",
+ "@zhengyi/vditor": "3.9.9",
"vue": "^3.3.4"
},
"devDependencies": {
diff --git a/console/pnpm-lock.yaml b/console/pnpm-lock.yaml
index c546400..922612b 100644
--- a/console/pnpm-lock.yaml
+++ b/console/pnpm-lock.yaml
@@ -5,15 +5,18 @@ settings:
excludeLinksFromLockfile: false
dependencies:
+ '@halo-dev/api-client':
+ specifier: ^2.11.0
+ version: 2.11.0
'@halo-dev/components':
- specifier: ^1.7.0
+ specifier: ^1.10.0
version: 1.10.0(vue-router@4.2.5)(vue@3.3.12)
'@halo-dev/console-shared':
- specifier: ^2.8.0
+ specifier: ^2.11.0
version: 2.11.0(vue-router@4.2.5)(vue@3.3.12)
'@zhengyi/vditor':
- specifier: ^3.9.8
- version: 3.9.8
+ specifier: 3.9.9
+ version: 3.9.9
canvas-confetti:
specifier: ^1.6.0
version: 1.9.2
@@ -1019,9 +1022,14 @@ packages:
'@types/node': 16.18.68
dev: true
- /@zhengyi/vditor@3.9.8:
- resolution: {integrity: sha512-PjGtpoVOezS//hf567BEqg8p0cEmlptV9oxiCc8UsCg9sHaJ0EYvhvS0m6Wsg/L7ShRVZe6RrjKa9SDtRu0m6w==, tarball: https://git.mczhengyi.top/api/packages/zhengyi/npm/%40zhengyi%2Fvditor/-/3.9.8/vditor-3.9.8.tgz}
+ /@zhengyi/halo-render@1.1.0:
+ resolution: {integrity: sha512-r+aD7wvdXVRyFcw/yI/PbdIqSsC+Bnql2WSKZa8CK+ntpTvc2tybn6Wxsfw96C71QS+Q/MPe8ufwZBjtRd+hhg==, tarball: https://git.mczhengyi.top/api/packages/zhengyi/npm/%40zhengyi%2Fhalo-render/-/1.1.0/halo-render-1.1.0.tgz}
+ dev: false
+
+ /@zhengyi/vditor@3.9.9:
+ resolution: {integrity: sha512-YHlWEbVkDvctAYUAghIISPjTPqxwubLuFlgbm1L6Oq3sGdIt4YZKUJA7Psv/JHaasX/tIvvcgZyUygSjjRBzMw==, tarball: https://git.mczhengyi.top/api/packages/zhengyi/npm/%40zhengyi%2Fvditor/-/3.9.9/vditor-3.9.9.tgz}
dependencies:
+ '@zhengyi/halo-render': 1.1.0
diff-match-patch: 1.0.5
dev: false
diff --git a/console/src/i18n/en-US.ts b/console/src/i18n/en-US.ts
index d668a43..cea0bb8 100644
--- a/console/src/i18n/en-US.ts
+++ b/console/src/i18n/en-US.ts
@@ -2,6 +2,27 @@ import type { I18nLang } from "@/type/i18n";
const lang: I18nLang = {
insert_image: "Insert Image",
+ confirm: "Confirm",
+ close: "Close",
+ default: "Default",
+ warning: "Warning",
+ danger: "Danger",
+ success: "Success",
+ info: "Info",
+ insert_tips: "Insert Tips",
+ type: "Type",
+ content: "Content",
+ platform: "Platform",
+ owner: "Owner",
+ repo: "Repo",
+ insert_git: "Insert Git Repo",
+ insert_custom: "Insert Custom",
+ insert_drive: "Insert Resources Link",
+ baidu_net_disk: "Baidu Net Disk",
+ ali_drive: "Ali Drive",
+ title: "Title",
+ link: "Link",
+ password: "Password",
};
export default lang;
diff --git a/console/src/i18n/zh-CN.ts b/console/src/i18n/zh-CN.ts
index b4012f6..47cb14d 100644
--- a/console/src/i18n/zh-CN.ts
+++ b/console/src/i18n/zh-CN.ts
@@ -1,8 +1,28 @@
-import type {I18nLang} from "@/type/i18n";
+import type { I18nLang } from "@/type/i18n";
const lang: I18nLang = {
- "insert_image": "插入图片"
-}
+ insert_image: "插入图片",
+ confirm: "确定",
+ close: "关闭",
+ default: "默认",
+ warning: "警告",
+ danger: "危险",
+ success: "成功",
+ info: "信息",
+ insert_tips: "插入Tips",
+ type: "类型",
+ content: "内容",
+ platform: "平台",
+ owner: "所有者",
+ repo: "仓库",
+ insert_git: "插入Git仓库",
+ insert_custom: "插入自定义块",
+ insert_drive: "插入资源链接",
+ baidu_net_disk: "百度网盘",
+ ali_drive: "阿里云盘",
+ title: "标题",
+ link: "链接",
+ password: "密码",
+};
-
-export default lang
+export default lang;
diff --git a/console/src/i18n/zh-TW.ts b/console/src/i18n/zh-TW.ts
index 7bf1294..bdd47bc 100644
--- a/console/src/i18n/zh-TW.ts
+++ b/console/src/i18n/zh-TW.ts
@@ -1,7 +1,28 @@
-import type {I18nLang} from "@/type/i18n";
+import type { I18nLang } from "@/type/i18n";
const lang: I18nLang = {
- "insert_image": "插入圖片"
-}
+ insert_image: "插入圖片",
+ confirm: "確定",
+ close: "關閉",
+ default: "默認",
+ warning: "警告",
+ danger: "危險",
+ success: "成功",
+ info: "訊息",
+ insert_tips: "插入Tips",
+ type: "類型",
+ content: "內容",
+ platform: "平臺",
+ owner: "所有者",
+ repo: "儲存庫",
+ insert_git: "插入Git存儲庫",
+ insert_custom: "插入自定義塊",
+ insert_drive: "插入資源鏈接",
+ baidu_net_disk: "百度網盤",
+ ali_drive: "阿里雲盤",
+ title: "標題",
+ link: "鏈接",
+ password: "密碼",
+};
-export default lang
+export default lang;
diff --git a/console/src/model/DriveModal.vue b/console/src/model/DriveModal.vue
new file mode 100644
index 0000000..0f0ecfb
--- /dev/null
+++ b/console/src/model/DriveModal.vue
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ t("confirm") }}
+
+
+ {{ t("close") }}
+
+
+
+
+
diff --git a/console/src/model/GitModal.vue b/console/src/model/GitModal.vue
new file mode 100644
index 0000000..28cdf12
--- /dev/null
+++ b/console/src/model/GitModal.vue
@@ -0,0 +1,72 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ t("confirm") }}
+
+
+ {{ t("close") }}
+
+
+
+
+
+
+
diff --git a/console/src/model/TipsModel.vue b/console/src/model/TipsModel.vue
new file mode 100644
index 0000000..b06977b
--- /dev/null
+++ b/console/src/model/TipsModel.vue
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+
+
+
+
+
+ {{ t("confirm") }}
+
+
+ {{ t("close") }}
+
+
+
+
+
diff --git a/console/src/type/editor.d.ts b/console/src/type/editor.d.ts
index 2c34734..abd9804 100644
--- a/console/src/type/editor.d.ts
+++ b/console/src/type/editor.d.ts
@@ -15,4 +15,6 @@ export declare type Options = {
showAttachment: () => void;
language: string;
codeBlockPreview: boolean;
+ uploadImage?: (files: File[]) => string | null | Promise;
+ openModal: (name: string) => void;
};
diff --git a/console/src/utils/i18n-utils.ts b/console/src/utils/i18n-utils.ts
index f3ad1c3..d106fb3 100644
--- a/console/src/utils/i18n-utils.ts
+++ b/console/src/utils/i18n-utils.ts
@@ -2,6 +2,7 @@ import zhCN from "@/i18n/zh-CN";
import type { I18nLang } from "@/type/i18n";
import zhTW from "@/i18n/zh-TW";
import enUS from "@/i18n/en-US";
+import {getLanguage} from "@/utils/vditor-utils";
const langDict: { [key: string]: I18nLang } = {
zh_CN: zhCN,
@@ -14,6 +15,10 @@ const langDict: { [key: string]: I18nLang } = {
* @param key key
* @param lang 目标语言
*/
-export function t(key: string, lang: keyof II18n): string {
+export function t(
+ key: string,
+ lang: keyof II18n | undefined = undefined
+): string {
+ if (!lang) lang = getLanguage(localStorage.getItem("locale") || "zh-CN");
return langDict[lang][key];
}
diff --git a/console/src/utils/icon.ts b/console/src/utils/icon.ts
index 337e46a..4ba709d 100644
--- a/console/src/utils/icon.ts
+++ b/console/src/utils/icon.ts
@@ -1 +1,2 @@
export const mdiImage = ``;
+export const mdiGrid = ``;
diff --git a/console/src/utils/vditor-utils.ts b/console/src/utils/vditor-utils.ts
index d88da83..c7e5b0f 100644
--- a/console/src/utils/vditor-utils.ts
+++ b/console/src/utils/vditor-utils.ts
@@ -1,5 +1,5 @@
import type { Options } from "@/type/editor";
-import { mdiImage } from "@/utils/icon";
+import {mdiGrid, mdiImage} from "@/utils/icon";
import { t } from "@/utils/i18n-utils";
export function getOptions(options: Options): IOptions {
@@ -22,7 +22,11 @@ export function getOptions(options: Options): IOptions {
},
after: options.after,
input: options.input,
- toolbar: getToolbar(options.showAttachment, getLanguage(options.language)),
+ toolbar: getToolbar(
+ options.showAttachment,
+ options.openModal,
+ getLanguage(options.language)
+ ),
counter: {
enable: true,
},
@@ -43,10 +47,13 @@ export function getOptions(options: Options): IOptions {
fullscreen: {
index: 1000,
},
+ upload: {
+ handler: options.uploadImage,
+ },
};
}
-function getLanguage(lang = "zh-CN"): keyof II18n {
+export function getLanguage(lang = "zh-CN"): keyof II18n {
switch (lang) {
case "zh-CN":
return "zh_CN";
@@ -63,6 +70,7 @@ function getLanguage(lang = "zh-CN"): keyof II18n {
function getToolbar(
showAttachmentCb: () => void,
+ openModal: (name: string) => void,
lang: keyof II18n
): (string | IMenuItem)[] | undefined {
return [
@@ -101,6 +109,29 @@ function getToolbar(
"|",
"fullscreen",
"edit-mode",
+ {
+ name: "insert_custom",
+ tip: t("insert_custom"),
+ icon: mdiGrid,
+ tipPosition: "n",
+ toolbar: [
+ {
+ name: "insert_tips",
+ icon: t("insert_tips"),
+ click: () => openModal("tips"),
+ },
+ {
+ name: "insert_git",
+ icon: t("insert_git"),
+ click: () => openModal("git"),
+ },
+ {
+ name: "insert_drive",
+ icon: t("insert_drive"),
+ click: () => openModal("drive"),
+ },
+ ],
+ },
{
name: "more",
toolbar: ["both", "export", "outline", "info", "help"],
diff --git a/console/src/views/Vditor.vue b/console/src/views/Vditor.vue
index 0a3c85b..1375054 100644
--- a/console/src/views/Vditor.vue
+++ b/console/src/views/Vditor.vue
@@ -5,21 +5,36 @@ import "@zhengyi/vditor/dist/index.css";
import type { EditorConfig } from "@/type/editor";
import { getOptions } from "@/utils/vditor-utils";
import type { AttachmentLike } from "@halo-dev/console-shared";
+import type { Attachment } from "@halo-dev/api-client";
+import { VLoading } from "@halo-dev/components";
+import TipsModel from "@/model/TipsModel.vue";
+import GitModal from "@/model/GitModal.vue";
+import DriveModal from "@/model/DriveModal.vue";
const props = withDefaults(
defineProps<{
raw?: string;
content: string;
+ uploadImage?: (file: File) => Promise;
}>(),
{
raw: "",
content: "",
+ uploadImage: undefined,
}
);
const vditor = ref();
const vditorRef = ref();
+const vditorLoaded = ref(false);
const attachmentSelectorModalShow = ref(false);
+// 特殊插入框, 当前支持none/tips/git
+const insertModel = ref("none");
+const insertValue = (value: string) => {
+ insertModel.value = "none";
+ vditor.value.insertValue(value);
+ vditor.value.focus();
+};
const emit = defineEmits<{
(event: "update:raw", value: string): void;
@@ -54,6 +69,7 @@ onUnmounted(async () => {
.querySelectorAll("script[id^='vditor']")
.forEach((el) => el.remove());
document.querySelectorAll("link[id^='vditor']").forEach((el) => el.remove());
+ vditorLoaded.value = false;
});
onMounted(async () => {
@@ -82,11 +98,34 @@ onMounted(async () => {
typeWriterMode: typeWriterMode,
after: () => {
vditor.value.setValue(props.raw || "# Title Here");
+ vditorLoaded.value = true;
},
input: debounceOnUpdate,
showAttachment: () => (attachmentSelectorModalShow.value = true),
language: lang,
codeBlockPreview: codeBlockPreview,
+ uploadImage: (files: File[]) => {
+ const acceptType = ["png", "jpg", "jpeg", "bmp", "gif", "webp", "svg"];
+ const extendName = files[0].name
+ .slice(files[0].name.lastIndexOf(".") + 1)
+ .toLowerCase();
+ if (acceptType.indexOf(extendName) === -1) {
+ vditor.value.tip("不允许上传该类型图片!", 2000);
+ return null;
+ }
+ if (props.uploadImage) {
+ vditor.value.tip("正在上传图片...", 2000);
+ props.uploadImage(files[0]).then((res: Attachment) => {
+ vditor.value.insertValue(
+ `\n\n![${res.spec.displayName}](${res.status.permalink})\n\n`
+ );
+ });
+ }
+ return null;
+ },
+ openModal: (name: string) => {
+ insertModel.value = name;
+ },
})
);
});
@@ -94,8 +133,27 @@ onMounted(async () => {
+
+
+
+
+
+
+
{
#plugin-vditor-mde input {
line-height: normal;
}
+
+.insert-modals label {
+ width: 100%;
+ display: flex;
+}
+
+.insert-modals label span {
+ width: 60px;
+ text-align: right;
+}
+
+.insert-modals select {
+ border: 1px solid #cccccc;
+ border-radius: 3px;
+ padding-top: 8px;
+ padding-bottom: 8px;
+ margin-left: 10px;
+ flex: 1;
+}
+
+.insert-modals textarea {
+ border: 1px solid #cccccc;
+ border-radius: 3px;
+ margin-left: 10px;
+ flex: 1;
+}
+
+.insert-modals input[type="text"] {
+ border: 1px solid #cccccc;
+ border-radius: 3px;
+ margin-left: 10px;
+ flex: 1;
+ padding: 8px 10px;
+}
diff --git a/download_dist.sh b/download_dist.sh
index 4d80ec3..9964220 100755
--- a/download_dist.sh
+++ b/download_dist.sh
@@ -4,7 +4,7 @@ cd src/main/resources/static
rm -rf dist
pwd
curl -o vditor.tgz \
- https://git.mczhengyi.top/zhengyi/-/packages/npm/@zhengyi%2Fvditor/3.9.8/files/249
+ https://git.mczhengyi.top/zhengyi/-/packages/npm/@zhengyi%2Fvditor/3.9.9/files/258
tar -xzvf vditor.tgz
mv package/dist .
rm -rf package
diff --git a/gradle.properties b/gradle.properties
index 95ac233..f271e55 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1 +1 @@
-version=1.3.1-SNAPSHOT
+version=1.4.0-SNAPSHOT
diff --git a/src/main/java/top/mczhengyi/vditor/bean/RenderConfig.java b/src/main/java/top/mczhengyi/vditor/bean/RenderConfig.java
index ad13c54..fbe7cee 100644
--- a/src/main/java/top/mczhengyi/vditor/bean/RenderConfig.java
+++ b/src/main/java/top/mczhengyi/vditor/bean/RenderConfig.java
@@ -7,4 +7,5 @@ public class RenderConfig {
Boolean enableRender;
String darkMode;
Boolean mediaRender;
+ Boolean onlyMarkdown;
}
diff --git a/src/main/java/top/mczhengyi/vditor/extension/VditorPostContentHandler.java b/src/main/java/top/mczhengyi/vditor/extension/VditorPostContentHandler.java
index 653e24d..f932460 100644
--- a/src/main/java/top/mczhengyi/vditor/extension/VditorPostContentHandler.java
+++ b/src/main/java/top/mczhengyi/vditor/extension/VditorPostContentHandler.java
@@ -21,7 +21,8 @@ public class VditorPostContentHandler implements ReactivePostContentHandler {
public Mono handle(PostContentContext contentContext) {
return reactiveSettingFetcher.fetch("render", RenderConfig.class)
.map(renderConfig -> {
- if (renderConfig.getEnableRender()) {
+ if (renderConfig.getEnableRender()&&
+ (!renderConfig.getOnlyMarkdown() || contentContext.getRawType().equals("markdown"))) {
contentContext.setContent(ScriptUtils.renderScript(renderConfig) + "\n" + contentContext.getContent());
}
return contentContext;
diff --git a/src/main/java/top/mczhengyi/vditor/extension/VditorSinglePageContentHandler.java b/src/main/java/top/mczhengyi/vditor/extension/VditorSinglePageContentHandler.java
index 731fdf6..df97490 100644
--- a/src/main/java/top/mczhengyi/vditor/extension/VditorSinglePageContentHandler.java
+++ b/src/main/java/top/mczhengyi/vditor/extension/VditorSinglePageContentHandler.java
@@ -19,7 +19,9 @@ public class VditorSinglePageContentHandler implements ReactiveSinglePageContent
public Mono handle(SinglePageContentContext contentContext) {
return reactiveSettingFetcher.fetch("render", RenderConfig.class)
.map(renderConfig -> {
- if (renderConfig.getEnableRender()) {
+ // 启用条件:开启渲染器,在启用仅Markdown渲染时当前页面为Markdown
+ if (renderConfig.getEnableRender() &&
+ (!renderConfig.getOnlyMarkdown() || contentContext.getRawType().equals("markdown"))) {
contentContext.setContent(ScriptUtils.renderScript(renderConfig) + "\n" + contentContext.getContent());
}
return contentContext;
diff --git a/src/main/resources/extensions/settings.yaml b/src/main/resources/extensions/settings.yaml
index 7aa7d85..4e1f245 100644
--- a/src/main/resources/extensions/settings.yaml
+++ b/src/main/resources/extensions/settings.yaml
@@ -53,4 +53,9 @@ spec:
name: mediaRender
label: "*实验性 渲染媒体标签"
help: 启用该功能会搜索文章内可解析的链接进行解析, 这可能会导致您的渲染出现问题!
- value: false
\ No newline at end of file
+ value: false
+ - $formkit: checkbox
+ name: onlyMarkdown
+ label: "仅在Markdown模式下渲染"
+ help: "启用该功能将仅在Markdown格式的文章下注入渲染脚本"
+ value: true
\ No newline at end of file
diff --git a/src/main/resources/plugin.yaml b/src/main/resources/plugin.yaml
index a77c6cb..671ae62 100644
--- a/src/main/resources/plugin.yaml
+++ b/src/main/resources/plugin.yaml
@@ -5,7 +5,7 @@ metadata:
name: vditor-mde
spec:
enabled: true
- requires: ">=2.8.0"
+ requires: ">=2.11.0"
author:
name: zhengyi59
website: https://github.com/justice2001/veditor-plugin