diff --git a/plugin.json b/plugin.json index c8c0c28..720dbfa 100644 --- a/plugin.json +++ b/plugin.json @@ -2,7 +2,7 @@ "name": "syplugin-misuzu-custom", "author": "Misuzu2027", "url": "https://github.com/Misuzu2027/syplugin-misuzu-custom", - "version": "0.0.6", + "version": "0.0.7", "minAppVersion": "3.0.14", "backends": [ "all" diff --git a/public/i18n/en_US.json b/public/i18n/en_US.json index 997159e..1006b6c 100644 --- a/public/i18n/en_US.json +++ b/public/i18n/en_US.json @@ -17,7 +17,7 @@ "MiddleClickToggleDocTree": "Middle-click to expand/collapse notebooks or documents", "Image": "Image", "MiddleClickResizeImageWidth": "Middle-click to resize image width", - "MiddleClickResizeImageWidthDesc":"Units are required. Example: 200px. px: fixed width; vw: viewport percentage.", + "MiddleClickResizeImageWidthDesc":"Units are required. Example: 200px, px: fixed width; 25%, %: viewport percentage.", "ZoomWidthLoadedImagesCurrentDocument": "Zoom the width of loaded images in the current document", "ShowTopBatchZoomBtn": "Show a batch image zoom button at the top" } \ No newline at end of file diff --git a/public/i18n/zh_CN.json b/public/i18n/zh_CN.json index 65ecd28..17892a3 100644 --- a/public/i18n/zh_CN.json +++ b/public/i18n/zh_CN.json @@ -17,7 +17,7 @@ "MiddleClickToggleDocTree":"中键展开/折叠笔记本或文档", "Image":"图片", "MiddleClickResizeImageWidth":"中键图片缩放宽度", - "MiddleClickResizeImageWidthDesc":"需要加上单位,例:200px。px:固定宽度;vw:视窗的比例。", + "MiddleClickResizeImageWidthDesc":"需要加上单位,例:200px,px:固定宽度;25%,%:视窗的比例。", "ZoomWidthLoadedImagesCurrentDocument":"缩放当前文档已加载图片的宽度", "ShowTopBatchZoomBtn":"顶部显示批量缩放图片按钮" } \ No newline at end of file diff --git a/src/components/img/ImageScalingService.ts b/src/components/img/ImageScalingService.ts index ce09cc7..b099452 100644 --- a/src/components/img/ImageScalingService.ts +++ b/src/components/img/ImageScalingService.ts @@ -1,11 +1,11 @@ import { EnvConfig } from "@/config/EnvConfig"; import { SettingService } from "@/service/SettingService"; -import { hasClosestByTagName, isPixelOrViewportWidth } from "@/utils/html-util"; +import { hasClosestByClassName, hasClosestByTagName, isPixelOrViewportWidth, isPxOrPercentWidth } from "@/utils/html-util"; import Instance from "@/utils/Instance"; import { confirmDialog, getActiveTab } from "@/utils/siyuan-util"; import { showMessage } from "siyuan"; -import { isStrBlank } from "@/utils/string-util"; +import { isStrBlank, isStrNotBlank } from "@/utils/string-util"; export class ImageScalingService { @@ -31,11 +31,22 @@ export class ImageScalingService { return; } + + + let divElement = document.createElement("div"); + const tipSpan = document.createElement("p"); + tipSpan.textContent = EnvConfig.ins.plugin.i18n.MiddleClickResizeImageWidthDesc; + const brElement = document.createElement("br"); const widthInput = document.createElement("input"); widthInput.className = "b3-text-field fn__block"; - confirmDialog(EnvConfig.ins.plugin.i18n.ZoomWidthLoadedImagesCurrentDocument - , widthInput, (): boolean => { + divElement.append(tipSpan); + divElement.append(brElement); + divElement.append(widthInput); + confirmDialog( + EnvConfig.ins.plugin.i18n.ZoomWidthLoadedImagesCurrentDocument + , divElement + , (): boolean => { return batchUpdateCurDocImageWidth(widthInput.value); }); } @@ -93,8 +104,9 @@ function handleImageZoomMousedown(event: MouseEvent) { let layoutTabContainerElement = clickElement.parentElement; // 图片宽度,目前思源只支持 px,vw。 - if (!isPixelOrViewportWidth(imageWidthValue)) { + if (!isPxOrPercentWidth(imageWidthValue)) { showImageFaileMessage("宽度格式不正确"); + event.preventDefault(); return; } @@ -107,8 +119,8 @@ function handleImageZoomMousedown(event: MouseEvent) { } layoutTabContainerElement = layoutTabContainerElement.parentElement; } - // 默认只读模式 - let isReadonly = true; + // 默认非只读模式 + let isReadonly = false; if (layoutTabContainerElement) { let readonlyButton = layoutTabContainerElement.querySelector('[data-type="readonly"]'); if (readonlyButton) { @@ -120,7 +132,7 @@ function handleImageZoomMousedown(event: MouseEvent) { event.preventDefault(); return; } - let flag = zoomImageWith(event.target as HTMLElement, imageWidthValue); + let flag = zoomImageWith(clickElement, imageWidthValue); if (flag) { event.preventDefault(); } @@ -131,6 +143,9 @@ function handleImageZoomMousedown(event: MouseEvent) { function zoomImageWith(target: HTMLElement, width: string): boolean { + if (!target || isStrBlank(width)) { + return; + } // 创建一个 mousedown 事件 const mouseDownEvent = new MouseEvent('mousedown', { bubbles: true, // 事件是否冒泡 @@ -144,16 +159,22 @@ function zoomImageWith(target: HTMLElement, width: string): boolean { view: window // 视图环境 }); - let imgElement = hasClosestByTagName(target, "img"); - if (!imgElement) { + let imgParentSpanElement = hasClosestByTagName(target, "span"); + if (!imgParentSpanElement) { return; } - let dragElement = imgElement.parentElement.querySelector(".protyle-action__drag"); + let dragElement = imgParentSpanElement.parentElement.querySelector(".protyle-action__drag"); if (!dragElement) { return; } + let imgSpanElement = hasClosestByClassName(imgParentSpanElement, "img", "span"); + if (imgSpanElement && isStrNotBlank(imgSpanElement.style.width)) { + imgSpanElement.removeAttribute('style') + // imgSpanElement.style.width = ''; + } + dragElement.dispatchEvent(mouseDownEvent); - imgElement.style.width = width; + imgParentSpanElement.style.width = width; dragElement.dispatchEvent(mouseUpEvent); return true; } @@ -274,7 +295,7 @@ function batchUpdateCurDocImageWidth(width: string): boolean { showImageFaileMessage("宽度为空"); return; } - if (!isPixelOrViewportWidth(width)) { + if (!isPxOrPercentWidth(width)) { showImageFaileMessage("宽度格式不正确"); return; } @@ -284,7 +305,7 @@ function batchUpdateCurDocImageWidth(width: string): boolean { return; } // 默认只读模式 - let isReadonly = true; + let isReadonly = false; let readonlyButton = currentDocument.querySelector('[data-type="readonly"]'); if (readonlyButton) { isReadonly = readonlyButton.querySelector("use").getAttribute("xlink:href") !== "#iconUnlock"; @@ -313,4 +334,12 @@ function showImageFaileMessage(reason: string) { 4000, "info", ); +} + +function showImageSuccessMessage(reason: string) { + showMessage( + `批量设置当前文档图片宽度完成!`, + 3000, + "info", + ); } \ No newline at end of file diff --git a/src/utils/html-util.ts b/src/utils/html-util.ts index bd5e038..0b3df8a 100644 --- a/src/utils/html-util.ts +++ b/src/utils/html-util.ts @@ -1,5 +1,5 @@ import { isArrayEmpty } from "./array-util"; -import { isStrBlank } from "./string-util"; +import { isStrBlank, isStrNotBlank } from "./string-util"; export const escapeAttr = (html: string) => { return html.replace(/"/g, """).replace(/'/g, "'"); @@ -275,15 +275,16 @@ export function hasClosestByTagName(element: HTMLElement | null, tagName: string if (!element || isStrBlank(tagName)) { return false; } + let tagNameUpper = tagName.toUpperCase(); // 检查传入的元素是否存在,并且是否是标签名 - if (element && element.tagName == tagName.toUpperCase()) { + if (element && element.tagName == tagNameUpper) { return element; } // 如果没有找到,检查父级元素 while (element && element.parentElement && element.tagName !== "BODY") { element = element.parentElement; - if (element.classList.contains(tagName)) { + if (element.tagName == tagNameUpper) { return element; } } @@ -293,13 +294,19 @@ export function hasClosestByTagName(element: HTMLElement | null, tagName: string -export function hasClosestByClassName(element: HTMLElement | null, className: string): HTMLElement | false { +export function hasClosestByClassName(element: HTMLElement | null, className: string, tagName?: string): HTMLElement | false { if (!element || isStrBlank(className)) { return false; } // 检查传入的元素是否存在,并且是否具有指定的类名 - if (element && element.classList.contains(className)) { - return element; + if (element + && element.classList.contains(className) + ) { + if (isStrBlank(tagName)) { + return element; + } else if (element.tagName == tagName.toUpperCase()) { + return element; + } } // 如果没有找到,检查父级元素 @@ -335,6 +342,12 @@ export function hasClosestById(element: HTMLElement | null, id: string): HTMLEle } export function isPixelOrViewportWidth(str: string): boolean { - const regex = /^\d+(?:\.\d+)?(px|vw)$/; + const regex = /^\d+(?:\.\d+)?(px|vw|%)$/; + return regex.test(str); +} + + +export function isPxOrPercentWidth(str: string): boolean { + const regex = /^\d+(?:\.\d+)?(px|%)$/; return regex.test(str); }