├── .gitignore ├── .gitmodules ├── Makefile ├── README.mkd ├── github-stars.crx ├── github-stars.js └── src ├── bg.js ├── github-stars.js └── manifest.json /.gitignore: -------------------------------------------------------------------------------- 1 | tmp/ 2 | *.pem 3 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "gm2chrome"] 2 | path = gm2chrome 3 | url = https://github.com/bcho/gm2chrome.git 4 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: clean convert 2 | 3 | CHROME_RUNTIME=`ls /usr/bin | grep 'chrom' | head -1` 4 | GM_CONVERTER=$(realpath gm2chrome/converter.py) 5 | PYTHON_RUNTIME=`which python3` 6 | 7 | EXT_NAME=github-stars 8 | 9 | EXT_SRC=$(realpath ./src) 10 | EXT_SOURCE=${EXT_SRC}/${EXT_NAME}.js 11 | EXT_PRE_MANI=${EXT_SRC}/manifest.json 12 | 13 | EXT_TMP=`realpath ./tmp` 14 | 15 | EXT_CRX_BUILD=$(realpath .) 16 | EXT_CRX_BUILD_PEM=${EXT_CRX_BUILD}/${EXT_NAME}.pem 17 | EXT_CRX_BUILD_CRX=${EXT_CRX_BUILD}/${EXT_NAME}.crx 18 | 19 | EXT_GM_BUILD=$(realpath .) 20 | EXT_GM_BUILD_SOURCE=${EXT_GM_BUILD}/${EXT_NAME}.js 21 | 22 | 23 | all: build_crx build_gm clean_tmp 24 | 25 | 26 | build_crx: convert_crx pack_crx 27 | 28 | convert_crx: 29 | ${PYTHON_RUNTIME} ${GM_CONVERTER} ${EXT_SOURCE} ${EXT_PRE_MANI} ${EXT_TMP} 30 | cp ${EXT_SRC}/*.js ${EXT_TMP}/ 31 | 32 | pack_crx: 33 | if [ -a ${EXT_CRX_BUILD_PEM} ]; \ 34 | then \ 35 | ${CHROME_RUNTIME} \ 36 | --pack-extension=${EXT_TMP} \ 37 | --pack-extension-key=${EXT_CRX_BUILD_PEM}; \ 38 | else \ 39 | ${CHROME_RUNTIME} --pack-extension=${EXT_TMP}; \ 40 | mv -f ${EXT_TMP}.pem ${EXT_CRX_BUILD_PEM}; \ 41 | fi; 42 | mv -f ${EXT_TMP}.crx ${EXT_CRX_BUILD_CRX} 43 | 44 | 45 | build_gm: 46 | cp ${EXT_SOURCE} ${EXT_GM_BUILD_SOURCE} 47 | 48 | 49 | clean_tmp: 50 | rm -rf ${EXT_TMP} 51 | 52 | clean: clean_tmp 53 | -------------------------------------------------------------------------------- /README.mkd: -------------------------------------------------------------------------------- 1 | # GitHub Stars 2 | 3 | Manage your github starred projects like a boss. 4 | 5 | 6 | ## Installation 7 | 8 | This Grease Monkey script can be used in both Firefox and Chrome / Chromium. 9 | 10 | ### Firefox Users 11 | 12 | You can enable this [script](github-stars.js) via [greasemonkey](https://addons.mozilla.org/en-US/firefox/addon/greasemonkey/) addons. 13 | 14 | ### Chrome / Chromium Users 15 | 16 | You can enable this script via: 17 | 18 | - [Tampermonkey](https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo?hl=en), 19 | - or install [it](github-stars.crx) manually. 20 | 21 | 22 | ## Usage 23 | 24 | ### Repository 25 | 26 | When you star a repository you can add extra comments for this repository, which may help you recall it after some days. 27 | 28 | 29 | Also, you can update your comments in repository's page. 30 | 31 | 32 | ### Search by comments 33 | 34 | In [stars page](https://github.com/stars)'s search box, you can filter your starred repositories by some words. 35 | 36 | 37 | ## TODO 38 | 39 | * demo 40 | * clear TODO tag in the code 41 | * comments persistent (using localStorage currently) 42 | 43 | 44 | ## Contributing 45 | 46 | Contribution is welcome, feel free to open an issue and fork. Waiting for your pull request. <3 47 | 48 | And ping me up with [larrydarrelc@gmail.com](mailto:larrydarrelc@gmail.com). 49 | -------------------------------------------------------------------------------- /github-stars.crx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcho/github-stars/34094a5ad42397088649df485619a6ebaa1e02c6/github-stars.crx -------------------------------------------------------------------------------- /github-stars.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name GitHub Stars 3 | // @namespace https://github.com/larrydarrelc/github-stars 4 | // @version 0.0.1 5 | // @description Manage your github starred projects like a boss. 6 | // 7 | // @match https://github.com/stars* 8 | // @match https://github.com/* 9 | // @require http://code.jquery.com/jquery-2.0.3.min.js 10 | // @permissions tabs 11 | // ==/UserScript== 12 | 13 | /*global $*/ 14 | 15 | (function () { 16 | 17 | // Helper Setup 18 | // ------------ 19 | 20 | // Local storage keys' prefix. 21 | var PREFIX = 'gs-'; 22 | 23 | // Script running environment (gm or crx). 24 | var MODE_GM = 0, 25 | MODE_CRX = 1, 26 | MODE = MODE_CRX; 27 | if ($.hasOwnProperty('facebox')) { 28 | MODE = MODE_GM; 29 | } 30 | 31 | // Templating settings. 32 | var TEMPLATE = { 33 | interpolate: /<%=([\w ]+)%>/g 34 | }; 35 | 36 | // Add comments box markup. 37 | var ADD_COMMENTS_BOX = '' + 38 | '
' + curRepo.comments + '
')[0]); 222 | } 223 | } 224 | 225 | // bind search box 226 | var q = document.querySelector('input#star-repo-search'); 227 | 228 | // TODO performance check 229 | q.addEventListener('keyup', function () { 230 | var needle = q.value; 231 | 232 | if (needle.length === 0) { 233 | repos.forEach(function (repo) { 234 | repo.ele.classList.remove('hidden'); 235 | }) 236 | } 237 | 238 | if (needle.length < MATCH_LENGTH) return; 239 | 240 | // compare project name and comments 241 | var cmpRepo = function (repo) { 242 | return ([repo.name, repo.comments].filter(function (a) { 243 | return (cmp(a, needle) >= MATCH_THRESHOLD); 244 | }).length > 0); 245 | }; 246 | 247 | repos.forEach(function (repo) { 248 | if (cmpRepo(repo)) { 249 | repo.ele.classList.remove('hidden'); 250 | } else { 251 | repo.ele.classList.add('hidden'); 252 | } 253 | }); 254 | }); 255 | }; 256 | 257 | var projectPage = function (projectName) { 258 | // inject edit comments box 259 | document 260 | .querySelector('.pagehead-actions') 261 | .appendChild($(EDIT_COMMENTS_BTN)[0]); 262 | 263 | // bind the :star: buttons 264 | var btn = document.querySelectorAll('.unstarred'), 265 | l = btn.length, 266 | e; 267 | for (var i = 0;i < l;i++) { 268 | e = btn[i]; 269 | e.addEventListener('click', function () { 270 | addComments(projectName); 271 | }) 272 | } 273 | }; 274 | 275 | 276 | // Helper Initialization 277 | // --------------------- 278 | 279 | var kick = function () { 280 | var path = location.pathname.substring(1); 281 | 282 | // faking a route 283 | if (isStarsPage(path)) { 284 | starsPage(); 285 | } else if (isProjectPage(path)) { 286 | projectPage(path); 287 | } else { 288 | console.log('reaching ', path); 289 | } 290 | }; 291 | 292 | kick(); 293 | })(); 294 | -------------------------------------------------------------------------------- /src/bg.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | var _ = function (markup, data) { 3 | var pattern = /<%=([\w ]+)%>/g, 4 | key; 5 | 6 | while ((key = pattern.exec(markup)) !== null) { 7 | markup = markup.replace(key[0], data[key[1].trim()]); 8 | } 9 | 10 | return markup; 11 | }; 12 | 13 | var runCodeWrapper = function (snippet) { 14 | var tmpl = [ 15 | '(function () {', 16 | 'try {', 17 | 'var script = document.createElement("script");', 18 | 'script.type = "text/javascript";', 19 | 'script.innerHTML = "<%= snippet %>";', 20 | 'document.body.appendChild(script);', 21 | 'window.setTimeout(function () {', 22 | 'script.parentElement.removeChild(script);', 23 | '}, 10);', 24 | '} catch (e) {', 25 | 'console.error(e);', 26 | '}', 27 | '})();'].join('\n'); 28 | 29 | return _(tmpl, {snippet: snippet.split('"').join('\\"')}); 30 | }; 31 | 32 | chrome.runtime.onMessage.addListener(function (req, sender, sendResp) { 33 | console.log('Execute code in the background.'); 34 | console.debug(req.snippet); 35 | 36 | chrome.tabs.executeScript({ 37 | code: runCodeWrapper(req.snippet) 38 | }); 39 | 40 | sendResp(); 41 | }); 42 | })(); 43 | -------------------------------------------------------------------------------- /src/github-stars.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name GitHub Stars 3 | // @namespace https://github.com/larrydarrelc/github-stars 4 | // @version 0.0.1 5 | // @description Manage your github starred projects like a boss. 6 | // 7 | // @match https://github.com/stars* 8 | // @match https://github.com/* 9 | // @require http://code.jquery.com/jquery-2.0.3.min.js 10 | // @permissions tabs 11 | // ==/UserScript== 12 | 13 | /*global $*/ 14 | 15 | (function () { 16 | 17 | // Helper Setup 18 | // ------------ 19 | 20 | // Local storage keys' prefix. 21 | var PREFIX = 'gs-'; 22 | 23 | // Script running environment (gm or crx). 24 | var MODE_GM = 0, 25 | MODE_CRX = 1, 26 | MODE = MODE_CRX; 27 | if ($.hasOwnProperty('facebox')) { 28 | MODE = MODE_GM; 29 | } 30 | 31 | // Templating settings. 32 | var TEMPLATE = { 33 | interpolate: /<%=([\w ]+)%>/g 34 | }; 35 | 36 | // Add comments box markup. 37 | var ADD_COMMENTS_BOX = '' + 38 | '' + curRepo.comments + '
')[0]); 222 | } 223 | } 224 | 225 | // bind search box 226 | var q = document.querySelector('input#star-repo-search'); 227 | 228 | // TODO performance check 229 | q.addEventListener('keyup', function () { 230 | var needle = q.value; 231 | 232 | if (needle.length === 0) { 233 | repos.forEach(function (repo) { 234 | repo.ele.classList.remove('hidden'); 235 | }) 236 | } 237 | 238 | if (needle.length < MATCH_LENGTH) return; 239 | 240 | // compare project name and comments 241 | var cmpRepo = function (repo) { 242 | return ([repo.name, repo.comments].filter(function (a) { 243 | return (cmp(a, needle) >= MATCH_THRESHOLD); 244 | }).length > 0); 245 | }; 246 | 247 | repos.forEach(function (repo) { 248 | if (cmpRepo(repo)) { 249 | repo.ele.classList.remove('hidden'); 250 | } else { 251 | repo.ele.classList.add('hidden'); 252 | } 253 | }); 254 | }); 255 | }; 256 | 257 | var projectPage = function (projectName) { 258 | // inject edit comments box 259 | document 260 | .querySelector('.pagehead-actions') 261 | .appendChild($(EDIT_COMMENTS_BTN)[0]); 262 | 263 | // bind the :star: buttons 264 | var btn = document.querySelectorAll('.unstarred'), 265 | l = btn.length, 266 | e; 267 | for (var i = 0;i < l;i++) { 268 | e = btn[i]; 269 | e.addEventListener('click', function () { 270 | addComments(projectName); 271 | }) 272 | } 273 | }; 274 | 275 | 276 | // Helper Initialization 277 | // --------------------- 278 | 279 | var kick = function () { 280 | var path = location.pathname.substring(1); 281 | 282 | // faking a route 283 | if (isStarsPage(path)) { 284 | starsPage(); 285 | } else if (isProjectPage(path)) { 286 | projectPage(path); 287 | } else { 288 | console.log('reaching ', path); 289 | } 290 | }; 291 | 292 | kick(); 293 | })(); 294 | -------------------------------------------------------------------------------- /src/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "background": { 3 | "scripts": ["bg.js"] 4 | } 5 | } 6 | --------------------------------------------------------------------------------