diff --git a/README.md b/README.md deleted file mode 100644 index 2ce477a..0000000 --- a/README.md +++ /dev/null @@ -1,80 +0,0 @@ -Session.js -== - -Gives information about the current session. - -To use: include the file session.js, then access the visitor object. -It uses the google javascript loader to get location data. -For async loading, use the window.session_loaded callback. - -To add more fields, add or remove included modules and options near the bottom of the js file. - - -API demo dump of `window.session`: -
-  {
-    "api_version": 0.2,
-    "locale": {
-      "country": "US",
-      "lang": "en"
-    },
-    "cur_session": {
-      "visits": 1,
-      "search": {
-        "engine": null,
-        "query": null
-      },
-      "referrer": "",
-      "url": "http://localhost:8000/demo.html",
-      "path": "/demo.html",
-      "start": 1325893718929,
-      "last_visit": 1325893718929
-    },
-    "orig_session": {
-      "visits": 20,
-      "search": {
-        "engine": null,
-        "query": null
-      },
-      "referrer": "http://localhost:8000/",
-      "url": "http://localhost:8000/test_visitor.html",
-      "path": "/test_visitor.html",
-      "start": 1325886709703,
-      "last_visit": 1325893718932
-    },
-    "browser": {
-      "browser": "Chrome",
-      "version": 16,
-      "OS": "Mac"
-    },
-    "plugins": {
-      "flash": true,
-      "silverlight": true,
-      "java": true,
-      "quicktime": true
-    },
-    "device": {
-      "screen": {
-        "width": 1280,
-        "height": 1024
-      },
-      "viewport": {
-        "width": 1206,
-        "height": 816
-      },
-      "is_phone": false,
-      "is_tablet": false,
-      "is_mobile": false
-    },
-    "location": {
-      "latitude": 35.046,
-      "longitude": -85.31,
-      "address": {
-        "city": "Chattanooga",
-        "region": "TN",
-        "country": "USA",
-        "country_code": "US"
-      }
-    }
-  }
-
diff --git a/demo.html b/demo.html deleted file mode 100644 index 9f484c7..0000000 --- a/demo.html +++ /dev/null @@ -1,19 +0,0 @@ - - - - - -

Session.js demo

-

Demo output:

-
-  
-  
- - - - diff --git a/example.html b/example.html new file mode 100644 index 0000000..ed51501 --- /dev/null +++ b/example.html @@ -0,0 +1,61 @@ + + + + + Session.js example usage + + +

Session.js Example Usage:

+
Info:
+
loading motd...
+

+ View Example Source +

+
+

About

+

Session.js is a javascript library that lets you customize your page according to the current session.

+

Such an example would be autosuggesting location box values, or timezones, based on either location or system settings returned by javascript.

+

For more information, check out the github project page or the API demo.

+
+ + + + + diff --git a/index.html b/index.html new file mode 100644 index 0000000..d7f1118 --- /dev/null +++ b/index.html @@ -0,0 +1,153 @@ + + + Demo for Session.js + + + + +

Session.js Demo Page

+

Demo output:

+
+    loading...
+  
+ +

Session.JS on GitHub by Iain

+ + + + diff --git a/ipinfodb_demo.html b/ipinfodb_demo.html new file mode 100644 index 0000000..1e05175 --- /dev/null +++ b/ipinfodb_demo.html @@ -0,0 +1,162 @@ + + + Demo for Session.js + + + + +

Session.js Demo Page

+

Using ipinfodb for location lookup

+

Demo output:

+
+    loading...
+  
+ +

Session.JS on GitHub by Iain

+ + + + + diff --git a/pack.sh b/pack.sh deleted file mode 100755 index e43c0ce..0000000 --- a/pack.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -echo 'Packing session.js to session.min.js' -uglifyjs session.js > session.min.js diff --git a/session-0.4.js b/session-0.4.js new file mode 100644 index 0000000..b618452 --- /dev/null +++ b/session-0.4.js @@ -0,0 +1,414 @@ +/** + * session.js 0.4.1 + * (c) 2012 Iain, CodeJoust + * session.js is freely distributable under the MIT license. + * Portions of session.js are inspired or borrowed from Underscore.js, and quirksmode.org demo javascript. + * This version uses google's jsapi library for location services. + * For details, see: https://github.com/codejoust/session.js + */ +(function(win, doc, nav){ + // Changing the API Version invalidates olde cookies with previous api version tags. + var API_VERSION = 0.4; + + // Settings: defaults + var options = { + // Use the HTML5 Geolocation API + // this ONLY returns lat & long, no city/address + use_html5_location: false, + // Attempts to use IPInfoDB if provided a valid key + // Get a key at http://ipinfodb.com/register.php + ipinfodb_key: false, + // Leaving true allows for fallback for both + // the HTML5 location and the IPInfoDB + gapi_location: true, + // Name of the location cookie (set blank to disable cookie) + // - WARNING: different providers use the same cookie + // - if switching providers, remember to use another cookie or provide checks for old cookies + location_cookie: "location", + // Location cookie expiration in hours + location_cookie_timeout: 5, + // Session expiration in days + session_timeout: 32, + // Session cookie name (set blank to disable cookie) + session_cookie: "first_session" + }; + + // Session object + var SessionRunner = function(){ + // Helper for querying. + // Usage: session.current_session.referrer_info.hostname.contains(['github.com','news.ycombinator.com']) + String.prototype.contains = function(other_str){ + if (typeof(other_str) === 'string'){ + return (this.indexOf(other_str) !== -1); } + for (var i = 0; i < other_str.length; i++){ + if (this.indexOf(other_str[i]) !== -1){ return true; } } + return false; } + // Merge options + if (win.session && win.session.options) { + for (option in win.session.options){ + options[option] = win.session.options[option]; } + } + // Modules to run + // If the module has arguments, + // it _needs_ to return a callback function. + var unloaded_modules = { + api_version: API_VERSION, + locale: modules.locale(), + current_session: modules.session(), + original_session: modules.session( + options.session_cookie, + options.session_timeout * 24 * 60 * 60 * 1000), + browser: modules.browser(), + plugins: modules.plugins(), + time: modules.time(), + device: modules.device() + }; + // Location switch + if (options.use_html5_location){ + unloaded_modules.location = modules.html5_location(); + } else if (options.ipinfodb_key){ + unloaded_modules.location = modules.ipinfodb_location(options.ipinfodb_key); + } else if (options.gapi_location){ + unloaded_modules.location = modules.gapi_location(); + } + // Cache win.session.start + if (win.session && win.session.start){ + var start = win.session.start; + } + // Set up checking, if all modules are ready + var asynchs = 0, module, result, + check_asynch = function(){ + if (asynchs === 0){ + // Run start calback + if (start){ start(win.session); } + } + }; + win.session = {}; + // Run asynchronous methods + for (var name in unloaded_modules){ + module = unloaded_modules[name]; + if (typeof module === "function"){ + try { + module(function(data){ + win.session[name] = data; + asynchs--; + check_asynch(); + }); + asynchs++; + } catch(err){ + if (win.console && typeof(console.log) === "function"){ + console.log(err); } + } + } else { + win.session[name] = module; + } } + check_asynch(); + }; + + + // Browser (and OS) detection + var browser = { + detect: function(){ + return { + browser: this.search(this.data.browser), + version: this.search(nav.userAgent) || this.search(nav.appVersion), + os: this.search(this.data.os) + } }, + search: function(data) { + if (typeof data === "object"){ + // search for string match + for(var i = 0; i < data.length; i++) { + var dataString = data[i].string, + dataProp = data[i].prop; + this.version_string = data[i].versionSearch || data[i].identity; + if (dataString){ + if (dataString.indexOf(data[i].subString) != -1){ + return data[i].identity; + } + } else if (dataProp){ + return data[i].identity; + } + } + } else { + // search for version number + var index = data.indexOf(this.version_string); + if (index == -1) return; + return parseFloat(data.substr(index + this.version_string.length + 1)); + } + }, + data: { + browser: [ + { string: nav.userAgent, subString: "Chrome", identity: "Chrome" }, + { string: nav.userAgent, subString: "OmniWeb", versionSearch: "OmniWeb/", identity: "OmniWeb" }, + { string: nav.vendor, subString: "Apple", identity: "Safari", versionSearch: "Version" }, + { prop: win.opera, identity: "Opera", versionSearch: "Version" }, + { string: nav.vendor, subString: "iCab",identity: "iCab" }, + { string: nav.vendor, subString: "KDE", identity: "Konqueror" }, + { string: nav.userAgent, subString: "Firefox", identity: "Firefox" }, + { string: nav.vendor, subString: "Camino", identity: "Camino" }, + { string: nav.userAgent, subString: "Netscape", identity: "Netscape" }, + { string: nav.userAgent, subString: "MSIE", identity: "Explorer", versionSearch: "MSIE" }, + { string: nav.userAgent, subString: "Gecko", identity: "Mozilla", versionSearch: "rv" }, + { string: nav.userAgent, subString: "Mozilla", identity: "Netscape", versionSearch: "Mozilla" } + ], + os: [ + { string: nav.platform, subString: "Win", identity: "Windows" }, + { string: nav.platform, subString: "Mac", identity: "Mac" }, + { string: nav.userAgent, subString: "iPhone", identity: "iPhone/iPod" }, + { string: nav.userAgent, subString: "iPad", identitiy: "iPad" }, + { string: nav.platform, subString: "Linux", identity: "Linux" }, + { string: nav.userAgent, subString: "Android", identity: "Android" } + ]} + }; + + var modules = { + browser: function(){ + return browser.detect(); + }, + time: function(){ + // split date and grab timezone estimation. + // timezone estimation: http://www.onlineaspect.com/2007/06/08/auto-detect-a-time-zone-with-javascript/ + var d1 = new Date(), d2 = new Date(); + d1.setMonth(0); d1.setDate(1); d2.setMonth(6); d2.setDate(1); + return({tz_offset: -(new Date().getTimezoneOffset()) / 60, observes_dst: (d1.getTimezoneOffset() !== d2.getTimezoneOffset()) }); + // Gives a browser estimation, not guaranteed to be correct. + }, + locale: function() { + var lang = ( + nav.language || + nav.browserLanguage || + nav.systemLanguage || + nav.userLanguage + ).split("-"); + if (lang.length == 2){ + return { country: lang[1].toLowerCase(), lang: lang[0].toLowerCase() }; + } else if (lang) { + return {lang: lang[0].toLowerCase(), country: null }; + } else { return{lang: null, country: null }; } + }, + device: function() { + var device = { + screen: { + width: screen.width, + height: screen.height + } + }; + var html = doc.documentElement, + body = doc.getElementsByTagName("body")[0]; + device.viewport = { + width: win.innerWidth || doc.documentElement.clientWidth || doc.body.clientWidth, + height: win.innerHeight || doc.documentElement.clientHeight || doc.body.clientHeight + }; + device.is_tablet = !!nav.userAgent.match(/(iPad|SCH-I800|xoom|kindle)/i); + device.is_phone = !device.isTablet && !!nav.userAgent.match(/(iPhone|iPod|blackberry|android 0.5|htc|lg|midp|mmp|mobile|nokia|opera mini|palm|pocket|psp|sgh|smartphone|symbian|treo mini|Playstation Portable|SonyEricsson|Samsung|MobileExplorer|PalmSource|Benq|Windows Phone|Windows Mobile|IEMobile|Windows CE|Nintendo Wii)/i); + device.is_mobile = (device.is_tablet || device.is_phone); + return device; + }, + plugins: function(){ + var check_plugin = function(name){ + if (nav.plugins){ + var plugin, i = 0, length = nav.plugins.length; + for (; i < length; i++ ){ + plugin = nav.plugins[i]; + if (plugin && plugin.name && plugin.name.toLowerCase().indexOf(name) !== -1){ + return true; + } } + return false; + } return false; + } + return { + flash: check_plugin("flash"), + silverlight: check_plugin("silverlight"), + java: check_plugin("java"), + quicktime: check_plugin("quicktime") + }; + }, + session: function (cookie, expires){ + var session = util.get_obj(cookie); + if (session == null){ + session = { + visits: 1, + start: new Date().getTime(), last_visit: new Date().getTime(), + url: win.location.href, path: win.location.pathname, + referrer: doc.referrer, referrer_info: util.parse_url(doc.referrer), + search: { engine: null, query: null } + }; + var search_engines = [ + { name: "Google", host: "google", query: "q" }, + { name: "Bing", host: "bing.com", query: "q" }, + { name: "Yahoo", host: "search.yahoo", query: "p" }, + { name: "AOL", host: "search.aol", query: "q" }, + { name: "Ask", host: "ask.com", query: "q" }, + { name: "Baidu", host: "baidu.com", query: "wd" } + ], length = search_engines.length, + engine, match, i = 0, + fallbacks = 'q query term p wd query text'.split(' '); + for (i = 0; i < length; i++){ + engine = search_engines[i]; + if (session.referrer_info.host.indexOf(engine.host) !== -1){ + session.search.engine = engine.name; + session.search.query = session.referrer_info.query[engine.query]; + session.search.terms = session.search.query ? session.search.query.split(" ") : null; + break; + } + } + if (session.search.engine === null && session.referrer_info.search.length > 1){ + for (i = 0; i < fallbacks.length; i++){ + var terms = session.referrer_info.query[fallbacks[i]]; + if (terms){ + session.search.engine = "Unknown"; + session.search.query = terms; session.search.terms = terms.split(" "); + break; + } + } + } + } else { + session.last_visit = new Date().getTime(); + session.visits++; + } + util.set_cookie(cookie, util.package_obj(session), expires); + return session; + }, + html5_location: function(){ + return function(callback){ + nav.geolocation.getCurrentPosition(function(pos){ + pos.source = 'html5'; + callback(pos); + }, function(err) { + if (options.gapi_location){ + modules.gapi_location()(callback); + } else { + callback({error: true, source: 'html5'}); } + }); + }; + }, + gapi_location: function(){ + return function(callback){ + var location = util.get_obj(options.location_cookie); + if (!location || location.source !== 'google'){ + win.gloader_ready = function() { + if ("google" in win){ + if (win.google.loader.ClientLocation){ + win.google.loader.ClientLocation.source = "google"; + callback(win.google.loader.ClientLocation); + } else { + callback({error: true, source: "google"}); + } + util.set_cookie( + options.location_cookie, + util.package_obj(win.google.loader.ClientLocation), + options.location_cookie_timeout * 60 * 60 * 1000); + }} + util.embed_script("https://www.google.com/jsapi?callback=gloader_ready"); + } else { + callback(location); + }} + }, + ipinfodb_location: function(api_key){ + return function (callback){ + var location_cookie = util.get_obj(options.location_cookie); + if (location_cookie && location_cookie.source === 'ipinfodb'){ callback(location_cookie); } + win.ipinfocb = function(data){ + if (data.statusCode === "OK"){ + data.source = "ipinfodb"; + util.set_cookie( + options.location_cookie, + util.package_obj(data), + options.location_cookie * 60 * 60 * 1000); + callback(data); + } else { + if (options.gapi_location){ return modules.gapi_location()(callback); } + else { callback({error: true, source: "ipinfodb", message: data.statusMessage}); } + }} + util.embed_script("http://api.ipinfodb.com/v3/ip-city/?key=" + api_key + "&format=json&callback=ipinfocb"); + }} + }; + + // Utilities + var util = { + parse_url: function(url_str){ + var a = doc.createElement("a"), query = {}; + a.href = url_str; query_str = a.search.substr(1); + // Disassemble query string + if (query_str != ''){ + var pairs = query_str.split("&"), i = 0, + length = pairs.length, parts; + for (; i < length; i++){ + parts = pairs[i].split("="); + if (parts.length === 2){ + query[parts[0]] = decodeURI(parts[1]); } + } + } + return { + host: a.host, + path: a.pathname, + protocol: a.protocol, + port: a.port === '' ? 80 : a.port, + search: a.search, + query: query } + }, + set_cookie: function(cname, value, expires, options){ // from jquery.cookie.js + if (!doc.cookie || !cname || !value){ return null; } + if (!options){ var options = {}; } + if (value === null || value === undefined){ expires = -1; } + if (expires){ options.expires = (new Date().getTime()) + expires; } + return (document.cookie = [ + encodeURIComponent(cname), '=', + encodeURIComponent(String(value)), + options.expires ? '; expires=' + new Date(options.expires).toUTCString() : '', // use expires attribute, max-age is not supported by IE + options.path ? '; path=' + options.path : '', + options.domain ? '; domain=' + options.domain : '', + (win.location && win.location.protocol === 'https:') ? '; secure' : '' + ].join('')); + }, + get_cookie: function(cookie_name, result){ // from jquery.cookie.js + return (result = new RegExp('(?:^|; )' + encodeURIComponent(cookie_name) + '=([^;]*)').exec(document.cookie)) ? decodeURIComponent(result[1]) : null; + }, + embed_script: function(url){ + var element = doc.createElement("script"); + element.type = "text/javascript"; + element.src = url; + doc.getElementsByTagName("body")[0].appendChild(element); + }, + package_obj: function (obj){ + obj.version = API_VERSION; + var ret = JSON.stringify(obj); + delete obj.version; return ret; + }, + get_obj: function(cookie_name){ + var obj; + try { obj = JSON.parse(util.get_cookie(cookie_name)); } catch(e){}; + if (obj && obj.version == API_VERSION){ + delete obj.version; return obj; + } + } + }; + + // JSON + var JSON = { + parse: (win.JSON && win.JSON.parse) || function(data){ + if (typeof data !== "string" || !data){ return null; } + return (new Function("return " + data))(); + }, + stringify: (win.JSON && win.JSON.stringify) || function(object){ + var type = typeof object; + if (type !== "object" || object === null) { + if (type === "string"){ return '"' + object + '"'; } + } else { + var k, v, json = [], + isArray = (object && object.constructor === Array); + for (k in object ) { + v = object[k]; type = typeof v; + if (type === "string") + v = '"' + v + '"'; + else if (type === "object" && v !== null) + v = this.stringify(v); + json.push((isArray ? "" : '"' + k + '":') + v); + } + return (isArray ? "[" : "{") + json.join(",") + (isArray ? "]" : "}"); + } } }; + + // Initialize SessionRunner + SessionRunner(); + +})(window, document, navigator); diff --git a/session-0.4.min.js b/session-0.4.min.js new file mode 100644 index 0000000..089cee5 --- /dev/null +++ b/session-0.4.min.js @@ -0,0 +1,8 @@ +/** + * session.js 0.4.1 + * (c) 2012 Iain, CodeJoust + * session.js is freely distributable under the MIT license. + * Portions of session.js are inspired or borrowed from Underscore.js, and quirksmode.org demo javascript. + * This version uses google's jsapi library for location services. + * For details, see: https://github.com/codejoust/session.js + */(function(e,t,n){var r=.4,i={use_html5_location:!1,ipinfodb_key:!1,gapi_location:!0,location_cookie:"location",location_cookie_timeout:5,session_timeout:32,session_cookie:"first_session"},s=function(){String.prototype.contains=function(e){if(typeof e=="string")return this.indexOf(e)!==-1;for(var t=0;t1)for(l=0;l 1){ + for (i = 0; i < fallbacks.length; i++){ + var terms = session.referrer_info.query[fallbacks[i]]; + if (terms){ + session.search.engine = "Unknown"; + session.search.query = terms; session.search.terms = terms.split(" "); + break; } - }); + } } - sess.referrer = doc.referrer; - sess.url = win.location.href; - sess.path = win.location.pathname; - sess.start = (new Date()).getTime(); - sess.last_visit = sess.start; - if (cookie_name){ utils.set_cookie(cookie_name, JSON.stringify(sess), expires); } } else { - sess = JSON.parse(sess); - sess.last_visit = (new Date()).getTime(); - sess.visits += 1; - utils.set_cookie(cookie_name, JSON.stringify(sess), expires) + session.prev_visit = session.last_visit; + session.last_visit = new Date().getTime(); + session.visits++; + session.time_since_last_visit = session.last_visit - session.prev_visit; } - return sess; - } - } - var session_loader = { - modules: { - locale: modules.locale(), - cur_session: modules.session(), - orig_session: modules.session('first_session', 1000 * 60 * 60 * 24 * (opts.session_days || 32)), - browser: modules.browser(), - plugins: modules.plugins(), - device: modules.device() + util.set_obj(cookie, session, expires); + return session; }, - init: function(){ - if (opts.enable_location){ - session_loader.modules['location'] = modules.location('location'); - } - // Setup session Object - var asyncs = 0, check_async = function(){ - if (asyncs == 0){ win.session_loaded && win.session_loaded(win.session); } + html5_location: function(){ + return function(callback){ + nav.geolocation.getCurrentPosition(function(pos){ + pos.source = 'html5'; + callback(pos); + }, function(err) { + if (options.gapi_location){ + modules.gapi_location()(callback); + } else { + callback({error: true, source: 'html5'}); } + }); }; - win.modules = session_loader.modules; - win.session = {api_version: 0.2} - for (module_name in session_loader.modules){ - (function(module_name){ - var module_runner = session_loader.modules[module_name]; - if (typeof(module_runner) === 'function'){ - //try { - var ret = module_runner; - if (typeof(ret) === 'function'){ - asyncs++; - ret(function(data){ - win.session[module_name] = data; - asyncs--; - check_async(); - }); + }, + gapi_location: function(){ + return function(callback){ + var location = util.get_obj(options.location_cookie); + if (!location || location.source !== 'google'){ + win.gloader_ready = function() { + if ("google" in win){ + if (win.google.loader.ClientLocation){ + win.google.loader.ClientLocation.source = "google"; + callback(win.google.loader.ClientLocation); } else { - win.session[module_name] = ret; + callback({error: true, source: "google"}); } - //} catch (e) { if (typeof(console) !== 'undefined'){ console.log(e); } } + util.set_obj( + options.location_cookie, + win.google.loader.ClientLocation, + options.location_cookie_timeout * 60 * 60 * 1000); + }}; + util.embed_script("https://www.google.com/jsapi?callback=gloader_ready"); + } else { + callback(location); + }}; + }, + architecture: function(){ + var arch = n.userAgent.match(/x86_64|Win64|WOW64|x86-64|x64\;|AMD64|amd64/) || + (n.cpuClass === 'x64') ? 'x64' : 'x86'; + return { + arch: arch, + is_x64: arch == 'x64', + is_x86: arch == 'x68' + } + }, + ipinfodb_location: function(api_key){ + return function (callback){ + var location_cookie = util.get_obj(options.location_cookie); + if (!location_cookie && location_cookie.source === 'ipinfodb'){ + win.ipinfocb = function(data){ + if (data.statusCode === "OK"){ + data.source = "ipinfodb"; + util.set_obj( + options.location_cookie, + data, + options.location_cookie * 60 * 60 * 1000); + callback(data); } else { - win.session[module_name] = module_runner; - } - })(module_name); + if (options.gapi_location){ return modules.gapi_location()(callback); } + else { callback({error: true, source: "ipinfodb", message: data.statusMessage}); } + }}; + util.embed_script("http://api.ipinfodb.com/v3/ip-city/?key=" + api_key + "&format=json&callback=ipinfocb"); + } else { callback(location_cookie); } + }} + }; + + // Utilities + var util = { + parse_url: function(url_str){ + var a = doc.createElement("a"), query = {}; + a.href = url_str; var query_str = a.search.substr(1); + // Disassemble query string + if (query_str != ''){ + var pairs = query_str.split("&"), i = 0, + length = pairs.length, parts; + for (; i < length; i++){ + parts = pairs[i].split("="); + if (parts.length === 2){ + query[parts[0]] = decodeURI(parts[1]); } + } + } + return { + host: a.host, + path: a.pathname, + protocol: a.protocol, + port: a.port === '' ? 80 : a.port, + search: a.search, + query: query } + }, + set_cookie: function(cname, value, expires, options){ // from jquery.cookie.js + if (!cname){ return null; } + if (!options){ options = {}; } + if (value === null || value === undefined){ expires = -1; } + if (expires){ options.expires = (new Date().getTime()) + expires; } + return (doc.cookie = [ + encodeURIComponent(cname), '=', + encodeURIComponent(String(value)), + options.expires ? '; expires=' + new Date(options.expires).toUTCString() : '', // use expires attribute, max-age is not supported by IE + '; path=' + (options.path ? options.path : '/'), + options.domain ? '; domain=' + options.domain : '', + (win.location && win.location.protocol === 'https:') ? '; secure' : '' + ].join('')); + }, + get_cookie: function(cookie_name, result){ // from jquery.cookie.js + return (result = new RegExp('(?:^|; )' + encodeURIComponent(cookie_name) + '=([^;]*)').exec(doc.cookie)) ? decodeURIComponent(result[1]) : null; + }, + embed_script: function(url){ + var element = doc.createElement("script"); + element.type = "text/javascript"; + element.src = url; + doc.getElementsByTagName("body")[0].appendChild(element); + }, + package_obj: function (obj){ + if(obj) { + obj.version = API_VERSION; + var ret = JSON.stringify(obj); + delete obj.version; + return ret; + } + }, + set_obj: function(cname, value, expires, options){ + util.set_cookie(cname, util.package_obj(value), expires, options); + }, + get_obj: function(cookie_name){ + var obj; + try { obj = JSON.parse(util.get_cookie(cookie_name)); } catch(e){} + if (obj && obj.version == API_VERSION){ + delete obj.version; return obj; } } }; - session_loader.init(); -})(window, document); + + // cookie options override + if (options.get_object != null){ + util.get_obj = options['get_object']; } + if (options.set_object != null){ + util.set_obj = options['set_object']; } + + // JSON + var JSON = { + parse: (win.JSON && win.JSON.parse) || function(data){ + if (typeof data !== "string" || !data){ return null; } + return (new Function("return " + data))(); + }, + stringify: (win.JSON && win.JSON.stringify) || function(object){ + var type = typeof object; + if (type !== "object" || object === null) { + if (type === "string"){ return '"' + object + '"'; } + } else { + var k, v, json = [], + isArray = (object && object.constructor === Array); + for (k in object ) { + v = object[k]; type = typeof v; + if (type === "string") + v = '"' + v + '"'; + else if (type === "object" && v !== null) + v = this.stringify(v); + json.push((isArray ? "" : '"' + k + '":') + v); + } + return (isArray ? "[" : "{") + json.join(",") + (isArray ? "]" : "}"); + } } }; + + // Initialize SessionRunner + SessionRunner(); + +}); +// Switch for testing purposes. +if (typeof(window.exports) === 'undefined'){ + session_fetch(window, document, navigator); +} else { + window.exports.session = session_fetch; +} diff --git a/session.min.js b/session.min.js index 7b1feea..85b992c 100644 --- a/session.min.js +++ b/session.min.js @@ -1,8 +1 @@ -/** - * session.js 0.0.2 - * (c) 2012 Iain, CodeJoust - * session is freely distributable under the MIT license. - * Portions of session.js are inspired or borrowed from Underscore.js, and quirksmode.org demo javascript. - * This version uses google's jsapi library for location services. - * For details, see: https://github.com/codejoust/session.js - */(function(win,doc){var opts={enable_location:!0,session_days:32};"session_opts"in window&&(opts=session_opts);var BrowserDetect={detect_browser:function(){return{browser:this.searchString(this.dataBrowser),version:this.searchVersion(navigator.userAgent)||this.searchVersion(navigator.appVersion),OS:this.searchString(this.dataOS)}},searchString:function(a){for(var b=0;b0){c_start=document.cookie.indexOf(a+"=");if(c_start!=-1){c_start=c_start+a.length+1,c_end=document.cookie.indexOf(";",c_start),c_end==-1&&(c_end=document.cookie.length);return unescape(document.cookie.substring(c_start,c_end))}}return null},each:function(a,b,c){if(a!=null)if(a.length===+a.length){for(var d=0,e=a.length;d1){for(i=0;i