Adam Barth's abandoned(?) HTML Cookie API proposal.
// Adam Barth's abandoned(?) HTML Cookie API proposal
// https://docs.google.com/Doc?docid=0AZpchfQ5mBrEZGQ0cDh3YzRfMTRmdHFma21kMg&hl=en&pli=1
(function () {
"use strict";
/** @constructor */
function Cookie(name, value) {
this.name = name;
this.value = value;
this.httpOnly = false;
}
function parseCookies(findName) {
var array = document.cookie.split(/;\s+/),
i, str, idx, cookie;
for (i = 0; i < array.length; i += 1) {
str = array[i];
idx = str.indexOf('=');
cookie = new Cookie(str.substring(0, idx), str.substring(idx + 1));
if (cookie.name === findName) {
return cookie;
} else {
array[i] = cookie;
}
}
return arguments.length > 0 ? null : array;
}
function getCookie(name, callback) {
setTimeout(function () {
callback(parseCookies(name));
}, 0);
}
function getAllCookies(callback) {
setTimeout(function () {
callback(parseCookies());
}, 0);
}
function setCookie(cookie, errback) {
setTimeout(function () {
var str = cookie.name + '=' + (cookie.value || ""),
foundCookie, expectDeleted;
if (cookie.expires) {
str += "; expires=" + cookie.expires;
}
if (cookie.domain) {
str += "; domain=" + cookie.domain;
}
if (cookie.secure) {
str += "; secure";
}
str += "; path=" + (cookie.path || "/");
document.cookie = str;
foundCookie = parseCookies(cookie.name);
expectDeleted = cookie.expires && (new Date(cookie.expires) < new Date());
if (!foundCookie && !expectDeleted) {
errback("Cookie not set");
} else if (foundCookie.value !== cookie.value) {
errback("Cookie not set");
}
}, 0);
}
function deleteCookie(name, errback) {
setTimeout(function () {
document.cookie = name + "=; expires=" + (new Date(0).toGMTString()) + "; path=/";
var foundCookie = parseCookies(name);
if (foundCookie) {
errback("Cookie not deleted");
}
}, 0);
}
document.getCookie = document.getCookie || getCookie;
document.getAllCookies = document.getAllCookies || getAllCookies;
document.setCookie = document.setCookie || setCookie;
document.deleteCookie = document.deleteCookie || deleteCookie;
} ());
//
// HTML Cookie API
// https://docs.google.com/Doc?docid=0AZpchfQ5mBrEZGQ0cDh3YzRfMTRmdHFma21kMg&hl=en&pli=1
//
// The document.cookie API is kind of terrible. Web developers shouldn't have
// to parse a cookie-string or prepare a properly formated set-cookie-string.
// This document present a less terrible cookie API for HTML.
//
// interface Cookie {
// attribute DOMString name;
// attribute DOMString value;
// attribute DOMString domain;
// attribute DOMString expires;
// attribute DOMString path;
// attribute Boolean secure;
// attribute Boolean httpOnly;
// };
//
// For session cookies, the value of |expires| is the empty string. For
// host-only cookies, the |domain| attribute is the empty string. For Cookie
// objects created by the DOM, the |domain| attribute is not prefixed with a dot
// ("."). Because HttpOnly cookies are inaccessible to script, the |httpOnly|
// attribute will usually be false. Modifying a Cookie object in memory does
// not affect the underlying cookie store.
//
// interface Document {
// ...
// void getCookie(in DOMString name, in CookieCallback callback);
// void getAllCookies(in CookieListCallback callback);
// void setCookie(in Cookie cookie, in optional VoidCallback error);
// void deleteCookie(in DOMString name, in optional VoidCallback error);
// ...
// };
//
// [Callback=FunctionOnly, NoInterfaceObject]
// interface CookieCallback {
// handleEvent(in Cookie cookie);
// };
//
// [Callback=FunctionOnly, NoInterfaceObject]
// interface CookieListCallback {
// handleEvent(in CookieList cookieList);
// };
//
// [Callback=FunctionOnly, NoInterfaceObject]
// interface VoidCallback {
// void handleEvent();
// };
//
// The getCookie() API calls |callback| asynchronously with a copy of the first
// cookie (in document.cookie order) for the current document whose name is
// |name|.
//
// document.getCookie("SID", function(cookie) {
// alert("The SID cookie has value " + cookie.value);
// });
//
// The getAllCookies() API calls |callback| asynchronously with an array-like
// object containing copies of the Cookies for the document (with HttpOnly
// cookies excluded). This API provides a snapshot of the data in the cookie
// store at some time, in the order they would appear if returned from
// document.cookie. Modifications to the cookie list returned this way are not
// reflected in the cookie store and modifications to the cookie store are not
// reflected in the returned cookie list.
//
// document.getAllCookies(function(cookies) {
// for (var i=0; i < cookies.length; ++i)
// alert(cookies[i].name + " has value " + cookies[i].value);
// });
//
// The setCookie() API stores a cookie in the cookie store with fields that
// match the attributes of |cookie|. If setCookie() fails to set the cookie
// (e.g., because of third-party cookie blocking), the user agent calls the
// |error| callback.
//
// I'm not entirely sure how to state this requirement, but the DOM should use
// "duck typing" so that the following works properly:
//
// document.setCookie({name: "foo", value: "bar"});
//
// The deleteCookie() API deletes all the cookies for this document with a name
// of |name|.