/** * Het JSX.HistoryManager object fixt het 'back button' probleem voor sites die via Ajax * of Flash van pagina inhoud veranderen. Dit houdt in dat de JSX.HistoryManager bij kan * houden welke pagina in welke volgorde is bezocht. Mocht de bezoeker op de back of * forward knop van de browser klikken, zal de betreffende pagina in de lijst van * JSX.HistoryManager worden geopend. * * @author Roel Schut * @version 1.3 - 2007.12.10 * * @event onInit Wordt uitgevoerd wanneer het Object tijdens onLoad wordt geinitialiseert * @event onChange Wordt uitgevoerd wanneer er van pagina wordt veranderd. * @event onVisit Wordt uitgevoerd wanneer er een nieuwe pagina wordt toegevoegd. * @event onBack Wordt uitgevoerd wanneer er op de back button wordt geklikt. * @event onForward Wordt uitgevoerd wanneer er op de forward button wordt geklikt. * @event onEnd Wordt uitgevoerd wanneer het eerste item in de HistoryManger wordt geladen. * @event onLast Wordt uitgevoerd wanneer het laatse item in de HistoryManager wordt geladen. */ if(typeof(JSX) != 'object') alert('Cannot find JSX!'); JSX.HistoryManager = {}; /***************************************************************************************** * De HistoryManager class wordt door het JSX.HistoryManager object gebruikt voor het * opslaan van data. */ JSX.HistoryManager.Class = JSX.Class.create('HistoryManager'); JSX.HistoryManager.Class.prototype = { /** * @access private * @var number Het level waarop dit object staat binnen JSX.HistoryManger. */ __level: null, /** * @access private * @var object Een object met data. */ __data: {}, /************************************************************************************* * Constructor * * @param number $level Het level waarop dit object staat binnen JSX.HistoryManger. * @param object $data Een object met data. */ __construct: function($level, $data) { JSX.HistoryManager.levels[$level] = this; this.__level = $level; this.__data = $data; }, /************************************************************************************* * Geeft het level terug waarop dit object staat binnen JSX.HistoryManager. * * @access public * @return number */ getLevel: function() { return this.__level; }, /************************************************************************************* * Geeft de meegestuurde data van dit object terug. * * @access public * @return number */ getData: function() { return this.__data; }, /************************************************************************************* * Geeft een String variant van het object terug. * * @access public * @return string */ toString: function() { return "[HistoryManager level='"+ this.__level +"' data='"+ this.__data +"']"; } }; var HistoryManager = JSX.HistoryManager.Class; /*######################################################################################*/ /***************************************************************************************** * Deze functie maakt het gebruik van de HistoryManager mogelijk. Het zorgt ervoor dat * er een iframe wordt gemaakt tijdens de body onLoad event welke wordt gebruikt voor het * bij houden van de geschiedenis. * * @param string $cacher Het bestand dat wordt gebruikt om het level van de cache bij te houden. * @return void */ JSX.HistoryManager.create = function($cacher, $cacheId) { // maak van HistoryManager event broadcaster JSX.Event.makeBroadcaster(this); // het level van de vorige pagina this.previous = null; // het level van de huidige pagina this.current = null; // cache (iframe) wordt geladen? this.loading = false; // volgorde van bezochte pagina's this.history = new Array(); // zijn we nu vanuit de geschiedenis aan het browsen? this.inHistory = false; // de hoogst aanwezige level this.level = 0; // alle aanwezige levels met bijbehorende pagina's this.levels = new Array(); var $manager = this; // het cache object wordt gebruikt door de iframe this.Cache = { // update src van de iframe update: function() { var $h = $manager.levels[$manager.level]; var $d = {}; var $g = $h.getData(); for($k in $g) $d[$k] = $g[$k]; $d[this.levelId] = $h.getLevel(); var $q = '?'; for(var $k in $d) { var $v = $d[$k]; if(isScalar($v)) $q += $k +'='+ escape($v) +'&'; } this.control.src = $cacher + $q; }, // wordt opgeroepen door de iframe wanneer een pagina wordt geladen loaded: function($data) { $level = $data[this.levelId]; delete($data[this.levelId]); $history = [$manager.levels[$level], $data]; $manager.dispatchEvent('onChange', $history); $manager.previous = $manager.current; $manager.current = $level; $manager.loading = false; //trace($manager.previous, $level, $manager.inHistory); // kijk of we terug gaan in de geschiedenis if($manager.previous > $level) { $manager.inHistory = true; $manager.dispatchEvent('onBack', $history); if($level == 1) $manager.dispatchEvent('onBegin', $history); } // of misschien gaan we wel weer naar voren else if($manager.inHistory) { var $last = ($level == $manager.level); if($last) $manager.inHistory = false; $manager.dispatchEvent('onForward', $history); if($last) $manager.dispatchEvent('onEnd', $history); } // neen, we hebben dus een nieuw pagina bezoek else { $manager.dispatchEvent('onVisit', $history); } } } // functie die tijdens de onLoad event van de body wordt // aangeroepen en de iframe voor het cachen aanmaakt var init = function() { if(isEmpty($cacheId)) var $cacheId = 'bb_cache'; var $cache = document.createElement('iframe'); $cache.setAttribute('id', $cacheId); $cache.setAttribute('name', $cacheId); $cache.setAttribute('width', '0'); $cache.setAttribute('height', '0'); $cache.setAttribute('frameborder', '0'); $cache.setAttribute('style', 'visibility: hidden'); document.body.appendChild($cache); this.Cache.control = $cache; this.Cache.levelId = '__'+ $cacheId +'_level__'; $manager.dispatchEvent('onInit'); } JSX.Loader.add(init, this); }; /***************************************************************************************** * Met deze functie wordt er nieuwe data aan JSX.HistoryManager toe gevoegd. Dit houdt in * dat er als het ware een nieuwe pagina wordt bezocht. Via de iframe cache wordt er een * nieuwe level aangemaakt waarop de browser reageert zodat de back en/of forward knoppen * worden geactiveerd. * * @param object $data De data die we toe willen voegen. * @return void */ JSX.HistoryManager.add = function($data) { if(this.current < this.level) { var $iL = (this.level-this.current); for(var $i=0; $i<$iL; $i++) { var $old = this.history.shift(); delete(this.levels[$old.getLevel()]); } this.level = this.history.length; } this.inHistory = false; this.level++; this.history.unshift(new HistoryManager(this.level, $data)); this.Cache.update(); };