/** * Gitstat.js * * A freely available library/widget/script/whatever * that pulls down data from Github about a repository and * displays the latest commits, along with a few other nice stats. * * This script is needlessly documented; if you're a veteran JS developer a lot * of the comments in here will seem useless to you, but to people who are still trying * to learn the language some of this stuff isn't easy to figure out, so I prefer to try * and let them have ample documentation to learn from. ;) * * @Author: Ryan McGrath | http://twitter.com/ryanmcgrath * @Requires: Nothing, completely stand-alone (because, y'know, nobody NEEDS jQuery ;P) */ ;(function(existing_gitstatus) { /** * If this script hasn't already been run once, we're fine to create this object and so forth; we only * want this to happen once to avoid potential overhead (however minimal). */ if(existing_gitstatus !== 'undefined') return; /** * new GitStatus(opts); * * The main object that we'll instantiate for each badge. Every instance of this will have its own routines * that run for it. We accept the "opts" as an object (or hash), and just store it for later use. Opts can have * a few parameters, take note. * * @param opts - An object/hash with various settings that get thrown onto the widget at render time. * :id - String (required). The id of the HTML node to inject this widget into. * :disable_tyles - Boolean (optional). Disables all attempts at CSS styling by this widget and leaves it up to the user. * :github_username - String (required). The username of the person who owns the repository we're going to pull down data about. * :github_repository - String (required). The name of the repository to pull down data about. * * @returns object (instantiated GitStatus) */ var GitStatus = window.GitStatus = function GitStatus(opts) { this.opts = opts; if(typeof this.opts.no_of_commits === 'undefined') this.opts.no_of_commits = 5; }; /** * GitStatus.util * * A general purpose dumping ground for utility functions (function-scope binding, JSON-P, etc). */ GitStatus.util = { /** * Some flags for debugging that we might consider wanting down the road. Nothing too fancy, but worth * having (should make life a wee bit easier down the road). */ DEBUG: false, /** * GitStatus.util.bind(bindReference, fn) * * Takes a reference (an object to scope to "this" at a later runtime) and binds it to a function (fn). * * @param bindReference - An object to set as the "this" reference for a later function call. * @param fn - A function to bind the "this" object for. * @returns fn - A new function to pass around, wherein it's all scoped as you want it. */ bind: function(bindReference, fn) { return function() { return fn.apply(bindReference, arguments); }; }, /** * GitStatus.util.loadScript(src, optional_callbackfn) * * Handles pulling down script tags, accepts an optional callback function that will * fire when the script fires its ready event (Note: this is NOT a JSON-P callback, see the next function for that). * * @param src - Required, the source URI for the script we're gonna toss onto the page. * @param optional_callbackfn - Optional, a callback function that will execute once this script is done. * @returns - void (nothing) */ loadScript: function(src, optional_callbackfn) { var newScript = document.createElement("script"); newScript.type = "text/javascript"; newScript.setAttribute("src", src); /** * For newer browsers that support this, we're fine to set this - it's basically stating * that we don't have any dependencies here to worry about and we're fine to let this go * out on its own and report back when done. * * If you were to have a dependency situation, you'd probably end up chaining loadScript callbacks to * achieve your desired order. */ newScript.setAttribute("async", "true"); /** * Automagically handle cleanup of injected script tags, so we don't litter someone's DOM * with our stuff. This branches for obvious reasons - i.e, IE. */ if(newScript.readyState) { newScript.onreadystatechange = function() { if(/loaded|complete/.test(newScript.readyState)) { newScript.onreadystatechange = null; if(typeof optional_callbackfn !== "undefined") optional_callbackfn(); !GitStatus.util.DEBUG && newScript && document.documentElement.firstChild.removeChild(newScript); } } } else { newScript.addEventListener("load", function() { if(typeof optional_callbackfn !== "undefined") optional_callbackfn(); !GitStatus.util.DEBUG && newScript && document.documentElement.firstChild.removeChild(newScript); }, false); } /** * Install it in an easy to retrieve place (that's also consistent - god forbid, someone might be using frames somewhere...?). */ document.documentElement.firstChild.appendChild(newScript); }, /** * GitStatus.util.jsonp(src, callbackfn, optional_scope, optional_fn_name) * * JSON-P function; fetches an external resource via a dynamically injected