diff --git a/app/src/protyle/render/av/action.ts b/app/src/protyle/render/av/action.ts
index 227693847..ea074d250 100644
--- a/app/src/protyle/render/av/action.ts
+++ b/app/src/protyle/render/av/action.ts
@@ -579,8 +579,11 @@ export const avContextmenu = (protyle: IProtyle, rowElement: HTMLElement, positi
sourceIds.push(rowId);
});
const avID = listItemElement.dataset.avId;
+ const viewID = listItemElement.dataset.viewId;
transaction(protyle, [{
action: "insertAttrViewBlock",
+ ignoreDefaultFill: viewID ? false : true,
+ viewID,
avID,
srcs,
context: {ignoreTip: "true"},
diff --git a/app/src/protyle/render/av/addToDatabase.ts b/app/src/protyle/render/av/addToDatabase.ts
index b89249034..ba258c2ad 100644
--- a/app/src/protyle/render/av/addToDatabase.ts
+++ b/app/src/protyle/render/av/addToDatabase.ts
@@ -19,8 +19,11 @@ export const addFilesToDatabase = (fileLiElements: Element[]) => {
if (srcs.length > 0) {
openSearchAV("", fileLiElements[0] as HTMLElement, (listItemElement) => {
const avID = listItemElement.dataset.avId;
+ const viewID = listItemElement.dataset.viewId;
transaction(undefined, [{
action: "insertAttrViewBlock",
+ ignoreDefaultFill: viewID ? false : true,
+ viewID,
avID,
srcs,
blockID: listItemElement.dataset.blockId
@@ -37,8 +40,11 @@ export const addEditorToDatabase = (protyle: IProtyle, range: Range, type?: stri
if ((range && protyle.title?.editElement?.contains(range.startContainer)) || type === "title") {
openSearchAV("", protyle.breadcrumb.element, (listItemElement) => {
const avID = listItemElement.dataset.avId;
+ const viewID = listItemElement.dataset.viewId;
transaction(protyle, [{
action: "insertAttrViewBlock",
+ ignoreDefaultFill: viewID ? false : true,
+ viewID,
avID,
srcs: [{
itemID: Lute.NewNodeID(),
@@ -89,8 +95,11 @@ export const addEditorToDatabase = (protyle: IProtyle, range: Range, type?: stri
});
});
const avID = listItemElement.dataset.avId;
+ const viewID = listItemElement.dataset.viewId;
transaction(protyle, [{
action: "insertAttrViewBlock",
+ ignoreDefaultFill: viewID ? false : true,
+ viewID,
avID,
srcs,
blockID: listItemElement.dataset.blockId
diff --git a/app/src/protyle/render/av/relation.ts b/app/src/protyle/render/av/relation.ts
index 401df9380..8292c7226 100644
--- a/app/src/protyle/render/av/relation.ts
+++ b/app/src/protyle/render/av/relation.ts
@@ -1,6 +1,6 @@
import {Menu} from "../../../plugin/Menu";
import {hasClosestByClassName, hasTopClosestByClassName} from "../../util/hasClosest";
-import {upDownHint} from "../../../util/upDownHint";
+import {UDLRHint, upDownHint} from "../../../util/upDownHint";
import {fetchPost} from "../../../util/fetch";
import {escapeGreat, escapeHtml} from "../../../util/escape";
import {transaction} from "../../wysiwyg/transaction";
@@ -12,6 +12,16 @@ import * as dayjs from "dayjs";
import {getFieldsByData} from "./view";
import {getColId} from "./col";
import {getFieldIdByCellElement} from "./row";
+import {isMobile} from "../../../util/functions";
+
+interface IAVItem {
+ avID: string;
+ avName: string;
+ blockID: string;
+ hPath: string;
+ viewName: string;
+ viewID: string;
+}
const genSearchList = (element: Element, keyword: string, avId?: string, excludes = true, cb?: () => void) => {
fetchPost("/api/av/searchAttributeView", {
@@ -19,13 +29,13 @@ const genSearchList = (element: Element, keyword: string, avId?: string, exclude
excludes: (excludes && avId) ? [avId] : undefined
}, (response) => {
let html = "";
- response.data.results.forEach((item: {
- avID: string
- avName: string
- blockID: string
- hPath: string
- }, index: number) => {
+ response.data.results.forEach((item: IAVItem & { children: IAVItem[] }, index: number) => {
+ const hasChildren = item.children && item.children.length > 0 && excludes;
html += `
+
+
+
+
${escapeHtml(item.avName || window.siyuan.languages._kernel[267])}
@@ -34,6 +44,16 @@ const genSearchList = (element: Element, keyword: string, avId?: string, exclude
`;
+ if (hasChildren) {
+ html += '
';
+ item.children.forEach((subItem) => {
+ html += `
+${escapeHtml(subItem.avName || window.siyuan.languages._kernel[267])}
+${escapeHtml(subItem.viewName)}
+
`;
+ });
+ html += "
";
+ }
});
element.innerHTML = html;
if (cb) {
@@ -58,7 +78,7 @@ export const openSearchAV = (avId: string, target: HTMLElement, cb?: (element: H
menu.addItem({
iconHTML: "",
type: "empty",
- label: `
+ label: `
@@ -72,10 +92,7 @@ export const openSearchAV = (avId: string, target: HTMLElement, cb?: (element: H
if (event.isComposing) {
return;
}
- const currentElement = upDownHint(listElement, event);
- if (currentElement) {
- event.stopPropagation();
- }
+ UDLRHint(listElement, event);
if (event.key === "Enter") {
event.preventDefault();
event.stopPropagation();
@@ -99,15 +116,31 @@ export const openSearchAV = (avId: string, target: HTMLElement, cb?: (element: H
genSearchList(listElement, inputElement.value, avId, excludes);
});
element.lastElementChild.addEventListener("click", (event) => {
- const listItemElement = hasClosestByClassName(event.target as HTMLElement, "b3-list-item");
- if (listItemElement) {
- event.stopPropagation();
- if (cb) {
- cb(listItemElement);
- } else {
- setDatabase(avId, target, listItemElement);
+ let clickTarget = event.target as HTMLElement;
+ while (clickTarget && !clickTarget.classList.contains("b3-list")) {
+ if (clickTarget.classList.contains("b3-list-item__toggle")) {
+ if (clickTarget.firstElementChild.classList.contains("b3-list-item__arrow--open")) {
+ clickTarget.firstElementChild.classList.remove("b3-list-item__arrow--open");
+ clickTarget.parentElement.nextElementSibling.classList.add("fn__none");
+ } else {
+ clickTarget.firstElementChild.classList.add("b3-list-item__arrow--open");
+ clickTarget.parentElement.nextElementSibling.classList.remove("fn__none");
+ }
+ event.preventDefault();
+ event.stopPropagation();
+ break;
+ } else if (clickTarget.classList.contains("b3-list-item")) {
+ event.preventDefault();
+ event.stopPropagation();
+ if (cb) {
+ cb(clickTarget);
+ } else {
+ setDatabase(avId, target, clickTarget);
+ }
+ window.siyuan.menus.menu.remove();
+ break;
}
- window.siyuan.menus.menu.remove();
+ clickTarget = clickTarget.parentElement;
}
});
genSearchList(listElement, "", avId, excludes, () => {
diff --git a/app/src/types/index.d.ts b/app/src/types/index.d.ts
index f62cf75bb..97708626f 100644
--- a/app/src/types/index.d.ts
+++ b/app/src/types/index.d.ts
@@ -547,6 +547,8 @@ interface IOperation {
isDetached?: boolean // insertAttrViewBlock 专享
srcIDs?: string[] // removeAttrViewBlock 专享
srcs?: IOperationSrcs[] // insertAttrViewBlock 专享
+ ignoreDefaultFill?: boolean // insertAttrViewBlock 专享
+ viewID?: string // insertAttrViewBlock 专享
name?: string // addAttrViewCol 专享
type?: TAVCol // addAttrViewCol 专享
deckID?: string // add/removeFlashcards 专享
diff --git a/app/src/util/upDownHint.ts b/app/src/util/upDownHint.ts
index 16522d288..0e6614b6e 100644
--- a/app/src/util/upDownHint.ts
+++ b/app/src/util/upDownHint.ts
@@ -95,3 +95,138 @@ export const upDownHint = (listElement: Element, event: KeyboardEvent, classActi
return currentHintElement;
}
};
+
+export const UDLRHint = (listElement: Element, event: KeyboardEvent, classActiveName = "b3-list-item--focus", defaultElement?: Element) => {
+ let currentHintElement: HTMLElement = listElement.querySelector("." + classActiveName);
+ if (!currentHintElement && defaultElement) {
+ defaultElement.classList.add(classActiveName);
+ defaultElement.scrollIntoView(true);
+ return;
+ }
+ if (!currentHintElement) {
+ return;
+ }
+ const className = classActiveName.split("--")[0];
+ if (event.key === "ArrowLeft") {
+ event.preventDefault();
+ event.stopPropagation();
+ currentHintElement.classList.remove(classActiveName);
+ if (currentHintElement.parentElement.classList.contains("b3-list")) {
+ if (currentHintElement.querySelector(".b3-list-item__arrow--open")) {
+ currentHintElement.querySelector(".b3-list-item__arrow--open").classList.remove("b3-list-item__arrow--open");
+ currentHintElement.nextElementSibling.classList.add("fn__none");
+ } else {
+ currentHintElement = listElement.firstElementChild as HTMLElement;
+ }
+ } else {
+ currentHintElement = currentHintElement.parentElement.previousElementSibling as HTMLElement;
+ }
+ currentHintElement.classList.add(classActiveName);
+ const overTop = listElement.scrollTop > currentHintElement.offsetTop - 46 - (currentHintElement.previousElementSibling?.clientHeight || 0);
+ if (listElement.scrollTop < currentHintElement.offsetTop - 46 - listElement.clientHeight + currentHintElement.clientHeight || overTop) {
+ currentHintElement.scrollIntoView(overTop);
+ }
+ return currentHintElement;
+ } else if (event.key === "ArrowRight") {
+ event.preventDefault();
+ event.stopPropagation();
+ currentHintElement.classList.remove(classActiveName);
+ if (currentHintElement.parentElement.classList.contains("b3-list")) {
+ if (currentHintElement.querySelector(".b3-list-item__arrow--open")) {
+ currentHintElement = currentHintElement.nextElementSibling.firstElementChild as HTMLElement;
+ } else {
+ currentHintElement.querySelector(".b3-list-item__arrow").classList.add("b3-list-item__arrow--open");
+ currentHintElement.nextElementSibling.classList.remove("fn__none");
+ }
+ } else {
+ if (!currentHintElement.nextElementSibling) {
+ if (currentHintElement.parentElement.nextElementSibling) {
+ currentHintElement = currentHintElement.parentElement.nextElementSibling as HTMLElement;
+ }
+ } else {
+ currentHintElement = currentHintElement.nextElementSibling as HTMLElement;
+ }
+ }
+ currentHintElement.classList.add(classActiveName);
+ if (listElement.scrollTop < currentHintElement.offsetTop - 46 - listElement.clientHeight + currentHintElement.clientHeight ||
+ listElement.scrollTop > currentHintElement.offsetTop - 46) {
+ currentHintElement.scrollIntoView(listElement.scrollTop > currentHintElement.offsetTop - 46);
+ }
+ return currentHintElement;
+ } else if (event.key === "ArrowDown") {
+ event.preventDefault();
+ event.stopPropagation();
+ currentHintElement.classList.remove(classActiveName);
+ if (!currentHintElement.nextElementSibling) {
+ currentHintElement = currentHintElement.parentElement.nextElementSibling as HTMLElement || listElement.firstElementChild as HTMLElement;
+ } else {
+ currentHintElement = currentHintElement.nextElementSibling as HTMLElement;
+ if (!currentHintElement.classList.contains(className)) {
+ if (currentHintElement.classList.contains("fn__none")) {
+ currentHintElement = currentHintElement.nextElementSibling as HTMLElement;
+ if (!currentHintElement) {
+ currentHintElement = listElement.firstElementChild as HTMLElement;
+ }
+ } else {
+ currentHintElement = currentHintElement.firstElementChild as HTMLElement;
+ }
+ }
+ }
+ currentHintElement.classList.add(classActiveName);
+ if (listElement.scrollTop < currentHintElement.offsetTop - 46 - listElement.clientHeight + currentHintElement.clientHeight ||
+ listElement.scrollTop > currentHintElement.offsetTop - 46) {
+ currentHintElement.scrollIntoView(listElement.scrollTop > currentHintElement.offsetTop - 46);
+ }
+ return currentHintElement;
+ } else if (event.key === "ArrowUp") {
+ event.preventDefault();
+ event.stopPropagation();
+ currentHintElement.classList.remove(classActiveName);
+ if (!currentHintElement.previousElementSibling) {
+ if (currentHintElement.parentElement.classList.contains("b3-list")) {
+ if (listElement.lastElementChild.classList.contains("fn__none")) {
+ currentHintElement = listElement.lastElementChild.previousElementSibling as HTMLElement;
+ } else {
+ currentHintElement = listElement.lastElementChild.lastElementChild as HTMLElement;
+ }
+ } else {
+ currentHintElement = currentHintElement.parentElement.previousElementSibling as HTMLElement;
+ }
+ } else {
+ currentHintElement = currentHintElement.previousElementSibling as HTMLElement;
+ if (!currentHintElement.classList.contains(className)) {
+ if (currentHintElement.classList.contains("fn__none")) {
+ currentHintElement = currentHintElement.previousElementSibling as HTMLElement;
+ } else {
+ currentHintElement = currentHintElement.lastElementChild as HTMLElement;
+ }
+ }
+ }
+ currentHintElement.classList.add(classActiveName);
+ const overTop = listElement.scrollTop > currentHintElement.offsetTop - 46 - (currentHintElement.previousElementSibling?.clientHeight || 0);
+ if (listElement.scrollTop < currentHintElement.offsetTop - 46 - listElement.clientHeight + currentHintElement.clientHeight || overTop) {
+ currentHintElement.scrollIntoView(overTop);
+ }
+ return currentHintElement;
+ } else if (event.key === "Home") {
+ event.preventDefault();
+ event.stopPropagation();
+ currentHintElement.classList.remove(classActiveName);
+ currentHintElement = listElement.children[0] as HTMLElement;
+ currentHintElement.classList.add(classActiveName);
+ currentHintElement.scrollIntoView();
+ return currentHintElement;
+ } else if (event.key === "End") {
+ event.preventDefault();
+ event.stopPropagation();
+ currentHintElement.classList.remove(classActiveName);
+ if (listElement.lastElementChild.classList.contains("fn__none")) {
+ currentHintElement = listElement.lastElementChild.previousElementSibling as HTMLElement;
+ } else {
+ currentHintElement = listElement.lastElementChild.lastElementChild as HTMLElement;
+ }
+ currentHintElement.classList.add(classActiveName);
+ currentHintElement.scrollIntoView(false);
+ return currentHintElement;
+ }
+};