You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by sy...@apache.org on 2005/09/28 12:25:30 UTC
svn commit: r292158 [3/4] - in /cocoon: blocks/ajax/ blocks/ajax/trunk/
blocks/ajax/trunk/WEB-INF/ blocks/ajax/trunk/WEB-INF/xconf/
blocks/ajax/trunk/java/ blocks/ajax/trunk/java/org/
blocks/ajax/trunk/java/org/apache/ blocks/ajax/trunk/java/org/apache...
Added: cocoon/blocks/ajax/trunk/java/org/apache/cocoon/ajax/resources/js/unittest.js
URL: http://svn.apache.org/viewcvs/cocoon/blocks/ajax/trunk/java/org/apache/cocoon/ajax/resources/js/unittest.js?rev=292158&view=auto
==============================================================================
--- cocoon/blocks/ajax/trunk/java/org/apache/cocoon/ajax/resources/js/unittest.js (added)
+++ cocoon/blocks/ajax/trunk/java/org/apache/cocoon/ajax/resources/js/unittest.js Wed Sep 28 03:24:51 2005
@@ -0,0 +1,363 @@
+// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+// (c) 2005 Jon Tirsen (http://www.tirsen.com)
+// (c) 2005 Michael Schuerig (http://www.schuerig.de/michael/)
+//
+// See scriptaculous.js for full license.
+
+// experimental, Firefox-only
+Event.simulateMouse = function(element, eventName) {
+ var options = Object.extend({
+ pointerX: 0,
+ pointerY: 0,
+ buttons: 0
+ }, arguments[2] || {});
+ var oEvent = document.createEvent("MouseEvents");
+ oEvent.initMouseEvent(eventName, true, true, document.defaultView,
+ options.buttons, options.pointerX, options.pointerY, options.pointerX, options.pointerY,
+ false, false, false, false, 0, $(element));
+
+ if(this.mark) Element.remove(this.mark);
+ this.mark = document.createElement('div');
+ this.mark.appendChild(document.createTextNode(" "));
+ document.body.appendChild(this.mark);
+ this.mark.style.position = 'absolute';
+ this.mark.style.top = options.pointerY + "px";
+ this.mark.style.left = options.pointerX + "px";
+ this.mark.style.width = "5px";
+ this.mark.style.height = "5px;";
+ this.mark.style.borderTop = "1px solid red;"
+ this.mark.style.borderLeft = "1px solid red;"
+
+ if(this.step)
+ alert('['+new Date().getTime().toString()+'] '+eventName+'/'+Test.Unit.inspect(options));
+
+ $(element).dispatchEvent(oEvent);
+};
+
+// Note: Due to a fix in Firefox 1.0.5/6 that probably fixed "too much", this doesn't work in 1.0.6 or DP2.
+// You need to downgrade to 1.0.4 for now to get this working
+// See https://bugzilla.mozilla.org/show_bug.cgi?id=289940 for the fix that fixed too much
+Event.simulateKey = function(element, eventName) {
+ var options = Object.extend({
+ ctrlKey: false,
+ altKey: false,
+ shiftKey: false,
+ metaKey: false,
+ keyCode: 0,
+ charCode: 0
+ }, arguments[2] || {});
+
+ var oEvent = document.createEvent("KeyEvents");
+ oEvent.initKeyEvent(eventName, true, true, window,
+ options.ctrlKey, options.altKey, options.shiftKey, options.metaKey,
+ options.keyCode, options.charCode );
+ $(element).dispatchEvent(oEvent);
+};
+
+Event.simulateKeys = function(element, command) {
+ for(var i=0; i<command.length; i++) {
+ Event.simulateKey(element,'keypress',{charCode:command.charCodeAt(i)});
+ }
+};
+
+var Test = {}
+Test.Unit = {};
+
+// security exception workaround
+Test.Unit.inspect = function(obj) {
+ var info = [];
+
+ if(typeof obj=="string" ||
+ typeof obj=="number") {
+ return obj;
+ } else {
+ for(property in obj)
+ if(typeof obj[property]!="function")
+ info.push(property + ' => ' +
+ (typeof obj[property] == "string" ?
+ '"' + obj[property] + '"' :
+ obj[property]));
+ }
+
+ return ("'" + obj + "' #" + typeof obj +
+ ": {" + info.join(", ") + "}");
+}
+
+Test.Unit.Logger = Class.create();
+Test.Unit.Logger.prototype = {
+ initialize: function(log) {
+ this.log = $(log);
+ if (this.log) {
+ this._createLogTable();
+ }
+ },
+ start: function(testName) {
+ if (!this.log) return;
+ this.testName = testName;
+ this.lastLogLine = document.createElement('tr');
+ this.statusCell = document.createElement('td');
+ this.nameCell = document.createElement('td');
+ this.nameCell.appendChild(document.createTextNode(testName));
+ this.messageCell = document.createElement('td');
+ this.lastLogLine.appendChild(this.statusCell);
+ this.lastLogLine.appendChild(this.nameCell);
+ this.lastLogLine.appendChild(this.messageCell);
+ this.loglines.appendChild(this.lastLogLine);
+ },
+ finish: function(status, summary) {
+ if (!this.log) return;
+ this.lastLogLine.className = status;
+ this.statusCell.innerHTML = status;
+ this.messageCell.innerHTML = this._toHTML(summary);
+ },
+ message: function(message) {
+ if (!this.log) return;
+ this.messageCell.innerHTML = this._toHTML(message);
+ },
+ summary: function(summary) {
+ if (!this.log) return;
+ this.logsummary.innerHTML = this._toHTML(summary);
+ },
+ _createLogTable: function() {
+ this.log.innerHTML =
+ '<div id="logsummary"></div>' +
+ '<table id="logtable">' +
+ '<thead><tr><th>Status</th><th>Test</th><th>Message</th></tr></thead>' +
+ '<tbody id="loglines"></tbody>' +
+ '</table>';
+ this.logsummary = $('logsummary')
+ this.loglines = $('loglines');
+ },
+ _toHTML: function(txt) {
+ return txt.escapeHTML().replace(/\n/g,"<br/>");
+ }
+}
+
+Test.Unit.Runner = Class.create();
+Test.Unit.Runner.prototype = {
+ initialize: function(testcases) {
+ this.options = Object.extend({
+ testLog: 'testlog'
+ }, arguments[1] || {});
+ this.options.resultsURL = this.parseResultsURLQueryParameter();
+ if (this.options.testLog) {
+ this.options.testLog = $(this.options.testLog) || null;
+ }
+ if(this.options.tests) {
+ this.tests = [];
+ for(var i = 0; i < this.options.tests.length; i++) {
+ if(/^test/.test(this.options.tests[i])) {
+ this.tests.push(new Test.Unit.Testcase(this.options.tests[i], testcases[this.options.tests[i]], testcases["setup"], testcases["teardown"]));
+ }
+ }
+ } else {
+ if (this.options.test) {
+ this.tests = [new Test.Unit.Testcase(this.options.test, testcases[this.options.test], testcases["setup"], testcases["teardown"])];
+ } else {
+ this.tests = [];
+ for(var testcase in testcases) {
+ if(/^test/.test(testcase)) {
+ this.tests.push(new Test.Unit.Testcase(testcase, testcases[testcase], testcases["setup"], testcases["teardown"]));
+ }
+ }
+ }
+ }
+ this.currentTest = 0;
+ this.logger = new Test.Unit.Logger(this.options.testLog);
+ setTimeout(this.runTests.bind(this), 1000);
+ },
+ parseResultsURLQueryParameter: function() {
+ return window.location.search.parseQuery()["resultsURL"];
+ },
+ // Returns:
+ // "ERROR" if there was an error,
+ // "FAILURE" if there was a failure, or
+ // "SUCCESS" if there was neither
+ getResult: function() {
+ var hasFailure = false;
+ for(var i=0;i<this.tests.length;i++) {
+ if (this.tests[i].errors > 0) {
+ return "ERROR";
+ }
+ if (this.tests[i].failures > 0) {
+ hasFailure = true;
+ }
+ }
+ if (hasFailure) {
+ return "FAILURE";
+ } else {
+ return "SUCCESS";
+ }
+ },
+ postResults: function() {
+ if (this.options.resultsURL) {
+ new Ajax.Request(this.options.resultsURL,
+ { method: 'get', parameters: 'result=' + this.getResult(), asynchronous: false });
+ }
+ },
+ runTests: function() {
+ var test = this.tests[this.currentTest];
+ if (!test) {
+ // finished!
+ this.postResults();
+ this.logger.summary(this.summary());
+ return;
+ }
+ if(!test.isWaiting) {
+ this.logger.start(test.name);
+ }
+ test.run();
+ if(test.isWaiting) {
+ this.logger.message("Waiting for " + test.timeToWait + "ms");
+ setTimeout(this.runTests.bind(this), test.timeToWait || 1000);
+ } else {
+ this.logger.finish(test.status(), test.summary());
+ this.currentTest++;
+ // tail recursive, hopefully the browser will skip the stackframe
+ this.runTests();
+ }
+ },
+ summary: function() {
+ var assertions = 0;
+ var failures = 0;
+ var errors = 0;
+ var messages = [];
+ for(var i=0;i<this.tests.length;i++) {
+ assertions += this.tests[i].assertions;
+ failures += this.tests[i].failures;
+ errors += this.tests[i].errors;
+ }
+ return (
+ this.tests.length + " tests, " +
+ assertions + " assertions, " +
+ failures + " failures, " +
+ errors + " errors");
+ }
+}
+
+Test.Unit.Assertions = Class.create();
+Test.Unit.Assertions.prototype = {
+ initialize: function() {
+ this.assertions = 0;
+ this.failures = 0;
+ this.errors = 0;
+ this.messages = [];
+ },
+ summary: function() {
+ return (
+ this.assertions + " assertions, " +
+ this.failures + " failures, " +
+ this.errors + " errors" + "\n" +
+ this.messages.join("\n"));
+ },
+ pass: function() {
+ this.assertions++;
+ },
+ fail: function(message) {
+ this.failures++;
+ this.messages.push("Failure: " + message);
+ },
+ error: function(error) {
+ this.errors++;
+ this.messages.push(error.name + ": "+ error.message + "(" + Test.Unit.inspect(error) +")");
+ },
+ status: function() {
+ if (this.failures > 0) return 'failed';
+ if (this.errors > 0) return 'error';
+ return 'passed';
+ },
+ assert: function(expression) {
+ var message = arguments[1] || 'assert: got "' + Test.Unit.inspect(expression) + '"';
+ try { expression ? this.pass() :
+ this.fail(message); }
+ catch(e) { this.error(e); }
+ },
+ assertEqual: function(expected, actual) {
+ var message = arguments[2] || "assertEqual";
+ try { (expected == actual) ? this.pass() :
+ this.fail(message + ': expected "' + Test.Unit.inspect(expected) +
+ '", actual "' + Test.Unit.inspect(actual) + '"'); }
+ catch(e) { this.error(e); }
+ },
+ assertNotEqual: function(expected, actual) {
+ var message = arguments[2] || "assertNotEqual";
+ try { (expected != actual) ? this.pass() :
+ this.fail(message + ': got "' + Test.Unit.inspect(actual) + '"'); }
+ catch(e) { this.error(e); }
+ },
+ assertNull: function(obj) {
+ var message = arguments[1] || 'assertNull'
+ try { (obj==null) ? this.pass() :
+ this.fail(message + ': got "' + Test.Unit.inspect(obj) + '"'); }
+ catch(e) { this.error(e); }
+ },
+ assertHidden: function(element) {
+ var message = arguments[1] || 'assertHidden';
+ this.assertEqual("none", element.style.display, message);
+ },
+ assertNotNull: function(object) {
+ var message = arguments[1] || 'assertNotNull';
+ this.assert(object != null, message);
+ },
+ assertInstanceOf: function(expected, actual) {
+ var message = arguments[2] || 'assertInstanceOf';
+ try {
+ (actual instanceof expected) ? this.pass() :
+ this.fail(message + ": object was not an instance of the expected type"); }
+ catch(e) { this.error(e); }
+ },
+ assertNotInstanceOf: function(expected, actual) {
+ var message = arguments[2] || 'assertNotInstanceOf';
+ try {
+ !(actual instanceof expected) ? this.pass() :
+ this.fail(message + ": object was an instance of the not expected type"); }
+ catch(e) { this.error(e); }
+ },
+ _isVisible: function(element) {
+ element = $(element);
+ if(!element.parentNode) return true;
+ this.assertNotNull(element);
+ if(element.style && Element.getStyle(element, 'display') == 'none')
+ return false;
+
+ return this._isVisible(element.parentNode);
+ },
+ assertNotVisible: function(element) {
+ this.assert(!this._isVisible(element), Test.Unit.inspect(element) + " was not hidden and didn't have a hidden parent either. " + ("" || arguments[1]));
+ },
+ assertVisible: function(element) {
+ this.assert(this._isVisible(element), Test.Unit.inspect(element) + " was not visible. " + ("" || arguments[1]));
+ }
+}
+
+Test.Unit.Testcase = Class.create();
+Object.extend(Object.extend(Test.Unit.Testcase.prototype, Test.Unit.Assertions.prototype), {
+ initialize: function(name, test, setup, teardown) {
+ Test.Unit.Assertions.prototype.initialize.bind(this)();
+ this.name = name;
+ this.test = test || function() {};
+ this.setup = setup || function() {};
+ this.teardown = teardown || function() {};
+ this.isWaiting = false;
+ this.timeToWait = 1000;
+ },
+ wait: function(time, nextPart) {
+ this.isWaiting = true;
+ this.test = nextPart;
+ this.timeToWait = time;
+ },
+ run: function() {
+ try {
+ try {
+ if (!this.isWaiting) this.setup.bind(this)();
+ this.isWaiting = false;
+ this.test.bind(this)();
+ } finally {
+ if(!this.isWaiting) {
+ this.teardown.bind(this)();
+ }
+ }
+ }
+ catch(e) { this.error(e); }
+ }
+});
\ No newline at end of file
Propchange: cocoon/blocks/ajax/trunk/java/org/apache/cocoon/ajax/resources/js/unittest.js
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/blocks/ajax/trunk/java/org/apache/cocoon/ajax/resources/js/unittest.js
------------------------------------------------------------------------------
svn:keywords = Id
Added: cocoon/blocks/ajax/trunk/java/org/apache/cocoon/ajax/resources/js/util.js
URL: http://svn.apache.org/viewcvs/cocoon/blocks/ajax/trunk/java/org/apache/cocoon/ajax/resources/js/util.js?rev=292158&view=auto
==============================================================================
--- cocoon/blocks/ajax/trunk/java/org/apache/cocoon/ajax/resources/js/util.js (added)
+++ cocoon/blocks/ajax/trunk/java/org/apache/cocoon/ajax/resources/js/util.js Wed Sep 28 03:24:51 2005
@@ -0,0 +1,521 @@
+// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+//
+// See scriptaculous.js for full license.
+
+Object.inspect = function(obj) {
+ var info = [];
+
+ if(typeof obj in ["string","number"]) {
+ return obj;
+ } else {
+ for(property in obj)
+ if(typeof obj[property]!="function")
+ info.push(property + ' => ' +
+ (typeof obj[property] == "string" ?
+ '"' + obj[property] + '"' :
+ obj[property]));
+ }
+
+ return ("'" + obj + "' #" + typeof obj +
+ ": {" + info.join(", ") + "}");
+}
+
+// borrowed from http://www.schuerig.de/michael/javascript/stdext.js
+// Copyright (c) 2005, Michael Schuerig, michael@schuerig.de
+
+Array.flatten = function(array, excludeUndefined) {
+ if (excludeUndefined === undefined) {
+ excludeUndefined = false;
+ }
+ var result = [];
+ var len = array.length;
+ for (var i = 0; i < len; i++) {
+ var el = array[i];
+ if (el instanceof Array) {
+ var flat = el.flatten(excludeUndefined);
+ result = result.concat(flat);
+ } else if (!excludeUndefined || el != undefined) {
+ result.push(el);
+ }
+ }
+ return result;
+};
+
+if (!Array.prototype.flatten) {
+ Array.prototype.flatten = function(excludeUndefined) {
+ return Array.flatten(this, excludeUndefined);
+ }
+}
+
+String.prototype.toArray = function() {
+ var results = [];
+ for (var i = 0; i < this.length; i++)
+ results.push(this.charAt(i));
+ return results;
+}
+
+/*--------------------------------------------------------------------------*/
+
+var Builder = {
+ node: function(elementName) {
+ var element = document.createElement('div');
+ element.innerHTML =
+ "<" + elementName + "></" + elementName + ">";
+
+ // attributes (or text)
+ if(arguments[1])
+ if(this._isStringOrNumber(arguments[1]) ||
+ (arguments[1] instanceof Array)) {
+ this._children(element.firstChild, arguments[1]);
+ } else {
+ var attrs = this._attributes(arguments[1]);
+ if(attrs.length)
+ element.innerHTML = "<" +elementName + " " +
+ attrs + "></" + elementName + ">";
+ }
+
+ // text, or array of children
+ if(arguments[2])
+ this._children(element.firstChild, arguments[2]);
+
+ return element.firstChild;
+ },
+ _text: function(text) {
+ return document.createTextNode(text);
+ },
+ _attributes: function(attributes) {
+ var attrs = [];
+ for(attribute in attributes)
+ attrs.push((attribute=='className' ? 'class' : attribute) +
+ '="' + attributes[attribute].toString().escapeHTML() + '"');
+ return attrs.join(" ");
+ },
+ _children: function(element, children) {
+ if(typeof children=='object') { // array can hold nodes and text
+ children.flatten().each( function(e) {
+ if(typeof e=='object')
+ element.appendChild(e)
+ else
+ if(Builder._isStringOrNumber(e))
+ element.appendChild(Builder._text(e));
+ });
+ } else
+ if(Builder._isStringOrNumber(children))
+ element.appendChild(Builder._text(children));
+ },
+ _isStringOrNumber: function(param) {
+ return(typeof param=='string' || typeof param=='number');
+ }
+}
+
+/* ------------- element ext -------------- */
+
+// adapted from http://dhtmlkitchen.com/learn/js/setstyle/index4.jsp
+// note: Safari return null on elements with display:none; see http://bugzilla.opendarwin.org/show_bug.cgi?id=4125
+// instead of "auto" values returns null so it's easier to use with || constructs
+
+String.prototype.camelize = function() {
+ var oStringList = this.split('-');
+ if(oStringList.length == 1)
+ return oStringList[0];
+ var ret = this.indexOf("-") == 0 ?
+ oStringList[0].charAt(0).toUpperCase() + oStringList[0].substring(1) : oStringList[0];
+ for(var i = 1, len = oStringList.length; i < len; i++){
+ var s = oStringList[i];
+ ret += s.charAt(0).toUpperCase() + s.substring(1)
+ }
+ return ret;
+}
+
+Element.getStyle = function(element, style) {
+ element = $(element);
+ var value = element.style[style.camelize()];
+ if(!value)
+ if(document.defaultView && document.defaultView.getComputedStyle) {
+ var css = document.defaultView.getComputedStyle(element, null);
+ value = (css!=null) ? css.getPropertyValue(style) : null;
+ } else if(element.currentStyle) {
+ value = element.currentStyle[style.camelize()];
+ }
+
+ // If top, left, bottom, or right values have been queried, return "auto" for consistency resaons
+ // if position is "static", as Opera (and others?) returns the pixel values relative to root element
+ // (or positioning context?)
+ if (window.opera && (style == "left" || style == "top" || style == "right" || style == "bottom"))
+ if (Element.getStyle(element, "position") == "static") value = "auto";
+
+ if(value=='auto') value = null;
+ return value;
+}
+
+// converts rgb() and #xxx to #xxxxxx format,
+// returns self (or first argument) if not convertable
+String.prototype.parseColor = function() {
+ color = "#";
+ if(this.slice(0,4) == "rgb(") {
+ var cols = this.slice(4,this.length-1).split(',');
+ var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3);
+ } else {
+ if(this.slice(0,1) == '#') {
+ if(this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase();
+ if(this.length==7) color = this.toLowerCase();
+ }
+ }
+ return(color.length==7 ? color : (arguments[0] || this));
+}
+
+Element.makePositioned = function(element) {
+ element = $(element);
+ var pos = Element.getStyle(element, 'position');
+ if(pos =='static' || !pos) {
+ element._madePositioned = true;
+ element.style.position = "relative";
+ // Opera returns the offset relative to the positioning context, when an element is position relative
+ // but top and left have not been defined
+ if (window.opera){
+ element.style.top = 0;
+ element.style.left = 0;
+ }
+ }
+}
+
+Element.undoPositioned = function(element) {
+ element = $(element);
+ if(typeof element._madePositioned != "undefined"){
+ element._madePositioned = undefined;
+ element.style.position = "";
+ element.style.top = "";
+ element.style.left = "";
+ element.style.bottom = "";
+ element.style.right = "";
+ }
+}
+
+Element.makeClipping = function(element) {
+ element = $(element);
+ if (typeof element._overflow != 'undefined') return;
+ element._overflow = element.style.overflow;
+ if((Element.getStyle(element, 'overflow') || 'visible') != 'hidden') element.style.overflow = 'hidden';
+}
+
+Element.undoClipping = function(element) {
+ element = $(element);
+ if (typeof element._overflow == 'undefined') return;
+ element.style.overflow = element._overflow;
+ element._overflow = undefined;
+}
+
+Element.collectTextNodesIgnoreClass = function(element, ignoreclass) {
+ var children = $(element).childNodes;
+ var text = "";
+ var classtest = new RegExp("^([^ ]+ )*" + ignoreclass+ "( [^ ]+)*$","i");
+
+ for (var i = 0; i < children.length; i++) {
+ if(children[i].nodeType==3) {
+ text+=children[i].nodeValue;
+ } else {
+ if((!children[i].className.match(classtest)) && children[i].hasChildNodes())
+ text += Element.collectTextNodesIgnoreClass(children[i], ignoreclass);
+ }
+ }
+
+ return text;
+}
+
+Element.setContentZoom = function(element, percent) {
+ element = $(element);
+ element.style.fontSize = (percent/100) + "em";
+ if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
+}
+
+Element.getOpacity = function(element){
+ return parseFloat(Element.getStyle(element, "opacity") || '1');
+}
+
+Element.setOpacity = function(element, value){
+ element= $(element);
+ var els = element.style;
+ if (value == 1){
+ els.opacity = '0.999999';
+ els.filter = null;
+ } else {
+ if(value < 0.00001) value = 0;
+ els.opacity = value;
+ els.filter = "alpha(opacity:"+value*100+")";
+ }
+}
+
+Element.getInlineOpacity = function(element){
+ element= $(element);
+ var op;
+ op = element.style.opacity;
+ if (typeof op != "undefined" && op != "") return op;
+ return "";
+}
+
+Element.setInlineOpacity = function(element, value){
+ element= $(element);
+ var els = element.style;
+ els.opacity = value;
+}
+
+Element.getDimensions = function(element){
+ element = $(element);
+ // All *Width and *Height properties give 0 on elements with display "none", so enable the element temporarily
+ if (element.style.display == "none"){
+ var originalVisibility = element.style.visibility;
+ var originalPosition = element.style.position;
+ element.style.visibility = "hidden";
+ element.style.position = "absolute";
+ element.style.display = "";
+ var originalWidth = element.clientWidth;
+ var originalHeight = element.clientHeight;
+ element.style.display = "none";
+ element.style.position = originalPosition;
+ element.style.visibility = originalVisibility;
+ return {width: originalWidth, height: originalHeight};
+ } else {
+ return {width: element.offsetWidth, height: element.offsetHeight};
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+Position.positionedOffset = function(element) {
+ var valueT = 0, valueL = 0;
+ do {
+ valueT += element.offsetTop || 0;
+ valueL += element.offsetLeft || 0;
+ element = element.offsetParent;
+ if (element) {
+ p = Element.getStyle(element,'position');
+ if(p == 'relative' || p == 'absolute') break;
+ }
+ } while (element);
+ return [valueL, valueT];
+}
+
+// Safari returns margins on body which is incorrect if the child is absolutely positioned.
+// for performance reasons, we create a specialized version of Position.cumulativeOffset for
+// KHTML/WebKit only
+
+if(/Konqueror|Safari|KHTML/.test(navigator.userAgent)) {
+ Position.cumulativeOffset = function(element) {
+ var valueT = 0, valueL = 0;
+ do {
+ valueT += element.offsetTop || 0;
+ valueL += element.offsetLeft || 0;
+
+ if (element.offsetParent==document.body)
+ if (Element.getStyle(element,'position')=='absolute') break;
+
+ element = element.offsetParent;
+ } while (element);
+ return [valueL, valueT];
+ }
+}
+
+Position.page = function(forElement) {
+ var valueT = 0, valueL = 0;
+
+ var element = forElement;
+ do {
+ valueT += element.offsetTop || 0;
+ valueL += element.offsetLeft || 0;
+
+ // Safari fix
+ if (element.offsetParent==document.body)
+ if (Element.getStyle(element,'position')=='absolute') break;
+
+ } while (element = element.offsetParent);
+
+ element = forElement;
+ do {
+ valueT -= element.scrollTop || 0;
+ valueL -= element.scrollLeft || 0;
+ } while (element = element.parentNode);
+
+ return [valueL, valueT];
+}
+
+// elements with display:none don't return an offsetParent,
+// fall back to manual calculation
+Position.offsetParent = function(element) {
+ if(element.offsetParent) return element.offsetParent;
+ if(element == document.body) return element;
+
+ while ((element = element.parentNode) && element != document.body)
+ if (Element.getStyle(element,'position')!='static')
+ return element;
+
+ return document.body;
+}
+
+Position.clone = function(source, target) {
+ var options = Object.extend({
+ setLeft: true,
+ setTop: true,
+ setWidth: true,
+ setHeight: true,
+ offsetTop: 0,
+ offsetLeft: 0
+ }, arguments[2] || {})
+
+ // find page position of source
+ source = $(source);
+ var p = Position.page(source);
+
+ // find coordinate system to use
+ target = $(target);
+ var delta = [0, 0];
+ var parent = null;
+ // delta [0,0] will do fine with position: fixed elements,
+ // position:absolute needs offsetParent deltas
+ if (Element.getStyle(target,'position') == 'absolute') {
+ parent = Position.offsetParent(target);
+ delta = Position.page(parent);
+ }
+
+ // correct by body offsets (fixes Safari)
+ if (parent==document.body) {
+ delta[0] -= document.body.offsetLeft;
+ delta[1] -= document.body.offsetTop;
+ }
+
+ // set position
+ if(options.setLeft) target.style.left = (p[0] - delta[0] + options.offsetLeft) + "px";
+ if(options.setTop) target.style.top = (p[1] - delta[1] + options.offsetTop) + "px";
+ if(options.setWidth) target.style.width = source.offsetWidth + "px";
+ if(options.setHeight) target.style.height = source.offsetHeight + "px";
+}
+
+Position.absolutize = function(element) {
+ element = $(element);
+ if(element.style.position=='absolute') return;
+ Position.prepare();
+
+ var offsets = Position.positionedOffset(element);
+ var top = offsets[1];
+ var left = offsets[0];
+ var width = element.clientWidth;
+ var height = element.clientHeight;
+
+ element._originalLeft = left - parseFloat(element.style.left || 0);
+ element._originalTop = top - parseFloat(element.style.top || 0);
+ element._originalWidth = element.style.width;
+ element._originalHeight = element.style.height;
+
+ element.style.position = 'absolute';
+ element.style.top = top + 'px';;
+ element.style.left = left + 'px';;
+ element.style.width = width + 'px';;
+ element.style.height = height + 'px';;
+}
+
+Position.relativize = function(element) {
+ element = $(element);
+ if(element.style.position=='relative') return;
+ Position.prepare();
+
+ element.style.position = 'relative';
+ var top = parseFloat(element.style.top || 0) - (element._originalTop || 0);
+ var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);
+
+ element.style.top = top + 'px';
+ element.style.left = left + 'px';
+ element.style.height = element._originalHeight;
+ element.style.width = element._originalWidth;
+}
+
+/*--------------------------------------------------------------------------*/
+
+Element.Class = {
+ // Element.toggleClass(element, className) toggles the class being on/off
+ // Element.toggleClass(element, className1, className2) toggles between both classes,
+ // defaulting to className1 if neither exist
+ toggle: function(element, className) {
+ if(Element.Class.has(element, className)) {
+ Element.Class.remove(element, className);
+ if(arguments.length == 3) Element.Class.add(element, arguments[2]);
+ } else {
+ Element.Class.add(element, className);
+ if(arguments.length == 3) Element.Class.remove(element, arguments[2]);
+ }
+ },
+
+ // gets space-delimited classnames of an element as an array
+ get: function(element) {
+ element = $(element);
+ return element.className.split(' ');
+ },
+
+ // functions adapted from original functions by Gavin Kistner
+ remove: function(element) {
+ element = $(element);
+ var regEx;
+ for(var i = 1; i < arguments.length; i++) {
+ regEx = new RegExp("(^|\\s)" + arguments[i] + "(\\s|$)", 'g');
+ element.className = element.className.replace(regEx, '')
+ }
+ },
+
+ add: function(element) {
+ element = $(element);
+ for(var i = 1; i < arguments.length; i++) {
+ Element.Class.remove(element, arguments[i]);
+ element.className += (element.className.length > 0 ? ' ' : '') + arguments[i];
+ }
+ },
+
+ // returns true if all given classes exist in said element
+ has: function(element) {
+ element = $(element);
+ if(!element || !element.className) return false;
+ var regEx;
+ for(var i = 1; i < arguments.length; i++) {
+ if((typeof arguments[i] == 'object') &&
+ (arguments[i].constructor == Array)) {
+ for(var j = 0; j < arguments[i].length; j++) {
+ regEx = new RegExp("(^|\\s)" + arguments[i][j] + "(\\s|$)");
+ if(!regEx.test(element.className)) return false;
+ }
+ } else {
+ regEx = new RegExp("(^|\\s)" + arguments[i] + "(\\s|$)");
+ if(!regEx.test(element.className)) return false;
+ }
+ }
+ return true;
+ },
+
+ // expects arrays of strings and/or strings as optional paramters
+ // Element.Class.has_any(element, ['classA','classB','classC'], 'classD')
+ has_any: function(element) {
+ element = $(element);
+ if(!element || !element.className) return false;
+ var regEx;
+ for(var i = 1; i < arguments.length; i++) {
+ if((typeof arguments[i] == 'object') &&
+ (arguments[i].constructor == Array)) {
+ for(var j = 0; j < arguments[i].length; j++) {
+ regEx = new RegExp("(^|\\s)" + arguments[i][j] + "(\\s|$)");
+ if(regEx.test(element.className)) return true;
+ }
+ } else {
+ regEx = new RegExp("(^|\\s)" + arguments[i] + "(\\s|$)");
+ if(regEx.test(element.className)) return true;
+ }
+ }
+ return false;
+ },
+
+ childrenWith: function(element, className) {
+ var children = $(element).getElementsByTagName('*');
+ var elements = new Array();
+
+ for (var i = 0; i < children.length; i++)
+ if (Element.Class.has(children[i], className))
+ elements.push(children[i]);
+
+ return elements;
+ }
+}
\ No newline at end of file
Propchange: cocoon/blocks/ajax/trunk/java/org/apache/cocoon/ajax/resources/js/util.js
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/blocks/ajax/trunk/java/org/apache/cocoon/ajax/resources/js/util.js
------------------------------------------------------------------------------
svn:keywords = Id
Added: cocoon/blocks/ajax/trunk/java/org/apache/cocoon/transformation/BrowserUpdateTransformer.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/ajax/trunk/java/org/apache/cocoon/transformation/BrowserUpdateTransformer.java?rev=292158&view=auto
==============================================================================
--- cocoon/blocks/ajax/trunk/java/org/apache/cocoon/transformation/BrowserUpdateTransformer.java (added)
+++ cocoon/blocks/ajax/trunk/java/org/apache/cocoon/transformation/BrowserUpdateTransformer.java Wed Sep 28 03:24:51 2005
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+package org.apache.cocoon.transformation;
+
+import java.io.IOException;
+import java.util.Map;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.util.Deprecation;
+import org.xml.sax.SAXException;
+
+/**
+ * @deprectated use {@link org.apache.cocoon.ajax.BrowserUpdateTransformer}
+ * @version $Id$
+ */
+public class BrowserUpdateTransformer extends org.apache.cocoon.ajax.BrowserUpdateTransformer {
+
+ public static final String AJAXMODE_PARAM = "cocoon-ajax";
+
+ public static final String BU_NSURI = "http://apache.org/cocoon/browser-update/1.0";
+
+ public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par) throws ProcessingException, SAXException, IOException {
+ Deprecation.logger.warn("Please use the BrowserUpdateTransformer in the Ajax block");
+ super.setup(resolver, objectModel, src, par);
+ }
+}
Propchange: cocoon/blocks/ajax/trunk/java/org/apache/cocoon/transformation/BrowserUpdateTransformer.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/blocks/ajax/trunk/java/org/apache/cocoon/transformation/BrowserUpdateTransformer.java
------------------------------------------------------------------------------
svn:keywords = Id
Added: cocoon/blocks/ajax/trunk/pom.xml
URL: http://svn.apache.org/viewcvs/cocoon/blocks/ajax/trunk/pom.xml?rev=292158&view=auto
==============================================================================
--- cocoon/blocks/ajax/trunk/pom.xml (added)
+++ cocoon/blocks/ajax/trunk/pom.xml Wed Sep 28 03:24:51 2005
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 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$
+ |
+ +-->
+<project>
+ <parent>
+ <groupId>apache-cocoon</groupId>
+ <artifactId>cocoon</artifactId>
+ <version>2.2-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>apache-cocoon</groupId>
+ <artifactId>cocoon-ajax</artifactId>
+ <version>2.2-SNAPSHOT</version>
+ <packaging>jar</packaging>
+ <build>
+ <sourceDirectory>java</sourceDirectory>
+ <testSourceDirectory>test</testSourceDirectory>
+ <resources>
+ <resource>
+ <directory>java</directory>
+ <excludes>
+ <exclude>**/*.java</exclude>
+ </excludes>
+ </resource>
+ </resources>
+ </build>
+ <dependencies>
+ <dependency>
+ <groupId>apache-cocoon</groupId>
+ <artifactId>cocoon-core</artifactId>
+ <version>2.2-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>apache-cocoon</groupId>
+ <artifactId>cocoon-test-core</artifactId>
+ <version>2.2-SNAPSHOT</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <reporting>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-project-info-reports-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </reporting>
+</project>
Propchange: cocoon/blocks/ajax/trunk/pom.xml
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/blocks/ajax/trunk/pom.xml
------------------------------------------------------------------------------
svn:keywords = Id
Added: cocoon/blocks/ajax/trunk/samples/ajax.xsamples
URL: http://svn.apache.org/viewcvs/cocoon/blocks/ajax/trunk/samples/ajax.xsamples?rev=292158&view=auto
==============================================================================
--- cocoon/blocks/ajax/trunk/samples/ajax.xsamples (added)
+++ cocoon/blocks/ajax/trunk/samples/ajax.xsamples Wed Sep 28 03:24:51 2005
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<!--
+ Copyright 1999-2004 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.
+-->
+
+<xsamples xpath="/samples" unless="group[@name='Ajax Block']">
+
+ <group name="Ajax">
+ <sample name="Ajax Block" href="ajax/">
+ Ajax block examples. This block is also used by <a href="forms/">Cocoon Forms</a>.
+ </sample>
+ </group>
+
+</xsamples>
Added: cocoon/blocks/ajax/trunk/samples/display-suggestions.xml
URL: http://svn.apache.org/viewcvs/cocoon/blocks/ajax/trunk/samples/display-suggestions.xml?rev=292158&view=auto
==============================================================================
--- cocoon/blocks/ajax/trunk/samples/display-suggestions.xml (added)
+++ cocoon/blocks/ajax/trunk/samples/display-suggestions.xml Wed Sep 28 03:24:51 2005
@@ -0,0 +1,12 @@
+<ul class="suggestions" xmlns:jx="http://apache.org/cocoon/templates/jx/1.0">
+ <jx:forEach var="suggestion" items="${suggestions}">
+ <jx:choose>
+ <jx:when test="${suggestion == selection}">
+ <li class="selected">${suggestion}</li>
+ </jx:when>
+ <jx:otherwise>
+ <li>${suggestion}</li>
+ </jx:otherwise>
+ </jx:choose>
+ </jx:forEach>
+</ul>
\ No newline at end of file
Propchange: cocoon/blocks/ajax/trunk/samples/display-suggestions.xml
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/blocks/ajax/trunk/samples/display-suggestions.xml
------------------------------------------------------------------------------
svn:keywords = Id
Added: cocoon/blocks/ajax/trunk/samples/file-browser-suggest.xml
URL: http://svn.apache.org/viewcvs/cocoon/blocks/ajax/trunk/samples/file-browser-suggest.xml?rev=292158&view=auto
==============================================================================
--- cocoon/blocks/ajax/trunk/samples/file-browser-suggest.xml (added)
+++ cocoon/blocks/ajax/trunk/samples/file-browser-suggest.xml Wed Sep 28 03:24:51 2005
@@ -0,0 +1,7 @@
+<ul class="contacts" xmlns:jx="http://apache.org/cocoon/templates/jx/1.0">
+ <jx:set var="root" value="#{java.io.File.new('/Users/sylvain/')}"/>
+ <jx:set var="file" value="
+ <jx:forEach var="child" items="${file.list()}">
+ <li>${child}</li>
+ </jx:forEach>
+</ul>
\ No newline at end of file
Propchange: cocoon/blocks/ajax/trunk/samples/file-browser-suggest.xml
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/blocks/ajax/trunk/samples/file-browser-suggest.xml
------------------------------------------------------------------------------
svn:keywords = Id
Added: cocoon/blocks/ajax/trunk/samples/file-browser.xml
URL: http://svn.apache.org/viewcvs/cocoon/blocks/ajax/trunk/samples/file-browser.xml?rev=292158&view=auto
==============================================================================
--- cocoon/blocks/ajax/trunk/samples/file-browser.xml (added)
+++ cocoon/blocks/ajax/trunk/samples/file-browser.xml Wed Sep 28 03:24:51 2005
@@ -0,0 +1,43 @@
+<page>
+ <title>Cocoon suggests</title>
+ <!-- include ajax scripts -->
+ <script type="text/javascript" src="resources/ajax/js/cocoon-ajax.js"/>
+ <style type="text/css">
+ /* autocompletion popup */
+ div.auto_complete {
+ height:200px;
+ overflow:scroll;
+ background-color:white;
+ border:1px solid #888;
+ margin:0px;
+ padding:0px;
+ }
+ /* autocompletion items */
+ ul.suggestions {
+ list-style-type: none;
+ margin:0px;
+ padding:0px;
+ }
+ /* selected autocompletion item */
+ ul.suggestions li.selected { background-color: #ffb; }
+
+ </style>
+
+<content>
+ <p>This sample shows autocompletion in action. The input below expects a filename in Cocoon's "samples" directory.
+ Start by either typing some letter or a '/' and see what happens...</p>
+
+ <form action="">
+ Please chose a file in the samples directory:<br/>
+ <input autocomplete="off" id="filename" name="filename" size="50"/>
+ <div class="auto_complete" id="update"/>
+ <script type="text/javascript">
+ // Parameters are [id of the input], [id of the suggestion div], [url to be called to get suggestions]
+ new Ajax.Autocompleter('filename', 'update', 'file-browser-suggest');
+ </script>
+ </form>
+
+ <p><em>Note: there's no submit button on this form as we don't really care about actually using
+ that information...</em></p>
+</content>
+</page>
\ No newline at end of file
Propchange: cocoon/blocks/ajax/trunk/samples/file-browser.xml
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/blocks/ajax/trunk/samples/file-browser.xml
------------------------------------------------------------------------------
svn:keywords = Id
Added: cocoon/blocks/ajax/trunk/samples/flow.js
URL: http://svn.apache.org/viewcvs/cocoon/blocks/ajax/trunk/samples/flow.js?rev=292158&view=auto
==============================================================================
--- cocoon/blocks/ajax/trunk/samples/flow.js (added)
+++ cocoon/blocks/ajax/trunk/samples/flow.js Wed Sep 28 03:24:51 2005
@@ -0,0 +1,52 @@
+/*
+ Copyright 1999-2004 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$
+ */
+var resolver = cocoon.getComponent(org.apache.excalibur.source.SourceResolver.ROLE);
+
+function fileBrowserSuggest() {
+ var prefix = "context://samples/";
+ var filename = cocoon.request.getParameter("filename");
+
+ var src = resolver.resolveURI(prefix + filename);
+ var suggestions = new java.util.ArrayList();
+ if (src.exists() && src.isCollection()) {
+ var children = src.children;
+ if (!filename.endsWith('/')) filename += "/";
+ suggestions.add(filename);
+ for (var i = 0; i < children.size(); i++) {
+ suggestions.add(filename + children.get(i).getName());
+ }
+ } else {
+ var parent = src.parent;
+ var children = parent.children;
+ if (filename.indexOf('/') != -1) {
+ filename = filename.substring(0, filename.lastIndexOf('/') + 1);
+ } else {
+ filename = "";
+ }
+ for (var i = 0; i < children.size(); i++) {
+ var child = children.get(i);
+ if (child.name.startsWith(src.name))
+ suggestions.add(filename + children.get(i).getName());
+ }
+ }
+
+ cocoon.sendPage("display-suggestions", { suggestions: suggestions, selection: cocoon.request.getParameter("filename")});
+
+}
\ No newline at end of file
Propchange: cocoon/blocks/ajax/trunk/samples/flow.js
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/blocks/ajax/trunk/samples/flow.js
------------------------------------------------------------------------------
svn:keywords = Id
Added: cocoon/blocks/ajax/trunk/samples/sitemap.xmap
URL: http://svn.apache.org/viewcvs/cocoon/blocks/ajax/trunk/samples/sitemap.xmap?rev=292158&view=auto
==============================================================================
--- cocoon/blocks/ajax/trunk/samples/sitemap.xmap (added)
+++ cocoon/blocks/ajax/trunk/samples/sitemap.xmap Wed Sep 28 03:24:51 2005
@@ -0,0 +1,76 @@
+<?xml version="1.0"?>
+<!--
+ Copyright 1999-2004 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$
+ -->
+<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
+
+ <map:resources>
+ <!-- this will later become a virtual transformer -->
+ <map:resource name="simple-page2html">
+ <map:transform src="context://samples/common/style/xsl/html/simple-page2html.xsl">
+ <map:parameter name="contextPath" value="{request:contextPath}"/>
+ <map:parameter name="servletPath" value="{request:servletPath}"/>
+ <map:parameter name="sitemapURI" value="{request:sitemapURI}"/>
+ <map:parameter name="file" value="{file}"/>
+ <map:parameter name="remove" value="{../0}"/>
+ </map:transform>
+ </map:resource>
+ </map:resources>
+
+<map:flow>
+ <map:script src="flow.js"/>
+</map:flow>
+
+<map:pipelines>
+ <map:pipeline>
+ <map:match pattern="">
+ <map:generate src="welcome.xml"/>
+ <map:transform src="context://samples/common/style/xsl/html/simple-samples2html.xsl">
+ <map:parameter name="contextPath" value="{request:contextPath}"/>
+ </map:transform>
+ <map:serialize/>
+ </map:match>
+
+ <!-- Main page of the file browser -->
+ <map:match pattern="file-browser">
+ <map:generate type="jx" src="file-browser.xml"/>
+ <map:call resource="simple-page2html">
+ <map:param name="file" value="file-browser.xml"/>
+ </map:call>
+ <map:serialize type="html"/>
+ </map:match>
+
+ <!-- Ajax callback to get suggestions -->
+ <map:match pattern="file-browser-suggest">
+ <map:call function="fileBrowserSuggest"/>
+ </map:match>
+
+ <!-- Called by the fileBrowserSuggest function -->
+ <map:match pattern="display-suggestions">
+ <map:generate type="jx" src="display-suggestions.xml"/>
+ <map:serialize type="xml"/>
+ </map:match>
+
+ <!-- Generic pipeline to load resources in jars -->
+ <map:match pattern="resources/*/**">
+ <map:read src="resource://org/apache/cocoon/{1}/resources/{2}"/>
+ </map:match>
+ </map:pipeline>
+</map:pipelines>
+</map:sitemap>
\ No newline at end of file
Propchange: cocoon/blocks/ajax/trunk/samples/sitemap.xmap
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/blocks/ajax/trunk/samples/sitemap.xmap
------------------------------------------------------------------------------
svn:keywords = Id
Added: cocoon/blocks/ajax/trunk/samples/welcome.xml
URL: http://svn.apache.org/viewcvs/cocoon/blocks/ajax/trunk/samples/welcome.xml?rev=292158&view=auto
==============================================================================
--- cocoon/blocks/ajax/trunk/samples/welcome.xml (added)
+++ cocoon/blocks/ajax/trunk/samples/welcome.xml Wed Sep 28 03:24:51 2005
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+<!--
+ Copyright 1999-2004 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$
+-->
+<samples name="Ajax Block Samples" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <group name="Back">
+ <sample name="Back" href="../..">to Cocoon Samples main page</sample>
+ <sample name="Back" href="..">to Cocoon Blocks Samples main page</sample>
+ </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>
+ </group>
+</samples>
Propchange: cocoon/blocks/ajax/trunk/samples/welcome.xml
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/blocks/ajax/trunk/samples/welcome.xml
------------------------------------------------------------------------------
svn:keywords = Id
Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/flow/javascript/Form.js
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/flow/javascript/Form.js?rev=292158&r1=292157&r2=292158&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/flow/javascript/Form.js (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/flow/javascript/Form.js Wed Sep 28 03:24:51 2005
@@ -118,6 +118,9 @@
var comingBack = false;
var bookmark = cocoon.createWebContinuation(ttl);
+
+ // Attach the form to the continuation so that we can access by just knowing the continuation id
+ bookmark.setAttribute("form", this.form);
if (comingBack) {
// We come back to the bookmark: process the form
@@ -162,7 +165,7 @@
if (httpResponse) {
httpResponse.setContentType("text/xml");
var text = "<?xml version='1.0'?><bu:document xmlns:bu='" +
- org.apache.cocoon.transformation.BrowserUpdateTransformer.BU_NSURI +
+ org.apache.cocoon.ajax.BrowserUpdateTransformer.BU_NSURI +
"'></bu:document>";
httpResponse.writer.print(text);
} else {
Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/AbstractDatatypeWidgetDefinitionBuilder.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/AbstractDatatypeWidgetDefinitionBuilder.java?rev=292158&r1=292157&r2=292158&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/AbstractDatatypeWidgetDefinitionBuilder.java (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/AbstractDatatypeWidgetDefinitionBuilder.java Wed Sep 28 03:24:51 2005
@@ -76,31 +76,40 @@
// when definition are managed like components.
definition.service(this.serviceManager);
- Element selectionListElement = DomHelper.getChildElement(widgetElement, Constants.DEFINITION_NS, "selection-list");
+ SelectionList list = buildSelectionList(widgetElement, definition, "selection-list");
+ if (list != null) {
+ definition.setSelectionList(list);
+ }
+ }
+
+ protected SelectionList buildSelectionList(
+ Element widgetElement, AbstractDatatypeWidgetDefinition definition, String name) throws Exception {
+ Element selectionListElement = DomHelper.getChildElement(widgetElement, Constants.DEFINITION_NS, name);
if(selectionListElement != null && definition.getDatatype() == null)
- throw new Exception("A widget with a selection list always requires a datatype as well! (at "+DomHelper.getLocation(selectionListElement)+" )");
+ throw new Exception("A widget with a selection list always requires a datatype as well! (at "+DomHelper.getLocation(selectionListElement)+" )");
- if (selectionListElement != null) {
- // Get an appropriate list builder
- ServiceSelector builderSelector = (ServiceSelector)this.serviceManager.lookup(SelectionListBuilder.ROLE + "Selector");
- SelectionListBuilder builder = null;
- try {
- // listType can be null, meaning we will use the default selection list
- String listType = selectionListElement.getAttribute("type");
- if ("".equals(listType)) {
- listType = null;
- }
+ if (selectionListElement == null)
+ return null;
- builder = (SelectionListBuilder)builderSelector.select(listType);
- SelectionList list = builder.build(selectionListElement, definition.getDatatype());
- definition.setSelectionList(list);
- } finally {
- if (builder != null) {
- builderSelector.release(builder);
- }
- this.serviceManager.release(builderSelector);
+ // Get an appropriate list builder
+ ServiceSelector builderSelector = (ServiceSelector)this.serviceManager.lookup(SelectionListBuilder.ROLE + "Selector");
+ SelectionListBuilder builder = null;
+ try {
+ // listType can be null, meaning we will use the default selection list
+ String listType = selectionListElement.getAttribute("type");
+ if ("".equals(listType)) {
+ listType = null;
}
+
+ builder = (SelectionListBuilder)builderSelector.select(listType);
+ return builder.build(selectionListElement, definition.getDatatype());
+
+ } finally {
+ if (builder != null) {
+ builderSelector.release(builder);
+ }
+ this.serviceManager.release(builderSelector);
}
}
}
Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/AbstractWidget.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/AbstractWidget.java?rev=292158&r1=292157&r2=292158&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/AbstractWidget.java (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/AbstractWidget.java Wed Sep 28 03:24:51 2005
@@ -484,6 +484,10 @@
generateDisplayData(contentHandler);
+ if (locale == null) {
+ locale = getForm().getLocale();
+ }
+
generateItemSaxFragment(contentHandler, locale);
contentHandler.endElement(Constants.INSTANCE_NS, element, Constants.INSTANCE_PREFIX_COLON + element);
Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/Field.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/Field.java?rev=292158&r1=292157&r2=292158&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/Field.java (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/Field.java Wed Sep 28 03:24:51 2005
@@ -502,6 +502,10 @@
public void setSelectionList(Object model, String valuePath, String labelPath) {
setSelectionList(getFieldDefinition().buildSelectionListFromModel(model, valuePath, labelPath));
}
+
+ public SelectionList getSuggestionList() {
+ return getFieldDefinition().getSuggestionList();
+ }
public Datatype getDatatype() {
return getFieldDefinition().getDatatype();
Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/FieldDefinition.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/FieldDefinition.java?rev=292158&r1=292157&r2=292158&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/FieldDefinition.java (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/FieldDefinition.java Wed Sep 28 03:24:51 2005
@@ -15,6 +15,8 @@
*/
package org.apache.cocoon.forms.formmodel;
+import org.apache.cocoon.forms.datatype.SelectionList;
+
/**
* The {@link WidgetDefinition} part of a Field widget, see {@link Field} for more information.
*
@@ -22,6 +24,7 @@
*/
public class FieldDefinition extends AbstractDatatypeWidgetDefinition {
private boolean required;
+ private SelectionList suggestionList;
public Widget createInstance() {
Field field = new Field(this);
@@ -32,16 +35,18 @@
* initialize this definition with the other, sort of like a copy constructor
*/
public void initializeFrom(WidgetDefinition definition) throws Exception {
- super.initializeFrom(definition);
-
- if(definition instanceof FieldDefinition) {
- FieldDefinition other = (FieldDefinition)definition;
-
- this.required = other.required;
-
- } else {
- throw new Exception("Definition to inherit from is not of the right type! (at "+getLocation()+")");
- }
+ if(!(definition instanceof FieldDefinition)) {
+ throw new Exception("Definition to inherit from is not of the right type! (at "+getLocation()+")");
+ }
+ super.initializeFrom(definition);
+
+ FieldDefinition other = (FieldDefinition)definition;
+
+ this.required = other.required;
+
+ if (suggestionList == null) {
+ suggestionList = other.getSuggestionList();
+ }
}
public boolean isRequired() {
@@ -51,5 +56,13 @@
public void setRequired(boolean required) {
checkMutable();
this.required = required;
+ }
+
+ public SelectionList getSuggestionList() {
+ return this.suggestionList;
+ }
+
+ public void setSuggestionList(SelectionList list) {
+ this.suggestionList = list;
}
}
Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/FieldDefinitionBuilder.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/FieldDefinitionBuilder.java?rev=292158&r1=292157&r2=292158&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/FieldDefinitionBuilder.java (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/formmodel/FieldDefinitionBuilder.java Wed Sep 28 03:24:51 2005
@@ -15,6 +15,8 @@
*/
package org.apache.cocoon.forms.formmodel;
+import org.apache.cocoon.forms.Constants;
+import org.apache.cocoon.forms.datatype.SelectionList;
import org.apache.cocoon.forms.util.DomHelper;
import org.w3c.dom.Element;
@@ -38,5 +40,10 @@
// parse "@required"
if(widgetElement.hasAttribute("required"))
definition.setRequired(DomHelper.getAttributeAsBoolean(widgetElement, "required", false));
+
+ SelectionList list = buildSelectionList(widgetElement, definition, "suggestion-list");
+ if (list != null) {
+ definition.setSuggestionList(list);
+ }
}
}
Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/generation/JXMacrosHelper.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/generation/JXMacrosHelper.java?rev=292158&r1=292157&r2=292158&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/generation/JXMacrosHelper.java (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/generation/JXMacrosHelper.java Wed Sep 28 03:24:51 2005
@@ -16,13 +16,14 @@
package org.apache.cocoon.forms.generation;
+import java.util.Collections;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
+import org.apache.cocoon.ajax.BrowserUpdateTransformer;
import org.apache.cocoon.environment.Request;
import org.apache.cocoon.forms.Constants;
import org.apache.cocoon.forms.FormsRuntimeException;
@@ -32,7 +33,6 @@
import org.apache.cocoon.forms.formmodel.tree.Tree;
import org.apache.cocoon.forms.formmodel.tree.TreeWalker;
import org.apache.cocoon.forms.validation.ValidationError;
-import org.apache.cocoon.transformation.BrowserUpdateTransformer;
import org.apache.cocoon.xml.AbstractXMLPipe;
import org.apache.cocoon.xml.AttributesImpl;
import org.apache.cocoon.xml.XMLConsumer;
@@ -40,6 +40,7 @@
import org.apache.commons.collections.ArrayStack;
import org.apache.commons.lang.BooleanUtils;
import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
/**
@@ -58,7 +59,6 @@
private boolean ajaxTemplate;
private Set updatedWidgets;
private Set childUpdatedWidgets;
- private Set parentUpdatedWidgets;
/**
* Builds and helper object, given the generator's consumer.
@@ -75,7 +75,6 @@
this.request = request;
this.ajaxRequest = request.getParameter("cocoon-ajax") != null;
}
-
public Form getForm(Form form, String attributeName) {
Form returnForm = form;
@@ -93,7 +92,6 @@
this.updatedWidgets = form.getUpdatedWidgetIds();
this.childUpdatedWidgets = form.getChildUpdatedWidgetIds();
- this.parentUpdatedWidgets = new HashSet();
// build attributes
AttributesImpl attrs = new AttributesImpl();
@@ -272,11 +270,11 @@
* @param locale
* @throws SAXException
*/
- public void generateWidget(Widget widget, Locale locale) throws SAXException {
+ public void generateWidget(Widget widget, Map arguments) throws SAXException {
// Needs to be buffered
- RootBufferingPipe pipe = new RootBufferingPipe(this.cocoonConsumer);
+ RootBufferingPipe pipe = new RootBufferingPipe(this.cocoonConsumer, arguments);
this.pipeStack.push(pipe);
- widget.generateSaxFragment(pipe, locale);
+ widget.generateSaxFragment(pipe, null);
}
/**
@@ -365,13 +363,50 @@
this.cocoonConsumer.endElement(Constants.INSTANCE_NS, "placeholder", Constants.INSTANCE_PREFIX_COLON + "placeholder");
this.cocoonConsumer.endElement(BrowserUpdateTransformer.BU_NSURI, "replace", "bu:replace");
}
-
+
return visible;
}
public boolean isModified(Widget widget) {
return this.updatedWidgets.contains(widget.getRequestParameterName());
}
+
+ public boolean generateStyling(Map attributes) throws SAXException {
+ return generateStyling(this.cocoonConsumer, attributes);
+ }
+
+ /**
+ * Generate a <code><fi:styling></code> element holding the attributes of a <code>ft:*</code>
+ * element that are in the "fi:" namespace.
+ *
+ * @param attributes the template instruction attributes
+ * @return true if a <code><fi:styling></code> was produced
+ * @throws SAXException
+ */
+ public static boolean generateStyling(ContentHandler handler, Map attributes) throws SAXException {
+ AttributesImpl attr = null;
+ Iterator entries = attributes.entrySet().iterator();
+ while(entries.hasNext()) {
+ Map.Entry entry = (Map.Entry)entries.next();
+ String key = (String)entry.getKey();
+
+ // FIXME: JXTG only gives the local name of attributes, so we can't distinguish namespaces...
+ if (!"id".equals(key) && !"widget-id".equals(key)) {
+ if (attr == null)
+ attr = new AttributesImpl();
+ attr.addCDATAAttribute(key, (String)entry.getValue());
+ }
+ }
+
+ if (attr != null) {
+ // There were some styling attributes
+ handler.startElement(Constants.INSTANCE_NS, "styling", Constants.INSTANCE_PREFIX_COLON + "styling", attr);
+ handler.endElement(Constants.INSTANCE_NS, "styling", Constants.INSTANCE_PREFIX_COLON + "styling");
+ return true;
+ } else {
+ return false;
+ }
+ }
/**
* A SAX pipe that buffers the <code>endElement()</code> event of the root element.
@@ -385,22 +420,37 @@
private String rootUri;
private String rootLoc;
private String rootRaw;
+ private Map arguments;
+ private boolean forbidStyling = false;
public RootBufferingPipe(XMLConsumer next) {
+ this(next, Collections.EMPTY_MAP);
+ }
+
+ public RootBufferingPipe(XMLConsumer next, Map arguments) {
this.setConsumer(next);
+ this.arguments = arguments;
}
public void startElement(String uri, String loc, String raw, Attributes a)
throws SAXException {
+ super.startElement(uri, loc, raw, a);
if (depth == 0) {
// Root element: keep its description
this.rootUri = uri;
this.rootLoc = loc;
this.rootRaw = raw;
+
+ // And produce fi:styling from attributes
+ this.forbidStyling = generateStyling(this.contentHandler, arguments);
+ }
+
+ if (depth == 1 && forbidStyling &&
+ uri.equals(Constants.INSTANCE_NS) && loc.equals("styling")) {
+ throw new SAXException("Cannot use 'fi:*' attributes and <fi:styling> at the same time");
}
depth++;
- super.startElement(uri, loc, raw, a);
}
public void endElement(String uri, String loc, String raw)
Added: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/generation/SelectionListFilter.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/generation/SelectionListFilter.java?rev=292158&view=auto
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/generation/SelectionListFilter.java (added)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/generation/SelectionListFilter.java Wed Sep 28 03:24:51 2005
@@ -0,0 +1,69 @@
+/*
+ * Copyright 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.
+ */
+package org.apache.cocoon.forms.generation;
+
+import org.apache.cocoon.forms.Constants;
+import org.apache.cocoon.xml.AbstractXMLPipe;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * A filter for selection lists, that keeps only those items that start with a given filter value.
+ *
+ * @since 2.1.8
+ * @version $Id$
+ */
+public class SelectionListFilter extends AbstractXMLPipe {
+
+ private ContentHandler next;
+ private int filterDepth = 0;
+ private int depth = 0;
+ private String filterValue;
+ private static final ContentHandler NULL_HANDLER = new DefaultHandler();
+
+ public SelectionListFilter(String filterValue, ContentHandler next) {
+ this.next = next;
+ this.setContentHandler(next);
+ this.filterValue = filterValue;
+ }
+
+ public void startElement(String uri, String loc, String raw, Attributes a) throws SAXException {
+ depth++;
+
+ if (uri.equals(Constants.INSTANCE_NS) && loc.equals("item")) {
+ String value = a.getValue("value");
+ if (!value.startsWith(this.filterValue)) {
+ filterDepth = depth;
+ setContentHandler(NULL_HANDLER);
+ }
+ }
+
+ super.startElement(uri, loc, raw, a);
+ }
+
+ public void endElement(String uri, String loc, String raw) throws SAXException {
+ super.endElement(uri, loc, raw);
+
+ if (depth == filterDepth) {
+ filterDepth = 0;
+ setContentHandler(this.next);
+ }
+
+ depth--;
+ }
+}
Propchange: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/generation/SelectionListFilter.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/generation/SelectionListFilter.java
------------------------------------------------------------------------------
svn:keywords = Id
Added: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/generation/SuggestionListGenerator.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/generation/SuggestionListGenerator.java?rev=292158&view=auto
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/generation/SuggestionListGenerator.java (added)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/generation/SuggestionListGenerator.java Wed Sep 28 03:24:51 2005
@@ -0,0 +1,106 @@
+/*
+ * Copyright 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.
+ */
+package org.apache.cocoon.forms.generation;
+
+import java.io.IOException;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.components.flow.ContinuationsManager;
+import org.apache.cocoon.components.flow.InvalidContinuationException;
+import org.apache.cocoon.components.flow.WebContinuation;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.forms.Constants;
+import org.apache.cocoon.forms.datatype.SelectionList;
+import org.apache.cocoon.forms.formmodel.Field;
+import org.apache.cocoon.forms.formmodel.Form;
+import org.apache.cocoon.generation.ServiceableGenerator;
+import org.apache.cocoon.sitemap.SitemapParameters;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+
+/**
+ * A generator for suggestion lists.
+ *
+ * @since 2.1.8
+ * @version $Id$
+ */
+public class SuggestionListGenerator extends ServiceableGenerator {
+
+ private ContinuationsManager contManager;
+ private WebContinuation wk;
+ private SelectionList list;
+ private String filter;
+ private Locale locale;
+
+ public void service(ServiceManager manager) throws ServiceException {
+ super.service(manager);
+ this.contManager = (ContinuationsManager)manager.lookup(ContinuationsManager.ROLE);
+ }
+
+ public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par) throws ProcessingException, SAXException, IOException {
+ super.setup(resolver, objectModel, src, par);
+
+ Request req = ObjectModelHelper.getRequest(objectModel);
+
+ String continuationId = par.getParameter("continuation-id", req.getParameter("continuation-id"));
+ String widgetPath = par.getParameter("widget-id", req.getParameter("widget-id")).replace('.', '/');
+ String widgetId = widgetPath.replace('/', '.');
+ this.filter = par.getParameter("filter", req.getParameter(widgetId));
+
+ // The interpreter id is the sitemap's URI
+ String interpreterId = SitemapParameters.getLocation(parameters).getURI();
+ wk = this.contManager.lookupWebContinuation(continuationId, interpreterId);
+ if (wk == null || wk.disposed()) {
+ throw new InvalidContinuationException("Cannot get continuation for suggestion list");
+ }
+
+ Form form = (Form)wk.getAttribute("form");
+ if (form == null) {
+ throw new ProcessingException("No form is attached to the continuation");
+ }
+
+ this.locale = form.getLocale();
+
+ Field field = (Field)form.lookupWidget(widgetPath);
+ list = field.getSuggestionList();
+ if (list == null) {
+ throw new ProcessingException(field + " has no suggestion list");
+ }
+ }
+
+ public void generate() throws IOException, SAXException, ProcessingException {
+ super.contentHandler.startDocument();
+ super.contentHandler.startPrefixMapping(Constants.INSTANCE_PREFIX, Constants.INSTANCE_NS);
+ ContentHandler handler;
+ if (filter == null || filter.length() == 0) {
+ handler = super.contentHandler;
+ } else {
+ handler = new SelectionListFilter(filter, super.contentHandler);
+ }
+ list.generateSaxFragment(handler, this.locale);
+
+ super.contentHandler.endPrefixMapping(Constants.INSTANCE_PREFIX);
+ super.contentHandler.endDocument();
+ }
+
+}
Propchange: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/generation/SuggestionListGenerator.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/generation/SuggestionListGenerator.java
------------------------------------------------------------------------------
svn:keywords = Id
Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/generation/jx-macros.xml
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/generation/jx-macros.xml?rev=292158&r1=292157&r2=292158&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/generation/jx-macros.xml (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/generation/jx-macros.xml Wed Sep 28 03:24:51 2005
@@ -44,7 +44,7 @@
<jx:if test="${cformsHelper.pushWidget(id)}">
<jx:set var="widget" value="${cformsHelper.peekWidget()}"/>
- <jx:set var="cformsDummy" value="${cformsHelper.generateWidget(widget, locale)}"/>
+ <jx:set var="cformsDummy" value="${cformsHelper.generateWidget(widget, macro.arguments)}"/>
<jx:evalBody/>
<jx:set var="cformsDummy" value="${cformsHelper.flushRootAndPop()}"/>
</jx:if>
Modified: cocoon/blocks/forms/trunk/samples/flow/forms_flow_example.js
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/samples/flow/forms_flow_example.js?rev=292158&r1=292157&r2=292158&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/samples/flow/forms_flow_example.js (original)
+++ cocoon/blocks/forms/trunk/samples/flow/forms_flow_example.js Wed Sep 28 03:24:51 2005
@@ -164,11 +164,9 @@
{title: "Tree binding is not yet done", document: null}
);
}
-function do_xdoceditor() {
- var form = new Form("forms/xdoceditor.xml");
- form.showForm("xdoceditor-display-pipeline.jx");
- print(form.lookupWidget("doc").getValue());
+function do_suggest() {
+ var form = new Form("forms/ajax_suggest_form.xml");
+ form.showForm("ajax_suggest-display-pipeline.jx");
+
}
-
-
Added: cocoon/blocks/forms/trunk/samples/forms/ajax_suggest_form.xml
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/samples/forms/ajax_suggest_form.xml?rev=292158&view=auto
==============================================================================
--- cocoon/blocks/forms/trunk/samples/forms/ajax_suggest_form.xml (added)
+++ cocoon/blocks/forms/trunk/samples/forms/ajax_suggest_form.xml Wed Sep 28 03:24:51 2005
@@ -0,0 +1,35 @@
+<?xml version="1.0"?>
+<!--
+ Copyright 1999-2004 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.
+-->
+<!-- form used to illustrate suggestion lists. -->
+<fd:form
+ xmlns:fd="http://apache.org/cocoon/forms/1.0#definition"
+ xmlns:i18n="http://apache.org/cocoon/i18n/2.1">
+
+ <fd:widgets>
+ <fd:field id="path">
+ <fd:datatype base="string"/>
+ <fd:suggestion-list>
+ <fd:item value="aaa"/>
+ <fd:item value="abb"/>
+ <fd:item value="abc"/>
+ <fd:item value="acc">
+ <fd:label>The last one</fd:label>
+ </fd:item>
+ </fd:suggestion-list>
+ </fd:field>
+ </fd:widgets>
+</fd:form>
Propchange: cocoon/blocks/forms/trunk/samples/forms/ajax_suggest_form.xml
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/blocks/forms/trunk/samples/forms/ajax_suggest_form.xml
------------------------------------------------------------------------------
svn:keywords = Id
Added: cocoon/blocks/forms/trunk/samples/forms/ajax_suggest_template.xml
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/samples/forms/ajax_suggest_template.xml?rev=292158&view=auto
==============================================================================
--- cocoon/blocks/forms/trunk/samples/forms/ajax_suggest_template.xml (added)
+++ cocoon/blocks/forms/trunk/samples/forms/ajax_suggest_template.xml Wed Sep 28 03:24:51 2005
@@ -0,0 +1,57 @@
+<?xml version="1.0"?>
+<!--
+ Copyright 1999-2004 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.
+-->
+<page xmlns:ft="http://apache.org/cocoon/forms/1.0#template" xmlns:fi="http://apache.org/cocoon/forms/1.0#instance" xmlns:jx="http://apache.org/cocoon/templates/jx/1.0">
+ <!-- Import the macros that define CForms template elements -->
+ <jx:import uri="resource://org/apache/cocoon/forms/generation/jx-macros.xml"/>
+ <script type="text/javascript" src="resources/ajax/js/cocoon-ajax.js"/>
+ <style type="text/css">
+ div.auto_complete {
+ background-color:white;
+ border:1px solid #888;
+ margin:0px;
+ padding:0px;
+ }
+ div.auto_complete ul {
+ list-style-type: none;
+ margin:0px;
+ padding:0px;
+ }
+ div.auto_complete li.selected { background-color: #ffb; }
+ </style>
+ <h4 class="samplesGroup">AJAX sample</h4>
+ <title>Cocoon suggests</title>
+ <content>
+
+ <para><em>Work in progress!</em> This simple example illustrates the <fd:suggestion-list> feature.
+ </para>
+
+
+ <ft:form-template action="continue" method="POST" ajax="true">
+ <ft:continuation-id/>
+ Type the letter 'a' in the field below<br/>
+ <ft:widget id="path"/>
+ <div id="autocomplete" class="auto_complete"/>
+ <script type="text/javascript">
+ new Ajax.Autocompleter("path-input", "autocomplete", "system_forms_suggest_path",
+ { parameters: "continuation-id=${cocoon.continuation.id}" });
+ </script>
+ </ft:form-template>
+ <p>
+ <a href="./">Back to Forms samples</a>
+ </p>
+ </content>
+</page>
Propchange: cocoon/blocks/forms/trunk/samples/forms/ajax_suggest_template.xml
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/blocks/forms/trunk/samples/forms/ajax_suggest_template.xml
------------------------------------------------------------------------------
svn:keywords = Id
Modified: cocoon/blocks/forms/trunk/samples/forms/form1_template.xml
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/samples/forms/form1_template.xml?rev=292158&r1=292157&r2=292158&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/samples/forms/form1_template.xml (original)
+++ cocoon/blocks/forms/trunk/samples/forms/form1_template.xml Wed Sep 28 03:24:51 2005
@@ -44,9 +44,9 @@
<fi:items>
<ft:widget id="email"/>
<ft:widget id="birthdate"/>
- <ft:widget id="fourchars">
- <!-- particular styling for the enumeration -->
- <fi:styling list-type="listbox" listbox-size="4"/>
+ <ft:widget id="fourchars" fi:list-type="listbox" fi:listbox-size="4">
+ <!-- particular styling for the enumeration
+ <fi:styling list-type="llistbox" listbox-size="4"/-->
</ft:widget>
</fi:items>
</fi:group>
Modified: cocoon/blocks/forms/trunk/samples/forms/sampletree_template.xml
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/samples/forms/sampletree_template.xml?rev=292158&r1=292157&r2=292158&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/samples/forms/sampletree_template.xml (original)
+++ cocoon/blocks/forms/trunk/samples/forms/sampletree_template.xml Wed Sep 28 03:24:51 2005
@@ -101,15 +101,14 @@
</ft:tree>
<br/>
<ft:tree id="tree2">
- <div>
- Tree sample:
- ${java.lang.System.err.println("In tree2")}
+ <div>
+ Tree sample:
<ft:tree-nodes>
<div style="margin-left: 15px"><toggle-icon/>${treeNode.node.data}
<ft:tree-children/>
</div>
</ft:tree-nodes>
- </div>
+ </div>
</ft:tree>
Example of a tree-table
Modified: cocoon/blocks/forms/trunk/samples/sitemap.xmap
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/samples/sitemap.xmap?rev=292158&r1=292157&r2=292158&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/samples/sitemap.xmap (original)
+++ cocoon/blocks/forms/trunk/samples/sitemap.xmap Wed Sep 28 03:24:51 2005
@@ -18,9 +18,12 @@
<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
<map:components>
+ <map:generators default="file">
+ <map:generator name="suggestion-list" src="org.apache.cocoon.forms.generation.SuggestionListGenerator"/>
+ </map:generators>
<map:transformers default="xslt">
- <map:transformer name="browser-update" src="org.apache.cocoon.transformation.BrowserUpdateTransformer"/>
+ <map:transformer name="browser-update" src="org.apache.cocoon.ajax.BrowserUpdateTransformer"/>
<map:transformer name="i18n" src="org.apache.cocoon.transformation.I18nTransformer">
<catalogues default="other">
<catalogue id="other" name="OtherMessages" location="messages"/>
@@ -177,6 +180,17 @@
</map:match>
<!--
+ | Show a suggestion list
+ -->
+ <map:match pattern="system_forms_suggest_*">
+ <map:generate type="suggestion-list">
+ <map:parameter name="widget-id" value="{1}"/>
+ </map:generate>
+ <map:transform type="i18n"/>
+ <map:transform src="suggest-list.xsl"/>
+ <map:serialize type="xml"/>
+ </map:match>
+ <!--
| Show a form, using the forms transformer
-->
<map:match pattern="*-display-pipeline">
@@ -448,6 +462,10 @@
<map:match pattern="htmlarea-success-pipeline">
<map:generate type="jx" src="forms/htmlarea_success.jx"/>
<map:serialize type="xml"/>
+ </map:match>
+
+ <map:match type="regexp" pattern="resources/(ajax)/(.*)">
+ <map:read src="resource://org/apache/cocoon/{1}/resources/{2}"/>
</map:match>
<map:match pattern="resources/**">
Added: cocoon/blocks/forms/trunk/samples/suggest-list.xsl
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/samples/suggest-list.xsl?rev=292158&view=auto
==============================================================================
--- cocoon/blocks/forms/trunk/samples/suggest-list.xsl (added)
+++ cocoon/blocks/forms/trunk/samples/suggest-list.xsl Wed Sep 28 03:24:51 2005
@@ -0,0 +1,19 @@
+<xsl:stylesheet
+ version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:fi="http://apache.org/cocoon/forms/1.0#instance">
+ <xsl:template match="/">
+ <ul>
+ <xsl:apply-templates/>
+ </ul>
+ </xsl:template>
+
+ <xsl:template match="fi:item">
+ <li>
+ <xsl:value-of select="@value"/>
+ <xsl:if test="fi:label and (fi:label != @value)">
+ <span class="informal"> (<xsl:copy-of select="fi:label/node()"/>)</span>
+ </xsl:if>
+ </li>
+ </xsl:template>
+</xsl:stylesheet>
Propchange: cocoon/blocks/forms/trunk/samples/suggest-list.xsl
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/blocks/forms/trunk/samples/suggest-list.xsl
------------------------------------------------------------------------------
svn:keywords = Id
Modified: cocoon/blocks/forms/trunk/samples/welcome.xml
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/samples/welcome.xml?rev=292158&r1=292157&r2=292158&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/samples/welcome.xml (original)
+++ cocoon/blocks/forms/trunk/samples/welcome.xml Wed Sep 28 03:24:51 2005
@@ -127,6 +127,12 @@
</sample>
</group>
+ <group name="Advanced Ajax samples (work in progress)">
+ <sample name="Cocoon suggests" href="do-suggest.flow">
+ (Ajax) Very simple demo of the <suggestion-list> feature.
+ </sample>
+ </group>
+
<group name="Dynamic repeater template and event handling">
<sample name="Dynamic repeater template" href="dreamteam">
Create your Euro 2004 soccer dream team