hellojs
Version:
A clientside Javascript library for standardizing requests to OAuth2 web services (and OAuth1 - with a shim)
3 lines (2 loc) • 37.3 kB
JavaScript
/*! hellojs v1.20.0 - (c) 2012-2023 Andrew Dodson - MIT https://adodson.com/hello.js/LICENSE */
if(!Object.create){Object.create=function(){function F(){}return function(o){if(arguments.length!=1){throw new Error("Object.create implementation only accepts one parameter.")}F.prototype=o;return new F}}()}if(!Object.keys){Object.keys=function(o,k,r){r=[];for(k in o){if(r.hasOwnProperty.call(o,k))r.push(k)}return r}}if(!Array.prototype.indexOf){Array.prototype.indexOf=function(s){for(var j=0;j<this.length;j++){if(this[j]===s){return j}}return-1}}if(!Array.prototype.forEach){Array.prototype.forEach=function(fun){if(this===void 0||this===null){throw new TypeError}var t=Object(this);var len=t.length>>>0;if(typeof fun!=="function"){throw new TypeError}var thisArg=arguments.length>=2?arguments[1]:void 0;for(var i=0;i<len;i++){if(i in t){fun.call(thisArg,t[i],i,t)}}return this}}if(!Array.prototype.filter){Array.prototype.filter=function(fun,thisArg){var a=[];this.forEach(function(val,i,t){if(fun.call(thisArg||void 0,val,i,t)){a.push(val)}});return a}}if(!Array.prototype.map){Array.prototype.map=function(fun,thisArg){var a=[];this.forEach(function(val,i,t){a.push(fun.call(thisArg||void 0,val,i,t))});return a}}if(!Array.isArray){Array.isArray=function(o){return Object.prototype.toString.call(o)==="[object Array]"}}if(typeof window==="object"&&typeof window.location==="object"&&!window.location.assign){window.location.assign=function(url){window.location=url}}if(!Function.prototype.bind){Function.prototype.bind=function(b){if(typeof this!=="function"){throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable")}function C(){}var a=[].slice;var f=a.call(arguments,1);var _this=this;var D=function(){return _this.apply(this instanceof C?this:b||window,f.concat(a.call(arguments)))};C.prototype=this.prototype;D.prototype=new C;return D}}var hello=function(name){return hello.use(name)};hello.utils={extend:function(r){Array.prototype.slice.call(arguments,1).forEach(function(a){if(Array.isArray(r)&&Array.isArray(a)){Array.prototype.push.apply(r,a)}else if(r&&(r instanceof Object||typeof r==="object")&&a&&(a instanceof Object||typeof a==="object")&&r!==a){for(var x in a){if(x==="__proto__"||x==="constructor"){continue}r[x]=hello.utils.extend(r[x],a[x])}}else{if(Array.isArray(a)){a=a.slice(0)}r=a}});return r}};hello.utils.extend(hello,{settings:{redirect_uri:window.location.href.split("#")[0],response_type:"token",display:"popup",state:"",oauth_proxy:"https://auth-server.herokuapp.com/proxy",timeout:2e4,popup:{resizable:1,scrollbars:1,width:500,height:550},scope:["basic"],scope_map:{basic:""},default_service:null,force:null,page_uri:window.location.href},services:{},use:function(service){var self=Object.create(this);self.settings=Object.create(this.settings);if(service){self.settings.default_service=service}self.utils.Event.call(self);return self},init:function(services,options){var utils=this.utils;if(!services){return this.services}for(var x in services){if(services.hasOwnProperty(x)){if(typeof services[x]!=="object"){services[x]={id:services[x]}}}}utils.extend(this.services,services);if(options){utils.extend(this.settings,options);if("redirect_uri"in options){this.settings.redirect_uri=utils.url(options.redirect_uri).href}}return this},login:function(){var _this=this;var utils=_this.utils;var error=utils.error;var promise=utils.Promise();var p=utils.args({network:"s",options:"o",callback:"f"},arguments);var url;var qs=utils.diffKey(p.options,_this.settings);var opts=p.options=utils.merge(_this.settings,p.options||{});opts.popup=utils.merge(_this.settings.popup,p.options.popup||{});p.network=p.network||_this.settings.default_service;promise.proxy.then(p.callback,p.callback);function emit(s,value){hello.emit(s,value)}promise.proxy.then(emit.bind(this,"auth.login auth"),emit.bind(this,"auth.failed auth"));if(typeof p.network!=="string"||!(p.network in _this.services)){return promise.reject(error("invalid_network","The provided network was not recognized"))}var provider=_this.services[p.network];var callbackId=utils.globalEvent(function(obj){if(obj){if(typeof obj=="string"){obj=JSON.parse(obj)}}else{obj=error("cancelled","The authentication was not completed")}if(!obj.error){utils.store(obj.network,obj);promise.fulfill({network:obj.network,authResponse:obj})}else{promise.reject(obj)}});var redirectUri=utils.url(opts.redirect_uri).href;var responseType=provider.oauth.response_type||opts.response_type;if(/\bcode\b/.test(responseType)&&!provider.oauth.grant){responseType=responseType.replace(/\bcode\b/,"token")}p.qs=utils.merge(qs,{client_id:encodeURIComponent(provider.id),response_type:encodeURIComponent(responseType),redirect_uri:encodeURIComponent(redirectUri),state:{client_id:provider.id,network:p.network,display:opts.display,callback:callbackId,state:opts.state,redirect_uri:redirectUri}});var session=utils.store(p.network);var SCOPE_SPLIT=/[,\s]+/;var scope=_this.settings.scope?[_this.settings.scope.toString()]:[];var scopeMap=utils.merge(_this.settings.scope_map,provider.scope||{});if(opts.scope){scope.push(opts.scope.toString())}if(session&&"scope"in session&&session.scope instanceof String){scope.push(session.scope)}scope=scope.join(",").split(SCOPE_SPLIT);scope=utils.unique(scope).filter(filterEmpty);p.qs.state.scope=scope.join(",");scope=scope.map(function(item){return item in scopeMap?scopeMap[item]:item});scope=scope.join(",").split(SCOPE_SPLIT);scope=utils.unique(scope).filter(filterEmpty);p.qs.scope=scope.join(provider.scope_delim||",");if(opts.force===false){if(session&&"access_token"in session&&session.access_token&&"expires"in session&&session.expires>(new Date).getTime()/1e3){var diff=utils.diff((session.scope||"").split(SCOPE_SPLIT),(p.qs.state.scope||"").split(SCOPE_SPLIT));if(diff.length===0){promise.fulfill({unchanged:true,network:p.network,authResponse:session});return promise}}}if(opts.display==="page"&&opts.page_uri){p.qs.state.page_uri=utils.url(opts.page_uri).href}if("login"in provider&&typeof provider.login==="function"){provider.login(p)}if(!/\btoken\b/.test(responseType)||parseInt(provider.oauth.version,10)<2||opts.display==="none"&&provider.oauth.grant&&session&&session.refresh_token){p.qs.state.oauth=provider.oauth;p.qs.state.oauth_proxy=opts.oauth_proxy}if(provider.oauth.base64_state){p.qs.state=window.btoa(JSON.stringify(p.qs.state))}else{p.qs.state=encodeURIComponent(JSON.stringify(p.qs.state))}if(parseInt(provider.oauth.version,10)===1){url=utils.qs(opts.oauth_proxy,p.qs,encodeFunction)}else if(opts.display==="none"&&provider.oauth.grant&&session&&session.refresh_token){p.qs.refresh_token=session.refresh_token;url=utils.qs(opts.oauth_proxy,p.qs,encodeFunction)}else{url=utils.qs(provider.oauth.auth,p.qs,encodeFunction)}emit("auth.init",p);if(opts.display==="none"){utils.iframe(url,redirectUri)}else if(opts.display==="popup"){var popup=utils.popup(url,redirectUri,opts.popup);var timer=setInterval(function(){if(!popup||popup.closed){clearInterval(timer);if(!promise.state){var response=error("cancelled","Login has been cancelled");if(!popup){response=error("blocked","Popup was blocked")}response.network=p.network;promise.reject(response)}}},100)}else{window.location=url}return promise.proxy;function encodeFunction(s){return s}function filterEmpty(s){return!!s}},logout:function(){var _this=this;var utils=_this.utils;var error=utils.error;var promise=utils.Promise();var p=utils.args({name:"s",options:"o",callback:"f"},arguments);p.options=p.options||{};promise.proxy.then(p.callback,p.callback);function emit(s,value){hello.emit(s,value)}promise.proxy.then(emit.bind(this,"auth.logout auth"),emit.bind(this,"error"));p.name=p.name||this.settings.default_service;p.authResponse=utils.store(p.name);if(p.name&&!(p.name in _this.services)){promise.reject(error("invalid_network","The network was unrecognized"))}else if(p.name&&p.authResponse){var callback=function(opts){utils.store(p.name,null);promise.fulfill(hello.utils.merge({network:p.name},opts||{}))};var _opts={};if(p.options.force){var logout=_this.services[p.name].logout;if(logout){if(typeof logout==="function"){logout=logout(callback,p)}if(typeof logout==="string"){utils.iframe(logout);_opts.force=null;_opts.message="Logout success on providers site was indeterminate"}else if(logout===undefined){return promise.proxy}}}callback(_opts)}else{promise.reject(error("invalid_session","There was no session to remove"))}return promise.proxy},getAuthResponse:function(service){service=service||this.settings.default_service;if(!service||!(service in this.services)){return null}return this.utils.store(service)||null},events:{}});hello.utils.extend(hello.utils,{error:function(code,message){return{error:{code:code,message:message}}},qs:function(url,params,formatFunction){if(params){formatFunction=formatFunction||encodeURIComponent;for(var x in params){var str="([\\?\\&])"+x+"=[^\\&]*";var reg=new RegExp(str);if(url.match(reg)){url=url.replace(reg,"$1"+x+"="+formatFunction(params[x]));delete params[x]}}}if(!this.isEmpty(params)){return url+(url.indexOf("?")>-1?"&":"?")+this.param(params,formatFunction)}return url},param:function(s,formatFunction){var b;var a={};var m;if(typeof s==="string"){formatFunction=formatFunction||decodeURIComponent;m=s.replace(/^[\#\?]/,"").match(/([^=\/\&]+)=([^\&]+)/g);if(m){for(var i=0;i<m.length;i++){b=m[i].match(/([^=]+)=(.*)/);a[b[1]]=formatFunction(b[2])}}return a}else{formatFunction=formatFunction||encodeURIComponent;var o=s;a=[];for(var x in o){if(o.hasOwnProperty(x)){if(o.hasOwnProperty(x)){a.push([x,o[x]==="?"?"?":formatFunction(o[x])].join("="))}}}return a.join("&")}},store:function(){var a=["localStorage","sessionStorage"];var i=-1;var prefix="test";var localStorage;while(a[++i]){try{localStorage=window[a[i]];localStorage.setItem(prefix+i,i);localStorage.removeItem(prefix+i);break}catch(e){localStorage=null}}if(!localStorage){var cache=null;localStorage={getItem:function(prop){prop=prop+"=";var m=document.cookie.split(";");for(var i=0;i<m.length;i++){var _m=m[i].replace(/(^\s+|\s+$)/,"");if(_m&&_m.indexOf(prop)===0){return _m.substr(prop.length)}}return cache},setItem:function(prop,value){cache=value;document.cookie=prop+"="+value}};cache=localStorage.getItem("hello")}function get(){var json={};try{json=JSON.parse(localStorage.getItem("hello"))||{}}catch(e){}return json}function set(json){localStorage.setItem("hello",JSON.stringify(json))}return function(name,value,days){var json=get();if(name&&value===undefined){return json[name]||null}else if(name&&value===null){try{delete json[name]}catch(e){json[name]=null}}else if(name){json[name]=value}else{return json}set(json);return json||null}}(),append:function(node,attr,target){var n=typeof node==="string"?document.createElement(node):node;if(typeof attr==="object"){if("tagName"in attr){target=attr}else{for(var x in attr){if(attr.hasOwnProperty(x)){if(typeof attr[x]==="object"){for(var y in attr[x]){if(attr[x].hasOwnProperty(y)){n[x][y]=attr[x][y]}}}else if(x==="html"){n.innerHTML=attr[x]}else if(!/^on/.test(x)){n.setAttribute(x,attr[x])}else{n[x]=attr[x]}}}}}if(target==="body"){(function self(){if(document.body){document.body.appendChild(n)}else{setTimeout(self,16)}})()}else if(typeof target==="object"){target.appendChild(n)}else if(typeof target==="string"){document.getElementsByTagName(target)[0].appendChild(n)}return n},iframe:function(src){this.append("iframe",{src:src,style:{position:"absolute",left:"-1000px",bottom:0,height:"1px",width:"1px"}},"body")},merge:function(){var args=Array.prototype.slice.call(arguments);args.unshift({});return this.extend.apply(null,args)},args:function(o,args){var p={};var i=0;var t=null;var x=null;for(x in o){if(o.hasOwnProperty(x)){break}}if(args.length===1&&typeof args[0]==="object"&&o[x]!="o!"){for(x in args[0]){if(o.hasOwnProperty(x)){if(x in o){return args[0]}}}}for(x in o){if(o.hasOwnProperty(x)){t=typeof args[i];if(typeof o[x]==="function"&&o[x].test(args[i])||typeof o[x]==="string"&&(o[x].indexOf("s")>-1&&t==="string"||o[x].indexOf("o")>-1&&t==="object"||o[x].indexOf("i")>-1&&t==="number"||o[x].indexOf("a")>-1&&t==="object"||o[x].indexOf("f")>-1&&t==="function")){p[x]=args[i++]}else if(typeof o[x]==="string"&&o[x].indexOf("!")>-1){return false}}}return p},url:function(path){if(!path){return window.location}else if(window.URL&&URL instanceof Function&&URL.length!==0){return new URL(path,window.location)}else{var a=document.createElement("a");a.href=path;return a.cloneNode(false)}},diff:function(a,b){return b.filter(function(item){return a.indexOf(item)===-1})},diffKey:function(a,b){if(a||!b){var r={};for(var x in a){if(!(x in b)){r[x]=a[x]}}return r}return a},unique:function(a){if(!Array.isArray(a)){return[]}return a.filter(function(item,index){return a.indexOf(item)===index})},isEmpty:function(obj){if(!obj)return true;if(Array.isArray(obj)){return!obj.length}else if(typeof obj==="object"){for(var key in obj){if(obj.hasOwnProperty(key)){return false}}}return true},Promise:function(){var STATE_PENDING=0;var STATE_FULFILLED=1;var STATE_REJECTED=2;var api=function(executor){if(!(this instanceof api))return new api(executor);this.id="Thenable/1.0.6";this.state=STATE_PENDING;this.fulfillValue=undefined;this.rejectReason=undefined;this.onFulfilled=[];this.onRejected=[];this.proxy={then:this.then.bind(this)};if(typeof executor==="function")executor.call(this,this.fulfill.bind(this),this.reject.bind(this))};api.prototype={fulfill:function(value){return deliver(this,STATE_FULFILLED,"fulfillValue",value)},reject:function(value){return deliver(this,STATE_REJECTED,"rejectReason",value)},then:function(onFulfilled,onRejected){var curr=this;var next=new api;curr.onFulfilled.push(resolver(onFulfilled,next,"fulfill"));curr.onRejected.push(resolver(onRejected,next,"reject"));execute(curr);return next.proxy}};var deliver=function(curr,state,name,value){if(curr.state===STATE_PENDING){curr.state=state;curr[name]=value;execute(curr)}return curr};var execute=function(curr){if(curr.state===STATE_FULFILLED)execute_handlers(curr,"onFulfilled",curr.fulfillValue);else if(curr.state===STATE_REJECTED)execute_handlers(curr,"onRejected",curr.rejectReason)};var execute_handlers=function(curr,name,value){if(curr[name].length===0)return;var handlers=curr[name];curr[name]=[];var func=function(){for(var i=0;i<handlers.length;i++)handlers[i](value)};if(typeof process==="object"&&typeof process.nextTick==="function")process.nextTick(func);else if(typeof setImmediate==="function")setImmediate(func);else setTimeout(func,0)};var resolver=function(cb,next,method){return function(value){if(typeof cb!=="function")next[method].call(next,value);else{var result;try{result=cb(value)}catch(e){next.reject(e);return}resolve(next,result)}}};var resolve=function(promise,x){if(promise===x||promise.proxy===x){promise.reject(new TypeError("cannot resolve promise with itself"));return}var then;if(typeof x==="object"&&x!==null||typeof x==="function"){try{then=x.then}catch(e){promise.reject(e);return}}if(typeof then==="function"){var resolved=false;try{then.call(x,function(y){if(resolved)return;resolved=true;if(y===x)promise.reject(new TypeError("circular thenable chain"));else resolve(promise,y)},function(r){if(resolved)return;resolved=true;promise.reject(r)})}catch(e){if(!resolved)promise.reject(e)}return}promise.fulfill(x)};return api}(),Event:function(){var separator=/[\s\,]+/;this.parent={events:this.events,findEvents:this.findEvents,parent:this.parent,utils:this.utils};this.events={};this.on=function(evt,callback){if(callback&&typeof callback==="function"){var a=evt.split(separator);for(var i=0;i<a.length;i++){this.events[a[i]]=[callback].concat(this.events[a[i]]||[])}}return this};this.off=function(evt,callback){this.findEvents(evt,function(name,index){if(!callback||this.events[name][index]===callback){this.events[name][index]=null}});return this};this.emit=function(evt){var args=Array.prototype.slice.call(arguments,1);args.push(evt);var handler=function(name,index){args[args.length-1]=name==="*"?evt:name;this.events[name][index].apply(this,args)};var _this=this;while(_this&&_this.findEvents){_this.findEvents(evt+",*",handler);_this=_this.parent}return this};this.emitAfter=function(){var _this=this;var args=arguments;setTimeout(function(){_this.emit.apply(_this,args)},0);return this};this.findEvents=function(evt,callback){var a=evt.split(separator);for(var name in this.events){if(this.events.hasOwnProperty(name)){if(a.indexOf(name)>-1){for(var i=0;i<this.events[name].length;i++){if(this.events[name][i]){callback.call(this,name,i)}}}}}};return this},globalEvent:function(callback,guid){guid=guid||"_hellojs_"+parseInt(Math.random()*1e12,10).toString(36);window[guid]=function(){try{if(callback.apply(this,arguments)){delete window[guid]}}catch(e){console.error(e)}};return guid},popup:function(url,redirectUri,options){var documentElement=document.documentElement;if(options.height&&options.top===undefined){var dualScreenTop=window.screenTop!==undefined?window.screenTop:screen.top;var height=screen.height||window.innerHeight||documentElement.clientHeight;options.top=parseInt((height-options.height)/2,10)+dualScreenTop}if(options.width&&options.left===undefined){var dualScreenLeft=window.screenLeft!==undefined?window.screenLeft:screen.left;var width=screen.width||window.innerWidth||documentElement.clientWidth;options.left=parseInt((width-options.width)/2,10)+dualScreenLeft}var optionsArray=[];Object.keys(options).forEach(function(name){var value=options[name];optionsArray.push(name+(value!==null?"="+value:""))});if(navigator.userAgent.indexOf("Safari")!==-1&&navigator.userAgent.indexOf("Chrome")===-1){url=redirectUri+"#oauth_redirect="+encodeURIComponent(encodeURIComponent(url))}var popup=window.open(url,"_blank",optionsArray.join(","));if(popup&&popup.focus){popup.focus()}return popup},responseHandler:function(window,parent){var _this=this;var p;var location=window.location;p=_this.param(location.search);if(p&&p.state&&(p.code||p.oauth_token)){try{var state=JSON.parse(p.state);p.redirect_uri=state.redirect_uri||location.href.replace(/[\?\#].*$/,"");var path=_this.qs(state.oauth_proxy,p);if(isValidUrl(path)){location.assign(path)}return}catch(e){console.error("Could not decode state parameter",e);return}}p=_this.merge(_this.param(location.search||""),_this.param(location.hash||""));if(p&&"state"in p){try{var a=JSON.parse(p.state);_this.extend(p,a)}catch(e){var stateDecoded=decodeURIComponent(p.state);try{var b=JSON.parse(stateDecoded);_this.extend(p,b)}catch(e){console.error("Could not decode state parameter")}}if("access_token"in p&&p.access_token&&p.network){if(!p.expires_in||parseInt(p.expires_in,10)===0){p.expires_in=0}p.expires_in=parseInt(p.expires_in,10);p.expires=(new Date).getTime()/1e3+(p.expires_in||60*60*24*365);authCallback(p,window,parent)}else if("error"in p&&p.error&&p.network){p.error={code:p.error,message:p.error_message||p.error_description};authCallback(p,window,parent)}else if(p.callback&&p.callback in parent){var res="result"in p&&p.result?JSON.parse(p.result):false;callback(parent,p.callback)(res);closeWindow()}if(p.page_uri&&isValidUrl(p.page_uri)){location.assign(p.page_uri)}}else if("oauth_redirect"in p){var url=decodeURIComponent(p.oauth_redirect);if(isValidUrl(url)){location.assign(url)}return}function isValidUrl(url){var regexp=/^https?:/;return regexp.test(url)&&(!Object.prototype.hasOwnProperty.call(window,"HELLOJS_REDIRECT_URL")||url.match(window.HELLOJS_REDIRECT_URL))}function authCallback(obj,window,parent){var cb=obj.callback;var network=obj.network;_this.store(network,obj);if("display"in obj&&obj.display==="page"){return}if(parent&&cb&&cb in parent){try{delete obj.callback}catch(e){}_this.store(network,obj);var str=JSON.stringify(obj);try{callback(parent,cb)(str)}catch(e){}}closeWindow()}function callback(parent,callbackID){if(callbackID.indexOf("_hellojs_")!==0){return function(){throw"Could not execute callback "+callbackID}}return parent[callbackID]}function closeWindow(){if(window.frameElement){parent.document.body.removeChild(window.frameElement)}else{try{window.close()}catch(e){}if(window.addEventListener){window.addEventListener("load",function(){window.close()})}}}}});hello.utils.Event.call(hello);(function(hello){var oldSessions={};var expired={};hello.on("auth.login, auth.logout",function(auth){if(auth&&typeof auth==="object"&&auth.network){oldSessions[auth.network]=hello.utils.store(auth.network)||{}}});(function self(){var CURRENT_TIME=(new Date).getTime()/1e3;var emit=function(eventName){hello.emit("auth."+eventName,{network:name,authResponse:session})};for(var name in hello.services){if(hello.services.hasOwnProperty(name)){if(!hello.services[name].id){continue}var session=hello.utils.store(name)||{};var provider=hello.services[name];var oldSess=oldSessions[name]||{};if(session&&"callback"in session){var cb=session.callback;try{delete session.callback}catch(e){}hello.utils.store(name,session);try{window[cb](session)}catch(e){}}if(session&&"expires"in session&&session.expires<CURRENT_TIME){var refresh=provider.refresh||session.refresh_token;if(refresh&&(!(name in expired)||expired[name]<CURRENT_TIME)){hello.emit("notice",name+" has expired trying to resignin");hello.login(name,{display:"none",force:false});expired[name]=CURRENT_TIME+600}else if(!refresh&&!(name in expired)){emit("expired");expired[name]=true}continue}else if(oldSess.access_token===session.access_token&&oldSess.expires===session.expires){continue}else if(!session.access_token&&oldSess.access_token){emit("logout")}else if(session.access_token&&!oldSess.access_token){emit("login")}else if(session.expires!==oldSess.expires){emit("update")}oldSessions[name]=session;if(name in expired){delete expired[name]}}}setTimeout(self,1e3)})()})(hello);hello.api=function(){var _this=this;var utils=_this.utils;var error=utils.error;var promise=utils.Promise();var p=utils.args({path:"s!",query:"o",method:"s",data:"o",timeout:"i",callback:"f"},arguments);p.method=(p.method||"get").toLowerCase();p.headers=p.headers||{};p.query=p.query||{};if(p.method==="get"||p.method==="delete"){utils.extend(p.query,p.data);p.data={}}var data=p.data=p.data||{};promise.then(p.callback,p.callback);if(!p.path){return promise.reject(error("invalid_path","Missing the path parameter from the request"))}p.path=p.path.replace(/^\/+/,"");var a=(p.path.split(/[\/\:]/,2)||[])[0].toLowerCase();if(a in _this.services){p.network=a;var reg=new RegExp("^"+a+":?/?");p.path=p.path.replace(reg,"")}p.network=_this.settings.default_service=p.network||_this.settings.default_service;var o=_this.services[p.network];if(!o){return promise.reject(error("invalid_network","Could not match the service requested: "+p.network))}if(!(!(p.method in o)||!(p.path in o[p.method])||o[p.method][p.path]!==false)){return promise.reject(error("invalid_path","The provided path is not available on the selected network"))}if(!p.oauth_proxy){p.oauth_proxy=_this.settings.oauth_proxy}if(!("proxy"in p)){p.proxy=p.oauth_proxy&&o.oauth&&parseInt(o.oauth.version,10)===1}if(!("timeout"in p)){p.timeout=_this.settings.timeout}if(!("formatResponse"in p)){p.formatResponse=true}p.authResponse=_this.getAuthResponse(p.network);if(p.authResponse&&p.authResponse.access_token){p.query.access_token=p.authResponse.access_token}var url=p.path;var m;p.options=utils.clone(p.query);p.data=utils.clone(data);var actions=o[{delete:"del"}[p.method]||p.method]||{};if(p.method==="get"){var query=url.split(/[\?#]/)[1];if(query){utils.extend(p.query,utils.param(query));url=url.replace(/\?.*?(#|$)/,"$1")}}if(m=url.match(/#(.+)/,"")){url=url.split("#")[0];p.path=m[1]}else if(url in actions){p.path=url;url=actions[url]}else if("default"in actions){url=actions["default"]}p.redirect_uri=_this.settings.redirect_uri;p.xhr=o.xhr;p.jsonp=o.jsonp;p.form=o.form;if(typeof url==="function"){url(p,getPath)}else{getPath(url)}return promise.proxy;function getPath(url){url=url.replace(/\@\{([a-z\_\-]+)(\|.*?)?\}/gi,function(m,key,defaults){var val=defaults?defaults.replace(/^\|/,""):"";if(key in p.query){val=p.query[key];delete p.query[key]}else if(p.data&&key in p.data){val=p.data[key];delete p.data[key]}else if(!defaults){promise.reject(error("missing_attribute","The attribute "+key+" is missing from the request"))}return val});if(!url.match(/^https?:\/\//)){url=o.base+url}p.url=url;utils.request(p,function(r,headers){if(!p.formatResponse){if(typeof headers==="object"?headers.statusCode>=400:typeof r==="object"&&"error"in r){promise.reject(r)}else{promise.fulfill(r)}return}if(r===true){r={success:true}}else if(!r){r={}}if(p.method==="delete"){r=!r||utils.isEmpty(r)?{success:true}:r}if(o.wrap&&(p.path in o.wrap||"default"in o.wrap)){var wrap=p.path in o.wrap?p.path:"default";var time=(new Date).getTime();var b=o.wrap[wrap](r,headers,p);if(b){r=b}}if(r&&"paging"in r&&r.paging.next){if(r.paging.next[0]==="?"){r.paging.next=p.path+r.paging.next}else{r.paging.next+="#"+p.path}}if(!r||"error"in r){promise.reject(r)}else{promise.fulfill(r)}})}};hello.utils.extend(hello.utils,{request:function(p,callback){var _this=this;var error=_this.error;if(!_this.isEmpty(p.data)&&!("FileList"in window)&&_this.hasBinary(p.data)){p.xhr=false;p.jsonp=false}var cors=this.request_cors(function(){return p.xhr===undefined||p.xhr&&(typeof p.xhr!=="function"||p.xhr(p,p.query))});if(cors){formatUrl(p,function(url){var x=_this.xhr(p.method,url,p.headers,p.data,callback);x.onprogress=p.onprogress||null;if(x.upload&&p.onuploadprogress){x.upload.onprogress=p.onuploadprogress}});return}var _query=p.query;p.query=_this.clone(p.query);p.callbackID=_this.globalEvent();if(p.jsonp!==false){p.query.callback=p.callbackID;if(typeof p.jsonp==="function"){p.jsonp(p,p.query)}if(p.method==="get"){formatUrl(p,function(url){_this.jsonp(url,callback,p.callbackID,p.timeout)});return}else{p.query=_query}}if(p.form!==false){p.query.redirect_uri=p.redirect_uri;p.query.state=JSON.stringify({callback:p.callbackID});var opts;if(typeof p.form==="function"){opts=p.form(p,p.query)}if(p.method==="post"&&opts!==false){formatUrl(p,function(url){_this.post(url,p.data,opts,callback,p.callbackID,p.timeout)});return}}callback(error("invalid_request","There was no mechanism for handling this request"));return;function formatUrl(p,callback){var sign;if(p.authResponse&&p.authResponse.oauth&&parseInt(p.authResponse.oauth.version,10)===1){sign=p.query.access_token;delete p.query.access_token;p.proxy=true}if(p.data&&(p.method==="get"||p.method==="delete")){_this.extend(p.query,p.data);p.data=null}var path=_this.qs(p.url,p.query);if(p.proxy){path=_this.qs(p.oauth_proxy,{path:path,access_token:sign||"",then:p.proxy_response_type||(p.method.toLowerCase()==="get"?"redirect":"proxy"),method:p.method.toLowerCase(),suppress_response_codes:p.suppress_response_codes||true})}callback(path)}},request_cors:function(callback){return"withCredentials"in new XMLHttpRequest&&callback()},domInstance:function(type,data){var test="HTML"+(type||"").replace(/^[a-z]/,function(m){return m.toUpperCase()})+"Element";if(!data){return false}if(window[test]){return data instanceof window[test]}else if(window.Element){return data instanceof window.Element&&(!type||data.tagName&&data.tagName.toLowerCase()===type)}else{return!(data instanceof Object||data instanceof Array||data instanceof String||data instanceof Number)&&data.tagName&&data.tagName.toLowerCase()===type}},clone:function(obj){if(obj===null||typeof obj!=="object"||obj instanceof Date||"nodeName"in obj||this.isBinary(obj)||typeof FormData==="function"&&obj instanceof FormData){return obj}if(Array.isArray(obj)){return obj.map(this.clone.bind(this))}var clone={};for(var x in obj){clone[x]=this.clone(obj[x])}return clone},xhr:function(method,url,headers,data,callback){var r=new XMLHttpRequest;var error=this.error;var binary=false;if(method==="blob"){binary=method;method="GET"}method=method.toUpperCase();r.onload=function(e){var json=r.response;try{json=JSON.parse(r.responseText)}catch(_e){if(r.status===401){json=error("access_denied",r.statusText)}}var headers=headersToJSON(r.getAllResponseHeaders());headers.statusCode=r.status;callback(json||(method==="GET"?error("empty_response","Could not get resource"):{}),headers)};r.onerror=function(e){var json=r.responseText;try{json=JSON.parse(r.responseText)}catch(_e){}callback(json||error("access_denied","Could not get resource"))};var x;if(method==="GET"||method==="DELETE"){data=null}else if(data&&typeof data!=="string"&&!(data instanceof FormData)&&!(data instanceof File)&&!(data instanceof Blob)){var f=new FormData;for(x in data)if(data.hasOwnProperty(x)){if(data[x]instanceof HTMLInputElement){if("files"in data[x]&&data[x].files.length>0){f.append(x,data[x].files[0])}}else if(data[x]instanceof Blob){f.append(x,data[x],data.name)}else{f.append(x,data[x])}}data=f}r.open(method,url,true);if(binary){if("responseType"in r){r.responseType=binary}else{r.overrideMimeType("text/plain; charset=x-user-defined")}}if(headers){for(x in headers){r.setRequestHeader(x,headers[x])}}r.send(data);return r;function headersToJSON(s){var r={};var reg=/([a-z\-]+):\s?(.*);?/gi;var m;while(m=reg.exec(s)){r[m[1]]=m[2]}return r}},jsonp:function(url,callback,callbackID,timeout){var _this=this;var error=_this.error;var bool=0;var head=document.getElementsByTagName("head")[0];var operaFix;var result=error("server_error","server_error");var cb=function(){if(!bool++){window.setTimeout(function(){callback(result);head.removeChild(script)},0)}};callbackID=_this.globalEvent(function(json){result=json;return true},callbackID);url=url.replace(new RegExp("=\\?(&|$)"),"="+callbackID+"$1");var script=_this.append("script",{id:callbackID,name:callbackID,src:url,async:true,onload:cb,onerror:cb,onreadystatechange:function(){if(/loaded|complete/i.test(this.readyState)){cb()}}});if(window.navigator.userAgent.toLowerCase().indexOf("opera")>-1){operaFix=_this.append("script",{text:"document.getElementById('"+callbackID+"').onerror();"});script.async=false}if(timeout){window.setTimeout(function(){result=error("timeout","timeout");cb()},timeout)}head.appendChild(script);if(operaFix){head.appendChild(operaFix)}},post:function(url,data,options,callback,callbackID,timeout){var _this=this;var error=_this.error;var doc=document;var form=null;var reenableAfterSubmit=[];var newform;var i=0;var x=null;var bool=0;var cb=function(r){if(!bool++){callback(r)}};_this.globalEvent(cb,callbackID);var win;try{win=doc.createElement('<iframe name="'+callbackID+'">')}catch(e){win=doc.createElement("iframe")}win.name=callbackID;win.id=callbackID;win.style.display="none";if(options&&options.callbackonload){win.onload=function(){cb({response:"posted",message:"Content was posted"})}}if(timeout){setTimeout(function(){cb(error("timeout","The post operation timed out"))},timeout)}doc.body.appendChild(win);if(_this.domInstance("form",data)){form=data.form;for(i=0;i<form.elements.length;i++){if(form.elements[i]!==data){form.elements[i].setAttribute("disabled",true)}}data=form}if(_this.domInstance("form",data)){form=data;for(i=0;i<form.elements.length;i++){if(!form.elements[i].disabled&&form.elements[i].type==="file"){form.encoding=form.enctype="multipart/form-data";form.elements[i].setAttribute("name","file")}}}else{for(x in data)if(data.hasOwnProperty(x)){if(_this.domInstance("input",data[x])&&data[x].type==="file"){form=data[x].form;form.encoding=form.enctype="multipart/form-data"}}if(!form){form=doc.createElement("form");doc.body.appendChild(form);newform=form}var input;for(x in data)if(data.hasOwnProperty(x)){var el=_this.domInstance("input",data[x])||_this.domInstance("textArea",data[x])||_this.domInstance("select",data[x]);if(!el||data[x].form!==form){var inputs=form.elements[x];if(input){if(!(inputs instanceof NodeList)){inputs=[inputs]}for(i=0;i<inputs.length;i++){inputs[i].parentNode.removeChild(inputs[i])}}input=doc.createElement("input");input.setAttribute("type","hidden");input.setAttribute("name",x);if(el){input.value=data[x].value}else if(_this.domInstance(null,data[x])){input.value=data[x].innerHTML||data[x].innerText}else{input.value=data[x]}form.appendChild(input)}else if(el&&data[x].name!==x){data[x].setAttribute("name",x);data[x].name=x}}for(i=0;i<form.elements.length;i++){input=form.elements[i];if(!(input.name in data)&&input.getAttribute("disabled")!==true){input.setAttribute("disabled",true);reenableAfterSubmit.push(input)}}}form.setAttribute("method","POST");form.setAttribute("target",callbackID);form.target=callbackID;form.setAttribute("action",url);setTimeout(function(){form.submit();setTimeout(function(){try{if(newform){newform.parentNode.removeChild(newform)}}catch(e){try{console.error("HelloJS: could not remove iframe")}catch(ee){}}for(var i=0;i<reenableAfterSubmit.length;i++){if(reenableAfterSubmit[i]){reenableAfterSubmit[i].setAttribute("disabled",false);reenableAfterSubmit[i].disabled=false}}},0)},100)},hasBinary:function(data){for(var x in data)if(data.hasOwnProperty(x)){if(this.isBinary(data[x])){return true}}return false},isBinary:function(data){return data instanceof Object&&(this.domInstance("input",data)&&data.type==="file"||"FileList"in window&&data instanceof window.FileList||"File"in window&&data instanceof window.File||"Blob"in window&&data instanceof window.Blob)},toBlob:function(dataURI){var reg=/^data\:([^;,]+(\;charset=[^;,]+)?)(\;base64)?,/i;var m=dataURI.match(reg);if(!m){return dataURI}var binary=atob(dataURI.replace(reg,""));var array=[];for(var i=0;i<binary.length;i++){array.push(binary.charCodeAt(i))}return new Blob([new Uint8Array(array)],{type:m[1]})}});(function(hello){var api=hello.api;var utils=hello.utils;utils.extend(utils,{dataToJSON:function(p){var _this=this;var w=window;var data=p.data;if(_this.domInstance("form",data)){data=_this.nodeListToJSON(data.elements)}else if("NodeList"in w&&data instanceof NodeList){data=_this.nodeListToJSON(data)}else if(_this.domInstance("input",data)){data=_this.nodeListToJSON([data])}if("File"in w&&data instanceof w.File||"Blob"in w&&data instanceof w.Blob||"FileList"in w&&data instanceof w.FileList){data={file:data}}if(!("FormData"in w&&data instanceof w.FormData)){for(var x in data)if(data.hasOwnProperty(x)){if("FileList"in w&&data[x]instanceof w.FileList){if(data[x].length===1){data[x]=data[x][0]}}else if(_this.domInstance("input",data[x])&&data[x].type==="file"){continue}else if(_this.domInstance("input",data[x])||_this.domInstance("select",data[x])||_this.domInstance("textArea",data[x])){data[x]=data[x].value}else if(_this.domInstance(null,data[x])){data[x]=data[x].innerHTML||data[x].innerText}}}p.data=data;return data},nodeListToJSON:function(nodelist){var json={};for(var i=0;i<nodelist.length;i++){var input=nodelist[i];if(input.disabled||!input.name){continue}if(input.type==="file"){json[input.name]=input}else{json[input.name]=input.value||input.innerHTML}}return json}});hello.api=function(){var p=utils.args({path:"s!",method:"s",data:"o",timeout:"i",callback:"f"},arguments);if(p.data){utils.dataToJSON(p)}return api.call(this,p)}})(hello);hello.utils.responseHandler(window,window.opener||window.parent);if(typeof chrome==="object"&&typeof chrome.identity==="object"&&chrome.identity.launchWebAuthFlow){(function(){hello.utils.popup=function(url){return _open(url,true)};hello.utils.iframe=function(url){_open(url,false)};hello.utils.request_cors=function(callback){callback();return true};var _cache={};chrome.storage.local.get("hello",function(r){_cache=r.hello||{}});hello.utils.store=function(name,value){if(arguments.length===0){return _cache}if(arguments.length===1){return _cache[name]||null}if(value){_cache[name]=value;chrome.storage.local.set({hello:_cache});return value}if(value===null){delete _cache[name];chrome.storage.local.set({hello:_cache});return null}};function _open(url,interactive){var ref={closed:false};chrome.identity.launchWebAuthFlow({url:url,interactive:interactive},function(responseUrl){if(responseUrl===undefined){ref.closed=true;return}var a=hello.utils.url(responseUrl);var _popup={location:{assign:function(url){_open(url,false)},search:a.search,hash:a.hash,href:a.href},close:function(){}};hello.utils.responseHandler(_popup,window)});return ref}})()}(function(){if(!(/^file:\/{3}[^\/]/.test(window.location.href)&&window.cordova)){return}hello.utils.iframe=function(url,redirectUri){hello.utils.popup(url,redirectUri,{hidden:"yes"})};var utilPopup=hello.utils.popup;hello.utils.popup=function(url,redirectUri,options){var popup=utilPopup.call(this,url,redirectUri,options);try{if(popup&&popup.addEventListener){var a=hello.utils.url(redirectUri);var redirectUriOrigin=a.origin||a.protocol+"//"+a.hostname;popup.addEventListener("loadstart",function(e){var url=e.url;if(url.indexOf(redirectUriOrigin)!==0){return}var a=hello.utils.url(url);var _popup={location:{assign:function(location){popup.executeScript({code:'window.location.href = "'+location+';"'})},search:a.search,hash:a.hash,href:a.href},close:function(){if(popup.close){popup.close();try{popup.closed=true}catch(_e){}}}};hello.utils.responseHandler(_popup,window)})}}catch(e){}return popup}})();if(typeof define==="function"&&define.amd){define(function(){return hello})}if(typeof module==="object"&&module.exports){module.exports=hello}