diff --git a/app/src/menus/protyle.ts b/app/src/menus/protyle.ts index 9c23da8d5..08ff72de2 100644 --- a/app/src/menus/protyle.ts +++ b/app/src/menus/protyle.ts @@ -1153,7 +1153,7 @@ export const imgMenu = (protyle: IProtyle, range: Range, assetElement: HTMLEleme imgElement.style.width = inputElement.value + "px"; imgElement.style.height = ""; }); - inputElement.addEventListener("change", () => { + inputElement.addEventListener("blur", () => { nodeElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss")); updateTransaction(protyle, id, nodeElement.outerHTML, html); window.siyuan.menus.menu.remove(); @@ -1215,7 +1215,7 @@ export const imgMenu = (protyle: IProtyle, range: Range, assetElement: HTMLEleme assetElement.style.width = ""; imgElement.style.width = ""; }); - inputElement.addEventListener("change", () => { + inputElement.addEventListener("blur", () => { nodeElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss")); updateTransaction(protyle, id, nodeElement.outerHTML, html); window.siyuan.menus.menu.remove(); diff --git a/app/src/protyle/gutter/index.ts b/app/src/protyle/gutter/index.ts index b9cc7378e..9656aca82 100644 --- a/app/src/protyle/gutter/index.ts +++ b/app/src/protyle/gutter/index.ts @@ -803,6 +803,7 @@ export class Gutter { } this.genAlign(selectsElement, protyle); this.genWidths(selectsElement, protyle); + // this.genHeights(selectsElement, protyle); if (!window.siyuan.config.readonly) { window.siyuan.menus.menu.append(new MenuItem({type: "separator"}).element); window.siyuan.menus.menu.append(new MenuItem({ @@ -1674,6 +1675,7 @@ export class Gutter { } this.genAlign([nodeElement], protyle); this.genWidths([nodeElement], protyle); + // this.genHeights([nodeElement], protyle); } window.siyuan.menus.menu.append(new MenuItem({type: "separator"}).element); if (!["NodeThematicBreak", "NodeBlockQueryEmbed", "NodeIFrame", "NodeHTMLBlock", "NodeWidget", "NodeVideo", "NodeAudio"].includes(type) && @@ -1856,10 +1858,55 @@ export class Gutter { }).element); } + private updateNodeElements(nodeElements: Element[], protyle: IProtyle, inputElement: HTMLInputElement) { + const undoOperations: IOperation[] = []; + const operations: IOperation[] = []; + nodeElements.forEach((e) => { + undoOperations.push({ + action: "update", + id: e.getAttribute("data-node-id"), + data: e.outerHTML + }); + }); + inputElement.addEventListener(inputElement.type === "number" ? "blur" : "change", () => { + nodeElements.forEach((e: HTMLElement) => { + operations.push({ + action: "update", + id: e.getAttribute("data-node-id"), + data: e.outerHTML + }); + }); + transaction(protyle, operations, undoOperations); + window.siyuan.menus.menu.remove(); + focusBlock(nodeElements[0]); + }); + } + private genWidths(nodeElements: Element[], protyle: IProtyle) { - const styles: IMenu[] = []; + let rangeElement: HTMLInputElement; + const firstElement = nodeElements[0] as HTMLElement + const styles: IMenu[] = [{ + iconHTML: "", + type: "readonly", + label: `
+ px +
`, + bind: (element) => { + const inputElement = element.querySelector("input"); + inputElement.addEventListener("input", () => { + nodeElements.forEach((item: HTMLElement) => { + item.style.width = inputElement.value + "px"; + item.style.flex = "none"; + }) + rangeElement.value = "0"; + rangeElement.parentElement.setAttribute("aria-label", inputElement.value + "px"); + }); + this.updateNodeElements(nodeElements, protyle, inputElement); + } + }]; ["25%", "33%", "50%", "67%", "75%", "100%"].forEach((item) => { styles.push({ + iconHTML: "", label: item, click: () => { this.genClick(nodeElements, protyle, (e: HTMLElement) => { @@ -1872,55 +1919,31 @@ export class Gutter { styles.push({ type: "separator" }); - let width = 100; - if (nodeElements.length === 1) { - const widthStyle = (nodeElements[0] as HTMLElement).style.width; - if (widthStyle.endsWith("%")) { - width = parseInt(widthStyle); - } - } + const width = firstElement.style.width.endsWith("%") ? parseInt(firstElement.style.width) : 0; window.siyuan.menus.menu.append(new MenuItem({ label: window.siyuan.languages.width, submenu: styles.concat([{ - label: `
+ iconHTML: "", + type: "readonly", + label: `
`, - bind(element) { - const rangeElement = element.querySelector("input"); + bind: (element) => { + rangeElement = element.querySelector("input"); rangeElement.addEventListener("input", () => { - nodeElements.forEach((e) => { - (e as HTMLElement).style.width = rangeElement.value + "%"; - (e as HTMLElement).style.flex = "none"; + nodeElements.forEach((e: HTMLElement) => { + e.style.width = rangeElement.value + "%"; + e.style.flex = "none"; }); rangeElement.parentElement.setAttribute("aria-label", `${rangeElement.value}%`); }); - const undoOperations: IOperation[] = []; - const operations: IOperation[] = []; - nodeElements.forEach((e) => { - undoOperations.push({ - action: "update", - id: e.getAttribute("data-node-id"), - data: e.outerHTML - }); - }); - rangeElement.addEventListener("change", () => { - nodeElements.forEach((e: HTMLElement) => { - operations.push({ - action: "update", - id: e.getAttribute("data-node-id"), - data: e.outerHTML - }); - }); - transaction(protyle, operations, undoOperations); - window.siyuan.menus.menu.remove(); - focusBlock(nodeElements[0]); - }); + this.updateNodeElements(nodeElements, protyle, rangeElement); } }, { type: "separator" }, { - label: window.siyuan.languages.clearFontStyle, - icon: "iconTrashcan", + iconHTML: "", + label: window.siyuan.languages.default, click: () => { this.genClick(nodeElements, protyle, (e: HTMLElement) => { if (e.style.width) { @@ -1933,6 +1956,88 @@ export class Gutter { }).element); } + // TODO https://github.com/siyuan-note/siyuan/issues/11055 + private genHeights(nodeElements: Element[], protyle: IProtyle) { + const matchHeight = nodeElements.find(item => { + if (!item.classList.contains("p") && !item.classList.contains("code-block") && !item.classList.contains("render-node")) { + return true + } + }) + if (matchHeight) { + return; + } + let rangeElement: HTMLInputElement; + const firstElement = nodeElements[0] as HTMLElement + const styles: IMenu[] = [{ + iconHTML: "", + type: "readonly", + label: `
+ px +
`, + bind: (element) => { + const inputElement = element.querySelector("input"); + inputElement.addEventListener("input", () => { + nodeElements.forEach((item: HTMLElement) => { + item.style.height = inputElement.value + "px"; + item.style.flex = "none"; + }) + rangeElement.value = "0"; + rangeElement.parentElement.setAttribute("aria-label", inputElement.value + "px"); + }); + this.updateNodeElements(nodeElements, protyle, inputElement); + } + }]; + ["25%", "33%", "50%", "67%", "75%", "100%"].forEach((item) => { + styles.push({ + iconHTML: "", + label: item, + click: () => { + this.genClick(nodeElements, protyle, (e: HTMLElement) => { + e.style.height = item; + e.style.flex = "none"; + }); + } + }); + }); + styles.push({ + type: "separator" + }); + const height = firstElement.style.height.endsWith("%") ? parseInt(firstElement.style.height) : 0; + window.siyuan.menus.menu.append(new MenuItem({ + label: window.siyuan.languages.height, + submenu: styles.concat([{ + iconHTML: "", + label: `
+ +
`, + bind: (element) => { + rangeElement = element.querySelector("input"); + rangeElement.addEventListener("input", () => { + nodeElements.forEach((e: HTMLElement) => { + e.style.height = rangeElement.value + "%"; + e.style.flex = "none"; + }); + rangeElement.parentElement.setAttribute("aria-label", `${rangeElement.value}%`); + }); + this.updateNodeElements(nodeElements, protyle, rangeElement); + } + }, { + type: "separator" + }, { + iconHTML: "", + label: window.siyuan.languages.default, + click: () => { + this.genClick(nodeElements, protyle, (e: HTMLElement) => { + if (e.style.height) { + e.style.height = ""; + e.style.overflow = "" + } + }); + } + }]), + }).element); + } + private genCopyTextRef(selectsElement: Element[]): false | IMenu { if (isNotEditBlock(selectsElement[0])) { return false;