From 65033377c07322f34c919defbe9d1cc702f3bfa5 Mon Sep 17 00:00:00 2001 From: Clay Reimann Date: Thu, 3 Dec 2015 21:43:05 -0600 Subject: [PATCH] Initial commit. Basic functionality working. Needs tests and documentation --- .gitignore | 2 + LICENSE | 13 ++++ assets/GitHub-Mark-120px-plus.png | Bin 0 -> 4268 bytes assets/GitHub-Mark-32px.png | Bin 0 -> 1714 bytes assets/GitHub-Mark-64px.png | Bin 0 -> 2625 bytes chrome.js | 72 ++++++++++++++++++++++ manifest.json | 29 +++++++++ options/options.html | 36 +++++++++++ options/options.js | 72 ++++++++++++++++++++++ package.json | 18 ++++++ search.js | 99 ++++++++++++++++++++++++++++++ 11 files changed, 341 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 assets/GitHub-Mark-120px-plus.png create mode 100644 assets/GitHub-Mark-32px.png create mode 100644 assets/GitHub-Mark-64px.png create mode 100644 chrome.js create mode 100644 manifest.json create mode 100644 options/options.html create mode 100644 options/options.js create mode 100644 package.json create mode 100644 search.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c346b13 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +bower_components/ +node_modules/ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..251516b --- /dev/null +++ b/LICENSE @@ -0,0 +1,13 @@ +Copyright (c) 2015, Clay Reimann + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION +OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/assets/GitHub-Mark-120px-plus.png b/assets/GitHub-Mark-120px-plus.png new file mode 100644 index 0000000000000000000000000000000000000000..ea6ff545a246caa64074ba809bbc86fcb8589071 GIT binary patch literal 4268 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 XLyRvu{aX3a{{tgEGu={c*U0|?Dtn-9 literal 0 HcmV?d00001 diff --git a/assets/GitHub-Mark-32px.png b/assets/GitHub-Mark-32px.png new file mode 100644 index 0000000000000000000000000000000000000000..8b25551a97921681334176ee143b41510a117d86 GIT binary patch literal 1714 zcmaJ?X;2eq7*4oFu!ne{XxAht2qc?8LXr|_LPCfTpaBK7K$c{I0Ld=NLIOeuC;@2) zZ$K%a)k+m-s0>xHmKxL%0V&0TRzzznhgyqrIC$F)0{WwLXLrBvd*^wc_uSc%h%m9E z{W5z3f#4_!7RvAyFh6!S_*<8qJ%KOIm?#E|L=rJQq=gB5C6WLG5;c?r%V0>EmEH#X z5eSwPRa6WXBMs#$5H%GtW2go-in9p>zW@UYDNNWc^XOXZQ? z1QjEV00I#$3^1wQUJ8&-2UsjB-G|9y(LDhMNN3PM{APL4eYi{(m*ERcUnJa{R+-3^ z34^A6;U^v`8N*O6ji%S@sd{fJqD`XFIUJ5zgTe5^5nj414F(y!G&=H(f)Lgzv?>%+ zAsWD}2qhpH7>|TU`X&W6IxDNuO_vET7|j5oG&&VDr!)hUO8+0KR?nh!m<)a!?|%yG zqOwq!CWCcIhE{<$E|F|@g>nP6FoYr6C<8>D?ID9%&5J(4oSbR1I^byW*g@__U z4QsF&uJSEcFeleM3~ChjEQGbHOjsGDMbyAl(p=Ttv9RaVo8~I#js@@Y9C^_2U})yn zzSHU%6FxuY?d;&65MyR({^lU*3$z$ZllDb(o&<7d;A_`h2U+3~BJ2Hv`{W}KEU801#cv_B|9Cm!ynR{S`AMsSn z;7E=B;mb!wx$L;S>yGXG^6=&WlQn9$s?&L%Y1D8TI^MlKB1DqsEng$>f4=xYWBoPI z_S1p!sJ#d2?YI4kPA{k}Eby?F=f-J9zIc`YDl^pzjVm~9ebE?Hn?t0Nx+la|D0MB; z9)2xv1G>a1|A9kQ>~DV<=X3-4yC&n!m8-3K#P z{X@0zRuQsy$+N ziSCoLJU{Z$nQy4A4Y5UJ07$5FA~qL2%Q+cLaqDU?Lz3?=BC5;Nk6BbTmmceEaM>-Z zi>O&-dSE=%ex;vcvCOk{*JQ5^_4M z4lW7%l9IqY(z7pV(?I@@8=KPFO82)O{VDI18-*d-k$YmI^XiuPs_LuFw<^ZcD}yP5 c*NrbeloN*74g`U%%F6r~k%+>C^#XapzmV0H-2eap literal 0 HcmV?d00001 diff --git a/assets/GitHub-Mark-64px.png b/assets/GitHub-Mark-64px.png new file mode 100644 index 0000000000000000000000000000000000000000..182a1a3f734fc1b7d712c68b04c29bad9460d6cd GIT binary patch literal 2625 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 W4I>>0bz>}E>ge79vOpen ' + repo.url.slice(0, matches.index) + + '' + matches[0] + '' + + repo.url.slice(matches.index + matches[0].length) + '' + }; + }); + console.log('returning ' + suggestions.length + ' suggestions'); + console.log(suggestions); + + chrome.omnibox.setDefaultSuggestion({ + description: suggestions.length + ' results for "%s"' + (suggestions.length > 5 ? '. Enter a more specific query.' : '') + }); + suggest(suggestions); + } + ); + + chrome.omnibox.onInputEntered.addListener( + function(repoName, disposition) { + console.log(repoName + ' ' + disposition); + var url = suggester.getUrlForRepo(repoName) + if (disposition === 'currentTab') { + chrome.tabs.query({active: true, currentWindow: true}, function (tabs) { + chrome.tabs.update(tabs[0].id, {url: url}); + }); + } else if (disposition === 'newForegroundTab') { + chrome.tabs.create({url: url, active: true}); + } else if (disposition === 'newBackgroundTab') { + chrome.tabs.create({url: url}); + } + + } + ); + } + ); +} + +initalizeSuggestionService(); +chrome.runtime.onMessage.addListener(function(message) { + if (message === 'settings-updated') { + initalizeSuggestionService(); + } +}) diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..c81dbe5 --- /dev/null +++ b/manifest.json @@ -0,0 +1,29 @@ +{ + "manifest_version": 2, + "name": "Github Repo Search", + "version": "1.0.0", + "omnibox": { "keyword" : "gh" }, + "icons": { + "16": "assets/GitHub-Mark-32px.png", + "32": "assets/GitHub-Mark-32px.png", + "64": "assets/GitHub-Mark-64px.png", + "128": "assets/Github-Mark-120px-plus.png" + + }, + "options_ui": { + "page": "options/options.html", + "chrome_style": true + }, + "permissions": [ + "tabs", + "storage" + ], + "background": { + "persistent": true, + "scripts": [ + "node_modules/github-api/github.js", + "search.js", + "chrome.js" + ] + } +} diff --git a/options/options.html b/options/options.html new file mode 100644 index 0000000..8748ef3 --- /dev/null +++ b/options/options.html @@ -0,0 +1,36 @@ + + + + + + + + Omnibox Github Search + + + + + + +
+
+
+ +
+
+ +
+
+
+
+
+ + + + + + diff --git a/options/options.js b/options/options.js new file mode 100644 index 0000000..3eda590 --- /dev/null +++ b/options/options.js @@ -0,0 +1,72 @@ +var FORM = document.getElementById('settings-form'); +FORM.addEventListener("submit", processForm); +var SAVE_BUTTON = document.getElementById('save-button') + +function processForm(e) { + e.preventDefault(); + var token = document.getElementById('oauth-token-1').value; + var url = document.getElementById('github-url-1').value; + chrome.storage.sync.set({ + githubs: [ + { + url: url, + token: token + } + ] + }); + chrome.runtime.sendMessage('settings-updated'); +} + +var FORM_GROUP_CLASS_NAME = 'form-group'; +var LABEL_CLASS_NAME = 'col-sm-2 control-label'; +var INPUT_DIV_CLASS_NAME = 'col-sm-6' +var INPUT_CLASS_NAME = 'form-control' +function createInputGroup(id, title, placeholder, value) { + var inputLabel = document.createElement('label'); + inputLabel.innerText = title; + inputLabel.setAttribute('for', id) + inputLabel.className = LABEL_CLASS_NAME; + var input = document.createElement('input'); + input.className = INPUT_CLASS_NAME; + input.setAttribute('id', id); + input.setAttribute('placeholder', placeholder); + input.value = value; + + var inputDiv = document.createElement('div'); + inputDiv.className = INPUT_DIV_CLASS_NAME; + inputDiv.appendChild(input); + + var inputGroup = document.createElement('div') + inputGroup.className = FORM_GROUP_CLASS_NAME; + inputGroup.appendChild(inputLabel); + inputGroup.appendChild(inputDiv); + + return inputGroup +} + +function addInstance(token, url) { + var num = FORM.children.length; + var fieldset = document.createElement('fieldset'); + var legend = document.createElement('legend'); + legend.innerText = 'Instance ' + num; + + var tokenGroup = createInputGroup('oauth-token-' + num, 'OAuth Token', 'token', token); + var urlGroup = createInputGroup('github-url-' + num, 'Github URL', 'https://api.github.com', url); + + fieldset.appendChild(legend); + fieldset.appendChild(tokenGroup); + fieldset.appendChild(urlGroup); + FORM.insertBefore(fieldset, SAVE_BUTTON); +} + +chrome.storage.sync.get(['githubs'], function(settings) { + var githubs = settings.githubs; + + if (!githubs) { + addInstance('', ''); + } else { + githubs.forEach(function(def) { + addInstance(def.token, def.url); + }); + } +}); diff --git a/package.json b/package.json new file mode 100644 index 0000000..e863d20 --- /dev/null +++ b/package.json @@ -0,0 +1,18 @@ +{ + "name": "github-search", + "version": "0.1.0", + "description": "Search github repositiories from the chrome omnibox", + "main": "search.js", + "scripts": { + "test": "gulp test" + }, + "keywords": [ + "github", + "search", + "developer", + "devtools", + "productivity" + ], + "author": "Clay Reimann", + "license": "ISC" +} diff --git a/search.js b/search.js new file mode 100644 index 0000000..d5108b9 --- /dev/null +++ b/search.js @@ -0,0 +1,99 @@ +/** + * A service that suggests repositories based on user input + * @param {Array[Object]} ghInstances - an array of objects with `url` and `token` properties + */ +var SuggestionService = function(ghInstances) { + this.GITHUBS = ghInstances.map(function(instance) { + return new Github({ + apiUrl: instance.url, + token: instance.token, + auth: 'oauth' + }); + }) + this.REPOS = []; + this.OUTSTANDING_API_REQUESTS = 0; + this.getRepos(); +} + +SuggestionService.prototype.makeRequest = function() { + this.OUTSTANDING_API_REQUESTS += 1; +}; +SuggestionService.prototype.finishRequest = function() { + this.OUTSTANDING_API_REQUESTS -= 1; +}; +SuggestionService.prototype.isReady = function() { + return this.OUTSTANDING_API_REQUESTS === 0; +}; + +SuggestionService.prototype.addRepository = function(github, repo) { + var contains = false; + this.REPOS.forEach(function(r) { + if (r.github === github && r.name === repo.full_name) { + contains = true; + } + }); + if (!contains) { + this.REPOS.push({ + github: github, + name: repo.full_name, + url: repo.html_url + }); + } +}; + +SuggestionService.prototype.getRepos = function() { + var _this = this; + this.REPOS = []; + this.GITHUBS.forEach(function(github) { + var user = github.getUser(); + + _this.makeRequest(); + user.repos(function(err, repos) { + console.log(repos.map(function(repo) { + return repo.full_name; + })); + _this.finishRequest(); + + if (!repos) { return; } + repos.forEach(function(repo) { + repo.user = user; + _this.addRepository(github, repo); + }); + }); + + _this.makeRequest(); + user.orgs(function(err, orgs) { + _this.finishRequest(); + + if (!orgs) { return; } + orgs.forEach(function(org) { + + _this.makeRequest(); + user.orgRepos(org.login, function(err, repos) { + _this.finishRequest(); + + console.log(repos.map(function(repo) { + return repo.full_name; + })); + if (!repos) { return; } + repos.forEach(function(repo) { + _this.addRepository(github, repo); + }); + }); + }); + }); + }); +}; + +SuggestionService.prototype.getRepositoriesMatching = function(text) { + return this.REPOS.filter(function(repo) { + return repo.name.search(new RegExp(text, 'i')) !== -1; + }); +} + +SuggestionService.prototype.getUrlForRepo = function(fullName) { + var repo = this.REPOS.filter(function(r) { + return r.name === fullName; + })[0]; + return repo ? repo.url : undefined; +};