You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by je...@apache.org on 2005/10/02 14:41:24 UTC
svn commit: r293104 - in /cocoon/blocks:
ajax/trunk/java/org/apache/cocoon/ajax/resources/js/
ajax/trunk/java/org/apache/cocoon/ajax/resources/macros/
ajax/trunk/samples/ ajax/trunk/samples/i18n/
forms/trunk/java/org/apache/cocoon/forms/resources/ form...
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 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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$
+-->
+
+<!-- An implementation of the TimedBrowserUpdate template engine as a JXTemplate tag library -->
+
+ <!--+ Usage Instructions
+ +
+ + The purpose of this Macro is to make regions in a webpage
+ + that update themselves periodically without user interaction.
+ + This is implemented using AJAX techniques taken from CForms.
+ +
+ + 1. Import this macro into your JXTemplate :
+ +
+ + <jx:import uri="resource://org/apache/cocoon/ajax/resources/macros/timedbrowserupdater.xml"/>
+ +
+ + 2. Use the tags in your page where you want auto-updating to occur :
+ +
+ + <tbu:replace id="element.id" state="${change.value}">
+ + <td id="element.id">
+ + Your value is: <b>${change.value}</b>
+ + </td>
+ + </tbu:replace>
+ +
+ + Where:
+ + "element.id" is an id that is unique to your page
+ + "change.value" is the value that you are primarilily interested in tracking
+ + i.e. the update is only made if this value changes.
+ +
+ + Note: The id attribute of both the <tbu:replace> and the child of <tbu:replace>
+ + would normally be the same as this indicates that this is the element being replaced.
+ + Only the first child of <tbu:replace> is used.
+ +
+ + 3. Add the BrowserUpdateTransformer to your pipeline, after the JXTGenerator.
+ +
+ + <map:transform type="browser-update"/>
+ +
+ + 4. Have your page load the JavaScript.
+ +
+ + <script type="text/javascript" src="resources/ajax/js/cocoon-ajax.js"/>
+ + <script type="text/javascript" src="resources/ajax/js/timedbrowserupdater.js"/>
+ +
+ + 5. Effect
+ +
+ + When the page is first loaded, it will display all of it's content normally,
+ + including the content of the <tbu:replace> tags.
+ + Thereafter, every 5 minutes, the regions inside <tbu:replace> tags will
+ + automatically update, having retrieved any changed values via an XMLHTTPRequest
+ + in the background, to the same URI as the page.
+ +
+ + 6. Console
+ +
+ + There is an optional sample console to control TimedBrowserUpdate.
+ +
+ + <tbu:console i18nCatalogue="catalogue.name"/>
+ +
+ + This outputs a simple form to control the Updater.
+ + It is not designed to be placed on the page more than once.
+ +
+ + You need to supply the name of an i18n Catalogue that contain terms used by the console
+ + and you need to ensure that the I18nTransformer is in your pipeline.
+ +
+ + The Console used these i18n keys :
+ +
+ + tbu.name.title the label in the console
+ + tbu.name.hint the hint of the console
+ + tbu.delay.title the label of the delay control
+ + tbu.delay.hint the hint of the delay control
+ + tbu.delay.30 delay for 300 secs
+ + tbu.delay.60 delay for 60 secs
+ + tbu.delay.120 delay for 120 secs
+ + tbu.delay.300 delay for 300 secs
+ + tbu.delay.600 delay for 600 secs
+ + tbu.isrunning.title button text for running state
+ + tbu.isrunning.hint button hint for running state
+ + tbu.notrunning.title button text for not running state
+ + tbu.notrunning.hint button hint for not running state
+ +
+ +-->
+
+
+
+<jx:template xmlns:jx="http://apache.org/cocoon/templates/jx/1.0"
+ xmlns:bu="http://apache.org/cocoon/browser-update/1.0"
+ xmlns:tbu="http://apache.org/cocoon/timed-browser-update/1.0"
+ xmlns:i18n="http://apache.org/cocoon/i18n/2.1">
+
+ <jx:macro name="replace" targetNamespace="http://apache.org/cocoon/timed-browser-update/1.0">
+ <jx:parameter name="id"/>
+ <jx:parameter name="state"/>
+ <jx:choose>
+ <jx:when test="${cocoon.request.getParameter('cocoon-ajax') == 'true' && cocoon.request.getParameter(id) != state}">
+ <bu:replace id="${id}" state="${state}">
+ <jx:evalBody/>
+ </bu:replace>
+ </jx:when>
+ <jx:otherwise>
+ <script language="Javascript">
+ TimedBrowserUpdaterInstance.registerWidget("${id}","${state}");
+ </script>
+ <jx:evalBody/>
+ </jx:otherwise>
+ </jx:choose>
+ </jx:macro>
+
+
+ <jx:macro name="console" targetNamespace="http://apache.org/cocoon/timed-browser-update/1.0">
+ <jx:parameter name="i18nCatalogue"/>
+
+ <form id="tbuconsole" name="tbuconsole">
+ <table class="tbuConsole" title="${i18nCatalogue}:tbu.name.hint" i18n:attr="title">
+ <tr>
+ <th class="tbuName">
+ <i18n:text i18n:catalogue="${i18nCatalogue}">tbu.name.title</i18n:text>
+ </th>
+ <td class="tbuRunning">
+ <input id="tbuToggleRunButton"
+ type="button"
+ title=""
+ value=""
+ onClick="TimedBrowserConsole.toggleTimer();"
+ tabindex="32000"
+ />
+ </td>
+ </tr>
+ <tr>
+ <th class="tbuFrequencyTitle">
+ <i18n:text i18n:catalogue="${i18nCatalogue}">tbu.frequency.title</i18n:text>
+ </th>
+ <td class="tbuFrequency">
+ <select id="tbuFrequencySelector"
+ size="1"
+ onchange="TimedBrowserConsole.setFrequency();"
+ title="${i18nCatalogue}:tbu.frequency.hint"
+ i18n:attr="title"
+ tabindex="32001"
+ >
+ <option value="30"><i18n:text i18n:catalogue="${i18nCatalogue}">tbu.frequency.30</i18n:text></option>
+ <option value="60"><i18n:text i18n:catalogue="${i18nCatalogue}">tbu.frequency.60</i18n:text></option>
+ <option value="120"><i18n:text i18n:catalogue="${i18nCatalogue}">tbu.frequency.120</i18n:text></option>
+ <option value="300"><i18n:text i18n:catalogue="${i18nCatalogue}">tbu.frequency.300</i18n:text></option>
+ <option value="600"><i18n:text i18n:catalogue="${i18nCatalogue}">tbu.frequency.600</i18n:text></option>
+ </select>
+ </td>
+ </tr>
+ <!-- uncomment this row to see the debug console -->
+ <!--<tr>
+ <th align="top">console</th>
+ <td class="tbuDebugConsole">
+ <textarea id="tbuConsole" rows="10" cols="40"></textarea>
+ </td>
+ </tr>-->
+ </table>
+ </form>
+ <script language="Javascript">
+ TimedBrowserConsole = new TimedBrowserUpdater.Console (
+ TimedBrowserUpdaterInstance,
+ {
+ frequencyControl: $("tbuFrequencySelector"),
+ toggleControl: $("tbuToggleRunButton"),
+ console: $("tbuDebugConsole"),
+ isRunningTitle: "<i18n:text i18n:catalogue="${i18nCatalogue}">tbu.isrunning.title</i18n:text>",
+ notRunningTitle: "<i18n:text i18n:catalogue="${i18nCatalogue}">tbu.notrunning.title</i18n:text>",
+ isRunningHint: "<i18n:text i18n:catalogue="${i18nCatalogue}">tbu.isrunning.hint</i18n:text>",
+ notRunningHint: "<i18n:text i18n:catalogue="${i18nCatalogue}">tbu.notrunning.hint</i18n:text>"
+ }
+ )
+ </script>
+ </jx:macro>
+
+
+</jx:template>
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 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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$
+-->
+<catalogue>
+ <message key="tbu.name.hint">Console for controlling the Timed Browser Updater</message>
+ <message key="tbu.name.title">Update</message>
+ <message key="tbu.frequency.hint">how often the updater will run</message>
+ <message key="tbu.frequency.title">Frequency</message>
+ <message key="tbu.frequency.30">30 secs</message>
+ <message key="tbu.frequency.60">1 minute</message>
+ <message key="tbu.frequency.120">2 minutes</message>
+ <message key="tbu.frequency.300">5 minutes</message>
+ <message key="tbu.frequency.600">10 minutes</message>
+ <message key="tbu.isrunning.title">ON</message>
+ <message key="tbu.notrunning.title">OFF</message>
+ <message key="tbu.isrunning.hint">click to stop the updater</message>
+ <message key="tbu.notrunning.hint">click to start the updater</message>
+</catalogue>
\ 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 @@
-->
<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
+ <map:components>
+ <map:transformers default="xslt">
+ <map:transformer name="browser-update" src="org.apache.cocoon.ajax.BrowserUpdateTransformer"/>
+ <map:transformer name="i18n" src="org.apache.cocoon.transformation.I18nTransformer">
+ <catalogues default="tbu">
+ <catalogue id="tbu" name="timedbrowserupdater" location="i18n"/>
+ </catalogues>
+ <cache-at-startup>true</cache-at-startup>
+ </map:transformer>
+ </map:transformers>
+ </map:components>
+
<map:resources>
<!-- this will later become a virtual transformer -->
<map:resource name="simple-page2html">
@@ -66,7 +78,28 @@
<map:generate type="jx" src="display-suggestions.xml"/>
<map:serialize type="xml"/>
</map:match>
+
+ <!-- display the timed updater screen -->
+ <map:match pattern="timed-updater-screen">
+ <map:generate type="jx" src="timed-updater.xml"/>
+ <map:transform type="browser-update"/>
+ <map:transform type="i18n"/>
+ <map:call resource="simple-page2html">
+ <map:param name="file" value="timed-updater.xml"/>
+ </map:call>
+ <map:select type="request-parameter">
+ <map:parameter name="parameter-name" value="cocoon-ajax"/>
+ <map:when test="true"><map:serialize type="xml"/></map:when>
+ <map:otherwise><map:serialize type="html"/></map:otherwise>
+ </map:select>
+ </map:match>
+
+ <!-- Ajax Timed Browser Updater -->
+ <map:match pattern="timed-updater">
+ <map:call function="timedUpdateDemo"/>
+ </map:match>
+
<map:match pattern="display-freememory">
<map:generate type="jx" src="display-freememory.xml"/>
<map:serialize type="xml"/>
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 @@
+<!--
+ 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$
+-->
+<page
+ xmlns:jx="http://apache.org/cocoon/templates/jx/1.0"
+ xmlns:tbu="http://apache.org/cocoon/timed-browser-update/1.0">
+
+ <!-- Import the macros that define TBU template elements -->
+ <jx:import uri="resource://org/apache/cocoon/ajax/resources/macros/timedbrowserupdater.xml"/>
+
+ <title>Timed Browser Updater Demo</title>
+ <!-- include ajax scripts -->
+ <script type="text/javascript" src="resources/ajax/js/cocoon-ajax.js"/>
+ <script type="text/javascript" src="resources/ajax/js/timedbrowserupdater.js"/>
+
+ <style>
+ .tbuConsole {
+ border-color: #09F;
+ border-width: 1px;
+ border-style: solid;
+ padding: 4px;
+ }
+ .tbuConsole th {
+ text-align: right;
+ }
+ </style>
+
+ <content>
+ <p>This sample simulates specific data changes on the backend, being picked up automatically by the Browser.</p>
+
+ <p>Be <em>patient</em>, the default update frequency is a mere <strong>30 secs</strong>.</p>
+ <blockquote>
+ <tbu:replace id="demo.hour" state="${data.hour}">
+ <p id="demo.hour" title="this piece of data changes every hour">Hour: ${data.hour} (last change: ${data.time})</p>
+ </tbu:replace>
+
+ <tbu:replace id="demo.min" state="${data.min}">
+ <p id="demo.min" title="this piece of data changes every minute">Minute: ${data.min} (last change: ${data.time})</p>
+ </tbu:replace>
+
+ <tbu:replace id="demo.rand" state="${data.rand}">
+ <p id="demo.rand" title="this piece of data changes randomly">Random: ${data.rand} (last change: ${data.time})</p>
+ </tbu:replace>
+ </blockquote>
+ <p><tbu:console i18nCatalogue="tbu"/></p><!---->
+ </content>
+</page>
\ No newline at end of file
Modified: cocoon/blocks/ajax/trunk/samples/welcome.xml
URL: http://svn.apache.org/viewcvs/cocoon/blocks/ajax/trunk/samples/welcome.xml?rev=293104&r1=293103&r2=293104&view=diff
==============================================================================
--- cocoon/blocks/ajax/trunk/samples/welcome.xml (original)
+++ cocoon/blocks/ajax/trunk/samples/welcome.xml Sun Oct 2 05:41:05 2005
@@ -24,6 +24,7 @@
</group>
<group name="Basic Samples">
- <sample name="File explorer" href="file-browser">Browse through the files in Cocoon's sample directory with Ajax autocompletion.</sample>
+ <sample name="File explorer" href="file-browser">Browse through the files in Cocoon's sample directory with Ajax auto-completion.</sample>
+ <sample name="Timed Browser Updater" href="timed-updater">Update regions of the screen with live information, asynchronously.</sample>
</group>
</samples>
Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/resources/forms-field-styling.xsl
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/resources/forms-field-styling.xsl?rev=293104&r1=293103&r2=293104&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/resources/forms-field-styling.xsl (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/resources/forms-field-styling.xsl Sun Oct 2 05:41:05 2005
@@ -28,6 +28,7 @@
<xsl:template match="head" mode="forms-field">
<script src="{$resources-uri}/js/forms-lib.js" type="text/javascript"/>
+ <script src="{$resources-uri}/ajax/js/cocoon-ajax.js" type="text/javascript"/>
<script src="{$resources-uri}/js/cforms.js" type="text/javascript"/>
<link rel="stylesheet" type="text/css" href="{$resources-uri}/css/forms.css"/>
</xsl:template>
Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/resources/js/cforms.js
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/resources/js/cforms.js?rev=293104&r1=293103&r2=293104&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/resources/js/cforms.js (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/resources/js/cforms.js Sun Oct 2 05:41:05 2005
@@ -1,23 +1,17 @@
/*
-* 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.
-*/
-
-/**
- * Runtime JavaScript library for Cocoon forms.
+ * 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
*
- * @version $Id$
+ * 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.
*/
//-------------------------------------------------------------------------------------------------
@@ -33,6 +27,7 @@
* Submits a form. If ajax mode is on and the browser is ajax-aware, the page isn't reloaded
*/
CForms.submitForm = function(element, name) {
+
if (name == undefined) {
name = element.name;
}
@@ -45,56 +40,48 @@
// FIXME: programmatically submitting the form doesn't trigger onsubmit ? (both in IE and Moz)
forms_onsubmit();
- // Provide feedback that something is happening.
- document.body.style.cursor = "wait";
+ if (CForms.ajax && BrowserUpdater != null) {
- var req = CForms.newXMLHttpRequest();
- if (req) {
- // The "ajax-action" attribute specifies an alternate submit location used in Ajax mode.
- // This allows to use Ajax in the portal where forms are normally posted to the portal URL.
- var uri = form.getAttribute("ajax-action");
- if (! uri)
- uri = form.action;
- if ( uri == "" )
- uri = document.location;
-
- req.open("POST", uri, true);
- req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
- // onreadystatechange must be all lower case (?)
- req.onreadystatechange = function() {
- if (req.readyState == 4) {
- CForms._handleBrowserUpdate(form, req);
- }
- }
- req.send(CForms._buildQueryString(form, name));
- // Reset submit-id
- form["forms_submit_id"].value = '';
- forms_onsubmitHandlers = new Array();
-
+ // Provide feedback that something is happening.
+ document.body.style.cursor = "wait";
+
+ var uri = form.getAttribute("ajax-action");
+ if (! uri) uri = form.action;
+ if ( uri == "" ) uri = document.location;
+
+ var req = new BrowserUpdater(
+ uri,
+ {
+ method: 'post',
+ postBody: CForms._buildQueryString(form, name),
+ onFailure: BrowserUpdater.handleError,
+ form: form
+ }
+ );
+
+ // Reset submit-id
+ form["forms_submit_id"].value = '';
+ forms_onsubmitHandlers = new Array();
} else {
// Non ajax-aware browser : regular submit
form.submit();
}
}
+
}
// Override the default forms_submitForm
forms_submitForm = CForms.submitForm;
/**
- * Create an XHR if the browser supports it.
- */
-CForms.newXMLHttpRequest = function () {
- if (this.ajax) {
- if (window.XMLHttpRequest)
- return new XMLHttpRequest;
- else if (window.ActiveXObject)
- return new ActiveXObject("Microsoft.XMLHTTP");
- }
-}
-
-/**
* Build a query string with all form inputs
+ *
+ * NB. It is possible that this could be replaced by the use of Form.serialize in prototype.js
+ * but that Objec t also sends Submit buttons, which it is possible CForms does not want
+ *
+ * Another possiblity is that we could overcome that horror in HTML whereby
+ * unchecked checkboxes are not normally submitted :-)
+ *
*/
CForms._buildQueryString = function(form, submitId) {
// Indicate to the server that we're in ajax mode
@@ -114,323 +101,3 @@
}
return result;
}
-
-/**
- * Handle the server response
- */
-CForms._handleBrowserUpdate = function(form, request) {
- // Restore normal cursor
- document.body.style.cursor = "auto";
- if (request.status == 200) {
- var xca;
- try { // An exception is thrown if header doesn't exist (at least in Moz)
- xca = request.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["continuation-id"]) {
- contParam += "&continuation-id=" + form.elements["continuation-id"].value;
- }
- window.location.href = form.action + contParam;
- } else {
- // Handle browser update directives
- var doc = request.responseXML;
- if (!doc) {
- BrowserUpdate.handleError("No xml answer", request);
- return;
- }
-
- BrowserUpdate.processResponse(doc, request);
- }
- } else {
- BrowserUpdate.handleError("Request failed - status=" + request.status, request);
- }
-}
-
-//-------------------------------------------------------------------------------------------------
-
-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;
- }
-}
-
-
-//-------------------------------------------------------------------------------------------------
-// General purpose AJAX infrastructure to handle a BU ("browser update") response
-//
-// To implement a new instruction, add the corresponding function as a property of
-// BrowserUpdate.handlers.
-//-------------------------------------------------------------------------------------------------
-
-BrowserUpdate = {};
-
-BrowserUpdate.processResponse = function(doc, request) {
- 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 = BrowserUpdate.handlers[handler];
- if (handlerFunc) {
- handlerFunc(node);
- } else {
- BrowserUpdate.handleError("No handler found for element " + handler, request);
- }
- }
- }
-}
-BrowserUpdate.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 (BrowserUpdate.highlight) {
- BrowserUpdate.highlight(newElement);
- }
- }
-}
-
-BrowserUpdate.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();
- }
- }
-}
-
-
-//-------------------------------------------------------------------------------------------------
-// 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;
-}
-
-BrowserUpdate.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/forms/trunk/samples/sitemap.xmap
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/samples/sitemap.xmap?rev=293104&r1=293103&r2=293104&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/samples/sitemap.xmap (original)
+++ cocoon/blocks/forms/trunk/samples/sitemap.xmap Sun Oct 2 05:41:05 2005
@@ -467,7 +467,7 @@
<map:match type="regexp" pattern="resources/(ajax)/(.*)">
<map:read src="resource://org/apache/cocoon/{1}/resources/{2}"/>
</map:match>
-
+
<map:match pattern="resources/**">
<map:read src="resource://org/apache/cocoon/forms/{0}"/>
</map:match>