diff --git a/src/components/searchbar/index.js b/src/components/searchbar/index.js index bd2b032c0..058980fba 100644 --- a/src/components/searchbar/index.js +++ b/src/components/searchbar/index.js @@ -190,6 +190,7 @@ function searchBar( */ function cloneSearchItem($item) { const $clone = $item.cloneNode(true); + syncCheckboxState($clone, $item); $clone.addEventListener("click", () => { $item.addEventListener( "settings-item-interaction-end", @@ -213,6 +214,26 @@ function searchBar( function syncSearchClone($clone, $item) { $clone.className = $item.className; $clone.innerHTML = $item.innerHTML; + syncCheckboxState($clone, $item); + } + + /** + * Sync the checked property of checkbox and radio elements, since cloneNode and innerHTML do not copy/preserve dynamic checked state. + * @param {HTMLElement} $clone + * @param {HTMLElement} $item + */ + function syncCheckboxState($clone, $item) { + const $itemCheckbox = $item.querySelector( + 'input[type="checkbox"], input[type="radio"]', + ); + if ($itemCheckbox) { + const $cloneCheckbox = $clone.querySelector( + 'input[type="checkbox"], input[type="radio"]', + ); + if ($cloneCheckbox) { + $cloneCheckbox.checked = $itemCheckbox.checked; + } + } } } diff --git a/src/lang/ar-ye.json b/src/lang/ar-ye.json index bf8a65fe3..afae38b27 100644 --- a/src/lang/ar-ye.json +++ b/src/lang/ar-ye.json @@ -766,5 +766,13 @@ "off": "إيقاف", "quick tools height": "ارتفاع الأدوات السريعة", "quick tools toggler": "مبدل الأدوات السريعة", - "running processes": "Running processes" + "running processes": "Running processes", + "recommend extensions": "Recommend extensions", + "settings-info-editor-recommend-extensions": "Suggest plugins when a file opens as plain text because no language mode is available.", + "extension recommendation title": "Extensions available for {extension}", + "extension recommendation message": "No syntax mode is installed for {extension}. Search plugins for \"{keyword}\".", + "extension request title": "No extension found for {extension}", + "extension request message": "Ask for a plugin so Acode can highlight this file type.", + "search plugins": "Search plugins", + "request plugin": "Request plugin" } diff --git a/src/lang/be-by.json b/src/lang/be-by.json index d42171d25..4b0231f85 100644 --- a/src/lang/be-by.json +++ b/src/lang/be-by.json @@ -766,5 +766,13 @@ "off": "Выкл", "quick tools height": "Вышыня хуткіх інструментаў", "quick tools toggler": "Пераключальнік хуткіх інструментаў", - "running processes": "Running processes" + "running processes": "Running processes", + "recommend extensions": "Recommend extensions", + "settings-info-editor-recommend-extensions": "Suggest plugins when a file opens as plain text because no language mode is available.", + "extension recommendation title": "Extensions available for {extension}", + "extension recommendation message": "No syntax mode is installed for {extension}. Search plugins for \"{keyword}\".", + "extension request title": "No extension found for {extension}", + "extension request message": "Ask for a plugin so Acode can highlight this file type.", + "search plugins": "Search plugins", + "request plugin": "Request plugin" } diff --git a/src/lang/bn-bd.json b/src/lang/bn-bd.json index aadf268e6..336254fcf 100644 --- a/src/lang/bn-bd.json +++ b/src/lang/bn-bd.json @@ -766,5 +766,13 @@ "off": "বন্ধ", "quick tools height": "কুইক টুলসের উচ্চতা", "quick tools toggler": "কুইক টুলস টগলার", - "running processes": "Running processes" + "running processes": "Running processes", + "recommend extensions": "Recommend extensions", + "settings-info-editor-recommend-extensions": "Suggest plugins when a file opens as plain text because no language mode is available.", + "extension recommendation title": "Extensions available for {extension}", + "extension recommendation message": "No syntax mode is installed for {extension}. Search plugins for \"{keyword}\".", + "extension request title": "No extension found for {extension}", + "extension request message": "Ask for a plugin so Acode can highlight this file type.", + "search plugins": "Search plugins", + "request plugin": "Request plugin" } diff --git a/src/lang/cs-cz.json b/src/lang/cs-cz.json index c6f14f300..b67c86c6e 100644 --- a/src/lang/cs-cz.json +++ b/src/lang/cs-cz.json @@ -766,5 +766,13 @@ "off": "Vypnuto", "quick tools height": "Výška rychlých nástrojů", "quick tools toggler": "Přepínač rychlých nástrojů", - "running processes": "Running processes" + "running processes": "Running processes", + "recommend extensions": "Recommend extensions", + "settings-info-editor-recommend-extensions": "Suggest plugins when a file opens as plain text because no language mode is available.", + "extension recommendation title": "Extensions available for {extension}", + "extension recommendation message": "No syntax mode is installed for {extension}. Search plugins for \"{keyword}\".", + "extension request title": "No extension found for {extension}", + "extension request message": "Ask for a plugin so Acode can highlight this file type.", + "search plugins": "Search plugins", + "request plugin": "Request plugin" } diff --git a/src/lang/de-de.json b/src/lang/de-de.json index fede78c8d..a7eb71834 100644 --- a/src/lang/de-de.json +++ b/src/lang/de-de.json @@ -766,5 +766,13 @@ "off": "Aus", "quick tools height": "Schnellwerkzeug-Höhe", "quick tools toggler": "Schnellwerkzeug-Schaltfläche", - "running processes": "Running processes" + "running processes": "Running processes", + "recommend extensions": "Recommend extensions", + "settings-info-editor-recommend-extensions": "Suggest plugins when a file opens as plain text because no language mode is available.", + "extension recommendation title": "Extensions available for {extension}", + "extension recommendation message": "No syntax mode is installed for {extension}. Search plugins for \"{keyword}\".", + "extension request title": "No extension found for {extension}", + "extension request message": "Ask for a plugin so Acode can highlight this file type.", + "search plugins": "Search plugins", + "request plugin": "Request plugin" } diff --git a/src/lang/en-us.json b/src/lang/en-us.json index 94c4fb595..f1d18c0b1 100644 --- a/src/lang/en-us.json +++ b/src/lang/en-us.json @@ -136,6 +136,7 @@ "live autocompletion": "Live autocompletion", "local word completion": "Local word completion", "language package completion": "Language package completion", + "recommend extensions": "Recommend extensions", "auto close tags": "Auto close tags", "auto rename tags": "Auto rename tags", "file properties": "File properties", @@ -689,6 +690,13 @@ "settings-info-editor-live-autocomplete": "Show suggestions while you type.", "settings-info-editor-local-word-completion": "Suggest words from the current file.", "settings-info-editor-language-completion": "Suggest keywords, snippets, and other completions from CodeMirror language packages.", + "settings-info-editor-recommend-extensions": "Suggest plugins when a file opens as plain text because no language mode is available.", + "extension recommendation title": "Extensions available for {extension}", + "extension recommendation message": "No syntax mode is installed for {extension}. Search plugins for \"{keyword}\".", + "extension request title": "No extension found for {extension}", + "extension request message": "Ask for a plugin so Acode can highlight this file type.", + "search plugins": "Search plugins", + "request plugin": "Request plugin", "settings-info-editor-auto-close-tags": "Automatically insert closing tags in HTML, XML, Vue, Angular, and PHP template files.", "settings-info-editor-auto-rename-tags": "Rename the matching opening or closing tag while editing HTML-like tags.", "settings-info-editor-rainbow-brackets": "Color matching brackets by nesting depth.", diff --git a/src/lang/es-sv.json b/src/lang/es-sv.json index e4e74e7ba..4d28b63c3 100644 --- a/src/lang/es-sv.json +++ b/src/lang/es-sv.json @@ -766,5 +766,13 @@ "off": "Apagado", "quick tools height": "Altura de herramientas rápidas", "quick tools toggler": "Alternador de herramientas rápidas", - "running processes": "Running processes" + "running processes": "Running processes", + "recommend extensions": "Recommend extensions", + "settings-info-editor-recommend-extensions": "Suggest plugins when a file opens as plain text because no language mode is available.", + "extension recommendation title": "Extensions available for {extension}", + "extension recommendation message": "No syntax mode is installed for {extension}. Search plugins for \"{keyword}\".", + "extension request title": "No extension found for {extension}", + "extension request message": "Ask for a plugin so Acode can highlight this file type.", + "search plugins": "Search plugins", + "request plugin": "Request plugin" } diff --git a/src/lang/fr-fr.json b/src/lang/fr-fr.json index 14e9149b6..2ef49b793 100644 --- a/src/lang/fr-fr.json +++ b/src/lang/fr-fr.json @@ -766,5 +766,13 @@ "off": "Désactivé", "quick tools height": "Hauteur des outils rapides", "quick tools toggler": "Bascule des outils rapides", - "running processes": "Running processes" + "running processes": "Running processes", + "recommend extensions": "Recommend extensions", + "settings-info-editor-recommend-extensions": "Suggest plugins when a file opens as plain text because no language mode is available.", + "extension recommendation title": "Extensions available for {extension}", + "extension recommendation message": "No syntax mode is installed for {extension}. Search plugins for \"{keyword}\".", + "extension request title": "No extension found for {extension}", + "extension request message": "Ask for a plugin so Acode can highlight this file type.", + "search plugins": "Search plugins", + "request plugin": "Request plugin" } diff --git a/src/lang/he-il.json b/src/lang/he-il.json index 8007eabde..a3f07262a 100644 --- a/src/lang/he-il.json +++ b/src/lang/he-il.json @@ -766,5 +766,13 @@ "off": "כבוי", "quick tools height": "גובה כלים מהירים", "quick tools toggler": "מחליף כלים מהירים", - "running processes": "Running processes" + "running processes": "Running processes", + "recommend extensions": "Recommend extensions", + "settings-info-editor-recommend-extensions": "Suggest plugins when a file opens as plain text because no language mode is available.", + "extension recommendation title": "Extensions available for {extension}", + "extension recommendation message": "No syntax mode is installed for {extension}. Search plugins for \"{keyword}\".", + "extension request title": "No extension found for {extension}", + "extension request message": "Ask for a plugin so Acode can highlight this file type.", + "search plugins": "Search plugins", + "request plugin": "Request plugin" } diff --git a/src/lang/hi-in.json b/src/lang/hi-in.json index 4fa22c5d3..b45d02154 100644 --- a/src/lang/hi-in.json +++ b/src/lang/hi-in.json @@ -766,5 +766,13 @@ "off": "बंद", "quick tools height": "त्वरित उपकरण ऊंचाई", "quick tools toggler": "त्वरित उपकरण टॉगलर", - "running processes": "Running processes" + "running processes": "Running processes", + "recommend extensions": "Recommend extensions", + "settings-info-editor-recommend-extensions": "Suggest plugins when a file opens as plain text because no language mode is available.", + "extension recommendation title": "Extensions available for {extension}", + "extension recommendation message": "No syntax mode is installed for {extension}. Search plugins for \"{keyword}\".", + "extension request title": "No extension found for {extension}", + "extension request message": "Ask for a plugin so Acode can highlight this file type.", + "search plugins": "Search plugins", + "request plugin": "Request plugin" } diff --git a/src/lang/hu-hu.json b/src/lang/hu-hu.json index 3627e1d2b..941ef882e 100644 --- a/src/lang/hu-hu.json +++ b/src/lang/hu-hu.json @@ -766,5 +766,13 @@ "off": "Kikapcsolva", "quick tools height": "Gyorseszközök magassága", "quick tools toggler": "Gyorseszközök be/ki", - "running processes": "Running processes" + "running processes": "Running processes", + "recommend extensions": "Recommend extensions", + "settings-info-editor-recommend-extensions": "Suggest plugins when a file opens as plain text because no language mode is available.", + "extension recommendation title": "Extensions available for {extension}", + "extension recommendation message": "No syntax mode is installed for {extension}. Search plugins for \"{keyword}\".", + "extension request title": "No extension found for {extension}", + "extension request message": "Ask for a plugin so Acode can highlight this file type.", + "search plugins": "Search plugins", + "request plugin": "Request plugin" } diff --git a/src/lang/id-id.json b/src/lang/id-id.json index 7c6642680..cda838d34 100644 --- a/src/lang/id-id.json +++ b/src/lang/id-id.json @@ -766,5 +766,13 @@ "off": "Mati", "quick tools height": "Tinggi alat cepat", "quick tools toggler": "Pengalih alat cepat", - "running processes": "Proses yang berjalan" + "running processes": "Proses yang berjalan", + "recommend extensions": "Recommend extensions", + "settings-info-editor-recommend-extensions": "Suggest plugins when a file opens as plain text because no language mode is available.", + "extension recommendation title": "Extensions available for {extension}", + "extension recommendation message": "No syntax mode is installed for {extension}. Search plugins for \"{keyword}\".", + "extension request title": "No extension found for {extension}", + "extension request message": "Ask for a plugin so Acode can highlight this file type.", + "search plugins": "Search plugins", + "request plugin": "Request plugin" } diff --git a/src/lang/index.d.ts b/src/lang/index.d.ts index fec355f62..d29eaabf5 100644 --- a/src/lang/index.d.ts +++ b/src/lang/index.d.ts @@ -139,6 +139,7 @@ declare type LangStrings = { "live autocompletion": string; "local word completion": string; "language package completion": string; + "recommend extensions": string; "auto close tags": string; "auto rename tags": string; "file properties": string; @@ -692,6 +693,13 @@ declare type LangStrings = { "settings-info-editor-live-autocomplete": string; "settings-info-editor-local-word-completion": string; "settings-info-editor-language-completion": string; + "settings-info-editor-recommend-extensions": string; + "extension recommendation title": string; + "extension recommendation message": string; + "extension request title": string; + "extension request message": string; + "search plugins": string; + "request plugin": string; "settings-info-editor-auto-close-tags": string; "settings-info-editor-auto-rename-tags": string; "settings-info-editor-rainbow-brackets": string; diff --git a/src/lang/ir-fa.json b/src/lang/ir-fa.json index f4785142b..395c351bb 100644 --- a/src/lang/ir-fa.json +++ b/src/lang/ir-fa.json @@ -766,5 +766,13 @@ "off": "خاموش", "quick tools height": "ارتفاع ابزار سریع", "quick tools toggler": "تغییر دهنده ابزار سریع", - "running processes": "Running processes" + "running processes": "Running processes", + "recommend extensions": "Recommend extensions", + "settings-info-editor-recommend-extensions": "Suggest plugins when a file opens as plain text because no language mode is available.", + "extension recommendation title": "Extensions available for {extension}", + "extension recommendation message": "No syntax mode is installed for {extension}. Search plugins for \"{keyword}\".", + "extension request title": "No extension found for {extension}", + "extension request message": "Ask for a plugin so Acode can highlight this file type.", + "search plugins": "Search plugins", + "request plugin": "Request plugin" } diff --git a/src/lang/it-it.json b/src/lang/it-it.json index 8ab2b1f8a..a71320d5b 100644 --- a/src/lang/it-it.json +++ b/src/lang/it-it.json @@ -766,5 +766,13 @@ "off": "Spento", "quick tools height": "Altezza strumenti veloci", "quick tools toggler": "Attivatore strumenti veloci", - "running processes": "Running processes" + "running processes": "Running processes", + "recommend extensions": "Recommend extensions", + "settings-info-editor-recommend-extensions": "Suggest plugins when a file opens as plain text because no language mode is available.", + "extension recommendation title": "Extensions available for {extension}", + "extension recommendation message": "No syntax mode is installed for {extension}. Search plugins for \"{keyword}\".", + "extension request title": "No extension found for {extension}", + "extension request message": "Ask for a plugin so Acode can highlight this file type.", + "search plugins": "Search plugins", + "request plugin": "Request plugin" } diff --git a/src/lang/ja-jp.json b/src/lang/ja-jp.json index 990b15421..5ef721bba 100644 --- a/src/lang/ja-jp.json +++ b/src/lang/ja-jp.json @@ -766,5 +766,13 @@ "off": "オフ", "quick tools height": "クイックツールの高さ", "quick tools toggler": "クイックツール切替", - "running processes": "Running processes" + "running processes": "Running processes", + "recommend extensions": "Recommend extensions", + "settings-info-editor-recommend-extensions": "Suggest plugins when a file opens as plain text because no language mode is available.", + "extension recommendation title": "Extensions available for {extension}", + "extension recommendation message": "No syntax mode is installed for {extension}. Search plugins for \"{keyword}\".", + "extension request title": "No extension found for {extension}", + "extension request message": "Ask for a plugin so Acode can highlight this file type.", + "search plugins": "Search plugins", + "request plugin": "Request plugin" } diff --git a/src/lang/ko-kr.json b/src/lang/ko-kr.json index 738fff95d..8b98f9db0 100644 --- a/src/lang/ko-kr.json +++ b/src/lang/ko-kr.json @@ -766,5 +766,13 @@ "off": "끄기", "quick tools height": "퀵툴 높이", "quick tools toggler": "퀵툴 토글러", - "running processes": "Running processes" + "running processes": "Running processes", + "recommend extensions": "Recommend extensions", + "settings-info-editor-recommend-extensions": "Suggest plugins when a file opens as plain text because no language mode is available.", + "extension recommendation title": "Extensions available for {extension}", + "extension recommendation message": "No syntax mode is installed for {extension}. Search plugins for \"{keyword}\".", + "extension request title": "No extension found for {extension}", + "extension request message": "Ask for a plugin so Acode can highlight this file type.", + "search plugins": "Search plugins", + "request plugin": "Request plugin" } diff --git a/src/lang/ml-in.json b/src/lang/ml-in.json index ab55e327d..9b9d1d804 100644 --- a/src/lang/ml-in.json +++ b/src/lang/ml-in.json @@ -766,5 +766,13 @@ "off": "ഓഫ്", "quick tools height": "ദ്രുത ഉപകരണ ഉയരം", "quick tools toggler": "ദ്രുത ഉപകരണ ടോഗ്ലർ", - "running processes": "Running processes" + "running processes": "Running processes", + "recommend extensions": "Recommend extensions", + "settings-info-editor-recommend-extensions": "Suggest plugins when a file opens as plain text because no language mode is available.", + "extension recommendation title": "Extensions available for {extension}", + "extension recommendation message": "No syntax mode is installed for {extension}. Search plugins for \"{keyword}\".", + "extension request title": "No extension found for {extension}", + "extension request message": "Ask for a plugin so Acode can highlight this file type.", + "search plugins": "Search plugins", + "request plugin": "Request plugin" } diff --git a/src/lang/mm-unicode.json b/src/lang/mm-unicode.json index 18992b935..005ead025 100644 --- a/src/lang/mm-unicode.json +++ b/src/lang/mm-unicode.json @@ -766,5 +766,13 @@ "off": "Off", "quick tools height": "Quick tools height", "quick tools toggler": "Quick tools toggler", - "running processes": "Running processes" + "running processes": "Running processes", + "recommend extensions": "Recommend extensions", + "settings-info-editor-recommend-extensions": "Suggest plugins when a file opens as plain text because no language mode is available.", + "extension recommendation title": "Extensions available for {extension}", + "extension recommendation message": "No syntax mode is installed for {extension}. Search plugins for \"{keyword}\".", + "extension request title": "No extension found for {extension}", + "extension request message": "Ask for a plugin so Acode can highlight this file type.", + "search plugins": "Search plugins", + "request plugin": "Request plugin" } diff --git a/src/lang/mm-zawgyi.json b/src/lang/mm-zawgyi.json index 9320281e0..c9d53ee74 100644 --- a/src/lang/mm-zawgyi.json +++ b/src/lang/mm-zawgyi.json @@ -766,5 +766,13 @@ "off": "Off", "quick tools height": "Quick tools height", "quick tools toggler": "Quick tools toggler", - "running processes": "Running processes" + "running processes": "Running processes", + "recommend extensions": "Recommend extensions", + "settings-info-editor-recommend-extensions": "Suggest plugins when a file opens as plain text because no language mode is available.", + "extension recommendation title": "Extensions available for {extension}", + "extension recommendation message": "No syntax mode is installed for {extension}. Search plugins for \"{keyword}\".", + "extension request title": "No extension found for {extension}", + "extension request message": "Ask for a plugin so Acode can highlight this file type.", + "search plugins": "Search plugins", + "request plugin": "Request plugin" } diff --git a/src/lang/pl-pl.json b/src/lang/pl-pl.json index c46bd1766..2eb3f852a 100644 --- a/src/lang/pl-pl.json +++ b/src/lang/pl-pl.json @@ -766,5 +766,13 @@ "off": "Wyłączone", "quick tools height": "Wysokość szybkich narzędzi", "quick tools toggler": "Przełącznik szybkich narzędzi", - "running processes": "Running processes" + "running processes": "Running processes", + "recommend extensions": "Recommend extensions", + "settings-info-editor-recommend-extensions": "Suggest plugins when a file opens as plain text because no language mode is available.", + "extension recommendation title": "Extensions available for {extension}", + "extension recommendation message": "No syntax mode is installed for {extension}. Search plugins for \"{keyword}\".", + "extension request title": "No extension found for {extension}", + "extension request message": "Ask for a plugin so Acode can highlight this file type.", + "search plugins": "Search plugins", + "request plugin": "Request plugin" } diff --git a/src/lang/pt-br.json b/src/lang/pt-br.json index fd6a55183..065da232e 100644 --- a/src/lang/pt-br.json +++ b/src/lang/pt-br.json @@ -766,5 +766,13 @@ "off": "Desligado", "quick tools height": "Altura das ferramentas rápidas", "quick tools toggler": "Alternador de ferramentas rápidas", - "running processes": "Running processes" + "running processes": "Running processes", + "recommend extensions": "Recommend extensions", + "settings-info-editor-recommend-extensions": "Suggest plugins when a file opens as plain text because no language mode is available.", + "extension recommendation title": "Extensions available for {extension}", + "extension recommendation message": "No syntax mode is installed for {extension}. Search plugins for \"{keyword}\".", + "extension request title": "No extension found for {extension}", + "extension request message": "Ask for a plugin so Acode can highlight this file type.", + "search plugins": "Search plugins", + "request plugin": "Request plugin" } diff --git a/src/lang/pu-in.json b/src/lang/pu-in.json index f8ee0c857..cef15df34 100644 --- a/src/lang/pu-in.json +++ b/src/lang/pu-in.json @@ -766,5 +766,13 @@ "off": "ਬੰਦ", "quick tools height": "ਤੇਜ਼ ਟੂਲ ਦੀ ਉਚਾਈ", "quick tools toggler": "ਤੇਜ਼ ਟੂਲ ਟੌਗਲਰ", - "running processes": "Running processes" + "running processes": "Running processes", + "recommend extensions": "Recommend extensions", + "settings-info-editor-recommend-extensions": "Suggest plugins when a file opens as plain text because no language mode is available.", + "extension recommendation title": "Extensions available for {extension}", + "extension recommendation message": "No syntax mode is installed for {extension}. Search plugins for \"{keyword}\".", + "extension request title": "No extension found for {extension}", + "extension request message": "Ask for a plugin so Acode can highlight this file type.", + "search plugins": "Search plugins", + "request plugin": "Request plugin" } diff --git a/src/lang/ru-ru.json b/src/lang/ru-ru.json index 696b1d35d..5edbb1ab5 100644 --- a/src/lang/ru-ru.json +++ b/src/lang/ru-ru.json @@ -766,5 +766,13 @@ "off": "Выкл", "quick tools height": "Высота быстрых инструментов", "quick tools toggler": "Переключатель быстрых инструментов", - "running processes": "Running processes" + "running processes": "Running processes", + "recommend extensions": "Recommend extensions", + "settings-info-editor-recommend-extensions": "Suggest plugins when a file opens as plain text because no language mode is available.", + "extension recommendation title": "Extensions available for {extension}", + "extension recommendation message": "No syntax mode is installed for {extension}. Search plugins for \"{keyword}\".", + "extension request title": "No extension found for {extension}", + "extension request message": "Ask for a plugin so Acode can highlight this file type.", + "search plugins": "Search plugins", + "request plugin": "Request plugin" } diff --git a/src/lang/tl-ph.json b/src/lang/tl-ph.json index 2e2ffe982..79f775866 100644 --- a/src/lang/tl-ph.json +++ b/src/lang/tl-ph.json @@ -766,5 +766,13 @@ "off": "Off", "quick tools height": "Quick tools height", "quick tools toggler": "Quick tools toggler", - "running processes": "Running processes" + "running processes": "Running processes", + "recommend extensions": "Recommend extensions", + "settings-info-editor-recommend-extensions": "Suggest plugins when a file opens as plain text because no language mode is available.", + "extension recommendation title": "Extensions available for {extension}", + "extension recommendation message": "No syntax mode is installed for {extension}. Search plugins for \"{keyword}\".", + "extension request title": "No extension found for {extension}", + "extension request message": "Ask for a plugin so Acode can highlight this file type.", + "search plugins": "Search plugins", + "request plugin": "Request plugin" } diff --git a/src/lang/tr-tr.json b/src/lang/tr-tr.json index fd9434727..0323f2fbb 100644 --- a/src/lang/tr-tr.json +++ b/src/lang/tr-tr.json @@ -766,5 +766,13 @@ "off": "Kapalı", "quick tools height": "Hızlı araçlar yüksekliği", "quick tools toggler": "Hızlı araçlar değiştirici", - "running processes": "Running processes" + "running processes": "Running processes", + "recommend extensions": "Recommend extensions", + "settings-info-editor-recommend-extensions": "Suggest plugins when a file opens as plain text because no language mode is available.", + "extension recommendation title": "Extensions available for {extension}", + "extension recommendation message": "No syntax mode is installed for {extension}. Search plugins for \"{keyword}\".", + "extension request title": "No extension found for {extension}", + "extension request message": "Ask for a plugin so Acode can highlight this file type.", + "search plugins": "Search plugins", + "request plugin": "Request plugin" } diff --git a/src/lang/uk-ua.json b/src/lang/uk-ua.json index 0b35e291d..a7e0ca6c3 100644 --- a/src/lang/uk-ua.json +++ b/src/lang/uk-ua.json @@ -766,5 +766,13 @@ "off": "Вимк", "quick tools height": "Висота швидких інструментів", "quick tools toggler": "Перемикач швидких інструментів", - "running processes": "Running processes" + "running processes": "Running processes", + "recommend extensions": "Recommend extensions", + "settings-info-editor-recommend-extensions": "Suggest plugins when a file opens as plain text because no language mode is available.", + "extension recommendation title": "Extensions available for {extension}", + "extension recommendation message": "No syntax mode is installed for {extension}. Search plugins for \"{keyword}\".", + "extension request title": "No extension found for {extension}", + "extension request message": "Ask for a plugin so Acode can highlight this file type.", + "search plugins": "Search plugins", + "request plugin": "Request plugin" } diff --git a/src/lang/uz-uz.json b/src/lang/uz-uz.json index 1c4f0eef1..d348a92d6 100644 --- a/src/lang/uz-uz.json +++ b/src/lang/uz-uz.json @@ -766,5 +766,13 @@ "off": "Off", "quick tools height": "Quick tools height", "quick tools toggler": "Quick tools toggler", - "running processes": "Running processes" + "running processes": "Running processes", + "recommend extensions": "Recommend extensions", + "settings-info-editor-recommend-extensions": "Suggest plugins when a file opens as plain text because no language mode is available.", + "extension recommendation title": "Extensions available for {extension}", + "extension recommendation message": "No syntax mode is installed for {extension}. Search plugins for \"{keyword}\".", + "extension request title": "No extension found for {extension}", + "extension request message": "Ask for a plugin so Acode can highlight this file type.", + "search plugins": "Search plugins", + "request plugin": "Request plugin" } diff --git a/src/lang/vi-vn.json b/src/lang/vi-vn.json index eab04aeb2..5eca509e8 100644 --- a/src/lang/vi-vn.json +++ b/src/lang/vi-vn.json @@ -766,5 +766,13 @@ "off": "Tắt", "quick tools height": "Chiều cao công cụ nhanh", "quick tools toggler": "Bật/tắt công cụ nhanh", - "running processes": "Running processes" + "running processes": "Running processes", + "recommend extensions": "Recommend extensions", + "settings-info-editor-recommend-extensions": "Suggest plugins when a file opens as plain text because no language mode is available.", + "extension recommendation title": "Extensions available for {extension}", + "extension recommendation message": "No syntax mode is installed for {extension}. Search plugins for \"{keyword}\".", + "extension request title": "No extension found for {extension}", + "extension request message": "Ask for a plugin so Acode can highlight this file type.", + "search plugins": "Search plugins", + "request plugin": "Request plugin" } diff --git a/src/lang/zh-cn.json b/src/lang/zh-cn.json index e55b2ba76..8165c6da9 100644 --- a/src/lang/zh-cn.json +++ b/src/lang/zh-cn.json @@ -766,5 +766,13 @@ "off": "关闭", "quick tools height": "快捷工具栏高度", "quick tools toggler": "快捷工具切换按钮", - "running processes": "Running processes" + "running processes": "Running processes", + "recommend extensions": "Recommend extensions", + "settings-info-editor-recommend-extensions": "Suggest plugins when a file opens as plain text because no language mode is available.", + "extension recommendation title": "Extensions available for {extension}", + "extension recommendation message": "No syntax mode is installed for {extension}. Search plugins for \"{keyword}\".", + "extension request title": "No extension found for {extension}", + "extension request message": "Ask for a plugin so Acode can highlight this file type.", + "search plugins": "Search plugins", + "request plugin": "Request plugin" } diff --git a/src/lang/zh-hant.json b/src/lang/zh-hant.json index 075d8cb3d..6c8284c32 100644 --- a/src/lang/zh-hant.json +++ b/src/lang/zh-hant.json @@ -766,5 +766,13 @@ "off": "關閉", "quick tools height": "快捷工具欄高度", "quick tools toggler": "快捷工具切換按鈕", - "running processes": "Running processes" + "running processes": "Running processes", + "recommend extensions": "Recommend extensions", + "settings-info-editor-recommend-extensions": "Suggest plugins when a file opens as plain text because no language mode is available.", + "extension recommendation title": "Extensions available for {extension}", + "extension recommendation message": "No syntax mode is installed for {extension}. Search plugins for \"{keyword}\".", + "extension request title": "No extension found for {extension}", + "extension request message": "Ask for a plugin so Acode can highlight this file type.", + "search plugins": "Search plugins", + "request plugin": "Request plugin" } diff --git a/src/lang/zh-tw.json b/src/lang/zh-tw.json index 136a11553..8ea64caff 100644 --- a/src/lang/zh-tw.json +++ b/src/lang/zh-tw.json @@ -766,5 +766,13 @@ "off": "關閉", "quick tools height": "快捷工具列高度", "quick tools toggler": "快捷工具列切換按鈕", - "running processes": "Running processes" + "running processes": "Running processes", + "recommend extensions": "Recommend extensions", + "settings-info-editor-recommend-extensions": "Suggest plugins when a file opens as plain text because no language mode is available.", + "extension recommendation title": "Extensions available for {extension}", + "extension recommendation message": "No syntax mode is installed for {extension}. Search plugins for \"{keyword}\".", + "extension request title": "No extension found for {extension}", + "extension request message": "Ask for a plugin so Acode can highlight this file type.", + "search plugins": "Search plugins", + "request plugin": "Request plugin" } diff --git a/src/lib/editorFile.js b/src/lib/editorFile.js index 9c89af17b..7a452d4c9 100644 --- a/src/lib/editorFile.js +++ b/src/lib/editorFile.js @@ -227,6 +227,20 @@ function createSessionProxy(state, file) { }); } +function maybeRecommendLanguageModeExtension(file, modeInfo) { + if (appSettings.value.recommendExtensions === false) return; + if (modeInfo?.name !== "text" || modeInfo.supportsFile(file.filename)) return; + + void import("./languageModeRecommendations").then( + ({ default: recommend }) => { + recommend(file, modeInfo); + }, + (error) => { + console.warn("Failed to load language mode recommendations.", error); + }, + ); +} + /** * @typedef {'run'|'save'|'change'|'focus'|'blur'|'close'|'rename'|'load'|'loadError'|'loadStart'|'loadEnd'|'changeMode'|'changeEncoding'|'changeReadOnly'} FileEvents */ @@ -1295,6 +1309,7 @@ export default class EditorFile { // Store mode info for later use when creating editor view this.currentMode = mode; this.currentLanguageExtension = modeInfo?.getExtension() || null; + maybeRecommendLanguageModeExtension(this, modeInfo); // sets file icon this.#tab.lead( diff --git a/src/lib/languageModeRecommendations.js b/src/lib/languageModeRecommendations.js new file mode 100644 index 000000000..68cdd9e18 --- /dev/null +++ b/src/lib/languageModeRecommendations.js @@ -0,0 +1,175 @@ +import notificationManager from "lib/notificationManager"; +import Path from "utils/Path"; +import Url from "utils/Url"; +import config from "./config"; + +let instance = null; + +function withSupportedEditor(url) { + const separator = url.includes("?") ? "&" : "?"; + return `${url}${separator}supported_editor=${config.SUPPORTED_EDITOR}`; +} + +function getSearchKeyword(filename) { + const ext = Path.extname(filename || "") + .replace(/^\./, "") + .trim() + .toLowerCase(); + + if (!/^[a-z0-9][a-z0-9._+-]*$/.test(ext)) return ""; + + return ext; +} + +function getIssueUrl(keyword) { + const params = new URLSearchParams({ + template: "1_feature_request.yml", + labels: "new plugin idea,enhancement", + title: `Plugin request: ${keyword} syntax highlighting`, + }); + + return `${config.GITHUB_URL}/issues/new?${params}`; +} + +function formatString(value, replacements) { + return String(value || "").replace(/\{(\w+)\}/g, (_, key) => { + return replacements[key] ?? ""; + }); +} + +async function openUrl(url) { + if (window.cordova?.exec) { + const { default: customTab } = await import("./customTab"); + await customTab(url); + return; + } + + window.open(url, "_blank", "noopener,noreferrer"); +} + +async function openExtensions(keyword) { + const { openWithSearch } = await import("sidebarApps/extensions"); + openWithSearch(keyword); +} + +function hasPlainTextFallback(modeInfo, filename) { + return modeInfo?.name === "text" && !modeInfo.supportsFile(filename); +} + +class LanguageModeRecommendations { + notifiedKeywords = new Set(); + pendingKeywords = new Set(); + availabilityCache = new Map(); + + async getPluginAvailability(keyword) { + if (this.availabilityCache.has(keyword)) { + return this.availabilityCache.get(keyword); + } + + const availability = fetch( + withSupportedEditor( + Url.join( + config.API_BASE, + `plugins?name=${encodeURIComponent(`mode:${keyword}`)}`, + ), + ), + ) + .then((response) => (response.ok ? response.json() : [])) + .then((plugins) => Array.isArray(plugins) && plugins.length > 0) + .catch(() => false); + + this.availabilityCache.set(keyword, availability); + return availability; + } + + recommend(file, modeInfo) { + if (!file || file.type !== "editor") return; + + const filename = file.filename || ""; + if (!hasPlainTextFallback(modeInfo, filename)) return; + + const keyword = getSearchKeyword(filename); + if ( + !keyword || + this.notifiedKeywords.has(keyword) || + this.pendingKeywords.has(keyword) + ) { + return; + } + + this.pendingKeywords.add(keyword); + void this.showRecommendation(keyword) + .then(() => { + this.notifiedKeywords.add(keyword); + }) + .catch((error) => { + console.warn("Failed to show extension recommendation.", error); + }) + .finally(() => { + this.pendingKeywords.delete(keyword); + }); + } + + async showRecommendation(keyword) { + const hasPlugins = await this.getPluginAvailability(keyword); + const displayExt = `.${keyword}`; + + if (hasPlugins) { + notificationManager.pushNotification({ + title: formatString(strings["extension recommendation title"], { + extension: displayExt, + keyword: `mode:${keyword}`, + }), + message: formatString(strings["extension recommendation message"], { + extension: displayExt, + keyword: `mode:${keyword}`, + }), + icon: "extension", + type: "info", + action: () => openExtensions(`mode:${keyword}`), + actions: [ + { + text: strings["search plugins"], + icon: "search", + action: () => openExtensions(`mode:${keyword}`), + }, + ], + }); + return; + } + + const issueUrl = getIssueUrl(keyword); + notificationManager.pushNotification({ + title: formatString(strings["extension request title"], { + extension: displayExt, + keyword, + }), + message: formatString(strings["extension request message"], { + extension: displayExt, + keyword, + }), + icon: "extension", + type: "warning", + action: () => openUrl(issueUrl), + actions: [ + { + text: strings["request plugin"], + icon: "open_in_new", + action: () => openUrl(issueUrl), + }, + ], + }); + } +} + +function getLanguageModeRecommendations() { + if (!instance) { + instance = new LanguageModeRecommendations(); + } + + return instance; +} + +export default function recommendLanguageModeExtension(file, modeInfo) { + getLanguageModeRecommendations().recommend(file, modeInfo); +} diff --git a/src/lib/notificationManager.js b/src/lib/notificationManager.js index 56ffee4b9..0a4bde492 100644 --- a/src/lib/notificationManager.js +++ b/src/lib/notificationManager.js @@ -12,6 +12,7 @@ import Ref from "html-tag-js/ref"; * @prop {number} [props.time] * @prop {(notification: NotificationProps) => void} [props.action] * @prop {(notification: NotificationProps) => void} [props.onDismiss] + * @prop {{text:string, icon?:string, action:(notification: NotificationProps) => void}[]} [props.actions] * @prop {() => number} [props.progress] * @prop {() => loading} [props.loading = false] * @prop {"info"|"success"|"warning"|"error"} [props.type] @@ -200,6 +201,24 @@ class NotificationManager { />
{safeMessage}
+ {Array.isArray(notification.actions) && + notification.actions.length > 0 && ( +
+ {notification.actions.map((action) => ( + + ))} +
+ )} ); } diff --git a/src/lib/settings.js b/src/lib/settings.js index 1e63af9af..959b60986 100644 --- a/src/lib/settings.js +++ b/src/lib/settings.js @@ -152,6 +152,7 @@ class Settings { liveAutoCompletion: true, localWordCompletion: true, languageCompletion: true, + recommendExtensions: true, useEmmet: true, autoIndent: true, codeFolding: true, diff --git a/src/settings/editorSettings.js b/src/settings/editorSettings.js index 2ee5b0b46..572d29b8b 100644 --- a/src/settings/editorSettings.js +++ b/src/settings/editorSettings.js @@ -140,6 +140,13 @@ export default function editorSettings() { info: strings["settings-info-editor-language-completion"], category: categories.assistance, }, + { + key: "recommendExtensions", + text: strings["recommend extensions"], + checkbox: values.recommendExtensions ?? true, + info: strings["settings-info-editor-recommend-extensions"], + category: categories.assistance, + }, { key: "useEmmet", text: strings["use emmet"], diff --git a/src/sidebarApps/extensions/index.js b/src/sidebarApps/extensions/index.js index 07e14cc8a..bc55678e9 100644 --- a/src/sidebarApps/extensions/index.js +++ b/src/sidebarApps/extensions/index.js @@ -27,6 +27,7 @@ let container = null; let $searchResult = null; const LIMIT = 50; +const SEARCH_INPUT_WAIT_TIMEOUT = 1000; let currentPage = 1; let hasMore = true; let isLoading = false; @@ -214,40 +215,86 @@ async function loadFilteredPlugins(filterState, isInitial = false) { async function searchPlugin() { clearTimeout(searchTimeout); searchTimeout = setTimeout(async () => { - // Clear filter when searching - currentFilter = null; - filterHasMore = true; - isFilterLoading = false; - $searchResult.onscroll = null; + await runSearch(this.value); + }, 500); +} - $searchResult.content = ""; - const status = await helpers.checkAPIStatus(); - if (!status) { - $searchResult.content = ( - {strings.api_error} - ); - return; - } +async function runSearch(query) { + // Clear filter when searching + currentFilter = null; + filterHasMore = true; + isFilterLoading = false; + $searchResult.onscroll = null; + + $searchResult.content = ""; + const status = await helpers.checkAPIStatus(); + if (!status) { + $searchResult.content = {strings.api_error}; + return; + } - const query = this.value; - if (!query) return; + query = String(query || "").trim(); + if (!query) return; - try { - $searchResult.classList.add("loading"); - const plugins = await fsOperation( - withSupportedEditor(Url.join(config.API_BASE, `plugins?name=${query}`)), - ).readFile("json"); + try { + $searchResult.classList.add("loading"); + const plugins = await fsOperation( + withSupportedEditor( + Url.join(config.API_BASE, `plugins?name=${encodeURIComponent(query)}`), + ), + ).readFile("json"); - installedPlugins = await listInstalledPlugins(); - $searchResult.content = plugins.map(ListItem); - updateHeight($searchResult); - } catch (error) { - window.log("error", error); - $searchResult.content = {strings.error}; - } finally { - $searchResult.classList.remove("loading"); - } - }, 500); + installedPlugins = await listInstalledPlugins(); + $searchResult.content = plugins.length ? ( + plugins.map(ListItem) + ) : ( + + {strings["no plugins found"] || strings.empty || "No plugins found"} + + ); + updateHeight($searchResult); + } catch (error) { + window.log("error", error); + $searchResult.content = {strings.error}; + } finally { + $searchResult.classList.remove("loading"); + } +} + +function getSearchInput() { + return container?.querySelector('input[name="search-ext"]'); +} + +function waitForSearchInput() { + const startTime = Date.now(); + + return new Promise((resolve) => { + const check = () => { + const searchInput = getSearchInput(); + if (searchInput || Date.now() - startTime >= SEARCH_INPUT_WAIT_TIMEOUT) { + resolve(searchInput); + return; + } + + requestAnimationFrame(check); + }; + + check(); + }); +} + +export async function openWithSearch(query) { + Sidebar.show(); + document + .querySelector('[data-action="sidebar-app"][data-id="extensions"]') + ?.click(); + + const searchInput = await waitForSearchInput(); + if (!searchInput) return; + + searchInput.value = query; + clearTimeout(searchTimeout); + void runSearch(query); } async function filterPlugins() { diff --git a/src/styles/notification.scss b/src/styles/notification.scss index 80c5b4844..a931e81d3 100644 --- a/src/styles/notification.scss +++ b/src/styles/notification.scss @@ -69,6 +69,57 @@ hyphens: auto; } + .notification-actions { + display: flex; + flex-wrap: wrap; + justify-content: flex-end; + gap: 6px; + width: 100%; + margin-top: -2px; + } + + .notification-action { + display: inline-flex; + align-items: center; + justify-content: center; + gap: 5px; + min-height: 28px; + max-width: 100%; + padding: 0 9px; + border: 1px solid color-mix(in srgb, var(--button-background-color) 45%, transparent); + border-radius: 5px; + color: var(--button-background-color); + background: color-mix(in srgb, var(--button-background-color) 9%, transparent); + font-size: 12px; + font-weight: 500; + line-height: 1.2; + transition: + background-color 0.2s ease, + border-color 0.2s ease, + transform 0.2s ease; + + &:active { + transform: scale(0.98); + } + + &:focus-visible { + outline: 2px solid color-mix(in srgb, var(--button-background-color) 40%, transparent); + outline-offset: 2px; + } + + .icon { + font-size: 14px; + flex-shrink: 0; + } + + span:not(.icon) { + min-width: 0; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + } + &.hiding { transform: translateX(120%); opacity: 0; @@ -91,4 +142,4 @@ color: var(--error-color); } } -} \ No newline at end of file +}