You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by jk...@apache.org on 2006/09/29 05:43:06 UTC

svn commit: r451106 [23/40] - in /tapestry/tapestry4/trunk: ./ tapestry-framework/src/java/org/apache/tapestry/asset/ tapestry-framework/src/js/dojo/ tapestry-framework/src/js/dojo/src/ tapestry-framework/src/js/dojo/src/animation/ tapestry-framework/s...

Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/validate/common.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/validate/common.js?view=auto&rev=451106
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/validate/common.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/validate/common.js Thu Sep 28 20:42:39 2006
@@ -0,0 +1,253 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.validate.common");
+
+dojo.require("dojo.regexp");
+
+// *** Validation Functions ****
+
+/**
+  Checks if a string has non whitespace characters. 
+  Parameters allow you to constrain the length.
+
+  @param value  A string.
+  @param flags  An object.
+    flags.length  If set, checks if there are exactly flags.length number of characters.
+    flags.minlength  If set, checks if there are at least flags.minlength number of characters.
+    flags.maxlength  If set, checks if there are at most flags.maxlength number of characters.
+  @return  true or false.
+*/
+dojo.validate.isText = function(value, flags) {
+	flags = (typeof flags == "object") ? flags : {};
+
+	// test for text
+	if ( /^\s*$/.test(value) ) { return false; }
+
+	// length tests
+	if ( typeof flags.length == "number" && flags.length != value.length ) { return false; }
+	if ( typeof flags.minlength == "number" && flags.minlength > value.length ) { return false; }
+	if ( typeof flags.maxlength == "number" && flags.maxlength < value.length ) { return false; }
+
+	return true;
+}
+
+/**
+  Validates whether a string is in an integer format. 
+
+  @param value  A string.
+  @param flags  An object.
+    flags.signed  The leading plus-or-minus sign.  Can be true, false, or [true, false].
+      Default is [true, false], (i.e. sign is optional).
+    flags.separator  The character used as the thousands separator.  Default is no separator.
+      For more than one symbol use an array, e.g. [",", ""], makes ',' optional.
+  @return  true or false.
+*/
+dojo.validate.isInteger = function(value, flags) {
+	var re = new RegExp("^" + dojo.regexp.integer(flags) + "$");
+	return re.test(value);
+}
+
+/**
+  Validates whether a string is a real valued number. 
+  Format is the usual exponential notation.
+
+  @param value  A string.
+  @param flags  An object.
+    flags.places  The integer number of decimal places.
+      If not given, the decimal part is optional and the number of places is unlimited.
+    flags.decimal  The character used for the decimal point.  Default is ".".
+    flags.exponent  Express in exponential notation.  Can be true, false, or [true, false].
+      Default is [true, false], (i.e. the exponential part is optional).
+    flags.eSigned  The leading plus-or-minus sign on the exponent.  Can be true, false, 
+      or [true, false].  Default is [true, false], (i.e. sign is optional).
+    flags in regexp.integer can be applied.
+  @return  true or false.
+*/
+dojo.validate.isRealNumber = function(value, flags) {
+	var re = new RegExp("^" + dojo.regexp.realNumber(flags) + "$");
+	return re.test(value);
+}
+
+/**
+  Validates whether a string denotes a monetary value. 
+
+  @param value  A string.
+  @param flags  An object.
+    flags.signed  The leading plus-or-minus sign.  Can be true, false, or [true, false].
+      Default is [true, false], (i.e. sign is optional).
+    flags.symbol  A currency symbol such as Yen "�", Pound "�", or the Euro sign "�".  
+      Default is "$".  For more than one symbol use an array, e.g. ["$", ""], makes $ optional.
+    flags.placement  The symbol can come "before" the number or "after".  Default is "before".
+    flags.separator  The character used as the thousands separator. The default is ",".
+    flags.fractional  The appropriate number of decimal places for fractional currency (e.g. cents)
+      Can be true, false, or [true, false].  Default is [true, false], (i.e. cents are optional).
+    flags.decimal  The character used for the decimal point.  Default is ".".
+  @return  true or false.
+*/
+dojo.validate.isCurrency = function(value, flags) {
+	var re = new RegExp("^" + dojo.regexp.currency(flags) + "$");
+	return re.test(value);
+}
+
+/**
+  Validates whether a string denoting an integer, 
+  real number, or monetary value is between a max and min. 
+
+  @param value  A string.
+  @param flags  An object.
+    flags.max  A number, which the value must be less than or equal to for the validation to be true.
+    flags.min  A number, which the value must be greater than or equal to for the validation to be true.
+    flags.decimal  The character used for the decimal point.  Default is ".".
+  @return  true or false.
+*/
+dojo.validate.isInRange = function(value, flags) {
+	//stripping the seperator allows NaN to perform as expected, if no separator, we assume ','
+	//once i18n support is ready for this, instead of assuming, we default to i18n's recommended value
+	value = value.replace((dojo.lang.has(flags,'separator'))?flags.separator:',','');
+	if(isNaN(value)){
+		return false;
+	}
+	// assign default values to missing paramters
+	flags = (typeof flags == "object") ? flags : {};
+	var max = (typeof flags.max == "number") ? flags.max : Infinity;
+	var min = (typeof flags.min == "number") ? flags.min : -Infinity;
+	var dec = (typeof flags.decimal == "string") ? flags.decimal : ".";
+	
+	// splice out anything not part of a number
+	var pattern = "[^" + dec + "\\deE+-]";
+	value = value.replace(RegExp(pattern, "g"), "");
+
+	// trim ends of things like e, E, or the decimal character
+	value = value.replace(/^([+-]?)(\D*)/, "$1");
+	value = value.replace(/(\D*)$/, "");
+
+	// replace decimal with ".". The minus sign '-' could be the decimal!
+	pattern = "(\\d)[" + dec + "](\\d)";
+	value = value.replace(RegExp(pattern, "g"), "$1.$2");
+
+	value = Number(value);
+	if ( value < min || value > max ) { return false; }
+
+	return true;
+}
+
+
+/**
+  Validates any sort of number based format.
+  Use it for phone numbers, social security numbers, zip-codes, etc.
+  The value can be validated against one format or one of multiple formats.
+
+  Format
+    #        Stands for a digit, 0-9.
+    ?        Stands for an optional digit, 0-9 or nothing.
+    All other characters must appear literally in the expression.
+
+  Example   
+    "(###) ###-####"       ->   (510) 542-9742
+    "(###) ###-#### x#???" ->   (510) 542-9742 x153
+    "###-##-####"          ->   506-82-1089       i.e. social security number
+    "#####-####"           ->   98225-1649        i.e. zip code
+
+  @param value  A string.
+  @param flags  An object.
+    flags.format  A string or an Array of strings for multiple formats.
+  @return  true or false
+*/
+dojo.validate.isNumberFormat = function(value, flags) {
+	var re = new RegExp("^" + dojo.regexp.numberFormat(flags) + "$", "i");
+	return re.test(value);
+}
+
+//Compares value against the Luhn algorithm to verify its integrity
+dojo.validate.isValidLuhn = function(value) {
+	var sum, parity, curDigit;
+	if(typeof value!='string'){
+		value = String(value);
+	}
+	value = value.replace(/[- ]/g,''); //ignore dashes and whitespaces
+	parity = value.length%2;
+	sum=0;
+	for(var i=0;i<value.length;i++){
+		curDigit = parseInt(value.charAt(i));
+		if(i%2==parity){
+			curDigit*=2;
+		}
+		if(curDigit>9){
+			curDigit-=9;
+		}
+		sum+=curDigit;
+	}
+	return !(sum%10);
+}
+/**
+	Procedural API Description
+
+		The main aim is to make input validation expressible in a simple format.
+		You define profiles which declare the required and optional fields and any constraints they might have.
+		The results are provided as an object that makes it easy to handle missing and invalid input.
+
+	Usage
+
+		var results = dojo.validate.check(form, profile);
+
+	Profile Object
+
+		var profile = {
+			// filters change the field value and are applied before validation.
+			trim: ["tx1", "tx2"],
+			uppercase: ["tx9"],
+			lowercase: ["tx5", "tx6", "tx7"],
+			ucfirst: ["tx10"],
+			digit: ["tx11"],
+
+			// required input fields that are blank will be reported missing.
+			// required radio button groups and drop-down lists with no selection will be reported missing.
+			// checkbox groups and selectboxes can be required to have more than one value selected.
+			// List required fields by name and use this notation to require more than one value: {checkboxgroup: 2}, {selectboxname: 3}.
+			required: ["tx7", "tx8", "pw1", "ta1", "rb1", "rb2", "cb3", "s1", {"doubledip":2}, {"tripledip":3}],
+
+			// dependant/conditional fields are required if the target field is present and not blank.
+			// At present only textbox, password, and textarea fields are supported.
+			dependencies:	{
+				cc_exp: "cc_no",	
+				cc_type: "cc_no",	
+			},
+
+			// Fields can be validated using any boolean valued function.  
+			// Use arrays to specify parameters in addition to the field value.
+			constraints: {
+				field_name1: myValidationFunction,
+				field_name2: dojo.validate.isInteger,
+				field_name3: [myValidationFunction, additional parameters],
+				field_name4: [dojo.validate.isValidDate, "YYYY.MM.DD"],
+				field_name5: [dojo.validate.isEmailAddress, false, true],
+			},
+
+			// Confirm is a sort of conditional validation.
+			// It associates each field in its property list with another field whose value should be equal.
+			// If the values are not equal, the field in the property list is reported as Invalid. Unless the target field is blank.
+			confirm: {
+				email_confirm: "email",	
+				pw2: "pw1",	
+			}
+		};
+
+	Results Object
+
+		isSuccessful(): Returns true if there were no invalid or missing fields, else it returns false.
+		hasMissing():  Returns true if the results contain any missing fields.
+		getMissing():  Returns a list of required fields that have values missing.
+		isMissing(field):  Returns true if the field is required and the value is missing.
+		hasInvalid():  Returns true if the results contain fields with invalid data.
+		getInvalid():  Returns a list of fields that have invalid values.
+		isInvalid(field):  Returns true if the field has an invalid value.
+
+*/

Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/validate/common.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/validate/creditCard.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/validate/creditCard.js?view=auto&rev=451106
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/validate/creditCard.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/validate/creditCard.js Thu Sep 28 20:42:39 2006
@@ -0,0 +1,89 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide('dojo.validate.creditCard');
+
+dojo.require("dojo.lang.common");
+
+/*
+	Validates Credit Cards using account number rules in conjunction with the Luhn algorightm
+	
+ */
+
+dojo.validate.isValidCreditCard = function(value,ccType){
+	//checks if type matches the # scheme, and if Luhn checksum is accurate (unless its an Enroute card, the checkSum is skipped)
+	if(value&&ccType&&((ccType.toLowerCase()=='er'||dojo.validate.isValidLuhn(value))&&(dojo.validate.isValidCreditCardNumber(value,ccType.toLowerCase())))){
+			return true;
+	}
+	return false;
+}
+dojo.validate.isValidCreditCardNumber = function(value,ccType) {
+	//only checks if the # matches the pattern for that card or any card types if none is specified
+	//value == CC #, white spaces and dashes are ignored
+	//ccType is of the values in cardinfo -- if Omitted it it returns a | delimited string of matching card types, or false if no matches found
+	if(typeof value!='string'){
+		value = String(value);
+	}
+	value = value.replace(/[- ]/g,''); //ignore dashes and whitespaces
+	/* 	FIXME: not sure on all the abbreviations for credit cards,below is what each stands for atleast to my knowledge
+		mc: Mastercard
+		ec: Eurocard
+		vi: Visa
+		ax: American Express
+		dc: Diners Club
+		bl: Carte Blanch
+		di: Discover
+		jcb: JCB
+		er: Enroute
+	 */
+	var results=[];
+	var cardinfo = {
+		'mc':'5[1-5][0-9]{14}','ec':'5[1-5][0-9]{14}','vi':'4([0-9]{12}|[0-9]{15})',
+		'ax':'3[47][0-9]{13}', 'dc':'3(0[0-5][0-9]{11}|[68][0-9]{12})',
+		'bl':'3(0[0-5][0-9]{11}|[68][0-9]{12})','di':'6011[0-9]{12}',
+		'jcb':'(3[0-9]{15}|(2131|1800)[0-9]{11})','er':'2(014|149)[0-9]{11}'
+	};
+	if(ccType&&dojo.lang.has(cardinfo,ccType.toLowerCase())){
+		return Boolean(value.match(cardinfo[ccType.toLowerCase()])); // boolean
+	}else{
+		for(var p in cardinfo){
+			if(value.match('^'+cardinfo[p]+'$')!=null){
+				results.push(p);
+			}
+		}
+		return (results.length)?results.join('|'):false; // string | boolean
+	}	
+}
+
+dojo.validate.isValidCvv = function(value, ccType) {
+	if(typeof value!='string'){
+		value=String(value);
+	}
+	var format;
+	switch (ccType.toLowerCase()){
+		case 'mc':
+		case 'ec':
+		case 'vi':
+		case 'di':
+			format = '###';
+			break;
+		case 'ax':
+			format = '####';
+			break;
+		default:
+			return false;
+	}
+	var flags = {format:format};
+	//FIXME? Why does isNumberFormat take an object for flags when its only parameter is either a string or an array inside the object?
+	if ((value.length == format.length)&&(dojo.validate.isNumberFormat(value, flags))){
+		return true;
+	}
+	return false;
+}
\ No newline at end of file

Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/validate/creditCard.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/validate/datetime.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/validate/datetime.js?view=auto&rev=451106
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/validate/datetime.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/validate/datetime.js Thu Sep 28 20:42:39 2006
@@ -0,0 +1,168 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.validate.datetime");
+dojo.require("dojo.validate.common");
+
+/**
+  Validates a time value in any International format.
+  The value can be validated against one format or one of multiple formats.
+
+  Format
+  h        12 hour, no zero padding.
+  hh       12 hour, has leading zero.
+  H        24 hour, no zero padding.
+  HH       24 hour, has leading zero.
+  m        minutes, no zero padding.
+  mm       minutes, has leading zero.
+  s        seconds, no zero padding.
+  ss       seconds, has leading zero.
+  All other characters must appear literally in the expression.
+
+  Example
+    "h:m:s t"  ->   2:5:33 PM
+    "HH:mm:ss" ->  14:05:33
+
+  @param value  A string.
+  @param flags  An object.
+    flags.format  A string or an array of strings.  Default is "h:mm:ss t".
+    flags.amSymbol  The symbol used for AM.  Default is "AM".
+    flags.pmSymbol  The symbol used for PM.  Default is "PM".
+  @return  true or false
+*/
+dojo.validate.isValidTime = function(value, flags) {
+	var re = new RegExp("^" + dojo.regexp.time(flags) + "$", "i");
+	return re.test(value);
+}
+
+/**
+  Validates 12-hour time format.
+  Zero-padding is not allowed for hours, required for minutes and seconds.
+  Seconds are optional.
+
+  @param value  A string.
+  @return  true or false
+*/
+dojo.validate.is12HourTime = function(value) {
+	return dojo.validate.isValidTime(value, {format: ["h:mm:ss t", "h:mm t"]});
+}
+
+/**
+  Validates 24-hour military time format.
+  Zero-padding is required for hours, minutes, and seconds.
+  Seconds are optional.
+
+  @param value  A string.
+  @return  true or false
+*/
+dojo.validate.is24HourTime = function(value) {
+	return dojo.validate.isValidTime(value, {format: ["HH:mm:ss", "HH:mm"]} );
+}
+
+/**
+  Returns true if the date conforms to the format given and is a valid date. Otherwise returns false.
+
+  @param dateValue  A string for the date.
+  @param format  A string, default is  "MM/DD/YYYY".
+  @return  true or false
+
+  Accepts any type of format, including ISO8601.
+  All characters in the format string are treated literally except the following tokens:
+
+  YYYY - matches a 4 digit year
+  M - matches a non zero-padded month
+  MM - matches a zero-padded month
+  D -  matches a non zero-padded date
+  DD -  matches a zero-padded date
+  DDD -  matches an ordinal date, 001-365, and 366 on leapyear
+  ww - matches week of year, 01-53
+  d - matches day of week, 1-7
+
+  Examples: These are all today's date.
+
+  Date          Format
+  2005-W42-3    YYYY-Www-d
+  2005-292      YYYY-DDD
+  20051019      YYYYMMDD
+  10/19/2005    M/D/YYYY
+  19.10.2005    D.M.YYYY
+*/
+dojo.validate.isValidDate = function(dateValue, format) {
+	// Default is the American format
+	if (typeof format == "object" && typeof format.format == "string"){ format = format.format; }
+	if (typeof format != "string") { format = "MM/DD/YYYY"; }
+
+	// Create a literal regular expression based on format
+	var reLiteral = format.replace(/([$^.*+?=!:|\/\\\(\)\[\]\{\}])/g, "\\$1");
+
+	// Convert all the tokens to RE elements
+	reLiteral = reLiteral.replace( "YYYY", "([0-9]{4})" );
+	reLiteral = reLiteral.replace( "MM", "(0[1-9]|10|11|12)" );
+	reLiteral = reLiteral.replace( "M", "([1-9]|10|11|12)" );
+	reLiteral = reLiteral.replace( "DDD", "(00[1-9]|0[1-9][0-9]|[12][0-9][0-9]|3[0-5][0-9]|36[0-6])" );
+	reLiteral = reLiteral.replace( "DD", "(0[1-9]|[12][0-9]|30|31)" );
+	reLiteral = reLiteral.replace( "D", "([1-9]|[12][0-9]|30|31)" );
+	reLiteral = reLiteral.replace( "ww", "(0[1-9]|[1-4][0-9]|5[0-3])" );
+	reLiteral = reLiteral.replace( "d", "([1-7])" );
+
+	// Anchor pattern to begining and end of string
+	reLiteral = "^" + reLiteral + "$";
+
+	// Dynamic RE that parses the original format given
+	var re = new RegExp(reLiteral);
+	
+	// Test if date is in a valid format
+	if (!re.test(dateValue))  return false;
+
+	// Parse date to get elements and check if date is valid
+	// Assume valid values for date elements not given.
+	var year = 0, month = 1, date = 1, dayofyear = 1, week = 1, day = 1;
+
+	// Capture tokens
+	var tokens = format.match( /(YYYY|MM|M|DDD|DD|D|ww|d)/g );
+
+	// Capture date values
+	var values = re.exec(dateValue);
+
+	// Match up tokens with date values
+	for (var i = 0; i < tokens.length; i++) {
+		switch (tokens[i]) {
+		case "YYYY":
+			year = Number(values[i+1]); break;
+		case "M":
+		case "MM":
+			month = Number(values[i+1]); break;
+		case "D":
+		case "DD":
+			date = Number(values[i+1]); break;
+		case "DDD":
+			dayofyear = Number(values[i+1]); break;
+		case "ww":
+			week = Number(values[i+1]); break;
+		case "d":
+			day = Number(values[i+1]); break;
+		}
+	}
+
+	// Leap years are divisible by 4, but not by 100, unless by 400
+	var leapyear = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
+
+	// 31st of a month with 30 days
+	if (date == 31 && (month == 4 || month == 6 || month == 9 || month == 11)) return false; 
+
+	// February 30th or 31st
+	if (date >= 30 && month == 2) return false; 
+
+	// February 29th outside a leap year
+	if (date == 29 && month == 2 && !leapyear) return false; 
+	if (dayofyear == 366 && !leapyear)  return false;
+
+	return true;
+}

Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/validate/datetime.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/validate/de.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/validate/de.js?view=auto&rev=451106
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/validate/de.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/validate/de.js Thu Sep 28 20:42:39 2006
@@ -0,0 +1,26 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.validate.de");
+dojo.require("dojo.validate.common");
+
+dojo.validate.isGermanCurrency = function(/*String*/value) {
+	//summary: checks to see if 'value' is a valid representation of German currency (Euros)
+	var flags = {
+		symbol: "\u20AC",
+		placement: "after",
+		signPlacement: "begin", //TODO: this is really locale-dependent.  Will get fixed in v0.5 currency rewrite. 
+		decimal: ",",
+		separator: "."
+	};
+	return dojo.validate.isCurrency(value, flags); // Boolean
+}
+
+

Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/validate/de.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/validate/jp.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/validate/jp.js?view=auto&rev=451106
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/validate/jp.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/validate/jp.js Thu Sep 28 20:42:39 2006
@@ -0,0 +1,23 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.validate.jp");
+dojo.require("dojo.validate.common");
+
+dojo.validate.isJapaneseCurrency = function(/*String*/value) {
+	//summary: checks to see if 'value' is a valid representation of Japanese currency
+	var flags = {
+		symbol: "\u00a5",
+		fractional: false
+	};
+	return dojo.validate.isCurrency(value, flags); // Boolean
+}
+
+

Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/validate/jp.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/validate/us.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/validate/us.js?view=auto&rev=451106
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/validate/us.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/validate/us.js Thu Sep 28 20:42:39 2006
@@ -0,0 +1,84 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.validate.us");
+dojo.require("dojo.validate.common");
+
+dojo.validate.us.isCurrency = function(/*String*/value, /*Object?*/flags){
+	// summary: Validates U.S. currency
+	// value: the representation to check
+	// flags: flags in validate.isCurrency can be applied.
+	return dojo.validate.isCurrency(value, flags); // Boolean
+}
+
+
+dojo.validate.us.isState = function(/*String*/value, /*Object?*/flags){
+	// summary: Validates US state and territory abbreviations.
+	//
+	// value: A two character string
+	// flags: An object
+	//    flags.allowTerritories  Allow Guam, Puerto Rico, etc.  Default is true.
+	//    flags.allowMilitary  Allow military 'states', e.g. Armed Forces Europe (AE).  Default is true.
+
+	var re = new RegExp("^" + dojo.regexp.us.state(flags) + "$", "i");
+	return re.test(value); // Boolean
+}
+
+dojo.validate.us.isPhoneNumber = function(/*String*/value){
+	// summary: Validates 10 US digit phone number for several common formats
+	// value: The telephone number string
+
+	var flags = {
+		format: [
+			"###-###-####",
+			"(###) ###-####",
+			"(###) ### ####",
+			"###.###.####",
+			"###/###-####",
+			"### ### ####",
+			"###-###-#### x#???",
+			"(###) ###-#### x#???",
+			"(###) ### #### x#???",
+			"###.###.#### x#???",
+			"###/###-#### x#???",
+			"### ### #### x#???",
+			"##########"
+		]
+	};
+
+	return dojo.validate.isNumberFormat(value, flags); // Boolean
+}
+
+dojo.validate.us.isSocialSecurityNumber = function(/*String*/value){
+// summary: Validates social security number
+	var flags = {
+		format: [
+			"###-##-####",
+			"### ## ####",
+			"#########"
+		]
+	};
+
+	return dojo.validate.isNumberFormat(value, flags); // Boolean
+}
+
+dojo.validate.us.isZipCode = function(/*String*/value){
+// summary: Validates U.S. zip-code
+	var flags = {
+		format: [
+			"#####-####",
+			"##### ####",
+			"#########",
+			"#####"
+		]
+	};
+
+	return dojo.validate.isNumberFormat(value, flags); // Boolean
+}

Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/validate/us.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/validate/web.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/validate/web.js?view=auto&rev=451106
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/validate/web.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/validate/web.js Thu Sep 28 20:42:39 2006
@@ -0,0 +1,95 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.validate.web");
+dojo.require("dojo.validate.common");
+
+dojo.validate.isIpAddress = function(/*String*/value, /*Object?*/flags) {
+	// summary: Validates an IP address
+	//
+	// description:
+	//  Supports 5 formats for IPv4: dotted decimal, dotted hex, dotted octal, decimal and hexadecimal.
+	//  Supports 2 formats for Ipv6.
+	//
+	// value  A string.
+	// flags  An object.  All flags are boolean with default = true.
+	//    flags.allowDottedDecimal  Example, 207.142.131.235.  No zero padding.
+	//    flags.allowDottedHex  Example, 0x18.0x11.0x9b.0x28.  Case insensitive.  Zero padding allowed.
+	//    flags.allowDottedOctal  Example, 0030.0021.0233.0050.  Zero padding allowed.
+	//    flags.allowDecimal  Example, 3482223595.  A decimal number between 0-4294967295.
+	//    flags.allowHex  Example, 0xCF8E83EB.  Hexadecimal number between 0x0-0xFFFFFFFF.
+	//      Case insensitive.  Zero padding allowed.
+	//    flags.allowIPv6   IPv6 address written as eight groups of four hexadecimal digits.
+	//    flags.allowHybrid   IPv6 address written as six groups of four hexadecimal digits
+	//      followed by the usual 4 dotted decimal digit notation of IPv4. x:x:x:x:x:x:d.d.d.d
+
+	var re = new RegExp("^" + dojo.regexp.ipAddress(flags) + "$", "i");
+	return re.test(value); // Boolean
+}
+
+
+dojo.validate.isUrl = function(/*String*/value, /*Object?*/flags) {
+	// summary: Checks if a string could be a valid URL
+	// value: A string
+	// flags: An object
+	//    flags.scheme  Can be true, false, or [true, false]. 
+	//      This means: required, not allowed, or either.
+	//    flags in regexp.host can be applied.
+	//    flags in regexp.ipAddress can be applied.
+	//    flags in regexp.tld can be applied.
+
+	var re = new RegExp("^" + dojo.regexp.url(flags) + "$", "i");
+	return re.test(value); // Boolean
+}
+
+dojo.validate.isEmailAddress = function(/*String*/value, /*Object?*/flags) {
+	// summary: Checks if a string could be a valid email address
+	//
+	// value: A string
+	// flags: An object
+	//    flags.allowCruft  Allow address like <ma...@yahoo.com>.  Default is false.
+	//    flags in regexp.host can be applied.
+	//    flags in regexp.ipAddress can be applied.
+	//    flags in regexp.tld can be applied.
+
+	var re = new RegExp("^" + dojo.regexp.emailAddress(flags) + "$", "i");
+	return re.test(value); // Boolean
+}
+
+dojo.validate.isEmailAddressList = function(/*String*/value, /*Object?*/flags) {
+	// summary: Checks if a string could be a valid email address list.
+	//
+	// value  A string.
+	// flags  An object.
+	//    flags.listSeparator  The character used to separate email addresses.  Default is ";", ",", "\n" or " ".
+	//    flags in regexp.emailAddress can be applied.
+	//    flags in regexp.host can be applied.
+	//    flags in regexp.ipAddress can be applied.
+	//    flags in regexp.tld can be applied.
+
+	var re = new RegExp("^" + dojo.regexp.emailAddressList(flags) + "$", "i");
+	return re.test(value); // Boolean
+}
+
+dojo.validate.getEmailAddressList = function(/*String*/value, /*Object?*/flags) {
+	// summary: Check if value is an email address list. If an empty list
+	//  is returned, the value didn't pass the test or it was empty.
+	//
+	// value: A string
+	// flags: An object (same as dojo.validate.isEmailAddressList)
+
+	if(!flags) { flags = {}; }
+	if(!flags.listSeparator) { flags.listSeparator = "\\s;,"; }
+
+	if ( dojo.validate.isEmailAddressList(value, flags) ) {
+		return value.split(new RegExp("\\s*[" + flags.listSeparator + "]\\s*")); // Array
+	}
+	return []; // Array
+}

Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/validate/web.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/AccordionContainer.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/AccordionContainer.js?view=auto&rev=451106
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/AccordionContainer.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/AccordionContainer.js Thu Sep 28 20:42:39 2006
@@ -0,0 +1,165 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+/**
+ * Holds a set of panes where every pane's title is visible, but only one pane's content is visible at a time.
+ *
+ * Front view (3 panes, pane #2 open)
+ * ------------------------
+ * |:::Pane#1 title:::    |
+ * |:::Pane#2 title:::    |
+ * |                      |
+ * |    pane#2 contents   |
+ * |                      |
+ * |:::Pane#3 title:::    |
+ * ------------------------
+ *
+ * Side view (showing implementation):
+ *
+ *         viewport    pane#3     pane#2     pane#1
+ *            =                                
+ *            |                                =
+ *            |                      =         |
+ * front      |                      |         |
+ *            |                      |         =
+ *            |                      =
+ *            |          =
+ *            =          |
+ *                       |
+ *                       =
+ *
+ * Panes are stacked by z-index like a stack of cards, so they can be slid correctly.
+ * The panes on the bottom extend past the bottom of the viewport.
+ *
+ * TODO: this class should extend PageContainer
+ */
+
+dojo.provide("dojo.widget.AccordionContainer");
+
+dojo.require("dojo.widget.*");
+dojo.require("dojo.html.*");
+dojo.require("dojo.lfx.html");
+dojo.require("dojo.widget.AccordionPane");
+
+dojo.widget.defineWidget(
+	"dojo.widget.AccordionContainer",
+	dojo.widget.HtmlWidget,
+	{
+		isContainer: true,
+		labelNodeClass: "label",
+		containerNodeClass: "accBody",
+
+		// Integer
+		//	Amount of time (in ms) it takes to slide panes
+		duration: 250,
+
+		fillInTemplate: function(){
+			with(this.domNode.style){
+				// position must be either relative or absolute
+				if(position!="absolute"){
+					position="relative";
+				}
+				overflow="hidden";
+			}
+		},
+
+		addChild: function(widget, overrideContainerNode, pos, ref, insertIndex){
+			var child = this._addChild(widget);
+			this._setSizes();
+			return child;
+		},
+		
+		_addChild: function(/*Widget*/ widget){
+			// summary
+			//	Internal call to add child, used during postCreate() and by the real addChild() call
+			if (widget.widgetType != "AccordionPane") {
+				var wrapper=dojo.widget.createWidget("AccordionPane",{label: widget.label, open: widget.open, labelNodeClass: this.labelNodeClass, containerNodeClass: this.containerNodeClass, allowCollapse: this.allowCollapse });
+				wrapper.addChild(widget);
+				this.addWidgetAsDirectChild(wrapper);
+				this.registerChild(wrapper, this.children.length);
+				return wrapper;
+			} else {
+				dojo.html.addClass(widget.containerNode, this.containerNodeClass);
+				dojo.html.addClass(widget.labelNode, this.labelNodeClass);
+				this.addWidgetAsDirectChild(widget);
+				this.registerChild(widget, this.children.length);	
+				return widget;
+			}
+		},
+	
+		postCreate: function() {
+			var tmpChildren = this.children;
+			this.children=[];
+			dojo.html.removeChildren(this.domNode);
+			dojo.lang.forEach(tmpChildren, dojo.lang.hitch(this,"_addChild"));
+			this._setSizes();
+		},
+	
+		removeChild: function(widget) {
+			dojo.widget.AccordionContainer.superclass.removeChild.call(this, widget);
+			this._setSizes();
+		},
+		
+		onResized: function(){
+			this._setSizes();
+		},
+
+		_setSizes: function() {
+			// summary
+			//	Move panes to right position based on current open node.
+			//	Set "slide" to false for initial widget creation, or true when changing the open pane
+			var mySize=dojo.html.getContentBox(this.domNode);
+
+			// get cumulative height of all the title bars, and figure out which pane is open
+			var totalCollapsedHeight = 0;
+			var openIdx = 0;
+			dojo.lang.forEach(this.children, function(child, idx){
+				totalCollapsedHeight += child.getLabelHeight();
+				if(child.open){ openIdx=idx; }
+			});
+
+			// size and position each pane
+			var y = 0;
+			dojo.lang.forEach(this.children, function(child, idx){
+				var childCollapsedHeight = child.getLabelHeight();
+				child.resizeTo(mySize.width, mySize.height-totalCollapsedHeight+childCollapsedHeight);
+				child.domNode.style.zIndex=idx+1;
+				child.domNode.style.position="absolute";
+				child.domNode.style.top = y+"px";
+				y += (idx==openIdx) ? dojo.html.getBorderBox(child.domNode).height : childCollapsedHeight;
+			});
+		},
+
+		selectPage: function(/*Widget*/ page){
+			// summary
+			//	close the current page and select a new one
+			dojo.lang.forEach(this.children, function(child){child.setSelected(child==page);});
+
+			// slide each pane that needs to be moved
+			var y = 0;
+			var anims = [];
+			dojo.lang.forEach(this.children, function(child, idx){
+				if(child.domNode.style.top != (y+"px")){
+					anims.push(dojo.lfx.html.slideTo(child.domNode, {top: y, left: 0}, this.duration));
+				}
+				y += child.open ? dojo.html.getBorderBox(child.domNode).height : child.getLabelHeight();
+			});
+			dojo.lfx.combine(anims).play();
+		}
+	}
+);
+
+// These arguments can be specified for the children of an AccordionContainer
+// Since any widget can be specified as a child, mix them
+// into the base widget class.  (This is a hack, but it's effective.)
+dojo.lang.extend(dojo.widget.Widget, {
+	label: "",
+	open: false
+});

Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/AccordionContainer.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/AccordionPane.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/AccordionPane.js?view=auto&rev=451106
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/AccordionPane.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/AccordionPane.js Thu Sep 28 20:42:39 2006
@@ -0,0 +1,96 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.AccordionPane");
+
+dojo.require("dojo.widget.*");
+dojo.require("dojo.html.*");
+dojo.require("dojo.html.selection");
+dojo.require("dojo.widget.html.layout");
+
+/*
+ * AccordionPane is a box with a title that contains another widget (often a ContentPane).
+ * It works in conjunction w/an AccordionContainer.
+ */
+dojo.widget.defineWidget(
+	"dojo.widget.AccordionPane",
+	dojo.widget.HtmlWidget,
+{
+	// parameters
+
+	// String
+	//	Label to print on top of AccordionPane
+	label: "",
+
+	// String
+	//	class string for the AccordionPane's dom node
+	"class": "dojoAccordionPane",
+
+	// String
+	//	class string for the AccordionPane's label node
+	labelNodeClass: "label",
+
+	// String
+	//	class string for the AccordionPane's container node
+	containerNodeClass: "accBody",
+	
+	// Boolean
+	//	If true, this is the open pane
+	open: false,
+
+	templatePath: dojo.uri.dojoUri("src/widget/templates/AccordionPane.html"),
+	templateCssPath: dojo.uri.dojoUri("src/widget/templates/AccordionPane.css"),
+
+	isContainer: true,
+
+	// methods
+    fillInTemplate: function() {
+    	dojo.html.addClass(this.domNode, this["class"]);
+		dojo.widget.AccordionPane.superclass.fillInTemplate.call(this);
+		dojo.html.disableSelection(this.labelNode);
+		this.setSelected(this.open);
+	},
+
+	setLabel: function(label) {
+		this.labelNode.innerHTML=label;
+	},
+	
+	resizeTo: function(width, height){
+		dojo.html.setMarginBox(this.domNode, {width: width, height: height});
+		var children = [
+			{domNode: this.labelNode, layoutAlign: "top"},
+			{domNode: this.containerNode, layoutAlign: "client"}
+		];
+		dojo.widget.html.layout(this.domNode, children);
+		var childSize = dojo.html.getContentBox(this.containerNode);
+		this.children[0].resizeTo(childSize.width, childSize.height);
+	},
+
+	getLabelHeight: function() {
+		return dojo.html.getMarginBox(this.labelNode).height;
+	},
+
+	onLabelClick: function() {
+		this.parent.selectPage(this);
+	},
+	
+	setSelected: function(/*Boolean*/ isSelected){
+		this.open=isSelected;
+		(isSelected ? dojo.html.addClass : dojo.html.removeClass)(this.domNode, this["class"]+"-selected");
+
+		// make sure child is showing (lazy load)
+		if(isSelected  && this.children.length){
+			var child = this.children[0];
+			if(!child.isShowing()){
+				child.show();
+			}
+		}
+	}
+});

Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/AccordionPane.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/AnimatedPng.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/AnimatedPng.js?view=auto&rev=451106
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/AnimatedPng.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/AnimatedPng.js Thu Sep 28 20:42:39 2006
@@ -0,0 +1,81 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.AnimatedPng");
+dojo.provide("dojo.widget.AnimatedPng");
+
+dojo.require("dojo.widget.*");
+dojo.require("dojo.widget.HtmlWidget");
+
+
+dojo.widget.defineWidget(
+	"dojo.widget.AnimatedPng",
+	dojo.widget.HtmlWidget,
+	{
+		isContainer: false,
+
+		domNode: null,
+		width: 0,
+		height: 0,
+		aniSrc: '',
+		interval: 100,
+
+		cellWidth: 0,
+		cellHeight: 0,
+		aniCols: 1,
+		aniRows: 1,
+		aniCells: 1,
+
+		blankSrc: dojo.uri.dojoUri("src/widget/templates/images/blank.gif"),
+
+		templateString: '<img class="dojoAnimatedPng" />',
+
+		postCreate: function(){
+			this.cellWidth = this.width;
+			this.cellHeight = this.height;
+
+			var img = new Image();
+			var self = this;
+
+			img.onload = function(){ self.initAni(img.width, img.height); };
+			img.src = this.aniSrc;
+		},
+
+		initAni: function(w, h){
+
+			this.domNode.src = this.blankSrc;
+			this.domNode.width = this.cellWidth;
+			this.domNode.height = this.cellHeight;
+			this.domNode.style.backgroundImage = 'url('+this.aniSrc+')';
+			this.domNode.style.backgroundRepeat = 'no-repeat';
+
+			this.aniCols = Math.floor(w/this.cellWidth);
+			this.aniRows = Math.floor(h/this.cellHeight);
+			this.aniCells = this.aniCols * this.aniRows;
+			this.aniFrame = 0;
+
+			window.setInterval(dojo.lang.hitch(this, 'tick'), this.interval);
+		},
+
+		tick: function(){
+
+			this.aniFrame++;
+			if (this.aniFrame == this.aniCells) this.aniFrame = 0;
+
+			var col = this.aniFrame % this.aniCols;
+			var row = Math.floor(this.aniFrame / this.aniCols);
+
+			var bx = -1 * col * this.cellWidth;
+			var by = -1 * row * this.cellHeight;
+
+			this.domNode.style.backgroundPosition = bx+'px '+by+'px';
+		}
+	}
+);

Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/AnimatedPng.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Button.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Button.js?view=auto&rev=451106
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Button.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Button.js Thu Sep 28 20:42:39 2006
@@ -0,0 +1,353 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.Button");
+
+dojo.require("dojo.lang.extras");
+dojo.require("dojo.html.*");
+dojo.require("dojo.html.selection");
+dojo.require("dojo.widget.*");
+
+dojo.widget.defineWidget(
+	"dojo.widget.Button",
+	dojo.widget.HtmlWidget,
+	{
+		isContainer: true,
+
+		// Constructor arguments
+		caption: "",
+		disabled: false,
+	
+		templatePath: dojo.uri.dojoUri("src/widget/templates/ButtonTemplate.html"),
+		templateCssPath: dojo.uri.dojoUri("src/widget/templates/ButtonTemplate.css"),
+		
+		// button images
+		inactiveImg: "src/widget/templates/images/soriaButton-",
+		activeImg: "src/widget/templates/images/soriaActive-",
+		pressedImg: "src/widget/templates/images/soriaPressed-",
+		disabledImg: "src/widget/templates/images/soriaDisabled-",
+		width2height: 1.0/3.0,
+	
+		// attach points
+		buttonNode: null,
+		containerNode: null,
+		leftImage: null,
+		centerImage: null,
+		rightImage: null,
+	
+		fillInTemplate: function(args, frag){
+			if(this.caption != ""){
+				this.containerNode.appendChild(document.createTextNode(this.caption));
+			}
+			dojo.html.disableSelection(this.containerNode);
+		},
+
+		postCreate: function(args, frag){
+			this.sizeMyself();
+		},
+	
+		sizeMyself: function(){
+			// we cannot size correctly if any of our ancestors are hidden (display:none),
+			// so temporarily attach to document.body
+			if(this.domNode.parentNode){
+				var placeHolder = document.createElement("span");
+				dojo.html.insertBefore(placeHolder, this.domNode);
+			}
+			dojo.body().appendChild(this.domNode);
+			
+			this.sizeMyselfHelper();
+			
+			// Put this.domNode back where it was originally
+			if(placeHolder){
+				dojo.html.insertBefore(this.domNode, placeHolder);
+				dojo.html.removeNode(placeHolder);
+			}
+		},
+
+		sizeMyselfHelper: function(){
+			var mb = dojo.html.getMarginBox(this.containerNode);
+			this.height = mb.height;
+			this.containerWidth = mb.width;
+			var endWidth= this.height * this.width2height;
+	
+			this.containerNode.style.left=endWidth+"px";
+	
+			this.leftImage.height = this.rightImage.height = this.centerImage.height = this.height;
+			this.leftImage.width = this.rightImage.width = endWidth+1;
+			this.centerImage.width = this.containerWidth;
+			this.centerImage.style.left=endWidth+"px";
+			this._setImage(this.disabled ? this.disabledImg : this.inactiveImg);
+
+			if ( this.disabled ) {
+				dojo.html.prependClass(this.domNode, "dojoButtonDisabled");
+				this.domNode.removeAttribute("tabIndex");
+				dojo.widget.wai.setAttr(this.domNode, "waiState", "disabled", true);
+			} else {
+				dojo.html.removeClass(this.domNode, "dojoButtonDisabled");
+				this.domNode.setAttribute("tabIndex", "0");
+				dojo.widget.wai.setAttr(this.domNode, "waiState", "disabled", false);
+			}
+				
+			this.domNode.style.height=this.height + "px";
+			this.domNode.style.width= (this.containerWidth+2*endWidth) + "px";
+		},
+	
+		onMouseOver: function(e){
+			if( this.disabled ){ return; }
+			dojo.html.prependClass(this.buttonNode, "dojoButtonHover");
+			this._setImage(this.activeImg);
+		},
+	
+		onMouseDown: function(e){
+			if( this.disabled ){ return; }
+			dojo.html.prependClass(this.buttonNode, "dojoButtonDepressed");
+			dojo.html.removeClass(this.buttonNode, "dojoButtonHover");
+			this._setImage(this.pressedImg);
+		},
+		onMouseUp: function(e){
+			if( this.disabled ){ return; }
+			dojo.html.prependClass(this.buttonNode, "dojoButtonHover");
+			dojo.html.removeClass(this.buttonNode, "dojoButtonDepressed");
+			this._setImage(this.activeImg);
+		},
+	
+		onMouseOut: function(e){
+			if( this.disabled ){ return; }
+			if( e.toElement && dojo.html.isDescendantOf(e.toElement, this.buttonNode) ){
+				return; // Ignore IE mouseOut events that dont actually leave button - Prevents hover image flicker in IE
+			}
+			dojo.html.removeClass(this.buttonNode, "dojoButtonHover");
+			this._setImage(this.inactiveImg);
+		},
+
+		onKey: function(e){
+			if (!e.key) { return; }
+			var menu = dojo.widget.getWidgetById(this.menuId);
+			if (e.key == e.KEY_ENTER || e.key == " "){
+				this.onMouseDown(e);
+				this.buttonClick(e);
+				dojo.lang.setTimeout(this, "onMouseUp", 75, e);
+				e.preventDefault();
+				e.stopPropagation();
+			}
+			if(menu && menu.isShowingNow && e.key == e.KEY_DOWN_ARROW){
+				// disconnect onBlur when focus moves into menu
+				dojo.event.disconnect(this.domNode, "onblur", this, "onBlur");
+				// allow event to propagate to menu
+			}
+		},
+
+		onFocus: function(e){
+			var menu = dojo.widget.getWidgetById(this.menuId);
+			if (menu ){
+				dojo.event.connectOnce(this.domNode, "onblur", this, "onBlur");
+			}
+		},
+
+		onBlur: function(e){
+			var menu = dojo.widget.getWidgetById(this.menuId);
+			if ( !menu ) { return; }
+	
+			if ( menu.close && menu.isShowingNow ){
+				menu.close();
+			}
+		},
+
+		buttonClick: function(e){
+			if( !this.disabled ) { this.onClick(e); }
+		},
+
+		onClick: function(e) { },
+
+		_setImage: function(prefix){
+			this.leftImage.src=dojo.uri.dojoUri(prefix + "l.gif");
+			this.centerImage.src=dojo.uri.dojoUri(prefix + "c.gif");
+			this.rightImage.src=dojo.uri.dojoUri(prefix + "r.gif");
+		},
+		
+		_toggleMenu: function(menuId){
+			var menu = dojo.widget.getWidgetById(menuId); 
+			if ( !menu ) { return; }
+			if ( menu.open && !menu.isShowingNow) {
+				var pos = dojo.html.getAbsolutePosition(this.domNode, false);
+				menu.open(pos.x, pos.y+this.height, this);
+			} else if ( menu.close && menu.isShowingNow ){
+				menu.close();
+			} else {
+				menu.toggle();
+			}
+		},
+		
+		setCaption: function(content){
+			this.caption=content;
+			this.containerNode.innerHTML=content;
+			this.sizeMyself();
+		},
+		
+		setDisabled: function(disabled){
+			this.disabled=disabled;
+			this.sizeMyself();
+		}
+	});
+
+/**** DropDownButton - push the button and a menu shows up *****/
+dojo.widget.defineWidget(
+	"dojo.widget.DropDownButton",
+	dojo.widget.Button,
+	{
+		menuId: "",
+
+		arrow: null,
+	
+		downArrow: "src/widget/templates/images/whiteDownArrow.gif",
+		disabledDownArrow: "src/widget/templates/images/whiteDownArrow.gif",
+	
+		fillInTemplate: function(args, frag){
+			dojo.widget.DropDownButton.superclass.fillInTemplate.call(this, args, frag);
+	
+			this.arrow = document.createElement("img");
+			dojo.html.setClass(this.arrow, "downArrow");
+
+			dojo.widget.wai.setAttr(this.domNode, "waiState", "haspopup", this.menuId);
+		},
+
+		sizeMyselfHelper: function(){
+			// draw the arrow (todo: why is the arror in containerNode rather than outside it?)
+			this.arrow.src = dojo.uri.dojoUri(this.disabled ? this.disabledDownArrow : this.downArrow);
+			this.containerNode.appendChild(this.arrow);
+
+			dojo.widget.DropDownButton.superclass.sizeMyselfHelper.call(this);
+		},
+
+		onClick: function (e){
+			this._toggleMenu(this.menuId);
+		}
+	});
+
+/**** ComboButton - left side is normal button, right side shows menu *****/
+dojo.widget.defineWidget(
+	"dojo.widget.ComboButton",
+	dojo.widget.Button,
+	{
+		menuId: "",
+	
+		templatePath: dojo.uri.dojoUri("src/widget/templates/ComboButtonTemplate.html"),
+	
+		// attach points
+		rightPart: null,
+		arrowBackgroundImage: null,
+	
+		// constants
+		splitWidth: 2,		// pixels between left&right part of button
+		arrowWidth: 5,		// width of segment holding down arrow
+	
+		sizeMyselfHelper: function(e){
+			var mb = dojo.html.getMarginBox(this.containerNode);
+			this.height = mb.height;
+			this.containerWidth = mb.width;
+
+			var endWidth= this.height/3;
+
+			if(this.disabled){
+				dojo.widget.wai.setAttr(this.domNode, "waiState", "disabled", true);
+				this.domNode.removeAttribute("tabIndex");
+			}
+			else {
+				dojo.widget.wai.setAttr(this.domNode, "waiState", "disabled", false);
+				this.domNode.setAttribute("tabIndex", "0");
+			}
+	
+			// left part
+			this.leftImage.height = this.rightImage.height = this.centerImage.height = 
+				this.arrowBackgroundImage.height = this.height;
+			this.leftImage.width = endWidth+1;
+			this.centerImage.width = this.containerWidth;
+			this.buttonNode.style.height = this.height + "px";
+			this.buttonNode.style.width = endWidth + this.containerWidth + "px";
+			this._setImage(this.disabled ? this.disabledImg : this.inactiveImg);
+
+			// right part
+			this.arrowBackgroundImage.width=this.arrowWidth;
+			this.rightImage.width = endWidth+1;
+			this.rightPart.style.height = this.height + "px";
+			this.rightPart.style.width = this.arrowWidth + endWidth + "px";
+			this._setImageR(this.disabled ? this.disabledImg : this.inactiveImg);
+	
+			// outer container
+			this.domNode.style.height=this.height + "px";
+			var totalWidth = this.containerWidth+this.splitWidth+this.arrowWidth+2*endWidth;
+			this.domNode.style.width= totalWidth + "px";
+		},
+	
+		_setImage: function(prefix){
+			this.leftImage.src=dojo.uri.dojoUri(prefix + "l.gif");
+			this.centerImage.src=dojo.uri.dojoUri(prefix + "c.gif");
+		},
+	
+		/*** functions on right part of button ***/
+		rightOver: function(e){
+			if( this.disabled ){ return; }
+			dojo.html.prependClass(this.rightPart, "dojoButtonHover");
+			this._setImageR(this.activeImg);
+		},
+	
+		rightDown: function(e){
+			if( this.disabled ){ return; }
+			dojo.html.prependClass(this.rightPart, "dojoButtonDepressed");
+			dojo.html.removeClass(this.rightPart, "dojoButtonHover");
+			this._setImageR(this.pressedImg);
+		},
+		rightUp: function(e){
+			if( this.disabled ){ return; }
+			dojo.html.prependClass(this.rightPart, "dojoButtonHover");
+			dojo.html.removeClass(this.rightPart, "dojoButtonDepressed");
+			this._setImageR(this.activeImg);
+		},
+	
+		rightOut: function(e){
+			if( this.disabled ){ return; }
+			dojo.html.removeClass(this.rightPart, "dojoButtonHover");
+			this._setImageR(this.inactiveImg);
+		},
+
+		rightClick: function(e){
+			if( this.disabled ){ return; }
+			this._toggleMenu(this.menuId);
+		},
+	
+		_setImageR: function(prefix){
+			this.arrowBackgroundImage.src=dojo.uri.dojoUri(prefix + "c.gif");
+			this.rightImage.src=dojo.uri.dojoUri(prefix + "r.gif");
+		},
+
+		/*** keyboard functions ***/
+		
+		onKey: function(e){
+			if (!e.key) { return; }
+			var menu = dojo.widget.getWidgetById(this.menuId);
+			if(e.key== e.KEY_ENTER || e.key == " "){
+				this.onMouseDown(e);
+				this.buttonClick(e);
+				dojo.lang.setTimeout(this, "onMouseUp", 75, e);
+				e.preventDefault();
+				e.stopPropagation();
+			} else if (e.key == e.KEY_DOWN_ARROW && e.altKey){
+				this.rightDown(e);
+				this.rightClick(e);
+				dojo.lang.setTimeout(this, "rightUp", 75, e);
+				e.preventDefault();
+				e.stopPropagation();
+			} else if(menu && menu.isShowingNow && e.key == e.KEY_DOWN_ARROW){
+				// disconnect onBlur when focus moves into menu
+				dojo.event.disconnect(this.domNode, "onblur", this, "onBlur");
+				// allow event to propagate to menu
+			}
+		}
+	});

Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Button.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Chart.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Chart.js?view=auto&rev=451106
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Chart.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Chart.js Thu Sep 28 20:42:39 2006
@@ -0,0 +1,256 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.Chart");
+dojo.provide("dojo.widget.Chart.DataSeries");
+
+dojo.require("dojo.widget.*");
+dojo.require("dojo.gfx.color");
+dojo.require("dojo.gfx.color.hsl");
+
+// Base class for svg and vml implementations of Chart
+dojo.declare(
+	"dojo.widget.Chart",
+	null,
+	function(){
+		this.series = [];
+	},
+{
+	isContainer: false,
+
+	assignColors: function(){
+		var hue=30;
+		var sat=120;
+		var lum=120;
+		var steps = Math.round(330/this.series.length);
+
+		for(var i=0; i<this.series.length; i++){
+			var c=dojo.gfx.color.hsl2rgb(hue,sat,lum);
+			if(!this.series[i].color){
+				this.series[i].color = dojo.gfx.color.rgb2hex(c[0],c[1],c[2]);
+			}
+			hue += steps;
+		}
+	},
+	parseData: function(table){
+		var thead=table.getElementsByTagName("thead")[0];
+		var tbody=table.getElementsByTagName("tbody")[0];
+		if(!(thead&&tbody)) dojo.raise("dojo.widget.Chart: supplied table must define a head and a body.");
+
+		//	set up the series.
+		var columns=thead.getElementsByTagName("tr")[0].getElementsByTagName("th");	//	should be <tr><..>
+		
+		//	assume column 0 == X
+		for (var i=1; i<columns.length; i++){
+			var key="column"+i;
+			var label=columns[i].innerHTML;
+			var plotType=columns[i].getAttribute("plotType")||"line";
+			var color=columns[i].getAttribute("color");
+			var ds=new dojo.widget.Chart.DataSeries(key,label,plotType,color);
+			this.series.push(ds);
+		}
+
+		//	ok, get the values.
+		var rows=tbody.rows;
+		var xMin=Number.MAX_VALUE,xMax=Number.MIN_VALUE;
+		var yMin=Number.MAX_VALUE,yMax=Number.MIN_VALUE;
+		var ignore = [
+			"accesskey","align","bgcolor","class",
+			"colspan","height","id","nowrap",
+			"rowspan","style","tabindex","title",
+			"valign","width"
+		];
+
+		for(var i=0; i<rows.length; i++){
+			var row=rows[i];
+			var cells=row.cells;
+			var x=Number.MIN_VALUE;
+			for (var j=0; j<cells.length; j++){
+				if (j==0){
+					x=parseFloat(cells[j].innerHTML);
+					xMin=Math.min(xMin, x);
+					xMax=Math.max(xMax, x);
+				} else {
+					var ds=this.series[j-1];
+					var y=parseFloat(cells[j].innerHTML);
+					yMin=Math.min(yMin,y);
+					yMax=Math.max(yMax,y);
+					var o={x:x, value:y};
+					var attrs=cells[j].attributes;
+					for(var k=0; k<attrs.length; k++){
+						var attr=attrs.item(k);
+						var bIgnore=false;
+						for (var l=0; l<ignore.length; l++){
+							if (attr.nodeName.toLowerCase()==ignore[l]){
+								bIgnore=true;
+								break;
+							}
+						}
+						if(!bIgnore) o[attr.nodeName]=attr.nodeValue;
+					}
+					ds.add(o);
+				}
+			}
+		}
+		return { x:{ min:xMin, max:xMax}, y:{ min:yMin, max:yMax} };
+	}
+});
+
+/*
+ *	Every chart has a set of data series; this is the series.  Note that each
+ *	member of value is an object and in the minimum has 2 properties: .x and
+ *	.value.
+ */
+dojo.declare(
+	"dojo.widget.Chart.DataSeries",
+	null,
+	function(key, label, plotType, color){
+		this.id = "DataSeries"+dojo.widget.Chart.DataSeries.count++;
+		this.key = key;
+		this.label = label||this.id;
+		this.plotType = plotType||"line";	//	let line be the default.
+		this.color = color;
+		this.values = [];
+	},
+{
+	add: function(v){
+		if(v.x==null||v.value==null){
+			dojo.raise("dojo.widget.Chart.DataSeries.add: v must have both an 'x' and 'value' property.");
+		}
+		this.values.push(v);
+	},
+
+	clear: function(){
+		this.values=[];
+	},
+
+	createRange: function(len){
+		var idx = this.values.length-1;
+		var length = (len||this.values.length);
+		return { "index": idx, "length": length, "start":Math.max(idx-length,0) };
+	},
+
+	//	trend values
+	getMean: function(len){
+		var range = this.createRange(len);
+		if(range.index<0){ return 0; }
+		var t = 0;
+		var c = 0;
+		for(var i=range.index; i>=range.start; i--){
+			var n = parseFloat(this.values[i].value);
+			if(!isNaN(n)){ t += n; c++; }
+		}
+		t /= Math.max(c,1);
+		return t;
+	},
+
+	getMovingAverage: function(len){
+		var range = this.createRange(len);
+		if(range.index<0){ return 0; }
+		var t = 0;
+		var c = 0;
+		for(var i=range.index; i>=range.start; i--){
+			var n = parseFloat(this.values[i].value);
+			if(!isNaN(n)){ t += n; c++; }
+		}
+		t /= Math.max(c,1);
+		return t;
+	},
+
+	getVariance: function(len){
+		var range = this.createRange(len);
+		if(range.index < 0){ return 0; }
+		var t = 0; // FIXME: for tom: wtf are t, c, and s?
+		var s = 0;
+		var c = 0;
+		for(var i=range.index; i>=range.start; i--){
+			var n = parseFloat(this.values[i].value);
+			if(!isNaN(n)){
+				t += n;
+				s += Math.pow(n,2);
+				c++;
+			}
+		}
+		return (s/c)-Math.pow(t/c,2);
+	},
+
+	getStandardDeviation: function(len){
+		return Math.sqrt(this.getVariance(len));
+	},
+
+	getMax: function(len){
+		var range = this.createRange(len);
+		if(range.index < 0){ return 0; }
+		var t = 0;
+		for (var i=range.index; i>=range.start; i--){
+			var n=parseFloat(this.values[i].value);
+			if (!isNaN(n)){
+				t=Math.max(n,t);
+			}
+		}
+		return t;
+	},
+
+	getMin: function(len){
+		var range=this.createRange(len);
+		if(range.index < 0){ return 0; }
+		var t = 0;
+		for(var i=range.index; i>=range.start; i--){
+			var n = parseFloat(this.values[i].value);
+			if(!isNaN(n)){
+				t=Math.min(n,t);
+			}
+		}
+		return t;
+	},
+
+	getMedian: function(len){
+		var range = this.createRange(len);
+
+		if(range.index<0){ return 0; }
+
+		var a = [];
+		for (var i=range.index; i>=range.start; i--){
+			var n=parseFloat(this.values[i].value);
+			if (!isNaN(n)){
+				var b=false;
+				for(var j=0; j<a.length&&!b; j++){
+					if (n==a[j]) b=true; 
+				}
+				if(!b){ a.push(n); }
+			}
+		}
+		a.sort();
+		if(a.length>0){ return a[Math.ceil(a.length/2)]; }
+		return 0;
+	},
+
+	getMode: function(len){
+		var range=this.createRange(len);
+		if(range.index<0){ return 0; }
+		var o = {};
+		var ret = 0
+		var m = 0;
+		for(var i=range.index; i>=range.start; i--){
+			var n=parseFloat(this.values[i].value);
+			if(!isNaN(n)){
+				if (!o[this.values[i].value]) o[this.values[i].value] = 1;
+				else o[this.values[i].value]++;
+			}
+		}
+		for(var p in o){
+			if(m<o[p]){ m=o[p]; ret=p; }
+		}
+		return parseFloat(ret);
+	}
+});
+
+dojo["requireIf"](dojo.render.svg.capable, "dojo.widget.svg.Chart");
+dojo["requireIf"](!dojo.render.svg.capable && dojo.render.vml.capable, "dojo.widget.vml.Chart");

Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Chart.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Checkbox.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Checkbox.js?view=auto&rev=451106
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Checkbox.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Checkbox.js Thu Sep 28 20:42:39 2006
@@ -0,0 +1,140 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.Checkbox");
+
+dojo.require("dojo.widget.*");
+dojo.require("dojo.widget.HtmlWidget");
+dojo.require("dojo.event.*");
+dojo.require("dojo.html.style");
+
+dojo.widget.defineWidget(
+	"dojo.widget.Checkbox",
+	dojo.widget.HtmlWidget,
+	{
+		templatePath: dojo.uri.dojoUri('src/widget/templates/Checkbox.html'),
+		templateCssPath: dojo.uri.dojoUri('src/widget/templates/Checkbox.css'),
+
+		// attributes
+		disabled: "enabled",
+		name: "",
+		checked: "",
+		tabIndex: "",
+		id: "",
+		value: "on",
+
+		postMixInProperties: function(){
+			dojo.widget.Checkbox.superclass.postMixInProperties.apply(this, arguments);
+			// set the variables referenced by the template
+			// valid HTML 4.01 and XHTML use disabled="disabled" - convert to boolean 
+			//NOTE: this doesn't catch disabled with no value if FF
+			this.disabled = (this.disabled == "disabled" || this.disabled == true);
+			// valid HTML 4.01 and XHTML require checked="checked"
+			// convert to boolean NOTE: this doesn't catch checked with no value in FF
+			this.checked = (this.checked == "checked" || this.checked == true);
+
+			// output valid checked and disabled attributes
+			this.disabledStr = this.disabled ? "disabled=\"disabled\"" : "";
+			this.checkedStr = this.checked ? "checked=\"checked\"" : "";
+
+			// set tabIndex="0" because if tabIndex=="" user won't be able to tab to the field
+
+
+			if(!this.disabled && this.tabIndex==""){ this.tabIndex="0"; }
+		},
+
+		postCreate: function(args, frag){
+			// find any associated label and create a labelled-by relationship
+			// assumes <label for="inputId">label text </label> rather than
+			// <label><input type="xyzzy">label text</label> 
+			if(this.id != ""){
+				var labels = document.getElementsByTagName("label");
+				if (labels != null && labels.length > 0){
+					for(var i=0; i<labels.length; i++){
+						if (labels[i].htmlFor == this.id){
+							labels[i].id = (labels[i].htmlFor + "label"); 
+							dojo.widget.wai.setAttr(this.domNode, "waiState", "labelledby", labels[i].id);
+							break;
+						}
+					}
+				}
+			}
+		},
+
+		fillInTemplate: function(){
+			this._setInfo();
+		},
+
+		_onClick: function(e){
+			if(this.disabled == false){
+				this.checked = !this.checked;
+				this._setInfo();
+			}
+			e.preventDefault();
+			this.onClick();
+		},
+
+		// user overridable function
+		onClick: function(){ },
+
+		onKey: function(e){
+			var k = dojo.event.browser.keys;
+			if(e.key == " "){
+	 			this._onClick(e);
+	 		}
+		},
+		
+		mouseOver: function(e){
+			this.hover(e, true);
+		},
+		
+		mouseOut: function(e){
+			this.hover(e, false);
+		},
+		
+		hover: function(e, isOver){
+			if (this.disabled == false){
+				var state = this.checked ? "On" : "Off";
+				var style = "dojoHtmlCheckbox" + state + "Hover";
+				if (isOver){
+					dojo.html.addClass(this.domNode, style);
+				}else{
+					dojo.html.removeClass(this.domNode,style);
+				}
+			}
+		},
+
+		// set CSS class string according to checked/unchecked and disabled/enabled state
+		_setInfo: function(){
+			var state = "dojoHtmlCheckbox" + (this.disabled ? "Disabled" : "") + (this.checked ? "On" : "Off");
+			dojo.html.setClass(this.domNode, "dojoHtmlCheckbox " + state);
+			this.inputNode.checked = this.checked;
+			dojo.widget.wai.setAttr(this.domNode, "waiState", "checked", this.checked);
+		}
+	}
+);
+dojo.widget.defineWidget(
+	"dojo.widget.a11y.Checkbox",
+	dojo.widget.Checkbox,
+	{	
+		templatePath: dojo.uri.dojoUri('src/widget/templates/CheckboxA11y.html'),
+		
+		postCreate: function(args, frag){
+			// nothing to do but don't want Checkbox version to run
+		},
+		
+		fillInTemplate: function(){
+		},
+		_onClick: function(){
+			this.onClick();
+		}
+	}
+);
+

Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Checkbox.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Clock.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Clock.js?view=auto&rev=451106
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Clock.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Clock.js Thu Sep 28 20:42:39 2006
@@ -0,0 +1,211 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.Clock");
+
+dojo.require("dojo.widget.*");
+dojo.require("dojo.gfx.*");
+dojo.require("dojo.uri.Uri");
+dojo.require("dojo.lang.common");
+dojo.require("dojo.lang.timing.Timer");
+
+dojo.widget.defineWidget(
+	"dojo.widget.Clock",
+	dojo.widget.HtmlWidget,
+	function(){
+		var self=this;
+		this.timeZoneOffset=0;	//	this is fun.
+		this.label="";		//	optional label.
+		
+		this.date=new Date();
+		
+		this.handColor="#788598";
+		this.handStroke="#6f7b8c";
+	//	this.secondHandColor="#c90405";
+		this.secondHandColor=[201, 4, 5, 0.8];
+		this.topLabelColor="#efefef";
+		this.labelColor="#fff";
+
+		//	timer
+		this.timer = new dojo.lang.timing.Timer(1000);
+
+		//	shapes
+		this.center={ x:75, y:75 };
+		this.hands={
+			hour:null,
+			minute:null,
+			second:null
+		};
+		this.shadows={
+			hour:{ shadow:null, shift:{ dx:2, dy:2} },
+			minute:{ shadow:null, shift:{ dx:2, dy:3} },
+			second:{ shadow:null, shift:{ dx:4, dy:4} }
+		};
+		this.image = dojo.uri.dojoUri("src/widget/templates/images/clock.png");
+		this.surface=null;
+		this.labelNode=null;
+		this.topLabelNode=null;
+
+		this.draw=function(){
+			self.date=new Date();
+			var h=(self.date.getHours()+self.timeZoneOffset) % 12;
+			var m=self.date.getMinutes();
+			var s=self.date.getSeconds();
+
+			self.placeHour(h, m, s);
+			self.placeMinute(m, s);
+			self.placeSecond(s);
+
+			self.topLabelNode.innerHTML=((self.date.getHours()+self.timeZoneOffset)>11)?"PM":"AM";
+		};
+
+		this.timer.onTick=self.draw;
+	},
+	{
+		set:function(/* Date */dt){
+			this.date=dt;
+			if(!this.timer.isRunning){
+				this.draw();
+			}
+		},
+		start:function(){ this.timer.start(); },
+		stop:function(){ this.timer.stop(); },
+
+		_initPoly:function(parent, points){
+			var path = parent.createPath();
+			var first = true;
+			dojo.lang.forEach(points, function(c){
+				if(first){
+					path.moveTo(c.x, c.y);
+					first=false;
+				} else {
+					path.lineTo(c.x, c.y);
+				}
+			});
+			return path;
+		},
+		_placeHand:function(shape, angle, shift){
+			var move = { dx:this.center.x + (shift?shift.dx:0), dy:this.center.y+(shift?shift.dy:0) };
+			return shape.setTransform([move, dojo.gfx.matrix.rotateg(-angle)]);
+		},
+		placeHour:function(h, m, s){
+			var angle=30 *(h + m/60 + s/3600);
+			this._placeHand(this.hands.hour, angle);
+			this._placeHand(this.shadows.hour.shadow, angle, this.shadows.hour.shift);
+		},
+		placeMinute:function(m, s){
+			var angle=6 * (m + s/60);
+			this._placeHand(this.hands.minute, angle);
+			this._placeHand(this.shadows.minute.shadow, angle, this.shadows.minute.shift);
+		},
+		placeSecond:function(s){
+			var angle=6 * s;
+			this._placeHand(this.hands.second, angle);
+			this._placeHand(this.shadows.second.shadow, angle, this.shadows.second.shift);
+		},
+		
+		init:function(){
+			//	start by setting up the domNode
+			if(this.domNode.style.position != "absolute"){
+				this.domNode.style.position = "relative";
+			}
+
+			//	clean out any children
+			while(this.domNode.childNodes.length>0){
+				this.domNode.removeChild(this.domNode.childNodes[0]);
+			}
+			
+			//	set ourselves up.
+			this.domNode.style.width="150px";
+			this.domNode.style.height="150px";
+
+			this.surface=dojo.gfx.createSurface(this.domNode, 150, 150);
+			this.surface.createRect({width: 150, height: 150});
+			this.surface.createImage({width: 150, height: 150, src: this.image+""});
+			
+			var hP=[ {x: -3, y: -4}, {x: 3, y: -4}, {x: 1, y: -27}, { x:-1, y:-27}, {x: -3, y: -4} ];
+			var mP=[ {x: -3, y: -4}, {x: 3, y: -4}, {x: 1, y: -38}, {x:-1, y:-38}, {x: -3, y: -4} ];
+			var sP=[ {x: -2, y: -2}, {x: 2, y: -2}, {x: 1, y: -45}, {x: -1, y: -45}, {x: -2, y: -2} ];
+			
+			this.shadows.hour.shadow = this._initPoly(this.surface, hP)
+				.setFill([0, 0, 0, 0.1]);
+			this.hands.hour = this._initPoly(this.surface, hP)
+				.setStroke({color: this.handStroke, width:1 })
+				.setFill({ 
+					type:"linear", 
+					x1:0, y1:0, x2:0, y2:-27, 
+					colors:[{offset:0, color:"#fff"}, {offset:0.33, color:this.handColor}]
+				});
+			this.shadows.minute.shadow = this._initPoly(this.surface, mP)
+				.setFill([0, 0, 0, 0.1]);
+			this.hands.minute = this._initPoly(this.surface, mP)
+				.setStroke({color: this.handStroke, width:1 })
+				.setFill({ 
+					type:"linear", 
+					x1:0, y1:0, x2:0, y2:-38, 
+					colors:[{offset:0, color:"#fff"}, {offset:0.33, color:this.handColor}]
+				});
+
+			this.surface.createCircle({r: 6})
+				.setStroke({color: this.handStroke, width:2 })
+				.setFill("#fff")
+				.setTransform({dx: 75, dy: 75});
+
+			this.shadows.second.shadow = this._initPoly(this.surface, sP)
+				.setFill([0, 0, 0, 0.1]);
+			this.hands.second = this._initPoly(this.surface, sP)
+				.setFill(this.secondHandColor);
+
+			//	clock centers, doesn't move.
+			this.surface.createCircle({r: 4})
+				.setFill(this.secondHandColor)
+				.setTransform({dx: 75, dy: 75});
+
+			//	labels
+			this.topLabelNode=document.createElement("div");
+			with(this.topLabelNode.style){
+				position="absolute";
+				top="3px";
+				left="0px";
+				color=this.topLabelColor;
+				textAlign="center";
+				width="150px";
+				fontFamily="sans-serif";
+				fontSize="11px";
+				textTransform="uppercase";
+				fontWeight="bold";
+			}
+			this.topLabelNode.innerHTML=((this.date.getHours()+this.timeZoneOffset)>11)?"PM":"AM";
+			this.domNode.appendChild(this.topLabelNode);
+
+			this.labelNode=document.createElement("div");
+			with(this.labelNode.style){
+				position="absolute";
+				top="134px";
+				left="0px";
+				color=this.labelColor;
+				textAlign="center";
+				width="150px";
+				fontFamily="sans-serif";
+				fontSize="10px";
+				textTransform="uppercase";
+				fontWeight="bold";
+			}
+			this.labelNode.innerHTML=this.label||"&nbsp;";
+			this.domNode.appendChild(this.labelNode);
+			
+			this.draw();
+		},
+		postCreate:function(){
+			this.init();
+			this.start();
+		}
+	}
+);

Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/ColorPalette.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/ColorPalette.js?view=auto&rev=451106
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/ColorPalette.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/ColorPalette.js Thu Sep 28 20:42:39 2006
@@ -0,0 +1,156 @@
+/*
+	Copyright (c) 2004-2006, The Dojo Foundation
+	All Rights Reserved.
+
+	Licensed under the Academic Free License version 2.1 or above OR the
+	modified BSD license. For more information on Dojo licensing, see:
+
+		http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.ColorPalette");
+dojo.require("dojo.widget.*");
+dojo.require("dojo.widget.Toolbar");
+dojo.require("dojo.html.layout");
+dojo.require("dojo.html.display");
+dojo.require("dojo.html.selection");
+
+dojo.widget.defineWidget(
+	"dojo.widget.ToolbarColorDialog",
+	dojo.widget.ToolbarDialog,
+{
+ 	palette: "7x10",
+
+	fillInTemplate: function (args, frag) {
+		dojo.widget.ToolbarColorDialog.superclass.fillInTemplate.call(this, args, frag);
+		this.dialog = dojo.widget.createWidget("ColorPalette", {palette: this.palette});
+		this.dialog.domNode.style.position = "absolute";
+
+		dojo.event.connect(this.dialog, "onColorSelect", this, "_setValue");
+	},
+
+	_setValue: function(color) {
+		this._value = color;
+		this._fireEvent("onSetValue", color);
+	},
+	
+	showDialog: function (e) {
+		dojo.widget.ToolbarColorDialog.superclass.showDialog.call(this, e);
+		var abs = dojo.html.getAbsolutePosition(this.domNode, true);
+		var y = abs.y + dojo.html.getBorderBox(this.domNode).height;
+		this.dialog.showAt(abs.x, y);
+	},
+	
+	hideDialog: function (e) {
+		dojo.widget.ToolbarColorDialog.superclass.hideDialog.call(this, e);
+		this.dialog.hide();
+	}
+});
+
+dojo.widget.defineWidget(
+	"dojo.widget.ColorPalette",
+	dojo.widget.HtmlWidget,
+{	
+	palette: "7x10",
+
+	bgIframe: null,
+	
+	palettes: {
+		"7x10": [["fff", "fcc", "fc9", "ff9", "ffc", "9f9", "9ff", "cff", "ccf", "fcf"],
+			["ccc", "f66", "f96", "ff6", "ff3", "6f9", "3ff", "6ff", "99f", "f9f"],
+			["c0c0c0", "f00", "f90", "fc6", "ff0", "3f3", "6cc", "3cf", "66c", "c6c"],
+			["999", "c00", "f60", "fc3", "fc0", "3c0", "0cc", "36f", "63f", "c3c"],
+			["666", "900", "c60", "c93", "990", "090", "399", "33f", "60c", "939"],
+			["333", "600", "930", "963", "660", "060", "366", "009", "339", "636"],
+			["000", "300", "630", "633", "330", "030", "033", "006", "309", "303"]],
+	
+		"3x4": [["ffffff"/*white*/, "00ff00"/*lime*/, "008000"/*green*/, "0000ff"/*blue*/],
+			["c0c0c0"/*silver*/, "ffff00"/*yellow*/, "ff00ff"/*fuchsia*/, "000080"/*navy*/],
+			["808080"/*gray*/, "ff0000"/*red*/, "800080"/*purple*/, "000000"/*black*/]]
+			//["00ffff"/*aqua*/, "808000"/*olive*/, "800000"/*maroon*/, "008080"/*teal*/]];
+	},
+
+	buildRendering: function () {
+		this.domNode = document.createElement("table");
+//		dojo.body().appendChild(this.domNode);
+		dojo.html.disableSelection(this.domNode);
+		dojo.event.connect(this.domNode, "onmousedown", function (e) {
+			e.preventDefault();
+		});
+		with (this.domNode) { // set the table's properties
+			cellPadding = "0"; cellSpacing = "1"; border = "1";
+			style.backgroundColor = "white"; //style.position = "absolute";
+		}
+		var colors = this.palettes[this.palette];
+		for (var i = 0; i < colors.length; i++) {
+			var tr = this.domNode.insertRow(-1);
+			for (var j = 0; j < colors[i].length; j++) {
+				if (colors[i][j].length == 3) {
+					colors[i][j] = colors[i][j].replace(/(.)(.)(.)/, "$1$1$2$2$3$3");
+				}
+	
+				var td = tr.insertCell(-1);
+				with (td.style) {
+					backgroundColor = "#" + colors[i][j];
+					border = "1px solid gray";
+					width = height = "15px";
+					fontSize = "1px";
+				}
+	
+				td.color = "#" + colors[i][j];
+	
+				td.onmouseover = function (e) { this.style.borderColor = "white"; }
+				td.onmouseout = function (e) { this.style.borderColor = "gray"; }
+				dojo.event.connect(td, "onmousedown", this, "click");
+	
+				td.innerHTML = "&nbsp;";
+			}
+		}
+
+		if(dojo.render.html.ie){
+			this.bgIframe = document.createElement("<iframe frameborder='0' src='javascript:void(0);'>");
+			with(this.bgIframe.style){
+				position = "absolute";
+				left = top = "0px";
+				display = "none";
+			}
+			dojo.body().appendChild(this.bgIframe);
+			dojo.html.setOpacity(this.bgIframe, 0);
+		}
+	},
+
+	click: function (e) {
+		this.onColorSelect(e.currentTarget.color);
+		e.currentTarget.style.borderColor = "gray";
+	},
+
+	onColorSelect: function (color) { },
+
+	hide: function (){
+		this.domNode.parentNode.removeChild(this.domNode);
+		if(this.bgIframe){
+			this.bgIframe.style.display = "none";
+		}
+	},
+	
+	showAt: function (x, y) {
+		with(this.domNode.style){
+			top = y + "px";
+			left = x + "px";
+			zIndex = 999;
+		}
+		dojo.body().appendChild(this.domNode);
+		if(this.bgIframe){
+			with(this.bgIframe.style){
+				display = "block";
+				top = y + "px";
+				left = x + "px";
+				zIndex = 998;
+				var s = dojo.html.getMarginBox(this.domNode);
+				width = s.width + "px";
+				height = s.height + "px";
+			}
+
+		}
+	}
+});

Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/ColorPalette.js
------------------------------------------------------------------------------
    svn:eol-style = native