From: Jan Schneider Date: Mon, 14 Jun 2010 11:11:05 +0000 (+0200) Subject: I still had hopes, but I'm giving up on the dhtmlHistry too now, like Michael did... X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=e202569291da961b1473114387a40b505cba6a49;p=horde.git I still had hopes, but I'm giving up on the dhtmlHistry too now, like Michael did long ago. --- diff --git a/horde/docs/CHANGES b/horde/docs/CHANGES index 5eac49352..2e2fb85b2 100644 --- a/horde/docs/CHANGES +++ b/horde/docs/CHANGES @@ -2,6 +2,7 @@ v4.0-cvs -------- +[jan] Remove dhtmlHistory library. [mms] Removed support for krb5 authentication driver. [jan] Allow to specify the URL parameter name for the alternate login setting. [mms] Remove reliance on PEAR Mail library. diff --git a/horde/js/dhtmlhistory.js b/horde/js/dhtmlhistory.js deleted file mode 100644 index 49681aa50..000000000 --- a/horde/js/dhtmlhistory.js +++ /dev/null @@ -1,499 +0,0 @@ -/** - * dhtmlHistory - An object that provides DHTML history, history data, and - * bookmarking for AJAX applications. - * - * Copyright (c) 2007 Brian Dillard and Brad Neuberg: - * Brian Dillard | Project Lead | bdillard@pathf.com | http://blogs.pathf.com/agileajax/ - * Brad Neuberg | Original Project Creator | http://codinginparadise.org - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT - * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR - * THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * This file has been altered from the original dhtmlHistory (v0.05; SVN - * revision 114) to remove unneeded functionality and to provide bug fixes and - * enhancements. - * - * This file requires the Prototype Javscript Library v1.6.0+ - * - * Additions Copyright 2005-2010 The Horde Project (http://www.horde.org/) - */ - -window.Horde = window.Horde || {}; - -Horde.dhtmlHistory = { - /* Our current hash location, without the "#" symbol. */ - // currentLocation: null, - - /* Our history change listener. */ - // listener: null, - - /* A hidden IFrame we use in Internet Explorer to detect history - changes. */ - // iframe: null, - - /* Indicates to the browser whether to ignore location changes. */ - // ignoreLocationChange: null, - - /* The amount of time in milliseconds that we should wait between add - requests. Firefox is okay with 200 ms, but Internet Explorer needs - 400. */ - WAIT_TIME: 200, - - /* The amount of time in milliseconds an add request has to wait in line - before being run on a setTimeout(). */ - currentWaitTime: 0, - - /* A flag that indicates that we should fire a history change event when - we are ready, i.e. after we are initialized and we have a history - change listener. This is needed due to an edge case in browsers other - than Internet Explorer; if you leave a page entirely then return, we - must fire this as a history change event. Unfortunately, we have lost - all references to listeners from earlier, because JavaScript - clears out. */ - // fireOnNewListener: null, - - /* A variable that indicates whether this is the first time this page has - been loaded. If you go to a web page, leave it for another one, and - then return, the page's onload listener fires again. We need a way to - differentiate between the first page load and subsequent ones. This - variable works hand in hand with the pageLoaded variable we store into - historyStorage. */ - // firstLoad: false, - - /* A variable to handle an important edge case in Internet Explorer. In - IE, if a user manually types an address into their browser's location - bar, we must intercept this by continiously checking the location bar - with a timer interval. However, if we manually change the location - bar ourselves programmatically, when using our hidden iframe, we need - to ignore these changes. Unfortunately, these changes are not atomic, - so we surround them with the variable 'ieAtomicLocationChange', that if - true means we are programmatically setting the location and should - ignore this atomic chunked change. */ - // ieAtomicLocationChange: null, - - /* Safari only variables. */ - // safariHistoryStartPoint: null, - // safariStack: null, - - /* PeriodicalExecuter instance. */ - // pe: null, - - /* Initializes our DHTML history. You should call this after the page is - finished loading. Returns true on success, false on failure. */ - initialize: function() - { - if (navigator.vendor && navigator.vendor === 'KDE') { - return false; - } - - Horde.historyStorage.init(); - - if (Prototype.Browser.WebKit) { - this.createSafari(); - } else if (Prototype.Browser.Opera) { - this.createOpera(); - } - - // Get our initial location - this.currentLocation = this.getCurrentLocation(); - - // Write out a hidden iframe for IE and set the amount of time to - // wait between add() requests. - if (Prototype.Browser.IE) { - this.iframe = new Element('IFRAME', { frameborder: 0, name: 'DhtmlHistoryFrame', id: 'DhtmlHistoryFrame', src: 'javascript:false;' }).hide(); - $(document.body).insert(this.iframe); - this.writeIframe(this.currentLocation); - - // Wait 400 milliseconds between history updates on IE - this.WAIT_TIME = 400; - - this.ignoreLocationChange = true; - } - - /* Add an unload listener for the page; this is needed for FF 1.5+ - because this browser caches all dynamic updates to the page, which - can break some of our logic related to testing whether this is the - first instance a page has loaded or whether it is being pulled from - the cache. */ - Event.observe(window, 'unload', function() { this.firstLoad = false; }.bind(this)); - - this.isFirstLoad(); - - /* Other browsers can use a location handler that checks at regular - intervals as their primary mechanism; we use it for IE as well to - handle an important edge case; see checkLocation() for details. */ - this.pe = new PeriodicalExecuter(this.checkLocation.bind(this), 0.1); - - return true; - }, - - stop: function() - { - if (this.pe) { - this.pe.stop(); - } - }, - - /* Adds a history change listener. Note that only one listener is - supported at this time. */ - addListener: function(callback) - { - this.listener = callback; - - /* If the page was just loaded and we should not ignore it, fire an - event to our new listener now. */ - if (this.fireOnNewListener) { - if (this.currentLocation) { - this.fireHistoryEvent(this.currentLocation); - } - this.fireOnNewListener = false; - } - }, - - add: function(newLoc, historyData) - { - if (Prototype.Browser.WebKit) { - newLoc = this.removeHash(newLoc); - Horde.historyStorage.put(newLoc, historyData); - this.currentLocation = newLoc; - this.ignoreLocationChange = true; - this.setLocation(newLoc); - this.putSafariState(newLoc); - } else { - /* Most browsers require that we wait a certain amount of time - before changing the location, such as 200 milliseconds; rather - than forcing external callers to use setTimeout() to account for - this to prevent bugs, we internally handle this detail by using - a 'currentWaitTime' variable and have requests wait in line. */ - setTimeout(this.addImpl.bind(this, newLoc, historyData), this.currentWaitTime); - } - - // Indicate that the next request will have to wait for awhile - this.currentWaitTime += this.WAIT_TIME; - }, - - setLocation: function(loc) - { - location.hash = loc; - }, - - /* Gets the current hash value that is in the browser's location bar, - removing leading # symbols if they are present. */ - getCurrentLocation: function() - { - if (Prototype.Browser.WebKit) { - return this.getSafariState(); - } else { - return this.removeHash(decodeURIComponent(location.hash)); - } - }, - - addImpl: function(newLoc, historyData) - { - // Indicate that the current wait time is now less - if (this.currentWaitTime) { - this.currentWaitTime -= this.WAIT_TIME; - } - - /* IE has a strange bug; if the newLoc is the same as _any_ - preexisting id in the document, then the history action gets - recorded twice; return immediately if there is an element with - this ID. */ - if ($('newLoc')) { - return; - } - - // Remove any leading hash symbols on newLoc - newLoc = this.removeHash(newLoc); - - // Store the history data into history storage - Horde.historyStorage.put(newLoc, historyData); - - // Indicate to the browser to ignore this upcoming location change. - // Indicate to IE that this is an atomic location change block. - this.ignoreLocationChange = this.ieAtomicLocationChange = true; - - // Save this as our current location and change the browser location - this.currentLocation = newLoc; - this.setLocation(encodeURIComponent(newLoc)); - - // Change the hidden iframe's location if on IE - if (Prototype.Browser.IE) { - this.writeIframe(newLoc); - } - - // End of atomic location change block for IE - this.ieAtomicLocationChange = false; - }, - - isFirstLoad: function() - { - if (!Horde.historyStorage.hasKey("DhtmlHistory_pageLoaded")) { - if (Prototype.Browser.IE) { - this.fireOnNewListener = false; - } else { - this.ignoreLocationChange = true; - } - this.firstLoad = true; - Horde.historyStorage.put("DhtmlHistory_pageLoaded", true); - } else { - if (Prototype.Browser.IE) { - this.firstLoad = false; - } else { - /* Indicate that we want to pay attention to this location - change. */ - this.ignoreLocationChange = false; - } - - /* For browsers other than IE, fire a history change event; - on IE, the event will be thrown automatically when it's - hidden iframe reloads on page load. Unfortunately, we don't - have any listeners yet; indicate that we want to fire an - event when a listener is added. */ - this.fireOnNewListener = true; - } - }, - - /* Notify the listener of new history changes. */ - fireHistoryEvent: function(newHash) - { - if (this.listener) { - // Extract the value from our history storage for this hash and - // call our listener. - this.listener.call(null, newHash, Horde.historyStorage.get(newHash)); - } - }, - - /* See if the browser has changed location. This is the primary history - mechanism for FF. For IE, we use this to handle an important edge case: - if a user manually types in a new hash value into their IE location - bar and press enter, we want to intercept this and notify any history - listener. */ - checkLocation: function() - { - /* Ignore any location changes that we made ourselves for browsers - other than IE. */ - if (!Prototype.Browser.IE) { - if (this.ignoreLocationChange) { - this.ignoreLocationChange = false; - return; - } - } else if (this.ieAtomicLocationChange) { - /* If we are dealing with IE and we are in the middle of making a - location change from an iframe, ignore it. */ - return; - } - - // Get hash location - var hash = this.getCurrentLocation(); - - // See if there has been a change or there is no hash location - if (hash.replace(/@/, '%40') == this.currentLocation || Object.isUndefined(hash)) { - return; - } - - /* On IE, we need to intercept users manually entering locations into - the browser; we do this by comparing the browsers location against - the iframes location; if they differ, we are dealing with a manual - event and need to place it inside our history, otherwise we can - return. */ - this.ieAtomicLocationChange = true; - - if (Prototype.Browser.IE) { - if (this.iframe.contentWindow.l == hash) { - // The iframe is unchanged - return; - } - this.writeIframe(hash); - } - - // Save this new location - this.currentLocation = hash; - - this.ieAtomicLocationChange = false; - - // Notify listeners of the change - this.fireHistoryEvent(hash); - }, - - /* Removes any leading hash that might be on a location. */ - removeHash: function(h) - { - if (h === null || Object.isUndefined(h)) { - return null; - } else if (h.startsWith('#')) { - if (h.length == 1) { - return ""; - } else { - return h.substring(1); - } - } - return h; - }, - - // IE Specific Code - /* For IE, says when the hidden iframe has finished loading. */ - iframeLoaded: function(newLoc) - { - // Ignore any location changes that we made ourselves - if (this.ignoreLocationChange) { - this.ignoreLocationChange = false; - return; - } - - // Get the new location - this.setLocation(encodeURIComponent(newLoc)); - - // Notify listeners of the change - this.fireHistoryEvent(newLoc); - }, - - writeIframe: function(l) - { - var d = this.iframe.contentWindow.document; - d.open(); - d.write(''); - d.close(); - }, - - // Safari specific code - createSafari: function() - { - this.WAIT_TIME = 400; - this.safariHistoryStartPoint = history.length; - - this.safariStack = new Element('INPUT', { id: 'DhtmlSafariHistory', type: 'text', value: '[]' }).hide(); - $(document.body).insert(this.safariStack); - }, - - getSafariStack: function() - { - return $F(this.safariStack).evalJSON(); - }, - - getSafariState: function() - { - var stack = this.getSafariStack(); - return stack[history.length - this.safariHistoryStartPoint - 1]; - }, - - putSafariState: function(newLoc) - { - var stack = this.getSafariStack(); - stack[history.length - this.safariHistoryStartPoint] = newLoc; - this.safariStack.setValue(stack.toJSON()); - }, - - // Opera specific code - createOpera: function() - { - this.WAIT_TIME = 400; - $(document.body).insert(new Element('IMG', { src: "javascript:location.href='javascript:Horde.dhtmlHistory.checkLocation();'" }).hide()); - } -}; - -/* An object that uses a hidden form to store history state across page loads. - The chief mechanism for doing so is using the fact that browsers save the - text in form data for the life of the browser and cache, which means the - text is still there when the user navigates back to the page. See - http://codinginparadise.org/weblog/2005/08/ajax-tutorial-saving-session-across.html - for full details. */ -Horde.historyStorage = { - /* Our hash of key name/values. */ - // storageHash: null, - - /* A reference to our textarea field. */ - // storageField: null, - - put: function(key, value) - { - this.loadHashTable(); - - // Store this new key - this.storageHash.set(key, value); - - // Save and serialize the hashtable into the form - this.saveHashTable(); - }, - - get: function(key) - { - // Make sure the hash table has been loaded from the form - this.loadHashTable(); - - var value = this.storageHash.get(key); - return Object.isUndefined(value) ? null : value; - }, - - remove: function(key) - { - // Make sure the hash table has been loaded from the form - this.loadHashTable(); - - // Delete the value - this.storageHash.unset(key); - - // Serialize and save the hash table into the form - this.saveHashTable(); - }, - - /* Clears out all saved data. */ - reset: function() - { - this.storageField.value = ""; - this.storageHash = $H(); - }, - - hasKey: function(key) - { - // Make sure the hash table has been loaded from the form - this.loadHashTable(); - return !(typeof this.storageHash.get(key) == undefined); - }, - - init: function() - { - // Write a hidden form into the page - var form = new Element('FORM').hide(); - $(document.body).insert(form); - - this.storageField = new Element('TEXTAREA', { id: 'historyStorageField' }); - form.insert(this.storageField); - - if (Prototype.Browser.Opera) { - this.storageField.focus(); - } - }, - - /* Loads the hash table up from the form. */ - loadHashTable: function() - { - if (!this.storageHash) { - // Destringify the content back into a real JS object - this.storageHash = (this.storageField.value) ? this.storageField.value.evalJSON() : $H(); - } - }, - - /* Saves the hash table into the form. */ - saveHashTable: function() - { - this.loadHashTable(); - this.storageField.value = this.storageHash.toJSON(); - } - -}; diff --git a/kronolith/js/kronolith.js b/kronolith/js/kronolith.js index c248a8c88..778c2d976 100644 --- a/kronolith/js/kronolith.js +++ b/kronolith/js/kronolith.js @@ -40,6 +40,8 @@ KronolithCore = { search: 'future', effectDur: 0.4, macos: navigator.appVersion.indexOf('Mac') !=- 1, + lastLocation: '', + currentLocation: '', doActionOpts: { onException: function(parentfunc, r, e) @@ -312,6 +314,7 @@ KronolithCore = { (loc == 'month' && date.getMonth() == this.date.getMonth()) || (loc == 'week' && date.getRealWeek() == this.date.getRealWeek()) || ((loc == 'day' || loc == 'agenda') && date.dateString() == this.date.dateString()))) { + this.addHistory(fullloc); return; } @@ -344,8 +347,11 @@ KronolithCore = { case 'tasks': var tasktype = locParts.shift() || this.tasktype; - if ((this.view == loc && this.tasktype == tasktype) || - !($w('all complete incomplete future').include(tasktype))) { + if (this.view == loc && this.tasktype == tasktype) { + this.addHistory(fullloc); + return; + } + if (!$w('all complete incomplete future').include(tasktype)) { return; } this.tasktype = tasktype; @@ -2452,7 +2458,7 @@ KronolithCore = { { if (!r.response.task) { RedBox.close(); - window.history.back(); + this.go(this.lastLocation); return; } @@ -2622,7 +2628,7 @@ KronolithCore = { this.loadEventsCallback(r, false); if (r.response.tasks) { this.closeRedBox(); - window.history.back(); + this.go(this.lastLocation); } else { $('kronolithTaskSave').disable(); } @@ -2656,7 +2662,7 @@ KronolithCore = { $('kronolithSharedCalendars').show(); this.editCalendar(type + '|' + cal); } else { - window.history.back(); + this.go(this.lastLocation); } }.bind(this)); return; @@ -2743,7 +2749,7 @@ KronolithCore = { break; default: this.closeRedBox(); - window.history.back(); + this.go(this.lastLocation); return; } } @@ -3348,7 +3354,7 @@ KronolithCore = { } form.down('.kronolithCalendarSave').enable(); this.closeRedBox(); - window.history.back(); + this.go(this.lastLocation); }, /** @@ -3606,11 +3612,11 @@ KronolithCore = { return event.value.sort; }, - addHistory: function(loc, data) + addHistory: function(loc) { - if (Horde.dhtmlHistory.getCurrentLocation() != loc) { - Horde.dhtmlHistory.add(loc, data); - } + location.hash = encodeURIComponent(loc); + this.lastLocation = this.currentLocation; + this.currentLocation = loc; }, /** @@ -3711,7 +3717,7 @@ KronolithCore = { break; case 'kronolithEventForm': this.closeRedBox(); - window.history.back(); + this.go(this.lastLocation); break; } break; @@ -3811,14 +3817,14 @@ KronolithCore = { case 'kronolithEventAlarmPrefs': this.closeRedBox(); - window.history.back(); + this.go(this.lastLocation); this.go('options', { app: 'kronolith', group: 'notification' }); e.stop(); break; case 'kronolithTaskAlarmPrefs': this.closeRedBox(); - window.history.back(); + this.go(this.lastLocation); this.go('options', { app: 'nag', group: 'notification' }); e.stop(); break; @@ -3879,7 +3885,7 @@ KronolithCore = { } }.bind(this)); this.closeRedBox(); - window.history.back(); + this.go(this.lastLocation); e.stop(); break; @@ -3911,7 +3917,7 @@ KronolithCore = { taskrow.hide(); } this.closeRedBox(); - window.history.back(); + this.go(this.lastLocation); e.stop(); break; @@ -4168,7 +4174,7 @@ KronolithCore = { case 'kronolithFormCancel': this.closeRedBox(); this.resetMap(); - window.history.back(); + this.go(this.lastLocation); e.stop(); break; @@ -4378,7 +4384,7 @@ KronolithCore = { delete Kronolith.conf.calendars[type][calendar]; } this.closeRedBox(); - window.history.back(); + this.go(this.lastLocation); }.bind(this)); e.stop(); break; @@ -4388,7 +4394,7 @@ KronolithCore = { this.toggleCalendar($F(form.down('input[name=type]')), $F(form.down('input[name=calendar]'))); this.closeRedBox(); - window.history.back(); + this.go(this.lastLocation); e.stop(); break; } else if (elt.tagName == 'INPUT' && @@ -4732,7 +4738,7 @@ KronolithCore = { if (r.response.events) { this.resetMap(); this.closeRedBox(); - window.history.back(); + this.go(this.lastLocation); } else { $('kronolithEventSave').enable(); $('kronolithEventSaveAsNew').enable(); @@ -4800,7 +4806,7 @@ KronolithCore = { { if (!r.response.event) { RedBox.close(); - window.history.back(); + this.go(this.lastLocation); return; } @@ -5616,14 +5622,14 @@ KronolithCore = { this.updateCalendarList(); this.updateMinical(this.date); - if (Horde.dhtmlHistory.initialize()) { - Horde.dhtmlHistory.addListener(this.go.bind(this)); + /* Initialize the starting page. */ + tmp = location.hash; + if (!tmp.empty() && tmp.startsWith('#')) { + tmp = (tmp.length == 1) ? '' : tmp.substring(1); } - - /* Initialize the starting page if necessary. addListener() will have - * already fired if there is a current location so only do a go() - * call if there is no current location. */ - if (!Horde.dhtmlHistory.getCurrentLocation()) { + if (!tmp.empty()) { + this.go(decodeURIComponent(tmp)); + } else { this.go(Kronolith.conf.login_view); } diff --git a/kronolith/lib/Kronolith.php b/kronolith/lib/Kronolith.php index f289cd96c..aa5af555f 100644 --- a/kronolith/lib/Kronolith.php +++ b/kronolith/lib/Kronolith.php @@ -70,7 +70,6 @@ class Kronolith Horde::addScriptFile('horde.js', 'horde'); Horde::addScriptFile('dragdrop2.js', 'horde'); Horde::addScriptFile('growler.js', 'horde'); - Horde::addScriptFile('dhtmlhistory.js', 'horde'); Horde::addScriptFile('redbox.js', 'horde'); Horde::addScriptFile('tooltips.js', 'horde'); Horde::addScriptFile('colorpicker.js', 'horde');