From e44a7e37b6c7b5961adaffc62b9042b8d442938e Mon Sep 17 00:00:00 2001
From: mensonge
Date: Thu, 13 Nov 2008 09:49:11 +0000
Subject: New feature: basic Ajax suggestion for tags and implementation of
Dojo toolkit
git-svn-id: https://semanticscuttle.svn.sourceforge.net/svnroot/semanticscuttle/trunk@151 b3834d28-1941-0410-a4f8-b48e95affb8f
---
includes/js/dojox/form/CheckedMultiSelect.js | 223 ++++++++++++++++
includes/js/dojox/form/DropDownSelect.js | 267 ++++++++++++++++++++
includes/js/dojox/form/PasswordValidator.js | 280 +++++++++++++++++++++
includes/js/dojox/form/README | 39 +++
includes/js/dojox/form/nls/PasswordValidator.js | 1 +
.../js/dojox/form/resources/CheckedMultiSelect.css | 65 +++++
.../resources/CheckedMultiSelect.css.commented.css | 99 ++++++++
.../dojox/form/resources/CheckedMultiSelect.html | 4 +
.../js/dojox/form/resources/DropDownSelect.css | 137 ++++++++++
.../resources/DropDownSelect.css.commented.css | 209 +++++++++++++++
.../js/dojox/form/resources/PasswordValidator.html | 3 +
.../form/resources/_CheckedMultiSelectItem.html | 4 +
.../dojox/form/tests/test_CheckedMultiSelect.html | 91 +++++++
.../js/dojox/form/tests/test_DropDownSelect.html | 128 ++++++++++
.../dojox/form/tests/test_PasswordValidator.html | 216 ++++++++++++++++
15 files changed, 1766 insertions(+)
create mode 100644 includes/js/dojox/form/CheckedMultiSelect.js
create mode 100644 includes/js/dojox/form/DropDownSelect.js
create mode 100644 includes/js/dojox/form/PasswordValidator.js
create mode 100644 includes/js/dojox/form/README
create mode 100644 includes/js/dojox/form/nls/PasswordValidator.js
create mode 100644 includes/js/dojox/form/resources/CheckedMultiSelect.css
create mode 100644 includes/js/dojox/form/resources/CheckedMultiSelect.css.commented.css
create mode 100644 includes/js/dojox/form/resources/CheckedMultiSelect.html
create mode 100644 includes/js/dojox/form/resources/DropDownSelect.css
create mode 100644 includes/js/dojox/form/resources/DropDownSelect.css.commented.css
create mode 100644 includes/js/dojox/form/resources/PasswordValidator.html
create mode 100644 includes/js/dojox/form/resources/_CheckedMultiSelectItem.html
create mode 100644 includes/js/dojox/form/tests/test_CheckedMultiSelect.html
create mode 100644 includes/js/dojox/form/tests/test_DropDownSelect.html
create mode 100644 includes/js/dojox/form/tests/test_PasswordValidator.html
(limited to 'includes/js/dojox/form')
diff --git a/includes/js/dojox/form/CheckedMultiSelect.js b/includes/js/dojox/form/CheckedMultiSelect.js
new file mode 100644
index 0000000..eb80c72
--- /dev/null
+++ b/includes/js/dojox/form/CheckedMultiSelect.js
@@ -0,0 +1,223 @@
+if(!dojo._hasResource["dojox.form.CheckedMultiSelect"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.form.CheckedMultiSelect"] = true;
+dojo.provide("dojox.form.CheckedMultiSelect");
+
+dojo.require("dijit.form.MultiSelect");
+dojo.require("dijit.form.CheckBox");
+
+dojo.declare("dojox.form._CheckedMultiSelectItem",
+ [dijit._Widget, dijit._Templated],
+ {
+ // summary:
+ // The individual items for a CheckedMultiSelect
+
+ widgetsInTemplate: true,
+ templateString:"
\n",
+
+ baseClass: "dojoxMultiSelectItem",
+
+ // option: Element
+ // The option that is associated with this item
+ option: null,
+ parent: null,
+
+ // disabled: boolean
+ // Whether or not this widget is disabled
+ disabled: false,
+
+ _changeBox: function(){
+ // summary:
+ // Called to force the select to match the state of the check box
+ // (only on click of the checkbox)
+ this.option.selected = this.checkBox.getValue() && true;
+
+ // fire the parent's change
+ this.parent._onChange();
+
+ // refocus the parent
+ this.parent.focus();
+ },
+
+ _labelClick: function(){
+ // summary:
+ // Called when the label portion is clicked
+ dojo.stopEvent(e);
+ if(this.disabled){
+ return;
+ }
+ var cb = this.checkBox;
+ cb.setValue(!cb.getValue());
+ this._changeBox();
+ },
+
+ _onMouse: function(e){
+ // summary:
+ // Sets the hover state depending on mouse state (passes through
+ // to the check box)
+ this.checkBox._onMouse(e);
+ },
+
+ _onClick: function(e){
+ // summary:
+ // Sets the click state (passes through to the check box)
+ this.checkBox._onClick(e);
+ },
+
+ _updateBox: function(){
+ // summary:
+ // Called to force the box to match the state of the select
+ this.checkBox.setValue(this.option.selected);
+ },
+
+ setAttribute: function(attr, value){
+ // summary:
+ // Disables (or enables) all the children as well
+ this.inherited(arguments);
+ switch(attr){
+ case "disabled":
+ this.checkBox.setAttribute(attr, value);
+ break;
+ default:
+ break;
+ }
+ }
+});
+
+dojo.declare("dojox.form.CheckedMultiSelect", dijit.form.MultiSelect, {
+ // summary:
+ // Extends the core dijit MultiSelect to provide a "checkbox" selector
+
+ templateString: "",
+ templateString:"\n",
+
+ baseClass: "dojoxMultiSelect",
+
+ // children: dojox.form._CheckedMultiSelectItem[]
+ // Array of all our children (for updating them)
+ children: [],
+
+ /*=====
+ dojox.form.__SelectOption = function(){
+ // value: String
+ // The value of the option. Setting to empty (or missing) will
+ // place a separator at that location
+ // label: String
+ // The label for our option. It can contain html tags.
+ this.value = value;
+ this.label = label;
+ }
+ =====*/
+
+ // options: dojox.form.__SelectOption[]
+ // our set of options
+ options: null,
+
+ _mouseDown: function(e){
+ // summary:
+ // Cancels the mousedown event to prevent others from stealing
+ // focus
+ dojo.stopEvent(e);
+ },
+
+ _updateChildren: function(){
+ // summary:
+ // Called to update the checked states of my children to match me
+ dojo.forEach(this.children,function(child){
+ child._updateBox();
+ });
+ },
+
+ _addChild: function(/*Element*/ option){
+ // summary:
+ // Adds and returns a child for the given option.
+ var item = new dojox.form._CheckedMultiSelectItem({
+ option: option,
+ parent: this
+ });
+ this.wrapperDiv.appendChild(item.domNode);
+ return item;
+ },
+
+ _loadChildren: function(){
+ // summary:
+ // Reloads the children to match our box.
+
+ // Destroy any existing children before loading them again
+ dojo.forEach(this.children, function(child){
+ child.destroyRecursive();
+ });
+ this.children = dojo.query("option", this.domNode).map(function(child){
+ return this._addChild(child);
+ }, this);
+ this.options = dojo.map(this.children, function(child){
+ var opt = child.option;
+ return { value:opt.value, label: opt.text };
+ });
+ // Update the statuses of the children
+ this._updateChildren();
+ },
+
+ addOption: function(/* dojox.form.__SelectOption or string, optional */ value, /* string? */ label){
+ // summary: Adds the given option to the select
+
+ var o = new Option("","");
+ o.value = value.value || value;
+ o.innerHTML = value.label || label;
+ this.containerNode.appendChild(o);
+ },
+
+ removeOption: function(/*String*/ optionId){
+ dojo.query("option[value=" + optionId + "]", this.domNode).forEach(function(node){
+ node.parentNode.removeChild(node);
+ }, this);
+ },
+
+ setOptionLabel: function(/*string*/ optionId, /*string*/ label){
+ dojo.query("option[value=" + optionId + "]", this.domNode).forEach(function(node){
+ node.innerHTML = label;
+ });
+ },
+
+ addSelected: function(select){
+ this.inherited(arguments);
+
+ // Reload my children and the children of the guy pointing to me
+ if(select._loadChildren){
+ select._loadChildren();
+ }
+ this._loadChildren();
+ },
+
+ setAttribute: function(attr, value){
+ // summary:
+ // Disable (or enable) all the children as well
+ this.inherited(arguments);
+ switch(attr){
+ case "disabled":
+ dojo.forEach(this.children, function(node){
+ if(node && node.setAttribute){
+ node.setAttribute(attr, value);
+ }
+ });
+ break;
+ default:
+ break;
+ }
+ },
+
+ startup: function(){
+ if(this._started){ return; }
+ this.inherited(arguments);
+
+ // Load children and make connections
+ this._loadChildren();
+ this.connect(this, "setValue", "_updateChildren");
+ this.connect(this, "invertSelection", "_updateChildren");
+ this.connect(this, "addOption", "_loadChildren");
+ this.connect(this, "removeOption", "_loadChildren");
+ this.connect(this, "setOptionLabel", "_loadChildren");
+ this._started = true;
+ }
+});
+
+}
diff --git a/includes/js/dojox/form/DropDownSelect.js b/includes/js/dojox/form/DropDownSelect.js
new file mode 100644
index 0000000..94d26d1
--- /dev/null
+++ b/includes/js/dojox/form/DropDownSelect.js
@@ -0,0 +1,267 @@
+if(!dojo._hasResource["dojox.form.DropDownSelect"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.form.DropDownSelect"] = true;
+dojo.provide("dojox.form.DropDownSelect");
+
+dojo.require("dijit.form.Button");
+dojo.require("dijit.Menu");
+
+dojo.require("dojo.data.ItemFileWriteStore");
+
+dojo.declare("dojox.form.DropDownSelect", dijit.form.DropDownButton, {
+ // summary:
+ // This is a "Styleable" select box - it is basically a DropDownButton which
+ // can take as its input a .
+
+ baseClass: "dojoxDropDownSelect",
+
+ /*=====
+ dojox.form.__SelectOption = function(){
+ // value: String
+ // The value of the option. Setting to empty (or missing) will
+ // place a separator at that location
+ // label: String
+ // The label for our option. It can contain html tags.
+ this.value = value;
+ this.label = label;
+ }
+ =====*/
+
+ // options: dojox.form.__SelectOption[]
+ // our set of options
+ options: null,
+
+ // emptyLabel: string
+ // What to display in an "empty" dropdown
+ emptyLabel: "",
+
+ // _isPopulated: boolean
+ // Whether or not we have been populated
+ _isPopulated: false,
+
+ _addMenuItem: function(/* dojox.form.__SelectOption */ option){
+ // summary:
+ // For the given option, add a menu item to our dropdown
+ // If the option doesn't have a value, then a separator is added
+ // in that place.
+ var menu = this.dropDown;
+
+ if(!option.value){
+ // We are a separator (no label set for it)
+ menu.addChild(new dijit.MenuSeparator());
+ }else{
+ // Just a regular menu option
+ var click = dojo.hitch(this, "setAttribute","value",option);
+ var mi = new dijit.MenuItem({
+ id: this.id + "_item_" + option.value,
+ label: option.label,
+ onClick: click
+ });
+ menu.addChild(mi);
+
+ }
+ },
+
+ _resetButtonState: function(){
+ // summary:
+ // Resets the menu and the length attribute of the button - and
+ // ensures that the label is appropriately set.
+ var len = this.options.length;
+
+ // reset the menu to make it "populatable on the next click
+ var dropDown = this.dropDown;
+ dojo.forEach(dropDown.getChildren(), function(child){
+ child.destroyRecursive();
+ });
+ this._isPopulated = false;
+
+ // Set our length attribute and our value
+ this.setAttribute("readOnly", (len === 1));
+ this.setAttribute("disabled", (len === 0));
+ this.setAttribute("value", this.value);
+ },
+
+ _updateSelectedState: function(){
+ // summary:
+ // Sets the "selected" class on the item for styling purposes
+ var val = this.value;
+ if(val){
+ var testId = this.id + "_item_" + val;
+ dojo.forEach(this.dropDown.getChildren(), function(child){
+ dojo[child.id === testId ? "addClass" : "removeClass"](child.domNode,
+ this.baseClass + "SelectedOption");
+ }, this);
+ }
+ },
+
+ addOption: function(/* dojox.form.__SelectOption or string, optional */ value, /* string? */ label){
+ // summary:
+ // Adds an option to the end of the select. If value is empty or
+ // missing, a separator is created instead.
+
+ this.options.push(value.value ? value : { value:value, label:label });
+ },
+
+ removeOption: function(/* string, dojox.form.__SelectOption or number */ valueOrIdx){
+ // summary:
+ // Removes the given option
+ this.options = dojo.filter(this.options, function(node, idx){
+ return !((typeof valueOrIdx === "number" && idx === valueOrIdx) ||
+ (typeof valueOrIdx === "string" && node.value === valueOrIdx) ||
+ (valueOrIdx.value && node.value === valueOrIdx.value));
+ });
+ },
+
+ setOptionLabel: function(/*string*/ value, /*string*/ label){
+ dojo.forEach(this.options, function(node){
+ if(node.value === value){
+ node.label = label;
+ }
+ });
+ },
+
+ destroy: function(){
+ // summary:
+ // Clear out an outstanding hack handle
+ if(this._labelHackHandle){
+ clearTimeout(this._labelHackHandle);
+ }
+ this.inherited(arguments);
+ },
+
+ setLabel: function(/* string */ content){
+ // summary:
+ // Wraps our label in a div - that way, our rich text can work
+ // correctly.
+
+ content = '' +
+ content +
+ '
';
+ // Because FF2 has a problem with layout, we need to delay this
+ // call for it.
+ if(this._labelHackHandle){
+ clearTimeout(this._labelHackHandle);
+ }
+ if(dojo.isFF === 2){
+ this._labelHackHandle = setTimeout(dojo.hitch(this, function(){
+ this._labelHackHandle = null;
+ dijit.form.DropDownButton.prototype.setLabel.call(this, content);
+ }), 0);
+ }else{
+ this.inherited(arguments);
+ }
+ },
+
+ setAttribute: function(/*string*/ attr, /* anything */ value){
+ // summary: sometime we get called to set our value - we need to
+ // make sure and route those requests through _setValue()
+ // instead.
+ if(attr === "value"){
+ // If a string is passed, then we set our value from looking it up.
+ if(typeof value === "string"){
+ value = dojo.filter(this.options, function(node){
+ return node.value === value;
+ })[0];
+ }
+
+ // If we don't have a value, try to show the first item
+ if(!value){
+ value = this.options[0] || { value: "", label: "" };
+ }
+ this.value = value.value;
+ if(this._started){
+ this.setLabel(value.label || this.emptyLabel || " ");
+ }
+ this._handleOnChange(value.value);
+ value = this.value;
+ }else{
+ this.inherited(arguments);
+ }
+ },
+
+ _fillContent: function(){
+ // summary:
+ // Loads our options and sets up our dropdown correctly. We
+ // don't want any content, so we don't call any inherit chain
+ // function.
+ var opts = this.options;
+ if(!opts){
+ opts = this.options = this.srcNodeRef ? dojo.query(">",
+ this.srcNodeRef).map(function(node){
+ if(node.getAttribute("type") === "separator"){
+ return { value: "", label: "" };
+ }
+ return { value: node.getAttribute("value"),
+ label: String(node.innerHTML) };
+ }, this) : [];
+ }
+
+ // Set the value to be the first, or the selected index
+ if(opts.length && !this.value){
+ var si = this.srcNodeRef.selectedIndex;
+ this.value = opts[si != -1 ? si : 0].value;
+ }
+
+ // Create the dropDown widget
+ this.dropDown = new dijit.Menu();
+ },
+
+ postCreate: function(){
+ // summary: sets up our event handling that we need for functioning
+ // as a select
+
+ this.inherited(arguments);
+
+ // Make our event connections for updating state
+ var fx = function(){
+ dojo[this._opened ? "addClass" : "removeClass"](this.focusNode,
+ this.baseClass + "ButtonOpened");
+ };
+ this.connect(this, "_openDropDown", fx);
+ this.connect(this, "_closeDropDown", fx);
+ this.connect(this, "onChange", "_updateSelectedState");
+ this.connect(this, "addOption", "_resetButtonState");
+ this.connect(this, "removeOption", "_resetButtonState");
+ this.connect(this, "setOptionLabel", "_resetButtonState");
+ },
+
+ startup: function(){
+ // summary:
+ // FF2 has layout problems if the reset call isn't done on a
+ // slight delay
+ this.inherited(arguments);
+ if(dojo.isFF === 2){
+ setTimeout(dojo.hitch(this, this._resetButtonState), 0);
+ }else{
+ this._resetButtonState();
+ }
+ },
+
+ _populate: function(/* function */ callback){
+ // summary:
+ // populates the menu (and does the callback, if passed)
+
+ var dropDown = this.dropDown;
+
+ // Add each menu item
+ dojo.forEach(this.options, this._addMenuItem, this);
+
+ // Update states
+ this._updateSelectedState();
+ dojo.addClass(this.dropDown.domNode, this.baseClass + "Menu");
+ this._isPopulated = true;
+ if(callback){ callback.call(this); }
+ },
+
+ _toggleDropDown: function(){
+ // summary: Overrides DropDownButton's toggle function to make sure
+ // that the values are correctly populated.
+ var dropDown = this.dropDown;
+ if(dropDown && !dropDown.isShowingNow && !this._isPopulated){
+ this._populate(dojox.form.DropDownSelect.superclass._toggleDropDown);
+ }else{
+ this.inherited(arguments);
+ }
+ }
+});
+
+}
diff --git a/includes/js/dojox/form/PasswordValidator.js b/includes/js/dojox/form/PasswordValidator.js
new file mode 100644
index 0000000..e147ddf
--- /dev/null
+++ b/includes/js/dojox/form/PasswordValidator.js
@@ -0,0 +1,280 @@
+if(!dojo._hasResource["dojox.form.PasswordValidator"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.form.PasswordValidator"] = true;
+dojo.provide("dojox.form.PasswordValidator");
+
+dojo.require("dijit.form._FormWidget");
+dojo.require("dijit.form.ValidationTextBox");
+
+dojo.requireLocalization("dojox.form", "PasswordValidator", null, "ROOT");
+
+dojo.declare("dojox.form._ChildTextBox", dijit.form.ValidationTextBox, {
+ // summary:
+ // A class that is shared between all our children - extends
+ // ValidationTextBox and provides some shared functionality
+ //
+ // containerWidget: widget
+ // Our parent (the PasswordValidator)
+ containerWidget: null,
+
+ // type: string
+ // Don't override this - we are all "password" types
+ type: "password",
+
+ reset: function(){
+ // summary:
+ // Force-set to empty string (we don't save passwords EVER)...and
+ // since _OldPWBox overrides setValue to check for empty string,
+ // call our parent class directly (not this.inherited())
+ dijit.form.ValidationTextBox.prototype.setValue.call(this, "", true);
+ this._hasBeenBlurred = false;
+ }
+});
+
+
+
+dojo.declare("dojox.form._OldPWBox", dojox.form._ChildTextBox, {
+ // summary:
+ // A class representing our "old password" box.
+ //
+ // _isPWValid: boolean
+ // Whether or not the password is valid
+ _isPWValid: false,
+
+ setValue: function(/* anything */ newVal, /* boolean? */ priority){
+ // summary:
+ // Updates _isPWValid if this isn't our initial update by calling
+ // our PasswordValidator's pwCheck function
+ if(newVal === ""){
+ newVal = dojox.form._OldPWBox.superclass.getValue.call(this);
+ }
+ if(priority !== null){
+ // Priority is passed in as null, explicitly when this is an
+ // update (not initially set). We want to check our password now.
+ this._isPWValid = this.containerWidget.pwCheck(newVal);
+ }
+ this.inherited("setValue", arguments);
+ },
+
+ isValid: function(/* boolean */ isFocused){
+ // Take into account the isPWValid setting
+ return this.inherited("isValid", arguments) && this._isPWValid;
+ },
+
+ _update: function(/* event */ e){
+ // Only call validate() if we've been blurred or else we get popups
+ // too early.
+ if(this._hasBeenBlurred){ this.validate(true); }
+ this._onMouse(e);
+ },
+
+ getValue: function(){
+ // summary:
+ // Only returns a value if our container widget is valid. This
+ // is to prevent exposure of "oldPW" too early.
+ if(this.containerWidget.isValid()){
+ return this.inherited("getValue", arguments);
+ }else{
+ return "";
+ }
+ }
+});
+
+
+dojo.declare("dojox.form._NewPWBox", dojox.form._ChildTextBox, {
+ // summary:
+ // A class representing our new password textbox
+
+ // required: boolean
+ // Whether or not this widget is required (default: true)
+ required: true,
+
+ onChange: function(){
+ // summary:
+ // Validates our verify box - to make sure that a change to me is
+ // reflected there
+ this.containerWidget._inputWidgets[2].validate(false);
+ this.inherited(arguments);
+ }
+});
+
+dojo.declare("dojox.form._VerifyPWBox", dojox.form._ChildTextBox, {
+ // summary:
+ // A class representing our verify textbox
+
+ isValid: function(isFocused){
+ // summary:
+ // Validates that we match the "real" password
+ return this.inherited("isValid", arguments) &&
+ (this.getValue() == this.containerWidget._inputWidgets[1].getValue());
+ }
+});
+
+dojo.declare("dojox.form.PasswordValidator", dijit.form._FormValueWidget, {
+ // summary:
+ // A password validation widget that simplifies the "old/new/verify"
+ // style of requesting passwords. You will probably want to override
+ // this class and implement your own pwCheck function.
+ //
+ // required: boolean
+ // Whether or not it is required for form submission
+ required: true,
+
+ // inputWidgets: TextBox[]
+ // An array of text boxes that are our components
+ _inputWidgets: null,
+
+ // oldName: string?
+ // The name to send our old password as (when form is posted)
+ oldName: "",
+
+ templateString:"\n\t \n
\n",
+
+ _hasBeenBlurred: false,
+
+ isValid: function(/* boolean */ isFocused){
+ // summary: we are valid if ALL our children are valid
+ return dojo.every(this._inputWidgets, function(i){
+ if(i && i._setStateClass){ i._setStateClass(); }
+ return (!i || i.isValid());
+ });
+ },
+
+ validate: function(/* boolean */ isFocused){
+ // summary: Validating this widget validates all our children
+ return dojo.every(dojo.map(this._inputWidgets, function(i){
+ if(i && i.validate){
+ i._hasBeenBlurred = (i._hasBeenBlurred || this._hasBeenBlurred);
+ return i.validate();
+ }
+ return true;
+ }, this), "return item;");
+ },
+
+ reset: function(){
+ // summary: Resetting this widget resets all our children
+ this._hasBeenBlurred = false;
+ dojo.forEach(this._inputWidgets, function(i){
+ if(i && i.reset){ i.reset(); }
+ }, this);
+ },
+
+ _createSubWidgets: function(){
+ // summary:
+ // Turns the inputs inside this widget into "real" validation
+ // widgets - and sets up the needed connections.
+ var widgets = this._inputWidgets,
+ msg = dojo.i18n.getLocalization("dojox.form", "PasswordValidator",
+ this.lang);
+ dojo.forEach(widgets, function(i, idx){
+ if(i){
+ var p = {containerWidget: this}, c;
+ if(idx === 0){
+ p.name = this.oldName;
+ p.invalidMessage = msg.badPasswordMessage;
+ c = dojox.form._OldPWBox;
+ }else if(idx === 1){
+ p.required = this.required;
+ c = dojox.form._NewPWBox;
+ }else if(idx === 2){
+ p.invalidMessage = msg.nomatchMessage;
+ c = dojox.form._VerifyPWBox;
+ }
+ widgets[idx] = new c(p, i);
+ }
+ }, this);
+ },
+
+ pwCheck: function(/* string */ password){
+ // summary:
+ // Overridable function for validation of the old password box.
+ //
+ // This function is called and passed the old password. Return
+ // true if it's OK to continue, and false if it is not.
+ //
+ // IMPORTANT SECURITY NOTE: Do NOT EVER EVER EVER check this in
+ // HTML or JavaScript!!!
+ //
+ // You will probably want to override this function to callback
+ // to a server to verify the password (the callback will need to
+ // be syncronous) - and it's probably a good idea to validate
+ // it again on form submission before actually doing
+ // anything destructive - that's why the "oldName" value
+ // is available.
+ //
+ // And don't just fetch the password from the server
+ // either :) Send the test password (probably hashed, for
+ // security) and return from the server a status instead.
+ //
+ // Again - DON'T BE INSECURE!!! Security is left as an exercise
+ // for the reader :)
+ return false;
+ },
+
+ postCreate: function(){
+ // summary:
+ // Sets up the correct widgets. You *MUST* specify one child
+ // text box (a simple HTML element) with pwType="new"
+ // *and* one child text box with pwType="verify". You *MAY*
+ // specify a third child text box with pwType="old" in order to
+ // prompt the user to enter in their old password before the
+ // widget returns that it is valid.
+
+ this.inherited(arguments);
+
+ // Turn my inputs into the correct stuff....
+ var widgets = this._inputWidgets = [];
+ dojo.forEach(["old","new","verify"], function(i){
+ widgets.push(dojo.query("input[pwType=" + i + "]",
+ this.containerNode)[0]);
+ }, this);
+ if (!widgets[1] || !widgets[2]){
+ throw new Error("Need at least pwType=\"new\" and pwType=\"verify\"");
+ }
+ if (this.oldName && !widgets[0]){
+ throw new Error("Need to specify pwType=\"old\" if using oldName");
+ }
+ this._createSubWidgets();
+ },
+
+ setAttribute: function(/* string */ attr, /* anything */ value){
+ this.inherited(arguments);
+
+ // Disabling (or enabling) the container disables (or enables) all
+ // the subwidgets as well - same for requiring
+ switch(attr){
+ case "disabled":
+ case "required":
+ dojo.forEach(this._inputWidgets, function(i){
+ if(i && i.setAttribute){ i.setAttribute(attr, value);}
+ });
+ break;
+ default:
+ break;
+ }
+ },
+
+ getValue: function(){
+ // summary: overridden to return an empty string if we aren't valid.
+ if (this.isValid()){
+ return this._inputWidgets[1].getValue();
+ }else{
+ return "";
+ }
+ },
+
+ focus: function(){
+ // summary:
+ // places focus on the first invalid input widget - if all
+ // input widgets are valid, the first widget is focused.
+ var f = false;
+ dojo.forEach(this._inputWidgets, function(i){
+ if(i && !i.isValid() && !f){
+ i.focus();
+ f = true;
+ }
+ });
+ if(!f){ this._inputWidgets[1].focus(); }
+ }
+});
+
+}
diff --git a/includes/js/dojox/form/README b/includes/js/dojox/form/README
new file mode 100644
index 0000000..3fc4f7c
--- /dev/null
+++ b/includes/js/dojox/form/README
@@ -0,0 +1,39 @@
+-------------------------------------------------------------------------------
+dojox.form Collection
+-------------------------------------------------------------------------------
+Version 1.0
+Release date: 02/26/2008
+-------------------------------------------------------------------------------
+Project state:
+experimental
+-------------------------------------------------------------------------------
+Credits
+ Nathan Toone (nathan)
+
+-------------------------------------------------------------------------------
+Project description
+
+ This is a collection of additional widgets that can be used in forms.
+-------------------------------------------------------------------------------
+Dependencies:
+
+ Depends on dojo core and dijit
+-------------------------------------------------------------------------------
+Documentation
+
+-------------------------------------------------------------------------------
+Installation instructions
+
+ Install into /dojox/form
+-------------------------------------------------------------------------------
+Additional Notes (Brief widget list):
+
+ * CheckedMultiSelect - an extension to dijit.form.MultiSelect which
+ uses check boxes instead of ctrl-click
+
+ * PasswordValidator - a widget which simplifies the common "old/new/verify"
+ mechanism of specifying passwords
+
+ * DropDownSelect - an extension to dijit.form.DropDownButton which is
+ meant to mirror the html drop down
+
diff --git a/includes/js/dojox/form/nls/PasswordValidator.js b/includes/js/dojox/form/nls/PasswordValidator.js
new file mode 100644
index 0000000..4887d27
--- /dev/null
+++ b/includes/js/dojox/form/nls/PasswordValidator.js
@@ -0,0 +1 @@
+({"badPasswordMessage":"Invalid Password.","nomatchMessage":"Passwords do not match."})
\ No newline at end of file
diff --git a/includes/js/dojox/form/resources/CheckedMultiSelect.css b/includes/js/dojox/form/resources/CheckedMultiSelect.css
new file mode 100644
index 0000000..1953b1e
--- /dev/null
+++ b/includes/js/dojox/form/resources/CheckedMultiSelect.css
@@ -0,0 +1,65 @@
+
+.dojoxMultiSelectSelect { display: none; }
+.dojoxMultiSelect {
+ border: solid black 1px;
+ margin: 1px 0;
+ overflow: scroll;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ height: 100px;
+}
+.dj_ie .dojoxMultiSelect,
+.dj_safari .dojoxMultiSelect {
+
+ padding-right: 15px;
+}
+.dojoxMultiSelectItem {
+ white-space: nowrap;
+ padding:.1em .2em;
+ cursor:default;
+}
+.dojoxMultiSelectDisabled * {
+ color:gray !important;
+}
+.dojoxMultiSelectItemLabel {
+ margin-left: .2em;
+}
+.tundra .dojoxMultiSelect {
+ margin: 0em 0.1em;
+}
+.tundra .dojoxMultiSelect {
+ background:#fff url("../../../dijit/themes/tundra/images/validationInputBg.png") repeat-x top left;
+ #background:#fff url('../../../dijit/themes/tundra/images/validationInputBg.gif') repeat-x top left;
+ border:1px solid #b3b3b3;
+ line-height: normal;
+}
+.tundra .dojoxMultiSelectFocused {
+
+ border-color:#406b9b;
+}
+.soria .dojoxMultiSelect {
+ margin: 0em 0.1em;
+}
+.soria .dojoxMultiSelect {
+ background:#fff url("../../../dijit/themes/soria/images/validationInputBg.png") repeat-x top left;
+ #background:#fff url('../../../dijit/themes/soria/images/validationInputBg.gif') repeat-x top left;
+ border:1px solid #8ba0bd;
+ line-height: normal;
+}
+.soria .dojoxMultiSelectFocused {
+
+ border-color:#406b9b;
+}
+.nihilo .dojoxMultiSelect {
+ margin: 0em 0.1em;
+}
+.nihilo .dojoxMultiSelect {
+ background:#fff url("../../../dijit/themes/nihilo/images/validationInputBg.png") repeat-x top left;
+ #background:#fff url('../../../dijit/themes/nihilo/images/validationInputBg.gif') repeat-x top left;
+ border:1px solid #d3d3d3;
+ line-height: normal;
+}
+.nihilo .dojoxMultiSelectFocused {
+
+ border-color:#b3b3b3;
+}
diff --git a/includes/js/dojox/form/resources/CheckedMultiSelect.css.commented.css b/includes/js/dojox/form/resources/CheckedMultiSelect.css.commented.css
new file mode 100644
index 0000000..32cd0b5
--- /dev/null
+++ b/includes/js/dojox/form/resources/CheckedMultiSelect.css.commented.css
@@ -0,0 +1,99 @@
+/*
+**----------------------------------------------------------------------------
+** CheckedMultiSelect
+**----------------------------------------------------------------------------
+*/
+.dojoxMultiSelectSelect { display: none; }
+
+.dojoxMultiSelect {
+ border: solid black 1px;
+ margin: 1px 0;
+ overflow: scroll;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ height: 100px;
+}
+
+.dj_ie .dojoxMultiSelect,
+.dj_safari .dojoxMultiSelect {
+ /* So that the scroll bar doesn't cover stuff up */
+ padding-right: 15px;
+}
+
+.dojoxMultiSelectItem {
+ white-space: nowrap;
+ padding:.1em .2em;
+ cursor:default;
+}
+
+.dojoxMultiSelectDisabled * {
+ color:gray !important;
+}
+
+.dojoxMultiSelectItemLabel {
+ margin-left: .2em;
+}
+
+/*
+**----------------------------------------------------------------------------
+** Tundra theme (make look similar to text box)
+**----------------------------------------------------------------------------
+*/
+.tundra .dojoxMultiSelect {
+ margin: 0em 0.1em;
+}
+
+.tundra .dojoxMultiSelect {
+ background:#fff url("../../../dijit/themes/tundra/images/validationInputBg.png") repeat-x top left;
+ #background:#fff url('../../../dijit/themes/tundra/images/validationInputBg.gif') repeat-x top left;
+ border:1px solid #b3b3b3;
+ line-height: normal;
+}
+
+.tundra .dojoxMultiSelectFocused {
+ /* input field when focused (ie: typing affects it) */
+ border-color:#406b9b;
+}
+
+/*
+**----------------------------------------------------------------------------
+** Soria theme (make look similar to text box)
+**----------------------------------------------------------------------------
+*/
+.soria .dojoxMultiSelect {
+ margin: 0em 0.1em;
+}
+
+.soria .dojoxMultiSelect {
+ background:#fff url("../../../dijit/themes/soria/images/validationInputBg.png") repeat-x top left;
+ #background:#fff url('../../../dijit/themes/soria/images/validationInputBg.gif') repeat-x top left;
+ border:1px solid #8ba0bd;
+ line-height: normal;
+}
+
+.soria .dojoxMultiSelectFocused {
+ /* input field when focused (ie: typing affects it) */
+ border-color:#406b9b;
+}
+
+/*
+**----------------------------------------------------------------------------
+** Nihilo theme (make look similar to text box)
+**----------------------------------------------------------------------------
+*/
+.nihilo .dojoxMultiSelect {
+ margin: 0em 0.1em;
+}
+
+.nihilo .dojoxMultiSelect {
+ background:#fff url("../../../dijit/themes/nihilo/images/validationInputBg.png") repeat-x top left;
+ #background:#fff url('../../../dijit/themes/nihilo/images/validationInputBg.gif') repeat-x top left;
+ border:1px solid #d3d3d3;
+ line-height: normal;
+}
+
+.nihilo .dojoxMultiSelectFocused {
+ /* input field when focused (ie: typing affects it) */
+ border-color:#b3b3b3;
+}
+
diff --git a/includes/js/dojox/form/resources/CheckedMultiSelect.html b/includes/js/dojox/form/resources/CheckedMultiSelect.html
new file mode 100644
index 0000000..256aad7
--- /dev/null
+++ b/includes/js/dojox/form/resources/CheckedMultiSelect.html
@@ -0,0 +1,4 @@
+
\ No newline at end of file
diff --git a/includes/js/dojox/form/resources/DropDownSelect.css b/includes/js/dojox/form/resources/DropDownSelect.css
new file mode 100644
index 0000000..cbd1971
--- /dev/null
+++ b/includes/js/dojox/form/resources/DropDownSelect.css
@@ -0,0 +1,137 @@
+
+.dojoxDropDownSelect {
+ margin: 0.2em;
+}
+.dijit_a11y .dojoxDropDownSelectDisabled .dijitButtonNode {
+ border-style: dotted !important;
+ border-color: #999 !important;
+ color:#999 !important;
+}
+.dojoxDropDownSelect .dijitButtonNode {
+ padding: 0px;
+}
+.dijitButtonNode .dojoxDropDownSelectLabel *
+{
+ vertical-align: baseline;
+}
+.dojoxDropDownSelectSelectedOption * {
+ font-weight: bold;
+}
+.dojoxDropDownSelectDisabled .dijitArrowButtonInner,
+.dojoxDropDownSelectReadOnly .dijitArrowButtonInner {
+ display: none;
+}
+.dojoxDropDownSelectMenu .dijitMenuItemIcon {
+ width: 1px;
+}
+.tundra .dojoxDropDownSelectDisabled * {
+ cursor: not-allowed !important;
+}
+.tundra .dojoxDropDownSelectReadOnly * {
+ cursor: default !important;
+}
+.tundra .dojoxDropDownSelectDisabled * {
+ cursor: not-allowed !important;
+}
+.tundra .dojoxDropDownSelectReadOnly * {
+ cursor: default !important;
+}
+.tundra .dojoxDropDownSelect .dijitButtonNode {
+ background:#fff url("../../../dijit/themes/tundra/images/validationInputBg.png") repeat-x top left;
+ #background:#fff url('../../../dijit/themes/tundra/images/validationInputBg.gif') repeat-x top left;
+ border:1px solid #b3b3b3;
+ line-height: normal;
+}
+.tundra .dojoxDropDownSelectDisabled .dijitButtonNode {
+
+ border-color: #d5d5d5 #bdbdbd #bdbdbd #d5d5d5;
+
+ background:#e4e4e4 url("../../../dijit/themes/tundra/images/buttonDisabled.png") top repeat-x;
+ opacity: 0.60;
+}
+.dj_ie .tundra .dojoxDropDownSelectDisabled .dijitButtonNode * {
+ filter: gray() alpha(opacity=50);
+}
+.tundra .dojoxDropDownSelectHover .dijitButtonNode,
+.tundra .dojoxDropDownSelect .dojoxDropDownSelectButtonOpened {
+
+
+ border-color:#a5beda;
+ border-bottom-color:#5c7590;
+ border-right-color:#5c7590;
+ color:#000;
+ background:#fcfdff url("../../../dijit/themes/tundra/images/buttonHover.png") repeat-x bottom;
+}
+.tundra .dojoxDropDownSelectActive .dijitButtonNode {
+
+ border-color:#366dba;
+ background: #ededed url("../../../dijit/themes/tundra/images/buttonActive.png") bottom repeat-x;
+}
+.soria .dojoxDropDownSelectDisabled * {
+ cursor: not-allowed !important;
+}
+.soria .dojoxDropDownSelectReadOnly * {
+ cursor: default !important;
+}
+.soria .dojoxDropDownSelect .dijitButtonNode {
+ background:#fff url("../../../dijit/themes/soria/images/validationInputBg.png") repeat-x top left;
+ #background:#fff url('../../../dijit/themes/soria/images/validationInputBg.gif') repeat-x top left;
+ border:1px solid #8ba0bd;
+ line-height: normal;
+}
+.soria .dojoxDropDownSelectDisabled .dijitButtonNode {
+
+ border-color: #b9bbdd #b9bbdd #b9bbdd #b9bbdd;
+
+ background:#c3d3e5 url("../../../dijit/themes/soria/images/buttonDisabled.png") top repeat-x;
+ opacity: 0.60;
+}
+.dj_ie .soria .dojoxDropDownSelectDisabled .dijitButtonNode * {
+ filter: gray() alpha(opacity=50);
+}
+.soria .dojoxDropDownSelectHover .dijitButtonNode,
+.soria .dojoxDropDownSelect .dojoxDropDownSelectButtonOpened {
+
+
+ color:#000;
+ background:#acc5e2 url("../../../dijit/themes/soria/images/buttonHover.png") repeat-x top left;
+}
+.soria .dojoxDropDownSelectActive .dijitButtonNode {
+
+ border-color:#657c9c;
+ background: #91b4e5 url("../../../dijit/themes/soria/images/buttonActive.png") top left repeat-x;
+}
+.nihilo .dojoxDropDownSelectDisabled * {
+ cursor: not-allowed !important;
+}
+.nihilo .dojoxDropDownSelectReadOnly * {
+ cursor: default !important;
+}
+.nihilo .dojoxDropDownSelect .dijitButtonNode {
+ background:#fff url("../../../dijit/themes/nihilo/images/validationInputBg.png") repeat-x top left;
+ #background:#fff url('../../../dijit/themes/nihilo/images/validationInputBg.gif') repeat-x top left;
+ border:1px solid #d3d3d3;
+ line-height: normal;
+}
+.nihilo .dojoxDropDownSelectDisabled .dijitButtonNode {
+
+ border-color: #dedede;
+
+ background:#fafafa url("../../../dijit/themes/nihilo/images/buttonDisabled.png") top repeat-x;
+ opacity: 0.60;
+}
+.dj_ie .nihilo .dojoxDropDownSelectDisabled .dijitButtonNode * {
+ filter: gray() alpha(opacity=50);
+}
+.nihilo .dojoxDropDownSelectHover .dijitButtonNode,
+.nihilo .dojoxDropDownSelect .dojoxDropDownSelectButtonOpened {
+
+
+ color:#000;
+ background:#fcfcfc url("../../../dijit/themes/nihilo/images/buttonHover.png") repeat-x top left;
+}
+.nihilo .dojoxDropDownSelectActive .dijitButtonNode {
+
+ border-color:#dedede;
+ background: #f5f5f5 url("../../../dijit/themes/nihilo/images/buttonActive.png") top left repeat-x;
+}
diff --git a/includes/js/dojox/form/resources/DropDownSelect.css.commented.css b/includes/js/dojox/form/resources/DropDownSelect.css.commented.css
new file mode 100644
index 0000000..a0a0636
--- /dev/null
+++ b/includes/js/dojox/form/resources/DropDownSelect.css.commented.css
@@ -0,0 +1,209 @@
+/*
+**----------------------------------------------------------------------------
+** DropDownSelect
+**----------------------------------------------------------------------------
+*/
+/* Mirror dijitDropDownButton a bit */
+.dojoxDropDownSelect {
+ margin: 0.2em;
+}
+.dijit_a11y .dojoxDropDownSelectDisabled .dijitButtonNode {
+ border-style: dotted !important;
+ border-color: #999 !important;
+ color:#999 !important;
+}
+
+/* And remove the padding - so it looks a "bit" more like a text box */
+.dojoxDropDownSelect .dijitButtonNode {
+ padding: 0px;
+}
+
+/* Fix the baseline of our label (for multi-size font elements) */
+.dijitButtonNode .dojoxDropDownSelectLabel *
+{
+ vertical-align: baseline;
+}
+
+/* Styling for the currently-selected option (rich text can mess this up) */
+.dojoxDropDownSelectSelectedOption * {
+ font-weight: bold;
+}
+
+/* And remove the arrow when we are read-only or disabled (1 or 0 options) */
+.dojoxDropDownSelectDisabled .dijitArrowButtonInner,
+.dojoxDropDownSelectReadOnly .dijitArrowButtonInner {
+ display: none;
+}
+
+/* And hide (at least, mostly) the menuItemIcon column */
+.dojoxDropDownSelectMenu .dijitMenuItemIcon {
+ width: 1px;
+}
+
+/*
+**----------------------------------------------------------------------------
+** Common stylings
+**----------------------------------------------------------------------------
+*/
+/* Cursor States */
+.tundra .dojoxDropDownSelectDisabled * {
+ cursor: not-allowed !important;
+}
+.tundra .dojoxDropDownSelectReadOnly * {
+ cursor: default !important;
+}
+
+
+/*
+**----------------------------------------------------------------------------
+** Tundra stylings
+**----------------------------------------------------------------------------
+*/
+/* Cursor States */
+.tundra .dojoxDropDownSelectDisabled * {
+ cursor: not-allowed !important;
+}
+.tundra .dojoxDropDownSelectReadOnly * {
+ cursor: default !important;
+}
+
+/* Make unselected "look" more like a text box and less like a button */
+.tundra .dojoxDropDownSelect .dijitButtonNode {
+ background:#fff url("../../../dijit/themes/tundra/images/validationInputBg.png") repeat-x top left;
+ #background:#fff url('../../../dijit/themes/tundra/images/validationInputBg.gif') repeat-x top left;
+ border:1px solid #b3b3b3;
+ line-height: normal;
+}
+
+/* Mirror DropDownButton */
+.tundra .dojoxDropDownSelectDisabled .dijitButtonNode {
+ /* disabled state - inner */
+ border-color: #d5d5d5 #bdbdbd #bdbdbd #d5d5d5;
+ /*color:#b4b4b4;*/
+ background:#e4e4e4 url("../../../dijit/themes/tundra/images/buttonDisabled.png") top repeat-x;
+ opacity: 0.60; /* Safari, Opera and Mozilla */
+}
+
+.dj_ie .tundra .dojoxDropDownSelectDisabled .dijitButtonNode * {
+ filter: gray() alpha(opacity=50); /* IE */
+}
+
+.tundra .dojoxDropDownSelectHover .dijitButtonNode,
+.tundra .dojoxDropDownSelect .dojoxDropDownSelectButtonOpened {
+ /* hover and opened state - inner */
+ /* TODO: change from Hover to Selected so that button is still highlighted while drop down is being used */
+ border-color:#a5beda;
+ border-bottom-color:#5c7590;
+ border-right-color:#5c7590;
+ color:#000;
+ background:#fcfdff url("../../../dijit/themes/tundra/images/buttonHover.png") repeat-x bottom;
+}
+
+.tundra .dojoxDropDownSelectActive .dijitButtonNode {
+ /* active state - inner (for when you are pressing a normal button, or
+ * when a toggle button is in a depressed state
+ */
+ border-color:#366dba;
+ background: #ededed url("../../../dijit/themes/tundra/images/buttonActive.png") bottom repeat-x;
+}
+
+
+/*
+**----------------------------------------------------------------------------
+** Soria stylings
+**----------------------------------------------------------------------------
+*/
+/* Cursor States */
+.soria .dojoxDropDownSelectDisabled * {
+ cursor: not-allowed !important;
+}
+.soria .dojoxDropDownSelectReadOnly * {
+ cursor: default !important;
+}
+
+/* Make unselected "look" more like a text box and less like a button */
+.soria .dojoxDropDownSelect .dijitButtonNode {
+ background:#fff url("../../../dijit/themes/soria/images/validationInputBg.png") repeat-x top left;
+ #background:#fff url('../../../dijit/themes/soria/images/validationInputBg.gif') repeat-x top left;
+ border:1px solid #8ba0bd;
+ line-height: normal;
+}
+
+/* Mirror DropDownButton */
+.soria .dojoxDropDownSelectDisabled .dijitButtonNode {
+ /* disabled state - inner */
+ border-color: #b9bbdd #b9bbdd #b9bbdd #b9bbdd;
+ /*color:#b4b4b4;*/
+ background:#c3d3e5 url("../../../dijit/themes/soria/images/buttonDisabled.png") top repeat-x;
+ opacity: 0.60; /* Safari, Opera and Mozilla */
+}
+
+.dj_ie .soria .dojoxDropDownSelectDisabled .dijitButtonNode * {
+ filter: gray() alpha(opacity=50); /* IE */
+}
+
+.soria .dojoxDropDownSelectHover .dijitButtonNode,
+.soria .dojoxDropDownSelect .dojoxDropDownSelectButtonOpened {
+ /* hover state - inner */
+ /* TODO: change from Hover to Selected so that button is still highlighted while drop down is being used */
+ color:#000;
+ background:#acc5e2 url("../../../dijit/themes/soria/images/buttonHover.png") repeat-x top left;
+}
+
+.soria .dojoxDropDownSelectActive .dijitButtonNode {
+ /* active state - inner (for when you are pressing a normal button, or
+ * when a toggle button is in a depressed state
+ */
+ border-color:#657c9c;
+ background: #91b4e5 url("../../../dijit/themes/soria/images/buttonActive.png") top left repeat-x;
+}
+
+/*
+**----------------------------------------------------------------------------
+** Nihilo stylings
+**----------------------------------------------------------------------------
+*/
+/* Cursor States */
+.nihilo .dojoxDropDownSelectDisabled * {
+ cursor: not-allowed !important;
+}
+.nihilo .dojoxDropDownSelectReadOnly * {
+ cursor: default !important;
+}
+
+/* Make unselected "look" more like a text box and less like a button */
+.nihilo .dojoxDropDownSelect .dijitButtonNode {
+ background:#fff url("../../../dijit/themes/nihilo/images/validationInputBg.png") repeat-x top left;
+ #background:#fff url('../../../dijit/themes/nihilo/images/validationInputBg.gif') repeat-x top left;
+ border:1px solid #d3d3d3;
+ line-height: normal;
+}
+
+/* Mirror DropDownButton */
+.nihilo .dojoxDropDownSelectDisabled .dijitButtonNode {
+ /* disabled state - inner */
+ border-color: #dedede;
+ /*color:#b4b4b4;*/
+ background:#fafafa url("../../../dijit/themes/nihilo/images/buttonDisabled.png") top repeat-x;
+ opacity: 0.60; /* Safari, Opera and Mozilla */
+}
+
+.dj_ie .nihilo .dojoxDropDownSelectDisabled .dijitButtonNode * {
+ filter: gray() alpha(opacity=50); /* IE */
+}
+
+.nihilo .dojoxDropDownSelectHover .dijitButtonNode,
+.nihilo .dojoxDropDownSelect .dojoxDropDownSelectButtonOpened {
+ /* hover state - inner */
+ /* TODO: change from Hover to Selected so that button is still highlighted while drop down is being used */
+ color:#000;
+ background:#fcfcfc url("../../../dijit/themes/nihilo/images/buttonHover.png") repeat-x top left;
+}
+
+.nihilo .dojoxDropDownSelectActive .dijitButtonNode {
+ /* active state - inner (for when you are pressing a normal button, or
+ * when a toggle button is in a depressed state
+ */
+ border-color:#dedede;
+ background: #f5f5f5 url("../../../dijit/themes/nihilo/images/buttonActive.png") top left repeat-x;
+}
diff --git a/includes/js/dojox/form/resources/PasswordValidator.html b/includes/js/dojox/form/resources/PasswordValidator.html
new file mode 100644
index 0000000..80a55ae
--- /dev/null
+++ b/includes/js/dojox/form/resources/PasswordValidator.html
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/includes/js/dojox/form/resources/_CheckedMultiSelectItem.html b/includes/js/dojox/form/resources/_CheckedMultiSelectItem.html
new file mode 100644
index 0000000..d9ec863
--- /dev/null
+++ b/includes/js/dojox/form/resources/_CheckedMultiSelectItem.html
@@ -0,0 +1,4 @@
+
diff --git a/includes/js/dojox/form/tests/test_CheckedMultiSelect.html b/includes/js/dojox/form/tests/test_CheckedMultiSelect.html
new file mode 100644
index 0000000..b8729d2
--- /dev/null
+++ b/includes/js/dojox/form/tests/test_CheckedMultiSelect.html
@@ -0,0 +1,91 @@
+
+
+
+
+
+
+
+ Test: dojox.form.CheckedMultiSelect
+ Automated test
+
+
+
diff --git a/includes/js/dojox/form/tests/test_DropDownSelect.html b/includes/js/dojox/form/tests/test_DropDownSelect.html
new file mode 100644
index 0000000..4487e54
--- /dev/null
+++ b/includes/js/dojox/form/tests/test_DropDownSelect.html
@@ -0,0 +1,128 @@
+
+
+
+
+
+
+
+
+ Test: dojox.form.DropDownSelect
+ Automated test
+
+
+
diff --git a/includes/js/dojox/form/tests/test_PasswordValidator.html b/includes/js/dojox/form/tests/test_PasswordValidator.html
new file mode 100644
index 0000000..e3b1e63
--- /dev/null
+++ b/includes/js/dojox/form/tests/test_PasswordValidator.html
@@ -0,0 +1,216 @@
+
+
+
+
+
+
+
+
+ Test: dojox.form.PasswordValidator
+ Automated test
+ No old password
+
+
+ Old password (hard-coded to "oldpw2") - not passed to getValues
+
+
+ Old password (hard-coded to "oldpw3") - passed to getValues
+
+
+ In Table, Old password (hard-coded to "oldpw4") - not passed to getValues
+
+
+ In Table, Old password (hard-coded to "oldpw5") - passed to getValues
+
+
+ No old password, not required
+
+
+
+
+ Get Values
+
+
+
+ Toggle Disabled
+
+
+
--
cgit v1.3-2-g0d8e