define([
"plugins/ui",
"plugins/quicksearch",
+ "plugins/github",
], function() {});
--- /dev/null
+/* This file is part of NIT ( http://www.nitlanguage.org ).\r
+\r
+ Licensed under the Apache License, Version 2.0 (the "License");\r
+ you may not use this file except in compliance with the License.\r
+ You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+\r
+ Documentation generator for the nit language.\r
+ Generate API documentation in HTML format from nit source code.\r
+*/\r
+\r
+/*\r
+ * Nitdoc.Github comment edition module\r
+ *\r
+ * Allows user to modify source code comments directly from the Nitdoc\r
+ */\r
+define([\r
+ "jquery",\r
+ "base64",\r
+ "plugins/github/ui",\r
+ "plugins/github/loginbox",\r
+], function($, Base64, UI, LoginBox) {\r
+ // Load GitHub UI\r
+ var upstream = $("body").attr("data-github-upstream");\r
+ var basesha1 = $("body").attr("data-github-base-sha1");\r
+ if(upstream && basesha1) {\r
+ console.log("init GitHub module (upstream: "+ upstream +", base: " + basesha1 + ")");\r
+\r
+ // parse origin\r
+ var parts = upstream.split(":");\r
+ UI.origin = {\r
+ user: parts[0],\r
+ repo: parts[1],\r
+ branch: parts[2],\r
+ sha: basesha1\r
+ };\r
+\r
+ // check local session\r
+ if(localStorage.user) {\r
+\r
+ var session = JSON.parse(localStorage.user);\r
+ UI.user = UI.tryLogin(session.login, Base64.decode(session.password), session.repo, session.branch);\r
+ if(!UI.user.login) {\r
+ console.log("Session found but authentification failed");\r
+ localStorage.clear();\r
+ }\r
+\r
+ // activate ui\r
+ LoginBox.init("nav.main ul");\r
+ if(UI.user && UI.user.login) {\r
+ LoginBox.displayLogout(UI.origin, UI.user);\r
+ UI.activate(UI.user);\r
+ } else {\r
+ LoginBox.displayLogin();\r
+ }\r
+ } else {\r
+ console.log("No session found");\r
+ }\r
+ }\r
+});\r
--- /dev/null
+/* This file is part of NIT ( http://www.nitlanguage.org ).\r
+\r
+ Licensed under the Apache License, Version 2.0 (the "License");\r
+ you may not use this file except in compliance with the License.\r
+ You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+\r
+ Documentation generator for the nit language.\r
+ Generate API documentation in HTML format from nit source code.\r
+*/\r
+\r
+/*\r
+ * Nitdoc.GitHub.CommentBox class\r
+ */\r
+define([\r
+ "jquery",\r
+ "base64",\r
+ "Markdown.Converter",\r
+ "plugins/github/ui",\r
+ "plugins/github/commitbox",\r
+], function($, Base64, mkdown, UI, CommitBox) {\r
+\r
+ // Init new modal box instance\r
+ var CommentBox = function(infos) {\r
+ this.infos = infos;\r
+ this.commentBoxDiv;\r
+ };\r
+\r
+ CommentBox.prototype.open = function(baseArea) {\r
+ //TODO redo\r
+ //UI.addOpenedComments();\r
+ var instance = this;\r
+\r
+ if(this.infos.requestID) {\r
+ // get comment from last pull request\r
+ var requests = JSON.parse(localStorage.requests);\r
+ this.infos.newComment = Base64.decode(requests[this.infos.requestID].comment);\r
+ } else {\r
+ this.infos.newComment = false;\r
+ }\r
+\r
+ // create comment box\r
+ var tarea = $(document.createElement("textarea"))\r
+ .append(this.infos.newComment === false? this.infos.oldComment: this.infos.newComment)\r
+ .keyup(function(event) {\r
+ $(event.target).css("height", (event.target.value.split(/\r|\n/).length * 16) + "px");\r
+ 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) ) {\r
+ $(event.target).parent().find("button.nitdoc-github-commit").removeAttr("disabled");\r
+ } else {\r
+ $(event.target).parent().find("button.nitdoc-github-commit").attr("disabled", "disabled");\r
+ }\r
+ })\r
+ .keydown(function(event) {\r
+ if(event.keyCode == 13){\r
+ $(event.target).css("height", ($(event.target).outerHeight() + 6) + "px");\r
+ }\r
+ });\r
+\r
+ this.commentBoxDiv = $(document.createElement("div"))\r
+ .addClass("nitdoc-github-commentbox")\r
+ .append(tarea)\r
+ .append(\r
+ $(document.createElement("a"))\r
+ .addClass("nitdoc-github-preview")\r
+ .click(function() {\r
+ var converter = new Markdown.Converter()\r
+ var html = converter.makeHtml(tarea.val());\r
+ ModalBox.open("Preview", html, false);\r
+ })\r
+ )\r
+ .append(\r
+ $(document.createElement("button"))\r
+ .addClass("nitdoc-github-button")\r
+ .addClass("nitdoc-github-commit")\r
+ .append("Commit")\r
+ .click(function() {\r
+ instance.infos.newComment = tarea.val();\r
+ instance.infos.commentBox = instance;\r
+ CommitBox.open(instance.infos);\r
+ })\r
+ )\r
+ .append(\r
+ $(document.createElement("button"))\r
+ .addClass("nitdoc-github-button")\r
+ .addClass("nitdoc-github-cancel")\r
+ .append("Cancel")\r
+ .click(function() {instance.close()})\r
+ );\r
+\r
+ baseArea.after(this.commentBoxDiv);\r
+ var cbWidth = this.commentBoxDiv.innerWidth();\r
+ var taWidth = tarea.outerWidth();\r
+ tarea.width(cbWidth - (taWidth - cbWidth));\r
+ tarea.trigger("keyup");\r
+ tarea.focus();\r
+ };\r
+\r
+ CommentBox.prototype.close = function() {\r
+ //TODO redo\r
+ //UI.remOpenedComments();\r
+ if(this.infos.isNew) {\r
+ this.commentBoxDiv.next().find("span.nitdoc-github-editComment").show();\r
+ } else if(this.infos.requestID) {\r
+ this.commentBoxDiv.next().show();\r
+ this.commentBoxDiv.next().next().show();\r
+ } else {\r
+ this.commentBoxDiv.next().show();\r
+ this.commentBoxDiv.next().next().find("span.nitdoc-github-editComment").show();\r
+ }\r
+ this.commentBoxDiv.remove();\r
+ };\r
+\r
+ return CommentBox;\r
+});\r
--- /dev/null
+/* This file is part of NIT ( http://www.nitlanguage.org ).\r
+\r
+ Licensed under the Apache License, Version 2.0 (the "License");\r
+ you may not use this file except in compliance with the License.\r
+ You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+\r
+ Documentation generator for the nit language.\r
+ Generate API documentation in HTML format from nit source code.\r
+*/\r
+\r
+/*\r
+ * Nitdoc.GitHub.CommitBox instance\r
+ */\r
+define([\r
+ "jquery",\r
+ "plugins/github/ui",\r
+], function($, UI) {\r
+console.log(UI);\r
+ // Init new commit box instance\r
+ var CommitBox = {\r
+ \r
+ // Open commit box instance\r
+ open: function(infos) {\r
+ $("body").append(\r
+ $(document.createElement("div"))\r
+ .attr("id", "nitdoc-github-commitBox-fade")\r
+ .addClass("nitdoc-github-fade")\r
+ );\r
+ $("body").append(\r
+ $(document.createElement("div"))\r
+ .attr("id", "nitdoc-github-commitBox")\r
+ .addClass("nitdoc-github-modal")\r
+ .append(\r
+ $(document.createElement("a"))\r
+ .addClass("nitdoc-github-close")\r
+ .attr("title", "Close")\r
+ .append("x")\r
+ .click(function() { CommitBox.close() })\r
+ )\r
+ .append("<h3>Commit changes</h3>")\r
+ .append(\r
+ $(document.createElement("div"))\r
+ .append(\r
+ $(document.createElement("label"))\r
+ .attr("for", "nitdoc-github-commit-message")\r
+ )\r
+ .append("<br/>")\r
+ .append(\r
+ $(document.createElement("textarea"))\r
+ .attr("id", "nitdoc-github-commit-message")\r
+ .append("doc: " + (infos.isNew ? "added" : "modified") + " comment for " + infos.namespace)\r
+ )\r
+ .append("<br/>")\r
+ .append(\r
+ $(document.createElement("input"))\r
+ .attr({\r
+ id: "nitdoc-github-commit-signedoff",\r
+ type: "checkbox",\r
+ value: "Signed-off-by: " + infos.user.signedOff\r
+ })\r
+ .change(function(e) {\r
+ if ($(this).is(':checked')) {\r
+ $("#nitdoc-github-commit-button").removeAttr("disabled");\r
+ } else {\r
+ $("#nitdoc-github-commit-button").attr("disabled", "disabled");\r
+ }\r
+ })\r
+ )\r
+ .append(\r
+ $(document.createElement("label"))\r
+ .attr("for", "nitdoc-github-commit-signedoff")\r
+ .text("Signed-off-by: " + infos.user.signedOff)\r
+ )\r
+ ).append(\r
+ $(document.createElement("div"))\r
+ .addClass("nitdoc-github-buttons")\r
+ .append(\r
+ $(document.createElement("button"))\r
+ .attr({\r
+ id: "nitdoc-github-commit-button",\r
+ disabled: "disabled"\r
+ })\r
+ .addClass("nitdoc-github-button")\r
+ .append(\r
+ $(document.createElement("img"))\r
+ .attr("src", "resources/icons/github-icon.png")\r
+ )\r
+ .append("Commit")\r
+ .mousedown(function() {\r
+ $(this).text("Commiting...");\r
+ })\r
+ .mouseup(function() {\r
+ infos.message = $("#nitdoc-github-commit-message").val() + "\n\n" + infos.user.signedOff;\r
+ UI.saveChanges(infos);\r
+ })\r
+ )\r
+ )\r
+ );\r
+\r
+ $("#nitdoc-github-commitBox")\r
+ .css({\r
+ top: "50%",\r
+ marginTop: -($("#nitdoc-github-commitBox").outerHeight() / 2) + "px",\r
+ left: "50%",\r
+ marginLeft: -($("#nitdoc-github-commitBox").outerWidth() / 2) + "px"\r
+ })\r
+ .find("#nitdoc-github-commit-message").focus();\r
+ },\r
+\r
+ // Close commit box instance\r
+ close: function() {\r
+ $("#nitdoc-github-commitBox").remove();\r
+ $("#nitdoc-github-commitBox-fade").remove();\r
+ }\r
+ }\r
+\r
+ return CommitBox;\r
+});\r
--- /dev/null
+/* This file is part of NIT ( http://www.nitlanguage.org ).\r
+\r
+ Licensed under the Apache License, Version 2.0 (the "License");\r
+ you may not use this file except in compliance with the License.\r
+ You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+\r
+ Documentation generator for the nit language.\r
+ Generate API documentation in HTML format from nit source code.\r
+*/\r
+\r
+/* \r
+ * GitHub API wrapper for github plugin\r
+ */\r
+define([\r
+ "jquery",\r
+ "base64"\r
+], function($, Base64) {\r
+ return {\r
+\r
+ // try to login the user to github API\r
+ login: function(user) {\r
+ var res = false;\r
+ $.ajax({\r
+ beforeSend: function (xhr) {\r
+ xhr.setRequestHeader ("Authorization", user.auth);\r
+ },\r
+ type: "GET",\r
+ url: "https://api.github.com/repos/" + user.login + "/" + user.repo,\r
+ async: false,\r
+ dataType: 'json',\r
+ success: function() {\r
+ res = true;\r
+ }\r
+ });\r
+ user.infos = this.getUserInfos(user);\r
+ user.signedOff = this.getSignedOff(user)\r
+ return res;\r
+ },\r
+\r
+ // request for user github account infos\r
+ getUserInfos: function(user) {\r
+ var res = false;\r
+ $.ajax({\r
+ beforeSend: function (xhr) {\r
+ xhr.setRequestHeader ("Authorization", user.auth);\r
+ },\r
+ type: "GET",\r
+ url: "https://api.github.com/users/" + user.login,\r
+ async: false,\r
+ dataType: 'json',\r
+ success: function(response) {\r
+ res = response;\r
+ },\r
+ error: function(response) {\r
+ res = response;\r
+ }\r
+ });\r
+ return res;\r
+ },\r
+\r
+ // build signedoff user default signature\r
+ getSignedOff: function(user) {\r
+ return user.infos.name + " <" + user.infos.email + ">";\r
+ },\r
+\r
+ // get the branches list from a repo\r
+ getBranches: function(user) {\r
+ var res = false;\r
+ $.ajax({\r
+ beforeSend: function (xhr) {\r
+ xhr.setRequestHeader ("Authorization", user.auth);\r
+ },\r
+ type: "GET",\r
+ url: "https://api.github.com/repos/" + user.login + "/" + user.repo + "/branches",\r
+ async: false,\r
+ dataType: 'json',\r
+ success: function(response) {\r
+ res = response;\r
+ },\r
+ error: function(response) {\r
+ res = response;\r
+ }\r
+ });\r
+ return res;\r
+ },\r
+\r
+ /* GitHub commits */\r
+\r
+ // get the latest commit on `branchName`\r
+ getCommit: function(user, sha) {\r
+ var res = false;\r
+ $.ajax({\r
+ beforeSend: function (xhr) {\r
+ xhr.setRequestHeader ("Authorization", user.auth);\r
+ },\r
+ type: "GET",\r
+ url: "https://api.github.com/repos/" + user.login + "/" + user.repo + "/git/commits/" + sha,\r
+ async: false,\r
+ dataType: 'json',\r
+ success: function(response) {\r
+ res = response;\r
+ },\r
+ error: function(response) {\r
+ res = response;\r
+ }\r
+ });\r
+ return res;\r
+ },\r
+\r
+ // get the base tree for a commit sha\r
+ getTree: function(user, sha) {\r
+ var res = false;\r
+ $.ajax({\r
+ beforeSend: function (xhr) {\r
+ xhr.setRequestHeader ("Authorization", user.auth);\r
+ },\r
+ type: "GET",\r
+ url: "https://api.github.com/repos/" + user.login + "/" + user.repo + "/git/trees/" + sha + "?recursive=1",\r
+ async: false,\r
+ dataType: 'json',\r
+ success: function(response) {\r
+ res = response;\r
+ },\r
+ error: function(response) {\r
+ res = response;\r
+ }\r
+ });\r
+ return res;\r
+ },\r
+\r
+ // create a new blob\r
+ createBlob: function(user, content) {\r
+ var res = false;\r
+ $.ajax({\r
+ beforeSend: function (xhr) {\r
+ xhr.setRequestHeader ("Authorization", user.auth);\r
+ },\r
+ type: "POST",\r
+ url: "https://api.github.com/repos/" + user.login + "/" + user.repo + "/git/blobs",\r
+ async: false,\r
+ dataType: 'json',\r
+ data: JSON.stringify({\r
+ content: Base64.encode(content),\r
+ encoding: "base64"\r
+ }),\r
+ success: function(response) {\r
+ res = response;\r
+ },\r
+ error: function(response) {\r
+ res = response;\r
+ }\r
+ });\r
+ return res;\r
+ },\r
+\r
+ // create a new tree from a base tree\r
+ createTree: function(user, baseTree, path, blob) {\r
+ var res = false;\r
+ $.ajax({\r
+ beforeSend: function (xhr) {\r
+ xhr.setRequestHeader ("Authorization", user.auth);\r
+ },\r
+ type: "POST",\r
+ url: "https://api.github.com/repos/" + user.login + "/" + user.repo + "/git/trees",\r
+ data: JSON.stringify({\r
+ base_tree: baseTree.sha,\r
+ tree: [{\r
+ path: path,\r
+ mode: "100644", // file (blob)\r
+ type: "blob",\r
+ sha: blob.sha\r
+ }]\r
+ }),\r
+ async: false,\r
+ dataType: 'json',\r
+ success: function(response) {\r
+ res = response;\r
+ },\r
+ error: function(response) {\r
+ res = response;\r
+ }\r
+ });\r
+ return res;\r
+ },\r
+\r
+ // create a new commit\r
+ createCommit: function(user, message, parentCommit, tree) {\r
+ var res = false;\r
+ $.ajax({\r
+ beforeSend: function (xhr) {\r
+ xhr.setRequestHeader ("Authorization", user.auth);\r
+ },\r
+ type: "POST",\r
+ url: "https://api.github.com/repos/" + user.login + "/" + user.repo + "/git/commits",\r
+ data: JSON.stringify({\r
+ message: message,\r
+ parents: parentCommit,\r
+ tree: tree.sha,\r
+ }),\r
+ async: false,\r
+ dataType: 'json',\r
+ success: function(response) {\r
+ res = response;\r
+ },\r
+ error: function(response) {\r
+ res = response;\r
+ }\r
+ });\r
+ return res;\r
+ },\r
+\r
+ // create a pull request\r
+ createPullRequest: function(user, title, body, origin, head) {\r
+ var res = false;\r
+ $.ajax({\r
+ beforeSend: function (xhr) {\r
+ xhr.setRequestHeader ("Authorization", user.auth);\r
+ },\r
+ type: "POST",\r
+ url: "https://api.github.com/repos/" + origin.user + "/" + origin.repo + "/pulls",\r
+ data: JSON.stringify({\r
+ title: title,\r
+ body: body,\r
+ base: origin.branch,\r
+ head: user.login + ":" + head\r
+ }),\r
+ async: false,\r
+ dataType: 'json',\r
+ success: function(response) {\r
+ res = response;\r
+ },\r
+ error: function(response) {\r
+ res = response;\r
+ }\r
+ });\r
+ return res;\r
+ },\r
+\r
+ // update a pull request\r
+ updatePullRequest: function(user, title, body, state, request) {\r
+ var res = false;\r
+ $.ajax({\r
+ beforeSend: function (xhr) {\r
+ xhr.setRequestHeader ("Authorization", user.auth);\r
+ },\r
+ type: "PATCH",\r
+ url: request.url,\r
+ data: JSON.stringify({\r
+ title: title,\r
+ body: body,\r
+ state: state\r
+ }),\r
+ async: false,\r
+ dataType: 'json',\r
+ success: function(response) {\r
+ res = response;\r
+ },\r
+ error: function(response) {\r
+ res = response;\r
+ }\r
+ });\r
+ return res;\r
+ },\r
+\r
+ /* Files */\r
+\r
+ getFile: function(user, path, branch) {\r
+ var res = false;\r
+ $.ajax({\r
+ type: "GET",\r
+ url: "https://api.github.com/repos/" + user.login + "/" + user.repo + "/contents/" + path,\r
+ data: {\r
+ ref: branch\r
+ },\r
+ async: false,\r
+ dataType: 'json',\r
+ success: function(response) {\r
+ res = response;\r
+ },\r
+ error: function(response) {\r
+ res = response;\r
+ }\r
+ });\r
+ return res;\r
+ }\r
+ }\r
+});\r
--- /dev/null
+/* This file is part of NIT ( http://www.nitlanguage.org ).\r
+\r
+ Licensed under the Apache License, Version 2.0 (the "License");\r
+ you may not use this file except in compliance with the License.\r
+ You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+\r
+ Documentation generator for the nit language.\r
+ Generate API documentation in HTML format from nit source code.\r
+*/\r
+\r
+define([\r
+ "jquery",\r
+ "plugins/github/ui",\r
+ "plugins/github/modalbox",\r
+], function($, UI, ModalBox) {\r
+ var LoginBox = {\r
+ init: function(containerSelector) {\r
+ this.loginBoxLi = $(document.createElement("li"))\r
+ .attr("id", "nitdoc-github-li")\r
+ .append(\r
+ $(document.createElement("a"))\r
+ .append(\r
+ $(document.createElement("img"))\r
+ .attr({\r
+ src: "resources/icons/github-icon.png",\r
+ alt: "GitHub"\r
+ })\r
+ .addClass("nitdoc-github-li-img")\r
+ )\r
+ .click(function() { LoginBox.toggle() })\r
+ )\r
+\r
+ this.loginBoxContent = $(document.createElement("div"));\r
+ this.loginBox = $(document.createElement("div"))\r
+ .attr("id", "nitdoc-github-loginbox")\r
+ .css("display", "none")\r
+ .append(\r
+ $(document.createElement("div"))\r
+ .addClass("nitdoc-github-loginbox-arrow")\r
+ .append(" ")\r
+ )\r
+ .append(\r
+ $(document.createElement("h3"))\r
+ .append("Github Sign In")\r
+ )\r
+ .append(this.loginBoxContent);\r
+\r
+ this.loginBoxLi.append(this.loginBox);\r
+ $(containerSelector).append(this.loginBoxLi);\r
+ },\r
+\r
+ // Panel of login box to display when the user is logged in\r
+ displayLogout: function(origin, user) {\r
+ var panel = $(document.createElement("div"))\r
+ .append(\r
+ $(document.createElement("h4"))\r
+ .append("Hello ")\r
+ .append(\r
+ $(document.createElement("a"))\r
+ .attr("href", "https://github.com/" + user.login)\r
+ .append(user.login)\r
+ ).append("!")\r
+ )\r
+ .append(\r
+ $(document.createElement("label"))\r
+ .attr("for", "github-origin")\r
+ .append("Origin")\r
+ )\r
+ .append(\r
+ $(document.createElement("input"))\r
+ .attr({\r
+ id: "github-origin",\r
+ type: "text",\r
+ disabled: "disabled",\r
+ value: origin.user + ":" + origin.repo + ":" + origin.branch\r
+ })\r
+ )\r
+ .append(\r
+ $(document.createElement("label"))\r
+ .attr("for", "github-base")\r
+ .append("Base")\r
+ )\r
+ .append(\r
+ $(document.createElement("input"))\r
+ .attr({\r
+ id: "github-base",\r
+ type: "text",\r
+ disabled: "disabled",\r
+ value: user.login + ":" + user.repo + ":" + user.branch\r
+ })\r
+ )\r
+ .append(\r
+ $(document.createElement("button"))\r
+ .addClass("nitdoc-github-button")\r
+ .addClass("nitdoc-github-cancel")\r
+ .append(\r
+ $(document.createElement("img"))\r
+ .attr("src", "resources/icons/github-icon.png")\r
+ ).append("Sign Off")\r
+ .click(function() { // log out user\r
+ UI.disactivate();\r
+ LoginBox.toggle();\r
+ })\r
+ );\r
+ $(".nitdoc-github-li-img").attr("src", "resources/icons/github-icon-green.png");\r
+ this.loginBoxContent.empty()\r
+ this.loginBoxContent.append(panel);\r
+ },\r
+\r
+ // Panel of login box to display when the user is logged out\r
+ displayLogin: function() {\r
+ var panel = $(document.createElement("form"))\r
+ .append(\r
+ $(document.createElement("label"))\r
+ .attr("for", "nitdoc-github-login-field")\r
+ .append("Username")\r
+ )\r
+ .append(\r
+ $(document.createElement("input"))\r
+ .attr({\r
+ id: "nitdoc-github-login-field",\r
+ type: "text"\r
+ })\r
+ )\r
+ .append(\r
+ $(document.createElement("label"))\r
+ .attr("for", "nitdoc-github-password-field")\r
+ .append("Password")\r
+ )\r
+ .append(\r
+ $(document.createElement("input"))\r
+ .attr({\r
+ id: "nitdoc-github-password-field",\r
+ type: "password"\r
+ })\r
+ )\r
+ .append(\r
+ $(document.createElement("label"))\r
+ .attr("for", "nitdoc-github-repo-field")\r
+ .append("Repository")\r
+ )\r
+ .append(\r
+ $(document.createElement("input"))\r
+ .attr({\r
+ id: "nitdoc-github-repo-field",\r
+ type: "text"\r
+ })\r
+ )\r
+ .append(\r
+ $(document.createElement("label"))\r
+ .attr("for", "nitdoc-github-branch-field")\r
+ .append("Branch")\r
+ )\r
+ .append(\r
+ $(document.createElement("input"))\r
+ .attr({\r
+ id: "nitdoc-github-branch-field",\r
+ type: "text"\r
+ })\r
+ )\r
+ .append(\r
+ $(document.createElement("button"))\r
+ .addClass("nitdoc-github-button")\r
+ .append(\r
+ $(document.createElement("img"))\r
+ .attr("src", "resources/icons/github-icon.png")\r
+ ).append("Sign In")\r
+ .click(function() {\r
+ var login = $('#nitdoc-github-login-field').val();\r
+ var password = $('#nitdoc-github-password-field').val();\r
+ var repo = $('#nitdoc-github-repo-field').val();\r
+ var branch = $('#nitdoc-github-branch-field').val();\r
+ if(!login || !password || !repo || !branch) {\r
+ ModalBox.open("Sign in error", "Please enter your GitHub username, password, repository and branch.", true);\r
+ } else {\r
+ var user = UI.tryLogin(login, password, repo, branch);\r
+ if(user == "error:login") {\r
+ ModalBox.open("Sign in error", "The username, password, repo or branch you entered is incorrect.", true);\r
+ } else if(user == "error:sha") {\r
+ ModalBox.open("Base commit not found", "The provided GitHub repository must contains the base commit '" + UI.origin.sha + "'", true);\r
+ } else if(user == "error:profile") {\r
+ 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);\r
+ } else {\r
+ UI.activate(user);\r
+ LoginBox.displayLogout(UI.origin, user);\r
+ }\r
+ }\r
+ return false;\r
+ })\r
+ )\r
+ $(".nitdoc-github-li-img").attr("src", "resources/icons/github-icon.png");\r
+ this.loginBoxContent.empty()\r
+ this.loginBoxContent.append(panel);\r
+ },\r
+\r
+ toggle: function() {\r
+ if(this.loginBox.is(':hidden')) {\r
+ this.loginBox.show();\r
+ if (!$('#loginGit').is(':hidden')) { $('#loginGit').focus(); }\r
+ } else {\r
+ this.loginBox.hide();\r
+ }\r
+ }\r
+ };\r
+\r
+ return LoginBox;\r
+});\r
--- /dev/null
+/* This file is part of NIT ( http://www.nitlanguage.org ).\r
+\r
+ Licensed under the Apache License, Version 2.0 (the "License");\r
+ you may not use this file except in compliance with the License.\r
+ You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+\r
+ Documentation generator for the nit language.\r
+ Generate API documentation in HTML format from nit source code.\r
+*/\r
+\r
+/*\r
+ * Nitdoc.GitHub.ModalBox class\r
+ */\r
+define([\r
+ "jquery",\r
+], function($) {\r
+ // Init new modal box instance\r
+ //TODO use DJQuery.UI Dialog: https://jqueryui.com/dialog/#modal-message\r
+ var ModalBox = {\r
+\r
+ // Open modal box instance\r
+ open: function(title, content, isError) {\r
+ $("body").append(\r
+ $(document.createElement("div"))\r
+ .attr("id", "nitdoc-github-modal-fade")\r
+ .addClass("nitdoc-github-fade")\r
+ )\r
+ .append(\r
+ $(document.createElement("div"))\r
+ .attr("id", "nitdoc-github-modal")\r
+ .addClass("nitdoc-github-modal")\r
+ .append(\r
+ $(document.createElement("a"))\r
+ .addClass("nitdoc-github-close")\r
+ .attr("title", "Close")\r
+ .append("x")\r
+ .click(function() { ModalBox.close() })\r
+ )\r
+ .append("<h3>" + title + "</h3>")\r
+ .append("<div>" + content + "</div>")\r
+ .append(\r
+ $(document.createElement("div"))\r
+ .addClass("nitdoc-github-buttons")\r
+ .append(\r
+ $(document.createElement("button"))\r
+ .addClass("nitdoc-github-button")\r
+ .append("Ok")\r
+ .click(function() { ModalBox.close() })\r
+ )\r
+ )\r
+ );\r
+\r
+ if(isError) {\r
+ $("#nitdoc-github-modal").addClass("nitdoc-github-error");\r
+ }\r
+\r
+ $("#nitdoc-github-modal")\r
+ .css({\r
+ top: "50%",\r
+ marginTop: -($("#nitdoc-github-modal").outerHeight() / 2) + "px",\r
+ left: "50%",\r
+ marginLeft: -($("#nitdoc-github-modal").outerWidth() / 2) + "px"\r
+ })\r
+ .find("button.nitdoc-github-button").focus();\r
+ },\r
+\r
+ // Close modal box instance\r
+ close: function() {\r
+ $("#nitdoc-github-modal").remove();\r
+ $("#nitdoc-github-modal-fade").remove();\r
+ }\r
+ };\r
+ return ModalBox;\r
+});\r
--- /dev/null
+/* This file is part of NIT ( http://www.nitlanguage.org ).\r
+\r
+ Licensed under the Apache License, Version 2.0 (the "License");\r
+ you may not use this file except in compliance with the License.\r
+ You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+\r
+ Documentation generator for the nit language.\r
+ Generate API documentation in HTML format from nit source code.\r
+*/\r
+\r
+/*\r
+ * Nitdoc.Github.UI for comment edition module\r
+ */\r
+define([\r
+ "jquery",\r
+ "plugins/github/user",\r
+ "plugins/github/github_api",\r
+ "plugins/github/utils",\r
+ "plugins/github/commentbox",\r
+ "base64",\r
+], function($, User, GithubAPI, Utils, CommentBox, Base64) {\r
+ var UI = {\r
+ openedComments: 0, // currently edited comments count\r
+ user: false, // logged user\r
+\r
+ // Activate comment UI for a logged user\r
+ activate: function(loggedUser) {\r
+ // Save session\r
+ this.user = loggedUser;\r
+ this.saveSession(this.user);\r
+ \r
+ // check local storage synchro with branch\r
+ if(localStorage.base != this.origin.sha) {\r
+ console.log("Base changed: cleaned cache");\r
+ localStorage.requests = "[]";\r
+ localStorage.base = this.origin.sha;\r
+ }\r
+\r
+ // Prevent page unload if there is comments in editing mode\r
+ $(window).on('beforeunload', function() {\r
+ if(UI.getOpenedComments() > 0){\r
+ return "There is uncommited modified comments. Are you sure you want to leave this page?";\r
+ }\r
+ });\r
+\r
+ this.attachCommentEvents();\r
+ this.reloadComments();\r
+ },\r
+\r
+ // clear storage\r
+ disactivate: function() {\r
+ if(UI.getOpenedComments() > 0){\r
+ if(!confirm('There is uncommited modified comments. Are you sure you want to leave this page?')) {\r
+ return false;\r
+ }\r
+ }\r
+ // close session and purge cookie\r
+ localStorage.clear();\r
+ $(window).unbind('beforeunload');\r
+ window.location.reload();\r
+ },\r
+\r
+ // Attempt login through GitHub API\r
+ tryLogin: function(login, password, repo, branch) {\r
+ var user = new User(login, password, repo, branch);\r
+ if(!GithubAPI.login(user)) {\r
+ return "error:login";\r
+ }\r
+ // check github profile fields\r
+ if(!user.infos.name || !user.infos.email) {\r
+ return "error:profile";\r
+ }\r
+ // check correct base commit\r
+ var commit = GithubAPI.getCommit(user, this.origin.sha);\r
+ if(!commit || !commit.sha) {\r
+ return "error:sha";\r
+ }\r
+ return user;\r
+ },\r
+\r
+ // Attach edit button on each comment\r
+ attachCommentEvents: function() {\r
+ // Blocks without comment\r
+ $("span.noComment").each(function() {\r
+ //FIXME this should be done by nitdoc\r
+ var baseComment = $(this).parent().prev();\r
+ var location = Utils.parseLocation(baseComment.attr("data-comment-location"));\r
+ var locString = location.path + ":" + location.lstart + "," + location.tabpos + "--" + location.lstart + ",0";\r
+ baseComment.attr("data-comment-location", locString);\r
+ $(this).html("<a class='nitdoc-github-editComment noComment'>add comment</a> for ");\r
+ $(this).addClass("nitdoc-github-editComment");\r
+ });\r
+ // Blocks with comment\r
+ $('.description div.comment').each(function() {\r
+ var p = $(this).next();\r
+ p.prepend("<span class='nitdoc-github-editComment'><a class='nitdoc-github-editComment'>edit comment</a> for </span>")\r
+ });\r
+\r
+ // Attach links events\r
+ $('a.nitdoc-github-editComment').each(function() {\r
+ $(this).css("cursor", "pointer")\r
+ $(this).click(function() {\r
+ // hide link\r
+ $(this).parent().hide();\r
+ // add infos\r
+ var infos = {};\r
+ var baseTextarea;\r
+ if(!$(this).hasClass("noComment")) {\r
+ $(this).parent().parent().prev().hide();\r
+ baseTextarea = $(this).parent().parent().prev().prev();\r
+ } else {\r
+ baseTextarea = $(this).parent().parent().prev();\r
+ infos.isNew = true;\r
+ }\r
+ infos.user = UI.user;\r
+ infos.location = Utils.parseLocation(baseTextarea.attr("data-comment-location"));\r
+ infos.namespace = baseTextarea.attr("data-comment-namespace");\r
+ infos.oldComment = baseTextarea.val();\r
+ var box = new CommentBox(infos);\r
+ box.open(baseTextarea);\r
+ });\r
+ });\r
+ },\r
+\r
+ // reload comments from saved pull request\r
+ reloadComments: function() {\r
+ if(!localStorage.requests){ return; }\r
+ var requests = JSON.parse(localStorage.requests);\r
+ var converter = new Markdown.Converter();\r
+ // Look for modified comments in page\r
+ for(i in requests) {\r
+ if(!requests[i]) { continue; }\r
+ var request = requests[i];\r
+ $("textarea[data-comment-location=\"" + request.location + "\"]").each(function () {\r
+ var div = $(this).next();\r
+ if(request.isClosed) {\r
+ if(div.is("div.comment.newComment")) {\r
+ // hide empty comment\r
+ div.next().remove();\r
+ div.next().find("span.noComment").show();\r
+ div.remove();\r
+ } else if(div.is("div.comment.locked")) {\r
+ // unlock comment\r
+ div.empty();\r
+ div.append(converter.makeHtml($(this).text()));\r
+ div.removeClass("locked");\r
+ div.css("cursor", "pointer")\r
+ div.next().remove();\r
+ div.next().find("span.nitdoc-github-editComment").show();\r
+ }\r
+ } else {\r
+ // create div for the new coment\r
+ if(!div.is("div.comment")) {\r
+ $(this).after("<div class='comment newComment'></div>");\r
+ div = $(this).next();\r
+ }\r
+ // lock modified comment\r
+ if(!div.hasClass("locked")) {\r
+ // convert modified comment to markdown\r
+ div.empty()\r
+ div.append(converter.makeHtml(Base64.decode(request.comment)));\r
+ // lock click\r
+ div.css("cursor", "auto");\r
+ div.addClass("locked");\r
+ div.next().find("span.nitdoc-github-editComment").hide();\r
+ div.after(\r
+ $("<p class='locked inheritance'>")\r
+ .text("comment modified in ")\r
+ .append("<a href='"+ request.request.html_url +"' target='_blank' title='Review on GitHub'>pull request #"+ request.request.number +"</a>")\r
+ .append(" ")\r
+ .append(\r
+ $("<a data-pullrequest-number='"+ request.request.number +"' class='nitdoc-github-update'>update</a>")\r
+ .click(function (){\r
+ $(this).parent().hide();\r
+ div.hide();\r
+ var baseTextarea = div.prev();\r
+ // add infos\r
+ var infos = {};\r
+ infos.user = UI.getUser();\r
+ infos.location = Utils.parseLocation(baseTextarea.attr("data-comment-location"));\r
+ infos.namespace = baseTextarea.attr("data-comment-namespace");\r
+ infos.oldComment = baseTextarea.val();\r
+ infos.requestID = $(this).attr("data-pullrequest-number");\r
+ var box = new CommentBox(infos);\r
+ box.open(baseTextarea); \r
+ })\r
+ )\r
+ .append(" ")\r
+ .append(\r
+ $("<a data-pullrequest-number='"+ request.request.number +"' class='nitdoc-github-cancel'>cancel</a>")\r
+ .click(function (){\r
+ ui.closePullRequest($(this).attr("data-pullrequest-number"));\r
+ ui.reloadComments();\r
+ })\r
+ )\r
+ );\r
+ }\r
+ // hide "add comment" link\r
+ if(div.hasClass("newComment")) {\r
+ div.next().next().find("span.noComment").hide();\r
+ }\r
+ }\r
+\r
+ });\r
+ }\r
+ },\r
+\r
+ // Commit changes and send pull request\r
+ saveChanges: function(infos) {\r
+ // if pull request update close existing pull request for the comment\r
+ if(infos.requestID) {\r
+ closePullRequest(infos.requestID);\r
+ }\r
+\r
+ // forge commit\r
+ var fileContent = getFileContent(infos.location.path);\r
+ infos.newContent = Utils.mergeComment(fileContent, infos.newComment, infos.location);\r
+\r
+ // commit\r
+ infos.request = pushChanges(infos)\r
+ if(!infos.request) {\r
+ ModalBox.open("Unable to commit changes!", response, true);\r
+ return;\r
+ }\r
+ saveRequest(infos);\r
+\r
+ // close boxes and reload comments \r
+ CommitBox.close();\r
+ infos.commentBox.close();\r
+ reloadComments();\r
+ },\r
+\r
+ /*\r
+ Creating a new pull request with the new comment take 5 steps:\r
+ 1. get the base tree from latest commit\r
+\r
+ 2. create a new blob with updated file content\r
+ 3. post a new tree from base tree and blob\r
+ 4. post the new commit with new tree\r
+ 5. create the pull request\r
+ */\r
+ pushChanges: function(infos) {\r
+ var baseTree = GithubAPI.getTree(user, origin.sha);\r
+ if(!baseTree.sha) {\r
+ ModalBox.open("Unable to locate base tree!", baseTree.status + ": " + baseTree.statusText, true);\r
+ return false;\r
+ }\r
+ console.log("Base tree: " + baseTree.url);\r
+ var newBlob = GithubAPI.createBlob(user, infos.newContent);\r
+ if(!newBlob.sha) {\r
+ ModalBox.open("Unable to create new blob!", newBlob.status + ": " + newBlob.statusText, true);\r
+ return false;\r
+ }\r
+ console.log("New blob: " + newBlob.url);\r
+ var newTree = GithubAPI.createTree(user, baseTree, infos.location.path, newBlob);\r
+ if(!newTree.sha) {\r
+ ModalBox.open("Unable to create new tree!", newTree.status + ": " + newTree.statusText, true);\r
+ return false;\r
+ }\r
+ console.log("New tree: " + newTree.url);\r
+ var newCommit = GithubAPI.createCommit(user, infos.message, baseTree.sha, newTree);\r
+ if(!newCommit.sha) {\r
+ ModalBox.open("Unable to create new commit!", newCommit.status + ": " + newCommit.statusText, true);\r
+ return false;\r
+ }\r
+ console.log("New commit: " + newCommit.url);\r
+ var pullRequest = GithubAPI.createPullRequest(user, infos.message.split("\n\n")[0], "Pull request from Nitdoc", origin, newCommit.sha);\r
+ if(!pullRequest.number) {\r
+ ModalBox.open("Unable to create pull request!", pullRequest.status + ": " + pullRequest.statusText, true);\r
+ return false;\r
+ }\r
+ console.log("New pull request: " + pullRequest.url);\r
+ return pullRequest;\r
+ },\r
+\r
+ // close previously opened pull request\r
+ closePullRequest: function(number) {\r
+ var requests = JSON.parse(localStorage.requests);\r
+ if(!requests[number]) {\r
+ ModalBox.open("Unable to close pull request!", "Pull request " + number + "not found", true);\r
+ return false;\r
+ }\r
+ // close pull request\r
+ var res = GithubAPI.updatePullRequest(user, "Canceled from Nitdoc", "", "closed", requests[number].request);\r
+ if(!res.id) {\r
+ ModalBox.open("Unable to close pull request!", res.status + ": " + res.statusText, true);\r
+ return false;\r
+ }\r
+ // update in localstorage\r
+ requests[number].isClosed = true;\r
+ localStorage.requests = JSON.stringify(requests);\r
+ },\r
+\r
+ // Get file content from github\r
+ getFileContent: function(githubUrl) {\r
+ var origFile = GithubAPI.getFile(user, githubUrl);\r
+ if(!origFile.content) {\r
+ ModalBox.open("Unable to locate source file!", origFile.status + ": " + origFile.statusText, true);\r
+ return;\r
+ }\r
+ var base64Content = origFile.content.substring(0, origFile.content.length - 1)\r
+ return Base64.decode(base64Content);\r
+ },\r
+\r
+ // save pull request in local storage\r
+ saveRequest: function(infos) {\r
+ var requests = [];\r
+ if(localStorage.requests) {requests = JSON.parse(localStorage.requests)}\r
+ requests[infos.request.number] = {\r
+ request: infos.request,\r
+ location: infos.location.origin,\r
+ comment: Base64.encode(infos.newComment)\r
+ };\r
+ localStorage.requests = JSON.stringify(requests);\r
+ },\r
+\r
+ // save user in local storage\r
+ saveSession: function(user) {\r
+ var session = {\r
+ login: user.login,\r
+ password: Base64.encode(user.password),\r
+ repo: user.repo,\r
+ branch: user.branch,\r
+ };\r
+ localStorage.user = JSON.stringify(session);\r
+ }\r
+ }\r
+ return UI;\r
+});\r
--- /dev/null
+/* This file is part of NIT ( http://www.nitlanguage.org ).\r
+\r
+ Licensed under the Apache License, Version 2.0 (the "License");\r
+ you may not use this file except in compliance with the License.\r
+ You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+\r
+ Documentation generator for the nit language.\r
+ Generate API documentation in HTML format from nit source code.\r
+*/\r
+\r
+/*\r
+ * GitHub API user object\r
+ */\r
+define([\r
+ "base64",\r
+], function(Base64) {\r
+ return function(login, password, repo, branch) {\r
+ this.login = login;\r
+ this.password = password;\r
+ this.repo = repo;\r
+ this.auth = "Basic " + Base64.encode(login + ':' + password);\r
+ this.branch = branch;\r
+ }\r
+});\r
+\r
--- /dev/null
+/* This file is part of NIT ( http://www.nitlanguage.org ).\r
+\r
+ Licensed under the Apache License, Version 2.0 (the "License");\r
+ you may not use this file except in compliance with the License.\r
+ You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+\r
+ Documentation generator for the nit language.\r
+ Generate API documentation in HTML format from nit source code.\r
+*/\r
+\r
+/*\r
+ * Nitdoc.Github comment edition module\r
+ *\r
+ * Allows user to modify source code comments directly from the Nitdoc\r
+ */\r
+define([\r
+ "jquery",\r
+ "base64",\r
+ "Markdown.Converter",\r
+ "plugins/utils",\r
+ "plugins/github/ui",\r
+], function($, Base64, mkdown, utils) {\r
+\r
+/*\r
+ * Nitdoc.GitHub.Utils module\r
+ */\r
+\r
+ return {\r
+ // Extract infos from string location "lib/standard/collection/array.nit:457,1--458,0"\r
+ parseLocation: function(location) {\r
+ var parts = location.split(":");\r
+ var loc = new Object();\r
+ loc.origin = location;\r
+ loc.path = parts[0];\r
+ loc.lstart = parseInt(parts[1].split("--")[0].split(",")[0]);\r
+ loc.tabpos = parseInt(parts[1].split("--")[0].split(",")[1]);\r
+ loc.lend = parseInt(parts[1].split("--")[1].split(",")[0]);\r
+ return loc;\r
+ },\r
+\r
+ // Meld modified comment into file conten\r
+ mergeComment: function(fileContent, comment, location) {\r
+ // replace comment in file content\r
+ var res = new String();\r
+ var lines = fileContent.split("\n");\r
+ // copy lines fron 0 to lstart\r
+ for(var i = 0; i < location.lstart - 1; i++) {\r
+ res += lines[i] + "\n";\r
+ }\r
+ // set comment\r
+ if(comment && comment != "") {\r
+ var commentLines = comment.split("\n");\r
+ for(var i = 0; i < commentLines.length; i++) {\r
+ var line = commentLines[i];\r
+ var tab = location.tabpos > 1 ? "\t" : "";\r
+ res += tab + (line.length > 0 ? "# " : "#") + line + "\n";\r
+ }\r
+ }\r
+ // copy lines fron lend to end\r
+ for(var i = location.lend - 1; i < lines.length; i++) {\r
+ res += lines[i];\r
+ if(i < lines.length - 1) { res += "\n"; }\r
+ }\r
+ return res;\r
+ }\r
+ }\r
+});\r
+++ /dev/null
-/* This file is part of NIT ( http://www.nitlanguage.org ).\r
-\r
- Licensed under the Apache License, Version 2.0 (the "License");\r
- you may not use this file except in compliance with the License.\r
- You may obtain a copy of the License at\r
-\r
- http://www.apache.org/licenses/LICENSE-2.0\r
-\r
- Unless required by applicable law or agreed to in writing, software\r
- distributed under the License is distributed on an "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- See the License for the specific language governing permissions and\r
- limitations under the License.\r
-\r
- Documentation generator for the nit language.\r
- Generate API documentation in HTML format from nit source code.\r
-*/\r
-\r
-/*\r
- * Nitdoc.Github comment edition module\r
- *\r
- * Allows user to modify source code comments directly from the Nitdoc\r
- */\r
-\r
-var Nitdoc = Nitdoc || {};\r
-\r
-Nitdoc.GitHub = {}; // Declare Nitdoc.GitHub submodule\r
-\r
-// Load GitHub UI\r
-$(document).ready(function() {\r
- //FIXME base should be choosen by user\r
- var upstream = $("body").attr("data-github-upstream");\r
- var basesha1 = $("body").attr("data-github-base-sha1");\r
- if(upstream && basesha1) {\r
- Nitdoc.GitHub.UI.init(upstream, basesha1);\r
- }\r
-});\r
-\r
-/*\r
- * Nitdoc.Github.UI for comment edition module\r
- */\r
-Nitdoc.GitHub.UI = function() {\r
- var openedComments = 0; // currently edited comments count\r
- var user = false; // logged user\r
- var origin;\r
-\r
- var init = function(upstream, basesha1) {\r
- console.log("init GitHub module (upstream: "+ upstream +", base: " + basesha1 + ")");\r
-\r
- // parse origin\r
- var parts = upstream.split(":");\r
- origin = {\r
- user: parts[0],\r
- repo: parts[1],\r
- branch: parts[2],\r
- sha: basesha1\r
- };\r
-\r
- // check local session\r
- if(localStorage.user) {\r
- var session = JSON.parse(localStorage.user);\r
- var user = tryLogin(session.login, Base64.decode(session.password), session.repo, session.branch);\r
- if(!user.login) {\r
- console.log("Session found but authentification failed");\r
- localStorage.clear();\r
- }\r
- } else {\r
- console.log("No session found");\r
- }\r
-\r
- // activate ui\r
- Nitdoc.GitHub.LoginBox.init("nav.main ul");\r
- if(user && user.login) {\r
- Nitdoc.GitHub.LoginBox.displayLogout(origin, user);\r
- activate(user);\r
- } else {\r
- Nitdoc.GitHub.LoginBox.displayLogin();\r
- }\r
-\r
- // Prevent page unload if there is comments in editing mode\r
- $(window).on('beforeunload', function() {\r
- if(Nitdoc.GitHub.UI.getOpenedComments() > 0){\r
- return "There is uncommited modified comments. Are you sure you want to leave this page?";\r
- }\r
- });\r
- }\r
-\r
- // Activate comment UI for a logged user\r
- var activate = function(loggedUser) {\r
- // Save session\r
- user = loggedUser;\r
- saveSession(user);\r
- \r
- // check local storage synchro with branch\r
- if(localStorage.base != origin.sha) {\r
- console.log("Base changed: cleaned cache");\r
- localStorage.requests = "[]";\r
- localStorage.base = origin.sha;\r
- }\r
-\r
- attachCommentEvents();\r
- reloadComments();\r
- }\r
-\r
- // clear storage\r
- var disactivate = function() {\r
- if(Nitdoc.GitHub.UI.getOpenedComments() > 0){\r
- if(!confirm('There is uncommited modified comments. Are you sure you want to leave this page?')) {\r
- return false;\r
- }\r
- }\r
- // close session and purge cookie\r
- localStorage.clear();\r
- $(window).unbind('beforeunload');\r
- window.location.reload();\r
- }\r
-\r
- // Attempt login through GitHub API\r
- var tryLogin = function(login, password, repo, branch) {\r
- var user = new Nitdoc.GitHub.User(login, password, repo, branch);\r
- if(!Nitdoc.GitHub.API.login(user)) {\r
- return "error:login";\r
- }\r
- // check github profile fields\r
- if(!user.infos.name || !user.infos.email) {\r
- return "error:profile";\r
- }\r
- // check correct base commit\r
- var commit = Nitdoc.GitHub.API.getCommit(user, origin.sha);\r
- if(!commit || !commit.sha) {\r
- return "error:sha";\r
- }\r
- return user;\r
- }\r
-\r
- // Attach edit button on each comment\r
- var attachCommentEvents = function() {\r
- // Blocks without comment\r
- $("span.noComment").each(function() {\r
- //FIXME this should be done by nitdoc\r
- var baseComment = $(this).parent().prev();\r
- var location = Nitdoc.GitHub.Utils.parseLocation(baseComment.attr("data-comment-location"));\r
- var locString = location.path + ":" + location.lstart + "," + location.tabpos + "--" + location.lstart + ",0";\r
- baseComment.attr("data-comment-location", locString);\r
- $(this).html("<a class='nitdoc-github-editComment noComment'>add comment</a> for ");\r
- $(this).addClass("nitdoc-github-editComment");\r
- });\r
- // Blocks with comment\r
- $('.description div.comment').each(function() {\r
- var p = $(this).next();\r
- p.prepend("<span class='nitdoc-github-editComment'><a class='nitdoc-github-editComment'>edit comment</a> for </span>")\r
- });\r
-\r
- // Attach links events\r
- $('a.nitdoc-github-editComment').each(function() {\r
- $(this).css("cursor", "pointer")\r
- $(this).click(function() {\r
- // hide link\r
- $(this).parent().hide();\r
- // add infos\r
- var infos = {};\r
- var baseTextarea;\r
- if(!$(this).hasClass("noComment")) {\r
- $(this).parent().parent().prev().hide();\r
- baseTextarea = $(this).parent().parent().prev().prev();\r
- } else {\r
- baseTextarea = $(this).parent().parent().prev();\r
- infos.isNew = true;\r
- }\r
- infos.user = Nitdoc.GitHub.UI.getUser();\r
- infos.location = Nitdoc.GitHub.Utils.parseLocation(baseTextarea.attr("data-comment-location"));\r
- infos.namespace = baseTextarea.attr("data-comment-namespace");\r
- infos.oldComment = baseTextarea.val();\r
- var box = new Nitdoc.GitHub.CommentBox(infos);\r
- box.open(baseTextarea);\r
- });\r
- });\r
- }\r
-\r
- // reload comments from saved pull request\r
- var reloadComments = function() {\r
- if(!localStorage.requests){ return; }\r
- var requests = JSON.parse(localStorage.requests);\r
- var converter = new Markdown.Converter();\r
- // Look for modified comments in page\r
- for(i in requests) {\r
- if(!requests[i]) { continue; }\r
- var request = requests[i];\r
- $("textarea[data-comment-location=\"" + request.location + "\"]").each(function () {\r
- var div = $(this).next();\r
- if(request.isClosed) {\r
- if(div.is("div.comment.newComment")) {\r
- // hide empty comment\r
- div.next().remove();\r
- div.next().find("span.noComment").show();\r
- div.remove();\r
- } else if(div.is("div.comment.locked")) {\r
- // unlock comment\r
- div.empty();\r
- div.append(converter.makeHtml($(this).text()));\r
- div.removeClass("locked");\r
- div.css("cursor", "pointer")\r
- div.next().remove();\r
- div.next().find("span.nitdoc-github-editComment").show();\r
- }\r
- } else {\r
- // create div for the new coment\r
- if(!div.is("div.comment")) {\r
- $(this).after("<div class='comment newComment'></div>");\r
- div = $(this).next();\r
- }\r
- // lock modified comment\r
- if(!div.hasClass("locked")) {\r
- // convert modified comment to markdown\r
- div.empty()\r
- div.append(converter.makeHtml(Base64.decode(request.comment)));\r
- // lock click\r
- div.css("cursor", "auto");\r
- div.addClass("locked");\r
- div.next().find("span.nitdoc-github-editComment").hide();\r
- div.after(\r
- $("<p class='locked inheritance'>")\r
- .text("comment modified in ")\r
- .append("<a href='"+ request.request.html_url +"' target='_blank' title='Review on GitHub'>pull request #"+ request.request.number +"</a>")\r
- .append(" ")\r
- .append(\r
- $("<a data-pullrequest-number='"+ request.request.number +"' class='nitdoc-github-update'>update</a>")\r
- .click(function (){\r
- $(this).parent().hide();\r
- div.hide();\r
- var baseTextarea = div.prev();\r
- // add infos\r
- var infos = {};\r
- infos.user = Nitdoc.GitHub.UI.getUser();\r
- infos.location = Nitdoc.GitHub.Utils.parseLocation(baseTextarea.attr("data-comment-location"));\r
- infos.namespace = baseTextarea.attr("data-comment-namespace");\r
- infos.oldComment = baseTextarea.val();\r
- infos.requestID = $(this).attr("data-pullrequest-number");\r
- var box = new Nitdoc.GitHub.CommentBox(infos);\r
- box.open(baseTextarea); \r
- })\r
- )\r
- .append(" ")\r
- .append(\r
- $("<a data-pullrequest-number='"+ request.request.number +"' class='nitdoc-github-cancel'>cancel</a>")\r
- .click(function (){\r
- ui.closePullRequest($(this).attr("data-pullrequest-number"));\r
- ui.reloadComments();\r
- })\r
- )\r
- );\r
- }\r
- // hide "add comment" link\r
- if(div.hasClass("newComment")) {\r
- div.next().next().find("span.noComment").hide();\r
- }\r
- }\r
-\r
- });\r
- }\r
- }\r
-\r
- // Commit changes and send pull request\r
- var saveChanges = function(infos) {\r
- // if pull request update close existing pull request for the comment\r
- if(infos.requestID) {\r
- closePullRequest(infos.requestID);\r
- }\r
-\r
- // forge commit\r
- var fileContent = getFileContent(infos.location.path);\r
- infos.newContent = Nitdoc.GitHub.Utils.mergeComment(fileContent, infos.newComment, infos.location);\r
-\r
- // commit\r
- infos.request = pushChanges(infos)\r
- if(!infos.request) {\r
- Nitdoc.GitHub.ModalBox.open("Unable to commit changes!", response, true);\r
- return;\r
- }\r
- saveRequest(infos);\r
-\r
- // close boxes and reload comments \r
- Nitdoc.GitHub.CommitBox.close();\r
- infos.commentBox.close();\r
- reloadComments();\r
- }\r
-\r
- /*\r
- Creating a new pull request with the new comment take 5 steps:\r
- 1. get the base tree from latest commit\r
-\r
- 2. create a new blob with updated file content\r
- 3. post a new tree from base tree and blob\r
- 4. post the new commit with new tree\r
- 5. create the pull request\r
- */\r
- var pushChanges = function(infos) {\r
- var baseTree = Nitdoc.GitHub.API.getTree(user, origin.sha);\r
- if(!baseTree.sha) {\r
- Nitdoc.GitHub.ModalBox.open("Unable to locate base tree!", baseTree.status + ": " + baseTree.statusText, true);\r
- return false;\r
- }\r
- console.log("Base tree: " + baseTree.url);\r
- var newBlob = Nitdoc.GitHub.API.createBlob(user, infos.newContent);\r
- if(!newBlob.sha) {\r
- Nitdoc.GitHub.ModalBox.open("Unable to create new blob!", newBlob.status + ": " + newBlob.statusText, true);\r
- return false;\r
- }\r
- console.log("New blob: " + newBlob.url);\r
- var newTree = Nitdoc.GitHub.API.createTree(user, baseTree, infos.location.path, newBlob);\r
- if(!newTree.sha) {\r
- Nitdoc.GitHub.ModalBox.open("Unable to create new tree!", newTree.status + ": " + newTree.statusText, true);\r
- return false;\r
- }\r
- console.log("New tree: " + newTree.url);\r
- var newCommit = Nitdoc.GitHub.API.createCommit(user, infos.message, baseTree.sha, newTree);\r
- if(!newCommit.sha) {\r
- Nitdoc.GitHub.ModalBox.open("Unable to create new commit!", newCommit.status + ": " + newCommit.statusText, true);\r
- return false;\r
- }\r
- console.log("New commit: " + newCommit.url);\r
- var pullRequest = Nitdoc.GitHub.API.createPullRequest(user, infos.message.split("\n\n")[0], "Pull request from Nitdoc", origin, newCommit.sha);\r
- if(!pullRequest.number) {\r
- Nitdoc.GitHub.ModalBox.open("Unable to create pull request!", pullRequest.status + ": " + pullRequest.statusText, true);\r
- return false;\r
- }\r
- console.log("New pull request: " + pullRequest.url);\r
- return pullRequest;\r
- }\r
-\r
- // close previously opened pull request\r
- var closePullRequest = function(number) {\r
- var requests = JSON.parse(localStorage.requests);\r
- if(!requests[number]) {\r
- Nitdoc.GitHub.ModalBox.open("Unable to close pull request!", "Pull request " + number + "not found", true);\r
- return false;\r
- }\r
- // close pull request\r
- var res = Nitdoc.GitHub.API.updatePullRequest(user, "Canceled from Nitdoc", "", "closed", requests[number].request);\r
- if(!res.id) {\r
- Nitdoc.GitHub.ModalBox.open("Unable to close pull request!", res.status + ": " + res.statusText, true);\r
- return false;\r
- }\r
- // update in localstorage\r
- requests[number].isClosed = true;\r
- localStorage.requests = JSON.stringify(requests);\r
- }\r
-\r
- // Get file content from github\r
- var getFileContent = function(githubUrl) {\r
- var origFile = Nitdoc.GitHub.API.getFile(user, githubUrl);\r
- if(!origFile.content) {\r
- Nitdoc.GitHub.ModalBox.open("Unable to locate source file!", origFile.status + ": " + origFile.statusText, true);\r
- return;\r
- }\r
- var base64Content = origFile.content.substring(0, origFile.content.length - 1)\r
- return Base64.decode(base64Content);\r
- }\r
-\r
- // save pull request in local storage\r
- var saveRequest = function(infos) {\r
- var requests = [];\r
- if(localStorage.requests) {requests = JSON.parse(localStorage.requests)}\r
- requests[infos.request.number] = {\r
- request: infos.request,\r
- location: infos.location.origin,\r
- comment: Base64.encode(infos.newComment)\r
- };\r
- localStorage.requests = JSON.stringify(requests);\r
- }\r
-\r
- // save user in local storage\r
- var saveSession = function(user) {\r
- var session = {\r
- login: user.login,\r
- password: Base64.encode(user.password),\r
- repo: user.repo,\r
- branch: user.branch,\r
- };\r
- localStorage.user = JSON.stringify(session);\r
- }\r
-\r
- // accessors\r
-\r
- var getUser = function() { return user; }\r
- var getOrigin = function() { return origin; }\r
- var getOpenedComments = function() { return openedComments; }\r
- var addOpenedComments = function() { openedComments += 1; }\r
- var remOpenedComments = function() { openedComments -= 1; }\r
-\r
- // public interface\r
- var ui = {\r
- init: init,\r
- tryLogin: tryLogin,\r
- activate: activate,\r
- disactivate: disactivate,\r
- getUser: getUser,\r
- getOrigin: getOrigin,\r
- getOpenedComments: getOpenedComments,\r
- addOpenedComments: addOpenedComments,\r
- remOpenedComments: remOpenedComments,\r
- saveChanges: saveChanges,\r
- closePullRequest: closePullRequest,\r
- reloadComments: reloadComments\r
- }\r
-\r
- return ui;\r
-}();\r
-\r
-/*\r
- * GitHub API user object\r
- */\r
-Nitdoc.GitHub.User = function(login, password, repo, branch) {\r
- this.login = login;\r
- this.password = password;\r
- this.repo = repo;\r
- this.auth = "Basic " + Base64.encode(login + ':' + password);\r
- this.branch = branch;\r
-};\r
-\r
-/* \r
- * GitHub API module\r
- */\r
-Nitdoc.GitHub.API = function() {\r
-\r
- // try to login the user to github API\r
- var login = function(user) {\r
- var res = false;\r
- $.ajax({\r
- beforeSend: function (xhr) {\r
- xhr.setRequestHeader ("Authorization", user.auth);\r
- },\r
- type: "GET",\r
- url: "https://api.github.com/repos/" + user.login + "/" + user.repo,\r
- async: false,\r
- dataType: 'json',\r
- success: function() {\r
- res = true;\r
- }\r
- });\r
- user.infos = getUserInfos(user);\r
- user.signedOff = getSignedOff(user)\r
- return res;\r
- }\r
-\r
- // request for user github account infos\r
- var getUserInfos = function(user) {\r
- var res = false;\r
- $.ajax({\r
- beforeSend: function (xhr) {\r
- xhr.setRequestHeader ("Authorization", user.auth);\r
- },\r
- type: "GET",\r
- url: "https://api.github.com/users/" + user.login,\r
- async: false,\r
- dataType: 'json',\r
- success: function(response) {\r
- res = response;\r
- },\r
- error: function(response) {\r
- res = response;\r
- }\r
- });\r
- return res;\r
- }\r
-\r
- // build signedoff user default signature\r
- var getSignedOff = function(user) {\r
- return user.infos.name + " <" + user.infos.email + ">";\r
- }\r
-\r
- // get the branches list from a repo\r
- var getBranches = function(user) {\r
- var res = false;\r
- $.ajax({\r
- beforeSend: function (xhr) {\r
- xhr.setRequestHeader ("Authorization", user.auth);\r
- },\r
- type: "GET",\r
- url: "https://api.github.com/repos/" + user.login + "/" + user.repo + "/branches",\r
- async: false,\r
- dataType: 'json',\r
- success: function(response) {\r
- res = response;\r
- },\r
- error: function(response) {\r
- res = response;\r
- }\r
- });\r
- return res;\r
- }\r
-\r
- /* GitHub commits */\r
-\r
- // get the latest commit on `branchName`\r
- var getCommit = function(user, sha) {\r
- var res = false;\r
- $.ajax({\r
- beforeSend: function (xhr) {\r
- xhr.setRequestHeader ("Authorization", user.auth);\r
- },\r
- type: "GET",\r
- url: "https://api.github.com/repos/" + user.login + "/" + user.repo + "/git/commits/" + sha,\r
- async: false,\r
- dataType: 'json',\r
- success: function(response) {\r
- res = response;\r
- },\r
- error: function(response) {\r
- res = response;\r
- }\r
- });\r
- return res;\r
- }\r
-\r
- // get the base tree for a commit sha\r
- var getTree = function(user, sha) {\r
- var res = false;\r
- $.ajax({\r
- beforeSend: function (xhr) {\r
- xhr.setRequestHeader ("Authorization", user.auth);\r
- },\r
- type: "GET",\r
- url: "https://api.github.com/repos/" + user.login + "/" + user.repo + "/git/trees/" + sha + "?recursive=1",\r
- async: false,\r
- dataType: 'json',\r
- success: function(response) {\r
- res = response;\r
- },\r
- error: function(response) {\r
- res = response;\r
- }\r
- });\r
- return res;\r
- }\r
-\r
- // create a new blob\r
- var createBlob = function(user, content) {\r
- var res = false;\r
- $.ajax({\r
- beforeSend: function (xhr) {\r
- xhr.setRequestHeader ("Authorization", user.auth);\r
- },\r
- type: "POST",\r
- url: "https://api.github.com/repos/" + user.login + "/" + user.repo + "/git/blobs",\r
- async: false,\r
- dataType: 'json',\r
- data: JSON.stringify({\r
- content: Base64.encode(content),\r
- encoding: "base64"\r
- }),\r
- success: function(response) {\r
- res = response;\r
- },\r
- error: function(response) {\r
- res = response;\r
- }\r
- });\r
- return res;\r
- }\r
-\r
- // create a new tree from a base tree\r
- var createTree = function(user, baseTree, path, blob) {\r
- var res = false;\r
- $.ajax({\r
- beforeSend: function (xhr) {\r
- xhr.setRequestHeader ("Authorization", user.auth);\r
- },\r
- type: "POST",\r
- url: "https://api.github.com/repos/" + user.login + "/" + user.repo + "/git/trees",\r
- data: JSON.stringify({\r
- base_tree: baseTree.sha,\r
- tree: [{\r
- path: path,\r
- mode: 100644, // file (blob)\r
- type: "blob",\r
- sha: blob.sha\r
- }]\r
- }),\r
- async: false,\r
- dataType: 'json',\r
- success: function(response) {\r
- res = response;\r
- },\r
- error: function(response) {\r
- res = response;\r
- }\r
- });\r
- return res;\r
- }\r
-\r
- // create a new commit\r
- var createCommit = function(user, message, parentCommit, tree) {\r
- var res = false;\r
- $.ajax({\r
- beforeSend: function (xhr) {\r
- xhr.setRequestHeader ("Authorization", user.auth);\r
- },\r
- type: "POST",\r
- url: "https://api.github.com/repos/" + user.login + "/" + user.repo + "/git/commits",\r
- data: JSON.stringify({\r
- message: message,\r
- parents: parentCommit,\r
- tree: tree.sha,\r
- }),\r
- async: false,\r
- dataType: 'json',\r
- success: function(response) {\r
- res = response;\r
- },\r
- error: function(response) {\r
- res = response;\r
- }\r
- });\r
- return res;\r
- }\r
-\r
- // create a pull request\r
- var createPullRequest = function(user, title, body, origin, head) {\r
- var res = false;\r
- $.ajax({\r
- beforeSend: function (xhr) {\r
- xhr.setRequestHeader ("Authorization", user.auth);\r
- },\r
- type: "POST",\r
- url: "https://api.github.com/repos/" + origin.user + "/" + origin.repo + "/pulls",\r
- data: JSON.stringify({\r
- title: title,\r
- body: body,\r
- base: origin.branch,\r
- head: user.login + ":" + head\r
- }),\r
- async: false,\r
- dataType: 'json',\r
- success: function(response) {\r
- res = response;\r
- },\r
- error: function(response) {\r
- res = response;\r
- }\r
- });\r
- return res;\r
- }\r
-\r
- // update a pull request\r
- var updatePullRequest = function(user, title, body, state, request) {\r
- var res = false;\r
- $.ajax({\r
- beforeSend: function (xhr) {\r
- xhr.setRequestHeader ("Authorization", user.auth);\r
- },\r
- type: "PATCH",\r
- url: request.url,\r
- data: JSON.stringify({\r
- title: title,\r
- body: body,\r
- state: state\r
- }),\r
- async: false,\r
- dataType: 'json',\r
- success: function(response) {\r
- res = response;\r
- },\r
- error: function(response) {\r
- res = response;\r
- }\r
- });\r
- return res;\r
- }\r
-\r
- /* Files */\r
-\r
- var getFile = function(user, path, branch) {\r
- var res = false;\r
- $.ajax({\r
- type: "GET",\r
- url: "https://api.github.com/repos/" + user.login + "/" + user.repo + "/contents/" + path,\r
- data: {\r
- ref: branch\r
- },\r
- async: false,\r
- dataType: 'json',\r
- success: function(response) {\r
- res = response;\r
- },\r
- error: function(response) {\r
- res = response;\r
- }\r
- });\r
- return res;\r
- }\r
-\r
- var api = {\r
- login: login,\r
- getCommit: getCommit,\r
- getBranches: getBranches,\r
- getTree: getTree,\r
- createBlob: createBlob,\r
- createTree: createTree,\r
- createCommit: createCommit,\r
- createPullRequest: createPullRequest,\r
- updatePullRequest: updatePullRequest,\r
- getFile: getFile\r
- }\r
-\r
- return api;\r
-}();\r
-\r
-/*\r
- * Nitdoc GitHub loginbox module\r
- */\r
-\r
-Nitdoc.GitHub.LoginBox = function() {\r
- var loginBox;\r
- var loginBoxLi;\r
- var loginBoxContent;\r
-\r
- var init = function(containerSelector) {\r
- loginBoxLi = $(document.createElement("li"))\r
- .attr("id", "nitdoc-github-li")\r
- .append(\r
- $(document.createElement("a"))\r
- .append(\r
- $(document.createElement("img"))\r
- .attr({\r
- src: "resources/icons/github-icon.png",\r
- alt: "GitHub"\r
- })\r
- .addClass("nitdoc-github-li-img")\r
- )\r
- .click(function() { Nitdoc.GitHub.LoginBox.toggle() })\r
- )\r
-\r
- loginBoxContent = $(document.createElement("div"));\r
- loginBox = $(document.createElement("div"))\r
- .attr("id", "nitdoc-github-loginbox")\r
- .css("display", "none")\r
- .append(\r
- $(document.createElement("div"))\r
- .addClass("nitdoc-github-loginbox-arrow")\r
- .append(" ")\r
- )\r
- .append(\r
- $(document.createElement("h3"))\r
- .append("Github Sign In")\r
- )\r
- .append(loginBoxContent);\r
-\r
- loginBoxLi.append(loginBox);\r
- $(containerSelector).append(loginBoxLi);\r
- }\r
-\r
- // Panel of login box to display when the user is logged in\r
- var displayLogout = function(origin, user) {\r
- var panel = $(document.createElement("div"))\r
- .append(\r
- $(document.createElement("h4"))\r
- .append("Hello ")\r
- .append(\r
- $(document.createElement("a"))\r
- .attr("href", "https://github.com/" + user.login)\r
- .append(user.login)\r
- ).append("!")\r
- )\r
- .append(\r
- $(document.createElement("label"))\r
- .attr("for", "github-origin")\r
- .append("Origin")\r
- )\r
- .append(\r
- $(document.createElement("input"))\r
- .attr({\r
- id: "github-origin",\r
- type: "text",\r
- disabled: "disabled",\r
- value: origin.user + ":" + origin.repo + ":" + origin.branch\r
- })\r
- )\r
- .append(\r
- $(document.createElement("label"))\r
- .attr("for", "github-base")\r
- .append("Base")\r
- )\r
- .append(\r
- $(document.createElement("input"))\r
- .attr({\r
- id: "github-base",\r
- type: "text",\r
- disabled: "disabled",\r
- value: user.login + ":" + user.repo + ":" + user.branch\r
- })\r
- )\r
- .append(\r
- $(document.createElement("button"))\r
- .addClass("nitdoc-github-button")\r
- .addClass("nitdoc-github-cancel")\r
- .append(\r
- $(document.createElement("img"))\r
- .attr("src", "resources/icons/github-icon.png")\r
- ).append("Sign Off")\r
- .click(function() { // log out user\r
- Nitdoc.GitHub.UI.disactivate();\r
- Nitdoc.GitHub.LoginBox.toggle();\r
- })\r
- );\r
- $(".nitdoc-github-li-img").attr("src", "resources/icons/github-icon-green.png");\r
- loginBoxContent.empty()\r
- loginBoxContent.append(panel);\r
- }\r
-\r
- // Panel of login box to display when the user is logged out\r
- var displayLogin = function() {\r
- var panel = $(document.createElement("form"))\r
- .append(\r
- $(document.createElement("label"))\r
- .attr("for", "nitdoc-github-login-field")\r
- .append("Username")\r
- )\r
- .append(\r
- $(document.createElement("input"))\r
- .attr({\r
- id: "nitdoc-github-login-field",\r
- type: "text"\r
- })\r
- )\r
- .append(\r
- $(document.createElement("label"))\r
- .attr("for", "nitdoc-github-password-field")\r
- .append("Password")\r
- )\r
- .append(\r
- $(document.createElement("input"))\r
- .attr({\r
- id: "nitdoc-github-password-field",\r
- type: "password"\r
- })\r
- )\r
- .append(\r
- $(document.createElement("label"))\r
- .attr("for", "nitdoc-github-repo-field")\r
- .append("Repository")\r
- )\r
- .append(\r
- $(document.createElement("input"))\r
- .attr({\r
- id: "nitdoc-github-repo-field",\r
- type: "text"\r
- })\r
- )\r
- .append(\r
- $(document.createElement("label"))\r
- .attr("for", "nitdoc-github-branch-field")\r
- .append("Branch")\r
- )\r
- .append(\r
- $(document.createElement("input"))\r
- .attr({\r
- id: "nitdoc-github-branch-field",\r
- type: "text"\r
- })\r
- )\r
- .append(\r
- $(document.createElement("button"))\r
- .addClass("nitdoc-github-button")\r
- .append(\r
- $(document.createElement("img"))\r
- .attr("src", "resources/icons/github-icon.png")\r
- ).append("Sign In")\r
- .click(function() {\r
- var login = $('#nitdoc-github-login-field').val();\r
- var password = $('#nitdoc-github-password-field').val();\r
- var repo = $('#nitdoc-github-repo-field').val();\r
- var branch = $('#nitdoc-github-branch-field').val();\r
- if(!login || !password || !repo || !branch) {\r
- Nitdoc.GitHub.ModalBox.open("Sign in error", "Please enter your GitHub username, password, repository and branch.", true);\r
- } else {\r
- var user = Nitdoc.GitHub.UI.tryLogin(login, password, repo, branch);\r
- if(user == "error:login") {\r
- Nitdoc.GitHub.ModalBox.open("Sign in error", "The username, password, repo or branch you entered is incorrect.", true);\r
- } else if(user == "error:sha") {\r
- Nitdoc.GitHub.ModalBox.open("Base commit not found", "The provided GitHub repository must contains the base commit '" + Nitdoc.GitHub.UI.getOrigin().sha + "'", true);\r
- } else if(user == "error:profile") {\r
- 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);\r
- } else {\r
- Nitdoc.GitHub.UI.activate(user);\r
- var origin = Nitdoc.GitHub.UI.getOrigin();\r
- Nitdoc.GitHub.LoginBox.displayLogout(origin, user);\r
- }\r
- }\r
- return false;\r
- })\r
- )\r
- $(".nitdoc-github-li-img").attr("src", "resources/icons/github-icon.png");\r
- loginBoxContent.empty()\r
- loginBoxContent.append(panel);\r
- }\r
-\r
- var toggle = function() {\r
- if(loginBox.is(':hidden')) {\r
- loginBox.show();\r
- if (!$('#loginGit').is(':hidden')) { $('#loginGit').focus(); }\r
- } else {\r
- loginBox.hide();\r
- }\r
- }\r
-\r
- // Public interface\r
- var loginbox = {\r
- init: init,\r
- displayLogin: displayLogin,\r
- displayLogout: displayLogout,\r
- toggle: toggle,\r
- \r
- };\r
-\r
- return loginbox;\r
-}();\r
-\r
-/*\r
- * Nitdoc.GitHub.CommentBox class\r
- */\r
-\r
-// Init new modal box instance\r
-Nitdoc.GitHub.CommentBox = function(infos) {\r
- this.infos = infos;\r
- this.commentBoxDiv;\r
-}\r
-\r
-Nitdoc.GitHub.CommentBox.prototype.open = function(baseArea) {\r
- Nitdoc.GitHub.UI.addOpenedComments();\r
- var instance = this;\r
-\r
- if(this.infos.requestID) {\r
- // get comment from last pull request\r
- var requests = JSON.parse(localStorage.requests);\r
- this.infos.newComment = Base64.decode(requests[this.infos.requestID].comment);\r
- } else {\r
- this.infos.newComment = false;\r
- }\r
-\r
- // create comment box\r
- var tarea = $(document.createElement("textarea"))\r
- .append(this.infos.newComment === false? this.infos.oldComment: this.infos.newComment)\r
- .keyup(function(event) {\r
- $(event.target).css("height", (event.target.value.split(/\r|\n/).length * 16) + "px");\r
- 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) ) {\r
- $(event.target).parent().find("button.nitdoc-github-commit").removeAttr("disabled");\r
- } else {\r
- $(event.target).parent().find("button.nitdoc-github-commit").attr("disabled", "disabled");\r
- }\r
- })\r
- .keydown(function(event) {\r
- if(event.keyCode == 13){\r
- $(event.target).css("height", ($(event.target).outerHeight() + 6) + "px");\r
- }\r
- });\r
-\r
- this.commentBoxDiv = $(document.createElement("div"))\r
- .addClass("nitdoc-github-commentbox")\r
- .append(tarea)\r
- .append(\r
- $(document.createElement("a"))\r
- .addClass("nitdoc-github-preview")\r
- .click(function() {\r
- var converter = new Markdown.Converter()\r
- var html = converter.makeHtml(tarea.val());\r
- Nitdoc.GitHub.ModalBox.open("Preview", html, false);\r
- })\r
- )\r
- .append(\r
- $(document.createElement("button"))\r
- .addClass("nitdoc-github-button")\r
- .addClass("nitdoc-github-commit")\r
- .append("Commit")\r
- .click(function() {\r
- instance.infos.newComment = tarea.val();\r
- instance.infos.commentBox = instance;\r
- Nitdoc.GitHub.CommitBox.open(instance.infos);\r
- })\r
- )\r
- .append(\r
- $(document.createElement("button"))\r
- .addClass("nitdoc-github-button")\r
- .addClass("nitdoc-github-cancel")\r
- .append("Cancel")\r
- .click(function() {instance.close()})\r
- );\r
-\r
- baseArea.after(this.commentBoxDiv);\r
- var cbWidth = this.commentBoxDiv.innerWidth();\r
- var taWidth = tarea.outerWidth();\r
- tarea.width(cbWidth - (taWidth - cbWidth));\r
- tarea.trigger("keyup");\r
- tarea.focus();\r
-}\r
-\r
-Nitdoc.GitHub.CommentBox.prototype.close = function() {\r
- Nitdoc.GitHub.UI.remOpenedComments();\r
- if(this.infos.isNew) {\r
- this.commentBoxDiv.next().find("span.nitdoc-github-editComment").show();\r
- } else if(this.infos.requestID) {\r
- this.commentBoxDiv.next().show();\r
- this.commentBoxDiv.next().next().show();\r
- } else {\r
- this.commentBoxDiv.next().show();\r
- this.commentBoxDiv.next().next().find("span.nitdoc-github-editComment").show();\r
- }\r
- this.commentBoxDiv.remove();\r
-}\r
-\r
-/*\r
- * Nitdoc.GitHub.ModalBox class\r
- */\r
-\r
-// Init new modal box instance\r
-Nitdoc.GitHub.ModalBox = function() {\r
-\r
- // Open modal box instance\r
- var open = function(title, content, isError) {\r
- $("body").append(\r
- $(document.createElement("div"))\r
- .attr("id", "nitdoc-github-modal-fade")\r
- .addClass("nitdoc-github-fade")\r
- )\r
- .append(\r
- $(document.createElement("div"))\r
- .attr("id", "nitdoc-github-modal")\r
- .addClass("nitdoc-github-modal")\r
- .append(\r
- $(document.createElement("a"))\r
- .addClass("nitdoc-github-close")\r
- .attr("title", "Close")\r
- .append("x")\r
- .click(function() { Nitdoc.GitHub.ModalBox.close() })\r
- )\r
- .append("<h3>" + title + "</h3>")\r
- .append("<div>" + content + "</div>")\r
- .append(\r
- $(document.createElement("div"))\r
- .addClass("nitdoc-github-buttons")\r
- .append(\r
- $(document.createElement("button"))\r
- .addClass("nitdoc-github-button")\r
- .append("Ok")\r
- .click(function() { Nitdoc.GitHub.ModalBox.close() })\r
- )\r
- )\r
- );\r
-\r
- if(isError) {\r
- $("#nitdoc-github-modal").addClass("nitdoc-github-error");\r
- }\r
-\r
- $("#nitdoc-github-modal")\r
- .css({\r
- top: "50%",\r
- marginTop: -($("#nitdoc-github-modal").outerHeight() / 2) + "px",\r
- left: "50%",\r
- marginLeft: -($("#nitdoc-github-modal").outerWidth() / 2) + "px"\r
- })\r
- .find("button.nitdoc-github-button").focus();\r
- }\r
-\r
- // Close modal box instance\r
- var close = function() {\r
- $("#nitdoc-github-modal").remove();\r
- $("#nitdoc-github-modal-fade").remove();\r
- }\r
-\r
- // Public interface\r
- var modalBox = {\r
- open: open,\r
- close: close\r
- };\r
-\r
- return modalBox;\r
-}();\r
-\r
-/*\r
- * Nitdoc.GitHub.CommitBox instance\r
- */\r
-\r
-// Init new commit box instance\r
-Nitdoc.GitHub.CommitBox = function() {\r
-\r
- // Open commit box instance\r
- var open = function(infos) {\r
- $("body").append(\r
- $(document.createElement("div"))\r
- .attr("id", "nitdoc-github-commitBox-fade")\r
- .addClass("nitdoc-github-fade")\r
- );\r
- $("body").append(\r
- $(document.createElement("div"))\r
- .attr("id", "nitdoc-github-commitBox")\r
- .addClass("nitdoc-github-modal")\r
- .append(\r
- $(document.createElement("a"))\r
- .addClass("nitdoc-github-close")\r
- .attr("title", "Close")\r
- .append("x")\r
- .click(function() { Nitdoc.GitHub.CommitBox.close() })\r
- )\r
- .append("<h3>Commit changes</h3>")\r
- .append(\r
- $(document.createElement("div"))\r
- .append(\r
- $(document.createElement("label"))\r
- .attr("for", "nitdoc-github-commit-message")\r
- )\r
- .append("<br/>")\r
- .append(\r
- $(document.createElement("textarea"))\r
- .attr("id", "nitdoc-github-commit-message")\r
- .append("doc: " + (infos.isNew ? "added" : "modified") + " comment for " + infos.namespace)\r
- )\r
- .append("<br/>")\r
- .append(\r
- $(document.createElement("input"))\r
- .attr({\r
- id: "nitdoc-github-commit-signedoff",\r
- type: "checkbox",\r
- value: "Signed-off-by: " + infos.user.signedOff\r
- })\r
- .change(function(e) {\r
- if ($(this).is(':checked')) {\r
- $("#nitdoc-github-commit-button").removeAttr("disabled");\r
- } else {\r
- $("#nitdoc-github-commit-button").attr("disabled", "disabled");\r
- }\r
- })\r
- )\r
- .append(\r
- $(document.createElement("label"))\r
- .attr("for", "nitdoc-github-commit-signedoff")\r
- .text("Signed-off-by: " + infos.user.signedOff)\r
- )\r
- ).append(\r
- $(document.createElement("div"))\r
- .addClass("nitdoc-github-buttons")\r
- .append(\r
- $(document.createElement("button"))\r
- .attr({\r
- id: "nitdoc-github-commit-button",\r
- disabled: "disabled"\r
- })\r
- .addClass("nitdoc-github-button")\r
- .append(\r
- $(document.createElement("img"))\r
- .attr("src", "resources/icons/github-icon.png")\r
- )\r
- .append("Commit")\r
- .mousedown(function() {\r
- $(this).text("Commiting...");\r
- })\r
- .mouseup(function() {\r
- infos.message = $("#nitdoc-github-commit-message").val() + "\n\n" + infos.user.signedOff;\r
- Nitdoc.GitHub.UI.saveChanges(infos);\r
- })\r
- )\r
- )\r
- );\r
-\r
- $("#nitdoc-github-commitBox")\r
- .css({\r
- top: "50%",\r
- marginTop: -($("#nitdoc-github-commitBox").outerHeight() / 2) + "px",\r
- left: "50%",\r
- marginLeft: -($("#nitdoc-github-commitBox").outerWidth() / 2) + "px"\r
- })\r
- .find("#nitdoc-github-commit-message").focus();\r
- }\r
-\r
- // Close commit box instance\r
- var close = function() {\r
- $("#nitdoc-github-commitBox").remove();\r
- $("#nitdoc-github-commitBox-fade").remove();\r
- }\r
-\r
- // Public interface\r
- var commitBox = {\r
- open: open,\r
- close: close\r
- }\r
- return commitBox;\r
-}();\r
-\r
-/*\r
- * Nitdoc.GitHub.Utils module\r
- */\r
-\r
-Nitdoc.GitHub.Utils = function() {\r
- // Extract infos from string location "lib/standard/collection/array.nit:457,1--458,0"\r
- var parseLocation = function(location) {\r
- var parts = location.split(":");\r
- var loc = new Object();\r
- loc.origin = location;\r
- loc.path = parts[0];\r
- loc.lstart = parseInt(parts[1].split("--")[0].split(",")[0]);\r
- loc.tabpos = parseInt(parts[1].split("--")[0].split(",")[1]);\r
- loc.lend = parseInt(parts[1].split("--")[1].split(",")[0]);\r
- return loc;\r
- }\r
-\r
- // Meld modified comment into file conten\r
- var mergeComment = function(fileContent, comment, location) {\r
- // replace comment in file content\r
- var res = new String();\r
- var lines = fileContent.split("\n");\r
- // copy lines fron 0 to lstart\r
- for(var i = 0; i < location.lstart - 1; i++) {\r
- res += lines[i] + "\n";\r
- }\r
- // set comment\r
- if(comment && comment != "") {\r
- var commentLines = comment.split("\n");\r
- for(var i = 0; i < commentLines.length; i++) {\r
- var line = commentLines[i];\r
- var tab = location.tabpos > 1 ? "\t" : "";\r
- res += tab + (line.length > 0 ? "# " : "#") + line + "\n";\r
- }\r
- }\r
- // copy lines fron lend to end\r
- for(var i = location.lend - 1; i < lines.length; i++) {\r
- res += lines[i];\r
- if(i < lines.length - 1) { res += "\n"; }\r
- }\r
- return res;\r
- }\r
-\r
- // Public interface\r
- var utils = {\r
- parseLocation: parseLocation,\r
- mergeComment: mergeComment\r
- };\r
-\r
- return utils;\r
-}();\r
-\r