/** * 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(); }