",
26 | "license": "MIT",
27 | "bugs": {
28 | "url": "https://github.com/akshaykumar6/github-js/issues"
29 | },
30 | "homepage": "http://akshaykumar6.github.io/github-js",
31 | "directories": {
32 | "test": "test"
33 | },
34 | "dependencies": {
35 | "grunt": "^0.4.5",
36 | "grunt-contrib-clean": "^0.6.0",
37 | "grunt-contrib-uglify": "^0.6.0",
38 | "grunt-contrib-cssmin": "^0.10.0",
39 | "grunt-contrib-copy": "^0.6.0"
40 | },
41 | "scripts": {
42 | "test": "echo \"Error: no test specified\" && exit 1"
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/github.css:
--------------------------------------------------------------------------------
1 | /**
2 | * Generic CSS
3 | */
4 |
5 | .gt-container a {
6 | color: #3572B0;
7 | text-decoration: none;
8 | }
9 | .gt-container a:focus, .gt-container a:hover, .gt-container a:active {
10 | text-decoration: underline;
11 | }
12 | .gt-container *{
13 | -webkit-box-sizing: border-box;
14 | -moz-box-sizing: border-box;
15 | box-sizing: border-box;
16 | }
17 | .gt-container{
18 | position: relative;
19 | width: 100%;
20 | background-color: #FFF;
21 | border-radius: 3px;
22 | border: 1px solid #D8D8D8;
23 | background: #FAFAFA;
24 | font-size: 1rem;
25 | min-width: 270px;
26 | }
27 | .gt-header{
28 | position: relative;
29 | width: 100%;
30 | padding-top: 10px;
31 | background-color: #F5F5F5;
32 | z-index: 2;
33 | }
34 | .gt-usr-avatar, .gt-org-avatar{
35 | width: 100px;
36 | height: 100px;
37 | margin: 0 auto;
38 | }
39 | .gt-usr-avatar a, .gt-org-avatar a{
40 | width: 100px;
41 | height: 100px;
42 | display: block;
43 | }
44 | .gt-usr-avatar img, .gt-org-avatar img{
45 | width: 100%;
46 | height: 100%;
47 | border-radius: 50%;
48 | }
49 | .gt-usr-name, .gt-org-name{
50 | padding: 10px 20px;
51 | text-align: center;
52 | }
53 | .gt-header .user-name{
54 | display: block;
55 | overflow: hidden;
56 | width: 100%;
57 | font-size: 1.6rem;
58 | line-height: 30px;
59 | text-overflow: ellipsis;
60 | }
61 | .gt-header .user-login{
62 | display: block;
63 | overflow: hidden;
64 | width: 100%;
65 | font-size: 1.25rem;
66 | font-style: normal;
67 | font-weight: 300;
68 | line-height: 24px;
69 | color: #666;
70 | text-overflow: ellipsis;
71 | }
72 | .gt-header .user-login:hover{
73 | text-decoration: underline;
74 | }
75 | .gt-usr-details{
76 | height: 50px;
77 | }
78 | .gt-repo-details{
79 | height: 60px;
80 | }
81 | .gt-usr-repo,.gt-usr-folwr,.gt-usr-folng{
82 | float: left;
83 | width: 33.33%;
84 | text-align: center;
85 | padding-top: 5px;
86 | height: 50px;
87 | }
88 | .gt-usr-txt{
89 | display: block;
90 | }
91 | .gt-usr-dt{
92 | display: block;
93 | }
94 | .gt-usr-details a,.gt-repo-details a{
95 | text-decoration: none !important;
96 | color: #000;
97 | }
98 | .gt-usr-repo:hover,.gt-usr-folwr:hover,.gt-usr-folng:hover{
99 | background-color: #E3E3E3;
100 | }
101 | .gt-usr-name p{
102 | margin: 5px 0;
103 | }
104 | .gt-shadow{
105 | border-bottom: 1px solid #DDD;
106 | box-shadow: 0 2px 2px -1px rgba(0,0,0,.4);
107 | -webkit-box-shadow: 0 2px 2px -1px rgba(0,0,0,.4);
108 | -moz-box-shadow: 0 2px 2px -1px rgba(0,0,0,.4);
109 | }
110 |
111 | /**
112 | * Organization
113 | */
114 |
115 | .gt-org-link{
116 | display: inline-block;
117 | margin: 5px;
118 | }
119 | .gt-org-repos{
120 | display: block;
121 | clear: both;
122 | }
123 | /**
124 | * Activity
125 | */
126 | .gt-activity-cnt{
127 | background-color: #FFF;
128 | position: relative;
129 | width: 100%;
130 | height: 300px;
131 | overflow-y: auto;
132 | }
133 | .gt-time-cnt{
134 |
135 | }
136 | .gt-time-str{
137 | color: #666;
138 | font-size: 0.9rem;
139 | }
140 | .gt-activity{
141 | padding: 10px 5px;
142 | border-top: 1px solid #D8D8D8;
143 | word-break: break-all;
144 | }
145 | .gt-no-activity{
146 | padding: 10px 5px;
147 | text-align: center;
148 | }
149 | .gt-activity .gt-avatar-cnt{
150 | float: left;
151 | width: 5%;
152 | min-width: 35px;
153 | padding-left: 5px;
154 | padding-bottom: 5px;
155 | }
156 | .gt-activity .gt-usr-avatar{
157 | width: 30px;
158 | height: 30px;
159 | }
160 | .gt-act-cnt{
161 | display: inline-block;
162 | display: -moz-inline-stack;
163 | float: left;
164 | width: 91%;
165 | padding-left: 7px;
166 | }
167 | .gt-clearfix{
168 | clear: both;
169 | }
170 | .gt-act-cnt p{
171 | margin: 2px 0px;
172 | color: #666;
173 | font-size: 0.9rem;
174 | overflow: hidden;
175 | text-overflow: ellipsis;
176 | width: 100%;
177 | display: block;
178 | white-space: nowrap;
179 | }
180 | .gt-act-cnt .pull-req-info{
181 | display: inline-block;
182 | padding: 3px 7px;
183 | margin-top: 5px;
184 | color: rgba(0,0,0,0.5);
185 | background: #e8f1f6;
186 | border-radius: 3px;
187 | width: auto;
188 | }
189 | .gt-commit-list{
190 | margin: 0;
191 | padding: 0;
192 | list-style-type: none;
193 | font-size: 0.9rem !important;
194 | }
195 | .gt-commit-item{
196 | margin: 5px 0;
197 | }
198 | .gt-commit-msg{
199 | color: #666;
200 | margin: 0 5px;
201 | }
202 | .gt-compare-link{
203 | font-size: 0.9rem;
204 | }
205 | .gt-scrollbar {
206 | -webkit-overflow-scrolling: touch
207 | }
208 | .gt-scrollbar::-webkit-scrollbar {
209 | height: 9px;
210 | width: 9px
211 | }
212 | .gt-scrollbar::-webkit-scrollbar-button:start:decrement, .gt-scrollbar::-webkit-scrollbar-button:end:increment {
213 | background: transparent;
214 | display: none
215 | }
216 | .gt-scrollbar::-webkit-scrollbar-track-piece {
217 | background: #F2F2F2;
218 | border: 1px solid #E3E3E3;
219 | }
220 | .gt-scrollbar::-webkit-scrollbar-thumb:vertical:hover, .gt-scrollbar::-webkit-scrollbar-thumb:horizontal:hover {
221 | background: #888;
222 | opacity: 0.6;
223 | }
224 | .gt-scrollbar::-webkit-scrollbar-thumb:vertical, .gt-scrollbar::-webkit-scrollbar-thumb:horizontal {
225 | background: #BBB;
226 | display: block;
227 | height: 50px;
228 | opacity: 0.2;
229 | }
230 | .gt-org-img, .gt-usr-img{
231 | background-repeat: no-repeat;
232 | background-position: 60%;
233 | border-radius: 50%;
234 | width: 100px;
235 | height: 100px;
236 | background-size: 112%;
237 | }
238 | .gt-repo-lg-stat{
239 | width: 100%;
240 | height: 10px;
241 | clear: both;
242 | background-color: #38AFB9;
243 | }
244 | .gt-repo-lg-cnt{
245 | position: relative;
246 | float: left;
247 | height: 100%;
248 | }
249 | .gt-repo-lg-name{
250 | height: 100%;
251 | position: relative;
252 | }
253 | .gt-repo-lg-name[data-title]:hover:after{
254 | content: attr(data-title);
255 | font-size: 12px;
256 | padding: 2px 8px;
257 | color: white;
258 | position: absolute;
259 | left: 40%;
260 | top: 175%;
261 | white-space: nowrap;
262 | z-index: 200;
263 | -moz-border-radius: 5px;
264 | -webkit-border-radius: 5px;
265 | border-radius: 5px;
266 | background-color: #222;
267 | }
268 |
269 | .gt-repo-lg-name:hover:before {
270 | border-bottom-color: #222;
271 | border-width: 5px;
272 | left: 48%;
273 | }
274 | .gt-repo-lg-name:before {
275 | border: solid transparent;
276 | content: " ";
277 | height: 0;
278 | width: 0;
279 | position: absolute;
280 | pointer-events: none;
281 | top: 75%;
282 | z-index: 201;
283 | }
284 | .gt-loading-txt{
285 | text-align: center;
286 | padding: 5px 0;
287 | color: #999;
288 | }
289 |
--------------------------------------------------------------------------------
/src/github.js:
--------------------------------------------------------------------------------
1 | // Github.js - v0.1.3
2 |
3 | // © 2015, Akshay Sharma Released under the MIT License.
4 |
5 | (function (root, factory) {
6 |
7 | // Set up library appropriately for the environment
8 | if (typeof define === 'function' && define.amd) {
9 | // Define for AMD
10 | define(['underscore'], factory);
11 | } else if (typeof exports === 'object') {
12 | // Export for Node, CommonJS-like modules
13 | module.exports = factory(require('underscore'));
14 | } else {
15 | // As browser global (root is window here)
16 | root.Github = factory(root._);
17 | }
18 |
19 | }(this, function (_) {
20 |
21 | var Github = {};
22 |
23 | // Current version of the library. Keep in sync with `package.json`
24 | Github.version = '0.1.3';
25 |
26 | // Common GitHub API URL
27 | var gitApiUrl = 'https://api.github.com/';
28 |
29 | // userProfile - render's the github user details to selector
30 | // @param Type - JSON -> options [username, selector]
31 |
32 | Github.userProfile = function (options) {
33 |
34 | if(options = gitMethods.initialize(options, ['username','selector'], 0)){
35 | var userUrl = gitApiUrl + 'users/' + options.username;
36 | gitMethods.getData(userUrl, options, gitMethods.getUserProfileHTML);
37 | } else{
38 | console.error("Parameters not passed correctly");
39 | }
40 |
41 | };
42 |
43 | //
44 | // repoProfile - render's the github repo details to selector
45 | // @param Type - JSON -> options [username, reponame, selector]
46 | //
47 | Github.repoProfile = function (options) {
48 |
49 | if(options = gitMethods.initialize(options, ['username','selector','reponame'], 0)){
50 | var repoUrl = gitApiUrl + 'repos/' + options.username +'/'+ options.reponame;
51 | gitMethods.getData(repoUrl, options, gitMethods.getRepoProfileHTML);
52 | } else{
53 | console.error("Parameters not passed correctly");
54 | }
55 |
56 | };
57 |
58 | //
59 | // orgProfile - render's the github organization details to selector
60 | // @param Type - JSON -> options [orgname, selector]
61 | //
62 | Github.orgProfile = function (options) {
63 |
64 | if(options = gitMethods.initialize(options, ['orgname','selector'], 0)){
65 | var orgUrl = gitApiUrl + 'orgs/' + options.orgname;
66 | gitMethods.getData(orgUrl, options, gitMethods.getOrgProfileHTML);
67 | } else{
68 | console.error("Parameters not passed correctly");
69 | }
70 |
71 | };
72 |
73 | //
74 | // userActivity - render's the github user activity to selector
75 | // @param Type - JSON -> options [username, selector and limit (optional)]
76 | //
77 | Github.userActivity = function (options) {
78 |
79 | if(options = gitMethods.initialize(options, ['username','selector'], 1)){
80 | var userUrl = gitApiUrl + 'users/' + options.username,
81 | eventsUrl = userUrl + '/events';
82 | gitMethods.getData(userUrl, options, gitMethods.getUserProfileHTML);
83 | gitMethods.getData(eventsUrl, options, gitMethods.getPublicActivityHTML);
84 | } else{
85 | console.error("Parameters not passed correctly");
86 | }
87 |
88 | };
89 |
90 | //
91 | // repoActivity - render's the github repository activity to selector
92 | // @param Type - JSON -> options [username, reponame, selector and limit (optional)]
93 | //
94 | Github.repoActivity = function (options) {
95 |
96 | if(options = gitMethods.initialize(options, ['username','selector','reponame'], 1)){
97 | var repoUrl = gitApiUrl + 'repos/' + options.username +'/'+ options.reponame,
98 | eventsUrl = repoUrl + '/events';
99 | gitMethods.getData(repoUrl, options, gitMethods.getRepoProfileHTML);
100 | gitMethods.getData(eventsUrl, options, gitMethods.getPublicActivityHTML);
101 | } else{
102 | console.error("Parameters not passed correctly");
103 | }
104 |
105 | };
106 |
107 | //
108 | // orgActivity - render's the github organization activity to selector
109 | // @param Type - JSON -> options [orgname, selector and limit (optional)]
110 | //
111 | Github.orgActivity = function (options) {
112 |
113 | if(options = gitMethods.initialize(options, ['orgname','selector'], 1)){
114 | var orgUrl = gitApiUrl + 'orgs/' + options.orgname,
115 | eventsUrl = orgUrl + '/events';
116 | gitMethods.getData(orgUrl, options, gitMethods.getOrgProfileHTML);
117 | gitMethods.getData(eventsUrl, options, gitMethods.getPublicActivityHTML);
118 | } else{
119 | console.error("Parameters not passed correctly");
120 | }
121 |
122 | };
123 |
124 | // Underscore templates for profiles, activities, etc.
125 | var gitTemplates = {
126 | // Parent container template
127 | parentTpl: ''+
128 | '
'+
129 | '
Loading..
'+
130 | '
'+
131 | '<%if(type){%>
<%}%>'+
134 | '
',
135 | // User profile template
136 | userProfileTpl: ''+
141 | ''+
147 | ''+
148 | '
'+
154 | '
'+
160 | '
'+
166 | '
',
167 | // Repository profile template
168 | repoProfileTpl: ''+
177 | ''+
178 | '
'+
184 | '
'+
190 | '
'+
196 | '
'+
197 | '
'+
198 | '
',
199 | // Organization profile template
200 | orgProfileTpl: ''+
205 | '',
216 | // Parent activity container template
217 | gitActivityTpl: ''+
218 | '
'+
223 | '
'+
224 | '
'+
225 | '<%= userLink%>'+'<%= message%>'+
226 | '
'+
227 | '
'+
228 | '
',
229 | // Activity templates keyed with activity type
230 | CommitCommentEvent:' commented on commit <%= commentLink%> '+
231 | '<%= payload.comment.body%>
',
232 | CreateEvent: ' created <%= payload.ref_type%> <%= branchLink%> at <%= repoLink%> ',
233 | DeleteEvent: ' deleted <%= payload.ref%> <%= payload.ref_type%> at <%= repoLink%> ',
234 | ForkEvent: ' forked <%= repoLink%> to <%= forkLink%> ',
235 | GollumEvent: ' <%= actionType%> the <%= repoLink%> wiki'+
236 | '<%= wikiMessage%>
',
237 | IssueCommentEvent: ' commented on issue <%= commentLink%> '+
238 | '<%= payload.comment.body%>
',
239 | IssuesEvent: ' <%= payload.action%> issue <%= issueUrl%> ',
240 | MemberEvent: ' added <%= memberLink%> to <%= repoLink%> ',
241 | PublicEvent: ' open sourced <%= repoLink%> ',
242 | PullRequestEvent: ' <%= payload.action%> pull request <%= mergeRequestUrl%> '+
243 | '<%= payload.pull_request.title%>
'+
244 | '<%= payload.pull_request.commits%><%if(payload.pull_request.commits > 1){%> commits <%}else{%> commit <%}%> '+
245 | 'with <%= payload.pull_request.changed_files%> <%if(payload.pull_request.commits > 1){%> files <%}else{%> file <%}%> changed.
',
246 | PullRequestReviewCommentEvent: ' commented on pull request <%= pullCommentUrl%> '+
247 | '<%= payload.comment.body%>
',
248 | PushEvent: ' pushed to <%= branchLink%> at <%= repoLink%> '+
249 | '<%= commitsHtml%>',
250 | ReleaseEvent: ' released <%= tagLink%> at <%= repoLink%> '+
251 | '
<%= zipLink%>',
252 | WatchEvent: ' starred <%= repoLink%> ',
253 | noActivityTpl: ''+
254 | ' There are no public events for this account in past 90 days. '+
255 | '
',
256 | notFoundTpl: ''+
257 | ' This account does not exist. '+
258 | '
'
259 | };
260 |
261 | // Object for locally used methods
262 | var gitMethods = {
263 | // Check variables and render base template
264 | initialize: function(options, variables, type){
265 | // Validate varaibles
266 | for (var i = 0; i < variables.length; i++) {
267 | if(!options[variables[i]])
268 | return false;
269 | }
270 | // Type - 0 - only profile
271 |
272 | // Type - 1 - profile and acitivity feed
273 | gitMethods.renderContent(gitMethods.getRenderedHTML(gitTemplates['parentTpl'],{
274 | type: type
275 | }),options.selector);
276 |
277 | // Set limit value
278 | options.limit = gitMethods.setLimit(options.limit);
279 | return options;
280 | },
281 |
282 | // Check if value is integer
283 | checkInteger: function (value) {
284 | if (value === parseInt(value, 10))
285 | return true;
286 | else
287 | return false;
288 | },
289 |
290 | // Get the rendered template with data
291 | getRenderedHTML: function (template, data) {
292 | if (data) {
293 | return _.template(template)(data);
294 | } else{
295 | return _.template(template)();
296 | }
297 | },
298 |
299 | // Render User profile HTML
300 | getUserProfileHTML: function (data, options){
301 | gitMethods.renderContent(gitMethods.getRenderedHTML(gitTemplates.userProfileTpl, data), options.selector,'.gt-header');
302 | },
303 |
304 | // Render the repository profile HTML with language stats
305 | getRepoProfileHTML: function (data, options){
306 | var languageUrl = gitApiUrl + 'repos/' + options.username +'/'+ options.reponame + '/languages';
307 | // Render template
308 | gitMethods.renderContent(gitMethods.getRenderedHTML(gitTemplates.repoProfileTpl, data), options.selector,'.gt-header');
309 | // Fetch language stat for repo
310 | gitMethods.getData(languageUrl, options, gitMethods.getLanguageHTML);
311 | },
312 |
313 | // Render organization profile HTML
314 | getOrgProfileHTML: function (data, options){
315 | gitMethods.renderContent(gitMethods.getRenderedHTML(gitTemplates.orgProfileTpl, data), options.selector,'.gt-header');
316 | },
317 |
318 | // Render recent public activities of user/repo/organization
319 | getPublicActivityHTML: function (data,options) {
320 | var html = '';
321 | // Get min of limit of data size
322 | var length = (options.limit < data.length)? options.limit : data.length;
323 |
324 | if (length==0) {
325 | // If no activity in last 90 days
326 | html += gitMethods.getRenderedHTML(gitTemplates['noActivityTpl']);
327 | }
328 | else{
329 | // Loop over all the activities
330 | for(var index = 0; index < length; index++){
331 | var activity = data[index];
332 | var payload = activity.payload;
333 |
334 | // Get attributes common to all activities
335 | activity.timeString = gitMethods.millisecondsToStr(new Date() - new Date(activity.created_at));
336 | activity.userLink = gitMethods.getGitHubLink(activity.actor.login, activity.actor.login);
337 | activity.repoLink = gitMethods.getGitHubLink(activity.repo.name, activity.repo.name);
338 |
339 | // Get the branch name
340 | activity.branchLink = '';
341 | if (payload.ref) {
342 | if (payload.ref.substring(0, 11) === 'refs/heads/') {
343 | activity.branch = payload.ref.substring(11);
344 | } else {
345 | activity.branch = payload.ref;
346 | }
347 | activity.branchLink = gitMethods.getGitHubLink(activity.repo.name + '/tree/' + activity.branch, activity.branch);
348 | }
349 |
350 | // Get the HTML of selected activity type
351 | switch(activity.type){
352 | case 'CommitCommentEvent': activity.commentLink = gitMethods.getLink(payload.comment.html_url, activity.repo.name + '@' +payload.comment.commit_id.substring(0,6));
353 | break;
354 | case 'CreateEvent':
355 | break;
356 | case 'DeleteEvent':
357 | break;
358 | case 'ForkEvent': activity.forkLink = gitMethods.getGitHubLink(payload.forkee.html_url, payload.forkee.full_name);
359 | break;
360 | case 'GollumEvent': var page = payload.pages[0];
361 | activity.actionType = page.action;
362 | activity.wikiMessage = activity.actionType.charAt(0).toUpperCase() + activity.actionType.slice(1) + ' ';
363 | activity.wikiMessage += gitMethods.getLink(page.html_url, page.title);
364 | break;
365 | case 'IssueCommentEvent': activity.commentLink= gitMethods.getLink(payload.comment.html_url, activity.repo.name + '#' +payload.issue.number);
366 | break;
367 | case 'IssuesEvent': activity.issueUrl = gitMethods.getLink(payload.issue.html_url, activity.repo.name + '#' +payload.issue.number);
368 | break;
369 | case 'MemberEvent': activity.memberLink = gitMethods.getGitHubLink(payload.member.login, payload.member.login);
370 | break;
371 | case 'PublicEvent':
372 | break;
373 | case 'PullRequestEvent': activity.mergeRequestUrl = gitMethods.getLink(payload.pull_request.html_url, activity.repo.name + '#' +payload.pull_request.number);
374 | break;
375 | case 'PullRequestReviewCommentEvent': activity.pullCommentUrl= gitMethods.getLink(payload.comment.html_url, activity.repo.name + '#' +payload.pull_request.number);
376 | break;
377 | case 'PushEvent': activity.commitsHtml = gitMethods.getCommitsHTML(activity);
378 | break;
379 | case 'ReleaseEvent': activity.tagLink = gitMethods.getLink(payload.release.html_url, payload.release.tag_name);
380 | activity.zipLink = gitMethods.getLink(payload.release.zipball_url, 'Download Source Code (zip)')
381 | break;
382 | case 'WatchEvent':
383 | break;
384 | }
385 | // Get activity specific message
386 | activity.message = gitMethods.getRenderedHTML(gitTemplates[activity.type], activity);
387 | html += gitMethods.getRenderedHTML(gitTemplates['gitActivityTpl'],activity);
388 |
389 | }
390 | }
391 | // Render created activity HTML to DOM
392 | gitMethods.renderContent(html, options.selector, '.gt-activity-cnt');
393 | },
394 |
395 | // Form HTML for commits in PushEvent
396 | getCommitsHTML: function(activity){
397 | var html = '',
398 | liElement, shaLink, commitMessage, commit, index,
399 | compareLink = '',
400 | payload = activity.payload,
401 | length = payload.commits.length,
402 | shaDiff = payload.before + '...' + payload.head;
403 |
404 | // Get links for 2 or less commit
405 | for(index = 0; index < length; index++){
406 | if (index>1) break;
407 | commit = payload.commits[index];
408 | // Create commit li element
409 | liElement = '- ';
410 | shaLink = gitMethods.getGitHubLink(activity.repo.name + '/commit/' + commit.sha, commit.sha.substring(0, 6));
411 | commitMessage = '' + commit.message.substring(0,150) + '';
412 | liElement += shaLink
413 | liElement += commitMessage;
414 | liElement += '
'
415 | html += liElement;
416 | }
417 |
418 | // Get the diff link between commits
419 | if (length === 2) {
420 | compareLink = gitMethods.getGitHubLink(activity.repo.name + '/compare/' + shaDiff, 'View comparison for these 2 commits »','gt-compare-link');
421 | } else if (length > 2) {
422 | compareLink = gitMethods.getGitHubLink(activity.repo.name + '/compare/' + shaDiff, (length-2)+' more ' + gitMethods.getPluralWord(length-2,'commit') + ' »','gt-compare-link');
423 | }
424 |
425 | html += '
'
426 | html += compareLink;
427 |
428 | return html;
429 | },
430 |
431 | // Utility for asynchronous AJAX calls
432 | getData: function(url, options, callback){
433 | var data, request;
434 | request = new XMLHttpRequest();
435 | request.open('GET', url, true);
436 | // Use OAuth token if available
437 | if (options.OAuth) {
438 | request.setRequestHeader('Authorization', 'Token ' + options.OAuth);
439 | }
440 |
441 | request.onload = function(e) {
442 | if (request.status >= 200 && request.status < 400){
443 | data = JSON.parse(request.responseText);
444 | callback(data, options);
445 | } else {
446 | // Unsuccessful request - invalid username/ lost internet connectivity/ exceeded rate limit/ API URL not found
447 | gitMethods.renderContent(gitMethods.getRenderedHTML(gitTemplates.notFoundTpl, data), options.selector,'.gt-container');
448 | console.error('An error occurred while connecting to GitHub API.');
449 | }
450 | };
451 |
452 | request.onerror = function(e) {
453 | console.error('An error occurred while connecting to GitHub API.');
454 | };
455 |
456 | request.send();
457 | },
458 |
459 | // Get anchor tag HTML for URL
460 | getLink: function(url, title, cssClass) {
461 | if (!title)
462 | title = url;
463 | if (typeof(cssClass) === 'undefined')
464 | cssClass = '';
465 | return gitMethods.getRenderedHTML('<%=title%>', { url: url, title: title });
466 | },
467 |
468 | // Get anchor tag HTML for non-github URL
469 | getGitHubLink: function(url, title, cssClass) {
470 | if (!title)
471 | title = url;
472 | if (typeof(cssClass) === 'undefined')
473 | cssClass = '';
474 | return gitMethods.getLink('https://github.com/' + url, title, cssClass);
475 | },
476 |
477 | // Only for plurals ending with 's'. Yeah! this sucks.
478 | getPluralWord: function (count, word) {
479 | if (count !== 1) return word + 's';
480 | return word;
481 | },
482 |
483 | // Get repository language stat HTML
484 | getLanguageHTML: function(data, options){
485 | var languageData = [], sum = 0,
486 | percentage, languageHtml = '';
487 | // Get total size and create array which can be sorted by value
488 | _.each(data, function(value, key){
489 | var data = {};
490 | data.language = key;
491 | data.size = value;
492 | languageData.push(data);
493 | sum += value;
494 | });
495 |
496 | // Sort languages by usage in repo
497 | languageData = languageData.sort(function(a, b){return b.size - a.size});
498 |
499 | // Get HTML for each language
500 | _.each(languageData, function(element){
501 | percentage = (parseInt(element.size)/sum*100).toFixed(1);
502 | languageHtml +='';
504 | });
505 |
506 | // Render language HTML to the container
507 | gitMethods.renderContent(languageHtml, options.selector,'.gt-repo-lg-stat');
508 | },
509 |
510 | // Get random HEX code for color
511 | getRandomColor: function(){
512 | return Math.random().toString(16).substring(2, 8);
513 | },
514 |
515 | // Convert milliseconds to time string
516 | millisecondsToStr: function(milliseconds) {
517 | function numberEnding(number) {
518 | return (number > 1) ? 's ago' : ' ago';
519 | }
520 | var temp = Math.floor(milliseconds / 1000);
521 |
522 | var years = Math.floor(temp / 31536000);
523 | if (years) return years + ' year' + numberEnding(years);
524 |
525 | var months = Math.floor((temp %= 31536000) / 2592000);
526 | if (months) return months + ' month' + numberEnding(months);
527 |
528 | var days = Math.floor((temp %= 2592000) / 86400);
529 | if (days) return days + ' day' + numberEnding(days);
530 |
531 | var hours = Math.floor((temp %= 86400) / 3600);
532 | if (hours) return 'about ' + hours + ' hour' + numberEnding(hours);
533 |
534 | var minutes = Math.floor((temp %= 3600) / 60);
535 | if (minutes) return minutes + ' minute' + numberEnding(minutes);
536 |
537 | var seconds = temp % 60;
538 | if (seconds) return seconds + ' second' + numberEnding(seconds);
539 |
540 | return 'just now';
541 | },
542 |
543 | // Render the content to the selector or subSelector
544 | renderContent: function(content, selector, subSelector){
545 | var selectorDivs = document.querySelectorAll(selector);
546 |
547 | for (var i = 0; i < selectorDivs.length; i++) {
548 | // if subSelector is passed, find it
549 | if (subSelector) {
550 | selectorDiv = selectorDivs[i].querySelector(subSelector);
551 | } else{
552 | selectorDiv = selectorDivs[i];
553 | }
554 | selectorDiv.innerHTML = content;
555 | }
556 |
557 | },
558 |
559 | // Set render limit for activities - default is 30
560 | setLimit: function(value){
561 | var limit;
562 | if (value !== 'undefined' && gitMethods.checkInteger(limit = parseInt(value, 10))) {
563 | limit = (limit>30)?30:limit;
564 | } else {
565 | limit = 30;
566 | }
567 | return limit;
568 | }
569 |
570 | };
571 |
572 |
573 | return Github;
574 | }));
--------------------------------------------------------------------------------