diff --git a/app/src/protyle/toolbar/index.ts b/app/src/protyle/toolbar/index.ts index a7bcf8330..b348cb504 100644 --- a/app/src/protyle/toolbar/index.ts +++ b/app/src/protyle/toolbar/index.ts @@ -1226,15 +1226,24 @@ export class Toolbar { hideElements(["hint"], protyle); window.siyuan.menus.menu.remove(); this.range = getEditorRange(nodeElement); - let html = `
${window.siyuan.languages.clear}
`; - const hljsLanguages = Constants.ALIAS_CODE_LANGUAGES.concat(window.hljs?.listLanguages() ?? []).sort(); + let html = `
${window.siyuan.languages.clear}
`; + let hljsLanguages = Constants.ALIAS_CODE_LANGUAGES.concat(window.hljs?.listLanguages() ?? []).sort(); + + const eventDetail = { languages: hljsLanguages }; + if (protyle.app && protyle.app.plugins) { + protyle.app.plugins.forEach((plugin: any) => { + plugin.eventBus.emit("code-languages-prepare", eventDetail); + }); + } + + hljsLanguages = eventDetail.languages; hljsLanguages.forEach((item, index) => { - html += `
${item}
`; + html += `
${item}
`; }); this.subElement.style.width = ""; this.subElement.style.padding = ""; - this.subElement.innerHTML = `
+ this.subElement.innerHTML = `
${html}
`; @@ -1260,41 +1269,47 @@ export class Toolbar { }); inputElement.addEventListener("input", (event) => { const lowerCaseValue = inputElement.value.toLowerCase(); - const matchLanguages = hljsLanguages.filter(item => item.includes(lowerCaseValue)); - let html = ""; - // sort + let html = `
${window.siyuan.languages.clear}
`; let matchInput = false; - matchLanguages.sort((a, b) => { - if (a.startsWith(lowerCaseValue) && b.startsWith(lowerCaseValue)) { - if (a.length < b.length) { + if (inputElement.value.trim()) { + const matchLanguages = hljsLanguages.filter(item => item.includes(lowerCaseValue)); + // sort + matchLanguages.sort((a, b) => { + if (a.startsWith(lowerCaseValue) && b.startsWith(lowerCaseValue)) { + if (a.length < b.length) { + return -1; + } else if (a.length === b.length) { + return 0; + } else { + return 1; + } + } else if (a.startsWith(lowerCaseValue)) { return -1; - } else if (a.length === b.length) { - return 0; - } else { + } else if (b.startsWith(lowerCaseValue)) { return 1; + } else { + return 0; } - } else if (a.startsWith(lowerCaseValue)) { - return -1; - } else if (b.startsWith(lowerCaseValue)) { - return 1; - } else { - return 0; + }).forEach((item) => { + if (inputElement.value === item) { + matchInput = true; + } + html += `
${item.replace(lowerCaseValue, "" + lowerCaseValue + "")}
`; + }); + if (!matchInput) { + html += `
${escapeHtml(inputElement.value.replace(/`| /g, "_"))}
`; } - }).forEach((item) => { - if (inputElement.value === item) { - matchInput = true; - } - html += `
${item.replace(lowerCaseValue, "" + lowerCaseValue + "")}
`; - }); - if (inputElement.value.trim() && !matchInput) { - html = `
${escapeHtml(inputElement.value.replace(/`| /g, "_"))}
${html}`; - } - html = `
${window.siyuan.languages.clear}
` + html; - listElement.innerHTML = html; - if (listElement.childElementCount > 2 && !matchInput && inputElement.value.trim()) { - listElement.firstElementChild.nextElementSibling.nextElementSibling.classList.add("b3-list-item--focus"); } else { - listElement.firstElementChild.nextElementSibling.classList.add("b3-list-item--focus"); + hljsLanguages.forEach((item, index) => { + html += `
${item}
`; + }); + } + listElement.innerHTML = html; + for (const item of listElement.children) { + if (item.getAttribute("data-id") !== "clear" && item.getBoundingClientRect().height !== 0) { + item.classList.add("b3-list-item--focus"); + break; + } } event.stopPropagation(); }); @@ -1315,6 +1330,12 @@ export class Toolbar { /// #else setPosition(this.subElement, 0, 0); /// #endif + for (const item of listElement.children) { + if (item.getBoundingClientRect().height !== 0) { + item.classList.add("b3-list-item--focus"); + break; + } + } this.element.classList.add("fn__none"); inputElement.select(); } @@ -1744,15 +1765,33 @@ ${item.name} } } - private updateLanguage(languageElement: HTMLElement[], protyle: IProtyle, selectedLang: string) { + private updateLanguage(languageElements: HTMLElement[], protyle: IProtyle, selectedLang: string) { const currentLang = selectedLang === window.siyuan.languages.clear ? "" : selectedLang; + + if (protyle.app && protyle.app.plugins) { + const languageChanges = languageElements.map(element => { + return { + oldLanguage: element.textContent || "", + languageElement: element + }; + }); + const eventDetail = { + language: currentLang, + languageChanges: languageChanges, + protyle: protyle + }; + protyle.app.plugins.forEach((plugin: any) => { + plugin.eventBus.emit("code-languages-change", eventDetail); + }); + } + if (!Constants.SIYUAN_RENDER_CODE_LANGUAGES.includes(currentLang)) { window.siyuan.storage[Constants.LOCAL_CODELANG] = currentLang; setStorageVal(Constants.LOCAL_CODELANG, window.siyuan.storage[Constants.LOCAL_CODELANG]); } const doOperations: IOperation[] = []; const undoOperations: IOperation[] = []; - languageElement.forEach(item => { + languageElements.forEach(item => { const nodeElement = hasClosestBlock(item); if (nodeElement) { const id = nodeElement.getAttribute("data-node-id"); diff --git a/app/src/types/index.d.ts b/app/src/types/index.d.ts index 97708626f..67cbdf62d 100644 --- a/app/src/types/index.d.ts +++ b/app/src/types/index.d.ts @@ -85,7 +85,8 @@ type TEventBus = "ws-main" | "sync-start" | "sync-end" | "sync-fail" | "switch-protyle" | "switch-protyle-mode" | "destroy-protyle" | "lock-screen" | - "mobile-keyboard-show" | "mobile-keyboard-hide" + "mobile-keyboard-show" | "mobile-keyboard-hide" | + "code-languages-prepare" | "code-languages-change" type TAVView = "table" | "gallery" type TAVCol = "text"