/*
* @title GCJ の解法をページ内に表示する
* @description 解法をダウンロードすることなくページ内に表示できます。Google Code Jam 公式ページ( https://code.google.com/codejam/ )のスコアボード(ただし https は不可)、Code Jam Language Stats ( http://www.go-hero.net/jam/ ) の参加者別ページで利用できます。IE、Chrome ではセキュリティの関係で動作しなくなっているようなので、Firefox でご利用ください。
* @include http://code.google.com/codejam/contest/scoreboard?*
* @include http://www.go-hero.net/jam/*/name/*
* @license MIT License
* @require
*/
// loadScript
// - based on http://www.nczonline.net/blog/2009/07/28/the-best-way-to-load-external-javascript/
// - replaced appendChild to insertBefore, see http://www.stevesouders.com/blog/2010/05/11/appendchild-vs-insertbefore/
function loadScript(url, callback){
var script = document.createElement("script")
script.type = "text/javascript";
if (script.readyState){ //IE
script.onreadystatechange = function(){
if (script.readyState == "loaded" ||
script.readyState == "complete"){
script.onreadystatechange = null;
callback();
}
};
} else { //Others
script.onload = function(){
callback();
};
}
script.src = url;
var head = document.getElementsByTagName ("head")[0] || document.documentElement;
head.insertBefore(script, head.firstChild);
}
function prepareToShow() {
// prepare for google-code-prettify
if (!window.prettyPrint) {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "http://google-code-prettify.googlecode.com/svn/trunk/src/prettify.js";
document.body.appendChild(script);
var link = document.createElement("link");
link.rel = "stylesheet";
link.type = "text/css"
link.href = "http://google-code-prettify.googlecode.com/svn/trunk/src/prettify.css";
document.body.appendChild(link);
var style = document.createElement("style");
style.type = "text/css"
style.appendChild(document.createTextNode("pre { word-wrap: break-word; }"));
document.body.appendChild(style);
}
// prepare for zip.js
if (!window.Zip) {
loadScript(
"https://github.com/miau/zipjs/raw/master/zip.min.js",
function() {
var files = document.createElement("ul");
files.id = "files";
files.innerHTML = "<li>(files)</li>";
if (window.GCJ) {
document.getElementById("scb-rank-div").appendChild(files);
} else {
document.getElementById("content").appendChild(files);
}
addShowLinks();
}
);
} else {
addShowLinks();
}
}
function addShowLinks() {
if (window.GCJ) {
var thead = document.getElementById('scb-table-header1');
var tdIndexToProblem= [];
var tdIndex = 0;
for (var i = 0, th; th = thead.childNodes[i]; i++) {
var colspan = th.getAttribute('colspan');
for (var j = 0; j < colspan; j++) {
tdIndexToProblem[tdIndex++] = [i - 1, j];
}
}
var elems = goog$dom$getElementsByTagNameAndClass("img", "scb-views-file", document);
for (var i = 0, elem; elem = elems[i]; i++) {
var td = elem.parentNode;
var tdIndex = getChildIndex(td);
var username = goog$dom$getElementsByTagNameAndClass("td", "scb-player-name", td.parentNode)[0].innerHTML.replace(/\s*<.*>\s*/g, '');
var url =
GCJ.base_url +
"/scoreboard/do?cmd=GetSourceCode&contest=" + GCJ.contestId +
"&problem=" + GCJ.problems[tdIndexToProblem[tdIndex][0] | 0].id +
"&io_set_id=" + (tdIndexToProblem[tdIndex][1]) +
"&username=" + username;
appendShowLink(elem, url);
}
} else {
var elems = document.getElementsByTagName("a");
for (var i = 0, elem; elem = elems[i]; i++) {
if (elem.href.match(/GetSourceCode/)) {
appendShowLink(elem, elem.href);
}
}
}
}
function getChildIndex(target) {
for (var i = 0, elem; elem = target.parentNode.childNodes[i]; i++) {
if (elem == target) {
return i;
}
}
}
function appendShowLink(elem, url) {
var showLink = document.createElement("a");
showLink.href = "#";
showLink.innerHTML = "Show";
showLink.setAttribute("onclick", "showContents(this.url); return false;");
showLink.url = url;
elem.parentNode.appendChild(document.createTextNode(" - "));
elem.parentNode.appendChild(showLink);
}
function showContents(orgUrl) {
var url = isSameOrigin(document.URL, orgUrl)
? orgUrl
: "http://allow-any-origin.appspot.com/" + orgUrl;
Zip.inflate_file(url, function(zip) {
var files = document.getElementById("files");
files.innerHTML = "";
// extract inner zip files
for (var i in zip.files) {
var file = zip.files[i];
if (file.name.match(/\.zip$/)) {
var fileData = file.inflate();
var innerZip = Zip.inflate(fileData);
for (var j in innerZip.files) {
zip.files[i + "/" + j] = innerZip.files[j];
}
delete zip.files[i];
}
}
for (var i in zip.files) {
var file = zip.files[i];
var item = document.createElement("li");
var contents = file.inflate();
for (var j = 0, str = ''; j < contents.length; j++) {
str += String.fromCharCode(contents[j]);
}
item.innerHTML =
"<h2>" + i + "</h2>" +
"<pre class='prettyprint'>" +
str.replace(/</g, "<") +
"</pre>";
files.appendChild(item);
}
prettyPrint();
});
}
function isSameOrigin(docUrl, targetUrl) {
if (targetUrl.match(RegExp("^/"))) {
return true;
}
return getOrigin(docUrl) == getOrigin(targetUrl);
}
function getOrigin(url) {
return url.match(RegExp("^https?://[^/]+")).shift();
}
// copied from Closure Library
goog$dom$getElementsByTagNameAndClass = function(opt_tag, opt_class, opt_el) {
return goog$dom$getElementsByTagNameAndClass_(document, opt_tag, opt_class,
opt_el);
};
goog$dom$getElementsByTagNameAndClass_ = function(doc, opt_tag, opt_class,
opt_el) {
var parent = opt_el || doc;
var tagName = (opt_tag && opt_tag != '*') ? opt_tag.toUpperCase() : '';
if (goog$dom$canUseQuerySelector_(parent) &&
(tagName || opt_class)) {
var query = tagName + (opt_class ? '.' + opt_class : '');
return parent.querySelectorAll(query);
}
// Use the native getElementsByClassName if available, under the assumption
// that even when the tag name is specified, there will be fewer elements to
// filter through when going by class than by tag name
if (opt_class && parent.getElementsByClassName) {
var els = parent.getElementsByClassName(opt_class);
if (tagName) {
var arrayLike = {};
var len = 0;
// Filter for specific tags if requested.
for (var i = 0, el; el = els[i]; i++) {
if (tagName == el.nodeName) {
arrayLike[len++] = el;
}
}
arrayLike.length = len;
return arrayLike;
} else {
return els;
}
}
var els = parent.getElementsByTagName(tagName || '*');
if (opt_class) {
var arrayLike = {};
var len = 0;
for (var i = 0, el; el = els[i]; i++) {
var className = el.className;
// Check if className has a split function since SVG className does not.
if (typeof className.split == 'function' &&
goog.array.contains(className.split(/\s+/), opt_class)) {
arrayLike[len++] = el;
}
}
arrayLike.length = len;
return arrayLike;
} else {
return els;
}
};
goog$dom$canUseQuerySelector_ = function(parent) {
return !!(parent.querySelectorAll && parent.querySelector);
};
prepareToShow();