This commit is contained in:
Vanessa 2023-07-28 20:16:32 +08:00
parent 119314ba02
commit ebc2111fe8
7 changed files with 78 additions and 29 deletions

View file

@ -105,7 +105,7 @@ export const renderTextMenu = (protyle: IProtyle, toolbarElement: Element) => {
let fontSize = "16px";
const nodeElements = getFontNodeElements(protyle);
if (nodeElements && nodeElements.length > 0) {
textElement = nodeElements[0];
textElement = nodeElements[0] as HTMLElement;
} else {
textElement = protyle.toolbar.range.cloneContents().querySelector('[data-type~="text"]') as HTMLElement;
if (!textElement) {
@ -512,14 +512,15 @@ export const initKeyboardToolbar = () => {
// appearance
if (["clear", "style2", "style4", "color", "backgroundColor", "fontSize", "style1"].includes(type)) {
const nodeElements = getFontNodeElements(protyle);
const itemElement = buttonElement.firstElementChild as HTMLElement;
if (type === "style1") {
fontEvent(protyle, nodeElements, type, buttonElement.firstElementChild.style.backgroundColor + Constants.ZWSP + buttonElement.firstElementChild.style.color);
fontEvent(protyle, nodeElements, type, itemElement.style.backgroundColor + Constants.ZWSP + itemElement.style.color);
} else if (type === "fontSize") {
fontEvent(protyle, nodeElements, type, buttonElement.firstElementChild.textContent.trim());
fontEvent(protyle, nodeElements, type, itemElement.textContent.trim());
} else if (type === "backgroundColor") {
fontEvent(protyle, nodeElements, type, buttonElement.firstElementChild.style.backgroundColor);
fontEvent(protyle, nodeElements, type, itemElement.style.backgroundColor);
} else if (type === "color") {
fontEvent(protyle, nodeElements, type, buttonElement.firstElementChild.style.color);
fontEvent(protyle, nodeElements, type, itemElement.style.color);
} else {
fontEvent(protyle, nodeElements, type);
}

View file

@ -311,7 +311,7 @@ export const hintTag = (key: string, protyle: IProtyle): IHintData[] => {
dataList[1].focus = true;
}
}
protyle.hint.genHTML(dataList, protyle, true);
protyle.hint.genHTML(dataList, protyle, true, "hint");
});
return [];
@ -344,9 +344,9 @@ export const genHintItemHTML = (item: IBlock) => {
<span class="b3-list-item__text">${item.content}</span>
</div>
<div class="b3-list-item__meta b3-list-item__showall" style="margin-bottom: 4px">${item.hPath}</div>`;
}
};
export const hintRef = (key: string, protyle: IProtyle, isQuick = false): IHintData[] => {
export const hintRef = (key: string, protyle: IProtyle, source: THintSource): IHintData[] => {
const nodeElement = hasClosestBlock(getEditorRange(protyle.wysiwyg.element).startContainer);
protyle.hint.genLoading(protyle);
fetchPost("/api/search/searchRefBlock", {
@ -360,14 +360,14 @@ export const hintRef = (key: string, protyle: IProtyle, isQuick = false): IHintD
if (response.data.newDoc) {
const newFileName = Lute.UnEscapeHTMLStr(replaceFileName(response.data.k));
dataList.push({
value: isQuick ? `((newFile "${newFileName}"${Constants.ZWSP}'${newFileName}${Lute.Caret}'))` : `((newFile '${newFileName}${Lute.Caret}'))`,
value: source === "search" ? `((newFile "${newFileName}"${Constants.ZWSP}'${newFileName}${Lute.Caret}'))` : `((newFile '${newFileName}${Lute.Caret}'))`,
html: `<div class="b3-list-item__first"><svg class="b3-list-item__graphic"><use xlink:href="#iconFile"></use></svg>
<span class="b3-list-item__text">${window.siyuan.languages.newFile} <mark>${response.data.k}</mark></span></div>`,
});
}
response.data.blocks.forEach((item: IBlock) => {
let value = `<span data-type="block-ref" data-id="${item.id}" data-subtype="d">${item.name || item.refText}</span>`;
if (isQuick) {
if (source === "search") {
value = `<span data-type="block-ref" data-id="${item.id}" data-subtype="s">${key}</span>`;
}
dataList.push({
@ -375,7 +375,7 @@ export const hintRef = (key: string, protyle: IProtyle, isQuick = false): IHintD
html: genHintItemHTML(item),
});
});
if (isQuick) {
if (source === "search") {
protyle.hint.splitChar = "((";
protyle.hint.lastIndex = -1;
}
@ -387,7 +387,7 @@ export const hintRef = (key: string, protyle: IProtyle, isQuick = false): IHintD
} else if (response.data.newDoc && dataList.length > 1) {
dataList[1].focus = true;
}
protyle.hint.genHTML(dataList, protyle, true, isQuick);
protyle.hint.genHTML(dataList, protyle, true, source);
});
return [];
};
@ -417,7 +417,7 @@ export const hintEmbed = (key: string, protyle: IProtyle): IHintData[] => {
html: window.siyuan.languages.emptyContent,
});
}
protyle.hint.genHTML(dataList, protyle, true);
protyle.hint.genHTML(dataList, protyle, true, "hint");
});
return [];
};

View file

@ -43,6 +43,7 @@ export class Hint {
public enableExtend = false;
public splitChar = "";
public lastIndex = -1;
private source: THintSource;
constructor(protyle: IProtyle) {
this.element = document.createElement("div");
@ -58,7 +59,7 @@ export class Hint {
}
const btnElement = hasClosestByMatchTag(eventTarget, "BUTTON");
if (btnElement && !btnElement.classList.contains("emojis__item") && !btnElement.classList.contains("emojis__type")) {
if (btnElement.parentElement.classList.contains("b3-list")) {
if (this.source !== "search") {
this.fill(decodeURIComponent(btnElement.getAttribute("data-value")), protyle, true, isCtrl(event));
} else {
// 划选引用点击,需先重置 range
@ -194,7 +195,7 @@ ${unicode2Emoji(emoji.unicode)}</button>`;
if (this.splitChar === "/" || this.splitChar === "、") {
clearTimeout(this.timeId);
if (this.enableSlash && !isMobile()) {
this.genHTML(hintSlash(key, protyle), protyle);
this.genHTML(hintSlash(key, protyle), protyle, false, "hint");
}
return;
}
@ -203,7 +204,7 @@ ${unicode2Emoji(emoji.unicode)}</button>`;
if (item.key === this.splitChar) {
clearTimeout(this.timeId);
this.timeId = window.setTimeout(() => {
this.genHTML(item.hint(key, protyle), protyle);
this.genHTML(item.hint(key, protyle, "hint"), protyle, false, "hint");
}, protyle.options.hint.delay);
}
});
@ -238,9 +239,9 @@ ${unicode2Emoji(emoji.unicode)}</button>`;
}
}
private getHTMLByData(data: IHintData[], hasSearch = false) {
private getHTMLByData(data: IHintData[]) {
let hintsHTML = '<div style="flex: 1;overflow:auto;">';
if (hasSearch) {
if (this.source !== "hint") {
hintsHTML = '<input style="margin:0 8px 4px 8px" class="b3-text-field"><div style="flex: 1;overflow:auto;">';
}
data.forEach((hintData, i) => {
@ -259,7 +260,8 @@ ${unicode2Emoji(emoji.unicode)}</button>`;
return `${hintsHTML}</div>`;
}
public genHTML(data: IHintData[], protyle: IProtyle, hide = false, hasSearch = false) {
public genHTML(data: IHintData[], protyle: IProtyle, hide = false, source: THintSource) {
this.source = source;
if (data.length === 0) {
if (!this.element.querySelector(".fn__loading") || hide) {
this.element.classList.add("fn__none");
@ -267,7 +269,7 @@ ${unicode2Emoji(emoji.unicode)}</button>`;
return;
}
this.element.innerHTML = this.getHTMLByData(data, hasSearch);
this.element.innerHTML = this.getHTMLByData(data);
this.element.classList.remove("fn__none");
// https://github.com/siyuan-note/siyuan/issues/4575
if (data[0].filter) {
@ -280,7 +282,7 @@ ${unicode2Emoji(emoji.unicode)}</button>`;
setPosition(this.element, textareaPosition.left, textareaPosition.top + 26, 30);
this.element.scrollTop = 0;
this.bindUploadEvent(protyle, this.element);
if (hasSearch) {
if (this.source !== "hint") {
const searchElement = this.element.querySelector("input.b3-text-field") as HTMLInputElement;
const oldValue = this.element.querySelector("mark")?.textContent || "";
searchElement.value = oldValue;
@ -305,7 +307,7 @@ ${unicode2Emoji(emoji.unicode)}</button>`;
focusByRange(protyle.toolbar.range);
}
});
const nodeElement = hasClosestBlock(protyle.toolbar.range.startContainer);
const nodeElement = protyle.toolbar.range ? hasClosestBlock(protyle.toolbar.range.startContainer) : false;
searchElement.addEventListener("input", (event: InputEvent) => {
if (event.isComposing) {
return;
@ -394,7 +396,7 @@ ${genHintItemHTML(item)}
public fill(value: string, protyle: IProtyle, updateRange = true, refIsS = false) {
hideElements(["hint", "toolbar"], protyle);
if (updateRange) {
if (updateRange && this.source !== "av") {
protyle.toolbar.range = getEditorRange(protyle.wysiwyg.element);
}
const range = protyle.toolbar.range;
@ -402,6 +404,50 @@ ${genHintItemHTML(item)}
if (!nodeElement) {
return;
}
if (this.source === "av") {
const avID = nodeElement.getAttribute("data-av-id");
const rowsElement = nodeElement.querySelectorAll(".av__row")
const previousID = rowsElement[rowsElement.length - 1].getAttribute("data-id")
let tempElement = document.createElement("div");
tempElement.innerHTML = value.replace(/<mark>/g, "").replace(/<\/mark>/g, "");
tempElement = tempElement.firstElementChild as HTMLDivElement;
if (value.startsWith("((newFile ") && value.endsWith(`${Lute.Caret}'))`)) {
const fileNames = value.substring(11, value.length - 4).split(`"${Constants.ZWSP}'`);
const realFileName = fileNames.length === 1 ? fileNames[0] : fileNames[1];
getSavePath(protyle.path, protyle.notebookId, (pathString) => {
fetchPost("/api/filetree/createDocWithMd", {
notebook: protyle.notebookId,
path: pathPosix().join(pathString, realFileName),
parentID: protyle.block.rootID,
markdown: ""
}, response => {
transaction(protyle, [{
action: "insertAttrViewBlock",
avID,
previousID,
srcIDs: [response.data],
}], [{
action: "removeAttrViewBlock",
srcIDs: [response.data],
avID,
}]);
});
});
} else {
const sourceId = tempElement.getAttribute('data-id')
transaction(protyle, [{
action: "insertAttrViewBlock",
avID,
previousID,
srcIDs: [sourceId],
}], [{
action: "removeAttrViewBlock",
srcIDs: [sourceId],
avID,
}]);
}
return;
}
this.enableExtend = false;
let id = "";
if (nodeElement) {
@ -513,7 +559,7 @@ ${genHintItemHTML(item)}
this.enableExtend = true;
if (value === "((" || value === "{{") {
if (value === "((") {
hintRef("", protyle);
hintRef("", protyle, "hint");
} else {
hintEmbed("", protyle);
}
@ -596,12 +642,12 @@ ${genHintItemHTML(item)}
const ids = value.split(Constants.ZWSP);
if (ids[1] === plugin.name) {
plugin.protyleSlash.find((slash) => {
if (slash.id === ids[2]){
if (slash.id === ids[2]) {
slash.callback(protyle.getInstance());
return true;
}
});
return true;
return true;
}
});
return;

View file

@ -131,7 +131,8 @@ export const avClick = (protyle: IProtyle, event: MouseEvent & { target: HTMLEle
const addRowElement = hasClosestByClassName(event.target, "av__row--add");
if (addRowElement) {
hintRef("", protyle, true);
(blockElement.querySelector(".av__title") as HTMLInputElement).focus()
hintRef("", protyle, "av");
event.preventDefault();
event.stopPropagation();
return true;

View file

@ -13,7 +13,7 @@ export class BlockRef extends ToolbarItem {
return;
}
fixTableRange(protyle.toolbar.range);
hintRef(protyle.toolbar.range.toString(), protyle, true);
hintRef(protyle.toolbar.range.toString(), protyle, "search");
protyle.toolbar.element.classList.add("fn__none");
event.stopPropagation();
});

View file

@ -46,6 +46,7 @@ type TEventBus = "ws-main" |
"input-search" |
"loaded-protyle"
type TAVCol = "text" | "date" | "number" | "relation" | "rollup" | "select" | "block" | "mSelect"
type THintSource = "search" | "av" | "hint";
type TAVFilterOperator =
"="
| "!="

View file

@ -345,7 +345,7 @@ interface IHintData {
interface IHintExtend {
key: string;
hint?(value: string, protyle: IProtyle): IHintData[];
hint?(value: string, protyle: IProtyle, source: THintSource): IHintData[];
}
/** @link https://ld246.com/article/1549638745630#options-hint */