Author: jeremy Date: Sun Oct 2 05:41:05 2005 New Revision: 293104 URL: http://svn.apache.org/viewcvs?rev=293104&view=rev Log: Updating CForms to use the prototype.js lib for all AJAX work. Adding TimedBrowserUpdater and sample to the Ajax Block Added: cocoon/blocks/ajax/trunk/java/org/apache/cocoon/ajax/resources/js/browserupdater.js cocoon/blocks/ajax/trunk/java/org/apache/cocoon/ajax/resources/js/domutils.js cocoon/blocks/ajax/trunk/java/org/apache/cocoon/ajax/resources/js/timedbrowserupdater.js cocoon/blocks/ajax/trunk/java/org/apache/cocoon/ajax/resources/macros/ cocoon/blocks/ajax/trunk/java/org/apache/cocoon/ajax/resources/macros/timedbrowserupdater.xml cocoon/blocks/ajax/trunk/samples/i18n/ cocoon/blocks/ajax/trunk/samples/i18n/timedbrowserupdater.xml cocoon/blocks/ajax/trunk/samples/timed-updater.xml Modified: cocoon/blocks/ajax/trunk/java/org/apache/cocoon/ajax/resources/js/cocoon-ajax.js cocoon/blocks/ajax/trunk/samples/flow.js cocoon/blocks/ajax/trunk/samples/sitemap.xmap cocoon/blocks/ajax/trunk/samples/welcome.xml cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/resources/forms-field-styling.xsl cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/resources/js/cforms.js cocoon/blocks/forms/trunk/samples/sitemap.xmap Added: cocoon/blocks/ajax/trunk/java/org/apache/cocoon/ajax/resources/js/browserupdater.js URL: http://svn.apache.org/viewcvs/cocoon/blocks/ajax/trunk/java/org/apache/cocoon/ajax/resources/js/browserupdater.js?rev=293104&view=auto ============================================================================== --- cocoon/blocks/ajax/trunk/java/org/apache/cocoon/ajax/resources/js/browserupdater.js (added) +++ cocoon/blocks/ajax/trunk/java/org/apache/cocoon/ajax/resources/js/browserupdater.js Sun Oct 2 05:41:05 2005 @@ -0,0 +1,275 @@ +/* + * Copyright 1999-2005 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* @version $Id$ */ + + +BrowserUpdater = Class.create(); +Object.extend(Object.extend(BrowserUpdater.prototype, Ajax.Request.prototype), { + initialize: function(url, options) { + this.transport = Ajax.getTransport(); + this.setOptions(options); + + var onComplete = this.options.onComplete || Prototype.emptyFunction; + this.options.onComplete = (function() { + if (this.checkContinue(this.options.form)) { + this.updateContent(); + onComplete(this.transport); + } + }).bind(this); + + this.request(url); + }, + + updateContent: function() { + var doc = this.transport.responseXML; + if (doc) { + var nodes = doc.documentElement.childNodes; + for (var i = 0; i < nodes.length; i++) { + var node = nodes[i]; + if (node.nodeType == DOMUtils.ELEMENT_NODE) { + var handler; + if (node.localName) { + handler = node.localName; + } else { + // No DOM2 support (IE6) + handler = node.nodeName.replace(/.*:/, ""); + } + var handlerFunc = BrowserUpdater.handlers[handler]; + if (handlerFunc) { + handlerFunc(node); + } else { + this.handleError("No handler found for element " + handler, this.transport); + return; + } + } + } + } else { + this.handleError("No xml answer", this.transport); + return; + } + + if (this.responseIsSuccess()) { + if (this.onComplete) { + setTimeout((function() {this.onComplete(this.transport)}).bind(this), 10); + } + document.body.style.cursor = "auto"; + self.status = "Update Complete"; + } + }, + + checkContinue: function(form) { + if (!form) return true; + var xca; + try { // An exception is thrown if header doesn't exist (at least in Moz) + xca = this.transport.getResponseHeader("X-Cocoon-Ajax"); + } catch (e) { + // header doesn't exist + } + if (xca == "continue") { + // Interaction with this page is finished: redirect the browser to the form's action URL + // Get the continuation-id, if any. + var contParam = '?cocoon-ajax-continue=true'; + if (form.elements && form.elements["continuation-id"]) { + contParam += "&continuation-id=" + form.elements["continuation-id"].value; + } + window.location.href = form.action + contParam; + return false; + } else { + return true; + } + }, + + handleError: function(message, request) { + if (confirm(message + "\nShow server response?")) { + var w = window.open(undefined, "Cocoon Error", "location=no"); + if (w == undefined) { + alert("You must allow popups from this server to display the response."); + } else { + var doc = w.document; + doc.open(); + doc.write(request.responseText); + doc.close(); + } + } + } + +}); + +BrowserUpdater.handlers = { + replace : function(element) { + var id = element.getAttribute("id"); + if (!id) { + alert("no id found on update element"); + return; + } + // Get the first child element (the first child may be some text!) + var firstChild = DOMUtils.firstChildElement(element); + + var oldElement = document.getElementById(id); + + if (!oldElement) { + alert("no element '" + id + "' in source document"); + return; + } + + var newElement = DOMUtils.importNode(firstChild, document); + + // Warn: it's replace(new, old)!! + oldElement.parentNode.replaceChild(newElement, oldElement); + // Ensure the new node has the correct id + newElement.setAttribute("id", id); + + if (BrowserUpdater.highlight) { + BrowserUpdater.highlight(newElement); + } + } + +} + +// NB. This will probably be replaced with scriptaculous Effects + + + +//------------------------------------------------------------------------------------------------- +// Fader used to highlight page areas that have been updated +//------------------------------------------------------------------------------------------------- + +/** + * Create a fader that will progressively change an element's background color from + * a given color back to its original color. + * + * @param elt the element to fade + * @param color the starting color (default yellow) + * @param duration the fade duration in msecs (default 1000) + * @param fps the animation frames per seconds (default 25) + */ +function Fader(elt, color, duration, fps) { + // Set default values + if (!color) color = "#FFFF80"; // yellow + if (!duration) duration = 1000; // 1 sec + if (!fps) fps = 25; // 25 frames/sec + + this.element = elt; + this.fromColor = Fader.colorToRgb(color); + this.toColor = Fader.colorToRgb(Fader.getBgColor(this.element)); + + this.maxFrames = Math.round(fps * duration / 1000.0); + this.delay = duration / this.maxFrames; +} + +/** + * Creates a default fader for a given element. This function can be used to set BrowserUpdate.highlight + */ +Fader.fade = function(elt) { + new Fader(elt).start(); +} + +Fader.prototype.start = function() { + this.frame = 0; + this._changeColor(); +} + +Fader.prototype._changeColor = function() { + if (this.frame < this.maxFrames) { + // Schedule the next iteration right now to keep a more accurate timing + var fader = this; + setTimeout(function() {fader._changeColor();}, this.delay); + } + var newColor = new Array(3); + for (var channel = 0; channel < 3; channel++) { + newColor[channel] = Math.floor( + this.fromColor[channel] * ((this.maxFrames - this.frame) / this.maxFrames) + + this.toColor[channel] * (this.frame/this.maxFrames) + ); + } + + this.frame++; + var color = Fader.rgbToColor(newColor[0], newColor[1], newColor[2]); + this.element.style.backgroundColor = color; +} + +/** Converts a "#RRGGBB" color as an array of 3 ints */ +Fader.colorToRgb = function(hex) { + return [ + parseInt(hex.substr(1,2),16), + parseInt(hex.substr(3,2),16), + parseInt(hex.substr(5,2),16) ]; +} + +/** Converts rgb values to a "#RRGGBB" color */ +Fader.rgbToColor = function(r, g, b) { + r = r.toString(16); if (r.length == 1) r = '0' + r; + g = g.toString(16); if (g.length == 1) g = '0' + g; + b = b.toString(16); if (b.length == 1) b = '0' + b; + return "#" + r + g + b; +} + +/** Get the background color of an element */ +Fader.getBgColor = function(elt) { + while(elt) { + var c; + if (window.getComputedStyle) c = window.getComputedStyle(elt,null).getPropertyValue("background-color"); + if (elt.currentStyle) c = elt.currentStyle.backgroundColor; + if ((c != "" && c != "transparent") || elt.tagName == "BODY") { break; } + elt = elt.parentNode; + } + if (c == undefined || c == "" || c == "transparent" || c == "white") c = "#FFFFFF"; + + var rgb = c.match(/rgb\s*\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)/); + if (rgb) return this.rgbToColor(parseInt(rgb[1]),parseInt(rgb[2]),parseInt(rgb[3])); + return c; +} + +BrowserUpdater.highlight = Fader.fade; + +//------------------------------------------------------------------------------------------------- +// Blinker used to highlight page areas that have been updated +//------------------------------------------------------------------------------------------------- + +function Blinker(elt, color, hltDelay, normalDelay, blinks) { + this.element = elt; + if (!color) color = "#FFFF80"; // yellow + if (!hltDelay) hltDelay = 100; + if (!normalDelay) normalDelay = 100; + if (!blinks) blinks = 2; + + this.hltColor = color; + this.hltDelay = hltDelay; + this.normalDelay = normalDelay; + this.normalColor = Fader.getBgColor(elt); + this.maxBlinks = blinks * 2; + this.blink = 0; +} + +Blinker.prototype.start = function() { + this.blink = 0; + this._doBlink(); +} + +Blinker.blink = function(elt) { + new Blinker(elt).start(); +} + +Blinker.prototype._doBlink = function() { + var hlt = (this.blink % 2 == 0); + this.element.style.backgroundColor = hlt ? this.hltColor : this.normalColor;; + if (this.blink <= this.maxBlinks) { + var blinker = this; + setTimeout(function() {blinker._doBlink();}, hlt ? this.hltDelay : this.normalDelay); + } + this.blink++; +} Modified: cocoon/blocks/ajax/trunk/java/org/apache/cocoon/ajax/resources/js/cocoon-ajax.js URL: http://svn.apache.org/viewcvs/cocoon/blocks/ajax/trunk/java/org/apache/cocoon/ajax/resources/js/cocoon-ajax.js?rev=293104&r1=293103&r2=293104&view=diff ============================================================================== --- cocoon/blocks/ajax/trunk/java/org/apache/cocoon/ajax/resources/js/cocoon-ajax.js (original) +++ cocoon/blocks/ajax/trunk/java/org/apache/cocoon/ajax/resources/js/cocoon-ajax.js Sun Oct 2 05:41:05 2005 @@ -31,6 +31,8 @@ this.require(path + 'dragdrop.js'); this.require(path + 'controls.js'); this.require(path + 'slider.js'); + this.require(path + 'browserupdater.js'); + this.require(path + 'domutils.js'); return; } } Added: cocoon/blocks/ajax/trunk/java/org/apache/cocoon/ajax/resources/js/domutils.js URL: http://svn.apache.org/viewcvs/cocoon/blocks/ajax/trunk/java/org/apache/cocoon/ajax/resources/js/domutils.js?rev=293104&view=auto ============================================================================== --- cocoon/blocks/ajax/trunk/java/org/apache/cocoon/ajax/resources/js/domutils.js (added) +++ cocoon/blocks/ajax/trunk/java/org/apache/cocoon/ajax/resources/js/domutils.js Sun Oct 2 05:41:05 2005 @@ -0,0 +1,91 @@ +/* + * Copyright 1999-2005 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +DOMUtils = { + // Stupid IE doesn't have these constants + ELEMENT_NODE : 1, + ATTRIBUTE_NODE : 2, + TEXT_NODE : 3, + CDATA_SECTION_NODE : 4, + ENTITY_REFERENCE_NODE : 5, + ENTITY_NODE : 6, + PROCESSING_INSTRUCTION_NODE : 7, + COMMENT_NODE : 8, + DOCUMENT_NODE : 9, + DOCUMENT_TYPE_NODE : 10, + DOCUMENT_FRAGMENT_NODE : 11 +} + +/** + * Get the first child element of an element, ignoring text nodes + */ +DOMUtils.firstChildElement = function(element) { + var nodes = element.childNodes; + for (var i = 0; i < nodes.length; i++) { + var node = nodes[i]; + if (node.nodeType == this.ELEMENT_NODE) { + return node; + } + } +} + +/** + * Imports an element into a document, taking care of using the correct implementation + * so that the browser interprets it as displayable XML + */ +DOMUtils.importNode = function(node, targetDoc) { + if(node.xml) { + // IE + var div = targetDoc.createElement("DIV"); + div.innerHTML = node.xml; + return this.firstChildElement(div); + } else { + return DOMUtils._importNode(node, targetDoc); + } +} + +/** + * DOM implementation of importNode, recursively creating nodes + */ +DOMUtils._importNode = function(node, targetDoc) { + switch(node.nodeType) { + case this.ELEMENT_NODE: + var element = targetDoc.createElement(node.nodeName); + //var element = targetDoc.createElementNS(node.namespaceURI, node.nodeName); + var attrs = node.attributes; + for (var i = 0; i < attrs.length; i++) { + attr = attrs[i]; + element.setAttribute(attr.nodeName, attr.nodeValue); + //element.setAttributeNS(attr.namespaceURI, attr.nodeName, attr.nodeValue); + } + var children = node.childNodes; + for (var j = 0; j < children.length; j++) { + var imported = this.importNode(children[j], targetDoc); + if (imported) element.appendChild(imported); + } + return element; + break; + + case this.TEXT_NODE: + return targetDoc.createTextNode(node.nodeValue); + break; + + case this.CDATA_SECTION_NODE: + return targetDoc.createTextNode(node.nodeValue); + break; + } +} + Added: cocoon/blocks/ajax/trunk/java/org/apache/cocoon/ajax/resources/js/timedbrowserupdater.js URL: http://svn.apache.org/viewcvs/cocoon/blocks/ajax/trunk/java/org/apache/cocoon/ajax/resources/js/timedbrowserupdater.js?rev=293104&view=auto ============================================================================== --- cocoon/blocks/ajax/trunk/java/org/apache/cocoon/ajax/resources/js/timedbrowserupdater.js (added) +++ cocoon/blocks/ajax/trunk/java/org/apache/cocoon/ajax/resources/js/timedbrowserupdater.js Sun Oct 2 05:41:05 2005 @@ -0,0 +1,218 @@ +/* + * Copyright 1999-2005 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* @version $Id$ */ + + +TimedBrowserUpdater = Class.create(); +TimedBrowserUpdater.prototype = Object.extend(new Ajax.Base(), { + initialize: function(url, options) { + this.setOptions(options); + this.onComplete = this.options.onComplete; + this.autostart = (this.options.autostart || true); // default autostart: true + this.frequency = (this.options.frequency || 30); // default frequency: 5 minutes + this.decay = 1; // default decay: none + this.populated = false; + this.updater = {}; + this.widgets = {}; + this.url = url; + this.timerIsRunning = false; + this.start(); + }, + + start: function() { + this.options.onComplete = this.updateComplete.bind(this); + this.onTimerEvent(); + this.timerIsRunning = true; + self.status = "Timer Starting"; + }, + + stop: function() { + this.updater.onComplete = undefined; + clearTimeout(this.timer); + this.timerIsRunning = false; + //(this.onComplete || Ajax.emptyFunction).apply(this, arguments); + self.status = "Timer Stoping"; + }, + + updateComplete: function(request) { + if (this.options.decay) { + this.decay = (request.responseText == this.lastText ? + this.decay * this.options.decay : 1); + + this.lastText = request.responseText; + } + this.updateWidgets(request.responseXML); + this.timer = setTimeout(this.onTimerEvent.bind(this), this.decay * this.frequency * 1000); + }, + + onTimerEvent: function() { + if (this.populated) { + this.options.postBody = this.buildQueryString(); + this.updater = new BrowserUpdater(this.url, this.options); + self.status = "Timer fired event"; + } else { + this.timer = setTimeout(this.onTimerEvent.bind(this), this.decay * this.frequency * 1000); + } + }, + + updateWidgets: function(doc) { + var nodes = doc.documentElement.childNodes; + for (var i = 0; i < nodes.length; i++) { + var node = nodes[i]; + if (node.nodeType == DOMUtils.ELEMENT_NODE) { + this.widgets[node.getAttribute("id")] = node.getAttribute("state"); + } + } + }, + + registerWidget: function(id, state) { + this.widgets[id] = state; + this.populated = true; + }, + + buildQueryString: function () { + var result = "cocoon-ajax=true"; + for (var key in this.widgets) { + result += "&" + encodeURIComponent(key) + "=" + encodeURIComponent(this.widgets[key]); + } + // see if there is a form with a continuation parameter + for (var form in document.forms) { + if (form != null && form.elements != null && form.elements["continuation-id"] != null) { + result += "&continuation-id=" + form.elements["continuation-id"].value; + break; + } + } + self.status = result; + return result; + } + +}); + +TimedBrowserUpdater.Console = Class.create(); +TimedBrowserUpdater.Console.prototype = Object.extend(new Ajax.Base(), { + initialize: function(client, options) { + this.expires = 604800000; // cookie expiry, 1 week + this.client = client; + this.setOptions(options); + this.console = this.options.console; + this.message("Initialise"); + this.isRunningTitle = ( this.options.isRunningTitle || "ON" ); + this.notRunningTitle = ( this.options.notRunningTitle || "OFF" ); + this.isRunningHint = ( this.options.isRunningHint || "Click to Stop" ); + this.notRunningHint = ( this.options.notRunningHint || "Click to Start" ); + this.frequencyControl = this.options.frequencyControl; + this.toggleControl = this.options.toggleControl; + + var autorun = this.getPreference( "TimedBrowserUpdater.autorun" ); + if ( autorun == undefined ) { + this.message("Autorun undefined"); + this.startTimer( ); + } else if ( autorun == "true" ) { + this.message("Autorun true"); + this.startTimer( ); + } else { + this.message("Autorun false"); + this.stopTimer( ); + } + + var frequency = this.getPreference( "TimedBrowserUpdater.frequency" ); + if ( frequency == undefined ) frequency = 300; + this.setFrequency(frequency); + }, + + message: function(message) { + if (this.console != undefined) { + this.console.value = this.console.value + "\n" + message; + } else { + self.status = message; + } + }, + + toggleTimer: function() { + if (this.client.timerIsRunning) { + this.stopTimer(); + } else { + this.startTimer(); + } + }, + + startTimer: function() { + if (!this.client.timerIsRunning) { + this.client.start( ); + this.message("Client Started"); + } + this.setPreference( "TimedBrowserUpdater.autorun", "true" ); + this.toggleControl.value = this.isRunningTitle; + this.toggleControl.title = this.isRunningHint; + }, + + stopTimer: function() { + if (this.client.timerIsRunning) { + this.client.stop( ); + this.message("Client Stopped"); + } + this.setPreference( "TimedBrowserUpdater.autorun", "false" ); + this.toggleControl.value = this.notRunningTitle; + this.toggleControl.title = this.notRunningHint; + }, + + setFrequency: function() { + var frequency = this.frequencyControl.value; + this.client.frequency = frequency; + this.setPreference( "TimedBrowserUpdater.frequency", frequency ); + for ( var i=0;i < this.frequencyControl.options.length;i++ ) { + if ( frequency == this.frequencyControl.options[i].value ) { + this.frequencyControl.selectedIndex = i; + break; + } + } + }, + + setPreference: function(name, value) { + var expiredate = new Date(); + expiredate.setTime(expiredate.getTime() + this.expires); + document.cookie = name + "=" + value + "; expires=" + expiredate.toGMTString() + "; path=/"; + this.message("Set Preference: " + name + ": " + value); + }, + + getPreference: function(name){ + var neq = name + "="; + var k = document.cookie.split(';'); + for (var i=0; i < k.length; i++) { + var c = k[i]; + while (c.charAt(0)==' ') c = c.substring(1,c.length); + if (c.indexOf(neq) == 0) { + var result = c.substring(neq.length,c.length); + this.message( "Read Preference: " + name + ": " + result); + return result; + } + } + this.message( "Read Preference: " + name + ": undefined"); + return undefined; + } + + + +}); + +TimedBrowserUpdaterInstance = new TimedBrowserUpdater( + document.location, + { + method: 'post', + onFailure: BrowserUpdater.handleError + } +); Added: cocoon/blocks/ajax/trunk/java/org/apache/cocoon/ajax/resources/macros/timedbrowserupdater.xml URL: http://svn.apache.org/viewcvs/cocoon/blocks/ajax/trunk/java/org/apache/cocoon/ajax/resources/macros/timedbrowserupdater.xml?rev=293104&view=auto ============================================================================== --- cocoon/blocks/ajax/trunk/java/org/apache/cocoon/ajax/resources/macros/timedbrowserupdater.xml (added) +++ cocoon/blocks/ajax/trunk/java/org/apache/cocoon/ajax/resources/macros/timedbrowserupdater.xml Sun Oct 2 05:41:05 2005 @@ -0,0 +1,188 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + +
+ tbu.name.title + + +
+ tbu.frequency.title + + +
+
+ +
+ + +
Modified: cocoon/blocks/ajax/trunk/samples/flow.js URL: http://svn.apache.org/viewcvs/cocoon/blocks/ajax/trunk/samples/flow.js?rev=293104&r1=293103&r2=293104&view=diff ============================================================================== --- cocoon/blocks/ajax/trunk/samples/flow.js (original) +++ cocoon/blocks/ajax/trunk/samples/flow.js Sun Oct 2 05:41:05 2005 @@ -17,6 +17,10 @@ /** * @version $Id$ */ + +importClass(Packages.java.util.Calendar); + + var resolver = cocoon.getComponent(org.apache.excalibur.source.SourceResolver.ROLE); function fileBrowserSuggest() { @@ -49,4 +53,15 @@ cocoon.sendPage("display-suggestions", { suggestions: suggestions, selection: cocoon.request.getParameter("filename")}); +} + +function timedUpdateDemo() { + var calendar = Calendar.getInstance(); + var data = { + time: calendar.getTime(), + hour: calendar.get(Calendar.HOUR_OF_DAY), + min: calendar.get(Calendar.MINUTE), + rand: Math.random() + }; + cocoon.sendPage("timed-updater-screen", {data: data}); } Added: cocoon/blocks/ajax/trunk/samples/i18n/timedbrowserupdater.xml URL: http://svn.apache.org/viewcvs/cocoon/blocks/ajax/trunk/samples/i18n/timedbrowserupdater.xml?rev=293104&view=auto ============================================================================== --- cocoon/blocks/ajax/trunk/samples/i18n/timedbrowserupdater.xml (added) +++ cocoon/blocks/ajax/trunk/samples/i18n/timedbrowserupdater.xml Sun Oct 2 05:41:05 2005 @@ -0,0 +1,34 @@ + + + + + Console for controlling the Timed Browser Updater + Update + how often the updater will run + Frequency + 30 secs + 1 minute + 2 minutes + 5 minutes + 10 minutes + ON + OFF + click to stop the updater + click to start the updater + \ No newline at end of file Modified: cocoon/blocks/ajax/trunk/samples/sitemap.xmap URL: http://svn.apache.org/viewcvs/cocoon/blocks/ajax/trunk/samples/sitemap.xmap?rev=293104&r1=293103&r2=293104&view=diff ============================================================================== --- cocoon/blocks/ajax/trunk/samples/sitemap.xmap (original) +++ cocoon/blocks/ajax/trunk/samples/sitemap.xmap Sun Oct 2 05:41:05 2005 @@ -20,6 +20,18 @@ --> + + + + + + + + true + + + + @@ -66,7 +78,28 @@ + + + + + + + + + + + + + + + + + + + + + Added: cocoon/blocks/ajax/trunk/samples/timed-updater.xml URL: http://svn.apache.org/viewcvs/cocoon/blocks/ajax/trunk/samples/timed-updater.xml?rev=293104&view=auto ============================================================================== --- cocoon/blocks/ajax/trunk/samples/timed-updater.xml (added) +++ cocoon/blocks/ajax/trunk/samples/timed-updater.xml Sun Oct 2 05:41:05 2005 @@ -0,0 +1,62 @@ + + + + + + + + Timed Browser Updater Demo + +