Skip to content

Instantly share code, notes, and snippets.

@pedromenezes
Created February 11, 2011 23:07
Show Gist options
  • Save pedromenezes/823236 to your computer and use it in GitHub Desktop.
Save pedromenezes/823236 to your computer and use it in GitHub Desktop.
github's TreeFinder
GitHub.TreeFinder = function() {
if ($("#slider").length != 0) {
var a = this;
$.hotkeys({
t: function() {
a.show()
}
});
var d = new Image;
d.src = "/images/modules/ajax/spinner.gif"
}
};
GitHub.TreeFinder.prototype = {
fileList: null,
recentFiles: [],
currentFinder: null,
currentInput: null,
show: function() {
if (!this.currentFinder) {
var a = this,
d;
a.currentFinder = $(".tree-finder").clone().show();
a.currentInput = a.currentFinder.find("input");
slider.slideForwardToLoading();
d = a.currentFinder.find(".breadcrumb").detach().addClass("js-tree-finder-breadcrumb");
$("#slider .breadcrumb:visible").hide().after(d);
$("#slider").bind("slid",
function() {
$("#slider .frame-center").is(":not(.tree-finder)") && a.hide()
});
a.attachBehaviors()
}
},
hide: function() {
if (this.currentFinder) {
var a = this;
a.currentInput.blur();
a.currentFinder.remove();
$(".js-tree-finder-breadcrumb").remove();
a.currentFinder = a.currentInput = null;
$("#slider").unbind("slid")
}
},
attachBehaviors: function() {
var a = this,
d = true,
b = null,
c = null;
a.loadFileList();
$(".js-dismiss-tree-list-help").live("click",
function() {
$.post(this.getAttribute("href"));
$(this).closest(".octotip").fadeOut(function() {
$(".tree-finder .octotip").remove()
});
a.currentInput.focus();
return false
});
$("tbody.js-results-list tr", a.currentFinder).live("mouseover",
function() {
if (d) {
a.currentFinder && a.currentFinder.find("tr.current").removeClass("current");
$(this).addClass("current")
}
});
a.currentFinder.find(".js-results-list").delegate("a", "click",
function() {
var f = $(this).text(),
h = $.inArray(f, a.recentFiles);
h > -1 && a.recentFiles.splice(h, 1);
a.recentFiles.unshift(f);
a.currentInput.blur();
$(document).unbind("keydown.treeFinder");
if (slider.enabled) return true;
else document.location = $(this).attr("href")
});
$("tr td.icon", a.currentFinder).live("click",
function() {
$(this).parents("tr:first").find("td a").click()
});
$(document).bind("keydown.treeFinder",
function(f) {
if (f.keyCode == 27) {
if (!slider.sliding && $("#slider .frame-center").is(".tree-finder")) {
slider.slideBackTo(location.pathname);
$(document).unbind("keydown.treeFinder")
}
return false
}
});
a.currentInput.focus().keyup(function() {
b && clearTimeout(b);
b = setTimeout(function() {
b = null;
d = true
},
250)
}).keydown(function(f) {
var h = a.currentFinder.find("tr.current"),
e = null;
switch (f.which) {
case 9:
case 16:
case 17:
case 18:
case 91:
case 93:
return false;
case 38:
case 40:
if (h.length == 0) return false;
e = f.which == 38 ? h.prev("tr") : h.next("tr");
if (e.length) {
d = false;
h.removeClass("current");
e.addClass("current");
f = 100;
h = $(window);
var i = h.height(),
l = e.offset().top - f;
e = e.offset().top + e.outerHeight() + f;
if (l < h.scrollTop()) h.scrollTop() > f && h.scrollTop(l);
else e > h.scrollTop() + i && h.scrollTop(e - i)
}
return false;
case 13:
if (h.length == 0) return false;
h.find("a").click();
return false
}
c &&
clearTimeout(c);
c = setTimeout(function() {
c = null;
a.updateResults()
},
100)
})
},
loadFileList: function() {
var a = this;
function d() {
a.loadedFileList()
}
a.fileList ? d() : $.ajax({
url: "/" + GitHub.nameWithOwner + "/tree-list/" + GitHub.commitSHA,
error: function() {
if (a.currentFinder) {
a.fileList = [];
a.currentFinder.find(".js-no-results th").text("Something went wrong");
d()
}
},
success: function(b) {
a.fileList = b ? $.trim(b).split("\n") : [];
d()
}
})
},
loadedFileList: function() {
var a = this;
if (a.currentFinder) {
$("#slider .frame-center").replaceWith(a.currentFinder);
a.updateResults()
}
},
updateResults: function() {
var a = this;
if (a.currentFinder && a.fileList) {
var d = a.currentInput.val(),
b = [],
c = a.currentFinder.find(".js-results-list"),
f = 0;
c.empty();
if (d) b = a.findMatchingFiles(d);
else if (a.recentFiles.length) {
b = a.recentFiles.slice(1, 6);
if (b.length < 20) b = b.concat(a.fileList.slice(0, 20 - b.length))
} else b = a.fileList;
if (b.length <= 0) {
a.currentFinder.find(".js-no-results").show();
a.currentFinder.find(".js-header").hide()
} else {
a.currentFinder.find(".js-no-results").hide();
a.currentFinder.find(".js-header").show();
b = b.slice(0, 50);
f = this.currentInput.val().replace("/", "").toLowerCase().replace(/(.)/g, "($1)(.*?)");
d = new RegExp("^(.*?)" + f + "$", "i");
var h = function(e, i) {
return i % 2 == 1 ? "<b>" + e + "</b>": e
};
for (f = 0; f < b.length; f++) {
a = (b[f].match(d) || []).slice(1).map(h).join("");
c.append('<tr><td class="icon"><img src="/images/icons/txt.png"></td><td><a class="js-slide-to" href="/' + GitHub.nameWithOwner + "/blob/" + (GitHub.currentRef || GitHub.commitSHA) + "/" + b[f] + '">' + a + "</a></td></tr>")
}
c.find("tr:first").addClass("current")
}
}
},
findMatchingFiles: function(a) {
var d = this;
if (!a) return [];
var b = [],
c = 0,
f,
h,
e,
i;
a = a.replace("/", "").toLowerCase();
f = new RegExp("^.*?" + a.replace(/(.)/g, "$1.*?") + "$");
for (c = 0; c < d.fileList.length; c++) {
h = d.fileList[c];
if (!h.match(/^vendor/)) {
e = h.replace("/", "").toLowerCase();
if (e.match(f)) {
i = e.score(a);
if (i > 0) {
if (e.match(a)) i = 1.1;
b.push([i, h])
}
}
}
}
return $.map(b.sort(function(l, o) {
return o[0] - l[0]
}),
function(l) {
return l[1]
})
}
};
String.prototype.score = function(a, d) {
d = d || 0;
if (a.length == 0) return 0.9;
if (a.length > this.length) return 0;
for (var b = a.length; b > 0; b--) {
var c = a.substring(0, b),
f = this.indexOf(c);
if (! (f < 0)) if (! (f + a.length > this.length + d)) {
c = this.substring(f + c.length);
var h = null;
h = b >= a.length ? "": a.substring(b);
h = c.score(h, d + f);
if (h > 0) {
a = this.length - c.length;
if (f != 0) {
d = 0;
b = this.charCodeAt(f - 1);
if (b == 32 || b == 9) for (d = f - 2; d >= 0; d--) {
b = this.charCodeAt(d);
a -= b == 32 || b == 9 ? 1: 0.15
} else a -= f
}
a += h * c.length;
a /= this.length;
return a
}
}
}
return 0
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment