mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-09-22 00:20:47 +02:00
Compare commits
4 commits
bc08148dab
...
ca9427cc82
Author | SHA1 | Date | |
---|---|---|---|
![]() |
ca9427cc82 | ||
![]() |
e775d0b5f8 | ||
![]() |
2535a64ff1 | ||
![]() |
b2ad366da3 |
5 changed files with 202 additions and 20 deletions
|
@ -579,8 +579,11 @@ export const avContextmenu = (protyle: IProtyle, rowElement: HTMLElement, positi
|
||||||
sourceIds.push(rowId);
|
sourceIds.push(rowId);
|
||||||
});
|
});
|
||||||
const avID = listItemElement.dataset.avId;
|
const avID = listItemElement.dataset.avId;
|
||||||
|
const viewID = listItemElement.dataset.viewId;
|
||||||
transaction(protyle, [{
|
transaction(protyle, [{
|
||||||
action: "insertAttrViewBlock",
|
action: "insertAttrViewBlock",
|
||||||
|
ignoreDefaultFill: viewID ? false : true,
|
||||||
|
viewID,
|
||||||
avID,
|
avID,
|
||||||
srcs,
|
srcs,
|
||||||
context: {ignoreTip: "true"},
|
context: {ignoreTip: "true"},
|
||||||
|
|
|
@ -19,8 +19,11 @@ export const addFilesToDatabase = (fileLiElements: Element[]) => {
|
||||||
if (srcs.length > 0) {
|
if (srcs.length > 0) {
|
||||||
openSearchAV("", fileLiElements[0] as HTMLElement, (listItemElement) => {
|
openSearchAV("", fileLiElements[0] as HTMLElement, (listItemElement) => {
|
||||||
const avID = listItemElement.dataset.avId;
|
const avID = listItemElement.dataset.avId;
|
||||||
|
const viewID = listItemElement.dataset.viewId;
|
||||||
transaction(undefined, [{
|
transaction(undefined, [{
|
||||||
action: "insertAttrViewBlock",
|
action: "insertAttrViewBlock",
|
||||||
|
ignoreDefaultFill: viewID ? false : true,
|
||||||
|
viewID,
|
||||||
avID,
|
avID,
|
||||||
srcs,
|
srcs,
|
||||||
blockID: listItemElement.dataset.blockId
|
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") {
|
if ((range && protyle.title?.editElement?.contains(range.startContainer)) || type === "title") {
|
||||||
openSearchAV("", protyle.breadcrumb.element, (listItemElement) => {
|
openSearchAV("", protyle.breadcrumb.element, (listItemElement) => {
|
||||||
const avID = listItemElement.dataset.avId;
|
const avID = listItemElement.dataset.avId;
|
||||||
|
const viewID = listItemElement.dataset.viewId;
|
||||||
transaction(protyle, [{
|
transaction(protyle, [{
|
||||||
action: "insertAttrViewBlock",
|
action: "insertAttrViewBlock",
|
||||||
|
ignoreDefaultFill: viewID ? false : true,
|
||||||
|
viewID,
|
||||||
avID,
|
avID,
|
||||||
srcs: [{
|
srcs: [{
|
||||||
itemID: Lute.NewNodeID(),
|
itemID: Lute.NewNodeID(),
|
||||||
|
@ -89,8 +95,11 @@ export const addEditorToDatabase = (protyle: IProtyle, range: Range, type?: stri
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
const avID = listItemElement.dataset.avId;
|
const avID = listItemElement.dataset.avId;
|
||||||
|
const viewID = listItemElement.dataset.viewId;
|
||||||
transaction(protyle, [{
|
transaction(protyle, [{
|
||||||
action: "insertAttrViewBlock",
|
action: "insertAttrViewBlock",
|
||||||
|
ignoreDefaultFill: viewID ? false : true,
|
||||||
|
viewID,
|
||||||
avID,
|
avID,
|
||||||
srcs,
|
srcs,
|
||||||
blockID: listItemElement.dataset.blockId
|
blockID: listItemElement.dataset.blockId
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import {Menu} from "../../../plugin/Menu";
|
import {Menu} from "../../../plugin/Menu";
|
||||||
import {hasClosestByClassName, hasTopClosestByClassName} from "../../util/hasClosest";
|
import {hasClosestByClassName, hasTopClosestByClassName} from "../../util/hasClosest";
|
||||||
import {upDownHint} from "../../../util/upDownHint";
|
import {UDLRHint, upDownHint} from "../../../util/upDownHint";
|
||||||
import {fetchPost} from "../../../util/fetch";
|
import {fetchPost} from "../../../util/fetch";
|
||||||
import {escapeGreat, escapeHtml} from "../../../util/escape";
|
import {escapeGreat, escapeHtml} from "../../../util/escape";
|
||||||
import {transaction} from "../../wysiwyg/transaction";
|
import {transaction} from "../../wysiwyg/transaction";
|
||||||
|
@ -12,6 +12,16 @@ import * as dayjs from "dayjs";
|
||||||
import {getFieldsByData} from "./view";
|
import {getFieldsByData} from "./view";
|
||||||
import {getColId} from "./col";
|
import {getColId} from "./col";
|
||||||
import {getFieldIdByCellElement} from "./row";
|
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) => {
|
const genSearchList = (element: Element, keyword: string, avId?: string, excludes = true, cb?: () => void) => {
|
||||||
fetchPost("/api/av/searchAttributeView", {
|
fetchPost("/api/av/searchAttributeView", {
|
||||||
|
@ -19,13 +29,13 @@ const genSearchList = (element: Element, keyword: string, avId?: string, exclude
|
||||||
excludes: (excludes && avId) ? [avId] : undefined
|
excludes: (excludes && avId) ? [avId] : undefined
|
||||||
}, (response) => {
|
}, (response) => {
|
||||||
let html = "";
|
let html = "";
|
||||||
response.data.results.forEach((item: {
|
response.data.results.forEach((item: IAVItem & { children: IAVItem[] }, index: number) => {
|
||||||
avID: string
|
const hasChildren = item.children && item.children.length > 0 && excludes;
|
||||||
avName: string
|
|
||||||
blockID: string
|
|
||||||
hPath: string
|
|
||||||
}, index: number) => {
|
|
||||||
html += `<div class="b3-list-item b3-list-item--narrow${index === 0 ? " b3-list-item--focus" : ""}" data-av-id="${item.avID}" data-block-id="${item.blockID}">
|
html += `<div class="b3-list-item b3-list-item--narrow${index === 0 ? " b3-list-item--focus" : ""}" data-av-id="${item.avID}" data-block-id="${item.blockID}">
|
||||||
|
<span class="b3-list-item__toggle b3-list-item__toggle--hl${excludes ? "" : " fn__none"}" style="align-self: flex-start;margin-top: 4px;">
|
||||||
|
<svg class="b3-list-item__arrow">${hasChildren ? '<use xlink:href="#iconRight"></use>' : ""}</svg>
|
||||||
|
</span>
|
||||||
|
<span class="fn__space"></span>
|
||||||
<div class="b3-list-item--two fn__flex-1">
|
<div class="b3-list-item--two fn__flex-1">
|
||||||
<div class="b3-list-item__first">
|
<div class="b3-list-item__first">
|
||||||
<span class="b3-list-item__text">${escapeHtml(item.avName || window.siyuan.languages._kernel[267])}</span>
|
<span class="b3-list-item__text">${escapeHtml(item.avName || window.siyuan.languages._kernel[267])}</span>
|
||||||
|
@ -34,6 +44,16 @@ const genSearchList = (element: Element, keyword: string, avId?: string, exclude
|
||||||
</div>
|
</div>
|
||||||
<svg aria-label="${window.siyuan.languages.thisDatabase}" style="margin: 0 0 0 4px" class="b3-list-item__hinticon ariaLabel${item.avID === avId ? "" : " fn__none"}"><use xlink:href="#iconInfo"></use></svg>
|
<svg aria-label="${window.siyuan.languages.thisDatabase}" style="margin: 0 0 0 4px" class="b3-list-item__hinticon ariaLabel${item.avID === avId ? "" : " fn__none"}"><use xlink:href="#iconInfo"></use></svg>
|
||||||
</div>`;
|
</div>`;
|
||||||
|
if (hasChildren) {
|
||||||
|
html += '<div class="fn__none">';
|
||||||
|
item.children.forEach((subItem) => {
|
||||||
|
html += `<div style="padding-left: 48px;" class="b3-list-item b3-list-item--narrow" data-av-id="${subItem.avID}" data-view-id="${subItem.viewID}">
|
||||||
|
<span class="b3-list-item__text">${escapeHtml(subItem.avName || window.siyuan.languages._kernel[267])}</span>
|
||||||
|
<span class="b3-list-item__meta">${escapeHtml(subItem.viewName)}</span>
|
||||||
|
</div>`;
|
||||||
|
});
|
||||||
|
html += "</div>";
|
||||||
|
}
|
||||||
});
|
});
|
||||||
element.innerHTML = html;
|
element.innerHTML = html;
|
||||||
if (cb) {
|
if (cb) {
|
||||||
|
@ -58,7 +78,7 @@ export const openSearchAV = (avId: string, target: HTMLElement, cb?: (element: H
|
||||||
menu.addItem({
|
menu.addItem({
|
||||||
iconHTML: "",
|
iconHTML: "",
|
||||||
type: "empty",
|
type: "empty",
|
||||||
label: `<div class="fn__flex-column b3-menu__filter">
|
label: `<div class="fn__flex-column b3-menu__filter"${isMobile() ? "" : ' style="width: 50vw"'} >
|
||||||
<input class="b3-text-field fn__flex-shrink"/>
|
<input class="b3-text-field fn__flex-shrink"/>
|
||||||
<div class="fn__hr"></div>
|
<div class="fn__hr"></div>
|
||||||
<div class="b3-list fn__flex-1 b3-list--background">
|
<div class="b3-list fn__flex-1 b3-list--background">
|
||||||
|
@ -72,10 +92,7 @@ export const openSearchAV = (avId: string, target: HTMLElement, cb?: (element: H
|
||||||
if (event.isComposing) {
|
if (event.isComposing) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const currentElement = upDownHint(listElement, event);
|
UDLRHint(listElement, event);
|
||||||
if (currentElement) {
|
|
||||||
event.stopPropagation();
|
|
||||||
}
|
|
||||||
if (event.key === "Enter") {
|
if (event.key === "Enter") {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
@ -99,15 +116,31 @@ export const openSearchAV = (avId: string, target: HTMLElement, cb?: (element: H
|
||||||
genSearchList(listElement, inputElement.value, avId, excludes);
|
genSearchList(listElement, inputElement.value, avId, excludes);
|
||||||
});
|
});
|
||||||
element.lastElementChild.addEventListener("click", (event) => {
|
element.lastElementChild.addEventListener("click", (event) => {
|
||||||
const listItemElement = hasClosestByClassName(event.target as HTMLElement, "b3-list-item");
|
let clickTarget = event.target as HTMLElement;
|
||||||
if (listItemElement) {
|
while (clickTarget && !clickTarget.classList.contains("b3-list")) {
|
||||||
event.stopPropagation();
|
if (clickTarget.classList.contains("b3-list-item__toggle")) {
|
||||||
if (cb) {
|
if (clickTarget.firstElementChild.classList.contains("b3-list-item__arrow--open")) {
|
||||||
cb(listItemElement);
|
clickTarget.firstElementChild.classList.remove("b3-list-item__arrow--open");
|
||||||
} else {
|
clickTarget.parentElement.nextElementSibling.classList.add("fn__none");
|
||||||
setDatabase(avId, target, listItemElement);
|
} 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, () => {
|
genSearchList(listElement, "", avId, excludes, () => {
|
||||||
|
|
2
app/src/types/index.d.ts
vendored
2
app/src/types/index.d.ts
vendored
|
@ -547,6 +547,8 @@ interface IOperation {
|
||||||
isDetached?: boolean // insertAttrViewBlock 专享
|
isDetached?: boolean // insertAttrViewBlock 专享
|
||||||
srcIDs?: string[] // removeAttrViewBlock 专享
|
srcIDs?: string[] // removeAttrViewBlock 专享
|
||||||
srcs?: IOperationSrcs[] // insertAttrViewBlock 专享
|
srcs?: IOperationSrcs[] // insertAttrViewBlock 专享
|
||||||
|
ignoreDefaultFill?: boolean // insertAttrViewBlock 专享
|
||||||
|
viewID?: string // insertAttrViewBlock 专享
|
||||||
name?: string // addAttrViewCol 专享
|
name?: string // addAttrViewCol 专享
|
||||||
type?: TAVCol // addAttrViewCol 专享
|
type?: TAVCol // addAttrViewCol 专享
|
||||||
deckID?: string // add/removeFlashcards 专享
|
deckID?: string // add/removeFlashcards 专享
|
||||||
|
|
|
@ -95,3 +95,138 @@ export const upDownHint = (listElement: Element, event: KeyboardEvent, classActi
|
||||||
return currentHintElement;
|
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;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue