src/cm/media/js/lib/yui/yui3-3.15.0/build/cookie/cookie-debug.js
changeset 602 e16a97fb364a
equal deleted inserted replaced
601:d334a616c023 602:e16a97fb364a
       
     1 YUI.add('cookie', function (Y, NAME) {
       
     2 
       
     3 /**
       
     4  * Utilities for cookie management
       
     5  * @module cookie
       
     6  */
       
     7 
       
     8     //shortcuts
       
     9     var L       = Y.Lang,
       
    10         O       = Y.Object,
       
    11         NULL    = null,
       
    12 
       
    13         //shortcuts to functions
       
    14         isString    = L.isString,
       
    15         isObject    = L.isObject,
       
    16         isUndefined = L.isUndefined,
       
    17         isFunction  = L.isFunction,
       
    18         encode      = encodeURIComponent,
       
    19         decode      = decodeURIComponent,
       
    20 
       
    21         //shortcut to document
       
    22         doc         = Y.config.doc;
       
    23 
       
    24     /*
       
    25      * Throws an error message.
       
    26      */
       
    27     function error(message){
       
    28         throw new TypeError(message);
       
    29     }
       
    30 
       
    31     /*
       
    32      * Checks the validity of a cookie name.
       
    33      */
       
    34     function validateCookieName(name){
       
    35         if (!isString(name) || name === ""){
       
    36             error("Cookie name must be a non-empty string.");
       
    37         }
       
    38     }
       
    39 
       
    40     /*
       
    41      * Checks the validity of a subcookie name.
       
    42      */
       
    43     function validateSubcookieName(subName){
       
    44         if (!isString(subName) || subName === ""){
       
    45             error("Subcookie name must be a non-empty string.");
       
    46         }
       
    47     }
       
    48 
       
    49     /**
       
    50      * Cookie utility.
       
    51      * @class Cookie
       
    52      * @static
       
    53      */
       
    54     Y.Cookie = {
       
    55 
       
    56         //-------------------------------------------------------------------------
       
    57         // Private Methods
       
    58         //-------------------------------------------------------------------------
       
    59 
       
    60         /**
       
    61          * Creates a cookie string that can be assigned into document.cookie.
       
    62          * @param {String} name The name of the cookie.
       
    63          * @param {String} value The value of the cookie.
       
    64          * @param {Boolean} encodeValue True to encode the value, false to leave as-is.
       
    65          * @param {Object} options (Optional) Options for the cookie.
       
    66          * @return {String} The formatted cookie string.
       
    67          * @method _createCookieString
       
    68          * @private
       
    69          * @static
       
    70          */
       
    71         _createCookieString : function (name /*:String*/, value /*:Variant*/, encodeValue /*:Boolean*/, options /*:Object*/) /*:String*/ {
       
    72 
       
    73             options = options || {};
       
    74 
       
    75             var text /*:String*/ = encode(name) + "=" + (encodeValue ? encode(value) : value),
       
    76                 expires = options.expires,
       
    77                 path    = options.path,
       
    78                 domain  = options.domain;
       
    79 
       
    80 
       
    81             if (isObject(options)){
       
    82                 //expiration date
       
    83                 if (expires instanceof Date){
       
    84                     text += "; expires=" + expires.toUTCString();
       
    85                 }
       
    86 
       
    87                 //path
       
    88                 if (isString(path) && path !== ""){
       
    89                     text += "; path=" + path;
       
    90                 }
       
    91 
       
    92                 //domain
       
    93                 if (isString(domain) && domain !== ""){
       
    94                     text += "; domain=" + domain;
       
    95                 }
       
    96 
       
    97                 //secure
       
    98                 if (options.secure === true){
       
    99                     text += "; secure";
       
   100                 }
       
   101             }
       
   102 
       
   103             return text;
       
   104         },
       
   105 
       
   106         /**
       
   107          * Formats a cookie value for an object containing multiple values.
       
   108          * @param {Object} hash An object of key-value pairs to create a string for.
       
   109          * @return {String} A string suitable for use as a cookie value.
       
   110          * @method _createCookieHashString
       
   111          * @private
       
   112          * @static
       
   113          */
       
   114         _createCookieHashString : function (hash /*:Object*/) /*:String*/ {
       
   115             if (!isObject(hash)){
       
   116                 error("Cookie._createCookieHashString(): Argument must be an object.");
       
   117             }
       
   118 
       
   119             var text /*:Array*/ = [];
       
   120 
       
   121             O.each(hash, function(value, key){
       
   122                 if (!isFunction(value) && !isUndefined(value)){
       
   123                     text.push(encode(key) + "=" + encode(String(value)));
       
   124                 }
       
   125             });
       
   126 
       
   127             return text.join("&");
       
   128         },
       
   129 
       
   130         /**
       
   131          * Parses a cookie hash string into an object.
       
   132          * @param {String} text The cookie hash string to parse (format: n1=v1&n2=v2).
       
   133          * @return {Object} An object containing entries for each cookie value.
       
   134          * @method _parseCookieHash
       
   135          * @private
       
   136          * @static
       
   137          */
       
   138         _parseCookieHash : function (text) {
       
   139 
       
   140             var hashParts   = text.split("&"),
       
   141                 hashPart    = NULL,
       
   142                 hash        = {};
       
   143 
       
   144             if (text.length){
       
   145                 for (var i=0, len=hashParts.length; i < len; i++){
       
   146                     hashPart = hashParts[i].split("=");
       
   147                     hash[decode(hashPart[0])] = decode(hashPart[1]);
       
   148                 }
       
   149             }
       
   150 
       
   151             return hash;
       
   152         },
       
   153 
       
   154         /**
       
   155          * Parses a cookie string into an object representing all accessible cookies.
       
   156          * @param {String} text The cookie string to parse.
       
   157          * @param {Boolean} shouldDecode (Optional) Indicates if the cookie values should be decoded or not. Default is true.
       
   158          * @param {Object} options (Optional) Contains settings for loading the cookie.
       
   159          * @return {Object} An object containing entries for each accessible cookie.
       
   160          * @method _parseCookieString
       
   161          * @private
       
   162          * @static
       
   163          */
       
   164         _parseCookieString : function (text /*:String*/, shouldDecode /*:Boolean*/, options /*:Object*/) /*:Object*/ {
       
   165 
       
   166             var cookies /*:Object*/ = {};
       
   167 
       
   168             if (isString(text) && text.length > 0) {
       
   169 
       
   170                 var decodeValue = (shouldDecode === false ? function(s){return s;} : decode),
       
   171                     cookieParts = text.split(/;\s/g),
       
   172                     cookieName  = NULL,
       
   173                     cookieValue = NULL,
       
   174                     cookieNameValue = NULL;
       
   175 
       
   176                 for (var i=0, len=cookieParts.length; i < len; i++){
       
   177                     //check for normally-formatted cookie (name-value)
       
   178                     cookieNameValue = cookieParts[i].match(/([^=]+)=/i);
       
   179                     if (cookieNameValue instanceof Array){
       
   180                         try {
       
   181                             cookieName = decode(cookieNameValue[1]);
       
   182                             cookieValue = decodeValue(cookieParts[i].substring(cookieNameValue[1].length+1));
       
   183                         } catch (ex){
       
   184                             //intentionally ignore the cookie - the encoding is wrong
       
   185                         }
       
   186                     } else {
       
   187                         //means the cookie does not have an "=", so treat it as a boolean flag
       
   188                         cookieName = decode(cookieParts[i]);
       
   189                         cookieValue = "";
       
   190                     }
       
   191                     // don't overwrite an already loaded cookie if set by option
       
   192                     if (!isUndefined(options) && options.reverseCookieLoading) {
       
   193                         if (isUndefined(cookies[cookieName])) {
       
   194                             cookies[cookieName] = cookieValue;
       
   195                         }
       
   196                     } else {
       
   197                         cookies[cookieName] = cookieValue;
       
   198                     }
       
   199                 }
       
   200 
       
   201             }
       
   202 
       
   203             return cookies;
       
   204         },
       
   205 
       
   206         /**
       
   207          * Sets the document object that the cookie utility uses for setting
       
   208          * cookies. This method is necessary to ensure that the cookie utility
       
   209          * unit tests can pass even when run on a domain instead of locally.
       
   210          * This method should not be used otherwise; you should use
       
   211          * <code>Y.config.doc</code> to change the document that the cookie
       
   212          * utility uses for everyday purposes.
       
   213          * @param {Object} newDoc The object to use as the document.
       
   214          * @method _setDoc
       
   215          * @private
       
   216          */
       
   217         _setDoc: function(newDoc){
       
   218             doc = newDoc;
       
   219         },
       
   220 
       
   221         //-------------------------------------------------------------------------
       
   222         // Public Methods
       
   223         //-------------------------------------------------------------------------
       
   224 
       
   225         /**
       
   226          * Determines if the cookie with the given name exists. This is useful for
       
   227          * Boolean cookies (those that do not follow the name=value convention).
       
   228          * @param {String} name The name of the cookie to check.
       
   229          * @return {Boolean} True if the cookie exists, false if not.
       
   230          * @method exists
       
   231          * @static
       
   232          */
       
   233         exists: function(name) {
       
   234 
       
   235             validateCookieName(name);   //throws error
       
   236 
       
   237             var cookies = this._parseCookieString(doc.cookie, true);
       
   238 
       
   239             return cookies.hasOwnProperty(name);
       
   240         },
       
   241 
       
   242         /**
       
   243          * Returns the cookie value for the given name.
       
   244          * @param {String} name The name of the cookie to retrieve.
       
   245          * @param {Function|Object} options (Optional) An object containing one or more
       
   246          *      cookie options: raw (true/false), reverseCookieLoading (true/false)
       
   247          *      and converter (a function).
       
   248          *      The converter function is run on the value before returning it. The
       
   249          *      function is not used if the cookie doesn't exist. The function can be
       
   250          *      passed instead of the options object for backwards compatibility. When
       
   251          *      raw is set to true, the cookie value is not URI decoded.
       
   252          * @return {Any} If no converter is specified, returns a string or null if
       
   253          *      the cookie doesn't exist. If the converter is specified, returns the value
       
   254          *      returned from the converter or null if the cookie doesn't exist.
       
   255          * @method get
       
   256          * @static
       
   257          */
       
   258         get : function (name, options) {
       
   259 
       
   260             validateCookieName(name);   //throws error
       
   261 
       
   262             var cookies,
       
   263                 cookie,
       
   264                 converter;
       
   265 
       
   266             //if options is a function, then it's the converter
       
   267             if (isFunction(options)) {
       
   268                 converter = options;
       
   269                 options = {};
       
   270             } else if (isObject(options)) {
       
   271                 converter = options.converter;
       
   272             } else {
       
   273                 options = {};
       
   274             }
       
   275 
       
   276             cookies = this._parseCookieString(doc.cookie, !options.raw, options);
       
   277             cookie = cookies[name];
       
   278 
       
   279             //should return null, not undefined if the cookie doesn't exist
       
   280             if (isUndefined(cookie)) {
       
   281                 return NULL;
       
   282             }
       
   283 
       
   284             if (!isFunction(converter)){
       
   285                 return cookie;
       
   286             } else {
       
   287                 return converter(cookie);
       
   288             }
       
   289         },
       
   290 
       
   291         /**
       
   292          * Returns the value of a subcookie.
       
   293          * @param {String} name The name of the cookie to retrieve.
       
   294          * @param {String} subName The name of the subcookie to retrieve.
       
   295          * @param {Function} converter (Optional) A function to run on the value before returning
       
   296          *      it. The function is not used if the cookie doesn't exist.
       
   297          * @param {Object} options (Optional) Containing one or more settings for cookie parsing.
       
   298          * @return {Any} If the cookie doesn't exist, null is returned. If the subcookie
       
   299          *      doesn't exist, null if also returned. If no converter is specified and the
       
   300          *      subcookie exists, a string is returned. If a converter is specified and the
       
   301          *      subcookie exists, the value returned from the converter is returned.
       
   302          * @method getSub
       
   303          * @static
       
   304          */
       
   305         getSub : function (name /*:String*/, subName /*:String*/, converter /*:Function*/, options /*:Object*/) /*:Variant*/ {
       
   306 
       
   307             var hash /*:Variant*/ = this.getSubs(name, options);
       
   308 
       
   309             if (hash !== NULL) {
       
   310 
       
   311                 validateSubcookieName(subName);   //throws error
       
   312 
       
   313                 if (isUndefined(hash[subName])){
       
   314                     return NULL;
       
   315                 }
       
   316 
       
   317                 if (!isFunction(converter)){
       
   318                     return hash[subName];
       
   319                 } else {
       
   320                     return converter(hash[subName]);
       
   321                 }
       
   322             } else {
       
   323                 return NULL;
       
   324             }
       
   325 
       
   326         },
       
   327 
       
   328         /**
       
   329          * Returns an object containing name-value pairs stored in the cookie with the given name.
       
   330          * @param {String} name The name of the cookie to retrieve.
       
   331          * @param {Object} options (Optional) Containing one or more settings for cookie parsing.
       
   332          * @return {Object} An object of name-value pairs if the cookie with the given name
       
   333          *      exists, null if it does not.
       
   334          * @method getSubs
       
   335          * @static
       
   336          */
       
   337         getSubs : function (name /*:String*/, options /*:Object*/) {
       
   338 
       
   339             validateCookieName(name);   //throws error
       
   340 
       
   341             var cookies = this._parseCookieString(doc.cookie, false, options);
       
   342             if (isString(cookies[name])){
       
   343                 return this._parseCookieHash(cookies[name]);
       
   344             }
       
   345             return NULL;
       
   346         },
       
   347 
       
   348         /**
       
   349          * Removes a cookie from the machine by setting its expiration date to
       
   350          * sometime in the past.
       
   351          * @param {String} name The name of the cookie to remove.
       
   352          * @param {Object} options (Optional) An object containing one or more
       
   353          *      cookie options: path (a string), domain (a string),
       
   354          *      and secure (true/false). The expires option will be overwritten
       
   355          *      by the method.
       
   356          * @return {String} The created cookie string.
       
   357          * @method remove
       
   358          * @static
       
   359          */
       
   360         remove : function (name, options) {
       
   361 
       
   362             validateCookieName(name);   //throws error
       
   363 
       
   364             //set options
       
   365             options = Y.merge(options || {}, {
       
   366                 expires: new Date(0)
       
   367             });
       
   368 
       
   369             //set cookie
       
   370             return this.set(name, "", options);
       
   371         },
       
   372 
       
   373         /**
       
   374          * Removes a sub cookie with a given name.
       
   375          * @param {String} name The name of the cookie in which the subcookie exists.
       
   376          * @param {String} subName The name of the subcookie to remove.
       
   377          * @param {Object} options (Optional) An object containing one or more
       
   378          *      cookie options: path (a string), domain (a string), expires (a Date object),
       
   379          *      removeIfEmpty (true/false), and secure (true/false). This must be the same
       
   380          *      settings as the original subcookie.
       
   381          * @return {String} The created cookie string.
       
   382          * @method removeSub
       
   383          * @static
       
   384          */
       
   385         removeSub : function(name, subName, options) {
       
   386 
       
   387             validateCookieName(name);   //throws error
       
   388 
       
   389             validateSubcookieName(subName);   //throws error
       
   390 
       
   391             options = options || {};
       
   392 
       
   393             //get all subcookies for this cookie
       
   394             var subs = this.getSubs(name);
       
   395 
       
   396             //delete the indicated subcookie
       
   397             if (isObject(subs) && subs.hasOwnProperty(subName)){
       
   398                 delete subs[subName];
       
   399 
       
   400                 if (!options.removeIfEmpty) {
       
   401                     //reset the cookie
       
   402 
       
   403                     return this.setSubs(name, subs, options);
       
   404                 } else {
       
   405                     //reset the cookie if there are subcookies left, else remove
       
   406                     for (var key in subs){
       
   407                         if (subs.hasOwnProperty(key) && !isFunction(subs[key]) && !isUndefined(subs[key])){
       
   408                             return this.setSubs(name, subs, options);
       
   409                         }
       
   410                     }
       
   411 
       
   412                     return this.remove(name, options);
       
   413                 }
       
   414             } else {
       
   415                 return "";
       
   416             }
       
   417 
       
   418         },
       
   419 
       
   420         /**
       
   421          * Sets a cookie with a given name and value.
       
   422          * @param {String} name The name of the cookie to set.
       
   423          * @param {Any} value The value to set for the cookie.
       
   424          * @param {Object} options (Optional) An object containing one or more
       
   425          *      cookie options: path (a string), domain (a string), expires (a Date object),
       
   426          *      secure (true/false), and raw (true/false). Setting raw to true indicates
       
   427          *      that the cookie should not be URI encoded before being set.
       
   428          * @return {String} The created cookie string.
       
   429          * @method set
       
   430          * @static
       
   431          */
       
   432         set : function (name, value, options) {
       
   433 
       
   434             validateCookieName(name);   //throws error
       
   435 
       
   436             if (isUndefined(value)){
       
   437                 error("Cookie.set(): Value cannot be undefined.");
       
   438             }
       
   439 
       
   440             options = options || {};
       
   441 
       
   442             var text = this._createCookieString(name, value, !options.raw, options);
       
   443             doc.cookie = text;
       
   444             return text;
       
   445         },
       
   446 
       
   447         /**
       
   448          * Sets a sub cookie with a given name to a particular value.
       
   449          * @param {String} name The name of the cookie to set.
       
   450          * @param {String} subName The name of the subcookie to set.
       
   451          * @param {Any} value The value to set.
       
   452          * @param {Object} options (Optional) An object containing one or more
       
   453          *      cookie options: path (a string), domain (a string), expires (a Date object),
       
   454          *      and secure (true/false).
       
   455          * @return {String} The created cookie string.
       
   456          * @method setSub
       
   457          * @static
       
   458          */
       
   459         setSub : function (name, subName, value, options) {
       
   460 
       
   461             validateCookieName(name);   //throws error
       
   462 
       
   463             validateSubcookieName(subName);   //throws error
       
   464 
       
   465             if (isUndefined(value)){
       
   466                 error("Cookie.setSub(): Subcookie value cannot be undefined.");
       
   467             }
       
   468 
       
   469             var hash = this.getSubs(name);
       
   470 
       
   471             if (!isObject(hash)){
       
   472                 hash = {};
       
   473             }
       
   474 
       
   475             hash[subName] = value;
       
   476 
       
   477             return this.setSubs(name, hash, options);
       
   478 
       
   479         },
       
   480 
       
   481         /**
       
   482          * Sets a cookie with a given name to contain a hash of name-value pairs.
       
   483          * @param {String} name The name of the cookie to set.
       
   484          * @param {Object} value An object containing name-value pairs.
       
   485          * @param {Object} options (Optional) An object containing one or more
       
   486          *      cookie options: path (a string), domain (a string), expires (a Date object),
       
   487          *      and secure (true/false).
       
   488          * @return {String} The created cookie string.
       
   489          * @method setSubs
       
   490          * @static
       
   491          */
       
   492         setSubs : function (name, value, options) {
       
   493 
       
   494             validateCookieName(name);   //throws error
       
   495 
       
   496             if (!isObject(value)){
       
   497                 error("Cookie.setSubs(): Cookie value must be an object.");
       
   498             }
       
   499 
       
   500             var text /*:String*/ = this._createCookieString(name, this._createCookieHashString(value), false, options);
       
   501             doc.cookie = text;
       
   502             return text;
       
   503         }
       
   504 
       
   505     };
       
   506 
       
   507 
       
   508 }, '@VERSION@', {"requires": ["yui-base"]});