WIP - Github Finder integration

need to replace jsonp and github stuff with gitter
This commit is contained in:
Sami Samhuri 2010-12-19 18:28:39 -08:00
parent 43a1376fe8
commit 148322be72
28 changed files with 1544 additions and 43 deletions

View file

@ -0,0 +1,28 @@
#code.Dark { background-color: #191919; color: white; }
#code.Dark .comment { color: #5E5A5F; }
#code.Dark .string { color: #93996D; }
#code.Dark .keywords { color: #CAA76F;}
#code.Dark .brackets { color: #F5F8F8; }
#code.Dark .symbol { color: #C06F52; }
/* CSS */
#code.Dark .properties { color: #C4AD7A}
#code.Dark .selectors { color: #977042 }
#code.Light { background-color: white; color: black; }
#code.Light .comment { color: green; }
#code.Light .string { color: teal; }
#code.Light .keywords { color: navy; font-weight: bold; }
#code.Light .brackets { color: navy; }
#code.Light .symbol { font-weight: bold; }
/* CSS */
#code.Light .properties { color: #C4AD7A}
#code.Light .selectors { color: #977042 }
/* CPP */
#code.Ligh .datatype { color: #006699; }
#code.Dark .datatype { font-weight: bold;}

BIN
GithubFinder/img/dir.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 B

BIN
GithubFinder/img/dir.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 485 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 679 B

BIN
GithubFinder/img/la.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 B

BIN
GithubFinder/img/la.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 B

BIN
GithubFinder/img/la_h.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 B

BIN
GithubFinder/img/la_h.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 B

BIN
GithubFinder/img/txt.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 B

BIN
GithubFinder/img/txt.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 B

View file

@ -0,0 +1,360 @@
/* to padd to get exactly 10,240 bytes */
// ;"ALEXLE";
window.F = Class.create({
initialize: function(options){
options = Object.extend( {
user_id: 'samsonjs'
,repository: SJS.projName
,branch: 'master'
}, options || {} );
this.ps = [];
this.shas = {};
this.u = options.user_id;
this.r = options.repository;
this.b = options.branch;
this.id = options.id;
this.render(this.id);
this.repo = null;
/* Prototype RC2 */
// document.on('click','a[data-sha]', function( event, element ){
// this.click( element.readAttribute('data-sha'), element );
// element.blur();
// }.bind(this) );
document.observe('click', function(e) {
e = e.findElement();
if( !e.readAttribute('data-sha') ) return;
this.click( e.readAttribute('data-sha'), e );
e.blur();
}.bind(this));
var idc = $('in'),
s = function() { idc.className = 'on' },
h = function() { if( Ajax.activeRequestCount == 0 ) idc.className = 'off' };
Ajax.Responders.register( {
onException: function(r,x) { console.log(x);h() }
,onComplete: h
,onCreate: s
});
/* init plugins */
if( FP )
for( var i = 0; i < FP.length; i++ )
new FP[i](this);
/* extractURL: if user assigns user_id, repo, branch */
this.xU();
this.oR(); // open repo
}
,xU: function() {
}
,render: function(selector) {
$(selector || document.body).insert(this.h());
this.psW = $('ps_w');
this.bW = $('b_w');
}
,h: function() {
return [
'<div id=content>',
'<div id=finder class=tbb>',
'<div id=r_w>',
'<div class=p>',
'<table width=100%>',
'<tr>',
'<td align=left id=r></td>', // repo
'<td align=center>Branch: <span id=brs_w></span></td>', // branches
'<td align=center id=in>Loading...</td>',
'<td align=right style=font-weight:bold><a href=https://github.com/sr3d/GithubFinder>Github Finder</a></td>',
'</tr>',
'</table>',
'</div>', // .p
'</div>', // #r_w
'<div id=b_w>', // browser wrapper
'<div id=ps_w style="width:200px"></div>',
'</div>',
// '<div class=clear></div>',
'</div>', // #finder
'<div id=f_c_w style="display:none">', // file content wrapper
'<div class=p>',
'<div id=f_h class=big></div>',
'</div>',
'<div id=f_c>', // file content
'<div class=p>', // padding
'<div id=f_w>', // file wrapper
'<div id=f></div>', // file
'</div>',
'<div id=diffoutput></div>',
'</div>', // padding
'</div>',
'<div class=clear></div>',
'</div>', // #f_c_w
'<div id=footer><b><a href=http://github.com/sr3d/GithubFinder>GithubFinder</a></b></div>',
'</div>' // # content
].join(' ');
}
/* openRepo */
,oR: function(repo) {
this.reset()
var u,r,b;
if( !repo ) {
/* check URL params */
var p = uP();
if( p["user_id"] && p["repo"] ) {
u = this.u = p["user_id"];
r = this.r = p["repo"]
b = this.b = p["branch"] || 'master';
} else {
// debugger
/* if user just come from a github repo ... */
var m = (new RegExp("^http://github.com/(.+)","i")).exec(document.referrer),
path = m ? m[1].split('/') : [];
if( path[0] && path[1] ) {
u = this.u = path[0];
r = this.r = path[1];
b = this.b = path[3] || 'master';
} else { /* default to app settings */
u = this.u;
r = this.r;
b = this.b;
}
}
} else {
/* User hits the "Go" button: grabbing the user/repo */
repo = repo.split('/');
if( repo.length < 2 ) { alert('invalid repository!'); return; }
u = this.u = repo[0];
r = this.r = repo[1];
b = this.b = ($('brs') ? $F('brs') : b) || 'master';
}
$('r').innerHTML = u + '/' + r;
/* Load the master branch */
GH.Commits.listBranch( u, r, b, {
onData: function(cs) {
// if(!cs.commits) { alert('repo not found'); return; }
var tree_sha = cs.commits[0].tree;
this.renderPanel(tree_sha);
}.bind(this)
});
/* Show branches info */
GH.Repo.listBranches( u, r, {
onData: function(bes) {
this.bes = $H(bes);
this.rBs();
}.bind(this)
});
}
,reset: function() {
$('f_c_w').hide();
this.cI = -1;
this.pI = 0;
while(this.ps.length > 0)
(this.ps.pop()).dispose();
}
,browse: function() {
this.oR( $('r').innerHTML );
return false;
}
/* render branches */
,rBs: function() {
var h = '<select id=brs>';
this.bes.each(function(b) {
h +=
'<option ' + (this.b == b.key ? ' selected=""' : ' ' ) + '>' +
b.key +
'</option>';
}.bind(this));
// html.push('</select>');
$('brs_w').innerHTML = h + '</select>';
document.getElementById('brs').observe('change', function() {
this.browse();
}.bind(this))
}
,renderPanel: function( sh, ix, it ) {
ix = ix || 0;
/* clear previously opened panels */
for( var i = this.ps.length - 1; i > ix; i-- ) {
(this.ps.pop()).dispose();
}
this.open( sh, it );
}
,_resizePanelsWrapper: function() {
var w = (this.ps.length * 201);
this.psW.style.width = w + 'px';
/* scroll to the last panel */
this.bW.scrollLeft = w;
}
/* request the content of the tree and render the panel */
,open: function( tree_sha, item ) {
GH.Tree.show( this.u, this.r, this.b, tree_sha, {
onData: function(tree) { // tree is already sorted
/* add all items to cache */
for( var i = 0, len = tree.length; i < len; i++ )
this.shas[ tree[i].sha ] = tree[i];
var name = item ? item.name : '' ;
// debugger
var p = new P( this, { tree: tree, index: this.ps.length, name: name, tree_sha: tree_sha, item: item } );
this.ps.push( p );
this._resizePanelsWrapper();
}.bind(this)
});
}
/**
* @sha: the sha of the object
* @e: the source element
* @kb: is this trigged by the keyboard
*/
,click: function(sha, e, kb) {
// console.log("kb" + kb);
// debugger
var it = this.shas[ sha ],
ix = +(e.up('.panel')).readAttribute('data-index'),
path = "";
/* set selection cursor && focus the item */
e.up('ul').select('li.cur').invoke('removeClassName','cur');
var p = e.up('div.panel'),
li = e.up('li').addClassName('cur'),
posTop = li.positionedOffset().top + li.offsetHeight - p.offsetHeight;
if( posTop > p.scrollTop) {
//p.scrollTop = posTop ;
}
/* current index */
this.cI = it.index;
this.pI = ix; // current panel index;
/* remember the current selected item */
this.ps[ ix ].cI = it.index;
/* don't be trigger happy: ptm = preview timer */
if(this._p) clearTimeout( this._p );
/* set a small delay here incase user switches really fast (e.g. keyboard navigation ) */
this._p = setTimeout( function(){
if( it.type == 'tree' ) {
this.renderPanel( it.sha, ix, it );
// don't show file preview panel
$('f_c_w').hide();
} else {
$('f_c_w').show();
if( /text/.test(it.mime_type) ) {
$('in').className = 'on';
GH.Blob.show( this.u, this.r, it.sha, { onSuccess: function(r) {
this.previewTextFile(r.responseText, it);
}.bind(this)} );
}
}
/* showPreview */
var p = function() {
$('diffoutput').hide();
$('f_c_w').show();
$('f_h').innerHTML = path;
}
}.bind(this), (kb ? 350 : 10)); // time out
return false
}
,previewTextFile: function( text, it ) {
text = text.replace(/\r\n/, "\n").split(/\n/);
var ln = [],
l = [],
sloc = 0;
for( var i = 0, len = text.length; i < len; i++ ) {
ln.push( '<span>' + (i + 1) + "</span>\n");
l.push( text[i] ? text[i].replace(/&/g, '&amp;').replace(/</g, '&lt;') : "" );
// count actual loc
sloc += text[i] ? 1 : 0;
}
if (typeof f.theme === 'undefined') f.theme = 'Light';
var html = [
'<div class=meta>',
'<span>' + it.mode + '</span>',
'<span>' + text.length + ' lines (' + sloc +' sloc)</span>',
'<span>' + it.size + ' bytes</span>',
'<span style="float:right">Theme: <select id="theme">',
'<option ' + (f.theme == 'Light' ? 'selected' : '' ) + '>Light</option>',
'<option ' + (f.theme == 'Dark' ? 'selected' : '' ) + '>Dark</option>',
'</select></span>',
'</div>',
'<div id=f_c_s>', // file content scroll
'<table cellspacing=0 cellpadding=0>',
'<tr>',
'<td valign=top>',
'<pre class=ln>',
ln.join(''),
'</pre>',
'</td>',
'<td width=100% valign=top>',
'<pre id=code>',
l.join("\n"),
'</pre>',
'</td>',
'</tr>',
'</div>'
];
$('diffoutput').hide();
$('in').className = 'off';
$('f').update( html.join('') ).show();
/* HACK!! */
$('theme').observe('change', function() {
window.f.theme = $F('theme');
$('code').removeClassName('Light').removeClassName('Dark').addClassName(window.f.theme);
});
}
,diff:function(){ alert('Diff is disabled.'); }
});

View file

@ -0,0 +1,159 @@
window.GH = {
hash: {}
// ,proxy: 'http://alexle.net/experiments/githubfinder/proxy.php?url='
,proxy: './proxy.php?url='
// ,proxy: ''
,api: 'http://github.com/api/v2/json'
/* set the proxy.php url and switch to the correct AR (AjaxRequest) */
,setProxy: function(p) {
this.proxy = p;
// window.AR = p.indexOf('./') == 0 ? Ajax.Request : JSP;
window.AR = JSP;
}
,Commits: {
_cache: []
/* list all commits for a specific branch */
,listBranch: function(u, r, b, o ) {
var onData = o.onData,
url = GH.api + '/commits/list/' + u + '/' + r + '/' + b;
o.onSuccess = function(res) {
onData( res.responseText );
}
new JSP( url, o );
}
,list: function( u, r, b, path, o ) {
var self = this,
url = GH.api + '/commits/list/' + u + '/' + r + '/' + b + path,
onData = o.onData;
o.onSuccess = function(res) {
var cs = res.responseText.commits;
// if(!cs) { alert('not found'); return;}
/* cache the commits */
self._cache[ url ] = cs;
onData( cs );
}
/* hit the cache first */
if( this._cache[ url ] ) {
onData( this._cache[ url ] );
return;
}
new JSP( url, o );
}
,show: function( u, r, sha, o ) {
var self = this,
url = GH.api + '/commits/show/' + u + '/' + r + '/' + sha,
onData = o.onData;
o.onSuccess = function(res) {
var c = res.responseText.commit;
/* cache */
self._cache[ sha ] = c;
onData( c );
}
/* hit the cache first */
if( this._cache[ sha ] ) {
onData( this._cache[ sha ] );
return;
}
new JSP( url, o );
}
}
,Tree: {
_cache: {}
,show: function( u, r, b, tree_sha, o ) {
var self = this,
url = GH.api + '/tree/show/' + u +'/' + r +'/' + tree_sha,
onData = o.onData;
o.onSuccess = function(res) {
var tree = res.responseText.tree;
// if(!tree) { alert('not found'); return;}
tree = tree.sort(function(a,b){
// blobs always lose to tree
if( a.type == 'blob' && b.type == 'tree' )
return 1;
if( a.type == 'tree' && b.type == 'blob' )
return -1;
return a.name > b.name ? 1 : ( a.name < b.name ? - 1 : 0 );
});
/* add the index to the item */
for( var i = 0, len = tree.length; i < len; i++ ) {
tree[i].index = i;
}
/* cache the tree so that we don't have to re-request every time */
self._cache[ tree_sha ] = tree;
onData(tree);
}
/* hit the cache first */
if( this._cache[ tree_sha ] ) {
onData( this._cache[ tree_sha ] );
return;
}
new JSP( url, o);
}
}
,Blob: {
show: function( u, r, sha, o ) {
var url = GH.api + '/blob/show/' + u + '/' + r + '/' + sha;
new AR( GH.proxy + url, o );
}
/**
* u,r,b: user, repo, branch
* fn: filename
* o: the options, with callback
*/
,loadPage: function(u,r,b,fn, o) {
var url = 'http://github.com/' + u + '/' + r + '/blob/' + b +'/' + fn;
new AR( GH.proxy + url, o );
}
}
,Repo: {
show: function( u, r, o ) {
var url = GH.api + '/repos/show/' + u + '/' + r,
onData = o.onData;
o.onSuccess = function(res) {
onData(res.responseText.repository);
}
new JSP( url, o );
}
,listBranches: function( u, r, o ) {
var url = GH.api + '/repos/show/' + u + '/' + r + '/branches',
onData = o.onData;
o.onSuccess = function(res) {
var branches = res.responseText.branches;
onData(branches);
}
new JSP( url, o );
}
}
,Raw: {
loadBlobAtCommit: function( u, r, commitId, path, options ) {
//http://github.com/:user_id/:repo/raw/:commit_id/:path
// http://github.com/mojombo/grit/raw/c0f0b4f7a62d2e563b48d0dc5cd9eb3c21e3b4c2/lib/grit.rb
url = 'https://github.com/' + u + '/' + r + '/raw/' + commitId + path;
new AR( GH.proxy + url, options );
}
}
};

View file

@ -0,0 +1,97 @@
var Keyboard = Class.create( PluginBase, {
initialize: function($super, f) {
// $super(f);
document.observe('keydown', function(e) {
if(e.findElement().tagName == 'INPUT') return; // user has focus in something, bail out.
// var k = e.which ? e.which : e.keyCode; // keycode
var k = e.which || e.keyCode; // keycode
var cI = f.cI,
pI = f.pI;
var p = f.ps[pI]; // panel
var t = p.tree; // the panel's tree
var d = function() {
if( t[ ++cI ] ) {
var item = t[cI];
// debugger
f.click( item.sha, $$('#p' + pI + ' a')[cI], true );
} else {
cI--;
}
};
var u = function() {
if( t[ --cI ] ) {
var item = t[cI];
f.click( item.sha, $$('#p' + pI + ' a')[cI], true );
} else {
cI++;
}
}
var l = function() {
if( f.ps[--pI] ) {
// debugger
t = f.ps[pI].tree;
// get index of the previously selected item
cI = f.ps[pI].cI;
// var item = f.ps[pI];
f.click( t[cI].sha, $$('#p' + pI + ' a')[cI], true );
} else {
pI++; // undo
}
}
var r = function() {
if( !t[cI] || t[cI].type != 'tree' ) return;
if( f.ps[++pI] ) {
t = f.ps[pI].tree;
cI = -1;
d(); // down!
} else {
pI--; // undo
}
}
// k == 40 ? d() : ( k == 39 ? r() : ( k == 38 ? u() : ( k == 37 ? l() : '';
switch( k ) {
case 40: // key down
d();
break;
case 38: // up
u();
break;
case 37: //left
l();
break
case 39: // right
r();
break;
default:
break;
}
// console.log("keypress");
if( k >= 37 && k <= 40)
e.stop();
});
}
});
/* add the plugin to the plugins list */
FP.push(Keyboard);

View file

@ -0,0 +1,41 @@
/* Panel */
window.P = Class.create({
initialize: function(f, options) {
this.f = f;
this.tree = options.tree || [];
this.index = options.index || 0 ;
this.name = options.name;
this.item = options.item;
this.r();
}
,dispose: function() {
$('p' + this.index ).remove();
this.p = null;
}
,r: function() {
this.f.psW.insert({ bottom: this.h() });
}
,h: function() {
var it, css, recent, ix=this.index, t=this.tree,bH = this.f.bW.offsetHeight,
h = '<ul class=files>';
for( var i = 0; i < t.length; i++ ) {
it = t[i];
h += '<li class=' + it.type + '>' +
'<span class="ico">' +
'<a href="#" data-sha="' + it.sha + '" data-name="' + it.name + '" onclick="return false">' +
it.name +
'</a>' +
'</span>'+
'</li>';
}
h += '</ul>';
return '<div id=p' + ix + ' data-index=' + ix +' class=panel style="height:' + bH +'px">' + h + '</div>';
}
});

View file

@ -0,0 +1,8 @@
;window.FP = []; // this array contains the list of all registered plugins
var PluginBase = Class.create( {
initialize: function(o) {
if( !this.mixin ) this.mixin = {};
Object.extend( o, this.mixin );
}
} );

View file

@ -0,0 +1,74 @@
/* code highliter */
var CH = Class.create( PluginBase, {
initialize: function($super, f) {
$super(f);
f.theme = 'Light';
// f.theme = 'Dark';
var hlt = CodeHighlighter;
var getFiletype = function(filename,text) {
var fileType,
matchingRules = {
'ruby': [ /\.rb$/i, /\.ru$/i, /\bRakefile\b/i, /\bGemfile\b/i, /\.gemspec\b/i, /\bconsole\b/i, /\.rake$/i ]
,'css': [ /\.css/i ]
,'html': [ /\.html?$/i, /\.aspx$/i, /\.php$/i, /\.erb$/i ]
,'javascript': [ /\.js$/i ]
,'python': [ /\.py$/i ]
,'applescript': [ /\.applescript$/i ]
,'yaml': [ /\.yml$/i ]
,'cpp': [ /\.c$/i, /\.cpp$/i, /\.h$/i ]
,'clojure': [ /\.clj$/i ]
,'haskell': [ /\.hs$/i ]
};
$H(matchingRules).each(function(type) {
for( var i = 0; i < type.value.length; i++ ) {
if( type.value[i].match(filename) ) {
fileType = type.key;
return;
}
}
} );
// debugger
/* attempt to futher detect the fileType */
if( !fileType ) {
text = text.replace(/\r\n/, "\n").split(/\n/)[0];
fileType = /ruby/i.test(text) ? 'ruby' :
/python/i.test(text) ? 'python' :
/php/i.test(text) ? 'php' :
'';
}
return fileType;
}
var old = f.previewTextFile;
f.previewTextFile = function( text, item ) {
old(text,item);
var codeEl = $('code');
codeEl.className = f.theme; // clear previous syntax class
codeEl.addClassName(getFiletype(item.name,text));
hlt.init();
}
}
/* add the link to the stylesheet */
// ,addStylesheet: function() {
// // <link href="css/code_highlighter.css" media="all" rel="stylesheet" type="text/css" />
// var css = document.createElement('link');
// css.href = 'css/code_highlighter.css';
// css.rel = 'stylesheet';
// css.type = 'text/css';
// document.body.appendChild(css);
// }
});
FP.push(CH);

View file

@ -0,0 +1,58 @@
/* make sure we have console */
/*
;if( typeof(console) == 'undefined' )
console = { log: function(){} };
*/
/* placeholder */
// var pH = function() {
// if( 'placeholder' in (document.createElement('input') ) )
// return;
//
// $$('input[placeholder]').each(function(i) {
// var t = i.readAttribute('placeholder');
// var f = function() {
// i.value.strip() == t ? i.value = '' : '';
// };
// i.on('focus', f);
//
// var b = function() {
// i.value.strip() == '' ? i.value = t : '';
// };
// i.on('blur', b);
// b();
// });
// };
/* Util stuff */
/* return a truncated sha */
var s = function(h) { return h.substr(0,6); };
/* truncate text to a minimum length, similar to the way Finder does it */
var t = function(s,l) {
var sl = s.length,
d = '...', // delimiter
dl = d.length,
r = (l - dl) / 2; // radius
return s.length < l ? s : s.substr(0, r) + d + s.substr( sl - r, sl);
}
/* parse URL Params as a hash with key are lowered case. (Doesn't handle duplicated key). */
var uP = function() {
var ps = [], pair, pairs,
url = window.location.href.split('?');
if( url.length == 1 ) return ps;
url = url[1].split('#')[0];
pairs = url.split('&');
for( var i = 0; i < pairs.length; i++ ) {
pair = pairs[i].split('=');
ps[ pair[0].toLowerCase() ] = pair[1];
}
return ps;
};

View file

@ -0,0 +1,394 @@
/* Unobtrustive Code Highlighter By Dan Webb 11/2005
Version: 0.4
Usage:
Add a script tag for this script and any stylesets you need to use
to the page in question, add correct class names to CODE elements,
define CSS styles for elements. That's it!
Known to work on:
IE 5.5+ PC
Firefox/Mozilla PC/Mac
Opera 7.23 + PC
Safari 2
Known to degrade gracefully on:
IE5.0 PC
Note: IE5.0 fails due to the use of lookahead in some stylesets. To avoid script errors
in older browsers use expressions that use lookahead in string format when defining stylesets.
This script is inspired by star-light by entirely cunning Dean Edwards
http://dean.edwards.name/star-light/.
*/
// replace callback support for safari.
if ("a".replace(/a/, function() {return "b"}) != "b") (function(){
var default_replace = String.prototype.replace;
String.prototype.replace = function(search,replace){
// replace is not function
if(typeof replace != "function"){
return default_replace.apply(this,arguments)
}
var str = "" + this;
var callback = replace;
// search string is not RegExp
if(!(search instanceof RegExp)){
var idx = str.indexOf(search);
return (
idx == -1 ? str :
default_replace.apply(str,[search,callback(search, idx, str)])
)
}
var reg = search;
var result = [];
var lastidx = reg.lastIndex;
var re;
while((re = reg.exec(str)) != null){
var idx = re.index;
var args = re.concat(idx, str);
result.push(
str.slice(lastidx,idx),
callback.apply(null,args).toString()
);
if(!reg.global){
lastidx += RegExp.lastMatch.length;
break
}else{
lastidx = reg.lastIndex;
}
}
result.push(str.slice(lastidx));
return result.join("")
}
})();
var CodeHighlighter = { styleSets : new Array };
CodeHighlighter.addStyle = function(name, rules) {
// using push test to disallow older browsers from adding styleSets
if ([].push) this.styleSets.push({
name : name,
rules : rules,
ignoreCase : arguments[2] || false
})
// function setEvent() {
// // set highlighter to run on load (use LowPro if present)
// if (typeof Event != 'undefined' && typeof Event.onReady == 'function')
// return Event.onReady(CodeHighlighter.init.bind(CodeHighlighter));
//
// var old = window.onload;
//
// if (typeof window.onload != 'function') {
// window.onload = function() { CodeHighlighter.init() };
// } else {
// window.onload = function() {
// old();
// CodeHighlighter.init();
// }
// }
// }
//
// // only set the event when the first style is added
// if (this.styleSets.length==1) setEvent();
}
CodeHighlighter.init = function() {
if (!document.getElementsByTagName) return;
if ("a".replace(/a/, function() {return "b"}) != "b") return; // throw out Safari versions that don't support replace function
// throw out older browsers
// var codeEls = document.getElementsByTagName("CODE");
// HACK:
var codeEls = [$('code')];
// collect array of all pre elements
codeEls.filter = function(f) {
var a = new Array;
for (var i = 0; i < this.length; i++)
if (f(this[i]))
a[a.length] = this[i];
return a;
}
var rules = new Array;
rules.toString = function() {
// joins regexes into one big parallel regex
var exps = new Array;
for (var i = 0; i < this.length; i++) exps.push(this[i].exp);
return exps.join("|");
}
function addRule(className, rule) {
// add a replace rule
var exp = (typeof rule.exp != "string")?String(rule.exp).substr(1, String(rule.exp).length-2):rule.exp;
// converts regex rules to strings and chops of the slashes
rules.push({
className : className,
exp : "(" + exp + ")",
length : (exp.match(/(^|[^\\])\([^?]/g) || "").length + 1, // number of subexps in rule
replacement : rule.replacement || null
});
}
function parse(text, ignoreCase) {
// main text parsing and replacement
return text.replace(new RegExp(rules, (ignoreCase)?"gi":"g"), function() {
var i = 0, j = 1, rule;
while (rule = rules[i++]) {
if (arguments[j]) {
// if no custom replacement defined do the simple replacement
if (!rule.replacement) return "<span class=\"" + rule.className + "\">" + arguments[0] + "</span>";
else {
// replace $0 with the className then do normal replaces
var str = rule.replacement.replace("$0", rule.className);
for (var k = 1; k <= rule.length - 1; k++) str = str.replace("$" + k, arguments[j + k]);
return str;
}
} else j+= rule.length;
}
});
}
function highlightCode(styleSet) {
// clear rules array
var parsed, clsRx = new RegExp("(\\s|^)" + styleSet.name + "(\\s|$)");
rules.length = 0;
// // get stylable elements by filtering out all code elements without the correct className
var stylableEls = codeEls.filter(function(item) { return clsRx.test(item.className) });
// var stylableEls = codeEls;
// add style rules to parser
for (var className in styleSet.rules) addRule(className, styleSet.rules[className]);
// replace for all elements
for (var i = 0; i < stylableEls.length; i++) {
// EVIL hack to fix IE whitespace badness if it's inside a <pre>
if (/MSIE/.test(navigator.appVersion) && stylableEls[i].parentNode.nodeName == 'PRE') {
stylableEls[i] = stylableEls[i].parentNode;
parsed = stylableEls[i].innerHTML.replace(/(<code[^>]*>)([^<]*)<\/code>/i, function() {
return arguments[1] + parse(arguments[2], styleSet.ignoreCase) + "</code>"
});
parsed = parsed.replace(/\n( *)/g, function() {
var spaces = "";
for (var i = 0; i < arguments[1].length; i++) spaces+= "&nbsp;";
return "\n" + spaces;
});
parsed = parsed.replace(/\t/g, "&nbsp;&nbsp;&nbsp;&nbsp;");
parsed = parsed.replace(/\n(<\/\w+>)?/g, "<br />$1").replace(/<br \/>[\n\r\s]*<br \/>/g, "<p><br></p>");
} else parsed = parse(stylableEls[i].innerHTML, styleSet.ignoreCase);
stylableEls[i].innerHTML = parsed;
}
}
// run highlighter on all stylesets
for (var i=0; i < this.styleSets.length; i++) {
highlightCode(this.styleSets[i]);
}
}
CodeHighlighter.addStyle("css", {
comment : {
exp : /\/\*[^*]*\*+([^\/][^*]*\*+)*\//
},
keywords : {
exp : /@\w[\w\s]*/
},
selectors : {
exp : "([\\w-:\\[.#][^{};>]*)(?={)"
},
properties : {
exp : "([\\w-]+)(?=\\s*:)"
},
units : {
exp : /([0-9])(em|en|px|%|pt)\b/,
replacement : "$1<span class=\"$0\">$2</span>"
},
urls : {
exp : /url\([^\)]*\)/
}
});
CodeHighlighter.addStyle("ruby",{
comment : {
exp : /#[^\n]*/
},
brackets : {
exp : /\(|\)/
},
string : {
exp : /'[^'\\]*(\\.[^'\\]*)*'|"[^"\\]*(\\.[^"\\]*)*"|\%w\(.*\)|`[^`\\]*(\\.[^`\\]*)*`/
},
keywords : {
exp : /\b(do|end|self|class|def|if|module|yield|then|else|for|until|unless|while|elsif|case|when|break|retry|redo|rescue|require|raise|extend)\b/
},
/* Added by Shelly Fisher (shelly@agileevolved.com) */
symbol : {
exp : /([^:])(:[A-Za-z0-9_!?]+)/
}
});
CodeHighlighter.addStyle("html", {
comment : {
exp: /<!\s*(--([^-]|[\r\n]|-[^-])*--\s*)>/
},
tag : {
exp: /(<\/?)([a-zA-Z1-9]+\s?)/,
replacement: "$1<span class=\"$0\">$2"
},
string : {
exp : /'[^']*'|"[^"]*"/
},
attribute : {
exp: /\b([a-zA-Z-:]+)(=)/,
replacement: "<span class=\"$0\">$1$2"
},
doctype : {
exp: /<!DOCTYPE([^&]|&[^g]|&g[^t])*>/
}
});
CodeHighlighter.addStyle("javascript",{
comment : {
exp : /(\/\/[^\n]*(\n|$))|(\/\*[^*]*\*+([^\/][^*]*\*+)*\/)/
},
parameter: {
exp: /\bfunction\s?\((.+)\)/
// ,replacement: "<span class='parameter'>$1</span>"
},
brackets : {
exp : /\(|\)/
},
string : {
exp : /'[^']*'|"[^"]*"/
},
keywords : {
exp : /\b(arguments|break|case|continue|default|delete|do|else|false|for|function|if|in|instanceof|new|null|return|switch|this|true|typeof|var|void|while|with)\b/
},
global : {
exp : /\b(toString|valueOf|window|element|prototype|constructor|document|escape|unescape|parseInt|parseFloat|setTimeout|clearTimeout|setInterval|clearInterval|NaN|isNaN|Infinity|String|Numeric|Array)\b/
}
});
CodeHighlighter.addStyle("yaml", {
keyword : {
exp : /\/\*[^*]*\*+([^\/][^*]*\*+)*\//
},
value : {
exp : /@\w[\w\s]*/
}
});
CodeHighlighter.addStyle("python",{
comment : {
exp : /#[^\n]+/
},
brackets : {
exp : /\(|\)/
},
string : {
exp : /'[^'\\]*(\\.[^'\\]*)*'|"[^"\\]*(\\.[^"\\]*)*"|""".*"""/
},
keywords : {
exp : /\b(and|assert|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|not|or|pass|print|raise|return|try|while|yield|as|None)\b/
}
});
CodeHighlighter.addStyle("applescript",{
comment : {
exp : /--[^\n]+|#![^\n]+/
},
brackets : {
exp : /\(|\)/
},
string : {
exp : /"[^"\\]*(\\.[^"\\]*)*"/
},
keywords : {
exp : /\b(about|above|after|against|and|apart[\s]+from|around|as|aside[\s]+from|at|back|before|beginning|behind|below|beneath|beside|between|but|by|considering|contain|contains|contains|continue|copy|div|does|eighth|else|end|equal|equals|error|every|exit|false|fifth|first|for|fourth|from|front|get|given|global|if|ignoring|in|instead[\s]+of|into|is|it|its|last|local|me|middle|mod|my|ninth|not|of|on|onto|or|out[\s]+of|over|prop|property|put|ref|reference|repeat|return|returning|script|second|set|seventh|since|sixth|some|tell|tenth|that|the|then|third|through|thru|timeout|times|to|transaction|true|try|until|where|while|whose|with|without)\b/
},
global : {
exp : /\b(AppleScript('s)?|current[\s]+application|missing[\s]+value|false|pi|true|version)\b/
}
});
CodeHighlighter.addStyle("cpp",{
comment : {
exp : /(\/\/[^\n]*(\n|$))|(\/\*[^*]*\*+([^\/][^*]*\*+)*\/)/
},
brackets : {
exp : /\(|\)/
},
string : {
exp : /"[^"\\]*(\\.[^"\\]*)*"/
},
keywords : {
exp : /\b(break|case|catch|class|const|__finally|__exception|__try|const_cast|continue|private|public|protected|__declspec|default|delete|deprecated|dllexport|dllimport|do|dynamic_cast|else|enum|explicit|extern|if|for|friend|goto|inline|mutable|naked|namespace|new|noinline|noreturn|nothrow|register|reinterpret_cast|return|selectany|sizeof|static|static_cast|struct|switch|template|this|thread|throw|true|false|try|typedef|typeid|typename|union|using|uuid|virtual|void|volatile|whcar_t|while)\b/
},
datatype: {
exp : /\b(ATOM|BOOL|BOOLEAN|BYTE|CHAR|COLORREF|DWORD|DWORDLONG|DWORD_PTR|DWORD32|DWORD64|FLOAT|HACCEL|HALF_PTR|HANDLE|HBITMAP|HBRUSH|HCOLORSPACE|HCONV|HCONVLIST|HCURSOR|HDC|HDDEDATA|HDESK|HDROP|HDWP|HENHMETAFILE|HFILE|HFONT|HGDIOBJ|HGLOBAL|HHOOK|HICON|HINSTANCE|HKEY|HKL|HLOCAL|HMENU|HMETAFILE|HMODULE|HMONITOR|HPALETTE|HPEN|HRESULT|HRGN|HRSRC|HSZ|HWINSTA|HWND|INT|INT_PTR|INT32|INT64|LANGID|LCID|LCTYPE|LGRPID|LONG|LONGLONG|LONG_PTR|LONG32|LONG64|LPARAM|LPBOOL|LPBYTE|LPCOLORREF|LPCSTR|LPCTSTR|LPCVOID|LPCWSTR|LPDWORD|LPHANDLE|LPINT|LPLONG|LPSTR|LPTSTR|LPVOID|LPWORD|LPWSTR|LRESULT|PBOOL|PBOOLEAN|PBYTE|PCHAR|PCSTR|PCTSTR|PCWSTR|PDWORDLONG|PDWORD_PTR|PDWORD32|PDWORD64|PFLOAT|PHALF_PTR|PHANDLE|PHKEY|PINT|PINT_PTR|PINT32|PINT64|PLCID|PLONG|PLONGLONG|PLONG_PTR|PLONG32|PLONG64|POINTER_32|POINTER_64|PSHORT|PSIZE_T|PSSIZE_T|PSTR|PTBYTE|PTCHAR|PTSTR|PUCHAR|PUHALF_PTR|PUINT|PUINT_PTR|PUINT32|PUINT64|PULONG|PULONGLONG|PULONG_PTR|PULONG32|PULONG64|PUSHORT|PVOID|PWCHAR|PWORD|PWSTR|SC_HANDLE|SC_LOCK|SERVICE_STATUS_HANDLE|SHORT|SIZE_T|SSIZE_T|TBYTE|TCHAR|UCHAR|UHALF_PTR|UINT|UINT_PTR|UINT32|UINT64|ULONG|ULONGLONG|ULONG_PTR|ULONG32|ULONG64|USHORT|USN|VOID|WCHAR|WORD|WPARAM|WPARAM|WPARAM|char|bool|short|int|__int32|__int64|__int8|__int16|long|float|double|__wchar_t|clock_t|_complex|_dev_t|_diskfree_t|div_t|ldiv_t|_exception|_EXCEPTION_POINTERS|FILE|_finddata_t|_finddatai64_t|_wfinddata_t|_wfinddatai64_t|__finddata64_t|__wfinddata64_t|_FPIEEE_RECORD|fpos_t|_HEAPINFO|_HFILE|lconv|intptr_t|jmp_buf|mbstate_t|_off_t|_onexit_t|_PNH|ptrdiff_t|_purecall_handler|sig_atomic_t|size_t|_stat|__stat64|_stati64|terminate_function|time_t|__time64_t|_timeb|__timeb64|tm|uintptr_t|_utimbuf|va_list|wchar_t|wctrans_t|wctype_t|wint_t|signed)\b/
},
preprocessor : {
exp : /^ *#.*/gm
}
});
// http://www.undermyhat.org/blog/wp-content/uploads/2009/09/shBrushClojure.js
CodeHighlighter.addStyle("clojure",{
comment : {
exp : /;[^\]]+$/
},
string : {
exp : /"[^"\\]*(\\.[^"\\]*)*"/m
},
functions : {
exp : /\b(:arglists|:doc|:file|:line|:macro|:name|:ns|:private|:tag|:test|new|alias|alter|and|apply|assert|class|cond|conj|count|def|defmacro|defn|defstruct|deref|do|doall|dorun|doseq|dosync|eval|filter|finally|find|first|fn|gen-class|gensym|if|import|inc|keys|let|list|loop|map|ns|or|print|println|quote|rand|recur|reduce|ref|repeat|require|rest|send|seq|set|sort|str|struct|sync|take|test|throw|trampoline|try|type|use|var|vec|when|while)\b/gmi
},
keyword : {
exp : /\[|\]/g
},
symbols : {
exp : /'[a-z][A-Za-z0-9_]*/g
},
keywords: {
exp: /(:[a-z][A-Za-z0-9_]*)/g
}
});
CodeHighlighter.addStyle("haskell",{
comment : {
exp : /(\-\-.*$)|(\{\-[\s\S]*?\-\})/gm
},
keywords : {
exp : /\b(as|case|of|class|data|datafamily|data instance|default|deriving|deriving instance|do|forall|foreign|hiding|if|then|else|import|infix|infixl|infixr|instance|let|in|mdo|module|newtype|proc|qualified|rec|type|type family|type instance|where)\b/
},
string : {
exp : /'[^']*'|"[^"]*"/
}
});

View file

@ -0,0 +1,113 @@
// See an updated version of this in it's own git repo:
// http://github.com/dandean/Ajax.JSONRequest
/* JSON-P implementation for Prototype.js somewhat by Dan Dean (http://www.dandean.com)
*
* *HEAVILY* based on Tobie Langel's version: http://gist.github.com/145466.
* Might as well just call this an iteration.
*
* This version introduces:
* - onCreate and onFailure callback options.
* - option to not invoke request upon instantiation.
*
* Tested in Firefox 3/3.5, Safari 4
*
* Note: while I still think JSON-P is an inherantly flawed technique,
* there are some valid use cases which this can provide for.
*
* See examples below for usage.
*/
window.JSP = Class.create(Ajax.Base, (function() {
var id = 0, head = document.getElementsByTagName('head')[0];
return {
initialize: function($super, url, options) {
$super(options);
this.options.url = url;
this.options.callbackParamName = this.options.callbackParamName || 'callback';
this.options.timeout = this.options.timeout || 10000; // Default timeout: 10 seconds
this.options.invokeImmediately = (!Object.isUndefined(this.options.invokeImmediately)) ? this.options.invokeImmediately : true ;
this.responseJSON = {};
if (this.options.invokeImmediately) {
this.request();
}
Ajax.Responders.dispatch('onCreate', this);
},
/**
* Ajax.JSONRequest#_cleanup() -> "undefined"
*
* Cleans up after the request
**/
_cleanup: function() {
if (this.timeout) {
clearTimeout(this.timeout);
this.timeout = null;
}
if (this.script && Object.isElement(this.script)) {
this.script.remove();
this.script = null;
}
},
/**
* Ajax.JSONRequest#request() -> "undefined"
*
* Invokes the JSON-P request lifecycle
**/
request: function() {
// Define local vars
var key = this.options.callbackParamName,
name = '_prototypeJSONPCallback_' + (id++);
// Add callback as a parameter and build request URL
this.options.parameters[key] = name;
var url = this.options.url + ((this.options.url.include('?') ? '&' : '?') + Object.toQueryString(this.options.parameters));
// Define callback function
window[name] = function(response) {
this._cleanup(); // Garbage collection
window[name] = undefined;
if( typeof(response) == 'Object' )
this.responseJSON = response;
else
this.responseText = response;
try {
Ajax.Responders.dispatch('onComplete', this, response);
if (Object.isFunction(this.options.onComplete)) {
this.options.onComplete.call(this, this);
}
if (Object.isFunction(this.options.onSuccess)) {
this.options.onSuccess.call(this,this);
}
} catch( ex ) {
Ajax.Responders.dispatch('onException', this, ex);
throw ex;
}
}.bind(this);
this.script = new Element('script', { type: 'text/javascript', src: url });
if (Object.isFunction(this.options.onCreate)) {
this.options.onCreate.call(this, this);
}
head.appendChild(this.script);
this.timeout = setTimeout(function() {
this._cleanup();
window[name] = Prototype.emptyFunction;
if (Object.isFunction(this.options.onFailure)) {
this.options.onFailure.call(this, this);
}
}.bind(this), this.options.timeout);
}
};
})());

60
GithubFinder/proxy.php Normal file
View file

@ -0,0 +1,60 @@
<?php
/* http://www.itbsllc.com/zip/proxyscripts.html */
// PHP Proxy
// Responds to both HTTP GET and POST requests
//
// Author: Abdul Qabiz
// March 31st, 2006
//
// Get the url of to be proxied
// Is it a POST or a GET?
$url = ($_POST['url']) ? $_POST['url'] : $_GET['url'];
$jsoncallback = ($_POST['callback']) ? $_POST['callback'] : $_GET['callback'];
$allowed_domain = 'http://github.com';
// echo strpos( $url, $allowed_domain );
if( strpos( $url, $allowed_domain ) === false )
die();
$headers = ($_POST['headers']) ? $_POST['headers'] : $_GET['headers'];
$mimeType =($_POST['mimeType']) ? $_POST['mimeType'] : $_GET['mimeType'];
//Start the Curl session
$session = curl_init($url);
// If it's a POST, put the POST data in the body
if ($_POST['url']) {
$postvars = '';
while ($element = current($_POST)) {
$postvars .= key($_POST).'='.$element.'&';
next($_POST);
}
curl_setopt ($session, CURLOPT_POST, true);
curl_setopt ($session, CURLOPT_POSTFIELDS, $postvars);
}
// Don't return HTTP headers. Do return the contents of the call
curl_setopt($session, CURLOPT_HEADER, ($headers == "true") ? true : false);
curl_setopt($session, CURLOPT_FOLLOWLOCATION, true);
//curl_setopt($ch, CURLOPT_TIMEOUT, 4);
curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
// Make the call
$response = curl_exec($session);
if ($mimeType != "")
{
// The web service returns XML. Set the Content-Type appropriately
header("Content-Type: ".$mimeType);
}
if( $jsoncallback )
echo $jsoncallback . "(" . json_encode($response) . ")";
else
echo $response;
curl_close($session);
?>

70
GithubFinder/styles.css Normal file
View file

@ -0,0 +1,70 @@
#gh-finder { font-size: 12px; font-family: Helvetica, Verdana, sans-serif; margin: 3em auto 1em; padding: 0; width: 92% }
#gh-finder .clear { clear:both }
#gh-finder a { color: #22a; text-decoration: none; border-bottom: none }
#gh-finder a:active { outline: none }
#gh-finder :focus { -moz-outline-style: none; outline: none;}
#gh-finder .p { padding: 10px; }
#gh-finder img { border: 0px}
#finder { width: 100%; overflow: hidden; height: 343px }
#r_w { width: 100%; background-color: #EAEAEA; border-bottom: 1px solid #CCC }
.tbb { border-bottom: 3px solid #CCC;} /* thick bottom border */
/* logo */
.big { font-size: 14px; font-weight: bold;}
#r_w { -moz-border-radius-topright: 7px; -webkit-border-top-right-radius: 7px; border-top-right-radius: 7px;
-moz-border-radius-topleft: 7px; -webkit-border-top-left-radius: 7px; border-top-left-radius: 7px
}
#in { color: transparent; padding: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px }
#in.on { background-color: #4F4A45; color: white }
#b_w { overflow: hidden; overflow-x: auto; height: 300px }
.panel { float: left; width: 200px; border-right: 1px solid #CCC; overflow: hidden; overflow-y: auto;
height: 300px }
.files { padding: 0; margin: 0; font-size: 1.3em }
.files li { list-style:none outside none; border-bottom: 1px solid #CCC; background-color: #F8F8F8; }
.t { padding: 10px; border-bottom: 1px solid #CCC; font-size: 14px; font-weight: bold} /* title */
.tree { background: #F8F8F8 url('./img/la.gif') no-repeat 95% 50%; font-weight: bold; }
.ico { background:url('./img/txt.gif') no-repeat 3px 50%; display: block;}
.tree .ico { background-image: url('./img/dir.gif'); }
.cur { background: #3D8CFF url('./img/la_h.gif') no-repeat 95% 50% !important;}
#gh-finder .cur a { color: white;}
.blob { background-image: none !important; }
.files a { padding: 8px 8px 8px 23px; display:block; }
#f_c_w .p {padding: 10px}
#f_c { overflow: hidden; }
#f_c_s { overflow-y: auto; }
#f { border: 1px solid #CCC; }
#commits .big { padding: 10px; border-bottom: 1px solid #CCC;}
/* commit entry */
.ce { padding: 10px 0; border-bottom: 1px solid #CCC; }
pre, #code, .meta, .diff { font:12px Monaco,monospace; margin: 0; }
.meta, .diff thead th { background-color: #EEE; color:#333; overflow:hidden; padding:10px; border-bottom: 1px solid #CCC}
.meta span { margin-left: 5px; padding-left: 9px;}
.meta span:first-child { display: none }
.ln, .diff th { background-color:#ECECEC; border-right:1px solid #DDD; color:#AAA; text-align: right; padding: 5px 5px }
#code { padding: 5px;}
/*.hover { background-color: #FFFFC7; }*/
.insert { background-color:#9E9 }
#footer { padding: 10px }
/* extension stuff */
.resize { cursor: col-resize; float: left; background-color: #DCDCDC;border-right: 1px solid #CCC;}
.hrz { cursor: row-resize !important; background-color: #DCDCDC; ;border-bottom: 1px solid #CCC;height: 3px; line-height: 3px; width: 99.9%}
#bml_w { float: right; font-size: 11px; width: 300px;}
.bml { border: 1px solid #CCC; padding: 1px; -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px; font-weight: bold;}
.bml:hover { background-color: white;}

View file

@ -1,3 +1,8 @@
#browse { text-align: center
; font-size: 1.4em
; margin: 1.6em
}
#info { text-align: center
; margin: 1em auto
; padding: 1em

View file

@ -6,6 +6,7 @@
var global = this
global.SJS = {
proj: function(name) {
SJS.projName = name
var data = createObjectStore(name)
if (document.addEventListener) {
document.addEventListener('DOMContentLoaded', ready, false)

View file

@ -37,38 +37,38 @@ a.img { border: none }
; text-decoration: underline
}
ul { text-align: center
; margin: 0 auto
; padding: 1em
; border: solid 1px #ccc
; width: 90%
; max-width: 950px
; background-color: #fff
; -moz-border-radius: 20px
; -webkit-border-radius: 20px
; border-radius: 20px
; behavior: url(assets/border-radius.htc)
; behavior: url(../assets/border-radius.htc)
}
ul.nav { text-align: center
; margin: 0 auto
; padding: 1em
; border: solid 1px #ccc
; width: 90%
; max-width: 950px
; background-color: #fff
; -moz-border-radius: 20px
; -webkit-border-radius: 20px
; border-radius: 20px
; behavior: url(assets/border-radius.htc)
; behavior: url(../assets/border-radius.htc)
}
li { display: inline
; font-size: 1.6em
; margin: 0
; padding: 0
}
ul.nav li { display: inline
; font-size: 1.6em
; margin: 0
; padding: 0
}
li:after { content: ' •' }
li:last-child:after { content: '' }
ul.nav li:after { content: ' •' }
ul.nav li:last-child:after { content: '' }
li a { padding: 5px
; text-shadow: #999 5px 5px 5px
; -webkit-transition: all 0.5s ease-out
}
li a:visited { color: #227 }
ul.nav li a { padding: 5px
; text-shadow: #999 5px 5px 5px
; -webkit-transition: all 0.5s ease-out
}
ul.nav li a:visited { color: #227 }
li a:hover,
li a:active { color: #000
ul.nav li a:hover,
ul.nav li a:active { color: #000
; text-shadow: #aa7 5px 5px 5px
; border-bottom: dashed 1px #000
}
@ -81,10 +81,10 @@ ul#projects li { display: block
; line-height: 1.8em
}
li.ie-bullet,
ul.nav li.ie-bullet,
ul#projects li.ie-bullet { display: none }
li.last:after,
ul.nav li.last:after,
ul#projects li:after { content: '' }
footer { text-align: center
@ -124,17 +124,17 @@ td:nth-child(2) { padding: 0 10px }
@media only screen and (orientation:portrait) and (device-height:1024px),
only screen and (max-device-width:480px)
{
ul { padding: 0.5em
; width: 70%
; max-width: 400px
}
ul.nav ul { padding: 0.5em
; width: 70%
; max-width: 400px
}
li { display: block
; font-size: 1.5em
; line-height: 1.6em
}
ul.nav li { display: block
; font-size: 1.5em
; line-height: 1.6em
}
li:after { content: '' }
ul.nav li:after { content: '' }
}
/* iPhone */
@ -147,7 +147,7 @@ td:nth-child(2) { padding: 0 10px }
#breadcrumbs { font-size: 0.8em }
li { font-size: 1.2em }
ul.nav li { font-size: 1.2em }
td { font-size: 1em
; line-height: 1.1em

View file

@ -28,7 +28,7 @@
<h1>samhuri.net</h1>
</header>
<nav>
<ul>
<ul class=nav>
<li><a href=proj>projects</a></li>
<li class=ie-bullet>&bull;</li>
<li><a href=blog>blog</a></li>

View file

@ -104,7 +104,7 @@
<header>
<h1>projects</h1>
</header>
<ul id=projects>
<ul class=nav id=projects>
{{#names}}
<li><a href={{.}}>{{.}}</a></li>
<li class=ie-bullet>&bull;</li>

View file

@ -4,6 +4,8 @@
<meta name=viewport content=width=device-width>
<title>{{name}} :: samhuri.net</title>
<link rel=icon type=image/gif href=../../assets/s.gif>
<link rel=stylesheet href=../../GithubFinder/styles.css>
<link rel=stylesheet href=../../GithubFinder/css/code_highlighter.css>
<link rel=stylesheet href=../../assets/proj-all.min.css>
<script>
var _gaq = _gaq || [];
@ -22,7 +24,36 @@
<script src=../../assets/storage-polyfill.min.js></script>
<![endif]-->
<script src=../../assets/proj-all.min.js></script>
<script> SJS.proj('{{name}}') </script>
<script src=http://ajax.googleapis.com/ajax/libs/prototype/1.6.1.0/prototype.js></script>
<script src=../../GithubFinder/javascripts/util.js></script>
<script src=../../GithubFinder/javascripts/vendors/jsonp.js></script>
<script src=../../GithubFinder/javascripts/gh.js></script>
<script src=../../GithubFinder/javascripts/p.js></script>
<script src=../../GithubFinder/javascripts/f.js></script>
<script src=../../GithubFinder/javascripts/plugins/base.js></script>
<script src=../../GithubFinder/javascripts/keyboard.js></script>
<script src=../../GithubFinder/javascripts/plugins/code_highlighter.js></script>
<script src=../../GithubFinder/javascripts/vendors/code_highlighter.js></script>
<script>
(function() {
SJS.proj('compiler')
if (document.addEventListener) {
document.addEventListener('DOMContentLoaded', ready, false)
} else if (window.attachEvent) {
window.attachEvent('onload', ready)
}
function ready() {
var bl = document.getElementById('browse-link')
bl.onclick = function() {
document.getElementById('browse').style.display = 'none'
GH.setProxy('http://samhuri.net/GithubFinder/proxy.php?url=')
var f = new F({ user_id: 'samsonjs', repository: 'compiler', id: 'gh-finder' })
return false
}
}
}())
</script>
</head>
<nav id=breadcrumbs><a href=../../>samhuri.net</a> &rarr; <a href=../>projects</a></nav>
<a href=https://github.com/samsonjs/{{name}}><img id=forkme src=../../assets/forkme.png alt="Fork me on GitHub"></a>
@ -50,6 +81,8 @@
</div>
<br class=clear>
</div>
<div id=browse><a id=browse-link href=#>browse project</a></div>
<div id=gh-finder></div>
<footer>
<a href=https://twitter.com/_sjs>@_sjs</a>
</footer>