mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-12-27 20:08:49 +01:00
This commit is contained in:
parent
119314ba02
commit
ebc2111fe8
7 changed files with 78 additions and 29 deletions
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 [];
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
});
|
||||
|
|
|
|||
1
app/src/types/index.d.ts
vendored
1
app/src/types/index.d.ts
vendored
|
|
@ -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 =
|
||||
"="
|
||||
| "!="
|
||||
|
|
|
|||
2
app/src/types/protyle.d.ts
vendored
2
app/src/types/protyle.d.ts
vendored
|
|
@ -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 */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue