| /* |
| Copyright (c) 2004-2006, The Dojo Foundation |
| All Rights Reserved. |
| |
| Licensed under the Academic Free License version 2.1 or above OR the |
| modified BSD license. For more information on Dojo licensing, see: |
| |
| http://dojotoolkit.org/community/licensing.shtml |
| */ |
| |
| dojo.provide("dojo.widget.html.stabile"); |
| |
| dojo.widget.html.stabile = { |
| // summary: Maintain state of widgets when user hits back/forward button |
| |
| // Characters to quote in single-quoted regexprs |
| _sqQuotables: new RegExp("([\\\\'])", "g"), |
| |
| // Current depth. |
| _depth: 0, |
| |
| // Set to true when calling v.toString, to sniff for infinite |
| // recursion. |
| _recur: false, |
| |
| // Levels of nesting of Array and object displays. |
| // If when >= depth, no display or array or object internals. |
| depthLimit: 2 |
| }; |
| |
| //// PUBLIC METHODS |
| |
| dojo.widget.html.stabile.getState = function(id){ |
| // summary |
| // Get the state stored for the widget with the given ID, or undefined |
| // if none. |
| |
| dojo.widget.html.stabile.setup(); |
| return dojo.widget.html.stabile.widgetState[id]; |
| } |
| |
| dojo.widget.html.stabile.setState = function(id, state, isCommit){ |
| // summary |
| // Set the state stored for the widget with the given ID. If isCommit |
| // is true, commits all widget state to more stable storage. |
| |
| dojo.widget.html.stabile.setup(); |
| dojo.widget.html.stabile.widgetState[id] = state; |
| if(isCommit){ |
| dojo.widget.html.stabile.commit(dojo.widget.html.stabile.widgetState); |
| } |
| } |
| |
| dojo.widget.html.stabile.setup = function(){ |
| // summary |
| // Sets up widgetState: a hash keyed by widgetId, maps to an object |
| // or array writable with "describe". If there is data in the widget |
| // storage area, use it, otherwise initialize an empty object. |
| |
| if(!dojo.widget.html.stabile.widgetState){ |
| var text = dojo.widget.html.stabile._getStorage().value; |
| dojo.widget.html.stabile.widgetState = text ? dj_eval("("+text+")") : {}; |
| } |
| } |
| |
| dojo.widget.html.stabile.commit = function(state){ |
| // summary |
| // Commits all widget state to more stable storage, so if the user |
| // navigates away and returns, it can be restored. |
| |
| dojo.widget.html.stabile._getStorage().value = dojo.widget.html.stabile.description(state); |
| } |
| |
| dojo.widget.html.stabile.description = function(v, showAll){ |
| // summary |
| // Return a JSON "description string" for the given value. |
| // Supports only core JavaScript types with literals, plus Date, |
| // and cyclic structures are unsupported. |
| // showAll defaults to false -- if true, this becomes a simple symbolic |
| // object dumper, but you cannot "eval" the output. |
| |
| // Save and later restore dojo.widget.html.stabile._depth; |
| var depth = dojo.widget.html.stabile._depth; |
| |
| var describeThis = function() { |
| return this.description(this, true); |
| } |
| |
| try { |
| |
| if(v===void(0)){ |
| return "undefined"; |
| } |
| if(v===null){ |
| return "null"; |
| } |
| if(typeof(v)=="boolean" || typeof(v)=="number" |
| || v instanceof Boolean || v instanceof Number){ |
| return v.toString(); |
| } |
| |
| if(typeof(v)=="string" || v instanceof String){ |
| // Quote strings and their contents as required. |
| // Replacing by $& fails in IE 5.0 |
| var v1 = v.replace(dojo.widget.html.stabile._sqQuotables, "\\$1"); |
| v1 = v1.replace(/\n/g, "\\n"); |
| v1 = v1.replace(/\r/g, "\\r"); |
| // Any other important special cases? |
| return "'"+v1+"'"; |
| } |
| |
| if(v instanceof Date){ |
| // Create a data constructor. |
| return "new Date("+d.getFullYear+","+d.getMonth()+","+d.getDate()+")"; |
| } |
| |
| var d; |
| if(v instanceof Array || v.push){ |
| // "push" test needed for KHTML/Safari, don't know why -cp |
| |
| if(depth>=dojo.widget.html.stabile.depthLimit) |
| return "[ ... ]"; |
| |
| d = "["; |
| var first = true; |
| dojo.widget.html.stabile._depth++; |
| for(var i=0; i<v.length; i++){ |
| // Skip functions and undefined values |
| // if(v[i]==undef || typeof(v[i])=="function") |
| // continue; |
| if(first){ |
| first = false; |
| }else{ |
| d += ","; |
| } |
| d+=arguments.callee(v[i], showAll); |
| } |
| return d+"]"; |
| } |
| |
| if(v.constructor==Object |
| || v.toString==describeThis){ |
| if(depth>=dojo.widget.html.stabile.depthLimit) |
| return "{ ... }"; |
| |
| // Instanceof Hash is good, or if we just use Objects, |
| // we can say v.constructor==Object. |
| // IE (5?) lacks hasOwnProperty, but perhaps objects do not always |
| // have prototypes?? |
| if(typeof(v.hasOwnProperty)!="function" && v.prototype){ |
| throw new Error("description: "+v+" not supported by script engine"); |
| } |
| var first = true; |
| d = "{"; |
| dojo.widget.html.stabile._depth++; |
| for(var key in v){ |
| // Skip values that are functions or undefined. |
| if(v[key]==void(0) || typeof(v[key])=="function") |
| continue; |
| if(first){ |
| first = false; |
| }else{ |
| d += ", "; |
| } |
| var kd = key; |
| // If the key is not a legal identifier, use its description. |
| // For strings this will quote the stirng. |
| if(!kd.match(/^[a-zA-Z_][a-zA-Z0-9_]*$/)){ |
| kd = arguments.callee(key, showAll); |
| } |
| d += kd+": "+arguments.callee(v[key], showAll); |
| } |
| return d+"}"; |
| } |
| |
| if(showAll){ |
| if(dojo.widget.html.stabile._recur){ |
| // Save the original definitions of toString; |
| var objectToString = Object.prototype.toString; |
| return objectToString.apply(v, []); |
| }else{ |
| dojo.widget.html.stabile._recur = true; |
| return v.toString(); |
| } |
| }else{ |
| // log("Description? "+v.toString()+", "+typeof(v)); |
| throw new Error("Unknown type: "+v); |
| return "'unknown'"; |
| } |
| |
| } finally { |
| // Always restore the global current depth. |
| dojo.widget.html.stabile._depth = depth; |
| } |
| |
| } |
| |
| |
| |
| //// PRIVATE TO MODULE |
| |
| dojo.widget.html.stabile._getStorage = function(){ |
| // summary |
| // Gets an object (form field) with a read/write "value" property. |
| |
| if (dojo.widget.html.stabile.dataField) { |
| return dojo.widget.html.stabile.dataField; |
| } |
| var form = document.forms._dojo_form; |
| return dojo.widget.html.stabile.dataField = form ? form.stabile : {value: ""}; |
| } |
| |