Created
October 21, 2013 20:20
-
-
Save dovy/7090282 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*! | |
* FamilySearch JavaScript SDK | |
* Copyright 2012, Dallan Quass & Dovy Paukstys | |
* For all api documentation: | |
* https://familysearch.org/developers/ | |
*/ | |
;(function(){ | |
// The FamilySearch namespace | |
var FamilySearch = { | |
// current version | |
Version: '0.1.0', | |
_appid : null, | |
_status : null, // unknown, authorized or unauthorized | |
_logging : false, | |
_cookies : false, | |
_code : null, | |
_access_token : null, | |
_api_format : '.json', | |
_environment : 'staging', | |
_host : { | |
sandbox : 'https://sandbox.familysearch.org', | |
staging : 'https://stage.familysearch.org', | |
production : 'https://familysearch.org' | |
}, | |
_oauth: { | |
sandbox : 'https://sandbox.familysearch.org/cis-web/oauth2/v3', | |
staging : 'https://identbeta.familysearch.org/cis-web/oauth2/v3', | |
production : 'https://ident.familysearch.org/cis-web/oauth2/v3', | |
}, | |
_url: { | |
api : '/platform', | |
status : '/users/current', | |
connect : '/authorization', | |
token : '/token', | |
disconnect : '/oauth/deauthorize', | |
logout : '/oauth/logout' | |
}, | |
// creates a quick and dirty unique id for use in states | |
uuid:function() { | |
return 'g' + (((1+Math.random())*0x10000)|0).toString(16).substring(1); | |
}, | |
// log messages for debugging, off by default | |
log:function() { | |
if(this._logging) { | |
var args = Array.prototype.slice.call(arguments, 0) || []; | |
if (window.console) window.console.log.apply(window.console,args); | |
if (FamilySearch.Event) FamilySearch.Event.trigger.apply(FamilySearch.Event,['log'].concat(args)); | |
} | |
}, | |
// Initialize the FamilySearch SDK library | |
// The best place to put this code is right before the closing </body> tag | |
// | |
// FamilySearch.init({ | |
// appId : 'YOUR APP KEY', // app id or app key | |
// access_token : 'YOUR ACCESS TOKEN', // set the access token if you already have it | |
// host : 'http://sandbox.familysearch.com', // change host if needed | |
// cookies : true, // enable cookies to allow the server to access the session | |
// logging : true // enable log messages to help in debugging | |
// }); | |
// | |
init:function(opts,cb) { | |
opts || (opts = {}); | |
if(!opts.app_id) { | |
return FamilySearch.log('FamilySearch Javascript SDK requires an Application ID'); | |
} | |
this._appid = opts.app_id; | |
if(!opts.environment) { | |
return FamilySearch.log('Setting the API environment to be: ' + opts.environment); | |
} | |
this._environment = opts.environment; | |
// authorize app if we already have an access token | |
if(opts.access_token) { | |
this._access_token = opts.access_token; | |
this._status = "authorized"; | |
} | |
this._logging = (window.location.toString().indexOf('familysearch_debug=1') > 0) || opts.logging || this._logging; | |
this._cookies = opts.cookies || this._cookies; | |
this._host = opts.host || this._host; | |
// oAuth callback function | |
if ( (window.location.toString().indexOf('state=') > 0) ) { | |
var u = window.location.toString().split('?'); | |
(window.opener || window.parent || window.top).postMessage(u[1], u[0]); | |
} | |
return this; | |
} | |
} | |
// Helper methods to make things easier | |
FamilySearch.Util = { | |
// Extend an object with all the properties of the passed object | |
extend:function extend(destination, source) { | |
for (var property in source) | |
destination[property] = source[property]; | |
return destination; | |
}, | |
// Create a URL-encoded query string from an object | |
encodeQueryString:function(obj,prefix){ | |
var str = []; | |
for(var p in obj) str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p])); | |
return str.join("&"); | |
}, | |
// Parses a query string and returns an object composed of key/value pairs | |
decodeQueryString:function(qs){ | |
qs = qs.replace('?','&'); | |
var | |
obj = {}, | |
segments = qs.split('&'), | |
kv; | |
for (var i=0; i<segments.length; i++) { | |
kv = segments[i].split('=', 2); | |
if (kv && kv[0]) { | |
obj[decodeURIComponent(kv[0])] = decodeURIComponent(kv[1]); | |
} | |
} | |
return obj; | |
}, | |
// Properly parse JSON without the need of an external library | |
parseJSON:function(data) { | |
return window.JSON && window.JSON.parse ? window.JSON.parse( data ) : (new Function("return " + data))(); | |
} | |
} | |
// FamilySearch custom events. You may 'bind' or 'unbind' a state function to an event; | |
// 'triggering'-ing an event fires all states in succession. | |
// | |
// function showStatus(status){ | |
// alert(status) | |
// } | |
// FamilySearch.Event.bind('auth:statusChange', showStatus); | |
// FamilySearch.Event.trigger('auth:statuschange','authorized'); | |
// FamilySearch.Event.unbind('auth:statusChange', showStatus); | |
// | |
FamilySearch.Event = { | |
_events:{}, | |
// Bind an event, specified by a string name, 'event', to a state, 'cb', function. | |
bind: function(event, cb){ | |
this._events[event] = this._events[event] || []; | |
this._events[event].push(cb); | |
}, | |
// Remove one or many states. If state is null, all | |
// states for the event wil be removed. | |
unbind: function(event, cb){ | |
if(event in this._events === false) return; | |
this._events[event].splice(this._events[event].indexOf(cb), 1); | |
if(!cb) delete this._events[event]; | |
}, | |
// Trigger an event, firing all bound states. Callbacks are passed the | |
// same arguments as 'trigger' is, apart from the event name. | |
trigger: function(event){ | |
if( event in this._events === false ) return; | |
for(var i = 0; i < this._events[event].length; i++){ | |
this._events[event][i].apply(this, Array.prototype.slice.call(arguments, 1)) | |
} | |
} | |
} | |
// APIs for making requests against FamilySearch's Server. | |
// All request types take the same arguments; url, parameters and a state. | |
// | |
FamilySearch.Request = { | |
states : {}, | |
// Standard JSONP request | |
// | |
// FamilySearch.Request.jsonp(url[, paramerters, state]) | |
// | |
jsonp:function(url,params,cb) { | |
console.log(url); | |
console.log(params); | |
console.log(cb); | |
var | |
self = this, | |
script = document.createElement('script'), | |
uuid = FamilySearch.uuid(), | |
params = FamilySearch.Util.extend((params||{}),{state:'FamilySearch.Request.states.' + uuid}), | |
url = url + (url.indexOf('?')>-1 ? '&' : '?') + FamilySearch.Util.encodeQueryString(params); | |
url = url.replace('?', FamilySearch._api_format+'?'); | |
this.states[uuid] = function(data) { | |
if(data.error) { | |
FamilySearch.log([data.error,data.error_description].join(' : ')); | |
} | |
if(cb) cb(data); | |
delete self.states[uuid]; | |
} | |
script.src = url; | |
document.getElementsByTagName('head')[0].appendChild(script); | |
}, | |
corsjson:function(url,params) { | |
var | |
method = ("_method" in params ? params._method : "GET"), | |
requestHeader = { | |
type : "Accept", | |
value : "application/json" | |
}; | |
if ("_method" in params) { // Don't keep this for our post string | |
delete params._method; | |
} | |
if (method == "POST") { // Change the content type to get the appropriate response | |
requestHeader = { | |
type : "Content-type", | |
value : "application/x-www-form-urlencoded" | |
}; | |
} | |
var xhr = new XMLHttpRequest(); | |
if ("withCredentials" in xhr) { | |
// Check if the XMLHttpRequest object has a "withCredentials" property. | |
// "withCredentials" only exists on XMLHTTPRequest2 objects. | |
xhr.open(method, url); | |
xhr.setRequestHeader(requestHeader.type, requestHeader.value); | |
xhr.send(FamilySearch.Util.encodeQueryString(params)); | |
} else if (typeof XDomainRequest != "undefined") { | |
// Otherwise, check if XDomainRequest. | |
// XDomainRequest only exists in IE, and is IE's way of making CORS requests. | |
xhr = new XDomainRequest(); | |
xhr.open(method, url); | |
xhr.setRequestHeader(requestHeader.type, requestHeader.value); | |
xhr.send(FamilySearch.Util.encodeQueryString(params)); | |
} else { | |
// Otherwise, CORS is not supported by the browser. | |
xhr = null; | |
} | |
xhr.onreadystatechange = function() { | |
if (this.status == 200 && this.readyState == 4) { | |
if (this.responseText != "") { | |
console.log(FamilySearch.Util.parseJSON(this.responseText)); | |
console.log('dovy'); | |
return FamilySearch.Util.parseJSON(this.responseText); | |
} | |
} | |
}; | |
xhr.onerror = function() { | |
FamilySearch.log('CORS request failed for URL: '+url); | |
FamilySearch.log(params); | |
}; | |
}, | |
cors:function(url,params,cb,method) { | |
var | |
self = this, | |
method = ("_method" in params ? params._method : "GET"), | |
requestHeader = new Array("Accept","application/json"), | |
script = document.createElement('script'), | |
uuid = FamilySearch.uuid(), | |
params = FamilySearch.Util.extend((params||{}),{state:'FamilySearch.Request.states.' + uuid}), | |
url = url + (url.indexOf('?')>-1 ? '&' : '?') + FamilySearch.Util.encodeQueryString(params); | |
url = url.replace('?', FamilySearch._api_format+'?'); | |
console.log(params); | |
if ("_method" in params) { // Don't keep this for our post string | |
delete params._method; | |
} | |
if (method == "POST") { // Change the content type to get the appropriate response | |
requestHeader = new Array("Content-type","application/x-www-form-urlencoded"); | |
} | |
this.states[uuid] = function(data) { | |
if(data.error) { | |
FamilySearch.log([data.error,data.error_description].join(' : ')); | |
} | |
if(cb) cb(data); | |
delete self.states[uuid]; | |
} | |
var xhr = new XMLHttpRequest(); | |
if ("withCredentials" in xhr) { | |
// Check if the XMLHttpRequest object has a "withCredentials" property. | |
// "withCredentials" only exists on XMLHTTPRequest2 objects. | |
xhr.open(method, url); | |
xhr.setRequestHeader(requestHeader); | |
xhr.send(FamilySearch.Util.encodeQueryString(params)); | |
} else if (typeof XDomainRequest != "undefined") { | |
// Otherwise, check if XDomainRequest. | |
// XDomainRequest only exists in IE, and is IE's way of making CORS requests. | |
xhr = new XDomainRequest(); | |
xhr.open(method, url); | |
xhr.setRequestHeader(requestHeader); | |
xhr.send(FamilySearch.Util.encodeQueryString(params)); | |
} else { | |
// Otherwise, CORS is not supported by the browser. | |
xhr = null; | |
} | |
xhr.onreadystatechange = function() { | |
if (this.status == 200 && this.readyState == 4) { | |
var data = FamilySearch.Util.parseJSON(this.responseText); | |
return data; | |
} | |
}; | |
xhr.onerror = function() { | |
FamilySearch.log('CORS request failed.'); | |
FamilySearch.log(url); | |
FamilySearch.log(params); | |
}; | |
var xhr = new XMLHttpRequest(); | |
if ("withCredentials" in xhr) { | |
// Check if the XMLHttpRequest object has a "withCredentials" property. | |
// "withCredentials" only exists on XMLHTTPRequest2 objects. | |
xhr.open(method, url, false); | |
xhr.setRequestHeader("Accept","application/json"); | |
xhr.send("grant_type=authorization_code&code="+code+'&client_id='+FamilySearch._appid); | |
} else if (typeof XDomainRequest != "undefined") { | |
// Otherwise, check if XDomainRequest. | |
// XDomainRequest only exists in IE, and is IE's way of making CORS requests. | |
xhr = new XDomainRequest(); | |
xhr.open(method, url); | |
xhr.setRequestHeader("Accept","application/json"); | |
xhr.send("grant_type=authorization_code&code="+code+'&client_id='+FamilySearch._appid); | |
} else { | |
// Otherwise, CORS is not supported by the browser. | |
xhr = null; | |
} | |
var data = xhr.responseText; | |
console.log(data); | |
return data; | |
}, | |
// Same as a jsonp request but with an access token for oauth authentication | |
// | |
// FamilySearch.Request.oauth(url[, paramerters, state]) | |
// | |
oauth:function(url,params,cb) { | |
params || (params = {}); | |
if(FamilySearch._access_token) { | |
FamilySearch.Util.extend(params,{access_token:FamilySearch._access_token}); | |
} else { | |
FamilySearch.log('FamilySearch.Request.oauth() called without an access token.'); | |
} | |
this.jsonp(url,params,cb); | |
}, | |
// Opens a popup window with the given url and places it at the | |
// center of the current window. Used for app authentication. Should only | |
// be called on a user event like a click as many browsers block popups | |
// if not initiated by a user. | |
// | |
// FamilySearch.Request.popup(url[, paramerters, state]) | |
// | |
popup: function(url,params,cb) { | |
this.registerXDHandler(); | |
// figure out where the center is | |
var | |
screenX = typeof window.screenX != 'undefined' ? window.screenX : window.screenLeft, | |
screenY = typeof window.screenY != 'undefined' ? window.screenY : window.screenTop, | |
outerWidth = typeof window.outerWidth != 'undefined' ? window.outerWidth : document.documentElement.clientWidth, | |
outerHeight = typeof window.outerHeight != 'undefined' ? window.outerHeight : (document.documentElement.clientHeight - 22), | |
width = params.width || 780, | |
height = params.height || 500, | |
left = parseInt(screenX + ((outerWidth - width) / 2), 10), | |
top = parseInt(screenY + ((outerHeight - height) / 2.5), 10), | |
features = ( | |
'width=' + width + | |
',height=' + height + | |
',left=' + left + | |
',top=' + top | |
); | |
var | |
uuid = FamilySearch.uuid(), | |
params = FamilySearch.Util.extend((params||{}),{ | |
state : uuid, | |
display : 'popup', | |
origin : this._origin() | |
}), | |
url = url + (url.indexOf('?')>-1 ? '&' : '?') + FamilySearch.Util.encodeQueryString(params); | |
var win = window.open(url,uuid,features); | |
this.states[uuid] = function(data) { | |
if(cb) cb(data,win); | |
delete FamilySearch.Request.states[uuid]; | |
} | |
}, | |
// Creates and inserts a hidden iframe with the given url then removes | |
// the iframe from the DOM | |
// | |
// FamilySearch.Request.hidden(url[, paramerters, state]) | |
// | |
hidden:function(url,params,cb) { | |
this.registerXDHandler(); | |
var | |
iframe = document.createElement('iframe'), | |
uuid = FamilySearch.uuid(), | |
params = FamilySearch.Util.extend((params||{}),{ | |
state : uuid, | |
display : 'hidden', | |
origin : this._origin() | |
}), | |
url = url + (url.indexOf('?')>-1 ? '&' : '?') + FamilySearch.Util.encodeQueryString(params); | |
iframe.style.display = "none"; | |
this.states[uuid] = function(data) { | |
if(cb) cb(data); | |
delete FamilySearch.Request.states[uuid]; | |
iframe.parentNode.removeChild(iframe); | |
} | |
iframe.src = url; | |
document.getElementsByTagName('body')[0].appendChild(iframe); | |
}, | |
// Make sure we're listening to the onMessage event | |
registerXDHandler:function() { | |
if(this.xd_registered) return; | |
var | |
self=FamilySearch.Request, | |
fn = function(e){FamilySearch.Request.onMessage(e)} | |
window.addEventListener | |
? window.addEventListener('message', fn, false) | |
: window.attachEvent('onmessage', fn); | |
this.xd_registered = true; | |
}, | |
// handles message events sent via postMessage, and fires the appropriate state | |
onMessage:function(e) { | |
var data = {}; | |
if (e.data && typeof e.data == 'string') { | |
data = FamilySearch.Util.decodeQueryString(e.data); | |
} | |
if(data.error) { | |
FamilySearch.log(data.error,data.error_description); | |
} | |
if(data.state) { | |
var cb = this.states[data.state]; | |
if(cb) { | |
if (data.code != "") { | |
data.code = FamilySearch.Auth.getToken(data.code); | |
} | |
cb(data); | |
delete this.states[data.state]; | |
} | |
} | |
}, | |
// get the origin of the page | |
_origin: function() { | |
return (window.location.protocol + '//' + window.location.host) | |
} | |
} | |
// Authentication | |
FamilySearch.Auth = { | |
// Returns the current authentication status of the user from the server, and provides | |
// an access token if the user is logged into FamilySearch and has authorized the app. | |
// | |
// FamilySearch.Auth.getStatus(function(response){ | |
// if(response.status == 'authorized') { | |
// // User is logged in and has authorized the app | |
// } | |
// }) | |
// | |
// The status returned in the response will be either 'authorized', user is logged in | |
// and has authorized the app, 'unauthorized', user is logged in but has not authorized | |
// the app and 'unknown', user is not logged in. | |
getStatus:function(cb) { | |
if(!FamilySearch._appid) { | |
return FamilySearch.log('FamilySearch.Auth.getStatus() called without an app id'); | |
} | |
var url = FamilySearch._host[FamilySearch._environment] + FamilySearch._url.status; | |
FamilySearch.Request.hidden(url,{client_id:FamilySearch._appid},function(data){ | |
FamilySearch.Auth.setStatus(data); | |
if(cb) cb(data); | |
}); | |
}, | |
// Launches the authorization window to connect to FamilySearch and if successful returns an | |
// access token. | |
// | |
// FamilySearch.Auth.connect(function(response){ | |
// if(response.status == 'authorized') { | |
// // User is logged in and has authorized the app | |
// } | |
// }) | |
// | |
connect:function(cb) { | |
if(!FamilySearch._appid) { | |
return FamilySearch.log('FamilySearch.Auth.connect() called without an app id.'); | |
} | |
if(!FamilySearch._access_token) { | |
// Get the base host URL for callback. | |
// No args or hashtags please. | |
var host = document.URL, | |
parts = null; | |
if (host.indexOf('#') > 0) { | |
parts = host.split('#'); | |
host = parts[0]; | |
} | |
if (host.indexOf('?') > 0) { | |
parts = host.split('?'); | |
host = parts[0]; | |
} | |
var url = FamilySearch._oauth[FamilySearch._environment] + FamilySearch._url.connect, | |
params = { | |
response_type : 'code', | |
client_id : FamilySearch._appid, | |
redirect_uri : host, // | |
//lng : // Language code | |
}; | |
FamilySearch.Request.popup(url,params,function(data,win){ | |
FamilySearch.Auth.setStatus(data); | |
if(win) win.close(); | |
if(cb) cb(data); | |
}); | |
} else { | |
FamilySearch.log('FamilySearch.Auth.connect() called when user is already connected.'); | |
if(cb) cb(); | |
} | |
}, | |
// Revokes your apps authorization access | |
// | |
// FamilySearch.Auth.disconnect(function(){ | |
// // App authorization has been revoked | |
// }) | |
// | |
disconnect:function(cb) { | |
if(!FamilySearch._appid) { | |
return FamilySearch.log('FamilySearch.Auth.disconnect() called without an app id.'); | |
} | |
var url = FamilySearch._host[FamilySearch._environment] + FamilySearch._url.disconnect; | |
FamilySearch.Request.jsonp(url,{client_id:FamilySearch._appid},function(r){ | |
FamilySearch.Auth.setStatus(null); | |
if(cb) cb(r); | |
}) | |
}, | |
// Logs the user out of FamilySearch | |
// | |
// FamilySearch.Auth.logout(function(){ | |
// // App authorization has been revoked | |
// }) | |
// | |
logout:function(cb) { | |
if(!FamilySearch._appid) { | |
return FamilySearch.log('FamilySearch.Auth.logout called() without an app id.'); | |
} | |
var url = FamilySearch._host[FamilySearch._environment] + FamilySearch._url.logout; | |
FamilySearch.Request.jsonp(url,{client_id:FamilySearch._appid},function(r){ | |
FamilySearch.Auth.setStatus(null); | |
if(cb) cb(r); | |
}); | |
}, | |
// Determines the correct status ('unknown', 'unauthorized' or 'authorized') and | |
// sets the access token if authorization is approved. | |
setStatus:function(data) { | |
data || (data = {}); | |
if(data.code) { | |
FamilySearch._access_token = data.code; | |
FamilySearch.Cookie('familysearch'+FamilySearch._appid, FamilySearch._access_token); | |
data.status = "authorized"; | |
} else { | |
FamilySearch._access_token = null; | |
FamilySearch.Cookie('familysearch'+FamilySearch._appid, null); | |
data.status = data.status || "unknown"; | |
} | |
if(FamilySearch._status != data.status) { | |
FamilySearch.Event.trigger('auth:statusChange',data.status); | |
} | |
return (FamilySearch._status = data.status); | |
}, | |
getToken:function(code) { | |
var url = FamilySearch._oauth[FamilySearch._environment] + FamilySearch._url.token, | |
params = FamilySearch.Util.extend((params||{}),{ | |
_method : "POST", | |
grant_type : "authorization_code", | |
code : code, | |
client_id : FamilySearch._appid | |
}); | |
var data = FamilySearch.Util.parseJSON(FamilySearch.Request.corsjson(url, params)); | |
console.log(data); | |
if (data.access_token != "") { | |
return data.access_token; | |
} | |
return code; | |
} | |
} | |
// Make API calls to FamilySearch's Servers | |
// | |
// The API strives to provide consistent access to FamilySearch’s data. IDs are embedded before | |
// the action so the urls read more like a sentence. To get all profile 1’s tree matches | |
// you would request | |
// | |
// FamilySearch.api('/profile-1/tree-matches',function(data){ | |
// // returns a list of tree matches for profile with id 1 | |
// }) | |
// | |
// Omitting the ids in urls implies the action should be applied to the current user’s data. | |
// For example, | |
// | |
// FamilySearch.api('/profile',function(data) { | |
// // returns current user's profile data | |
// }) | |
// | |
// will return the profile information for the logged in user. Parameters can optionally be | |
// passed in as the second argument: | |
// | |
// FamilySearch.api('/profile-101',{fields:'first_name,last_name'},function(data) { | |
// // only returns first and last name of profile with id 101 | |
// }) | |
// | |
// Visit htp://dev.familysearch.com for more detailed documentation. | |
// | |
FamilySearch.Api = { | |
// Makes an oauth jsonp request to FamilySearch's servers for data. | |
// | |
// FamilySearch.Api.get('/user',function(data){ | |
// // do something awesome with FamilySearch data | |
// }) | |
// | |
get:function(path,params,cb) { | |
if(typeof params == 'function') { | |
cb = params; | |
params = {}; | |
} | |
params || (params = {}); | |
if(params.method) { | |
params['_method'] = params.method; | |
delete params.method; | |
} | |
path = FamilySearch._host[FamilySearch._environment] + FamilySearch._url.api + "/" + path.replace(/^\//,''); | |
FamilySearch.Request.oauth(path, params, cb); | |
}, | |
// Makes an oauth jsonp request to FamilySearch's servers to save data. All jsonp | |
// requests use a GET method but we can get around this by adding a | |
// _method=post parameter to our request. | |
// | |
// FamilySearch.Api.post(function(data){ | |
// // Add awesome data to FamilySearch | |
// }) | |
// | |
post:function(path,params,cb) { | |
params = FamilySearch.Util.extend({'_method':'post'},params || {}); | |
this.get(path,params,cb); | |
} | |
} | |
// Cookies | |
// Helper function to get/set browser cookies so an application's server can have access | |
// to the access token. | |
// | |
FamilySearch.Cookie = function (key, value, options) { | |
if(!FamilySearch._cookies) return; | |
if (arguments.length > 1 && String(value) !== "[object Object]") { | |
options = FamilySearch.Util.extend({}, options); | |
if (value === null || value === undefined) options.expires = -1; | |
if (typeof options.expires === 'number') { | |
var days = options.expires, t = options.expires = new Date(); | |
t.setDate(t.getDate() + days); | |
} | |
value = String(value); | |
return (document.cookie = [ | |
encodeURIComponent(key), '=', | |
options.raw ? value : encodeURIComponent(value), | |
options.expires ? '; expires=' + options.expires.toUTCString() : '', | |
options.path ? '; path=' + options.path : '', | |
options.domain ? '; domain=' + options.domain : '', | |
options.secure ? '; secure' : '' | |
].join('')); | |
} | |
options = value || {}; | |
var result, decode = options.raw ? function (s) { return s; } : decodeURIComponent; | |
return (result = new RegExp('(?:^|; )' + encodeURIComponent(key) + '=([^;]*)').exec(document.cookie)) ? decode(result[1]) : null; | |
} | |
// shortcuts to make things easier | |
window.FamilySearch = window.$g = FamilySearch.Util.extend(FamilySearch,{ | |
getStatus : FamilySearch.Auth.getStatus, | |
connect : FamilySearch.Auth.connect, | |
disconnect : FamilySearch.Auth.disconnect, | |
logout : FamilySearch.Auth.logout, | |
api : FamilySearch.Api.get //most api calls are gets | |
}); | |
}).call(this); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment