nitdoc: Add a function to check the repo github.
[nit.git] / share / nitdoc / scripts / js-facilities.js
1 // User
2 var userB64 = null;
3 var sessionStarted = false;
4 var editComment = 0;
5 var currentfileContent = '';
6
7 // SHA GitHub
8 var shaLastCommit = "";
9 var shaBaseTree;
10 var shaNewTree;
11 var shaNewCommit;
12 var shaBlob;
13 var shaMaster;
14 var repoExist = false;
15
16 /*
17 * JQuery Case Insensitive :icontains selector
18 */
19 $.expr[':'].icontains = function(obj, index, meta, stack){
20 return (obj.textContent.replace(/\[[0-9]+\]/g, "") || obj.innerText.replace(/\[[0-9]+\]/g, "") || jQuery(obj).text().replace(/\[[0-9]+\]/g, "") || '').toLowerCase().indexOf(meta[3].toLowerCase()) >= 0;
21 };
22
23 /*
24 * Quick Search global vars
25 */
26
27 // Current search results preview table
28 var currentTable = null;
29
30 //Hightlighted index in search result preview table
31 var currentIndex = -1;
32
33
34 /*
35 * Add folding and filtering facilities to class description page.
36 */
37 $(document).ready(function() {
38
39 // Hide edit tags
40 $('textarea').hide();
41 $('a[id=commitBtn]').hide();
42 $('a[id=cancelBtn]').hide();
43 // Hide Authenfication form
44 $(".popover").hide();
45 // Update display
46 updateDisplaying();
47
48 /*
49 * Highlight the spoted element
50 */
51 highlightBlock(currentAnchor());
52
53 /*
54 * Nav block folding
55 */
56
57 // Menu nav folding
58 $(".menu nav h3")
59 .prepend(
60 $(document.createElement("a"))
61 .html("-")
62 .addClass("fold")
63 )
64 .css("cursor", "pointer")
65 .click( function() {
66 if($(this).find("a.fold").html() == "+") {
67 $(this).find("a.fold").html("-");
68 } else {
69 $(this).find("a.fold").html("+");
70 }
71 $(this).nextAll().toggle();
72 })
73
74 // Insert search field
75 $("nav.main ul")
76 .append(
77 $(document.createElement("li"))
78 .append(
79 $(document.createElement("form"))
80 .append(
81 $(document.createElement("input"))
82 .attr({
83 id: "search",
84 type: "text",
85 autocomplete: "off",
86 value: "quick search..."
87 })
88 .addClass("notUsed")
89
90 // Key management
91 .keyup(function(e) {
92 switch(e.keyCode) {
93
94 // Select previous result on "Up"
95 case 38:
96 // If already on first result, focus search input
97 if(currentIndex == 0) {
98 $("#search").val($(currentTable.find("tr")[currentIndex]).data("searchDetails").name);
99 $("#search").focus();
100 // Else select previous result
101 } else if(currentIndex > 0) {
102 $(currentTable.find("tr")[currentIndex]).removeClass("activeSearchResult");
103 currentIndex--;
104 $(currentTable.find("tr")[currentIndex]).addClass("activeSearchResult");
105 $("#search").val($(currentTable.find("tr")[currentIndex]).data("searchDetails").name);
106 $("#search").focus();
107 }
108 break;
109
110 // Select next result on "Down"
111 case 40:
112 if(currentIndex < currentTable.find("tr").length - 1) {
113 $(currentTable.find("tr")[currentIndex]).removeClass("activeSearchResult");
114 currentIndex++;
115 $(currentTable.find("tr")[currentIndex]).addClass("activeSearchResult");
116 $("#search").val($(currentTable.find("tr")[currentIndex]).data("searchDetails").name);
117 $("#search").focus();
118 }
119 break;
120 // Go to url on "Enter"
121 case 13:
122 if(currentIndex > -1) {
123 window.location = $(currentTable.find("tr")[currentIndex]).data("searchDetails").url;
124 return false;
125 }
126 if($("#search").val().length == 0)
127 return false
128
129 window.location = "full-index.html#q=" + $("#search").val();
130 if(window.location.href.indexOf("full-index.html") > -1) {
131 location.reload();
132 }
133 return false;
134 break;
135
136 // Hide results preview on "Escape"
137 case 27:
138 $(this).blur();
139 if(currentTable != null) {
140 currentTable.remove();
141 currentTable = null;
142 }
143 break;
144
145 default:
146 if($("#search").val().length == 0) {
147 return false;
148 }
149
150 // Remove previous table
151 if(currentTable != null) {
152 currentTable.remove();
153 }
154
155 // Build results table
156 currentIndex = -1;
157 currentTable = $(document.createElement("table"));
158
159 // Escape regexp related characters in query
160 var query = $("#search").val();
161 query = query.replace(/\[/gi, "\\[");
162 query = query.replace(/\|/gi, "\\|");
163 query = query.replace(/\*/gi, "\\*");
164 query = query.replace(/\+/gi, "\\+");
165 query = query.replace(/\\/gi, "\\\\");
166 query = query.replace(/\?/gi, "\\?");
167 query = query.replace(/\(/gi, "\\(");
168 query = query.replace(/\)/gi, "\\)");
169
170 var index = 0;
171 var regexp = new RegExp("^" + query, "i");
172 for(var entry in entries) {
173 if(index > 10) {
174 break;
175 }
176 var result = entry.match(regexp);
177 if(result != null && result.toString().toUpperCase() == $("#search").val().toUpperCase()) {
178 for(var i = 0; i < entries[entry].length; i++) {
179 if(index > 10) {
180 break;
181 }
182 currentTable.append(
183 $(document.createElement("tr"))
184 .data("searchDetails", {name: entry, url: entries[entry][i]["url"]})
185 .data("index", index)
186 .append($(document.createElement("td")).html(entry))
187 .append(
188 $(document.createElement("td"))
189 .addClass("entryInfo")
190 .html(entries[entry][i]["txt"] + "&nbsp;&raquo;"))
191 .mouseover( function() {
192 $(currentTable.find("tr")[currentIndex]).removeClass("activeSearchResult");
193 $(this).addClass("activeSearchResult");
194 currentIndex = $(this).data("index");
195 })
196 .mouseout( function() {
197 $(this).removeClass("activeSearchResult");
198 })
199 .click( function() {
200 window.location = $(this).data("searchDetails")["url"];
201 })
202 );
203 index++;
204 }
205 }
206 }
207
208 // Initialize table properties
209 currentTable.attr("id", "searchTable");
210 currentTable.css("position", "absolute");
211 currentTable.width($("#search").outerWidth());
212 $("header").append(currentTable);
213 currentTable.offset({left: $("#search").offset().left + ($("#search").outerWidth() - currentTable.outerWidth()), top: $("#search").offset().top + $("#search").outerHeight()});
214
215 // Preselect first entry
216 if(currentTable.find("tr").length > 0) {
217 currentIndex = 0;
218 $(currentTable.find("tr")[currentIndex]).addClass("activeSearchResult");
219 $("#search").focus();
220 }
221 break;
222 }
223 })
224 .focusout(function() {
225 if($(this).val() == "") {
226 $(this).addClass("notUsed");
227 $(this).val("quick search...");
228 }
229 })
230 .focusin(function() {
231 if($(this).val() == "quick search...") {
232 $(this).removeClass("notUsed");
233 $(this).val("");
234 }
235 })
236 )
237 .submit( function() {
238 return false;
239 })
240 )
241 );
242
243 // Close quicksearch list on click
244 $(document).click(function(e) {
245 if(e.target != $("#search")[0] && e.target != $("#searchTable")[0]) {
246 if(currentTable != null) {
247 currentTable.remove();
248 currentTable = null;
249 }
250 }
251 });
252
253 // Insert filter field
254 $("article.filterable h2, nav.filterable h3")
255 .after(
256 $(document.createElement("div"))
257 .addClass("filter")
258 .append(
259 $(document.createElement("input"))
260 .attr({
261 type: "text",
262 value: "filter..."
263 })
264 .addClass("notUsed")
265 .keyup(function() {
266 $(this).parent().parent().find("ul li:not(:icontains('" + $(this).val() + "'))").addClass("hide");
267 $(this).parent().parent().find("ul li:icontains('" + $(this).val() + "')").removeClass("hide");
268 })
269 .focusout(function() {
270 if($(this).val() == "") {
271 $(this).addClass("notUsed");
272 $(this).val("filter...");
273 }
274 })
275 .focusin(function() {
276 if($(this).val() == "filter...") {
277 $(this).removeClass("notUsed");
278 $(this).val("");
279 }
280 })
281 )
282 );
283
284 // Filter toggle between H I R in nav porperties list
285 $("nav.properties.filterable .filter")
286 .append(
287 $(document.createElement("a"))
288 .html("H")
289 .attr({
290 title: "hide inherited properties"
291 })
292 .click( function() {
293 if($(this).hasClass("hidden")) {
294 $(this).parent().parent().find("li.inherit").show();
295 } else {
296 $(this).parent().parent().find("li.inherit").hide();
297 }
298
299 $(this).toggleClass("hidden");
300 })
301 )
302 .append(
303 $(document.createElement("a"))
304 .html("R")
305 .attr({
306 title: "hide redefined properties"
307 })
308 .click( function() {
309 if($(this).hasClass("hidden")) {
310 $(this).parent().parent().find("li.redef").show();
311 } else {
312 $(this).parent().parent().find("li.redef").hide();
313 }
314
315 $(this).toggleClass("hidden");
316 })
317 )
318 .append(
319 $(document.createElement("a"))
320 .html("I")
321 .attr({
322 title: "hide introduced properties"
323 })
324 .click( function() {
325 if($(this).hasClass("hidden")) {
326 $(this).parent().parent().find("li.intro").show();
327 } else {
328 $(this).parent().parent().find("li.intro").hide();
329 }
330
331 $(this).toggleClass("hidden");
332 })
333 );
334
335 // Filter toggle between I R in
336 $("article.properties.filterable .filter, article.classes.filterable .filter")
337 .append(
338 $(document.createElement("a"))
339 .html("I")
340 .attr({
341 title: "hide introduced properties"
342 })
343 .click( function() {
344 if($(this).hasClass("hidden")) {
345 $(this).parent().parent().find("li.intro").show();
346 } else {
347 $(this).parent().parent().find("li.intro").hide();
348 }
349
350 $(this).toggleClass("hidden");
351 })
352 )
353 .append(
354 $(document.createElement("a"))
355 .html("R")
356 .attr({
357 title: "hide redefined properties"
358 })
359 .click( function() {
360 if($(this).hasClass("hidden")) {
361 $(this).parent().parent().find("li.redef").show();
362 } else {
363 $(this).parent().parent().find("li.redef").hide();
364 }
365
366 $(this).toggleClass("hidden");
367 })
368 );
369
370 /*
371 * Anchors jumps
372 */
373 $("a[href*='#']").click( function() {
374 highlightBlock($(this).attr("href").split(/#/)[1]);
375 });
376
377 //Preload filter fields with query string
378 preloadFilters();
379 // Hide Authenfication form
380 $(".popover").hide();
381 // Display Login modal
382 $("#logGitHub").click(function(){ displayLogginModal(); });
383 // Update display
384 updateDisplaying();
385 // If cookie existing the session is opened
386 if(sessionStarted){ userB64 = "Basic " + getUserPass("logginNitdoc"); }
387
388 // Sign In an github user or Log out him
389 $("#signIn").click(function(){
390 if(!sessionStarted){
391 if($('#loginGit').val() == "" || $('#passwordGit').val() == ""){ displayMessage('The comment field is empty!', 40, 45); }
392 else
393 {
394 userName = $('#loginGit').val();
395 password = $('#passwordGit').val();
396 repoName = $('#repositoryGit').val();
397 branchName = $('#branchGit').val();
398 userB64 = "Basic " + base64.encode(userName+':'+password);
399 setCookie("logginNitdoc", base64.encode(userName+':'+password+':'+repoName+':'+branchName), 1);
400 $('#loginGit').val("");
401 $('#passwordGit').val("");
402 }
403 }
404 else
405 {
406 // Delete cookie and reset settings
407 del_cookie("logginNitdoc");
408 }
409 displayLogginModal();
410 });
411
412 // Activate edit mode
413 $('pre[class=text_label]').click(function(){
414 // the customer is loggued ?
415 if(!sessionStarted || userName == ""){
416 // No => nothing happen
417 return;
418 }
419 else{
420 var arrayNew = $(this).text().split('\n');
421 var lNew = arrayNew.length - 1;
422 var adapt = "";
423
424 for (var i = 0; i < lNew; i++) {
425 adapt += arrayNew[i];
426 if(i < lNew-1){ adapt += "\n"; }
427 }
428 editComment += 1;
429 // hide comment
430 $(this).hide();
431 // Show edit box
432 $(this).next().show();
433 // Show cancel button
434 $(this).next().next().show();
435 // Show commit button
436 $(this).next().next().next().show();
437 // Add text in edit box
438 if($(this).next().val() == ""){ $(this).next().val(adapt); }
439 // Resize edit box
440 $(this).next().height($(this).next().prop("scrollHeight"));
441 // Select it
442 $(this).next().select();
443 preElement = $(this);
444 }
445 });
446
447 // Disable the edit mode
448 $('a[id=cancelBtn]').click(function(){
449 if(editComment > 0){ editComment -= 1; }
450 // Hide itself
451 $(this).hide();
452 // Hide commitBtn
453 $(this).next().hide();
454 // Hide Textarea
455 $(this).prev().hide();
456 // Show comment
457 $(this).prev().prev().show();
458 });
459
460 // Display commit form
461 $('a[id=commitBtn]').click(function(){
462 updateComment = $(this).prev().prev().val();
463 commentType = $(this).prev().prev().prev().attr('type');
464
465 if(updateComment == ""){ displayMessage('The comment field is empty!', 40, 45); }
466 else{
467 if(!sessionStarted){
468 displayMessage("You need to be loggued before commit something", 45, 40);
469 displayLogginModal();
470 return;
471 }
472 $('#commitMessage').val('New commit');
473 pathFile = $(this).prev().prev().prev().attr('tag');
474 $('#modal').show().prepend('<a class="close"><img src="resources/icons/close.png" class="btn_close" title="Close" alt="Close" /></a>');
475 $('body').append('<div id="fade"></div>');
476 $('#fade').css({'filter' : 'alpha(opacity=80)'}).fadeIn();
477 }
478 });
479
480 // Close commit form
481 $('.btn_close').click(function(){
482 $(this).hide();
483 $(this).next().hide();
484 if(editComment > 0){ editComment -= 1; }
485 });
486
487 //Close Popups and Fade Layer
488 $('body').on('click', 'a.close, #fade', function() {
489 if(editComment > 0){ editComment -= 1; }
490 $('#fade , #modal').fadeOut(function() {
491 $('#fade, a.close').remove();
492 });
493 $('#modalQuestion').hide();
494 });
495
496 $('#loginAction').click(function(){
497 var text;
498 var url;
499 var line;
500 // Look if the customer is logged
501 if(!sessionStarted){
502 displayMessage("You need to be loggued before commit something", 100, 40);
503 $('.popover').show();
504 return;
505 }
506 else{ userB64 = "Basic " + getUserPass("logginNitdoc"); }
507 githubRepo = repoName;
508 // Check if repo exist
509 isRepoExisting();
510 if(repoExist){
511 editComment -= 1;
512 commitMessage = $('#commitMessage').val();
513 if(commitMessage == ""){ commitMessage = "New commit";}
514 if(sessionStarted){
515 if ($.trim(updateComment) == ''){ this.value = (this.defaultValue ? this.defaultValue : ''); }
516 else{ startCommitProcess(); }
517 }
518 $('#modal, #modalQuestion').fadeOut(function() {
519 $('#login').val("");
520 $('#password').val("");
521 $('textarea').hide();
522 $('textarea').prev().show();
523 });
524 $('a[id=cancelBtn]').hide();
525 $('a[id=commitBtn]').hide();
526 }
527 else{ editComment -= 1; }
528 });
529 });
530
531 /* Parse current URL and return anchor name */
532 function currentAnchor() {
533 var index = document.location.hash.indexOf("#");
534 if (index >= 0) {
535 return document.location.hash.substring(index + 1);
536 }
537 return null;
538 }
539
540 /* Prealod filters field using search query */
541 function preloadFilters() {
542 // Parse URL and get query string
543 var search = currentAnchor();
544
545 if(search == null || search.indexOf("q=") == -1)
546 return;
547
548 search = search.substring(2, search.length);
549
550 if(search == "" || search == "undefined")
551 return;
552
553 $(":text").val(search);
554 $(".filter :text")
555 .removeClass("notUsed")
556 .trigger("keyup");
557
558 }
559
560 /* Hightlight the spoted block */
561 function highlightBlock(a) {
562 if(a == undefined) {
563 return;
564 }
565
566 $(".highlighted").removeClass("highlighted");
567
568 var target = $("#" + a);
569
570 if(target.is("article")) {
571 target.parent().addClass("highlighted");
572 }
573
574 target.addClass("highlighted");
575 target.show();
576 }
577
578 // Init process to commit the new comment
579 function startCommitProcess()
580 {
581 var numL = preElement.attr("title");
582 commentLineStart = numL.split('-')[0] - 1;
583 commentLineEnd = (commentLineStart + preElement.text().split('\n').length) - 1;
584 state = true;
585 replaceComment(updateComment, currentfileContent);
586 getLastCommit();
587 getBaseTree();
588 editComment = false;
589 }
590
591 function displayLogginModal(){
592 if ($('.popover').is(':hidden')) { $('.popover').show(); }
593 else { $('.popover').hide(); }
594 updateDisplaying();
595 }
596
597 function updateDisplaying(){
598 if (checkCookie())
599 {
600 $('#loginGit').hide();
601 $('#passwordGit').hide();
602 $('#lbpasswordGit').hide();
603 $('#lbloginGit').hide();
604 $('#repositoryGit').hide();
605 $('#lbrepositoryGit').hide();
606 $('#lbbranchGit').hide();
607 $('#branchGit').hide();
608 $("#liGitHub").attr("class", "current");
609 $("#imgGitHub").attr("src", "resources/icons/github-icon-w.png");
610 $('#nickName').text(userName);
611 $('#githubAccount').attr("href", "https://github.com/"+userName);
612 $('#logginMessage').css({'display' : 'block'});
613 $('#logginMessage').css({'text-align' : 'center'});
614 $('.popover').css({'height' : '80px'});
615 $('#signIn').text("Sign out");
616 sessionStarted = true;
617 }
618 else
619 {
620 sessionStarted = false;
621 $('#logginMessage').css({'display' : 'none'});
622 $("#liGitHub").attr("class", "");
623 $("#imgGitHub").attr("src", "resources/icons/github-icon.png");
624 $('#loginGit').val("");
625 $('#passwordGit').val("");
626 $('#nickName').text("");
627 $('.popover').css({'height' : '280px'});
628 $('#logginMessage').css({'display' : 'none'});
629 $('#repositoryGit').val($('#repoName').attr('name'));
630 $('#branchGit').val('wikidoc');
631 $('#signIn').text("Sign In");
632 $('#loginGit').show();
633 $('#passwordGit').show();
634 $('#lbpasswordGit').show();
635 $('#lbloginGit').show();
636 $('#repositoryGit').show();
637 $('#lbrepositoryGit').show();
638 $('#lbbranchGit').show();
639 $('#branchGit').show();
640 }
641 }
642
643 function setCookie(c_name, value, exdays)
644 {
645 var exdate=new Date();
646 exdate.setDate(exdate.getDate() + exdays);
647 var c_value=escape(value) + ((exdays==null) ? "" : "; expires="+exdate.toUTCString());
648 document.cookie=c_name + "=" + c_value;
649 }
650
651 function del_cookie(c_name)
652 {
653 document.cookie = c_name + '=; expires=Thu, 01 Jan 1970 00:00:01 GMT;';
654 }
655
656 function getCookie(c_name)
657 {
658 var c_value = document.cookie;
659 var c_start = c_value.indexOf(" " + c_name + "=");
660 if (c_start == -1) { c_start = c_value.indexOf(c_name + "="); }
661 if (c_start == -1) { c_value = null; }
662 else
663 {
664 c_start = c_value.indexOf("=", c_start) + 1;
665 var c_end = c_value.indexOf(";", c_start);
666 if (c_end == -1) { c_end = c_value.length; }
667 c_value = unescape(c_value.substring(c_start,c_end));
668 }
669 return c_value;
670 }
671
672 function getUserPass(c_name){
673 var cookie = base64.decode(getCookie(c_name));
674 return base64.encode(cookie.split(':')[0] + ':' + cookie.split(':')[1]);
675 }
676
677 function checkCookie()
678 {
679 var cookie=getCookie("logginNitdoc");
680 if (cookie!=null && cookie!="")
681 {
682 cookie = base64.decode(cookie);
683 userName = cookie.split(':')[0];
684 repoName = cookie.split(':')[2];
685 branchName = cookie.split(':')[3];
686 return true;
687 }
688 else { return false; }
689 }
690
691
692 /*
693 * Base64
694 */
695 base64 = {};
696 base64.PADCHAR = '=';
697 base64.ALPHA = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
698 base64.getbyte64 = function(s,i) {
699 // This is oddly fast, except on Chrome/V8.
700 // Minimal or no improvement in performance by using a
701 // object with properties mapping chars to value (eg. 'A': 0)
702 var idx = base64.ALPHA.indexOf(s.charAt(i));
703 if (idx == -1) {
704 throw "Cannot decode base64";
705 }
706 return idx;
707 }
708
709 base64.decode = function(s) {
710 // convert to string
711 s = "" + s;
712 var getbyte64 = base64.getbyte64;
713 var pads, i, b10;
714 var imax = s.length
715 if (imax == 0) {
716 return s;
717 }
718
719 if (imax % 4 != 0) {
720 throw "Cannot decode base64";
721 }
722
723 pads = 0
724 if (s.charAt(imax -1) == base64.PADCHAR) {
725 pads = 1;
726 if (s.charAt(imax -2) == base64.PADCHAR) {
727 pads = 2;
728 }
729 // either way, we want to ignore this last block
730 imax -= 4;
731 }
732
733 var x = [];
734 for (i = 0; i < imax; i += 4) {
735 b10 = (getbyte64(s,i) << 18) | (getbyte64(s,i+1) << 12) |
736 (getbyte64(s,i+2) << 6) | getbyte64(s,i+3);
737 x.push(String.fromCharCode(b10 >> 16, (b10 >> 8) & 0xff, b10 & 0xff));
738 }
739
740 switch (pads) {
741 case 1:
742 b10 = (getbyte64(s,i) << 18) | (getbyte64(s,i+1) << 12) | (getbyte64(s,i+2) << 6)
743 x.push(String.fromCharCode(b10 >> 16, (b10 >> 8) & 0xff));
744 break;
745 case 2:
746 b10 = (getbyte64(s,i) << 18) | (getbyte64(s,i+1) << 12);
747 x.push(String.fromCharCode(b10 >> 16));
748 break;
749 }
750 return x.join('');
751 }
752
753 base64.getbyte = function(s,i) {
754 var x = s.charCodeAt(i);
755 if (x > 255) {
756 throw "INVALID_CHARACTER_ERR: DOM Exception 5";
757 }
758 return x;
759 }
760
761
762 base64.encode = function(s) {
763 if (arguments.length != 1) {
764 throw "SyntaxError: Not enough arguments";
765 }
766 var padchar = base64.PADCHAR;
767 var alpha = base64.ALPHA;
768 var getbyte = base64.getbyte;
769
770 var i, b10;
771 var x = [];
772
773 // convert to string
774 s = "" + s;
775
776 var imax = s.length - s.length % 3;
777
778 if (s.length == 0) {
779 return s;
780 }
781 for (i = 0; i < imax; i += 3) {
782 b10 = (getbyte(s,i) << 16) | (getbyte(s,i+1) << 8) | getbyte(s,i+2);
783 x.push(alpha.charAt(b10 >> 18));
784 x.push(alpha.charAt((b10 >> 12) & 0x3F));
785 x.push(alpha.charAt((b10 >> 6) & 0x3f));
786 x.push(alpha.charAt(b10 & 0x3f));
787 }
788 switch (s.length - imax) {
789 case 1:
790 b10 = getbyte(s,i) << 16;
791 x.push(alpha.charAt(b10 >> 18) + alpha.charAt((b10 >> 12) & 0x3F) +
792 padchar + padchar);
793 break;
794 case 2:
795 b10 = (getbyte(s,i) << 16) | (getbyte(s,i+1) << 8);
796 x.push(alpha.charAt(b10 >> 18) + alpha.charAt((b10 >> 12) & 0x3F) +
797 alpha.charAt((b10 >> 6) & 0x3f) + padchar);
798 break;
799 }
800 return x.join('');
801 }
802
803 $.fn.spin = function(opts) {
804 this.each(function() {
805 var $this = $(this),
806 data = $this.data();
807
808 if (data.spinner) {
809 data.spinner.stop();
810 delete data.spinner;
811 }
812 if (opts !== false) {
813 data.spinner = new Spinner($.extend({color: $this.css('color')}, opts)).spin(this);
814 }
815 });
816 return this;
817 };
818
819 function getLastCommit()
820 {
821 var urlHead = '';
822 if(sessionStarted){ urlHead = "https://api.github.com/repos/"+userName+"/"+githubRepo+"/git/refs/heads/"+branchName;}
823 else{
824 // TODO: get url of the original repo.
825 return;
826 }
827
828 $.ajax({
829 beforeSend: function (xhr) {
830 if (userB64 != ""){ xhr.setRequestHeader ("Authorization", userB64); }
831 },
832 type: "GET",
833 url: urlHead,
834 dataType:"json",
835 async: false,
836 success: function(success)
837 {
838 shaLastCommit = success.object.sha;
839 }
840 });
841 }
842
843 function getBaseTree()
844 {
845 $.ajax({
846 beforeSend: function (xhr) {
847 if (userB64 != ""){ xhr.setRequestHeader ("Authorization", userB64); }
848 },
849 type: "GET",
850 url: "https://api.github.com/repos/"+userName+"/"+githubRepo+"/git/commits/" + shaLastCommit,
851 dataType:"json",
852 async: false,
853 success: function(success)
854 {
855 shaBaseTree = success.tree.sha;
856 if (state){ setBlob(); }
857 else{ return; }
858 },
859 error: function(){
860 return;
861 }
862 });
863 }
864
865 function setNewTree()
866 {
867 $.ajax({
868 beforeSend: function (xhr) { xhr.setRequestHeader ("Authorization", userB64); },
869 type: "POST",
870 url: "https://api.github.com/repos/"+userName+"/"+githubRepo+"/git/trees",
871 async: false,
872 data:'{ "base_tree" : "'+shaBaseTree+'", '+
873 '"tree":[{ '+
874 '"path":"'+ pathFile +'",'+
875 '"mode":"100644",'+
876 '"type":"blob",'+
877 '"sha": "'+ shaBlob +'"'+
878 '}] '+
879 '}',
880 success: function(success)
881 { // si l'appel a bien fonctionné
882 shaNewTree = JSON.parse(success).sha;
883 setNewCommit();
884 },
885 error: function(){
886 return;
887 }
888 });
889 }
890
891 function setNewCommit()
892 {
893 $.ajax({
894 beforeSend: function (xhr) { xhr.setRequestHeader ("Authorization", userB64); },
895 type: "POST",
896 url: "https://api.github.com/repos/"+userName+"/"+githubRepo+"/git/commits",
897 async: false,
898 data:'{ "message" : "'+ commitMessage +'", '+
899 '"parents" :"'+shaLastCommit+'",'+
900 '"tree": "'+shaNewTree+'"'+
901 '}',
902 success: function(success)
903 {
904 shaNewCommit = JSON.parse(success).sha;
905 commit();
906 },
907 error: function(){
908 return;
909 }
910 });
911 }
912
913 //Create a commit
914 function commit()
915 {
916 $.ajax({
917 beforeSend: function (xhr) { xhr.setRequestHeader ("Authorization", userB64); },
918 type: "POST",
919 url: "https://api.github.com/repos/"+userName+"/"+githubRepo+"/git/refs/heads/"+branchName,
920 data:'{ "sha" : "'+shaNewCommit+'", '+
921 '"force" :"true"'+
922 '}',
923 success: function(success) { displayMessage('Commit created successfully', 40, 40); },
924 error:function(error){ displayMessage('Error ' + JSON.parse(error).object.message, 40, 40); }
925 });
926 }
927
928 // Create a blob
929 function setBlob()
930 {
931 $.ajax({
932 beforeSend: function (xhr) { xhr.setRequestHeader ("Authorization", userB64); },
933 type: "POST",
934 url: "https://api.github.com/repos/"+userName+"/"+githubRepo+"/git/blobs",
935 async: false,
936 data:'{ "content" : "'+text.replace(/\r?\n/g, '\\n').replace(/\t/g, '\\t').replace(/\"/g,'\\"')+'", '+
937 '"encoding" :"utf-8"'+
938 '}',
939 success: function(success)
940 {
941 shaBlob = JSON.parse(success).sha;
942 setNewTree();
943 },
944 error:function(error){
945 displayMessage('Error : Problem parsing JSON', 40, 40);
946 return;
947 }
948 });
949 }
950
951 // Display file content
952 function getFileContent(urlFile, newComment)
953 {
954 $.ajax({
955 beforeSend: function (xhr) {
956 xhr.setRequestHeader ("Accept", "application/vnd.github-blob.raw");
957 if (userB64 != ""){ xhr.setRequestHeader ("Authorization", userB64); }
958 },
959 type: "GET",
960 url: urlFile,
961 async:false,
962 success: function(success)
963 {
964 state = true;
965 replaceComment(newComment, success);
966 }
967 });
968 }
969
970 function replaceComment(newComment, fileContent){
971 var arrayNew = newComment.split('\n');
972 var lNew = arrayNew.length;
973 text = "";
974 var lines = fileContent.split("\n");
975 for (var i = 0; i < lines.length; i++) {
976 if(i == commentLineStart){
977 // We change the comment
978 for(var j = 0; j < lNew; j++){
979 if(commentType == 1){ text += "\t# " + arrayNew[j] + "\n"; }
980 else{
981 if(arrayNew[j] == ""){ text += "#"+"\n"; }
982 else{ text += "# " + arrayNew[j] + "\n"; }
983 }
984 }
985 }
986 else if(i < commentLineStart || i >= commentLineEnd){
987 if(i == lines.length-1){ text += lines[i]; }
988 else{ text += lines[i] + "\n"; }
989 }
990 }
991 }
992
993 function getCommentLastCommit(path){
994 var urlRaw;
995 getLastCommit();
996 if(shaLastCommit != ""){
997 if (checkCookie()) { urlRaw="https://rawgithub.com/"+ userName +"/"+ repoName +"/" + shaLastCommit + "/" + path; }
998 else{ urlRaw="https://rawgithub.com/StefanLage/"+ $('#repoName').attr('name') +"/" + shaLastCommit + "/" + path; }
999
1000 $.ajax({
1001 type: "GET",
1002 url: urlRaw,
1003 async: false,
1004 success: function(success)
1005 {
1006 currentfileContent = success;
1007 }
1008 });
1009 }
1010 }
1011
1012 function displayMessage(msg, widthDiv, margModal){
1013 $('#modal').hide();
1014 $('#btnCreateBranch').css('margin-left',widthDiv + '%');
1015 $('#txtQuestion').text(msg);
1016 $('#btnCreateBranch').text("Ok");
1017 $('#btnCancelBranch').hide();
1018 $('#modalQuestion').css({'left' : margModal + '%'})
1019 $('#modalQuestion').show();
1020 $('#modalQuestion').show().prepend('<a class="close"><img src="resources/icons/close.png" class="btnCloseQuestion" title="Close" alt="Close" /></a>');
1021 $('body').append('<div id="fade"></div>');
1022 $('#fade').css({'filter' : 'alpha(opacity=80)'}).fadeIn();
1023 }
1024
1025 // Check if the repo already exist
1026 function isRepoExisting(){
1027 $.ajax({
1028 beforeSend: function (xhr) {
1029 if (userB64 != "") { xhr.setRequestHeader ("Authorization", userB64); }
1030 },
1031 type: "GET",
1032 url: "https://api.github.com/repos/"+userName+"/"+githubRepo,
1033 async:false,
1034 dataType:'json',
1035 success: function(){ repoExist = true; },
1036 error: function()
1037 {
1038 displayMessage('Repo not found !', 35, 45);
1039 repoExist = false;
1040 }
1041 });
1042 }