/** * Copyright (c) 2005 - 2010, James Auldridge * All rights reserved. * * Licensed under the BSD, MIT, and GPL (your choice!) Licenses: * http://code.google.com/p/cookies/wiki/License * */ var jaaulde = window.jaaulde || {}; jaaulde.utils = jaaulde.utils || {}; jaaulde.utils.cookies = ( function() { var resolveOptions, assembleOptionsString, parseCookies, constructor, defaultOptions = { expiresAt: null, path: '/', domain: null, secure: false }; /** * resolveOptions - receive an options object and ensure all options are present and valid, replacing with defaults where necessary * * @access private * @static * @parameter Object options - optional options to start with * @return Object complete and valid options object */ resolveOptions = function( options ) { var returnValue, expireDate; if( typeof options !== 'object' || options === null ) { returnValue = defaultOptions; } else { returnValue = { expiresAt: defaultOptions.expiresAt, path: defaultOptions.path, domain: defaultOptions.domain, secure: defaultOptions.secure }; if( typeof options.expiresAt === 'object' && options.expiresAt instanceof Date ) { returnValue.expiresAt = options.expiresAt; } else if( typeof options.hoursToLive === 'number' && options.hoursToLive !== 0 ) { expireDate = new Date(); expireDate.setTime( expireDate.getTime() + ( options.hoursToLive * 60 * 60 * 1000 ) ); returnValue.expiresAt = expireDate; } if( typeof options.path === 'string' && options.path !== '' ) { returnValue.path = options.path; } if( typeof options.domain === 'string' && options.domain !== '' ) { returnValue.domain = options.domain; } if( options.secure === true ) { returnValue.secure = options.secure; } } return returnValue; }; /** * assembleOptionsString - analyze options and assemble appropriate string for setting a cookie with those options * * @access private * @static * @parameter options OBJECT - optional options to start with * @return STRING - complete and valid cookie setting options */ assembleOptionsString = function( options ) { options = resolveOptions( options ); return ( ( typeof options.expiresAt === 'object' && options.expiresAt instanceof Date ? '; expires=' + options.expiresAt.toGMTString() : '' ) + '; path=' + options.path + ( typeof options.domain === 'string' ? '; domain=' + options.domain : '' ) + ( options.secure === true ? '; secure' : '' ) ); }; /** * parseCookies - retrieve document.cookie string and break it into a hash with values decoded and unserialized * * @access private * @static * @return OBJECT - hash of cookies from document.cookie */ parseCookies = function() { var cookies = {}, i, pair, name, value, separated = document.cookie.split( ';' ), unparsedValue; for( i = 0; i < separated.length; i = i + 1 ) { pair = separated[i].split( '=' ); name = pair[0].replace( /^\s*/, '' ).replace( /\s*$/, '' ); try { value = decodeURIComponent( pair[1] ); } catch( e1 ) { value = pair[1]; } if( typeof JSON === 'object' && JSON !== null && typeof JSON.parse === 'function' ) { try { unparsedValue = value; value = JSON.parse( value ); } catch( e2 ) { value = unparsedValue; } } cookies[name] = value; } return cookies; }; constructor = function(){}; /** * get - get one, several, or all cookies * * @access public * @paramater Mixed cookieName - String:name of single cookie; Array:list of multiple cookie names; Void (no param):if you want all cookies * @return Mixed - Value of cookie as set; Null:if only one cookie is requested and is not found; Object:hash of multiple or all cookies (if multiple or all requested); */ constructor.prototype.get = function( cookieName ) { var returnValue, item, cookies = parseCookies(); if( typeof cookieName === 'string' ) { returnValue = ( typeof cookies[cookieName] !== 'undefined' ) ? cookies[cookieName] : null; } else if( typeof cookieName === 'object' && cookieName !== null ) { returnValue = {}; for( item in cookieName ) { if( typeof cookies[cookieName[item]] !== 'undefined' ) { returnValue[cookieName[item]] = cookies[cookieName[item]]; } else { returnValue[cookieName[item]] = null; } } } else { returnValue = cookies; } return returnValue; }; /** * filter - get array of cookies whose names match the provided RegExp * * @access public * @paramater Object RegExp - The regular expression to match against cookie names * @return Mixed - Object:hash of cookies whose names match the RegExp */ constructor.prototype.filter = function( cookieNameRegExp ) { var cookieName, returnValue = {}, cookies = parseCookies(); if( typeof cookieNameRegExp === 'string' ) { cookieNameRegExp = new RegExp( cookieNameRegExp ); } for( cookieName in cookies ) { if( cookieName.match( cookieNameRegExp ) ) { returnValue[cookieName] = cookies[cookieName]; } } return returnValue; }; /** * set - set or delete a cookie with desired options * * @access public * @paramater String cookieName - name of cookie to set * @paramater Mixed value - Any JS value. If not a string, will be JSON encoded; NULL to delete * @paramater Object options - optional list of cookie options to specify * @return void */ constructor.prototype.set = function( cookieName, value, options ) { if( typeof options !== 'object' || options === null ) { options = {}; } if( typeof value === 'undefined' || value === null ) { value = ''; options.hoursToLive = -8760; } else if( typeof value !== 'string' ) { if( typeof JSON === 'object' && JSON !== null && typeof JSON.stringify === 'function' ) { value = JSON.stringify( value ); } else { throw new Error( 'cookies.set() received non-string value and could not serialize.' ); } } var optionsString = assembleOptionsString( options ); document.cookie = cookieName + '=' + encodeURIComponent( value ) + optionsString; }; /** * del - delete a cookie (domain and path options must match those with which the cookie was set; this is really an alias for set() with parameters simplified for this use) * * @access public * @paramater MIxed cookieName - String name of cookie to delete, or Bool true to delete all * @paramater Object options - optional list of cookie options to specify ( path, domain ) * @return void */ constructor.prototype.del = function( cookieName, options ) { var allCookies = {}, name; if( typeof options !== 'object' || options === null ) { options = {}; } if( typeof cookieName === 'boolean' && cookieName === true ) { allCookies = this.get(); } else if( typeof cookieName === 'string' ) { allCookies[cookieName] = true; } for( name in allCookies ) { if( typeof name === 'string' && name !== '' ) { this.set( name, null, options ); } } }; /** * test - test whether the browser is accepting cookies * * @access public * @return Boolean */ constructor.prototype.test = function() { var returnValue = false, testName = 'cT', testValue = 'data'; this.set( testName, testValue ); if( this.get( testName ) === testValue ) { this.del( testName ); returnValue = true; } return returnValue; }; /** * setOptions - set default options for calls to cookie methods * * @access public * @param Object options - list of cookie options to specify * @return void */ constructor.prototype.setOptions = function( options ) { if( typeof options !== 'object' ) { options = null; } defaultOptions = resolveOptions( options ); }; return new constructor(); } )(); ( function() { if( window.jQuery ) { ( function( $ ) { $.cookies = jaaulde.utils.cookies; var extensions = { /** * $( 'selector' ).cookify - set the value of an input field, or the innerHTML of an element, to a cookie by the name or id of the field or element * (field or element MUST have name or id attribute) * * @access public * @param options OBJECT - list of cookie options to specify * @return jQuery */ cookify: function( options ) { return this.each( function() { var i, nameAttrs = ['name', 'id'], name, $this = $( this ), value; for( i in nameAttrs ) { if( ! isNaN( i ) ) { name = $this.attr( nameAttrs[ i ] ); if( typeof name === 'string' && name !== '' ) { if( $this.is( ':checkbox, :radio' ) ) { if( $this.attr( 'checked' ) ) { value = $this.val(); } } else if( $this.is( ':input' ) ) { value = $this.val(); } else { value = $this.html(); } if( typeof value !== 'string' || value === '' ) { value = null; } $.cookies.set( name, value, options ); break; } } } } ); }, /** * $( 'selector' ).cookieFill - set the value of an input field or the innerHTML of an element from a cookie by the name or id of the field or element * * @access public * @return jQuery */ cookieFill: function() { return this.each( function() { var n, getN, nameAttrs = ['name', 'id'], name, $this = $( this ), value; getN = function() { n = nameAttrs.pop(); return !! n; }; while( getN() ) { name = $this.attr( n ); if( typeof name === 'string' && name !== '' ) { value = $.cookies.get( name ); if( value !== null ) { if( $this.is( ':checkbox, :radio' ) ) { if( $this.val() === value ) { $this.attr( 'checked', 'checked' ); } else { $this.removeAttr( 'checked' ); } } else if( $this.is( ':input' ) ) { $this.val( value ); } else { $this.html( value ); } } break; } } } ); }, /** * $( 'selector' ).cookieBind - call cookie fill on matching elements, and bind their change events to cookify() * * @access public * @param options OBJECT - list of cookie options to specify * @return jQuery */ cookieBind: function( options ) { return this.each( function() { var $this = $( this ); $this.cookieFill().change( function() { $this.cookify( options ); } ); } ); } }; $.each( extensions, function( i ) { $.fn[i] = this; } ); } )( window.jQuery ); } } )();