mirror of
https://github.com/kennethreitz-archive/gitx.git
synced 2026-06-05 23:40:18 +00:00
9689c430ef
- remove the underline from file names (makes them easier to read)
- add icons to replace the file modification buttons (icons by Nathan Kinsinger)
332 lines
9.8 KiB
JavaScript
332 lines
9.8 KiB
JavaScript
var commit;
|
|
|
|
// Create a new Commit object
|
|
// obj: PBGitCommit object
|
|
var Commit = function(obj) {
|
|
this.object = obj;
|
|
|
|
this.refs = obj.refs();
|
|
this.author_name = obj.author;
|
|
this.sha = obj.realSha();
|
|
this.parents = obj.parents;
|
|
this.subject = obj.subject;
|
|
this.notificationID = null;
|
|
|
|
// TODO:
|
|
// this.author_date instant
|
|
|
|
// This can be called later with the output of
|
|
// 'git show' to fill in missing commit details (such as a diff)
|
|
this.parseDetails = function(details) {
|
|
this.raw = details;
|
|
|
|
var diffStart = this.raw.indexOf("\ndiff ");
|
|
var messageStart = this.raw.indexOf("\n\n") + 2;
|
|
|
|
if (diffStart > 0) {
|
|
this.message = this.raw.substring(messageStart, diffStart).replace(/^ /gm, "").escapeHTML();
|
|
this.diff = this.raw.substring(diffStart);
|
|
} else {
|
|
this.message = this.raw.substring(messageStart).replace(/^ /gm, "").escapeHTML();
|
|
this.diff = "";
|
|
}
|
|
this.header = this.raw.substring(0, messageStart);
|
|
|
|
var match = this.header.match(/\nauthor (.*) <(.*@.*|.*)> ([0-9].*)/);
|
|
if (!(match[2].match(/@[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}/)))
|
|
this.author_email = match[2];
|
|
|
|
this.author_date = new Date(parseInt(match[3]) * 1000);
|
|
|
|
match = this.header.match(/\ncommitter (.*) <(.*@.*|.*)> ([0-9].*)/);
|
|
this.committer_name = match[1];
|
|
this.committer_email = match[2];
|
|
this.committer_date = new Date(parseInt(match[3]) * 1000);
|
|
}
|
|
|
|
this.reloadRefs = function() {
|
|
this.refs = this.object.refs();
|
|
}
|
|
|
|
};
|
|
|
|
|
|
var confirm_gist = function(confirmation_message) {
|
|
if (!Controller.isFeatureEnabled_("confirmGist")) {
|
|
gistie();
|
|
return;
|
|
}
|
|
|
|
// Set optional confirmation_message
|
|
confirmation_message = confirmation_message || "Yes. Paste this commit.";
|
|
var deleteMessage = Controller.getConfig_("github.token") ? " " : "You might not be able to delete it after posting.<br>";
|
|
var publicMessage = Controller.isFeatureEnabled_("publicGist") ? "<b>public</b>" : "private";
|
|
// Insert the verification links into div#notification_message
|
|
var notification_text = 'This will create a ' + publicMessage + ' paste of your commit to <a href="http://gist.github.com/">http://gist.github.com/</a><br>' +
|
|
deleteMessage +
|
|
'Are you sure you want to continue?<br/><br/>' +
|
|
'<a href="#" onClick="hideNotification();return false;" style="color: red;">No. Cancel.</a> | ' +
|
|
'<a href="#" onClick="gistie();return false;" style="color: green;">' + confirmation_message + '</a>';
|
|
|
|
notify(notification_text, 0);
|
|
// Hide img#spinner, since it?s visible by default
|
|
$("spinner").style.display = "none";
|
|
}
|
|
|
|
var gistie = function() {
|
|
notify("Uploading code to Gistie..", 0);
|
|
|
|
parameters = {
|
|
"file_ext[gistfile1]": "patch",
|
|
"file_name[gistfile1]": commit.object.subject.replace(/[^a-zA-Z0-9]/g, "-") + ".patch",
|
|
"file_contents[gistfile1]": commit.object.patch(),
|
|
};
|
|
|
|
// TODO: Replace true with private preference
|
|
token = Controller.getConfig_("github.token");
|
|
login = Controller.getConfig_("github.user");
|
|
if (token && login) {
|
|
parameters.login = login;
|
|
parameters.token = token;
|
|
}
|
|
if (!Controller.isFeatureEnabled_("publicGist"))
|
|
parameters.private = true;
|
|
|
|
var params = [];
|
|
for (var name in parameters)
|
|
params.push(encodeURIComponent(name) + "=" + encodeURIComponent(parameters[name]));
|
|
params = params.join("&");
|
|
|
|
var t = new XMLHttpRequest();
|
|
t.onreadystatechange = function() {
|
|
if (t.readyState == 4 && t.status >= 200 && t.status < 300) {
|
|
if (m = t.responseText.match(/gist: ([a-f0-9]+)/))
|
|
notify("Code uploaded to gistie <a target='_new' href='http://gist.github.com/" + m[1] + "'>#" + m[1] + "</a>", 1);
|
|
else {
|
|
notify("Pasting to Gistie failed :(.", -1);
|
|
Controller.log_(t.responseText);
|
|
}
|
|
}
|
|
}
|
|
|
|
t.open('POST', "http://gist.github.com/gists");
|
|
t.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
|
|
t.setRequestHeader('Accept', 'text/javascript, text/html, application/xml, text/xml, */*');
|
|
t.setRequestHeader('Content-type', 'application/x-www-form-urlencoded;charset=UTF-8');
|
|
|
|
try {
|
|
t.send(params);
|
|
} catch(e) {
|
|
notify("Pasting to Gistie failed: " + e, -1);
|
|
}
|
|
}
|
|
|
|
var setGravatar = function(email, image) {
|
|
if (Controller && !Controller.isReachable_("www.gravatar.com"))
|
|
return;
|
|
|
|
if(Controller && !Controller.isFeatureEnabled_("gravatar")) {
|
|
image.src = "";
|
|
return;
|
|
}
|
|
|
|
if (!email) {
|
|
image.src = "http://www.gravatar.com/avatar/?d=wavatar&s=60";
|
|
return;
|
|
}
|
|
|
|
image.src = "http://www.gravatar.com/avatar/" +
|
|
hex_md5(email.toLowerCase().replace(/ /g, "")) + "?d=wavatar&s=60";
|
|
}
|
|
|
|
var selectCommit = function(a) {
|
|
Controller.selectCommit_(a);
|
|
}
|
|
|
|
// Relead only refs
|
|
var reload = function() {
|
|
$("notification").style.display = "none";
|
|
commit.reloadRefs();
|
|
showRefs();
|
|
}
|
|
|
|
var showRefs = function() {
|
|
var refs = $("refs");
|
|
if (commit.refs) {
|
|
refs.parentNode.style.display = "";
|
|
refs.innerHTML = "";
|
|
for (var i = 0; i < commit.refs.length; i++) {
|
|
var ref = commit.refs[i];
|
|
refs.innerHTML += '<span class="refs ' + ref.type() + (commit.currentRef == ref.ref ? ' currentBranch' : '') + '">' + ref.shortName() + '</span>';
|
|
}
|
|
} else
|
|
refs.parentNode.style.display = "none";
|
|
}
|
|
|
|
var loadCommit = function(commitObject, currentRef) {
|
|
// These are only the things we can do instantly.
|
|
// Other information will be loaded later by loadCommitDetails,
|
|
// Which will be called from the controller once
|
|
// the commit details are in.
|
|
|
|
if (commit && commit.notificationID)
|
|
clearTimeout(commit.notificationID);
|
|
|
|
commit = new Commit(commitObject);
|
|
commit.currentRef = currentRef;
|
|
|
|
$("commitID").innerHTML = commit.sha;
|
|
$("authorID").innerHTML = commit.author_name;
|
|
$("subjectID").innerHTML = commit.subject.escapeHTML();
|
|
$("diff").innerHTML = ""
|
|
$("message").innerHTML = ""
|
|
$("files").innerHTML = ""
|
|
$("date").innerHTML = ""
|
|
showRefs();
|
|
|
|
for (var i = 0; i < $("commit_header").rows.length; ++i) {
|
|
var row = $("commit_header").rows[i];
|
|
if (row.innerHTML.match(/Parent:/)) {
|
|
row.parentNode.removeChild(row);
|
|
--i;
|
|
}
|
|
}
|
|
|
|
// Scroll to top
|
|
scroll(0, 0);
|
|
|
|
if (!commit.parents)
|
|
return;
|
|
|
|
for (var i = 0; i < commit.parents.length; i++) {
|
|
var newRow = $("commit_header").insertRow(-1);
|
|
newRow.innerHTML = "<td class='property_name'>Parent:</td><td>" +
|
|
"<a href='' onclick='selectCommit(this.innerHTML); return false;'>" +
|
|
commit.parents[i] + "</a></td>";
|
|
}
|
|
|
|
commit.notificationID = setTimeout(function() {
|
|
if (!commit.fullyLoaded)
|
|
notify("Loading commit…", 0);
|
|
commit.notificationID = null;
|
|
}, 500);
|
|
|
|
}
|
|
|
|
var showDiff = function() {
|
|
|
|
// Callback for the diff highlighter. Used to generate a filelist
|
|
var newfile = function(name1, name2, id, mode_change, old_mode, new_mode) {
|
|
var img = document.createElement("img");
|
|
var p = document.createElement("p");
|
|
var link = document.createElement("a");
|
|
link.setAttribute("href", "#" + id);
|
|
p.appendChild(link);
|
|
var finalFile = "";
|
|
if (name1 == name2) {
|
|
finalFile = name1;
|
|
img.src = "../../images/modified.png";
|
|
img.title = "Modified file";
|
|
p.title = "Modified file";
|
|
if (mode_change)
|
|
p.appendChild(document.createTextNode(" mode " + old_mode + " -> " + new_mode));
|
|
}
|
|
else if (name1 == "/dev/null") {
|
|
img.src = "../../images/added.png";
|
|
img.title = "Added file";
|
|
p.title = "Added file";
|
|
finalFile = name2;
|
|
}
|
|
else if (name2 == "/dev/null") {
|
|
img.src = "../../images/removed.png";
|
|
img.title = "Removed file";
|
|
p.title = "Removed file";
|
|
finalFile = name1;
|
|
}
|
|
else {
|
|
img.src = "../../images/renamed.png";
|
|
img.title = "Renamed file";
|
|
p.title = "Renamed file";
|
|
finalFile = name2;
|
|
p.insertBefore(document.createTextNode(name1 + " -> "), link);
|
|
}
|
|
|
|
link.appendChild(document.createTextNode(finalFile));
|
|
link.setAttribute("representedFile", finalFile);
|
|
|
|
p.insertBefore(img, link);
|
|
$("files").appendChild(p);
|
|
}
|
|
|
|
var binaryDiff = function(filename) {
|
|
if (filename.match(/\.(png|jpg|icns|psd)$/i))
|
|
return '<a href="#" onclick="return showImage(this, \'' + filename + '\')">Display image</a>';
|
|
else
|
|
return "Binary file differs";
|
|
}
|
|
|
|
highlightDiff(commit.diff, $("diff"), { "newfile" : newfile, "binaryFile" : binaryDiff });
|
|
}
|
|
|
|
var showImage = function(element, filename)
|
|
{
|
|
element.outerHTML = '<img src="GitX://' + commit.sha + '/' + filename + '">';
|
|
return false;
|
|
}
|
|
|
|
var enableFeature = function(feature, element)
|
|
{
|
|
if(!Controller || Controller.isFeatureEnabled_(feature)) {
|
|
element.style.display = "";
|
|
} else {
|
|
element.style.display = "none";
|
|
}
|
|
}
|
|
|
|
var enableFeatures = function()
|
|
{
|
|
enableFeature("gist", $("gist"))
|
|
enableFeature("gravatar", $("author_gravatar").parentNode)
|
|
enableFeature("gravatar", $("committer_gravatar").parentNode)
|
|
}
|
|
|
|
var loadCommitDetails = function(data)
|
|
{
|
|
commit.parseDetails(data);
|
|
|
|
if (commit.notificationID)
|
|
clearTimeout(commit.notificationID)
|
|
else
|
|
$("notification").style.display = "none";
|
|
|
|
var formatEmail = function(name, email) {
|
|
return email ? name + " <<a href='mailto:" + email + "'>" + email + "</a>>" : name;
|
|
}
|
|
|
|
$("authorID").innerHTML = formatEmail(commit.author_name, commit.author_email);
|
|
$("date").innerHTML = commit.author_date;
|
|
setGravatar(commit.author_email, $("author_gravatar"));
|
|
|
|
if (commit.committer_name != commit.author_name) {
|
|
$("committerID").parentNode.style.display = "";
|
|
$("committerID").innerHTML = formatEmail(commit.committer_name, commit.committer_email);
|
|
|
|
$("committerDate").parentNode.style.display = "";
|
|
$("committerDate").innerHTML = commit.committer_date;
|
|
setGravatar(commit.committer_email, $("committer_gravatar"));
|
|
} else {
|
|
$("committerID").parentNode.style.display = "none";
|
|
$("committerDate").parentNode.style.display = "none";
|
|
}
|
|
|
|
$("message").innerHTML = commit.message.replace(/\n/g,"<br>");
|
|
|
|
if (commit.diff.length < 200000)
|
|
showDiff();
|
|
else
|
|
$("diff").innerHTML = "<a class='showdiff' href='' onclick='showDiff(); return false;'>This is a large commit. Click here or press 'v' to view.</a>";
|
|
|
|
hideNotification();
|
|
enableFeatures();
|
|
}
|