better cookie library

This commit is contained in:
John Bintz 2011-11-25 10:20:13 -05:00
parent bde3536505
commit 9f2b6240f6
4 changed files with 711 additions and 44 deletions

View File

@ -2,7 +2,7 @@ Everything that I use JavaScript-wise goes in here, so I can pull it in to all m
Every other project is owned by the original owner, I'm just aggregating for my own convenience. Every other project is owned by the original owner, I'm just aggregating for my own convenience.
* [jquery.cookie.js](https://github.com/carhartl/jquery-cookie) * [jquery.cookies.js](http://code.google.com/p/cookies)
* [jquery.elastic.js](http://unwrongest.com/projects/elastic/) * [jquery.elastic.js](http://unwrongest.com/projects/elastic/)
* [jquery.viewport.js](https://github.com/borbit/jquery.viewport) * [jquery.viewport.js](https://github.com/borbit/jquery.viewport)
* [Better-Autocomplete](https://github.com/betamos/Better-Autocomplete) * [Better-Autocomplete](https://github.com/betamos/Better-Autocomplete)

View File

@ -12,8 +12,8 @@ def process_zip_url(url, &block)
end end
sources = { sources = {
'jquery.cookie' => [ 'jquery.cookies' => [
'https://raw.github.com/carhartl/jquery-cookie/master/jquery.cookie.js' 'http://cookies.googlecode.com/svn/trunk/jquery.cookies.js'
], ],
'jquery-elastic' => lambda { 'jquery-elastic' => lambda {
process_zip_url('http://jquery-elastic.googlecode.com/files/jquery.elastic-1.6.11.zip') do |entry| process_zip_url('http://jquery-elastic.googlecode.com/files/jquery.elastic-1.6.11.zip') do |entry|
@ -46,6 +46,8 @@ sources = {
desc 'Update verything' desc 'Update verything'
task :update do task :update do
rm_rf 'vendor/assets'
sources.each do |name, files| sources.each do |name, files|
case files case files
when Array when Array

View File

@ -1,41 +0,0 @@
/**
* jQuery Cookie plugin
*
* Copyright (c) 2010 Klaus Hartl (stilbuero.de)
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*
*/
jQuery.cookie = function (key, value, options) {
// key and at least value given, set cookie...
if (arguments.length > 1 && String(value) !== "[object Object]") {
options = jQuery.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() : '', // use expires attribute, max-age is not supported by IE
options.path ? '; path=' + options.path : '',
options.domain ? '; domain=' + options.domain : '',
options.secure ? '; secure' : ''
].join(''));
}
// key and possibly options given, get cookie...
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;
};

View File

@ -0,0 +1,706 @@
/**
* Copyright (c) 2005 - 2011, James Auldridge
* All rights reserved.
*
* Licensed under the BSD, MIT, and GPL (your choice!) Licenses:
* @link http://code.google.com/p/cookies/wiki/License
*
* Last eror free JSHint: 20110418 12:14
* @link http://jshint.com/
* Checked Options:
* Disallow bitwise operators
* Require curly braces around all blocks
* Require ===
* Require for..in statements to be filtered
* Require variables to be declared before usage
* Environment
* Browser
* jQuery
*/
( function( global )
{
"use strict";
var document, Object, jaaulde;
/*
* localize global variables which are used more than once
*/
document = global.document;
Object = global.Object;
/*
* jaaulde Namespace preparation - the only var introduced into global space
*/
jaaulde = global.jaaulde = ( global.jaaulde || {} );
jaaulde.utils = jaaulde.utils || {};
jaaulde.utils.cookies = ( function()
{
/* Private vars */
var defaultOptions,
/* Private functions */
resolveOptions, assembleOptionsString, isNaN, trim, 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
* would prefer jQuery.extend here, but we want this library to work without jQuery
* @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 global.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' : '' )
);
};
/**
* trim - remove left and right whitespace
* Some logic borrowed from http://jquery.com/
*
* @access private
* @static
* @parameter data STRING
* @return STRING
*/
trim = global.String.prototype.trim ?
function( data )
{
return global.String.prototype.trim.call( data );
} :
( function()
{
var trimLeft, trimRight;
trimLeft = /^\s+/;
trimRight = /\s+$/;
return function( data )
{
return data.replace( trimLeft, '' ).replace( trimRight, '' );
};
}() );
/**
* isNaN - check if given value is not a number
* Borrowed from http://jquery.com/
*
* @access private
* @static
* @parameter obj MIXED
* @return BOOL
*/
isNaN = ( function()
{
var rdigit = /\d/, isNaN = global.isNaN;
return function( obj )
{
return ( obj === null || ! rdigit.test( obj ) || isNaN( obj ) );
};
}() );
/**
* 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 parseJSON, rbrace;
parseJSON = global.JSON && global.JSON.parse ?
( function()
{
var rvalidchars, rvalidescape, rvalidtokens, rvalidbraces;
rvalidchars = /^[\],:{}\s]*$/;
rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g;
rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g;
rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g;
return function( data )
{
var returnValue, validJSON;
returnValue = null;
if( typeof data === 'string' && data !== '' )
{
// Make sure leading/trailing whitespace is removed (IE can't handle it)
data = trim( data );
if( data !== '' )
{
try
{
// Make sure the incoming data is actual JSON. Logic borrowed from http://json.org/json2.js
validJSON = rvalidchars.test( data.replace( rvalidescape, '@' ).replace( rvalidtokens, ']' ).replace( rvalidbraces, '' ) );
returnValue = validJSON ?
global.JSON.parse( data ) :
null;
}
catch( e1 )
{
returnValue = null;
}
}
}
return returnValue;
};
}() ) :
function()
{
return null;
};
rbrace = /^(?:\{.*\}|\[.*\])$/;
return function()
{
var cookies, splitOnSemiColons, cookieCount, i, splitOnEquals, name, rawValue, value;
cookies = {};
splitOnSemiColons = document.cookie.split( ';' );
cookieCount = splitOnSemiColons.length;
for( i = 0; i < cookieCount; i = i + 1 )
{
splitOnEquals = splitOnSemiColons[i].split( '=' );
name = trim( splitOnEquals.shift() );
if( splitOnEquals.length >= 1 )
{
rawValue = splitOnEquals.join( '=' );
}
else
{
rawValue = '';
}
try
{
value = decodeURIComponent( rawValue );
}
catch( e2 )
{
value = rawValue;
}
//Logic borrowed from http://jquery.com/ dataAttr method
try
{
value = value === 'true' ?
true :
value === 'false' ?
false :
! isNaN( value ) ?
parseFloat( value ) :
rbrace.test( value ) ?
parseJSON( value ) :
value;
}
catch( e3 ) {}
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;
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( Object.prototype.hasOwnProperty.call( cookieName, item ) )
{
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;
returnValue = {};
cookies = parseCookies();
if( typeof cookieNameRegExp === 'string' )
{
cookieNameRegExp = new RegExp( cookieNameRegExp );
}
for( cookieName in cookies )
{
if( Object.prototype.hasOwnProperty.call( cookies, cookieName ) && 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 (http://code.google.com/p/cookies/wiki/JSON); 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 = {};
}
// TODO: consider value serialization method to parallel parse cookies
if( typeof value === 'undefined' || value === null )
{
value = '';
options.hoursToLive = -8760;
}
else
{
//Logic borrowed from http://jquery.com/ dataAttr method and reversed
value = value === true ?
'true' :
value === false ?
'false' :
! isNaN( value ) ?
'' + value :
value;
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 value which could not be serialized.' );
}
}
}
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;
allCookies = {};
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( Object.prototype.hasOwnProperty.call( allCookies, name ) && 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, testName, testValue;
testName = 'cookiesCT';
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();
}() );
if( global.jQuery )
{
( function( $ )
{
var NameTokenAttrResolver, cookies, extensions;
NameTokenAttrResolver = function()
{
var nameTokenAttrs = ['name', 'id'];
this.current = null;
this.nextAttrName = function()
{
this.current = nameTokenAttrs.shift();
return !! this.current;
};
};
cookies = $.cookies = jaaulde.utils.cookies;
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 )
{
this
.not( ':input' )
/*
Iterate non input elements
*/
.each( function()
{
var $this, NTAR, nameToken, value;
$this = $( this );
NTAR = new NameTokenAttrResolver();
while( NTAR.nextAttrName() )
{
nameToken = $this.attr( NTAR.current );
if( typeof nameToken === 'string' && nameToken !== '' )
{
value = $this.html();
cookies.set(
nameToken,
( typeof value === 'string' && value !== '' ) ? value : null,
options
);
break;
}
}
} )
.end()
.filter( ':input')
.filter( ':radio' )
/*
Iterate radio inputs
*/
.each( function()
{
} )
.end()
.filter( ':checkbox' )
/*
Iterate checkbox inputs
*/
.each( function()
{
} )
.end()
.not( ':radio, :checkbox' )
/*
Iterate all other inputs
*/
.each( function()
{
var $this, NTAR, nameToken, value;
$this = $( this );
NTAR = new NameTokenAttrResolver();
while( NTAR.nextAttrName() )
{
nameToken = $this.attr( NTAR.current );
if( typeof nameToken === 'string' && nameToken !== '' )
{
value = $this.val();
cookies.set(
nameToken,
( typeof value === 'string' && value !== '' ) ? value : null,
options
);
break;
}
}
} );
return this;
},
/**
* $( '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()
{
this
.not( ':input' )
/*
Iterate non input elements
*/
.each( function()
{
var $this, NTAR, nameToken, value;
$this = $( this );
NTAR = new NameTokenAttrResolver();
while( NTAR.nextAttrName() )
{
nameToken = $this.attr( NTAR.current );
if( typeof nameToken === 'string' && nameToken !== '' )
{
value = cookies.get( nameToken );
if( value !== null )
{
$this.html( value );
}
break;
}
}
} )
.end()
.filter( ':input')
.filter( ':radio' )
/*
Iterate radio inputs
*/
.each( function()
{
} )
.end()
.filter( ':checkbox' )
/*
Iterate checkbox inputs
*/
.each( function()
{
} )
.end()
.not( ':radio, :checkbox' )
/*
Iterate all other inputs
*/
.each( function()
{
var $this, NTAR, nameToken, value;
$this = $( this );
NTAR = new NameTokenAttrResolver();
while( NTAR.nextAttrName() )
{
nameToken = $this.attr( NTAR.current );
if( typeof nameToken === 'string' && nameToken !== '' )
{
value = cookies.get( nameToken );
if( value !== null )
{
$this.val( value );
}
break;
}
}
} );
return this;
},
/**
* $( '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;
} );
}( global.jQuery ) );
}
}( window ) );