From 35c3dfe0081c228d80f84d38205dc39184d2f922 Mon Sep 17 00:00:00 2001 From: Renkin <906155099@qq.com> Date: Tue, 31 Oct 2023 14:13:25 +0800 Subject: [PATCH 1/2] feat: support insert button on en website --- src/contentScript.js | 68 ++++++++++++----------- src/locales/en.js | 101 ++++++++++++++++++++--------------- src/locales/index.js | 19 ++++--- src/locales/{cn.js => zh.js} | 16 +++++- 4 files changed, 120 insertions(+), 84 deletions(-) rename src/locales/{cn.js => zh.js} (58%) diff --git a/src/contentScript.js b/src/contentScript.js index e018861..64c257d 100644 --- a/src/contentScript.js +++ b/src/contentScript.js @@ -13,7 +13,11 @@ import { } from "./utils"; import zenAble from "./zen/zenMode"; import hideFailCases from "./submission/hideFailCases"; - +import { t as tt, lang } from "./locales"; +let documentLang = document.documentElement.lang; +const t = (keypath, slotText) => tt(keypath, slotText, documentLang); +// console.log("lang", lang); +// lang = document.documentElement.lang // WTF! ant message didn't go well with chrome extension? const message = { success({ content }) { @@ -222,7 +226,7 @@ function goToVisDebug() { }; const prefixMap = { Python3: ` - # 如何你在调试链表题目,手动生成链表很麻烦,想快速生成链表可以注释如下方法,并使用如下方法,输入一个数组,返回一个链表 + # ${t("app.linkedListCommnet")} # eg:head = ListNodes([4,2,1,3]).head # class ListNodes: # def __init__(self, vals)->ListNode: @@ -234,7 +238,7 @@ function goToVisDebug() { # self.head = dummy.next `, JavaScript: ` -// 如何你在调试链表题目,手动生成链表很麻烦,想快速生成链表可以注释如下方法,并使用如下方法,输入一个数组,返回一个链表 +// ${t("app.linkedListCommnet")} // eg:head = ListNodes([4,2,1,3]).head // function ListNodes(vals) { // let cur = new ListNode() @@ -310,18 +314,18 @@ using namespace std; }; const suffixMap = { Python3: ` -# 替换下方的 xxx 为主函数名, yyy 为测试用例参数开启调试 +# ${t("app.visualDebugComment")} Solution().xxx(yyy) `, JavaScript: ` -// 替换下方的 xxx 为主函数名, yyy 为测试用例参数开启调试 +// ${t("app.visualDebugComment")} xxx(yyy) `, "C++": ` int main() { Solution s; - // 替换下方的 xxx 为主函数名, yyy 为测试用例参数开启调试 + // ${t("app.visualDebugComment")} s.xxx(yyy); return 0; } @@ -331,7 +335,7 @@ int main() }; if (!supportedLanguages.includes(language)) return message.warn({ - content: `当前仅支持 ${supportedLanguages.join(",")}`, + content: `${t("app.visualDebugSupport")} ${supportedLanguages.join(",")}`, }); const code = (prefixMap[language] || "") + @@ -348,17 +352,17 @@ int main() function getCodeLanguage() { const langMap = { - "cpp": "C++", - "python3": "Python3", - "java": "Java", - "c": "C", - "javascript": "JavaScript", - } - const l =window?.monaco?.editor?.getModels()[0]?.getLanguageId() || - localStorage.getItem("global_lang") - - return langMap[l.toLowerCase()] + cpp: "C++", + python3: "Python3", + java: "Java", + c: "C", + javascript: "JavaScript", + }; + const l = + window?.monaco?.editor?.getModels()[0]?.getLanguageId() || + localStorage.getItem("global_lang"); + return langMap[l.toLowerCase()]; } function insertButton() { const customBtnStyle = { @@ -369,10 +373,7 @@ function insertButton() { const buttons = document.querySelectorAll("button"); for (var i = 0; i < buttons.length; ++i) { - if (buttons[i].innerText.includes("运行")) { - - // 停止观察器 - // observer.disconnect(); + if (buttons[i].innerText.includes(t("Locale.app.run"))) { // const container = document.createElement("div"); @@ -400,7 +401,7 @@ function insertButton() { // }; // buttons[i].parentElement.prepend(copyButton); const writeSolutionButton = document.createElement("a"); - writeSolutionButton.innerText = "写题解"; + writeSolutionButton.innerText = t("Locale.app.wirteSolution"); Object.assign(writeSolutionButton.style, customBtnStyle); writeSolutionButton.className = buttons[i].className; @@ -413,7 +414,7 @@ function insertButton() { if (!desc) { return message.warn({ - content: "获取题目描述失败,请先切换到题目描述标签", + content: t("app.getProblemError"), }); } const title = document.title; @@ -426,7 +427,7 @@ function insertButton() { // const desc = document.querySelector("#question-detail-main-tabs")?.children[1]?.children[0]?.children[1]?.innerText; - const hide = message.loading("正在存储题目信息,请稍后~", 0); + const hide = message.loading(t("app.savingProblem"), 0); writeSolutionButton.setAttribute("disabled", true); // Dismiss manually and asynchronously setTimeout(() => { @@ -466,8 +467,7 @@ function insertButton() { ); } else { message.warn({ - content: - "使用 Github API 失败,已为您切换为普通模式,普通模式仅可自动带入题目名称,题目地址以及题解语言。", + content: t("app.githubAPIError"), }); setTimeout(() => { window.open( @@ -484,20 +484,24 @@ function insertButton() { }; // ReactDOM.render(, writeSolutionButton); - - buttons[i].parentElement.parentElement.prepend(writeSolutionButton); // ele.appendChild(writeSolutionButton); const visDebugButton = document.createElement("a"); - visDebugButton.innerText = "可视化调试"; + visDebugButton.innerText = t("Locale.app.visualizationDebug"); Object.assign(visDebugButton.style, customBtnStyle); visDebugButton.className = buttons[i].className; visDebugButton.onclick = goToVisDebug; + if (documentLang === "en") { + buttons[i].parentElement.prepend(visDebugButton); + buttons[i].parentElement.prepend(writeSolutionButton); + } else { + buttons[i].parentElement.parentElement.prepend(writeSolutionButton); - buttons[i].parentElement.parentElement.prepend(visDebugButton); + buttons[i].parentElement.parentElement.prepend(visDebugButton); + } inserted = true; - } else if (buttons[i].innerText.includes("提交")) { + } else if (buttons[i].innerText.includes(t("app.submit"))) { const click = buttons[i].onclick; buttons[i].onclick = (...args) => { click.call(buttons[i], ...args); @@ -536,7 +540,7 @@ const timerId = setInterval(() => { if (inserted && submitProxied) return clearInterval(timerId); if (retried > MAX_TRY) { clearInterval(timerId); - return console.error("初始化 chrome 插件 content script 失败"); + return console.error(t("app.initializeContentScriptFailed")); } insertButton(); diff --git a/src/locales/en.js b/src/locales/en.js index 8e28b42..856d91f 100644 --- a/src/locales/en.js +++ b/src/locales/en.js @@ -1,46 +1,61 @@ export const en = { - app: { - back: "Back to Home page", - viewSolution: "View solution", - viewInHandpickCollection:"This question has been collected in the handpick collection《{slotText}》Click to view", - notCollected: "This question has not been collected by LeetCode Plus, click to view all collected questions", - allCollected: "All collected questions", - writingExplanation: "Writing explanation", - goToTheWebsiteToUse: "Go to the website to use", - checkTips: - "Generally, as long as you turn on automatic updates, chrome will automatically update within five hours after the plug-in is updated. If you want to update as soon as possible, or if you disable automatic updates, you can check the latest version here.", - checkBtn: "Check for updates", - selfIntroduction: - "The author is a front-end architect with 40K stars on Github, the author of the leetcode-cheatsheet leetcode plugin, master all kinds of algorithm routines, and wrote hundreds of thousands of words of algorithm brushing e-books. Reply to the public account [电子书] to get.", - allSolutions: { - columns: { - title: "Title", - tag: "Tag", - }, + app: { + back: "Back to Home page", + viewSolution: "View solution", + viewInHandpickCollection: + "This question has been collected in the handpick collection《{slotText}》Click to view", + notCollected: + "This question has not been collected by LeetCode Plus, click to view all collected questions", + allCollected: "All collected questions", + writingExplanation: "Writing explanation", + goToTheWebsiteToUse: "Go to the website to use", + checkTips: + "Generally, as long as you turn on automatic updates, chrome will automatically update within five hours after the plug-in is updated. If you want to update as soon as possible, or if you disable automatic updates, you can check the latest version here.", + checkBtn: "Check for updates", + selfIntroduction: + "The author is a front-end architect with 40K stars on Github, the author of the leetcode-cheatsheet leetcode plugin, master all kinds of algorithm routines, and wrote hundreds of thousands of words of algorithm brushing e-books. Reply to the public account [电子书] to get.", + allSolutions: { + columns: { + title: "Title", + tag: "Tag", }, }, - codeTemplate: { - name: "Code Template", - }, - dataStructureVisualization: { - name: "Data Structure Visualization", - }, - - explanationTemplate: { - name: "Explanation Template", - }, - complexityQuickCheck: { - name: "Complexity Quick Check", - }, - learningRoute: { - name: "Learning Route", - }, - checkForUpdates: { - name: "Check for Updates", - }, - aboutMe: { - name: "About Me", - }, - }; - export default en; - \ No newline at end of file + initializeContentScriptFailed:"Failed to initialize the chrome plugin content script", + run: "Run", + submit: "Submit", + wirteSolution: "Write Solution", + visualizationDebug: "Visualization Debug", + linkedListCommnet: + "If you are debugging linked list questions, it is very troublesome to generate linked lists manually. If you want to quickly generate linked lists, you can comment out the following method and use the following method to enter an array and return a linked list.", + visualDebugComment: + "Replace xxx below with the main function name, yyy with the test case parameter, and turn on debugging", + getProblemError: + "Failed to get the problem description, please switch to the problem description tab first", + savingProblem: "Saving problem information, please wait~", + githubAPIError: + "Failed to use Github API, has been switched to normal mode, normal mode can only automatically bring in the problem name, problem address and solution language.", + }, + codeTemplate: { + name: "Code Template", + }, + dataStructureVisualization: { + name: "Data Structure Visualization", + }, + + explanationTemplate: { + name: "Explanation Template", + }, + complexityQuickCheck: { + name: "Complexity Quick Check", + }, + learningRoute: { + name: "Learning Route", + }, + checkForUpdates: { + name: "Check for Updates", + }, + aboutMe: { + name: "About Me", + }, +}; +export default en; diff --git a/src/locales/index.js b/src/locales/index.js index cbf34c4..c7d99a9 100644 --- a/src/locales/index.js +++ b/src/locales/index.js @@ -1,20 +1,20 @@ -import cn from "./cn"; +import zh from "./zh"; import en from "./en"; // import { getStorage, setStorage } from "../utils"; // const STORAGE_LANG_KEY = "LEETCODE_CHEAT_LANG"; const LEETCODE_URL_CN = "https://leetcode.cn"; const LEETCODE_URL_EN = "https://leetcode.com"; -const DEFAULT_LANG = "cn"; +const DEFAULT_LANG = "zh"; -let lang = DEFAULT_LANG; +export let lang = DEFAULT_LANG; const ALL_LANGS = { - cn, + zh, en, }; export const ALL_LANG_OPTIONS = { - cn: "简体中文", + zh: "简体中文", en: "English", }; @@ -22,7 +22,7 @@ export const AllLangs = Object.keys(ALL_LANGS); export const initLang = async (currentUrl) => { const isCnHref = currentUrl.includes(LEETCODE_URL_CN); - setLang(isCnHref ? "cn" : "en"); + setLang(isCnHref ? "zh" : "en"); }; export const setLang = (_lang) => { @@ -38,9 +38,12 @@ const getForPath = (obj, path) => { return result; }; -export const t = (keypath, slotText) => { - const langData ={ Locale: ALL_LANGS[lang] } +export const t = (keypath, slotText,l) => { + const langData ={ Locale: ALL_LANGS[l||lang] } if (!keypath) return ""; + if (!keypath.includes("Locale")) { + keypath = "Locale." + keypath + } let content = getForPath(langData, keypath); if (slotText) { if (Array.isArray(slotText)) { diff --git a/src/locales/cn.js b/src/locales/zh.js similarity index 58% rename from src/locales/cn.js rename to src/locales/zh.js index 6ca8fed..d8f3b57 100644 --- a/src/locales/cn.js +++ b/src/locales/zh.js @@ -2,7 +2,7 @@ export const cn = { app: { back: "返回主页", viewSolution: "查看本题题解", - viewInHandpickCollection:"该题已被收录到精选合集《{slotText}》点击查看", + viewInHandpickCollection: "该题已被收录到精选合集《{slotText}》点击查看", notCollected: "本题暂未被力扣加加收录,点击查看所有已收录题目~", allCollected: "所有已收录的题目", writingExplanation: "正在撰写题解...", @@ -18,6 +18,20 @@ export const cn = { tag: "标签", }, }, + initializeContentScriptFailed:"初始化 chrome 插件 content script 失败", + run: "运行", + submit: "提交", + wirteSolution: "写题解", + visualizationDebug: "可视化调试", + linkedListCommnet: + "如果你在调试链表题目,手动生成链表很麻烦,想快速生成链表可以注释如下方法,并使用如下方法,输入一个数组,返回一个链表", + visualDebugComment: + "替换下方的 xxx 为主函数名, yyy 为测试用例参数开启调试", + visualDebugSupport: "当前仅支持", + getProblemError: "获取题目描述失败,请先切换到题目描述标签页", + savingProblem: "正在存储题目信息,请稍后~", + githubAPIError: + "使用 Github API 失败,已为您切换为普通模式,普通模式仅可自动带入题目名称,题目地址以及题解语言。", }, codeTemplate: { name: "代码模板", From 4087ea4eb4614e179e33d6ec7e20c5026955f07a Mon Sep 17 00:00:00 2001 From: Renkin <906155099@qq.com> Date: Tue, 31 Oct 2023 14:14:37 +0800 Subject: [PATCH 2/2] chore: delete comment --- src/contentScript.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/contentScript.js b/src/contentScript.js index 64c257d..6bb8c29 100644 --- a/src/contentScript.js +++ b/src/contentScript.js @@ -13,11 +13,10 @@ import { } from "./utils"; import zenAble from "./zen/zenMode"; import hideFailCases from "./submission/hideFailCases"; -import { t as tt, lang } from "./locales"; +import { t as tt } from "./locales"; let documentLang = document.documentElement.lang; const t = (keypath, slotText) => tt(keypath, slotText, documentLang); -// console.log("lang", lang); -// lang = document.documentElement.lang + // WTF! ant message didn't go well with chrome extension? const message = { success({ content }) {