Enable user-specific, cookie-based storage of context collapse/expand settings on the homepage. Also, removed unused cookie get/set code from the toggle_notes.js file

git-svn-id: http://www.rousette.org.uk/svn/tracks-repos/trunk@262 a4c988fc-2ded-0310-b66e-134b36920a42
This commit is contained in:
lukemelia 2006-06-10 17:09:16 +00:00
parent cf0d56e10b
commit da22d34962
4 changed files with 221 additions and 136 deletions

View file

@ -14,6 +14,7 @@ class LoginController < ApplicationController
session['noexpiry'] = params['user_noexpiry']
msg = (should_expire_sessions?) ? "will expire after 1 hour of inactivity." : "will not expire."
flash['notice'] = "Login successful: session #{msg}"
cookies[:tracks_login] = { :value => @user.login, :expires => Time.now + 1.year }
redirect_back_or_default :controller => "todo", :action => "list"
else
@login = params['user_login']

View file

@ -7,4 +7,126 @@ Ajax.Responders.register({
if($('busy') && Ajax.activeRequestCount==0)
Element.hide('busy');
}
});
});
/**
* Provides a simple interface for creating, retrieving and clearing cookies.
* Adapted from Jonathan Buchanan's code at http://insin.woaf.net/code/javascript/cookiemanager.html
*/
CookieManager = Class.create();
CookieManager.prototype =
{
BROWSER_IS_IE:
(document.all
&& window.ActiveXObject
&& navigator.userAgent.toLowerCase().indexOf("msie") > -1
&& navigator.userAgent.toLowerCase().indexOf("opera") == -1),
/**
* I hate navigator string based browser detection too, but when Opera alone
* chokes on cookies containing double quotes...
*/
BROWSER_IS_OPERA:
(navigator.userAgent.toLowerCase().indexOf("opera") != -1),
initialize: function(options)
{
this.options = Object.extend({
shelfLife: 365,
userData: false
}, options || {});
this.cookieShelfLife = this.options.shelfLife;
this.userDataForIE = this.options.userData;
// Internet Explorer has a cookie handling bug - if the *combined size*
// of all cookies stored for a given domain is greater than 4096 bytes,
// document.cookie will return an empty string. Until this is fixed, we
// can fall back on IE's proprietary userData behaviour if necessary.
if (this.BROWSER_IS_IE && this.userDataForIE)
{
this.IE_CACHE_NAME = "storage";
if ($(this.IE_CACHE_NAME) == null)
{
var div = document.createElement("DIV");
div.id = this.IE_CACHE_NAME;
document.body.appendChild(div);
}
this.store = $(this.IE_CACHE_NAME);
this.store.style.behavior = "url('#default#userData')";
}
},
/**
* Returns the value of a cookie with the given name, or <code>null</code>
* if no such cookie exists.
*/
getCookie: function(aCookieName)
{
var result = null;
if (this.BROWSER_IS_IE && this.userDataForIE)
{
this.store.load(this.IE_CACHE_NAME);
result = this.store.getAttribute(aCookieName);
}
else
{
for (var i = 0; i < document.cookie.split('; ').length; i++)
{
var crumb = document.cookie.split('; ')[i].split('=');
if (crumb[0] == aCookieName && crumb[1] != null)
{
result = crumb[1];
break;
}
}
}
if (this.BROWSER_IS_OPERA && result != null)
{
result = result.replace(/%22/g, '"');
}
return result;
},
/**
* Sets a cookie with the given name and value.
*/
setCookie: function(aCookieName, aCookieValue)
{
if (this.BROWSER_IS_IE && this.userDataForIE)
{
this.store.setAttribute(aCookieName, aCookieValue);
this.store.save(this.IE_CACHE_NAME);
}
else
{
if (this.BROWSER_IS_OPERA)
{
aCookieValue = aCookieValue.replace(/"/g, "%22");
}
var date = new Date();
date.setTime(date.getTime() + (this.cookieShelfLife * 24*60*60*1000));
var expires = '; expires=' + date.toGMTString();
document.cookie = aCookieName + '=' + aCookieValue + expires + '; path=/';
}
},
/**
* Clears the cookie with the given name.
*/
clearCookie: function(aCookieName)
{
if (this.BROWSER_IS_IE && this.userDataForIE)
{
this.store.load(this.IE_CACHE_NAME);
this.store.removeAttribute(aCookieName);
this.store.save(this.IE_CACHE_NAME);
}
else
{
document.cookie =
aCookieName + '=;expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/';
}
}
}

View file

@ -7,117 +7,108 @@
* <script type="text/javascript" src="todo-items.js"></script>
*/
addEvent(window, "load", addNextActionListingToggles);
var todoItems = {
function addNextActionListingToggles()
{
var toggleElems = document.getElementsByClassName('container_toggle');
for(var i = 0; i < toggleElems.length; i++)
addNextActionListingToggles: function()
{
addEvent(toggleElems[i], "click", toggleNextActionListing);
}
}
this.contextCollapseCookieManager = new CookieManager();
var toggleElems = document.getElementsByClassName('container_toggle');
toggleElems.each(function(toggleElem){
Event.observe(toggleElem, 'click', todoItems.toggleNextActionListing);
containerElem = todoItems.findNearestParentByClassName(toggleElem, "container");
collapsedCookie = contextCollapseCookieManager.getCookie(todoItems.buildCookieName(containerElem));
if (collapsedCookie)
{
itemsElem = todoItems.findItemsElem(toggleElem);
todoItems.collapseNextActionListing(toggleElem, itemsElem);
}
});
},
function ensureVisibleWithEffectAppear(elemId)
{
if ($(elemId).style.display == 'none')
{
new Effect.Appear(elemId,{duration:0.4});
}
}
function fadeAndRemoveItem(itemContainerElemId)
{
var fadingElemId = itemContainerElemId + '-fading';
$(itemContainerElemId).setAttribute('id',fadingElemId);
Element.removeClassName($(fadingElemId),'item-container');
new Effect.Fade(fadingElemId,{afterFinish:function(effect) { Element.remove(fadingElemId); }, duration:0.4});
}
function toggleNextActionListing()
{
var itemsElem = findItemsElem(this);
if (Element.visible(itemsElem))
Effect.BlindUp(itemsElem, { duration: 0.4});
else
Effect.BlindDown(itemsElem, { duration: 0.4 });
this.setAttribute('title', (this.style.display == 'none') ? 'Expand' : 'Collapse');
var childImgElems = this.getElementsByTagName('img');
for(var i = 0; i < childImgElems.length; i++)
ensureVisibleWithEffectAppear: function(elemId)
{
if (childImgElems[i].src.indexOf('collapse.png') != -1)
if ($(elemId).style.display == 'none')
{
new Effect.Appear(elemId,{duration:0.4});
}
},
fadeAndRemoveItem: function(itemContainerElemId)
{
var fadingElemId = itemContainerElemId + '-fading';
$(itemContainerElemId).setAttribute('id',fadingElemId);
Element.removeClassName($(fadingElemId),'item-container');
new Effect.Fade(fadingElemId,{afterFinish:function(effect) { Element.remove(fadingElemId); }, duration:0.4});
},
toggleNextActionListing: function()
{
itemsElem = todoItems.findItemsElem(this);
containerElem = todoItems.findNearestParentByClassName(this, "container");
if (Element.visible(itemsElem))
{
childImgElems[i].src = childImgElems[i].src.replace('collapse','expand');
childImgElems[i].setAttribute('title','Expand');
//SetCookie(idname, "collapsed");
todoItems.collapseNextActionListing(this, itemsElem);
contextCollapseCookieManager.setCookie(todoItems.buildCookieName(containerElem), true)
}
else
{
todoItems.expandNextActionListing(this, itemsElem);
contextCollapseCookieManager.clearCookie(todoItems.buildCookieName(containerElem))
}
else if (childImgElems[i].src.indexOf('expand.png') != -1)
{
childImgElems[i].src = childImgElems[i].src.replace('expand','collapse');
childImgElems[i].setAttribute('title','Collapse');
//SetCookie(idname, "expanded");
}
}
return false;
}
function findNearestParentByClassName(elem, parentClassName)
{
var parentElem = elem.parentNode;
while(parentElem)
{
if (Element.hasClassName(parentElem, parentClassName))
{
return parentElem;
}
parentElem = parentElem.parentNode;
}
return null;
}
function findItemsElem(toggleElem)
{
var containerElem = findNearestParentByClassName(toggleElem, "container");
if (containerElem)
return document.getElementsByClassName('toggle_target',containerElem)[0];
else
return null;
}
// This is a cross-browser function for event addition.
function addEvent(obj, evType, fn)
{
if (obj.addEventListener)
{
obj.addEventListener(evType, fn, false);
return true;
}
else if (obj.attachEvent)
{
var r = obj.attachEvent("on" + evType, fn);
return r;
}
else
{
alert("Event handler could not be attached");
return false;
},
expandNextActionListing: function(toggleElem, itemsElem)
{
Effect.BlindDown(itemsElem, { duration: 0.4 });
toggleElem.setAttribute('title', 'Collapse');
imgElem = todoItems.findFirstImgElementWithSrcContaining(toggleElem, 'expand.png');
imgElem.src = imgElem.src.replace('expand','collapse');
imgElem.setAttribute('title','Collapse');
},
collapseNextActionListing: function(toggleElem, itemsElem)
{
Effect.BlindUp(itemsElem, { duration: 0.4});
toggleElem.setAttribute('title', 'Expand');
imgElem = todoItems.findFirstImgElementWithSrcContaining(toggleElem, 'collapse.png');
imgElem.src = imgElem.src.replace('collapse','expand');
imgElem.setAttribute('title','Expand');
},
findFirstImgElementWithSrcContaining: function(searchRootElem, srcString)
{
childImgElems = $A(searchRootElem.getElementsByTagName('img'));
return childImgElems.detect(function(childImgElem) { return childImgElem.src.indexOf(srcString) != -1 });
},
buildCookieName: function(containerElem)
{
tracks_login = contextCollapseCookieManager.getCookie('tracks_login');
return 'tracks_'+tracks_login+'_context_' + containerElem.id + '_collapsed';
},
findNearestParentByClassName: function(elem, parentClassName)
{
var parentElem = elem.parentNode;
while(parentElem)
{
if (Element.hasClassName(parentElem, parentClassName))
{
return parentElem;
}
parentElem = parentElem.parentNode;
}
return null;
},
findItemsElem : function(toggleElem)
{
var containerElem = todoItems.findNearestParentByClassName(toggleElem, "container");
if (containerElem)
return document.getElementsByClassName('toggle_target',containerElem)[0];
else
return null;
}
}
function removeEvent(obj, evType, fn)
{
if (obj.removeEventListener)
{
obj.removeEventListener(evType, fn, false);
return true;
}
else if (obj.detachEvent)
{
var r = obj.detachEvent("on"+evType, fn);
return r;
}
else
{
alert("Handler could not be removed");
}
}
Event.observe(window, "load", todoItems.addNextActionListingToggles);

View file

@ -10,33 +10,4 @@ function toggleAll(className) {
elems[i].style.display = 'block';
}
}
}
function SetCookie (name, value) {
var argv = SetCookie.arguments;
var argc = SetCookie.arguments.length;
var expires = (argc > 2) ? argv[2] : null;
var path = (argc > 3) ? argv[3] : null;
var domain = (argc > 4) ? argv[4] : null;
var secure = (argc > 5) ? argv[5] : false;
document.cookie = name + "=" + escape (value) +
((expires == null) ? "" : ("; expires=" +
expires.toGMTString())) +
((path == null) ? "" : ("; path=" + path)) +
((domain == null) ? "" : ("; domain=" + domain)) +
((secure == true) ? "; secure" : "");
}
var bikky = document.cookie;
function getCookie(name) { // use: getCookie("name");
var index = bikky.indexOf(name + "=");
if (index == -1) return null;
index = bikky.indexOf("=", index) + 1; // first character
var endstr = bikky.indexOf(";", index);
if (endstr == -1) endstr = bikky.length; // last character
return unescape(bikky.substring(index, endstr));
}
}