diff --git a/app/src/protyle/render/av/cell.ts b/app/src/protyle/render/av/cell.ts index 89e2bdc19..94e0be456 100644 --- a/app/src/protyle/render/av/cell.ts +++ b/app/src/protyle/render/av/cell.ts @@ -81,6 +81,20 @@ const genCellValueByElement = (colType: TAVCol, cellElement: HTMLElement) => { contents: Array.from(cellElement.querySelectorAll("span")).map((item: HTMLElement) => item.textContent), } }; + } else if (colType === "mAsset") { + const mAsset: IAVCellAssetValue[] = [] + Array.from(cellElement.children).forEach((item) => { + const isImg = item.classList.contains("av__cellassetimg") + mAsset.push({ + type: isImg ? "image" : "file", + content: isImg ? item.getAttribute("src") : item.getAttribute("data-url"), + name: isImg ? "" : item.textContent + }) + }) + cellValue = { + type: colType, + mAsset + }; } if (colType === "block") { cellValue.isDetached = cellElement.dataset.detached === "true"; @@ -148,8 +162,13 @@ export const genCellValue = (colType: TAVCol, value: string | any) => { type: colType, relation: {blockIDs: [], contents: value ? [value] : []} }; + } else if (colType === "mAsset") { + cellValue = { + type: colType, + mAsset: [] + }; } - } else { + } else if (typeof value !== "undefined") { if (colType === "mSelect" || colType === "select") { cellValue = { type: colType, @@ -178,6 +197,10 @@ export const genCellValue = (colType: TAVCol, value: string | any) => { relation: value }; } + } else { + cellValue = { + type: colType, + }; } if (colType === "block") { cellValue.isDetached = true; @@ -503,7 +526,7 @@ const updateCellValueByInput = (protyle: IProtyle, type: TAVCol, cellElements: H }); }; -export const updateCellsValue = (protyle: IProtyle, nodeElement: HTMLElement, value: string | any = "", cElements?: HTMLElement[]) => { +export const updateCellsValue = (protyle: IProtyle, nodeElement: HTMLElement, value?: any, cElements?: HTMLElement[]) => { const doOperations: IOperation[] = []; const undoOperations: IOperation[] = []; @@ -538,6 +561,24 @@ export const updateCellsValue = (protyle: IProtyle, nodeElement: HTMLElement, va const colId = item.getAttribute("data-col-id"); text += getCellText(item); + const oldValue = genCellValueByElement(type, item); + // relation 为全部更新,以下类型为添加 + if (type === "mAsset") { + if (Array.isArray(value)) { + value = oldValue.mAsset.concat(value); + } else if (typeof value !== "undefined") { + // 不传入为删除,传入字符串不进行处理 + return; + } + } else if (type === "mSelect") { + // 不传入为删除 + if (typeof value === "string") { + value = oldValue.mSelect.concat({ + content: value, + color: (oldValue.mSelect.length + 1).toString() + }); + } + } const cellValue = genCellValue(type, value); doOperations.push({ action: "updateAttrViewCell", @@ -553,7 +594,7 @@ export const updateCellsValue = (protyle: IProtyle, nodeElement: HTMLElement, va avID, keyID: colId, rowID, - data: genCellValueByElement(type, item) + data: oldValue }); if (!hasClosestByClassName(cellElements[0], "custom-attr")) { updateAttrViewCellAnimation(item, cellValue); diff --git a/app/src/protyle/render/av/openMenuPanel.ts b/app/src/protyle/render/av/openMenuPanel.ts index ee53cfb49..2df254ca1 100644 --- a/app/src/protyle/render/av/openMenuPanel.ts +++ b/app/src/protyle/render/av/openMenuPanel.ts @@ -23,7 +23,7 @@ import {previewImage} from "../../preview/image"; import {assetMenu} from "../../../menus/protyle"; import {addView, bindViewEvent, getSwitcherHTML, getViewHTML, openViewMenu} from "./view"; import {removeBlock} from "../../wysiwyg/remove"; -import {getEditorRange} from "../../util/selection"; +import {focusBlock, getEditorRange} from "../../util/selection"; import {avRender} from "./render"; import {setPageSize} from "./row"; import {bindRelationEvent, getRelationHTML, openSearchAV, setRelationCell, updateRelation} from "./relation"; @@ -394,6 +394,7 @@ export const openMenuPanel = (options: { window.siyuan.menus.menu.remove(); } else { avPanelElement.remove(); + focusBlock(options.blockElement); } window.siyuan.menus.menu.remove(); event.preventDefault(); diff --git a/app/src/protyle/upload/index.ts b/app/src/protyle/upload/index.ts index 896c0cd50..72ac0d862 100644 --- a/app/src/protyle/upload/index.ts +++ b/app/src/protyle/upload/index.ts @@ -8,6 +8,7 @@ import {pathPosix} from "../../util/pathName"; import {genAssetHTML} from "../../asset/renderAssets"; import {hasClosestBlock} from "../util/hasClosest"; import {getContenteditableElement} from "../wysiwyg/getBlock"; +import {updateCellsValue} from "../render/av/cell"; export class Upload { public element: HTMLElement; @@ -119,11 +120,18 @@ const genUploadedLabel = (responseText: string, protyle: IProtyle) => { } let succFileText = ""; const keys = Object.keys(response.data.succMap); + const avAssets: IAVCellAssetValue[] = []; keys.forEach((key, index) => { const path = response.data.succMap[key]; const type = pathPosix().extname(key).toLowerCase(); const filename = protyle.options.upload.filename(key); - succFileText += genAssetHTML(type, path, filename.substring(0, filename.length - type.length), filename); + const name = filename.substring(0, filename.length - type.length) + avAssets.push({ + type: Constants.SIYUAN_ASSETS_IMAGE.includes(type) ? "image" : "file", + content: path, + name: name + }) + succFileText += genAssetHTML(type, path, name, filename); if (!Constants.SIYUAN_ASSETS_AUDIO.includes(type) && !Constants.SIYUAN_ASSETS_VIDEO.includes(type) && keys.length - 1 !== index) { if (nodeElement && nodeElement.classList.contains("table")) { @@ -135,8 +143,12 @@ const genUploadedLabel = (responseText: string, protyle: IProtyle) => { } } }); - // 避免插入代码块中,其次因为都要独立成块 https://github.com/siyuan-note/siyuan/issues/7607 - insertHTML(succFileText, protyle, insertBlock); + if (nodeElement && nodeElement.classList.contains("av")) { + updateCellsValue(protyle, nodeElement, avAssets); + } else { + // 避免插入代码块中,其次因为都要独立成块 https://github.com/siyuan-note/siyuan/issues/7607 + insertHTML(succFileText, protyle, insertBlock); + } }; export const uploadLocalFiles = (files: string[], protyle: IProtyle, isUpload: boolean) => { @@ -159,15 +171,15 @@ export const uploadFiles = (protyle: IProtyle, files: FileList | DataTransferIte formData.append("file[]", files[i] as File); } const xhr = new XMLHttpRequest(); - xhr.open("POST", Constants.UPLOAD_ADDRESS); + xhr.open("POST", Constants.UPLOAD_ADDRESS); xhr.onreadystatechange = () => { if (xhr.readyState === XMLHttpRequest.DONE) { if (xhr.status === 200) { - successCB(xhr.responseText); + successCB(xhr.responseText); } else if (xhr.status === 0) { showMessage(window.siyuan.languages.fileTypeError); } else { - showMessage(xhr.responseText); + showMessage(xhr.responseText); } if (element) { element.value = ""; diff --git a/app/src/protyle/util/insertHTML.ts b/app/src/protyle/util/insertHTML.ts index 36a4a7edd..187af3e5b 100644 --- a/app/src/protyle/util/insertHTML.ts +++ b/app/src/protyle/util/insertHTML.ts @@ -8,12 +8,16 @@ import {Constants} from "../../constants"; import {highlightRender} from "../render/highlightRender"; import {scrollCenter} from "../../util/highlightById"; import {updateAVName} from "../render/av/action"; -import {readText} from "./compatibility"; import {updateCellsValue} from "../render/av/cell"; -const processAV = (range: Range, text: string, protyle: IProtyle, blockElement: Element) => { - if (blockElement.querySelector(".av__cell--select, .av__row--select")) { +const processAV = (range: Range, html: string, protyle: IProtyle, blockElement: Element) => { + const text = protyle.lute.BlockDOM2StdMd(html); + const cellsElement: HTMLElement[] = Array.from(blockElement.querySelectorAll(".av__cell--select")); + const rowsElement = blockElement.querySelector(".av__row--select"); + if (rowsElement) { updateCellsValue(protyle, blockElement as HTMLElement, text); + } else if (cellsElement.length > 0) { + updateCellsValue(protyle, blockElement as HTMLElement, text, cellsElement); } else { range.insertNode(document.createTextNode(text)); range.collapse(false); @@ -52,14 +56,7 @@ export const insertHTML = (html: string, protyle: IProtyle, isBlock = false, } if (blockElement.classList.contains("av")) { range.deleteContents(); - const text = readText(); - if (typeof text === "string") { - processAV(range, text, protyle, blockElement); - } else { - text.then((t) => { - processAV(range, t, protyle, blockElement); - }); - } + processAV(range, html, protyle, blockElement); return; } let id = blockElement.getAttribute("data-node-id");