diff --git a/e107_files/e107.css b/e107_files/e107.css index 6ddb7a65b..1327ee842 100644 --- a/e107_files/e107.css +++ b/e107_files/e107.css @@ -32,7 +32,20 @@ .even { background-color: #F5F5F5 } .first, .last { } -/* Loading Status default style */ +/* e107 Tabs - see core/tabs.js */ +ul.e-tabs { list-style-type: none; } + +ul.e-tabs li { display: inline; margin: 0px; border: 0 none; background-color: transparent; } +ul.e-tabs li a { text-decoration: none; padding: 5px; } + +ul.e-tabs li a:link, +ul.e-tabs li a:visited { border: 1px solid #C0C0C0; } + +ul.e-tabs li a:hover, +ul.e-tabs li.active a:link, +ul.e-tabs li.active a:visited { background-color: #EEEEEE; border: 1px solid #808080; } + +/* Page Loading Status default style */ #loading-mask { color: #556B2F; font-size: 1.2em; font-weight:bold; position:absolute; text-align: center; padding: 0; margin: 0; } #loading-mask .loader { position: fixed; top: 40%; left: 50%; width: 200px; text-align: center; background: #F0F9E3 none repeat scroll 0 0; border: 2px solid #556B2F; font-weight: bold; padding: 10px 5px; margin-left: -100px; margin-top: 0; } #loading-mask img { margin: 10px auto; } diff --git a/e107_files/jslib/core/decorate.js b/e107_files/jslib/core/decorate.js index f1c008802..6a8f656ec 100644 --- a/e107_files/jslib/core/decorate.js +++ b/e107_files/jslib/core/decorate.js @@ -1,6 +1,18 @@ -/* - * DECORATE HTML ELEMENTS +/* + * e107 website system + * + * Copyright (c) 2001-2008 e107 Developers (e107.org) + * Released under the terms and conditions of the + * GNU General Public License (http://gnu.org). + * + * DECORATE HTML LIST ELEMENTS * Inspired by Magento' decorate JS functions (www.magentocommerce.com) + * + * $Source: /cvs_backup/e107_0.8/e107_files/jslib/core/decorate.js,v $ + * $Revision: 1.3 $ + * $Date: 2008-11-17 17:43:57 $ + * $Author: secretr $ + * */ e107Utils.Decorate = { @@ -112,7 +124,7 @@ e107Utils.Decorate = { decorateAllParams.each( function(v) { this.params[v] = this.decorateParams.include(v); }.bind(this)); - console.log(elements[0]); + // decorate first if(this.params.first) { Element.addClassName(elements[0], 'first'); diff --git a/e107_files/jslib/core/tabs.js b/e107_files/jslib/core/tabs.js new file mode 100644 index 000000000..c912f8fad --- /dev/null +++ b/e107_files/jslib/core/tabs.js @@ -0,0 +1,325 @@ +/* + * e107 website system + * + * Copyright (c) 2001-2008 e107 Developers (e107.org) + * Released under the terms and conditions of the + * GNU General Public License (http://gnu.org). + * + * e107Widget.Tabs Class + * + * Create tabs, supports ajax/inline content, browser history & bookmarks + * (unobtrusive Javascript) + * + * $Source: /cvs_backup/e107_0.8/e107_files/jslib/core/tabs.js,v $ + * $Revision: 1.1 $ + * $Date: 2008-11-17 17:43:57 $ + * $Author: secretr $ + * +*/ + +/** + * Global prefs + */ +e107Base.setPref('core-tabs', { + bookmarkFix: true, + historyNavigation: false, + pageOverlay: false, + elementOverlay: true, + ajaxCache: true +}); + +e107Widgets.Tabs = Class.create(e107WidgetAbstract, { + + Version: '1.0', + + initialize: function(container, options) { + this.events = new e107EventManager(this); + var optHandlers = { + show: this.show, + hide: this.hide + } + Object.extend(optHandlers , options || {}); + + this.global = this; + this.initMod('core-tabs', optHandlers).__initTabData(container); + + }, + + __initTabData: function(container) { + var cstring, celement = $(container); + if(null === celement) + throw('e107Widgets.Tabs: invalid value for container'); //TODO Lan + + if(Object.isString(container)) { + cstring = container; + } else if(Object.isElement(container)) { + cstring = celement.identify(); + } + + this.histotyHash = ('etab-' + cstring).camelize(); + if(!this.getModCache('-data')) { + this.setModCache('-data', {}); + } + + this.tabData = this.getModCache('-data')['ref-' + cstring]; + this._observer = this.observer.bindAsEventListener(this); //click observer + + if(!this.tabData && !this.___initialized) { + if(this.options.bookmarkFix || this.options.historyNavigation) this.options.history = true; + + this.___methods = $w('show hide select tabSelect ajaxSelect visible getPanelId getMenuId startObserve stopObserve getPanelId getPanel getMenuId getMenu'); + this.tabData = { + container: celement, + list: $A() + } + celement.select('ul.e-tabs > li').inject(this.tabData.list, function(arr, elitem, i) { + var mid = elitem.identify(), + a = elitem.select('a')[0], + act = a.hash.substr(1), + cid = $(act); + + var that = this; + arr[i] = { Index: i, menuId: mid, menu: elitem, menuAction: act, actionItem: a, panel: cid, panelId: cid.id, ajaxUrl: a.readAttribute('rel'), global: that, exec: that._exec.bind(that, i) }; + this._extendTab(arr[i]); + + return arr; + }.bind(this)); + + this.exec_recursive('hide').getDefault().select(); + this.startEvents(); + this.___initialized = true; + this.getModCache('-data')['ref-' + cstring] = this.tabData; + } + }, + + _extendTab: function(data) { + this.___methods.inject(data, function(obj, method) { + obj[method] = this[method].bind(this, obj); + return obj; + }.bind(this)); + data.events = new e107EventManager(this); + data.options = this.options; + data.histotyHash = this.histotyHash; + + return this._detectLoad(data); + }, + + _detectLoad: function(tab) { + if(tab.ajaxUrl) { + var lopts = $w(tab.ajaxUrl).detect(function (values) { + return values.startsWith('ajax-tab-url'); + }); + if(lopts) { + lopts = lopts.substr(('ajax-tab-url::').length); + if(!lopts) { + var link = tab.actionItem.readAttribute('href').split('#')[0]; //link url + tab.ajaxUrl = link ? link : document.location.href.split('#')[0]; //self url + } else { + tab.ajaxUrl = decodeURIComponent(lopts); + } + } + } + return tab; + }, + + _exec: function(index, method, options) { + if(!this.___methods.include(method) || !this.tabData.list[index]) { + throw('e107Widgets.Tabs_exec: wrong method or object not found!'); + } + + this.tabData.list[index][method](options); + return this.tabData.list[index]; + }, + + /** + * Available only in instance' global scope + */ + exec: function(index, method, options) { + this.tabData.list[index].exec(method, options || {}); + return this; + }, + + /** + * Available only in instance' global scope + */ + exec_recursive: function(method, except, options) { + if(except) + this.tabData.list.without(except).invoke('exec', method, options || {}); + else + this.tabData.list.invoke('exec', method, options || {}); + return this; + }, + + _getTabByIdnex: function(index) { + return this.tabData.list[index] || null; + }, + + _getTabByPanelId: function(name) { + return this.tabData.list.find(function(tab_obj) { return tab_obj.getPanelId() == name }) || null; + }, + + /** + * Available only in instance' global scope + */ + get: function(tab) { + if(Object.isNumber(tab)) + return this._getTabByIdnex(tab); + else if(Object.isString(tab)) + return this._getTabByPanelId(tab); + return tab; + }, + + getPanelId: function(tab_obj) { + return tab_obj.panelId; + }, + + getPanel: function(tab_obj) { + return tab_obj.panel; + }, + + getMenuId: function(tab_obj) { + return tab_obj.menuId; + }, + + getMenu: function(tab_obj) { + return tab_obj.menu; + }, + + /** + * Available only in instance' global scope + */ + getDefault: function() { + var current = e107History.get(this.histotyHash); + if(current) { + var tab = this.get(current) || this.tabData.list[0]; + this._active = tab.Index; + return tab; + } + + this._active = 0; + return this.tabData.list[0]; + }, + + getActive: function() { + if(!this.global._active) { + var _active = this.tabData.list.find(function(tab_obj) { return tab_obj.visible(); }) || null; + if(_active) { + this.global._active = _active.Index; + } + } + return this.get(this.global._active); + }, + + visible: function(tab) { + return tab.getPanel().visible(); + }, + + show: function(tab) { + tab.getMenu().addClassName('active'); + tab.getPanel().addClassName('active').show(); + if(tab.global.options.history) + e107History.set(tab.histotyHash, tab.getPanelId()); + return tab; + }, + + hide: function(tab) { + tab.getMenu().removeClassName('active'); + tab.getPanel().removeClassName('active').hide(); + + return tab; + }, + + select: function(tab) { + if(!tab.visible()) { + if(tab.ajaxUrl) + return tab.ajaxSelect(); + return tab.tabSelect(); + } + return tab; + }, + + ajaxSelect: function(tab) { + if(!tab.ajaxUrl || (this.global.options.ajaxCache && tab.options['ajaxCached'])) + return tab.tabSelect(); + + tab.getMenu().addClassName('active'); + new e107Ajax.Updater(tab.getPanel(), tab.ajaxUrl, { + overlayPage: this.options.pageOverlay ? tab.getPanel() : false, + overlayElement: this.global.options.overlayElement ? this.global.options.overlayElement : false, + onComplete: function() { tab.options.ajaxCached = this.global.options.ajaxCache; tab.tabSelect(); }.bind(this) + }); + + return tab; + }, + + tabSelect: function(tab) { + + this.global.events.notify('hideActive', this.global.getActive()); //global trigger + tab.events.notify('hide', this.global.getActive()); // tab object trigger + this.options.hide(this.global.getActive()); + + this.global.events.notify('showSelected', tab); //global trigger + tab.events.notify('show', tab); // tab object trigger + this.options.show(tab); + + this.global._active = tab.Index; + + return tab; + }, + + startEvents: function() { + this.exec_recursive('startObserve'); + this._startHistory(); + return this; + }, + + stopEvents: function() { + this.exec_recursive('stopObserve'); + this._stopHistory(); + return this; + }, + + startObserve: function(tab) { + tab.actionItem.observe('click', this._observer); return this; + }, + + stopObserve: function(tab) { + tab.actionItem.stopObserving('click', this._observer); return this; + }, + + observer: function(event) { + var el = event.findElement('a'); + if(el) { + event.stop(); + + this.get(el.hash.substr(1)).select(); + } + }, + + eventObserve: function(method, callback) { + this.events.observe(method, callback); return this; + }, + + eventStopObserve: function() { + this.events.stopObserving(method, callback); return this; + }, + + _startHistory: function() { + if(this.options.historyNavigation) { + e107History.Observer.start(); + var that = this; + // set handler for this instance + e107History.Registry.set({ + id: this.histotyHash, + onStateChange: function(tab) { + that.get(String(tab)).select(); + } + }); + } + }, + + _stopHistory: function() { + e107History.Observer.stop(); + e107History.Registry.unset(this.histotyHash); + } +}); diff --git a/e107_files/jslib/e107.js.php b/e107_files/jslib/e107.js.php index 26ddb5b3e..77861c017 100644 --- a/e107_files/jslib/e107.js.php +++ b/e107_files/jslib/e107.js.php @@ -1,11 +1,32 @@ +/* + * e107 website system + * + * Copyright (c) 2001-2008 e107 Developers (e107.org) + * Released under the terms and conditions of the + * GNU General Public License (http://gnu.org). + * + * e107 Javascript API + * + * $Source: /cvs_backup/e107_0.8/e107_files/jslib/e107.js.php,v $ + * $Revision: 1.4 $ + * $Date: 2008-11-17 17:43:57 $ + * $Author: secretr $ + * +*/ + +var e107API = { + Version: '1.0.1', + ServerVersion: '0.8.1' +} + /* * Old stuff * FIXME ASAP */ - var nowLocal = new Date(); /* time at very beginning of js execution */ var localTime = Math.floor(nowLocal.getTime()/1000); /* time, in ms -- recorded at top of jscript */ -/* NOTE: if serverDelta is needed for js functions, you must pull it from +/** + * NOTE: if serverDelta is needed for js functions, you must pull it from * the cookie (as calculated during a previous page load!) * The value calculated in SyncWithServerTime is not known until after the * entire page has been processed. @@ -36,7 +57,7 @@ function SyncWithServerTime(serverTime) * @copyright (c) 2008 Netatoo SARL * @license MIT License * - * @desc Used to retrieve the browser version + * @desc Retrieve the browser version */ (function() { var nav = navigator; @@ -44,7 +65,7 @@ function SyncWithServerTime(serverTime) var v = nav.appVersion; var version = parseFloat(v); - Prototype.Browser = { + e107API.Browser = { IE : (Prototype.Browser.IE) ? parseFloat(v.split("MSIE ")[1]) || 0 : 0, Firefox : (Prototype.Browser.Gecko) ? parseFloat(ua.split("Firefox/")[1]) || 0 : 0, Camino : (Prototype.Browser.Gecko) ? parseFloat(ua.split("Camino/")[1]) || 0 : 0, @@ -113,9 +134,8 @@ var e107Registry = { //Global Preferences Pref: { - Core: { - zIndex: 100 //base system z-index + zIndex: 5 //base system z-index } } } @@ -205,7 +225,7 @@ var e107Event = { * EventManager * Prototype Xtensions http://www.prototypextensions.com * - * @desc Easly event manager for creating custom event on your own class + * @desc Create custom events on your own class */ var e107EventManager = Class.create({ @@ -231,7 +251,7 @@ var e107EventManager = Class.create({ /** * observe * - * @desc Add an callback for listener 'name' + * @desc Add a callback for listener 'name' */ observe: function(name, callback) { var observers = this.events.get(name); @@ -239,7 +259,9 @@ var e107EventManager = Class.create({ if(!observers) observers = this.addObserver(name); if(!Object.isFunction(callback)) { - throw('e107EventManager.observe : callback must be an js function'); + //throw('e107EventManager.observe : callback must be an js function'); + //surpess error + return this; } var i = this.events.get(name).keys().length; @@ -248,6 +270,24 @@ var e107EventManager = Class.create({ return this; }, + /** + * stopObserving (class improvements) + * + * @desc Remove callback for listener 'name' + */ + stopObserving: function(name, callback) { + var observers = this.events.get(name); + + if(!observers) return this; + observers.each( function(pair) { + if(pair.value == callback) { + observers.unset(pair.key); + $break; + } + }); + return this; + }, + /** * notify * @@ -255,12 +295,14 @@ var e107EventManager = Class.create({ */ notify: function(name) { var observers = this.events.get(name); - - if(observers) { - var args = $A(arguments).slice(1); - observers.each(function(callback) { - if(Object.isFunction(callback[1])) { - callback[1].apply(this.scope, args); + //console.log('notifying ' + name); + if(observers) { + var args = $A(arguments).slice(1); + //Fix - preserve order + observers.keys().sort().each( function(key) { + var callback = observers.get(key); + if(Object.isFunction(callback)) { + callback.apply(this.scope, args); } }); } @@ -439,22 +481,20 @@ var e107Base = { setCache: function(cache_str, cache_item) { this.clearCache(cache_str); - e107Registry.Cache.set(cache_str, cache_item); + e107Registry.Cache['cache-' + cache_str] = cache_item; return this; }, getCache: function(cache_str, def) { - return varset(e107Registry.Cache.get(cache_str), def); + return varset(e107Registry.Cache['cache-' + cache_str], def); }, - clearCache: function(cache_str, def) { + clearCache: function(cache_str) { var cached = this.getCache(cache_str); - if(null !== cached) { - if(cached.destroy) { - cached.destroy(); - } - } - return varset(e107Registry.Cache.unset(cache_str), def); + if(cached && Object.isFunction(cached['destroy'])) cached.destroy(); + e107Registry.Cache['cache-' + cache_str] = null; + delete e107Registry.Cache['cache-' + cache_str]; + return this; }, parseTemplate: function(mod, name, data) { @@ -570,7 +610,8 @@ Object.extend(String.prototype, { /** * e107WidgetAbstract Class */ -var e107WidgetAbstract = Class.create({ +var e107WidgetAbstract = Class.create(e107Base); +var e107WidgetAbstract = Class.create(e107WidgetAbstract, { initMod: function(modId, options, inherit) { @@ -588,8 +629,7 @@ var e107WidgetAbstract = Class.create({ return match[1] + 'Mod' + match[2]; }); var parent_method = !e107Base[mod_method] ? method : mod_method; - this[mod_method] = e107Base[parent_method].bind(e107Base, this.mod); - //console.log(mod_method, parent_method); + this[mod_method] = e107Base[parent_method].bind(this, this.mod); }.bind(that)); Object.extend(that, { @@ -602,20 +642,24 @@ var e107WidgetAbstract = Class.create({ }, setModCache: function(cache_str, cache_item) { - return e107Base.setCache(this.getModName(true) + cache_str, cache_item); + e107Base.setCache(this.getModName(true) + varsettrue(cache_str, ''), cache_item); + return this; }, getModCache: function(cache_str) { - return e107Base.getCache(this.getModName(true) + cache_str); + return e107Base.getCache(this.getModName(true) + varsettrue(cache_str, '')); }, clearModCache: function(cache_str) { - return e107Base.clearCache(this.getModName(true) + cache_str); + e107Base.clearCache(this.getModName(true) + varsettrue(cache_str, '')); + return this; } }); //Merge option object (recursive) this.setOptions(options, inherit); + + return this; }, @@ -1219,14 +1263,14 @@ e107Utils.LoadingStatus = Class.create(e107WidgetAbstract, { startObserving: function() { Event.observe(window,"resize", this.re_center); - if(Prototype.Browser.IE && Prototype.Browser.IE <= 7) + if(e107API.Browser.IE && e107API.Browser.IE <= 7) Event.observe(window,"scroll", this.re_center); return this; }, stopObserving: function() { Event.stopObserving(window, "resize", this.re_center); - if(Prototype.Browser.IE && Prototype.Browser.IE <= 7) + if(e107API.Browser.IE && e107API.Browser.IE <= 7) Event.stopObserving(window, "scroll", this.re_center); return this; }, @@ -1288,7 +1332,7 @@ e107Utils.LoadingStatus = Class.create(e107WidgetAbstract, { iecenter: function() { //TODO - actually ie7 should work without this - investigate - if(Prototype.Browser.IE && Prototype.Browser.IE <= 7) { + if(e107API.Browser.IE && e107API.Browser.IE <= 7) { //The 'freezing' problem solved (opacity = 1 ?!) this.loading_mask.show(); var offset = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop; @@ -1346,7 +1390,7 @@ e107Event.register('ajax_loading_start', function(event) { loadingObj = new e107Utils.LoadingStatus(false, { show_auto: false }); e107.setModCache('ajax-loader', loadingObj); } - loadingObj.set_destination(event.memo.overlayElement).show(); + loadingObj.set_destination(event.memo.overlayPage).show(); }); e107Event.register('ajax_loading_end', function(event) { @@ -1504,7 +1548,7 @@ var e107History = { this.__title = document.title; - if(Prototype.Browser.IE && Prototype.Browser.IE < 8) { + if(e107API.Browser.IE && e107API.Browser.IE < 8) { document.observe('dom:loaded', function(e) { if(!$('e107-px-historyframe')) { e107History.__iframe = new Element('iframe', { @@ -1566,7 +1610,7 @@ var e107History = { var hash = window.location.hash.substring(1); // If IE, look in the iframe if the hash is updated - if(Prototype.Browser.IE && Prototype.Browser.IE < 8 && this.__iframe) { + if(e107API.Browser.IE && e107API.Browser.IE < 8 && this.__iframe) { var hashInFrame = this.getHashOnIframe(); if(hashInFrame != hash) { @@ -1590,7 +1634,7 @@ var e107History = { window.location.hash = newHash; // If IE, apply new hash to frame for history - if(Prototype.Browser.IE && Prototype.Browser.IE < 8 && this.__iframe) { + if(e107API.Browser.IE && e107API.Browser.IE < 8 && this.__iframe) { if(this.__currentHash != newHash) { this.setHashOnIframe(newHash); @@ -1609,7 +1653,7 @@ var e107History = { * this.__altered allows to force the dispatch. */ isAltered: function() { - if(this.__altered == true) { + if(this.__altered) { return true; } this.__altered = false; @@ -1805,9 +1849,12 @@ e107History.Observer = { // Dispatch only if location.hash has been altered if(e107History.isAltered()) { + var oldstate = String(e107History.__previousHash).toQueryParams(); + //FIXME - possible bugs/performance issues here - investigate further e107History.hash.each(function(pair) { var registry = e107History.Registry.get(pair.key); - if(registry) { + //Bugfix - notify callbacks only when required + if(registry && (e107History.__altered === pair.key || oldstate[pair.key] !== pair.value)) { registry.onStateChange.bind(e107History)( pair.value ); } }); @@ -1866,7 +1913,7 @@ e107Ajax.History = { ? options.history.state : this.getCurrentVersion(id); getter.set(currentVersion, options); } - + // add handler on registry this.addCallback(type, id); @@ -1883,24 +1930,25 @@ e107Ajax.History = { e107History.Observer.start(); // console.log(this.cacheString + id, e107.getModCache(this.cacheString + id).get('0')); // Set history altered state to true : force dispatch - e107History.__altered = true; + e107History.__altered = id; // Return void if registry is already set if(!Object.isUndefined(e107History.Registry.get(id))) return; - + // Add this id to history registry var cacheS = this.cacheString + id; - e107History.Registry.set({ + e107History.Registry.set({ id: id, onStateChange: function(state) { var options = e107.getModCache(cacheS).get(state.toString()); var request = null; - - if(Object.isUndefined(options)) return; - if(options.history.cache == true && options.history.__request) { + if(Object.isUndefined(options)) return; + + if(options.history.cache == true && options.history.__request) { new Ajax.Cache(options.history.__request); } else { + //make a request if(type == 'Request') { request = new Ajax.Request(options.history.__url, options); @@ -2030,8 +2078,10 @@ Ajax.Updater = Class.create(Ajax.Updater, { if(request.options.updateElement) { e107Event.trigger('ajax_update_before', request.options); } - if(request.options.overlayElement){ + if(request.options.overlayPage){ e107Event.trigger('ajax_loading_start', request.options); + } else if(request.options.overlayElement) { //FIXME - overlay element feature + e107Event.trigger('ajax_loading_element_start', request.options, $(request.options.overlayElement)); } }, @@ -2040,9 +2090,11 @@ Ajax.Updater = Class.create(Ajax.Updater, { e107Event.trigger('ajax_update_after', request.options); } /*Ajax.activeRequestCount == 0 && */ - if(request.options.overlayElement) { + if(request.options.overlayPage) { e107Event.trigger('ajax_loading_end', request.options); - } + } else if(request.options.overlayElement) { //FIXME - overlay element feature + e107Event.trigger('ajax_loading_element_end', request.options, $(request.options.overlayElement)); + } }, onException: function(request, e) { @@ -2230,11 +2282,12 @@ e107Ajax.Updater = Class.create({ initialize: function(container, url, options) { this.options = {}; - if(!options.parameters) options.parameters = {}; Object.extend(this.options, options || {}); - if(!this.options['parameters'] || !this.options.parameters['ajax_used']) - Object.extend(this.options['parameters'], { 'ajax_used': 1 }); + if(!this.options['parameters']) + this.options['parameters'] = { 'ajax_used': 1 } + else if(!this.options.parameters['ajax_used']) + this.options['parameters']['ajax_used'] = 1; //required for ajax_update event trigger this.options.updateElement = container; @@ -2255,7 +2308,7 @@ e107Ajax.Updater = Class.create({ } // Add container to this.options this.options.container = container; - + // Enable history observer var version = e107Ajax.History.observe('Updater', id, url, this.options); @@ -2328,7 +2381,7 @@ e107Ajax.fillForm = Class.create(e107AjaxAbstract, { //Ajax history is NOT supported (and shouldn't be) var options = { - overlayElement: destEl, + overlayPage: destEl, history: false, diff --git a/e107_handlers/js_helper.php b/e107_handlers/js_helper.php index 5a4bd3ef8..4cd535eb9 100644 --- a/e107_handlers/js_helper.php +++ b/e107_handlers/js_helper.php @@ -7,8 +7,8 @@ * GNU General Public License (http://gnu.org). * * $Source: /cvs_backup/e107_0.8/e107_handlers/js_helper.php,v $ - * $Revision: 1.1 $ - * $Date: 2008-11-09 20:31:10 $ + * $Revision: 1.2 $ + * $Date: 2008-11-17 17:43:57 $ * $Author: secretr $ * */ @@ -53,9 +53,16 @@ class e_jshelper /** * Response array getter * + * @param bool $reset clear current response actions * @return array response actions */ - function getResponseActions() { + function getResponseActions($reset = false) { + if($reset) + { + $ret = $this->_response_actions; + $this->_reset(); + return $ret; + } return $this->_response_actions; } @@ -68,7 +75,7 @@ class e_jshelper */ function buildXMLResponse() { - $action_array = $this->getResponseActions(); + $action_array = $this->getResponseActions(true); $ret = "\n"; foreach ($action_array as $action => $field_array) { @@ -82,7 +89,7 @@ class e_jshelper continue; $transport_value = $value; if(!is_numeric($value) && !is_bool($value)) { $transport_value = ""; } - $ret .= "\t{$transport_value}\n"; + $ret .= "\t\t{$transport_value}\n"; } $ret .= "\t\n"; } @@ -114,7 +121,7 @@ class e_jshelper */ function buildJSONResponse() { - return "/*-secure-\n".json_encode($this->getResponseActions())."\n*/"; + return "/*-secure-\n".json_encode($this->getResponseActions(true))."\n*/"; } /** @@ -133,6 +140,17 @@ class e_jshelper echo $this->buildJSONResponse(); } + /** + * Reset response action array to prevent duplicates + * + * @access private + * @return void + */ + function _reset() + { + $this->_response_actions = array(); + } + /** * Convert (optional) and send array as JSON response string * @@ -153,14 +171,14 @@ class e_jshelper * @param string $errextended * @param bool $exit */ - function sendAjaxError($errcode, $errmessage, $errextended='', $exit=true) + function sendAjaxError($errcode, $errmessage, $errextended = '', $exit = true) { header('Content-type: text/html; charset='.CHARSET, true); header("HTTP/1.0 {$errcode} {$errmessage}", true); header("e107ErrorMessage: {$errmessage}", true); header("e107ErrorCode: {$errcode}", true); - //Safari also needs some kind of output + //Safari expects some kind of output, even empty echo ($errextended ? $errextended : ' '); if($exit) exit; @@ -170,13 +188,13 @@ class e_jshelper * Clean string to be used as JS string * Should be using for passing strings to e107 JS API - e.g Languages,Templates etc. * - * @param string $lan_string + * @param string $string * @return string * @access static */ - function toString($lan_string) + function toString($string) { - return "'".str_replace(array("\\", "'"), array("", "\\'"), $lan_string)."'"; + return "'".str_replace(array("\\", "'"), array("", "\\'"), $string)."'"; } } ?> \ No newline at end of file diff --git a/e107_images/generic/loading_16.gif b/e107_images/generic/loading_16.gif new file mode 100644 index 000000000..11c289e4e Binary files /dev/null and b/e107_images/generic/loading_16.gif differ diff --git a/e107_images/generic/loading_32.gif b/e107_images/generic/loading_32.gif new file mode 100644 index 000000000..f864d5fd3 Binary files /dev/null and b/e107_images/generic/loading_32.gif differ