From 1917c6aeb76f7177268f6054d5752fffbdeaf4da Mon Sep 17 00:00:00 2001 From: sachin Date: Thu, 4 Jun 2026 22:29:28 +0530 Subject: [PATCH 1/7] added handle Cses submit and cses injected script to submit the cses problem from cph --- manifest-chrome.partial.json | 3 +- manifest-firefox.partial.json | 4 +- package-lock.json | 218 ++++++++++++++++++++++++++++++++++ package.json | 1 + src/csesInjectedScript.ts | 82 +++++++++++++ src/handleSubmit.ts | 72 +++++++++++ webpack.config.js | 1 + 7 files changed, 379 insertions(+), 2 deletions(-) create mode 100644 src/csesInjectedScript.ts diff --git a/manifest-chrome.partial.json b/manifest-chrome.partial.json index 399004f..987a6d8 100644 --- a/manifest-chrome.partial.json +++ b/manifest-chrome.partial.json @@ -1,8 +1,9 @@ { "manifest_version": 3, - "permissions": ["scripting", "webNavigation", "offscreen"], + "permissions": ["scripting", "webNavigation", "offscreen","tabs"], "host_permissions": [ "http://localhost/*", + "https://cses.fi/*", "https://codeforces.com/*", "https://maang.in/*" ], diff --git a/manifest-firefox.partial.json b/manifest-firefox.partial.json index fd764b9..224fcf5 100644 --- a/manifest-firefox.partial.json +++ b/manifest-firefox.partial.json @@ -6,9 +6,11 @@ "permissions": [ "scripting", "*://localhost/*", + "https://cses.fi/*", "*://codeforces.com/*", "*://maang.in/*", - "webNavigation" + "webNavigation", + "tabs" ], "browser_specific_settings": { "gecko": { diff --git a/package-lock.json b/package-lock.json index f6c87c8..81551d6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ }, "devDependencies": { "copy-webpack-plugin": "^14.0.0", + "merge-jsons-webpack-plugin": "^2.0.1", "prettier": "^3.8.3", "ts-loader": "^9.5.1", "typescript": "^5.5.3", @@ -460,6 +461,24 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.15.tgz", + "integrity": "sha512-EwOCDEex4quD37XhqM3omwtMoJjr//isUZz1JopUNWms+4Z2ViyM/k1YIRePpoVNnQhENnxtFjLaxNHrT7xIUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/browserslist": { "version": "4.23.2", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.2.tgz", @@ -587,6 +606,13 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, "node_modules/copy-webpack-plugin": { "version": "14.0.0", "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-14.0.0.tgz", @@ -850,6 +876,13 @@ "flat": "cli.js" } }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -859,6 +892,25 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/glob": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", + "integrity": "sha512-mRyN/EsN2SyNhKWykF3eEGhDpeNplMWaW18Bmh76tnOqk5TbELAVwFAYOCmKVssOYFrYvvLMguiA+NXO3ZTuVA==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.2", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -924,6 +976,25 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, "node_modules/interpret": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", @@ -1069,6 +1140,16 @@ "node": ">=8" } }, + "node_modules/merge-jsons-webpack-plugin": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/merge-jsons-webpack-plugin/-/merge-jsons-webpack-plugin-2.0.1.tgz", + "integrity": "sha512-8GP8rpOX3HSFsm7Gx+b3OAQR7yhgeAQvMqcZOJ+/cQIrqdak1c42a2T2vyeee8pzGPBf7pMLumthPh4CHgv2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob": "7.1.1" + } + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -1096,6 +1177,19 @@ "node": ">= 0.6" } }, + "node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", @@ -1118,6 +1212,16 @@ "node": ">=0.10.0" } }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, "node_modules/p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -1163,6 +1267,16 @@ "node": ">=8" } }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -1845,6 +1959,13 @@ "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", "dev": true + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" } }, "dependencies": { @@ -2220,6 +2341,22 @@ "color-convert": "^2.0.1" } }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.15.tgz", + "integrity": "sha512-EwOCDEex4quD37XhqM3omwtMoJjr//isUZz1JopUNWms+4Z2ViyM/k1YIRePpoVNnQhENnxtFjLaxNHrT7xIUg==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "browserslist": { "version": "4.23.2", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.2.tgz", @@ -2298,6 +2435,12 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, "copy-webpack-plugin": { "version": "14.0.0", "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-14.0.0.tgz", @@ -2482,12 +2625,32 @@ "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", "dev": true }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, "function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true }, + "glob": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", + "integrity": "sha512-mRyN/EsN2SyNhKWykF3eEGhDpeNplMWaW18Bmh76tnOqk5TbELAVwFAYOCmKVssOYFrYvvLMguiA+NXO3ZTuVA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.2", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, "glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -2534,6 +2697,22 @@ "resolve-cwd": "^3.0.0" } }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, "interpret": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", @@ -2640,6 +2819,15 @@ "p-locate": "^4.1.0" } }, + "merge-jsons-webpack-plugin": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/merge-jsons-webpack-plugin/-/merge-jsons-webpack-plugin-2.0.1.tgz", + "integrity": "sha512-8GP8rpOX3HSFsm7Gx+b3OAQR7yhgeAQvMqcZOJ+/cQIrqdak1c42a2T2vyeee8pzGPBf7pMLumthPh4CHgv2BA==", + "dev": true, + "requires": { + "glob": "7.1.1" + } + }, "merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -2661,6 +2849,15 @@ "mime-db": "1.52.0" } }, + "minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, "neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", @@ -2679,6 +2876,15 @@ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "requires": { + "wrappy": "1" + } + }, "p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -2709,6 +2915,12 @@ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true + }, "path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -3146,6 +3358,12 @@ "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true } } } diff --git a/package.json b/package.json index dd5582f..c5ef563 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "license": "MIT", "devDependencies": { "copy-webpack-plugin": "^14.0.0", + "merge-jsons-webpack-plugin": "^2.0.1", "prettier": "^3.8.3", "ts-loader": "^9.5.1", "typescript": "^5.5.3", diff --git a/src/csesInjectedScript.ts b/src/csesInjectedScript.ts new file mode 100644 index 0000000..d9934d8 --- /dev/null +++ b/src/csesInjectedScript.ts @@ -0,0 +1,82 @@ +import { ContentScriptData } from './types'; +import log from './log'; + +declare const browser: any; +if (typeof browser !== 'undefined') { + self.chrome = browser; +} + +log('cph-submit cses script injected'); + +const extMap: Record = { + 'cpp': 'solution.cpp', + 'c': 'solution.c', + 'java': 'solution.java', + 'python': 'solution.py', + 'pypy': 'solution.py', + 'rust': 'solution.rs', + 'javascript': 'solution.js', + 'ruby': 'solution.rb', + 'haskell': 'solution.hs', + 'pascal': 'solution.pas', + 'scala': 'solution.scala', +}; + +const langMap: Record = { + 'cpp': 'C++', + 'c': 'C', + 'java': 'Java', + 'python': 'Python3', + 'pypy': 'Python3', + 'rust': 'Rust', + 'javascript': 'Node.js', + 'ruby': 'Ruby', + 'haskell': 'Haskell', + 'pascal': 'Pascal', + 'scala': 'Scala', +}; +const idToKey: Record = { + 54: 'cpp', + 43: 'c', + 60: 'java', + 31: 'python', + 40: 'pypy', + 75: 'rust', + 55: 'javascript', + 67: 'ruby', + 12: 'haskell', +}; + +chrome.runtime.onMessage.addListener((message) => { + if (message.type !== 'cph-submit-cses') return; + + const { sourceCode, languageId } = message; + + const form = document.querySelector('form'); + if (!form) { + log('CSES form not found'); + return; + } + + + const fileInput = form.querySelector('input[type="file"]') as HTMLInputElement; + if (fileInput) { + const langKey = idToKey[languageId] ?? 'cpp'; + const fileName = extMap[langKey] ?? 'solution.cpp'; + const file = new File([sourceCode], fileName, { type: 'text/plain' }); + const dt = new DataTransfer(); + dt.items.add(file); + fileInput.files = dt.files; + } + + + const langSelect = form.querySelector('select[name="lang"]') as HTMLSelectElement; + if (langSelect) { + const langKey = idToKey[languageId] ?? 'cpp'; + langSelect.value = langMap[langKey] ?? 'C++'; + } + + + form.submit(); + log('CSES form submitted'); +}); \ No newline at end of file diff --git a/src/handleSubmit.ts b/src/handleSubmit.ts index 8e2aaf4..eab1e42 100644 --- a/src/handleSubmit.ts +++ b/src/handleSubmit.ts @@ -91,6 +91,17 @@ export const isAlgoZenithProblem = (problemUrl: string) => { return false; } }; +export const isCSESProblem = (problemUrl:string)=>{ + console.log(`problemURL-CSES ${problemUrl} `) + try{ + const url = new URL(problemUrl); + return( + url.hostname==='cses.fi' || url.hostname.endsWith('.cses.fi') + ); + }catch{ + return false; + } +} export const handleAlgoZenithSubmit = async ( problemName: string, @@ -140,7 +151,59 @@ export const handleAlgoZenithSubmit = async ( }, ); }; +export const handleCSESSubmit = async ( + problemName: string, + languageId: number, + sourceCode: string, + problemUrl: string, +) => { + log('Handling CSES submit for', problemUrl); + log('isCSES check:', isCSESProblem(problemUrl)); + + + const submitUrl = problemUrl + .replace('/task/', '/submit/') + .replace(/\/?$/, '/'); + + const tab = await chrome.tabs.create({ + active: true, + url: submitUrl, + }); + + const tabId = tab.id as number; + chrome.windows.update(tab.windowId, { focused: true }); + chrome.tabs.onUpdated.addListener( + function listener(updatedTabId, changeInfo) { + if (updatedTabId === tabId && changeInfo.status === 'complete') { + chrome.tabs.onUpdated.removeListener(listener); + + setTimeout(async () => { + if (typeof browser !== 'undefined') { + await browser.tabs.executeScript(tabId, { + file: '/dist/csesInjectedScript.js', + }); + } else { + await chrome.scripting.executeScript({ + target: { tabId, allFrames: false }, + files: ['/dist/csesInjectedScript.js'], + }); + } + + chrome.tabs.sendMessage(tabId, { + type: 'cph-submit-cses', + problemName, + languageId, + sourceCode, + url: problemUrl, + }); + + log('Message sent to CSES tab'); + }, 1000); + } + }, + ); +}; export const handleSubmit = async ( problemName: string, languageId: number, @@ -160,6 +223,15 @@ export const handleSubmit = async ( problemUrl, ); } + if(isCSESProblem(problemUrl)){ + + return handleCSESSubmit( + problemName, + languageId, + sourceCode, + problemUrl, + ); + } const submitTarget = resolveSubmitTarget(problemUrl); diff --git a/webpack.config.js b/webpack.config.js index 92da5af..813c502 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -6,6 +6,7 @@ module.exports = { backgroundScript: './src/backgroundScript.ts', injectedScript: './src/injectedScript.ts', algoZenithInjectedScript: './src/algoZenithInjectedScript.ts', + csesInjectedScript: './src/csesInjectedScript.ts', offscreen: './src/offscreen.ts', }, output: { From d905ce1cf0f5e1a705a2d1ee0254f7a69bc69a08 Mon Sep 17 00:00:00 2001 From: sachin Date: Fri, 5 Jun 2026 13:11:58 +0530 Subject: [PATCH 2/7] Fix id to key mapping for some langs --- manifest-chrome.partial.json | 2 +- src/csesInjectedScript.ts | 56 +++++++++++++++++++----------------- 2 files changed, 30 insertions(+), 28 deletions(-) diff --git a/manifest-chrome.partial.json b/manifest-chrome.partial.json index 987a6d8..9c29acb 100644 --- a/manifest-chrome.partial.json +++ b/manifest-chrome.partial.json @@ -1,6 +1,6 @@ { "manifest_version": 3, - "permissions": ["scripting", "webNavigation", "offscreen","tabs"], + "permissions": ["scripting", "webNavigation", "offscreen","tabs"], "host_permissions": [ "http://localhost/*", "https://cses.fi/*", diff --git a/src/csesInjectedScript.ts b/src/csesInjectedScript.ts index d9934d8..96c5010 100644 --- a/src/csesInjectedScript.ts +++ b/src/csesInjectedScript.ts @@ -9,49 +9,48 @@ if (typeof browser !== 'undefined') { log('cph-submit cses script injected'); const extMap: Record = { - 'cpp': 'solution.cpp', - 'c': 'solution.c', - 'java': 'solution.java', - 'python': 'solution.py', - 'pypy': 'solution.py', - 'rust': 'solution.rs', + 'cpp': 'solution.cpp', + 'c': 'solution.c', + 'java': 'solution.java', + 'python': 'solution.py', + 'rust': 'solution.rs', 'javascript': 'solution.js', - 'ruby': 'solution.rb', - 'haskell': 'solution.hs', - 'pascal': 'solution.pas', - 'scala': 'solution.scala', + 'ruby': 'solution.rb', + 'haskell': 'solution.hs', + 'scala': 'solution.scala', + 'pascal': 'solution.pas' }; const langMap: Record = { - 'cpp': 'C++', - 'c': 'C', - 'java': 'Java', - 'python': 'Python3', - 'pypy': 'Python3', - 'rust': 'Rust', + 'cpp': 'C++', + 'c': 'C', + 'java': 'Java', + 'python': 'Python3', + 'rust': 'Rust', 'javascript': 'Node.js', - 'ruby': 'Ruby', - 'haskell': 'Haskell', - 'pascal': 'Pascal', - 'scala': 'Scala', + 'ruby': 'Ruby', + 'haskell': 'Haskell', + 'scala': 'Scala', + 'pascal': 'Pascal' }; const idToKey: Record = { - 54: 'cpp', + 54: 'cpp', 50: 'cpp', 42: 'cpp', 61: 'cpp', 89: 'cpp', 91: 'cpp', 59: 'cpp', 2: 'cpp', 52: 'cpp', 43: 'c', - 60: 'java', - 31: 'python', - 40: 'pypy', - 75: 'rust', - 55: 'javascript', + 36: 'java', 60: 'java', 87: 'java', + 7: 'python', 31: 'python', 40: 'python', 41: 'python', 70: 'python', + 75: 'rust', 98: 'rust', + 34: 'javascript', 55: 'javascript', 67: 'ruby', 12: 'haskell', + 20: 'scala', + 3: 'pascal', 4: 'pascal', 51: 'pascal' }; chrome.runtime.onMessage.addListener((message) => { if (message.type !== 'cph-submit-cses') return; const { sourceCode, languageId } = message; - + const form = document.querySelector('form'); if (!form) { log('CSES form not found'); @@ -61,7 +60,10 @@ chrome.runtime.onMessage.addListener((message) => { const fileInput = form.querySelector('input[type="file"]') as HTMLInputElement; if (fileInput) { + log(`langID is ${languageId}`); + const langKey = idToKey[languageId] ?? 'cpp'; + log(`langKey is ${langKey}`); const fileName = extMap[langKey] ?? 'solution.cpp'; const file = new File([sourceCode], fileName, { type: 'text/plain' }); const dt = new DataTransfer(); From 368cd1258d0449846adc6c86450fb2436bdabb66 Mon Sep 17 00:00:00 2001 From: sachin Date: Sat, 6 Jun 2026 18:57:17 +0530 Subject: [PATCH 3/7] removed extra TABS permission from manifest.json and made it working for chrome aswell --- manifest-chrome.partial.json | 4 ++-- manifest-firefox.partial.json | 4 ++-- src/handleSubmit.ts | 34 ++++++++++++++++++---------------- 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/manifest-chrome.partial.json b/manifest-chrome.partial.json index 9c29acb..2fe1851 100644 --- a/manifest-chrome.partial.json +++ b/manifest-chrome.partial.json @@ -1,11 +1,11 @@ { "manifest_version": 3, - "permissions": ["scripting", "webNavigation", "offscreen","tabs"], + "permissions": ["scripting", "webNavigation", "offscreen"], "host_permissions": [ "http://localhost/*", "https://cses.fi/*", "https://codeforces.com/*", - "https://maang.in/*" + "https://maang.in/*" ], "background": { "service_worker": "dist/backgroundScript.js", diff --git a/manifest-firefox.partial.json b/manifest-firefox.partial.json index 224fcf5..45a8c86 100644 --- a/manifest-firefox.partial.json +++ b/manifest-firefox.partial.json @@ -9,8 +9,8 @@ "https://cses.fi/*", "*://codeforces.com/*", "*://maang.in/*", - "webNavigation", - "tabs" + "webNavigation" + ], "browser_specific_settings": { "gecko": { diff --git a/src/handleSubmit.ts b/src/handleSubmit.ts index eab1e42..1711927 100644 --- a/src/handleSubmit.ts +++ b/src/handleSubmit.ts @@ -160,7 +160,6 @@ export const handleCSESSubmit = async ( log('Handling CSES submit for', problemUrl); log('isCSES check:', isCSESProblem(problemUrl)); - const submitUrl = problemUrl .replace('/task/', '/submit/') .replace(/\/?$/, '/'); @@ -179,26 +178,29 @@ export const handleCSESSubmit = async ( chrome.tabs.onUpdated.removeListener(listener); setTimeout(async () => { - if (typeof browser !== 'undefined') { - await browser.tabs.executeScript(tabId, { - file: '/dist/csesInjectedScript.js', - }); - } else { + + if (typeof chrome !== 'undefined' && chrome.scripting) { await chrome.scripting.executeScript({ target: { tabId, allFrames: false }, files: ['/dist/csesInjectedScript.js'], }); - } - - chrome.tabs.sendMessage(tabId, { - type: 'cph-submit-cses', - problemName, - languageId, - sourceCode, - url: problemUrl, - }); + } else if (typeof browser !== 'undefined') { + await browser.tabs.executeScript(tabId, { + file: '/dist/csesInjectedScript.js', + }); + } + setTimeout(() => { + chrome.tabs.sendMessage(tabId, { + type: 'cph-submit-cses', + problemName, + languageId, + sourceCode, + url: problemUrl, + }); - log('Message sent to CSES tab'); + log('Message sent to CSES tab'); + }, 500); + }, 1000); } }, From d95fac718d5c8dcceab5e455226b8c18415b31a5 Mon Sep 17 00:00:00 2001 From: sachin Date: Sat, 6 Jun 2026 19:37:53 +0530 Subject: [PATCH 4/7] Readme updated --- readme.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/readme.md b/readme.md index 945889c..6bab465 100644 --- a/readme.md +++ b/readme.md @@ -1,7 +1,6 @@ # ![ICON](icon-48.png) cph-submit -Browser add on that enables Codeforces submit with -[Competitive Programming Helper](https://github.com/agrawal-d/cph) +Browser add on that enables direct submit on platforms like codeforces and CSES with [Competitive Programming Helper](https://github.com/agrawal-d/cph) Available for Firefox and Google Chrome. From a3e6102227b873d357f981516b1b76a55545a61d Mon Sep 17 00:00:00 2001 From: sachin Date: Sat, 6 Jun 2026 21:15:51 +0530 Subject: [PATCH 5/7] fixed package and readme file and added alert in CSES script --- package-lock.json | 218 -------------------------------------- package.json | 1 - src/csesInjectedScript.ts | 92 +++++++++------- 3 files changed, 56 insertions(+), 255 deletions(-) diff --git a/package-lock.json b/package-lock.json index 81551d6..f6c87c8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,6 @@ }, "devDependencies": { "copy-webpack-plugin": "^14.0.0", - "merge-jsons-webpack-plugin": "^2.0.1", "prettier": "^3.8.3", "ts-loader": "^9.5.1", "typescript": "^5.5.3", @@ -461,24 +460,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/brace-expansion": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.15.tgz", - "integrity": "sha512-EwOCDEex4quD37XhqM3omwtMoJjr//isUZz1JopUNWms+4Z2ViyM/k1YIRePpoVNnQhENnxtFjLaxNHrT7xIUg==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, "node_modules/browserslist": { "version": "4.23.2", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.2.tgz", @@ -606,13 +587,6 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true, - "license": "MIT" - }, "node_modules/copy-webpack-plugin": { "version": "14.0.0", "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-14.0.0.tgz", @@ -876,13 +850,6 @@ "flat": "cli.js" } }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true, - "license": "ISC" - }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -892,25 +859,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-mRyN/EsN2SyNhKWykF3eEGhDpeNplMWaW18Bmh76tnOqk5TbELAVwFAYOCmKVssOYFrYvvLMguiA+NXO3ZTuVA==", - "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.2", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - } - }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -976,25 +924,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dev": true, - "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true, - "license": "ISC" - }, "node_modules/interpret": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", @@ -1140,16 +1069,6 @@ "node": ">=8" } }, - "node_modules/merge-jsons-webpack-plugin": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/merge-jsons-webpack-plugin/-/merge-jsons-webpack-plugin-2.0.1.tgz", - "integrity": "sha512-8GP8rpOX3HSFsm7Gx+b3OAQR7yhgeAQvMqcZOJ+/cQIrqdak1c42a2T2vyeee8pzGPBf7pMLumthPh4CHgv2BA==", - "dev": true, - "license": "MIT", - "dependencies": { - "glob": "7.1.1" - } - }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -1177,19 +1096,6 @@ "node": ">= 0.6" } }, - "node_modules/minimatch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", @@ -1212,16 +1118,6 @@ "node": ">=0.10.0" } }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, "node_modules/p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -1267,16 +1163,6 @@ "node": ">=8" } }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -1959,13 +1845,6 @@ "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", "dev": true - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true, - "license": "ISC" } }, "dependencies": { @@ -2341,22 +2220,6 @@ "color-convert": "^2.0.1" } }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.15.tgz", - "integrity": "sha512-EwOCDEex4quD37XhqM3omwtMoJjr//isUZz1JopUNWms+4Z2ViyM/k1YIRePpoVNnQhENnxtFjLaxNHrT7xIUg==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, "browserslist": { "version": "4.23.2", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.2.tgz", @@ -2435,12 +2298,6 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, "copy-webpack-plugin": { "version": "14.0.0", "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-14.0.0.tgz", @@ -2625,32 +2482,12 @@ "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", "dev": true }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, "function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true }, - "glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-mRyN/EsN2SyNhKWykF3eEGhDpeNplMWaW18Bmh76tnOqk5TbELAVwFAYOCmKVssOYFrYvvLMguiA+NXO3ZTuVA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.2", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, "glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -2697,22 +2534,6 @@ "resolve-cwd": "^3.0.0" } }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, "interpret": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", @@ -2819,15 +2640,6 @@ "p-locate": "^4.1.0" } }, - "merge-jsons-webpack-plugin": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/merge-jsons-webpack-plugin/-/merge-jsons-webpack-plugin-2.0.1.tgz", - "integrity": "sha512-8GP8rpOX3HSFsm7Gx+b3OAQR7yhgeAQvMqcZOJ+/cQIrqdak1c42a2T2vyeee8pzGPBf7pMLumthPh4CHgv2BA==", - "dev": true, - "requires": { - "glob": "7.1.1" - } - }, "merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -2849,15 +2661,6 @@ "mime-db": "1.52.0" } }, - "minimatch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, "neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", @@ -2876,15 +2679,6 @@ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "requires": { - "wrappy": "1" - } - }, "p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -2915,12 +2709,6 @@ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true - }, "path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -3358,12 +3146,6 @@ "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", "dev": true - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true } } } diff --git a/package.json b/package.json index c5ef563..dd5582f 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,6 @@ "license": "MIT", "devDependencies": { "copy-webpack-plugin": "^14.0.0", - "merge-jsons-webpack-plugin": "^2.0.1", "prettier": "^3.8.3", "ts-loader": "^9.5.1", "typescript": "^5.5.3", diff --git a/src/csesInjectedScript.ts b/src/csesInjectedScript.ts index 96c5010..0cd544a 100644 --- a/src/csesInjectedScript.ts +++ b/src/csesInjectedScript.ts @@ -9,76 +9,96 @@ if (typeof browser !== 'undefined') { log('cph-submit cses script injected'); const extMap: Record = { - 'cpp': 'solution.cpp', - 'c': 'solution.c', - 'java': 'solution.java', - 'python': 'solution.py', - 'rust': 'solution.rs', - 'javascript': 'solution.js', - 'ruby': 'solution.rb', - 'haskell': 'solution.hs', - 'scala': 'solution.scala', - 'pascal': 'solution.pas' + cpp: `.cpp`, + c: '.c', + java: '.java', + python: '.py', + rust: '.rs', + javascript: '.js', + ruby: '.rb', + haskell: '.hs', + scala: '.scala', + pascal: '.pas', }; const langMap: Record = { - 'cpp': 'C++', - 'c': 'C', - 'java': 'Java', - 'python': 'Python3', - 'rust': 'Rust', - 'javascript': 'Node.js', - 'ruby': 'Ruby', - 'haskell': 'Haskell', - 'scala': 'Scala', - 'pascal': 'Pascal' + cpp: 'C++', + c: 'C', + java: 'Java', + python: 'Python3', + rust: 'Rust', + javascript: 'Node.js', + ruby: 'Ruby', + haskell: 'Haskell', + scala: 'Scala', + pascal: 'Pascal', }; const idToKey: Record = { - 54: 'cpp', 50: 'cpp', 42: 'cpp', 61: 'cpp', 89: 'cpp', 91: 'cpp', 59: 'cpp', 2: 'cpp', 52: 'cpp', + 54: 'cpp', + 50: 'cpp', + 42: 'cpp', + 61: 'cpp', + 89: 'cpp', + 91: 'cpp', + 59: 'cpp', + 2: 'cpp', + 52: 'cpp', 43: 'c', - 36: 'java', 60: 'java', 87: 'java', - 7: 'python', 31: 'python', 40: 'python', 41: 'python', 70: 'python', - 75: 'rust', 98: 'rust', - 34: 'javascript', 55: 'javascript', + 36: 'java', + 60: 'java', + 87: 'java', + 7: 'python', + 31: 'python', + 40: 'python', + 41: 'python', + 70: 'python', + 75: 'rust', + 98: 'rust', + 34: 'javascript', + 55: 'javascript', 67: 'ruby', 12: 'haskell', 20: 'scala', - 3: 'pascal', 4: 'pascal', 51: 'pascal' + 3: 'pascal', + 4: 'pascal', + 51: 'pascal', }; chrome.runtime.onMessage.addListener((message) => { if (message.type !== 'cph-submit-cses') return; - const { sourceCode, languageId } = message; - + const { sourceCode, problemName, languageId } = message; + const form = document.querySelector('form'); if (!form) { + alert('CSES form not found'); log('CSES form not found'); return; } - - const fileInput = form.querySelector('input[type="file"]') as HTMLInputElement; + const fileInput = form.querySelector( + 'input[type="file"]', + ) as HTMLInputElement; if (fileInput) { log(`langID is ${languageId}`); const langKey = idToKey[languageId] ?? 'cpp'; log(`langKey is ${langKey}`); - const fileName = extMap[langKey] ?? 'solution.cpp'; - const file = new File([sourceCode], fileName, { type: 'text/plain' }); + const fileName = `${problemName}+extMap[langKey]`; + const file = new File([sourceCode], fileName, { type: 'text/plain' }); const dt = new DataTransfer(); dt.items.add(file); fileInput.files = dt.files; } - - const langSelect = form.querySelector('select[name="lang"]') as HTMLSelectElement; + const langSelect = form.querySelector( + 'select[name="lang"]', + ) as HTMLSelectElement; if (langSelect) { const langKey = idToKey[languageId] ?? 'cpp'; langSelect.value = langMap[langKey] ?? 'C++'; } - form.submit(); log('CSES form submitted'); -}); \ No newline at end of file +}); From 3d2bf8a53da2a7d2321db9fd22986ad6093551cf Mon Sep 17 00:00:00 2001 From: sachin Date: Sat, 6 Jun 2026 21:26:05 +0530 Subject: [PATCH 6/7] fixed readme --- readme.md | 3 ++- src/csesInjectedScript.ts | 28 +++++++++++++--------------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/readme.md b/readme.md index 6bab465..d38ce65 100644 --- a/readme.md +++ b/readme.md @@ -1,6 +1,7 @@ # ![ICON](icon-48.png) cph-submit -Browser add on that enables direct submit on platforms like codeforces and CSES with [Competitive Programming Helper](https://github.com/agrawal-d/cph) +Browser add-on that enables direct submission on Codeforces,CSES and Maang.in +with[Competitive Programming Helper](https://github.com/agrawal-d/cph). Available for Firefox and Google Chrome. diff --git a/src/csesInjectedScript.ts b/src/csesInjectedScript.ts index 0cd544a..626160d 100644 --- a/src/csesInjectedScript.ts +++ b/src/csesInjectedScript.ts @@ -9,16 +9,16 @@ if (typeof browser !== 'undefined') { log('cph-submit cses script injected'); const extMap: Record = { - cpp: `.cpp`, - c: '.c', - java: '.java', - python: '.py', - rust: '.rs', - javascript: '.js', - ruby: '.rb', - haskell: '.hs', - scala: '.scala', - pascal: '.pas', + cpp: 'solution.cpp', + c: 'solution.c', + java: 'solution.java', + python: 'solution.py', + rust: 'solution.rs', + javascript: 'solution.js', + ruby: 'solution.rb', + haskell: 'solution.hs', + scala: 'solution.scala', + pascal: 'solution.pas', }; const langMap: Record = { @@ -67,7 +67,7 @@ const idToKey: Record = { chrome.runtime.onMessage.addListener((message) => { if (message.type !== 'cph-submit-cses') return; - const { sourceCode, problemName, languageId } = message; + const { sourceCode, languageId } = message; const form = document.querySelector('form'); if (!form) { @@ -80,11 +80,9 @@ chrome.runtime.onMessage.addListener((message) => { 'input[type="file"]', ) as HTMLInputElement; if (fileInput) { - log(`langID is ${languageId}`); - const langKey = idToKey[languageId] ?? 'cpp'; - log(`langKey is ${langKey}`); - const fileName = `${problemName}+extMap[langKey]`; + + const fileName = extMap[langKey] ?? 'solution.cpp'; const file = new File([sourceCode], fileName, { type: 'text/plain' }); const dt = new DataTransfer(); dt.items.add(file); From c08a5f251ab6f7329959b682152a53d33ca60823 Mon Sep 17 00:00:00 2001 From: sachin Date: Sat, 6 Jun 2026 21:37:54 +0530 Subject: [PATCH 7/7] final format check --- manifest-chrome.partial.json | 4 ++-- manifest-firefox.partial.json | 1 - src/handleSubmit.ts | 29 ++++++++++++----------------- webpack.config.js | 2 +- 4 files changed, 15 insertions(+), 21 deletions(-) diff --git a/manifest-chrome.partial.json b/manifest-chrome.partial.json index 2fe1851..85ef12c 100644 --- a/manifest-chrome.partial.json +++ b/manifest-chrome.partial.json @@ -1,11 +1,11 @@ { "manifest_version": 3, - "permissions": ["scripting", "webNavigation", "offscreen"], + "permissions": ["scripting", "webNavigation", "offscreen"], "host_permissions": [ "http://localhost/*", "https://cses.fi/*", "https://codeforces.com/*", - "https://maang.in/*" + "https://maang.in/*" ], "background": { "service_worker": "dist/backgroundScript.js", diff --git a/manifest-firefox.partial.json b/manifest-firefox.partial.json index 45a8c86..ca092cf 100644 --- a/manifest-firefox.partial.json +++ b/manifest-firefox.partial.json @@ -10,7 +10,6 @@ "*://codeforces.com/*", "*://maang.in/*", "webNavigation" - ], "browser_specific_settings": { "gecko": { diff --git a/src/handleSubmit.ts b/src/handleSubmit.ts index 1711927..81685a0 100644 --- a/src/handleSubmit.ts +++ b/src/handleSubmit.ts @@ -91,17 +91,15 @@ export const isAlgoZenithProblem = (problemUrl: string) => { return false; } }; -export const isCSESProblem = (problemUrl:string)=>{ - console.log(`problemURL-CSES ${problemUrl} `) - try{ +export const isCSESProblem = (problemUrl: string) => { + console.log(`problemURL-CSES ${problemUrl} `); + try { const url = new URL(problemUrl); - return( - url.hostname==='cses.fi' || url.hostname.endsWith('.cses.fi') - ); - }catch{ + return url.hostname === 'cses.fi' || url.hostname.endsWith('.cses.fi'); + } catch { return false; } -} +}; export const handleAlgoZenithSubmit = async ( problemName: string, @@ -178,7 +176,6 @@ export const handleCSESSubmit = async ( chrome.tabs.onUpdated.removeListener(listener); setTimeout(async () => { - if (typeof chrome !== 'undefined' && chrome.scripting) { await chrome.scripting.executeScript({ target: { tabId, allFrames: false }, @@ -188,7 +185,7 @@ export const handleCSESSubmit = async ( await browser.tabs.executeScript(tabId, { file: '/dist/csesInjectedScript.js', }); - } + } setTimeout(() => { chrome.tabs.sendMessage(tabId, { type: 'cph-submit-cses', @@ -200,7 +197,6 @@ export const handleCSESSubmit = async ( log('Message sent to CSES tab'); }, 500); - }, 1000); } }, @@ -225,13 +221,12 @@ export const handleSubmit = async ( problemUrl, ); } - if(isCSESProblem(problemUrl)){ - + if (isCSESProblem(problemUrl)) { return handleCSESSubmit( - problemName, - languageId, - sourceCode, - problemUrl, + problemName, + languageId, + sourceCode, + problemUrl, ); } diff --git a/webpack.config.js b/webpack.config.js index 813c502..d53f0e1 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -6,7 +6,7 @@ module.exports = { backgroundScript: './src/backgroundScript.ts', injectedScript: './src/injectedScript.ts', algoZenithInjectedScript: './src/algoZenithInjectedScript.ts', - csesInjectedScript: './src/csesInjectedScript.ts', + csesInjectedScript: './src/csesInjectedScript.ts', offscreen: './src/offscreen.ts', }, output: {