This commit is contained in:
Vanessa 2023-10-01 10:26:31 +08:00
parent 05cfcf7c2b
commit 64900706b2
13 changed files with 119 additions and 58 deletions

View File

@ -125,7 +125,7 @@ export class Menu {
this.element.lastElementChild.append(element); this.element.lastElementChild.append(element);
} }
public popup(options: { x: number, y: number, h?: number, w?: number }, isLeft = false) { public popup(options: IPosition, isLeft = false) {
if (this.element.lastElementChild.innerHTML === "") { if (this.element.lastElementChild.innerHTML === "") {
return; return;
} }

View File

@ -27,10 +27,7 @@ openWindow = () => {
}; };
/// #else /// #else
openWindow = (options: { openWindow = (options: {
position?: { position?: IPosition,
x: number,
y: number,
},
height?: number, height?: number,
width?: number, width?: number,
tab?: Tab, tab?: Tab,

View File

@ -41,7 +41,7 @@ export class Menu {
this.menu.addSeparator(index); this.menu.addSeparator(index);
} }
open(options: { x: number, y: number, h?: number, w?: number, isLeft?: boolean }) { open(options:IPosition) {
if (this.isOpen) { if (this.isOpen) {
return; return;
} }

View File

@ -240,7 +240,7 @@ export class Breadcrumb {
} }
} }
public showMenu(protyle: IProtyle, position: { x: number, y: number }) { public showMenu(protyle: IProtyle, position:IPosition) {
if (!window.siyuan.menus.menu.element.classList.contains("fn__none") && if (!window.siyuan.menus.menu.element.classList.contains("fn__none") &&
window.siyuan.menus.menu.element.getAttribute("data-name") === "breadcrumbMore") { window.siyuan.menus.menu.element.getAttribute("data-name") === "breadcrumbMore") {
window.siyuan.menus.menu.remove(); window.siyuan.menus.menu.remove();

View File

@ -698,6 +698,7 @@ export class Gutter {
protyle.toolbar.subElement.style.width = ""; protyle.toolbar.subElement.style.width = "";
protyle.toolbar.subElement.style.padding = ""; protyle.toolbar.subElement.style.padding = "";
protyle.toolbar.subElement.append(appearanceMenu(protyle, selectsElement)); protyle.toolbar.subElement.append(appearanceMenu(protyle, selectsElement));
protyle.toolbar.subElement.style.zIndex = (++window.siyuan.zIndex).toString();
protyle.toolbar.subElement.classList.remove("fn__none"); protyle.toolbar.subElement.classList.remove("fn__none");
protyle.toolbar.subElementCloseCB = undefined; protyle.toolbar.subElementCloseCB = undefined;
const position = selectsElement[0].getBoundingClientRect(); const position = selectsElement[0].getBoundingClientRect();
@ -1497,6 +1498,7 @@ export class Gutter {
protyle.toolbar.subElement.style.width = ""; protyle.toolbar.subElement.style.width = "";
protyle.toolbar.subElement.style.padding = ""; protyle.toolbar.subElement.style.padding = "";
protyle.toolbar.subElement.append(appearanceMenu(protyle, [nodeElement])); protyle.toolbar.subElement.append(appearanceMenu(protyle, [nodeElement]));
protyle.toolbar.subElement.style.zIndex = (++window.siyuan.zIndex).toString();
protyle.toolbar.subElement.classList.remove("fn__none"); protyle.toolbar.subElement.classList.remove("fn__none");
protyle.toolbar.subElementCloseCB = undefined; protyle.toolbar.subElementCloseCB = undefined;
const position = nodeElement.getBoundingClientRect(); const position = nodeElement.getBoundingClientRect();

View File

@ -28,11 +28,7 @@ import {openNewWindowById} from "../../window/openNewWindow";
import {genImportMenu} from "../../menus/navigation"; import {genImportMenu} from "../../menus/navigation";
import {transferBlockRef} from "../../menus/block"; import {transferBlockRef} from "../../menus/block";
export const openTitleMenu = (protyle: IProtyle, position: { export const openTitleMenu = (protyle: IProtyle, position: IPosition) => {
x: number
y: number
isLeft?: boolean
}) => {
hideTooltip(); hideTooltip();
if (!window.siyuan.menus.menu.element.classList.contains("fn__none") && if (!window.siyuan.menus.menu.element.classList.contains("fn__none") &&
window.siyuan.menus.menu.element.getAttribute("data-name") === "titleMenu") { window.siyuan.menus.menu.element.getAttribute("data-name") === "titleMenu") {

View File

@ -600,7 +600,9 @@ ${genHintItemHTML(item)}
} else if (value === Constants.ZWSP + 2) { } else if (value === Constants.ZWSP + 2) {
range.deleteContents(); range.deleteContents();
this.fixImageCursor(range); this.fixImageCursor(range);
protyle.toolbar.showAssets(protyle, nodeElement, range); protyle.toolbar.range = range;
const rangePosition = getSelectionPosition(nodeElement, range);
protyle.toolbar.showAssets(protyle, {x: rangePosition.left, y: rangePosition.top + 26, w: 0, h: 26});
updateTransaction(protyle, id, nodeElement.outerHTML, html); updateTransaction(protyle, id, nodeElement.outerHTML, html);
return; return;
} else if (value === Constants.ZWSP + 3) { } else if (value === Constants.ZWSP + 3) {

View File

@ -84,6 +84,10 @@ ${contentHTML}
} }
return `<div class="b3-menu__items"> return `<div class="b3-menu__items">
${html} ${html}
<button data-type="addAssetExist" class="b3-menu__item">
<svg class="b3-menu__icon"><use xlink:href="#iconImage"></use></svg>
<span class="b3-menu__label">${window.siyuan.languages.assets}</span>
</button>
<button class="b3-menu__item"> <button class="b3-menu__item">
<svg class="b3-menu__icon"><use xlink:href="#iconDownload"></use></svg> <svg class="b3-menu__icon"><use xlink:href="#iconDownload"></use></svg>
<span class="b3-menu__label">${window.siyuan.languages.insertAsset}</span> <span class="b3-menu__label">${window.siyuan.languages.insertAsset}</span>
@ -314,8 +318,8 @@ export const addAssetLink = (protyle: IProtyle, data: IAV, cellElements: HTMLEle
const rect = target.getBoundingClientRect(); const rect = target.getBoundingClientRect();
menu.open({ menu.open({
x: rect.right, x: rect.right,
y: rect.top, y: rect.bottom,
w: rect.width, w: target.parentElement.clientWidth + 8,
h: rect.height, h: rect.height,
}); });
}; };

View File

@ -12,6 +12,8 @@ import {formatNumber} from "./number";
import {removeAttrViewColAnimation} from "./action"; import {removeAttrViewColAnimation} from "./action";
import {addAssetLink, bindAssetEvent, editAssetItem, getAssetHTML, updateAssetCell} from "./asset"; import {addAssetLink, bindAssetEvent, editAssetItem, getAssetHTML, updateAssetCell} from "./asset";
import {Constants} from "../../../constants"; import {Constants} from "../../../constants";
import {hideElements} from "../../ui/hideElements";
import {pathPosix} from "../../../util/pathName";
export const openMenuPanel = (options: { export const openMenuPanel = (options: {
protyle: IProtyle, protyle: IProtyle,
@ -322,7 +324,12 @@ export const openMenuPanel = (options: {
while (target && !target.isSameNode(avPanelElement)) { while (target && !target.isSameNode(avPanelElement)) {
const type = target.dataset.type; const type = target.dataset.type;
if (type === "close") { if (type === "close") {
avPanelElement.remove(); if (options.protyle.toolbar.subElement.className.includes("fn__none")) {
avPanelElement.remove();
} else {
// 优先关闭资源文件搜索
hideElements(["util"], options.protyle)
}
window.siyuan.menus.menu.remove(); window.siyuan.menus.menu.remove();
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
@ -672,6 +679,35 @@ export const openMenuPanel = (options: {
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
break; break;
} else if (type === "addAssetExist") {
const rect = target.getBoundingClientRect()
options.protyle.toolbar.showAssets(options.protyle, {x: rect.right, y: rect.bottom, w: target.parentElement.clientWidth + 8, h: rect.height}, (url) => {
let value: IAVCellAssetValue;
if (Constants.SIYUAN_ASSETS_IMAGE.includes(pathPosix().extname(url).toLowerCase())) {
value = {
type: "image",
content: url,
name: ""
}
} else {
value = {
type: "file",
content: url,
name: pathPosix().basename(url).substring(0, Constants.SIZE_LINK_TEXT_MAX)
}
}
updateAssetCell({
protyle: options.protyle,
data,
cellElements: options.cellElements,
type: "addUpdate",
addUpdateValue: [value]
});
hideElements(["util"], options.protyle);
});
event.preventDefault();
event.stopPropagation();
break;
} else if (type === "editAssetItem") { } else if (type === "editAssetItem") {
editAssetItem(options.protyle, data, options.cellElements, target.parentElement); editAssetItem(options.protyle, data, options.cellElements, target.parentElement);
event.preventDefault(); event.preventDefault();

View File

@ -18,6 +18,7 @@ export class Font extends ToolbarItem {
protyle.toolbar.subElement.style.width = ""; protyle.toolbar.subElement.style.width = "";
protyle.toolbar.subElement.style.padding = ""; protyle.toolbar.subElement.style.padding = "";
protyle.toolbar.subElement.append(appearanceMenu(protyle, getFontNodeElements(protyle))); protyle.toolbar.subElement.append(appearanceMenu(protyle, getFontNodeElements(protyle)));
protyle.toolbar.subElement.style.zIndex = (++window.siyuan.zIndex).toString();
protyle.toolbar.subElement.classList.remove("fn__none"); protyle.toolbar.subElement.classList.remove("fn__none");
protyle.toolbar.subElementCloseCB = undefined; protyle.toolbar.subElementCloseCB = undefined;
focusByRange(protyle.toolbar.range); focusByRange(protyle.toolbar.range);

View File

@ -1115,6 +1115,7 @@ export class Toolbar {
} }
updateTransaction(protyle, id, newHTML, html); updateTransaction(protyle, id, newHTML, html);
}; };
this.subElement.style.zIndex = (++window.siyuan.zIndex).toString();
this.subElement.classList.remove("fn__none"); this.subElement.classList.remove("fn__none");
const nodeRect = renderElement.getBoundingClientRect(); const nodeRect = renderElement.getBoundingClientRect();
this.element.classList.add("fn__none"); this.element.classList.add("fn__none");
@ -1255,6 +1256,7 @@ export class Toolbar {
focusByRange(this.range); focusByRange(this.range);
} }
}); });
this.subElement.style.zIndex = (++window.siyuan.zIndex).toString();
this.subElement.classList.remove("fn__none"); this.subElement.classList.remove("fn__none");
this.subElementCloseCB = undefined; this.subElementCloseCB = undefined;
/// #if !MOBILE /// #if !MOBILE
@ -1410,6 +1412,7 @@ export class Toolbar {
event.stopPropagation(); event.stopPropagation();
} }
}); });
this.subElement.style.zIndex = (++window.siyuan.zIndex).toString();
this.subElement.classList.remove("fn__none"); this.subElement.classList.remove("fn__none");
this.subElementCloseCB = undefined; this.subElementCloseCB = undefined;
this.element.classList.add("fn__none"); this.element.classList.add("fn__none");
@ -1490,6 +1493,7 @@ export class Toolbar {
} }
hintRenderWidget(listElement.textContent, protyle); hintRenderWidget(listElement.textContent, protyle);
}); });
this.subElement.style.zIndex = (++window.siyuan.zIndex).toString();
this.subElement.classList.remove("fn__none"); this.subElement.classList.remove("fn__none");
this.subElementCloseCB = undefined; this.subElementCloseCB = undefined;
this.element.classList.add("fn__none"); this.element.classList.add("fn__none");
@ -1511,8 +1515,25 @@ export class Toolbar {
}); });
} }
public showAssets(protyle: IProtyle, nodeElement: HTMLElement, range: Range) { private renderAssetList(listElement: Element, previewElement: Element, k: string, position: IPosition) {
this.range = range; fetchPost("/api/search/searchAsset", {
k,
}, (response) => {
let searchHTML = "";
response.data.forEach((item: { path: string, hName: string }, index: number) => {
searchHTML += `<div data-value="${item.path}" class="b3-list-item${index === 0 ? " b3-list-item--focus" : ""}"><div class="b3-list-item__text">${item.hName}</div></div>`;
});
listElement.innerHTML = searchHTML || `<li class="b3-list--empty">${window.siyuan.languages.emptyContent}</li>`;
if (response.data.length > 0) {
previewElement.innerHTML = renderAssetsPreview(response.data[0].path);
}
/// #if !MOBILE
setPosition(this.subElement, position.x, position.y, position.h, position.w);
/// #endif
});
}
public showAssets(protyle: IProtyle, position: IPosition, avCB?: (url: string) => void) {
hideElements(["hint"], protyle); hideElements(["hint"], protyle);
window.siyuan.menus.menu.remove(); window.siyuan.menus.menu.remove();
this.subElement.style.width = ""; this.subElement.style.width = "";
@ -1531,6 +1552,7 @@ export class Toolbar {
<div style="width: 260px;display: ${isMobile() || window.outerWidth < window.outerWidth / 2 + 260 ? "none" : "flex"};padding: 8px;overflow: auto;justify-content: center;align-items: center;"></div> <div style="width: 260px;display: ${isMobile() || window.outerWidth < window.outerWidth / 2 + 260 ? "none" : "flex"};padding: 8px;overflow: auto;justify-content: center;align-items: center;"></div>
</div>`; </div>`;
const listElement = this.subElement.querySelector(".b3-list"); const listElement = this.subElement.querySelector(".b3-list");
const previewElement = this.subElement.firstElementChild.lastElementChild;
listElement.addEventListener("mouseover", (event) => { listElement.addEventListener("mouseover", (event) => {
const target = event.target as HTMLElement; const target = event.target as HTMLElement;
const hoverItemElement = hasClosestByClassName(target, "b3-list-item"); const hoverItemElement = hasClosestByClassName(target, "b3-list-item");
@ -1539,15 +1561,13 @@ export class Toolbar {
} }
previewElement.innerHTML = renderAssetsPreview(hoverItemElement.getAttribute("data-value")); previewElement.innerHTML = renderAssetsPreview(hoverItemElement.getAttribute("data-value"));
}); });
const previewElement = this.subElement.firstElementChild.lastElementChild;
previewElement.innerHTML = renderAssetsPreview(listElement.firstElementChild.getAttribute("data-value"));
const inputElement = this.subElement.querySelector("input"); const inputElement = this.subElement.querySelector("input");
inputElement.addEventListener("keydown", (event: KeyboardEvent) => { inputElement.addEventListener("keydown", (event: KeyboardEvent) => {
event.stopPropagation(); event.stopPropagation();
if (event.isComposing) { if (event.isComposing) {
return; return;
} }
const isEmpty = !this.subElement.querySelector(".b3-list-item"); const isEmpty = this.subElement.querySelector(".b3-list--empty");
if (!isEmpty) { if (!isEmpty) {
const currentElement = upDownHint(listElement, event); const currentElement = upDownHint(listElement, event);
if (currentElement) { if (currentElement) {
@ -1557,8 +1577,13 @@ export class Toolbar {
if (event.key === "Enter") { if (event.key === "Enter") {
if (!isEmpty) { if (!isEmpty) {
hintRenderAssets(this.subElement.querySelector(".b3-list-item--focus").getAttribute("data-value"), protyle); const currentURL = this.subElement.querySelector(".b3-list-item--focus").getAttribute("data-value")
} else { if (avCB) {
avCB(currentURL)
} else {
hintRenderAssets(currentURL, protyle);
}
} else if (!avCB) {
focusByRange(this.range); focusByRange(this.range);
} }
this.subElement.classList.add("fn__none"); this.subElement.classList.add("fn__none");
@ -1566,21 +1591,14 @@ export class Toolbar {
event.preventDefault(); event.preventDefault();
} else if (event.key === "Escape") { } else if (event.key === "Escape") {
this.subElement.classList.add("fn__none"); this.subElement.classList.add("fn__none");
focusByRange(this.range); if (!avCB) {
focusByRange(this.range);
}
} }
}); });
inputElement.addEventListener("input", (event) => { inputElement.addEventListener("input", (event) => {
event.stopPropagation(); event.stopPropagation();
fetchPost("/api/search/searchAsset", { this.renderAssetList(listElement, previewElement, inputElement.value, position);
k: inputElement.value,
}, (response) => {
let searchHTML = "";
response.data.forEach((item: { path: string, hName: string }, index: number) => {
searchHTML += `<div data-value="${item.path}" class="b3-list-item${index === 0 ? " b3-list-item--focus" : ""}">${item.hName}</div>`;
});
listElement.innerHTML = searchHTML || `<li class="b3-list--empty">${window.siyuan.languages.emptyContent}</li>`;
previewElement.innerHTML = renderAssetsPreview(listElement.firstElementChild.getAttribute("data-value"));
});
}); });
this.subElement.lastElementChild.addEventListener("click", (event) => { this.subElement.lastElementChild.addEventListener("click", (event) => {
const target = event.target as HTMLElement; const target = event.target as HTMLElement;
@ -1598,38 +1616,32 @@ export class Toolbar {
} }
if (target.classList.contains("b3-list--empty")) { if (target.classList.contains("b3-list--empty")) {
this.subElement.classList.add("fn__none"); this.subElement.classList.add("fn__none");
focusByRange(this.range); if (!avCB) {
focusByRange(this.range);
}
event.stopPropagation(); event.stopPropagation();
return; return;
} }
const listItemElement = hasClosestByClassName(target, "b3-list-item"); const listItemElement = hasClosestByClassName(target, "b3-list-item");
if (listItemElement) { if (listItemElement) {
event.stopPropagation(); event.stopPropagation();
hintRenderAssets(listItemElement.getAttribute("data-value"), protyle); const currentURL = listItemElement.getAttribute("data-value")
if (avCB) {
avCB(currentURL)
} else {
hintRenderAssets(currentURL, protyle);
}
} }
}); });
this.subElement.style.zIndex = (++window.siyuan.zIndex).toString();
this.subElement.classList.remove("fn__none"); this.subElement.classList.remove("fn__none");
this.subElementCloseCB = undefined; this.subElementCloseCB = undefined;
/// #if !MOBILE /// #if MOBILE
const rangePosition = getSelectionPosition(nodeElement, range);
setPosition(this.subElement, rangePosition.left, rangePosition.top + 18, Constants.SIZE_TOOLBAR_HEIGHT);
/// #else
setPosition(this.subElement, 0, 0); setPosition(this.subElement, 0, 0);
/// #endif /// #endif
this.element.classList.add("fn__none"); this.element.classList.add("fn__none");
inputElement.select(); inputElement.select();
fetchPost("/api/search/searchAsset", { this.renderAssetList(listElement, previewElement, "", position);
k: "",
}, (response) => {
let html = "";
response.data.forEach((item: { hName: string, path: string }, index: number) => {
html += `<div data-value="${item.path}" class="b3-list-item${index === 0 ? " b3-list-item--focus" : ""}"><div class="b3-list-item__text">${item.hName}</div></div>`;
});
if (html === "") {
html = `<li class="b3-list--empty">${window.siyuan.languages.emptyContent}</li>`;
}
this.subElement.querySelector(".b3-list--background").innerHTML = html;
});
} }
public showContent(protyle: IProtyle, range: Range, nodeElement: Element) { public showContent(protyle: IProtyle, range: Range, nodeElement: Element) {
@ -1721,6 +1733,7 @@ export class Toolbar {
setPosition(this.subElement, rangePosition.left, rangePosition.top + 28, Constants.SIZE_TOOLBAR_HEIGHT); setPosition(this.subElement, rangePosition.left, rangePosition.top + 28, Constants.SIZE_TOOLBAR_HEIGHT);
} }
}); });
this.subElement.style.zIndex = (++window.siyuan.zIndex).toString();
this.subElement.classList.remove("fn__none"); this.subElement.classList.remove("fn__none");
this.subElementCloseCB = undefined; this.subElementCloseCB = undefined;
this.element.classList.add("fn__none"); this.element.classList.add("fn__none");

View File

@ -1,7 +1,7 @@
/// #if MOBILE /// #if MOBILE
import {getCurrentEditor} from "../../mobile/editor"; import {getCurrentEditor} from "../../mobile/editor";
/// #else /// #else
import {getAllModels} from "../../layout/getAll"; import {getAllEditor} from "../../layout/getAll";
/// #endif /// #endif
// "gutter", "toolbar", "select", "hint", "util", "dialog" // "gutter", "toolbar", "select", "hint", "util", "dialog"
@ -67,11 +67,13 @@ export const hideAllElements = (types: string[]) => {
editor.protyle.toolbar.subElementCloseCB = undefined; editor.protyle.toolbar.subElementCloseCB = undefined;
} }
/// #else /// #else
getAllModels().editor.forEach(item => { getAllEditor().forEach(item => {
item.editor.protyle.toolbar.subElement.classList.add("fn__none"); if (item.protyle.toolbar) {
if (item.editor.protyle.toolbar.subElementCloseCB) { item.protyle.toolbar.subElement.classList.add("fn__none");
item.editor.protyle.toolbar.subElementCloseCB(); if (item.protyle.toolbar.subElementCloseCB) {
item.editor.protyle.toolbar.subElementCloseCB = undefined; item.protyle.toolbar.subElementCloseCB();
item.protyle.toolbar.subElementCloseCB = undefined;
}
} }
}); });
/// #endif /// #endif

View File

@ -152,6 +152,14 @@ interface Window {
openFileByURL(URL: string): boolean openFileByURL(URL: string): boolean
} }
interface IPosition {
x: number,
y: number,
w?: number,
h?: number,
isLeft?: boolean
}
interface ISaveLayout { interface ISaveLayout {
name: string, name: string,
layout: IObject layout: IObject