From d59a4921188753dbe4c0161081755a28112c3ef6 Mon Sep 17 00:00:00 2001 From: Nathan Gass Date: Thu, 22 Mar 2012 18:18:42 +0000 Subject: Branch itools/devel-utf8 created --- devel-utf8/itjs/state.js | 120 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 devel-utf8/itjs/state.js (limited to 'devel-utf8/itjs/state.js') diff --git a/devel-utf8/itjs/state.js b/devel-utf8/itjs/state.js new file mode 100644 index 0000000..e5e7c97 --- /dev/null +++ b/devel-utf8/itjs/state.js @@ -0,0 +1,120 @@ +/** + * Generic state object (singleton), for supporting Ajax browser history + * + * $Id$ + * + */ +var it_state = +{ +it_iframe: null, +it_history_field: null, +it_state_saved: false, +it_store_handlers: [], +it_restore_handlers: [], + +/** + * Register a handler that gets called before creating a history entry + * @param p.object Object that contains handler method + * @param p.method Method of p.object to call + */ +register_store_handler: function(p) +{ + this.it_store_handlers[this.it_store_handlers.length] = p; +}, + + +/** + * Register a handler that gets called after restoring a history entry + * @param p.object Object that contains handler method + * @param p.method Method of p.object to call + * @param p.initial optional flag: if true, handler is called with initial empty state + */ +register_restore_handler: function(p) +{ + this.it_restore_handlers[this.it_restore_handlers.length] = p; + + // If we already have state data, call registered handler immediately. Yup this _is_ needed! + if (this.it_history_field && this.it_history_field.value) + p.object[p.method](); +}, + + +/** + * Create a new history entry, saving all values of it_state (asynchronously) + * Users must call this without parameter! + */ +new_history_entry: function(p) +{ + this.store_state(); + this.it_state_saved = true; + + if (!this.it_iframe && !(this.it_iframe = document.getElementById('it_state'))) + ED('it_state::new_history_entry(): it_state object not found!'); + + var idoc; + if ((idoc = it_get_iframe_document(this.it_iframe))) + { + idoc.title = document.title; + idoc.forms[0].submit(); + } + this.it_history_field = null; +}, + + +/** + * Restore state from history, called from iframe's onload handler but in main window's context + */ +restore_history: function() +{ + if (!this.it_iframe && !(this.it_iframe = document.getElementById('it_state'))) + ED('it_state::restore_history(): it_state object not found!'); + + var idoc = it_get_iframe_document(this.it_iframe); + this.it_history_field = idoc ? idoc.getElementById('state') : {}; // Work-around IE5 not returning iframe document + this.it_state_saved = false; + + if (this.it_history_field.value) + { + var res = eval('({' + this.it_history_field.value + '})'); + for (var key in res) + this[key] = res[key]; + } + + for (var i in this.it_restore_handlers) + { + if (this.it_history_field.value || (this.it_restore_handlers[i].initial && (!idoc || !idoc.location.href.match(/s=/)))) + this.it_restore_handlers[i].object[this.it_restore_handlers[i].method](); + } +}, + + +/** + * Call all store handlers and store state in it_history_field + */ +store_state: function() +{ + if (!this.it_iframe && !(this.it_iframe = document.getElementById('it_state'))) + ED('it_state::store_state(): it_state object not found!'); + + var idoc = it_get_iframe_document(this.it_iframe); + this.it_history_field = idoc ? idoc.getElementById('state') : {}; // Work-around IE5 not returning iframe document + + for (var i in this.it_store_handlers) + this.it_store_handlers[i].object[this.it_store_handlers[i].method](); + + var ser = []; + for (var key in this) + { + var value = this[key], type = typeof(value); + if (!key.match(/^it_/) && type.match(/boolean|number|string/)) + ser[ser.length] = key + ':' + ((type == 'string') ? "'" + value.replace(/([\\'])/g, '\\\1') + "'" : value); + } + + this.it_history_field.value = ser.join(','); +} /* NO COMMA */ +} + +function it_state_restore_history() +{ + it_state.restore_history(); +} -- cgit v1.2.3