1 /* This file is part of NIT ( http://www.nitlanguage.org ).
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
7 http://www.apache.org/licenses/LICENSE-2.0
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
15 Documentation generator for the nit language.
16 Generate API documentation in HTML format from nit source code.
20 * Nitdoc.Github comment edition module
22 * Allows user to modify source code comments directly from the Nitdoc
25 var Nitdoc
= Nitdoc ||
{};
27 Nitdoc
.GitHub
= {}; // Declare Nitdoc.GitHub submodule
30 $
(document
).ready(function() {
31 //FIXME base should be choosen by user
32 var upstream
= $
("body").attr("data-github-upstream");
33 var basesha1
= $
("body").attr("data-github-base-sha1");
34 if(upstream
&& basesha1
) {
35 Nitdoc
.GitHub
.UI
.init(upstream
, basesha1
);
40 * Nitdoc.Github.UI for comment edition module
42 Nitdoc
.GitHub
.UI
= function() {
43 var openedComments
= 0; // currently edited comments count
44 var user
= false; // logged user
47 var init
= function(upstream
, basesha1
) {
48 console
.log("init GitHub module (upstream: "+ upstream
+", base: " + basesha1
+ ")");
51 var parts
= upstream
.split(":");
59 // check local session
60 if(localStorage
.user
) {
61 var session
= JSON
.parse(localStorage
.user
);
62 var user
= tryLogin(session
.login
, Base64
.decode(session
.password
), session
.repo
, session
.branch
);
64 console
.log("Session found but authentification failed");
68 console
.log("No session found");
72 Nitdoc
.GitHub
.LoginBox
.init("nav.main ul");
73 if(user
&& user
.login
) {
74 Nitdoc
.GitHub
.LoginBox
.displayLogout(origin
, user
);
77 Nitdoc
.GitHub
.LoginBox
.displayLogin();
80 // Prevent page unload if there is comments in editing mode
81 $
(window
).on('beforeunload', function() {
82 if(Nitdoc
.GitHub
.UI
.getOpenedComments() > 0){
83 return "There is uncommited modified comments. Are you sure you want to leave this page?";
88 // Activate comment UI for a logged user
89 var activate
= function(loggedUser
) {
94 // check local storage synchro with branch
95 if(localStorage
.base
!= origin
.sha
) {
96 console
.log("Base changed: cleaned cache");
97 localStorage
.requests
= "[]";
98 localStorage
.base
= origin
.sha
;
101 attachCommentEvents();
106 var disactivate
= function() {
107 if(Nitdoc
.GitHub
.UI
.getOpenedComments() > 0){
108 if(!confirm('There is uncommited modified comments. Are you sure you want to leave this page?')) {
112 // close session and purge cookie
113 localStorage
.clear();
114 $
(window
).unbind('beforeunload');
115 window
.location
.reload();
118 // Attempt login through GitHub API
119 var tryLogin
= function(login
, password
, repo
, branch
) {
120 var user
= new Nitdoc
.GitHub
.User(login
, password
, repo
, branch
);
121 if(!Nitdoc
.GitHub
.API
.login(user
)) {
122 return "error:login";
124 // check github profile fields
125 if(!user
.infos
.name ||
!user
.infos
.email
) {
126 return "error:profile";
128 // check correct base commit
129 var commit
= Nitdoc
.GitHub
.API
.getCommit(user
, origin
.sha
);
130 if(!commit ||
!commit
.sha
) {
136 // Attach edit button on each comment
137 var attachCommentEvents
= function() {
138 // Blocks without comment
139 $
("span.noComment").each(function() {
140 //FIXME this should be done by nitdoc
141 var baseComment
= $
(this).parent().prev();
142 var location
= Nitdoc
.GitHub
.Utils
.parseLocation(baseComment
.attr("data-comment-location"));
143 var locString
= location
.path
+ ":" + location
.lstart
+ "," + location
.tabpos
+ "--" + location
.lstart
+ ",0";
144 baseComment
.attr("data-comment-location", locString
);
145 $
(this).html("<a class='nitdoc-github-editComment noComment'>add comment</a> for ");
146 $
(this).addClass("nitdoc-github-editComment");
148 // Blocks with comment
149 $
('.description div.comment').each(function() {
150 var p
= $
(this).next();
151 p
.prepend("<span class='nitdoc-github-editComment'><a class='nitdoc-github-editComment'>edit comment</a> for </span>")
154 // Attach links events
155 $
('a.nitdoc-github-editComment').each(function() {
156 $
(this).css("cursor", "pointer")
157 $
(this).click(function() {
159 $
(this).parent().hide();
163 if(!$
(this).hasClass("noComment")) {
164 $
(this).parent().parent().prev().hide();
165 baseTextarea
= $
(this).parent().parent().prev().prev();
167 baseTextarea
= $
(this).parent().parent().prev();
170 infos
.user
= Nitdoc
.GitHub
.UI
.getUser();
171 infos
.location
= Nitdoc
.GitHub
.Utils
.parseLocation(baseTextarea
.attr("data-comment-location"));
172 infos
.namespace = baseTextarea
.attr("data-comment-namespace");
173 infos
.oldComment
= baseTextarea
.val();
174 var box
= new Nitdoc
.GitHub
.CommentBox(infos
);
175 box
.open(baseTextarea
);
180 // reload comments from saved pull request
181 var reloadComments
= function() {
182 if(!localStorage
.requests
){ return; }
183 var requests
= JSON
.parse(localStorage
.requests
);
184 var converter
= new Markdown
.Converter();
185 // Look for modified comments in page
187 if(!requests
[i]) { continue; }
188 var request
= requests
[i];
189 $
("textarea[data-comment-location=\"" + request
.location
+ "\"]").each(function () {
190 var div
= $
(this).next();
191 if(request
.isClosed
) {
192 if(div
.is("div.comment.newComment")) {
193 // hide empty comment
195 div
.next().find("span.noComment").show();
197 } else if(div
.is("div.comment.locked")) {
200 div
.append(converter
.makeHtml($
(this).text()));
201 div
.removeClass("locked");
202 div
.css("cursor", "pointer")
204 div
.next().find("span.nitdoc-github-editComment").show();
207 // create div for the new coment
208 if(!div
.is("div.comment")) {
209 $
(this).after("<div class='comment newComment'></div>");
210 div
= $
(this).next();
212 // lock modified comment
213 if(!div
.hasClass("locked")) {
214 // convert modified comment to markdown
216 div
.append(converter
.makeHtml(Base64
.decode(request
.comment
)));
218 div
.css("cursor", "auto");
219 div
.addClass("locked");
220 div
.next().find("span.nitdoc-github-editComment").hide();
222 $
("<p class='locked inheritance'>")
223 .text("comment modified in ")
224 .append("<a href='"+ request
.request
.html_url
+"' target='_blank' title='Review on GitHub'>pull request #"+ request
.request
.number
+"</a>")
227 $
("<a data-pullrequest-number='"+ request
.request
.number
+"' class='nitdoc-github-update'>update</a>")
229 $
(this).parent().hide();
231 var baseTextarea
= div
.prev();
234 infos
.user
= Nitdoc
.GitHub
.UI
.getUser();
235 infos
.location
= Nitdoc
.GitHub
.Utils
.parseLocation(baseTextarea
.attr("data-comment-location"));
236 infos
.namespace = baseTextarea
.attr("data-comment-namespace");
237 infos
.oldComment
= baseTextarea
.val();
238 infos
.requestID
= $
(this).attr("data-pullrequest-number");
239 var box
= new Nitdoc
.GitHub
.CommentBox(infos
);
240 box
.open(baseTextarea
);
245 $
("<a data-pullrequest-number='"+ request
.request
.number
+"' class='nitdoc-github-cancel'>cancel</a>")
247 ui
.closePullRequest($
(this).attr("data-pullrequest-number"));
253 // hide "add comment" link
254 if(div
.hasClass("newComment")) {
255 div
.next().next().find("span.noComment").hide();
263 // Commit changes and send pull request
264 var saveChanges
= function(infos
) {
265 // if pull request update close existing pull request for the comment
266 if(infos
.requestID
) {
267 closePullRequest(infos
.requestID
);
271 var fileContent
= getFileContent(infos
.location
.path
);
272 infos
.newContent
= Nitdoc
.GitHub
.Utils
.mergeComment(fileContent
, infos
.newComment
, infos
.location
);
275 infos
.request
= pushChanges(infos
)
277 Nitdoc
.GitHub
.ModalBox
.open("Unable to commit changes!", response
, true);
282 // close boxes and reload comments
283 Nitdoc
.GitHub
.CommitBox
.close();
284 infos
.commentBox
.close();
289 Creating a new pull request with the new comment take 5 steps:
290 1. get the base tree from latest commit
292 2. create a new blob with updated file content
293 3. post a new tree from base tree and blob
294 4. post the new commit with new tree
295 5. create the pull request
297 var pushChanges
= function(infos
) {
298 var baseTree
= Nitdoc
.GitHub
.API
.getTree(user
, origin
.sha
);
300 Nitdoc
.GitHub
.ModalBox
.open("Unable to locate base tree!", baseTree
.status
+ ": " + baseTree
.statusText
, true);
303 console
.log("Base tree: " + baseTree
.url
);
304 var newBlob
= Nitdoc
.GitHub
.API
.createBlob(user
, infos
.newContent
);
306 Nitdoc
.GitHub
.ModalBox
.open("Unable to create new blob!", newBlob
.status
+ ": " + newBlob
.statusText
, true);
309 console
.log("New blob: " + newBlob
.url
);
310 var newTree
= Nitdoc
.GitHub
.API
.createTree(user
, baseTree
, infos
.location
.path
, newBlob
);
312 Nitdoc
.GitHub
.ModalBox
.open("Unable to create new tree!", newTree
.status
+ ": " + newTree
.statusText
, true);
315 console
.log("New tree: " + newTree
.url
);
316 var newCommit
= Nitdoc
.GitHub
.API
.createCommit(user
, infos
.message
, baseTree
.sha
, newTree
);
318 Nitdoc
.GitHub
.ModalBox
.open("Unable to create new commit!", newCommit
.status
+ ": " + newCommit
.statusText
, true);
321 console
.log("New commit: " + newCommit
.url
);
322 var pullRequest
= Nitdoc
.GitHub
.API
.createPullRequest(user
, infos
.message
.split("\n\n")[0], "Pull request from Nitdoc", origin
, newCommit
.sha
);
323 if(!pullRequest
.number
) {
324 Nitdoc
.GitHub
.ModalBox
.open("Unable to create pull request!", pullRequest
.status
+ ": " + pullRequest
.statusText
, true);
327 console
.log("New pull request: " + pullRequest
.url
);
331 // close previously opened pull request
332 var closePullRequest
= function(number
) {
333 var requests
= JSON
.parse(localStorage
.requests
);
334 if(!requests
[number]) {
335 Nitdoc
.GitHub
.ModalBox
.open("Unable to close pull request!", "Pull request " + number
+ "not found", true);
338 // close pull request
339 var res
= Nitdoc
.GitHub
.API
.updatePullRequest(user
, "Canceled from Nitdoc", "", "closed", requests
[number].request
);
341 Nitdoc
.GitHub
.ModalBox
.open("Unable to close pull request!", res
.status
+ ": " + res
.statusText
, true);
344 // update in localstorage
345 requests
[number].isClosed
= true;
346 localStorage
.requests
= JSON
.stringify(requests
);
349 // Get file content from github
350 var getFileContent
= function(githubUrl
) {
351 var origFile
= Nitdoc
.GitHub
.API
.getFile(user
, githubUrl
);
352 if(!origFile
.content
) {
353 Nitdoc
.GitHub
.ModalBox
.open("Unable to locate source file!", origFile
.status
+ ": " + origFile
.statusText
, true);
356 var base64Content
= origFile
.content
.substring(0, origFile
.content
.length
- 1)
357 return Base64
.decode(base64Content
);
360 // save pull request in local storage
361 var saveRequest
= function(infos
) {
363 if(localStorage
.requests
) {requests
= JSON
.parse(localStorage
.requests
)}
364 requests
[infos
.request
.number
] = {
365 request
: infos
.request
,
366 location
: infos
.location
.origin
,
367 comment
: Base64
.encode(infos
.newComment
)
369 localStorage
.requests
= JSON
.stringify(requests
);
372 // save user in local storage
373 var saveSession
= function(user
) {
376 password
: Base64
.encode(user
.password
),
380 localStorage
.user
= JSON
.stringify(session
);
385 var getUser
= function() { return user
; }
386 var getOrigin
= function() { return origin
; }
387 var getOpenedComments
= function() { return openedComments
; }
388 var addOpenedComments
= function() { openedComments
+= 1; }
389 var remOpenedComments
= function() { openedComments
-= 1; }
396 disactivate
: disactivate
,
398 getOrigin
: getOrigin
,
399 getOpenedComments
: getOpenedComments
,
400 addOpenedComments
: addOpenedComments
,
401 remOpenedComments
: remOpenedComments
,
402 saveChanges
: saveChanges
,
403 closePullRequest
: closePullRequest
,
404 reloadComments
: reloadComments
411 * GitHub API user object
413 Nitdoc
.GitHub
.User
= function(login
, password
, repo
, branch
) {
415 this.password
= password
;
417 this.auth
= "Basic " + Base64
.encode(login
+ ':' + password
);
418 this.branch
= branch
;
424 Nitdoc
.GitHub
.API
= function() {
426 // try to login the user to github API
427 var login
= function(user
) {
430 beforeSend
: function (xhr
) {
431 xhr
.setRequestHeader ("Authorization", user
.auth
);
434 url
: "https://api.github.com/repos/" + user
.login
+ "/" + user
.repo
,
437 success
: function() {
441 user
.infos
= getUserInfos(user
);
442 user
.signedOff
= getSignedOff(user
)
446 // request for user github account infos
447 var getUserInfos
= function(user
) {
450 beforeSend
: function (xhr
) {
451 xhr
.setRequestHeader ("Authorization", user
.auth
);
454 url
: "https://api.github.com/users/" + user
.login
,
457 success
: function(response
) {
460 error
: function(response
) {
467 // build signedoff user default signature
468 var getSignedOff
= function(user
) {
469 return user
.infos
.name
+ " <" + user
.infos
.email
+ ">";
472 // get the branches list from a repo
473 var getBranches
= function(user
) {
476 beforeSend
: function (xhr
) {
477 xhr
.setRequestHeader ("Authorization", user
.auth
);
480 url
: "https://api.github.com/repos/" + user
.login
+ "/" + user
.repo
+ "/branches",
483 success
: function(response
) {
486 error
: function(response
) {
495 // get the latest commit on `branchName`
496 var getCommit
= function(user
, sha
) {
499 beforeSend
: function (xhr
) {
500 xhr
.setRequestHeader ("Authorization", user
.auth
);
503 url
: "https://api.github.com/repos/" + user
.login
+ "/" + user
.repo
+ "/git/commits/" + sha
,
506 success
: function(response
) {
509 error
: function(response
) {
516 // get the base tree for a commit sha
517 var getTree
= function(user
, sha
) {
520 beforeSend
: function (xhr
) {
521 xhr
.setRequestHeader ("Authorization", user
.auth
);
524 url
: "https://api.github.com/repos/" + user
.login
+ "/" + user
.repo
+ "/git/trees/" + sha
+ "?recursive=1",
527 success
: function(response
) {
530 error
: function(response
) {
538 var createBlob
= function(user
, content
) {
541 beforeSend
: function (xhr
) {
542 xhr
.setRequestHeader ("Authorization", user
.auth
);
545 url
: "https://api.github.com/repos/" + user
.login
+ "/" + user
.repo
+ "/git/blobs",
548 data
: JSON
.stringify({
549 content
: Base64
.encode(content
),
552 success
: function(response
) {
555 error
: function(response
) {
562 // create a new tree from a base tree
563 var createTree
= function(user
, baseTree
, path
, blob
) {
566 beforeSend
: function (xhr
) {
567 xhr
.setRequestHeader ("Authorization", user
.auth
);
570 url
: "https://api.github.com/repos/" + user
.login
+ "/" + user
.repo
+ "/git/trees",
571 data
: JSON
.stringify({
572 base_tree
: baseTree
.sha
,
575 mode
: 100644, // file (blob)
582 success
: function(response
) {
585 error
: function(response
) {
592 // create a new commit
593 var createCommit
= function(user
, message
, parentCommit
, tree
) {
596 beforeSend
: function (xhr
) {
597 xhr
.setRequestHeader ("Authorization", user
.auth
);
600 url
: "https://api.github.com/repos/" + user
.login
+ "/" + user
.repo
+ "/git/commits",
601 data
: JSON
.stringify({
603 parents
: parentCommit
,
608 success
: function(response
) {
611 error
: function(response
) {
618 // create a pull request
619 var createPullRequest
= function(user
, title
, body
, origin
, head
) {
622 beforeSend
: function (xhr
) {
623 xhr
.setRequestHeader ("Authorization", user
.auth
);
626 url
: "https://api.github.com/repos/" + origin
.user
+ "/" + origin
.repo
+ "/pulls",
627 data
: JSON
.stringify({
631 head
: user
.login
+ ":" + head
635 success
: function(response
) {
638 error
: function(response
) {
645 // update a pull request
646 var updatePullRequest
= function(user
, title
, body
, state
, request
) {
649 beforeSend
: function (xhr
) {
650 xhr
.setRequestHeader ("Authorization", user
.auth
);
654 data
: JSON
.stringify({
661 success
: function(response
) {
664 error
: function(response
) {
673 var getFile
= function(user
, path
, branch
) {
677 url
: "https://api.github.com/repos/" + user
.login
+ "/" + user
.repo
+ "/contents/" + path
,
683 success
: function(response
) {
686 error
: function(response
) {
695 getCommit
: getCommit
,
696 getBranches
: getBranches
,
698 createBlob
: createBlob
,
699 createTree
: createTree
,
700 createCommit
: createCommit
,
701 createPullRequest
: createPullRequest
,
702 updatePullRequest
: updatePullRequest
,
710 * Nitdoc GitHub loginbox module
713 Nitdoc
.GitHub
.LoginBox
= function() {
718 var init
= function(containerSelector
) {
719 loginBoxLi
= $
(document
.createElement("li"))
720 .attr("id", "nitdoc-github-li")
722 $
(document
.createElement("a"))
724 $
(document
.createElement("img"))
726 src
: "resources/icons/github-icon.png",
729 .addClass("nitdoc-github-li-img")
731 .click(function() { Nitdoc
.GitHub
.LoginBox
.toggle() })
734 loginBoxContent
= $
(document
.createElement("div"));
735 loginBox
= $
(document
.createElement("div"))
736 .attr("id", "nitdoc-github-loginbox")
737 .css("display", "none")
739 $
(document
.createElement("div"))
740 .addClass("nitdoc-github-loginbox-arrow")
744 $
(document
.createElement("h3"))
745 .append("Github Sign In")
747 .append(loginBoxContent
);
749 loginBoxLi
.append(loginBox
);
750 $
(containerSelector
).append(loginBoxLi
);
753 // Panel of login box to display when the user is logged in
754 var displayLogout
= function(origin
, user
) {
755 var panel
= $
(document
.createElement("div"))
757 $
(document
.createElement("h4"))
760 $
(document
.createElement("a"))
761 .attr("href", "https://github.com/" + user
.login
)
766 $
(document
.createElement("label"))
767 .attr("for", "github-origin")
771 $
(document
.createElement("input"))
775 disabled
: "disabled",
776 value
: origin
.user
+ ":" + origin
.repo
+ ":" + origin
.branch
780 $
(document
.createElement("label"))
781 .attr("for", "github-base")
785 $
(document
.createElement("input"))
789 disabled
: "disabled",
790 value
: user
.login
+ ":" + user
.repo
+ ":" + user
.branch
794 $
(document
.createElement("button"))
795 .addClass("nitdoc-github-button")
796 .addClass("nitdoc-github-cancel")
798 $
(document
.createElement("img"))
799 .attr("src", "resources/icons/github-icon.png")
801 .click(function() { // log out user
802 Nitdoc
.GitHub
.UI
.disactivate();
803 Nitdoc
.GitHub
.LoginBox
.toggle();
806 $
(".nitdoc-github-li-img").attr("src", "resources/icons/github-icon-green.png");
807 loginBoxContent
.empty()
808 loginBoxContent
.append(panel
);
811 // Panel of login box to display when the user is logged out
812 var displayLogin
= function() {
813 var panel
= $
(document
.createElement("form"))
815 $
(document
.createElement("label"))
816 .attr("for", "nitdoc-github-login-field")
820 $
(document
.createElement("input"))
822 id
: "nitdoc-github-login-field",
827 $
(document
.createElement("label"))
828 .attr("for", "nitdoc-github-password-field")
832 $
(document
.createElement("input"))
834 id
: "nitdoc-github-password-field",
839 $
(document
.createElement("label"))
840 .attr("for", "nitdoc-github-repo-field")
841 .append("Repository")
844 $
(document
.createElement("input"))
846 id
: "nitdoc-github-repo-field",
851 $
(document
.createElement("label"))
852 .attr("for", "nitdoc-github-branch-field")
856 $
(document
.createElement("input"))
858 id
: "nitdoc-github-branch-field",
863 $
(document
.createElement("button"))
864 .addClass("nitdoc-github-button")
866 $
(document
.createElement("img"))
867 .attr("src", "resources/icons/github-icon.png")
870 var login
= $
('#nitdoc-github-login-field').val();
871 var password
= $
('#nitdoc-github-password-field').val();
872 var repo
= $
('#nitdoc-github-repo-field').val();
873 var branch
= $
('#nitdoc-github-branch-field').val();
874 if(!login ||
!password ||
!repo ||
!branch
) {
875 Nitdoc
.GitHub
.ModalBox
.open("Sign in error", "Please enter your GitHub username, password, repository and branch.", true);
877 var user
= Nitdoc
.GitHub
.UI
.tryLogin(login
, password
, repo
, branch
);
878 if(user
== "error:login") {
879 Nitdoc
.GitHub
.ModalBox
.open("Sign in error", "The username, password, repo or branch you entered is incorrect.", true);
880 } else if(user
== "error:sha") {
881 Nitdoc
.GitHub
.ModalBox
.open("Base commit not found", "The provided GitHub repository must contains the base commit '" + Nitdoc
.GitHub
.UI
.getOrigin().sha
+ "'", true);
882 } else if(user
== "error:profile") {
883 Nitdoc
.GitHub
.ModalBox
.open("Incomplete GitHub profile", "Please set your public name and email in your <a href='https://github.com/settings/profile'>GitHub profile</a>.<br/><br/>Your public profile informations are used to sign-off your commits.", true);
885 Nitdoc
.GitHub
.UI
.activate(user
);
886 var origin
= Nitdoc
.GitHub
.UI
.getOrigin();
887 Nitdoc
.GitHub
.LoginBox
.displayLogout(origin
, user
);
893 $
(".nitdoc-github-li-img").attr("src", "resources/icons/github-icon.png");
894 loginBoxContent
.empty()
895 loginBoxContent
.append(panel
);
898 var toggle
= function() {
899 if(loginBox
.is(':hidden')) {
901 if (!$
('#loginGit').is(':hidden')) { $
('#loginGit').focus(); }
910 displayLogin
: displayLogin
,
911 displayLogout
: displayLogout
,
920 * Nitdoc.GitHub.CommentBox class
923 // Init new modal box instance
924 Nitdoc
.GitHub
.CommentBox
= function(infos
) {
929 Nitdoc
.GitHub
.CommentBox
.prototype.open
= function(baseArea
) {
930 Nitdoc
.GitHub
.UI
.addOpenedComments();
933 if(this.infos
.requestID
) {
934 // get comment from last pull request
935 var requests
= JSON
.parse(localStorage
.requests
);
936 this.infos
.newComment
= Base64
.decode(requests
[this.infos
.requestID
].comment
);
938 this.infos
.newComment
= false;
941 // create comment box
942 var tarea
= $
(document
.createElement("textarea"))
943 .append(this.infos
.newComment
=== false?
this.infos
.oldComment
: this.infos
.newComment
)
944 .keyup(function(event
) {
945 $
(event
.target
).css("height", (event
.target
.value
.split(/\r|
\n/).length
* 16) + "px");
946 if ( (!instance
.infos
.requestID
&& $
(event
.target
).val() != instance
.infos
.oldComment
) ||
(instance
.infos
.requestID
&& $
(event
.target
).val() != instance
.infos
.oldComment
&& $
(event
.target
).val() != instance
.infos
.newComment
) ) {
947 $
(event
.target
).parent().find("button.nitdoc-github-commit").removeAttr("disabled");
949 $
(event
.target
).parent().find("button.nitdoc-github-commit").attr("disabled", "disabled");
952 .keydown(function(event
) {
953 if(event
.keyCode
== 13){
954 $
(event
.target
).css("height", ($
(event
.target
).outerHeight() + 6) + "px");
958 this.commentBoxDiv
= $
(document
.createElement("div"))
959 .addClass("nitdoc-github-commentbox")
962 $
(document
.createElement("a"))
963 .addClass("nitdoc-github-preview")
965 var converter
= new Markdown
.Converter()
966 var html
= converter
.makeHtml(tarea
.val());
967 Nitdoc
.GitHub
.ModalBox
.open("Preview", html
, false);
971 $
(document
.createElement("button"))
972 .addClass("nitdoc-github-button")
973 .addClass("nitdoc-github-commit")
976 instance
.infos
.newComment
= tarea
.val();
977 instance
.infos
.commentBox
= instance
;
978 Nitdoc
.GitHub
.CommitBox
.open(instance
.infos
);
982 $
(document
.createElement("button"))
983 .addClass("nitdoc-github-button")
984 .addClass("nitdoc-github-cancel")
986 .click(function() {instance
.close()})
989 baseArea
.after(this.commentBoxDiv
);
990 var cbWidth
= this.commentBoxDiv
.innerWidth();
991 var taWidth
= tarea
.outerWidth();
992 tarea
.width(cbWidth
- (taWidth
- cbWidth
));
993 tarea
.trigger("keyup");
997 Nitdoc
.GitHub
.CommentBox
.prototype.close
= function() {
998 Nitdoc
.GitHub
.UI
.remOpenedComments();
999 if(this.infos
.isNew
) {
1000 this.commentBoxDiv
.next().find("span.nitdoc-github-editComment").show();
1001 } else if(this.infos
.requestID
) {
1002 this.commentBoxDiv
.next().show();
1003 this.commentBoxDiv
.next().next().show();
1005 this.commentBoxDiv
.next().show();
1006 this.commentBoxDiv
.next().next().find("span.nitdoc-github-editComment").show();
1008 this.commentBoxDiv
.remove();
1012 * Nitdoc.GitHub.ModalBox class
1015 // Init new modal box instance
1016 Nitdoc
.GitHub
.ModalBox
= function() {
1018 // Open modal box instance
1019 var open
= function(title
, content
, isError
) {
1021 $
(document
.createElement("div"))
1022 .attr("id", "nitdoc-github-modal-fade")
1023 .addClass("nitdoc-github-fade")
1026 $
(document
.createElement("div"))
1027 .attr("id", "nitdoc-github-modal")
1028 .addClass("nitdoc-github-modal")
1030 $
(document
.createElement("a"))
1031 .addClass("nitdoc-github-close")
1032 .attr("title", "Close")
1034 .click(function() { Nitdoc
.GitHub
.ModalBox
.close() })
1036 .append("<h3>" + title
+ "</h3>")
1037 .append("<div>" + content
+ "</div>")
1039 $
(document
.createElement("div"))
1040 .addClass("nitdoc-github-buttons")
1042 $
(document
.createElement("button"))
1043 .addClass("nitdoc-github-button")
1045 .click(function() { Nitdoc
.GitHub
.ModalBox
.close() })
1051 $
("#nitdoc-github-modal").addClass("nitdoc-github-error");
1054 $
("#nitdoc-github-modal")
1057 marginTop
: -($
("#nitdoc-github-modal").outerHeight() / 2) + "px",
1059 marginLeft
: -($
("#nitdoc-github-modal").outerWidth() / 2) + "px"
1061 .find("button.nitdoc-github-button").focus();
1064 // Close modal box instance
1065 var close
= function() {
1066 $
("#nitdoc-github-modal").remove();
1067 $
("#nitdoc-github-modal-fade").remove();
1080 * Nitdoc.GitHub.CommitBox instance
1083 // Init new commit box instance
1084 Nitdoc
.GitHub
.CommitBox
= function() {
1086 // Open commit box instance
1087 var open
= function(infos
) {
1089 $
(document
.createElement("div"))
1090 .attr("id", "nitdoc-github-commitBox-fade")
1091 .addClass("nitdoc-github-fade")
1094 $
(document
.createElement("div"))
1095 .attr("id", "nitdoc-github-commitBox")
1096 .addClass("nitdoc-github-modal")
1098 $
(document
.createElement("a"))
1099 .addClass("nitdoc-github-close")
1100 .attr("title", "Close")
1102 .click(function() { Nitdoc
.GitHub
.CommitBox
.close() })
1104 .append("<h3>Commit changes</h3>")
1106 $
(document
.createElement("div"))
1108 $
(document
.createElement("label"))
1109 .attr("for", "nitdoc-github-commit-message")
1113 $
(document
.createElement("textarea"))
1114 .attr("id", "nitdoc-github-commit-message")
1115 .append("doc: " + (infos
.isNew ?
"added" : "modified") + " comment for " + infos
.namespace)
1119 $
(document
.createElement("input"))
1121 id
: "nitdoc-github-commit-signedoff",
1123 value
: "Signed-off-by: " + infos
.user
.signedOff
1125 .change(function(e
) {
1126 if ($
(this).is(':checked')) {
1127 $
("#nitdoc-github-commit-button").removeAttr("disabled");
1129 $
("#nitdoc-github-commit-button").attr("disabled", "disabled");
1134 $
(document
.createElement("label"))
1135 .attr("for", "nitdoc-github-commit-signedoff")
1136 .text("Signed-off-by: " + infos
.user
.signedOff
)
1139 $
(document
.createElement("div"))
1140 .addClass("nitdoc-github-buttons")
1142 $
(document
.createElement("button"))
1144 id
: "nitdoc-github-commit-button",
1145 disabled
: "disabled"
1147 .addClass("nitdoc-github-button")
1149 $
(document
.createElement("img"))
1150 .attr("src", "resources/icons/github-icon.png")
1153 .mousedown(function() {
1154 $
(this).text("Commiting...");
1156 .mouseup(function() {
1157 infos
.message
= $
("#nitdoc-github-commit-message").val() + "\n\n" + infos
.user
.signedOff
;
1158 Nitdoc
.GitHub
.UI
.saveChanges(infos
);
1164 $
("#nitdoc-github-commitBox")
1167 marginTop
: -($
("#nitdoc-github-commitBox").outerHeight() / 2) + "px",
1169 marginLeft
: -($
("#nitdoc-github-commitBox").outerWidth() / 2) + "px"
1171 .find("#nitdoc-github-commit-message").focus();
1174 // Close commit box instance
1175 var close
= function() {
1176 $
("#nitdoc-github-commitBox").remove();
1177 $
("#nitdoc-github-commitBox-fade").remove();
1189 * Nitdoc.GitHub.Utils module
1192 Nitdoc
.GitHub
.Utils
= function() {
1193 // Extract infos from string location "lib/standard/collection/array.nit:457,1--458,0"
1194 var parseLocation
= function(location
) {
1195 var parts
= location
.split(":");
1196 var loc
= new Object();
1197 loc
.origin
= location
;
1198 loc
.path
= parts
[0];
1199 loc
.lstart
= parseInt(parts
[1].split("--")[0].split(",")[0]);
1200 loc
.tabpos
= parseInt(parts
[1].split("--")[0].split(",")[1]);
1201 loc
.lend
= parseInt(parts
[1].split("--")[1].split(",")[0]);
1205 // Meld modified comment into file conten
1206 var mergeComment
= function(fileContent
, comment
, location
) {
1207 // replace comment in file content
1208 var res
= new String();
1209 var lines
= fileContent
.split("\n");
1210 // copy lines fron 0 to lstart
1211 for(var i
= 0; i
< location
.lstart
- 1; i
++) {
1212 res
+= lines
[i] + "\n";
1215 if(comment
&& comment
!= "") {
1216 var commentLines
= comment
.split("\n");
1217 for(var i
= 0; i
< commentLines
.length
; i
++) {
1218 var line
= commentLines
[i];
1219 var tab
= location
.tabpos
> 1 ?
"\t" : "";
1220 res
+= tab
+ (line
.length
> 0 ?
"# " : "#") + line
+ "\n";
1223 // copy lines fron lend to end
1224 for(var i
= location
.lend
- 1; i
< lines
.length
; i
++) {
1226 if(i
< lines
.length
- 1) { res
+= "\n"; }
1233 parseLocation
: parseLocation
,
1234 mergeComment
: mergeComment