Skip to content

Instantly share code, notes, and snippets.

@jacortinas
Created February 11, 2011 05:33
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jacortinas/821969 to your computer and use it in GitHub Desktop.
Save jacortinas/821969 to your computer and use it in GitHub Desktop.
A javascript solution to the github-challenge by integrum
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.cdnjs.com/ajax/libs/underscore.js/1.1.4/underscore-min.js"></script>
</head>
<body>
<p id="loading_msg">Loading...</p>
<script type="text/javascript">
/* To being with, just in case the "$" is already taken in the global scope
* this declaration of the jQuery dom loaded handler, reassigns it to the bling
* within the scope of the function. */
jQuery(function($){
/* Use underscore.js templating to render the final html output.
* This also removes the loading message. */
function render_commits(grouped_data){
/* Cache the loading message element, it's called in a loop a little later.
* If it weren't cached, then it would have to re-query the DOM on every iteration. */
var loading_msg = $('#loading_msg');
/* Using a built-in templating feature in underscore.js, has ERB like
* syntax, but allows javascript execution inside. This is a part I
* don't particularly like. Tt seems way to dense in my opinion, but this
* is what I got it to look like, after I tried to clean it up. :-| */
var author_template = _.template(
'<h1><%= name %></h1>' +
'<ul><% _.each(commits, function(commit){ %>' +
'<li>Commit: <%= commit.id %><br /><%= commit.message %></li>' +
'<% }); %></ul>'
);
/* For each item, append the compiled template before the loading message */
_.each(grouped_data, function(data){
loading_msg.before(author_template(data));
});
// NOW REMOVE THE MESSAGE OF LOADING
loading_msg.remove();
}
/* Taken from the prototype.js library, this replace ampersands,
* greater than, and less than, characters. Not for security, but for
* the protection of the DOM structure of the containing elements.
* Adding a little more explanation of this, there were some html element
* in the commit messages from the rails/rails. Without escaping those
* elements like this, they DESTROYED the DOM structure of their containing
* elements. Like I said above, this is NOT a security solution though, it's
* very easy to encode html tags using hexadecimal or some other encoding. */
function html_escape(str){
return str.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
}
/* Here we use the builtin support for JSONP in jQuery to grab the json
* data of rails commits, from Github's API. */
$.ajax({
url: 'http://github.com/api/v2/json/commits/list/rails/rails/master',
dataType: 'jsonp',
success: function(data){
/* Where we will store our "massaged" commits */
var grouped_data = [];
/* Grouping algorithm is loosely based on the rubinious's group_by algorithm on hashes.
* https://github.com/evanphx/rubinius/blob/master/kernel/common/enumerable.rb#L493 */
_.each(data.commits, function(commit){
/* idx is referring the index of the object within grouped_data that has
* a 'name' property that matches commit.author.name. */
var idx = _.indexOf(_.pluck(grouped_data, 'name'), commit.author.name);
/* idx >= 0 means that the object referring to a specific commit.author is already
* in the grouped_data array. In that case we just push the current commit to the
* end of the grouped_data[idx].commits array. */
if (idx >= 0) {
grouped_data[idx].commits.push({id: commit.id, message: html_escape(commit.message)});
} else {
/* Push a new object for a specific author to the grouped_data array */
grouped_data.push({
name: commit.author.name,
commits: [{
id: commit.id, message: html_escape(commit.message)
}]
});
}
});
/* Render the data to the document */
render_commits(grouped_data);
}
});
});
</script>
</body>
</html>
[
{
'name': 'authorname',
'commits': [
{'id': 'gitsha1', 'message': 'htmlescapedcommitmessage'},
{'id': 'blah', 'message': 'blahblahblabhlabhrailsblah'},
{...}
]
},
{...}
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment