works in Chrome 7 and Safari 5

This commit is contained in:
Sami Samhuri 2010-11-08 22:33:59 -08:00
parent 0045038619
commit b0254932d0

View file

@ -7,13 +7,15 @@
// TODO: // TODO:
// - authentication and write APIs // - authentication and write APIs
// - run in browsers (dojo?)
var request = require('request') (function() {
, util = require('util') var global = this
, isBrowser = 'document' in global
, request = isBrowser ? xhr : require('request')
, Blob, Branch, Commit, Raw, Repo, Tree, User , Blob, Branch, Commit, Raw, Repo, Tree, User
, api
module.exports = { api = {
blob: function(repo, sha, path, cb) { blob: function(repo, sha, path, cb) {
return new Blob(repo, sha, path, cb) return new Blob(repo, sha, path, cb)
}, },
@ -75,6 +77,9 @@ module.exports = {
return new User(user).getWatched(cb) return new User(user).getWatched(cb)
} }
} }
if (isBrowser) global.GITR = api
else module.exports = api
// Define resources // // Define resources //
@ -139,8 +144,8 @@ function createResource(route, options) {
if (!route) throw new Error('route is required') if (!route) throw new Error('route is required')
options = options || {} options = options || {}
var resource = function() { Resource.apply(this, slice(arguments)) } var resource = function() { Resource.apply(this, [].slice.call(arguments)) }
util.inherits(resource, Resource) inherits(resource, Resource)
resource.prototype._route = route resource.prototype._route = route
resource.prototype._params = options.params || paramsFromRoute(route) resource.prototype._params = options.params || paramsFromRoute(route)
@ -178,7 +183,7 @@ function createResource(route, options) {
// If the optional last arg is an object then it is set as the main resource // If the optional last arg is an object then it is set as the main resource
// data. // data.
function Resource(/* ...args, opt: data or callback */) { function Resource(/* ...args, opt: data or callback */) {
var args = slice(arguments) var args = [].slice.call(arguments)
, last = args[args.length - 1] , last = args[args.length - 1]
// assign params from args // assign params from args
@ -270,6 +275,8 @@ Resource.prototype._get = function(path, cb) {
request({uri: 'http://github.com/api/v2/json/' + path}, function(err, response, body) { request({uri: 'http://github.com/api/v2/json/' + path}, function(err, response, body) {
if (err) if (err)
cb(err) cb(err)
else if (isBrowser)
cb(null, body) // body is an object
else if (response.statusCode !== 200) else if (response.statusCode !== 200)
cb(new Error('failed to fetch ' + path + ': ' + response.statusCode)) cb(new Error('failed to fetch ' + path + ': ' + response.statusCode))
else if (response.headers['content-type'].match(/json/)) else if (response.headers['content-type'].match(/json/))
@ -309,6 +316,57 @@ function getter(obj, prop, fn, opts) { // minor convenience
Object.defineProperty(obj, prop, opts) Object.defineProperty(obj, prop, opts)
} }
function inherits(ctor, superCtor) {
ctor.super_ = superCtor
ctor.prototype = Object.create(superCtor.prototype, {
constructor: {
value: ctor,
enumerable: false
}
})
}
function xhr(options, cb) {
GITR._jsonpCallback = function(obj) {
cb(null, null, obj)
}
;(function (global, oDOC, handler) {
options.uri += '?callback=GITR._jsonpCallback'
var head = oDOC.head || oDOC.getElementsByTagName("head")
// loading code borrowed directly from LABjs itself
setTimeout(function () {
if ("item" in head) { // check if ref is still a live node list
if (!head[0]) { // append_to node not yet ready
setTimeout(arguments.callee, 25)
return
}
head = head[0]; // reassign from live node list ref to pure node ref -- avoids nasty IE bug where changes to DOM invalidate live node lists
}
var scriptElem = oDOC.createElement("script"),
scriptdone = false
scriptElem.onload = scriptElem.onreadystatechange = function () {
if ((scriptElem.readyState && scriptElem.readyState !== "complete" && scriptElem.readyState !== "loaded") || scriptdone) {
return false
}
scriptElem.onload = scriptElem.onreadystatechange = null
scriptdone = true
};
scriptElem.src = options.uri
head.insertBefore(scriptElem, head.firstChild)
}, 0)
// required: shim for FF <= 3.5 not having document.readyState
if (oDOC.readyState == null && oDOC.addEventListener) {
oDOC.readyState = "loading"
oDOC.addEventListener("DOMContentLoaded", handler = function () {
oDOC.removeEventListener("DOMContentLoaded", handler, false)
oDOC.readyState = "complete"
}, false)
}
})(window, document)
}
// get an only property, if any // get an only property, if any
function onlyProp(obj) { function onlyProp(obj) {
if (obj && typeof obj === 'object') { if (obj && typeof obj === 'object') {
@ -326,6 +384,29 @@ function paramsFromRoute(route) {
.map(function(s) { return s.slice(1) }) .map(function(s) { return s.slice(1) })
} }
function slice(x) { return [].slice.call(x) }
function titleCaseFirst(s) { return s.charAt(0).toUpperCase() + s.slice(1) } function titleCaseFirst(s) { return s.charAt(0).toUpperCase() + s.slice(1) }
if (isBrowser) {
function update(array, args) {
var arrayLength = array.length, length = args.length;
while (length--) array[arrayLength + length] = args[length];
return array;
}
function merge(array, args) {
array = [].slice.call(array, 0);
return update(array, args);
}
if (!Function.prototype.bind) {
Function.prototype.bind = function(context) {
if (arguments.length < 2 && typeof arguments[0] === 'undefined') return this
var __method = this, args = [].slice.call(arguments, 1)
return function() {
var a = merge(args, arguments)
return __method.apply(context, a)
}
}
}
}
}())