summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitattributes31
-rw-r--r--framework/Web/Javascripts/base/ajax.js174
-rw-r--r--framework/Web/Javascripts/base/controls.js31
-rw-r--r--framework/Web/Javascripts/base/effects.js22
-rw-r--r--framework/Web/Javascripts/base/postback.js2
-rw-r--r--framework/Web/Javascripts/base/prado.js66
-rw-r--r--framework/Web/Javascripts/base/validation.js2
-rw-r--r--framework/Web/Javascripts/base/validators.js9
-rw-r--r--framework/Web/Javascripts/effects/CHANGELOG613
-rw-r--r--framework/Web/Javascripts/effects/MIT-LICENSE20
-rw-r--r--framework/Web/Javascripts/effects/README57
-rw-r--r--framework/Web/Javascripts/effects/builder.js101
-rw-r--r--framework/Web/Javascripts/effects/controls.js59
-rw-r--r--framework/Web/Javascripts/effects/dragdrop.js366
-rw-r--r--framework/Web/Javascripts/effects/effects.js597
-rw-r--r--framework/Web/Javascripts/effects/rico.js1659
-rw-r--r--framework/Web/Javascripts/effects/slider.js351
-rw-r--r--framework/Web/Javascripts/extended/dom.js222
-rw-r--r--framework/Web/Javascripts/extended/event.js2
-rw-r--r--framework/Web/Javascripts/extended/string.js25
-rw-r--r--framework/Web/Javascripts/extra/behaviour.js17
-rw-r--r--framework/Web/Javascripts/extra/logger.js168
-rw-r--r--framework/Web/Javascripts/js/validator.js1
-rw-r--r--framework/Web/Javascripts/prototype/AUTHORS12
-rw-r--r--framework/Web/Javascripts/prototype/LICENSE16
-rw-r--r--framework/Web/Javascripts/prototype/README64
-rw-r--r--framework/Web/Javascripts/prototype/THANKS21
-rw-r--r--framework/Web/Javascripts/prototype/ajax.js75
-rw-r--r--framework/Web/Javascripts/prototype/array.js25
-rw-r--r--framework/Web/Javascripts/prototype/base.js6
-rw-r--r--framework/Web/Javascripts/prototype/dom.js26
-rw-r--r--framework/Web/Javascripts/prototype/enumerable.js6
-rw-r--r--framework/Web/Javascripts/prototype/form.js61
-rw-r--r--framework/Web/Javascripts/prototype/prototype.js16
-rw-r--r--framework/Web/Javascripts/prototype/range.js8
-rw-r--r--framework/Web/Javascripts/prototype/string.js16
-rw-r--r--framework/Web/Javascripts/tests/CompareValidator.html95
-rw-r--r--framework/Web/Javascripts/tests/CustomValidator.html74
-rw-r--r--framework/Web/Javascripts/tests/DatePicker.html99
-rw-r--r--framework/Web/Javascripts/tests/Effects.html124
-rw-r--r--framework/Web/Javascripts/tests/Form.disable.html37
-rw-r--r--framework/Web/Javascripts/tests/Insertion.html47
-rw-r--r--framework/Web/Javascripts/tests/PradoTestSuite.html37
-rw-r--r--framework/Web/Javascripts/tests/RangeValidator.html65
-rw-r--r--framework/Web/Javascripts/tests/RegularExpressionValidator.html72
-rw-r--r--framework/Web/Javascripts/tests/RequiredFieldValidator.html95
-rw-r--r--framework/Web/Javascripts/tests/RequiredListValidator.html110
-rw-r--r--framework/Web/Javascripts/tests/ValidationTests.html79
-rw-r--r--framework/Web/Javascripts/tests/calendar_system.css70
-rw-r--r--framework/Web/Javascripts/tests/compression.html18
-rw-r--r--framework/Web/Javascripts/tests/console.html30
-rw-r--r--framework/Web/Javascripts/tests/fungii_logo.gifbin5473 -> 0 bytes
-rw-r--r--framework/Web/Javascripts/tests/getElementsByClassName.html28
-rw-r--r--framework/Web/Javascripts/tests/getElementsBySelector.html55
-rw-r--r--framework/Web/Javascripts/tests/index.html138
-rw-r--r--framework/Web/Javascripts/tests/librarytest.html49
-rw-r--r--framework/Web/Javascripts/tests/test_scripts/TestRequiredFieldValidator.html85
-rw-r--r--framework/Web/Javascripts/tests/test_scripts/TestSuite.html36
58 files changed, 3767 insertions, 2623 deletions
diff --git a/.gitattributes b/.gitattributes
index dd6d39c3..2fe936f8 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -428,6 +428,7 @@ framework/TODO.txt -text
framework/Web/Javascripts/base/ajax.js -text
framework/Web/Javascripts/base/controls.js -text
framework/Web/Javascripts/base/datepicker.js -text
+framework/Web/Javascripts/base/effects.js -text
framework/Web/Javascripts/base/focus.js -text
framework/Web/Javascripts/base/json.js -text
framework/Web/Javascripts/base/postback.js -text
@@ -435,6 +436,10 @@ framework/Web/Javascripts/base/prado.js -text
framework/Web/Javascripts/base/scroll.js -text
framework/Web/Javascripts/base/validation.js -text
framework/Web/Javascripts/base/validators.js -text
+framework/Web/Javascripts/effects/CHANGELOG -text
+framework/Web/Javascripts/effects/MIT-LICENSE -text
+framework/Web/Javascripts/effects/README -text
+framework/Web/Javascripts/effects/builder.js -text
framework/Web/Javascripts/effects/controls.js -text
framework/Web/Javascripts/effects/dragdrop.js -text
framework/Web/Javascripts/effects/effects.js -text
@@ -456,6 +461,10 @@ framework/Web/Javascripts/js/base.js -text
framework/Web/Javascripts/js/dom.js -text
framework/Web/Javascripts/js/logger.js -text
framework/Web/Javascripts/js/validator.js -text
+framework/Web/Javascripts/prototype/AUTHORS -text
+framework/Web/Javascripts/prototype/LICENSE -text
+framework/Web/Javascripts/prototype/README -text
+framework/Web/Javascripts/prototype/THANKS -text
framework/Web/Javascripts/prototype/ajax.js -text
framework/Web/Javascripts/prototype/array.js -text
framework/Web/Javascripts/prototype/base.js -text
@@ -469,28 +478,6 @@ framework/Web/Javascripts/prototype/position.js -text
framework/Web/Javascripts/prototype/prototype.js -text
framework/Web/Javascripts/prototype/range.js -text
framework/Web/Javascripts/prototype/string.js -text
-framework/Web/Javascripts/tests/CompareValidator.html -text
-framework/Web/Javascripts/tests/CustomValidator.html -text
-framework/Web/Javascripts/tests/DatePicker.html -text
-framework/Web/Javascripts/tests/Effects.html -text
-framework/Web/Javascripts/tests/Form.disable.html -text
-framework/Web/Javascripts/tests/Insertion.html -text
-framework/Web/Javascripts/tests/PradoTestSuite.html -text
-framework/Web/Javascripts/tests/RangeValidator.html -text
-framework/Web/Javascripts/tests/RegularExpressionValidator.html -text
-framework/Web/Javascripts/tests/RequiredFieldValidator.html -text
-framework/Web/Javascripts/tests/RequiredListValidator.html -text
-framework/Web/Javascripts/tests/ValidationTests.html -text
-framework/Web/Javascripts/tests/calendar_system.css -text
-framework/Web/Javascripts/tests/compression.html -text
-framework/Web/Javascripts/tests/console.html -text
-framework/Web/Javascripts/tests/fungii_logo.gif -text
-framework/Web/Javascripts/tests/getElementsByClassName.html -text
-framework/Web/Javascripts/tests/getElementsBySelector.html -text
-framework/Web/Javascripts/tests/index.html -text
-framework/Web/Javascripts/tests/librarytest.html -text
-framework/Web/Javascripts/tests/test_scripts/TestRequiredFieldValidator.html -text
-framework/Web/Javascripts/tests/test_scripts/TestSuite.html -text
framework/Web/Services/TPageService.php -text
framework/Web/THttpRequest.php -text
framework/Web/THttpResponse.php -text
diff --git a/framework/Web/Javascripts/base/ajax.js b/framework/Web/Javascripts/base/ajax.js
index f1dd69c5..ccfb085d 100644
--- a/framework/Web/Javascripts/base/ajax.js
+++ b/framework/Web/Javascripts/base/ajax.js
@@ -53,17 +53,20 @@ Prado.AJAX.Request.prototype = Object.extend(Ajax.Request.prototype,
respondToReadyState: function(readyState) {
var event = Ajax.Request.Events[readyState];
var transport = this.transport, json = this.evalJSON();
+
+
if(event == 'Complete' && transport.status)
Ajax.Responders.dispatch('on' + transport.status, this, transport, json);
- if (event == 'Complete')
+ (this.options['on' + event] || Prototype.emptyFunction)(transport, json);
+ Ajax.Responders.dispatch('on' + event, this, transport, json);
+
+ if (event == 'Complete')
(this.options['on' + this.transport.status]
|| this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')]
|| Prototype.emptyFunction)(transport, json);
- (this.options['on' + event] || Prototype.emptyFunction)(transport, json);
- Ajax.Responders.dispatch('on' + event, this, transport, json);
-
+
/* Avoid memory leak in MSIE: clean up the oncomplete event handler */
if (event == 'Complete')
this.transport.onreadystatechange = Prototype.emptyFunction;
@@ -208,12 +211,10 @@ Prado.AJAX.RemoteObject.prototype =
__onSuccess : function(transport, json)
{
if(this.__handlers[this.__callback])
- this.__handlers[this.__callback](json, transport.responseText);
+ this.__handlers[this.__callback](json, transport.responseText);
}
};
-
-
/**
* Respond to Prado AJAX request exceptions.
*/
@@ -235,7 +236,7 @@ Prado.AJAX.Exception =
{
var msg = 'HTTP '+transport.status+" with response : \n";
msg += transport.responseText + "\n";
- msg += "Data : \n"+e;
+ msg += "Data : \n"+inspect(e);
Logger.warn(msg);
}
},
@@ -285,12 +286,14 @@ Prado.AJAX.Callback.prototype = Object.extend(new Prado.AJAX.RemoteObject(),
/**
* Create and request a new Prado callback service.
- * @param string the callback ID, must be of the form, <t>ClassName.ComponentID.MethodName</t>
+ * @param string|element the callback ID, must be of the form, <t>ClassName.ComponentID.MethodName</t>
* @param list options with list key onCallbackReturn, and more.
*
*/
initialize : function(ID, options)
{
+ if(!isString(ID) && typeof(ID.id) != "undefined")
+ ID = ID.id;
if(!isString(ID))
throw new Error('A Control ID must be specified');
this.baseInitialize(this, options);
@@ -307,7 +310,25 @@ Prado.AJAX.Callback.prototype = Object.extend(new Prado.AJAX.RemoteObject(),
var IDs = Prado.AJAX.Callback.IDs;
this.__service.post.data['__data'] = {};
for(var i = 0; i<IDs.length; i++)
- this.__service.post.data['__data'][IDs[i]] = $F(IDs[i]);
+ {
+ var id = IDs[i];
+ if(id.indexOf("[]") > -1)
+ this.__service.post.data['__data'][id] =
+ this.collectArrayPostData(id);
+ else if(isObject($(id)))
+ this.__service.post.data['__data'][id] = $F(id);
+ }
+ },
+
+ collectArrayPostData : function(name)
+ {
+ var elements = document.getElementsByName(name);
+ var data = [];
+ $A(elements).each(function(el)
+ {
+ if($F(el)) data.push($F(el));
+ });
+ return data;
},
/**
@@ -318,18 +339,134 @@ Prado.AJAX.Callback.prototype = Object.extend(new Prado.AJAX.RemoteObject(),
requestCallback : function()
{
this.collectPostData();
- return this.__call(Prado.AJAX.Callback.Server, 'handleCallback', this.options.params);
+ if(Prado.AJAX.Validate(this.options))
+ return this.__call(Prado.AJAX.Callback.Server, 'handleCallback', this.options.params);
},
-
+
/**
* On callback request return, call the onSuccess function.
*/
handleCallback : function(result, output)
{
- this.options.onSuccess(result, output);
+ if(typeof(result) != "undefined" && !isNull(result))
+ {
+ this.options.onSuccess(result['data'], output);
+ if(result['actions'])
+ result.actions.each(Prado.AJAX.Callback.Action.__run);
+ }
}
});
+/**
+ * Prase and evaluate Callback clien-side actions.
+ */
+Prado.AJAX.Callback.Action =
+{
+ __run : function(command)
+ {
+ for(var name in command)
+ {
+ //first parameter must be a valid element or begins with '@'
+ if(command[name][0] && ($(command[name][0]) || command[name][0].indexOf("[]") > -1))
+ {
+ name.toFunction().apply(this,command[name]);
+ }
+ }
+ }
+};
+
+
+/**
+ * Returns false if validation required and validates to false,
+ * returns true otherwise.
+ * @return boolean true if validation passes.
+ */
+Prado.AJAX.Validate = function(options)
+{
+ if(options.CausesValidation)
+ {
+ if(options.ValidatorGroup)
+ return Prado.AJAX.ValidateGroup1(options.ValidatorGroup);
+ else if(options.ValidationGroup)
+ return Prado.AJAX.ValidateGroup2(options.ValidationGroup);
+ else
+ return Prado.AJAX.ValidateOthers(options.ValidationForm);
+ }
+ else
+ return true;
+};
+
+/**
+ * Validate Validator Groups.
+ * @param string ValidatorGroup
+ * @return boolean true if valid, false otherwise
+ */
+Prado.AJAX.ValidateGroup1 = function(groupId)
+{
+ var groups = Prado.Validation.groups;
+ var group = null;
+ for(var i = 0; i < groups.length; i++)
+ {
+ if(groups[i].id == groupId)
+ {
+ group = groups[i];
+ Prado.Validation.groups[i].active = true;
+ Prado.Validation.CurrentTargetGroup = null;
+ Prado.Validation.IsGroupValidation = true;
+ }
+ else
+ {
+ Prado.Validation.groups[i].active = false;
+ }
+ }
+ if(group)
+ {
+ return Prado.Validation.IsValid(group.target.form);
+ }
+ return true;
+};
+
+/**
+ * Validate ValidationGroup
+ * @param string ValidationGroup
+ * @return boolean true if valid, false otherwise.
+ */
+Prado.AJAX.ValidateGroup2 = function(groupId)
+{
+ var groups = Prado.Validation.TargetGroups;
+ for(var id in groups)
+ {
+ if(groups[id] == groupId)
+ {
+ var target = $(id);
+ Prado.Validation.ActiveTarget = target;
+ Prado.Validation.CurrentTargetGroup = groupId;
+ Prado.Validation.IsGroupValidation = false;
+ return Prado.Validation.IsValid(target.form);
+ }
+ }
+ return true;
+};
+
+/**
+ * Validate the page
+ * @return boolean true if valid, false otherwise.
+ */
+Prado.AJAX.ValidateOthers = function(formId)
+{
+ if(Prado.Validation)
+ {
+ var form = $(formId);
+ form = form || document.forms[0];
+ Prado.Validation.ActiveTarget = form;
+ Prado.Validation.CurrentTargetGroup = null;
+ Prado.Validation.IsGroupValidation = false;
+ return Prado.Validation.IsValid(form);
+ }
+ return true;
+};
+
+
//Available callback service
Prado.AJAX.Callback.Server = '';
@@ -342,14 +479,17 @@ Prado.AJAX.Callback.IDs = [];
* @param string callback ID
* @param array parameters to pass to the callback service
*/
-Prado.Callback = function(ID, params, onSuccess)
+Prado.Callback = function(ID, params, onSuccess, options)
{
- var options =
+ var callback =
{
'params' : [params] || [],
- 'onSuccess' : onSuccess || Prototype.emptyFunction
+ 'onSuccess' : onSuccess || Prototype.emptyFunction,
+ 'CausesValidation' : true
};
+
+ Object.extend(callback, options || {});
- new Prado.AJAX.Callback(ID, options);
+ new Prado.AJAX.Callback(ID, callback);
return false;
} \ No newline at end of file
diff --git a/framework/Web/Javascripts/base/controls.js b/framework/Web/Javascripts/base/controls.js
index 6cb908ed..ad5b8abe 100644
--- a/framework/Web/Javascripts/base/controls.js
+++ b/framework/Web/Javascripts/base/controls.js
@@ -140,8 +140,9 @@ Prado.ActivePanel.Request.prototype =
{
if(this.options.update)
{
- var element = $(this.options.update)
- if(element) element.innerHTML = output;
+ if (!this.options.evalScripts)
+ output = output.stripScripts();
+ Element.update(this.options.update, output);
}
}
}
@@ -160,7 +161,7 @@ Prado.DropContainer.prototype = Object.extend(new Prado.ActivePanel.Request(),
{
onDrop : this.onDrop.bind(this),
evalScripts : true,
- onSuccess : options.onSuccess || this.update.bind(this)
+ onSuccess : options.onSuccess || this.onSuccess.bind(this)
});
Droppables.add(element, this.options);
},
@@ -168,12 +169,26 @@ Prado.DropContainer.prototype = Object.extend(new Prado.ActivePanel.Request(),
onDrop : function(draggable, droppable)
{
this.callback(draggable.id)
+ }
+});
+
+Prado.ActiveImageButton = Class.create();
+Prado.ActiveImageButton.prototype =
+{
+ initialize : function(element, options)
+ {
+ this.element = $(element);
+ this.options = options;
+ Event.observe(this.element, "click", this.click.bind(this));
},
- update : function(result, output)
+ click : function(e)
{
- this.onSuccess(result, output);
- if (this.options.evalScripts)
- Prado.AJAX.EvalScript(output);
+ var el = $('{$this->ClientID}');
+ var imagePos = Position.cumulativeOffset(this.element);
+ var clickedPos = [e.clientX, e.clientY];
+ var param = (clickedPos[0]-imagePos[0]+1)+","+(clickedPos[1]-imagePos[1]+1);
+ Prado.Callback(this.element, param, null, this.options);
+ Event.stop(e);
}
-}); \ No newline at end of file
+} \ No newline at end of file
diff --git a/framework/Web/Javascripts/base/effects.js b/framework/Web/Javascripts/base/effects.js
new file mode 100644
index 00000000..cc31d00e
--- /dev/null
+++ b/framework/Web/Javascripts/base/effects.js
@@ -0,0 +1,22 @@
+Prado.Effect =
+{
+ Highlight : function(element, duration)
+ {
+ new Effect.Highlight(element, {'duration':duration});
+ },
+
+ Scale : function(element, percent)
+ {
+ new Effect.Scale(element, percent);
+ },
+
+ MoveBy : function(element, toTop, toLeft)
+ {
+ new Effect.MoveBy(element, toTop, toLeft);
+ },
+
+ ScrollTo : function(element, duration)
+ {
+ new Effect.ScrollTo(element, {'duration':duration});
+ }
+} \ No newline at end of file
diff --git a/framework/Web/Javascripts/base/postback.js b/framework/Web/Javascripts/base/postback.js
index 2889c4ff..b7e095a4 100644
--- a/framework/Web/Javascripts/base/postback.js
+++ b/framework/Web/Javascripts/base/postback.js
@@ -13,7 +13,7 @@ Prado.doPostBack = function(formID, eventTarget, eventParameter, performValidati
if (performValidation)
{
//canSubmit = Prado.Validation.validate(validationGroup);
- canSubmit = Prado.Validation.OnSubmit();
+ canSubmit = Prado.Validation.OnSubmit(theForm);
}
if (canSubmit)
{
diff --git a/framework/Web/Javascripts/base/prado.js b/framework/Web/Javascripts/base/prado.js
index 3eded927..7dd14e19 100644
--- a/framework/Web/Javascripts/base/prado.js
+++ b/framework/Web/Javascripts/base/prado.js
@@ -1,65 +1 @@
-Prado = Class.create();
-
-Prado.version = '3.0a';
-
-Prado.Button = Class.create();
-
-Prado.Button.buttonFired = false;
-Prado.Button.fireButton = function(event, target)
-{
- if (!Prado.Button.buttonFired && event.keyCode == 13 && !(event.srcElement && (event.srcElement.tagName.toLowerCase() == "textarea")))
- {
- var defaultButton = document.getElementById ? document.getElementById(target) : document.all[target];
- if (defaultButton && typeof(defaultButton.click) != "undefined")
- {
- Prado.Button.buttonFired = true;
- defaultButton.click();
- event.cancelBubble = true;
- if (event.stopPropagation)
- event.stopPropagation();
- return false;
- }
- }
- return true;
-}
-
-Prado.TextBox = Class.create();
-
-/**
- * Returns FALSE when the "Enter" key is pressed AND when onchange
- * property is defined. The onchange function is called. However,
- * it does not call event listener functions.
- * @return boolean false if "Enter" and onchange property is defined, true otherwise.
- */
-Prado.TextBox.handleReturnKey = function(ev)
-{
- var kc = ev.keyCode != null ? ev.keyCode : ev.charCode;
- if(kc == Event.KEY_RETURN)
- {
- var target = Event.element(ev);
- if(target && isFunction(target.onchange))
- {
- target.onchange();
- Event.stop(ev);
- return false;
- }
- }
- return true;
-}
-
-/**
- * Creates a LinkButton and register the post back to the onclick event.
- */
-/* to finish when doPostback changes
-Prado.LinkButton = Class.create();
-Prado.LinkButton.prototype =
-{
- initialize : function(element, name)
- {
- Event.observe(element, 'click', function(e)
- {
- Prado.doPostback(element, name, '');
- Event.stop(e);
- });
- }
-}*/ \ No newline at end of file
+var Prado = { Version: 2.0 }; \ No newline at end of file
diff --git a/framework/Web/Javascripts/base/validation.js b/framework/Web/Javascripts/base/validation.js
index 4129ad70..ceebc2ba 100644
--- a/framework/Web/Javascripts/base/validation.js
+++ b/framework/Web/Javascripts/base/validation.js
@@ -193,7 +193,7 @@ Prado.Validation.groups = [];
/**
* Second type of grouping.
*/
-Prado.Validation.TargetGroups = [];
+Prado.Validation.TargetGroups = {};
/**
diff --git a/framework/Web/Javascripts/base/validators.js b/framework/Web/Javascripts/base/validators.js
index f281c87e..99d6b416 100644
--- a/framework/Web/Javascripts/base/validators.js
+++ b/framework/Web/Javascripts/base/validators.js
@@ -27,13 +27,10 @@ Prado.Validation.TEmailAddressValidator = Prado.Validation.TRegularExpressionVal
Prado.Validation.TCustomValidator = function()
{
- var trim = Prado.Validation.Util.trim;
- var value = isNull(this.control) ? '' : trim(Form.Element.getValue(this.control));
- var valid = true;
+ var value = isNull(this.control) ? null : $F(this.control);
var func = this.attr.clientvalidationfunction;
- if (isString(func) && func != "")
- eval("valid = (" + func + "(this, value) != false);");
- return valid;
+ eval("var validate = "+func);
+ return validate && isFunction(validate) ? validate(this, value) : true;
}
Prado.Validation.TRangeValidator = function()
diff --git a/framework/Web/Javascripts/effects/CHANGELOG b/framework/Web/Javascripts/effects/CHANGELOG
new file mode 100644
index 00000000..0b7687b5
--- /dev/null
+++ b/framework/Web/Javascripts/effects/CHANGELOG
@@ -0,0 +1,613 @@
+*V1.5.0*
+
+* Prepared for V1.5.0 final
+
+* Update lib/prototype.js to Prototype 1.4.0 final
+
+*V1.5.0_rc6*
+
+* Update lib/prototype.js to Prototype 1.4.0_rc4
+
+* Fix Effect.SlideDown/SlideUp on Internet Explorer, includes a change to Effect.Scale, (should) fix #2962 and others, [thx wyldeone]
+
+* Make Draggables that are reverting cancel the default revert effect when they are dragged again while reverting, fixes #3188, [thx maverick]
+
+* Fix a problem with a wrong reference in Effect.Pulsate, fixes #3184, [thx cyx_]
+
+* Fix Sortable.findElements for XHTML in Gecko, fixes #3081, [thx fgnass]
+
+* Fix a problem with the slider getting NaN results when clicking directly on the track, fixes #3020, [thx rectalogic]
+
+* Fix a problem with Safari not doing sub-pixel rendering when setting opacity to 1 with Element.setOpacity
+
+* Fix slider to make handle width/height count for track length, fixes #3040, fixes #3017, [thx buggedcom]
+
+* Added Basic unit test for Effect.inspect
+
+* Fix Effect.multiple to deal correctly with delays
+
+* Safeguard Effect.Base.render to only do updates when Effect is in running state, fixes #2912
+
+* Added inspect method to Effect.Base
+
+* Added functional test for DOM-based UL sortables #3016
+
+* Added offset option to Effect.ScrollTo
+
+* More effects.js/dragdrop.js refactoring
+
+* Refactoring and optimizations for effects (not complete yet)
+
+* Refactoring and optimizations for Draggables/Droppables/Sortables (not complete yet)
+
+*V1.5.0_rc5*
+
+* Make Droppables.remove accept DOM IDs in addition to elements
+
+* Added some unit tests for drag and drop
+
+* Update lib/prototype.js to Prototype 1.4.0_rc3
+
+* Make 'contents' a synonym for 'content' on Effect.Scale scaleMode option
+
+* Fix some possible exceptions in slider.js
+
+* Support for various snapping options on Draggables, adresses #2826, [thx saimonmoore]
+
+* Support horizontal ghostable Sortables, fixes #2794, [thx johnm]
+
+* Prevent an exception on IE with a functional test, see #2706
+
+* Add functional testing of hoverclasses for sortables
+
+* Add an assert for correct UTF-8 return chars in Autocompleter
+
+* Correct IE detection in Autocompleter for Opera, fixes #2558 [thx gary]
+
+* Add onDrag callback to Draggable observers, #2827 [thx saimonmoore]
+
+* Added Form.Element.DelayedObserver to controls.js for live-search fields
+
+* Remove Element.Class in favour of Prototype Element.ClassNames, new function Element.childrenWithClassName()
+
+* Update Copyright notice in slider.js
+
+* Fix slider firing onChange events to eagerly on dragging a handle [thx wombert]
+
+* Fix a problem with Start/End spans and single handles
+
+* Add event property to Slider object so that callbacks can determine if setValue originated from a UI event or from script
+
+* Fix Builder.node() throwing unresolved errors in IE6, #2707 [thx flwombat]
+
+* Give currently active handle on slider the "selected" CSS class
+
+* Add start and end spans to slider
+
+* Make track clickable for sliders (moves last active handle [or first handle] to nearest possible position)
+
+* Make initial values on slider work for single and multiple handle sliders
+
+*V1.5.0_rc4*
+
+* Abort Effect.Highlight on elements which have display:none set (prevents problem with Safari)
+
+* Make Effect.Queue an Enumerable, fix a problem with Effect.Grow, more unit tests
+
+* Added restricted option to prevent moved of handles prior/after adjacent handles on Sliders with multiple handles
+
+* Update lib/prototype.js to Prototype 1.4.0_rc2
+
+* Fix a bug with wrongly scrolling to the page top in Ajax.InPlaceEditor (circumvents various browser bugs) [Jon Tirsen], #2616
+
+* major slider refactoring, changed slider range to default to [0,1]. Slider Range can be set with range:$R(from,to) option. The increment option is not active for now.
+
+* Added spans support for Control.Slider to mark spans bordered by slider handles, see unit test [thx to www.bartenbach.de for sponsoring this functionality]
+
+* Added preliminary support for optional multiple handles to Control.Slider [thx to www.bartenbach.de for sponsoring this functionality]
+
+* Fixed wrong inclusion of libs in inplace editor functional test
+
+* Fixed Effect.SlideDown/SlideUp to honor refactoring of Effect.Scale, fixes #2523 [thx obiwanki]
+
+* Reset the zIndex on Draggables correctly, #2483 [thx Jon Whitcraft]
+
+* Fix onChange callback on Sortables when dragging between sortables, #2488 [thx Dylan Greene]
+
+* Removed Builder code from effects.js, removed Object.debug (implemented as Test.Unit.inspect)
+
+* Added slider unit tests, fixed handling of values to autocalculate min/max, fixed upper/lower boundaries on setting the value programmatically
+
+* Synced to Rails 1.0 release candidate, update to Prototype 1.4.0_rc1, removed util.js, merged rests of util.js into effects.js to prepare for refactoring
+
+* Give Builder it's own file
+
+* Fix a logic issue with Autocompleter [thx tshinnic], #2457
+
+*V1.5.0_rc3*
+
+* Make Effect position available to callbacks
+
+* Droppables.fire: send event to onDrop callback [François Beausoleil], #2389
+
+* InPlaceEditor: Add disabling the field while loadTextURL loads and add a class while loading, plus fix various bugs with Internet Explorer and InPlaceEditor, [Jon Tirsen] #2302, #2303
+
+* Made Droppables.remove work again [thx Mindaugas Pelionis], #2409
+
+* Fixed that IE6 would incorrectly render the "fix-windowed-elements-overlapping" IFRAME on autocompletion [thx tshinnic], #2403
+
+* Fixed Element.getOpacity throwing an error on Safari in some situations (this caused the autocompleter not to work)
+
+* Added format option to Sortable.create and Sortable.serialize to allow custom id formats. The format option takes a regular expression where the first grouping that matches is used for building the parameters. The default format is /^[^_]*_(.*)$/ which matches the string_identifier format. If you want to use the full id of the elements, use "format: /(.*)/". More examples are available in the sortable unit test file.
+
+* Started refactorings to use the new Prototype features and general code-cleanup
+
+* Update lib/prototype.js to Prototype 1.4.0_pre11
+
+* Fixed a typo breaking the up arrow key for autocompletion [thx tshinnic], #2406
+
+* Changed the handle option on Draggbles to accept classnames, or ids or elements [thx to Andrew West], #2274
+
+* Force indicator to be hidden on hiding autocompletion update element, #2342
+
+* Make Draggables honor external CSS positioning [thx to Mark Shawkey], #2359
+
+* Make zindex handling for Draggables honor external CSS styles
+
+* Fix two Sortable.serialize issues, [thx Avi, Gorou], #2339, #2357
+
+* Make Element.getOpacity work with IE, added unit tests [thx to Greg Hill]
+
+* Make Element.setOpacity honor non-alpha filters on IE (it now works with filters for alpha PNGs)
+
+* Fixed that Element.class.remove wrongly deleted spaces between class names, fixes #2311, #2313
+
+* Fixed Builder for OPTION and OPTGROUP tags on Firefox < 1.5 and Internet Explorer 6, completely fixes #2325
+
+* Improved Builder implementation to deal with Firefox-specific requirements and innerHTML parsing, partly fixes #2325
+
+*V1.5.0_rc2*
+
+* Update lib/prototype.js to corrected Prototype 1.4.0_pre7 (fixed a problem with IE)
+
+* Update lib/prototype.js to Prototype 1.4.0_pre7
+
+* Reverted to patched version of Prototype 1.4.0_pre4 for the time being (getResponseHeader problem on Mozilla)
+
+* Attempt to fix crashes in Safari 2.0.1, probably related to the event registering und unregistering in Draggables, possibly fixes #2310
+
+* Update lib/prototype.js to Prototype 1.4.0_pre6
+
+* Changed effects_test.html functional test to incoporate Firefox anti-flicker overflow:hidden CSS property
+
+*V1.5.0_rc1*
+
+* Prepared Rakefile and README for V1.5.0_rc1 release
+
+* Droppables w/greedy and hoverclass are now reverted when dragged item is no longer over them, fixes #2184
+
+* Let Effect.Highlight correctly parse IE colors, add String.prototype.parseColor() for this, fixes #2037
+
+* Fix Effect.Highlight to restore background image only if there was one
+
+* Made Effect.tagifyText work again on IE
+
+* Added String.prototype.toArray because Strings aren't iterable on IE
+
+* Fixed Element.getOpacity falsely returning 0 on IE
+
+* Some cleaning up in util.js
+
+* Cleaned up Effect.Opacity
+
+* Removed useless line in Position.page
+
+* Make scriptaculous.js work if a query strings are used when calling it
+
+* Fixed typos in slider.js and the functional test
+
+* Fixed a bug with Safari and the InPlaceEditor with form submission. Add support for interpreting simple <br>s into linebreaks. [Jon Tirsen]
+
+* New Control.Slider() for horizontal and vertical sliders [Marty Haught]
+
+* Fixed autoapplying a 'layout' on IE with Effect.Opacity not working for elements given as id string
+
+* Make Effect.Parallel render final frames and call beforeFinish/afterFinish on included effects
+
+* Make Element.setOpacity work correctly again (browser-specific extensions, except for IE, are disabled at this time)
+
+* Added focusing the text field or text area created when using Ajax.InPlaceEditor #2126 [thx to Lee Mallabone]
+
+* Fixed Element.Class.childrenWith not returning the correct elements #2120 [cmees AT rogers DOT com]
+
+* Added MIT-LICENSE header to scriptaculous.js, cut back on license info in other libs to keep files smaller
+
+* Fix issues with form elements inside draggables not clickable with Firefox #2129
+
+* Fixed an error in dragdrop.js with Draggables when no Droppables are defined
+
+* Fixed an issue with Element.makePositioned causing Effect.SlideDown to fail on Safari
+
+* Make effects "stateless" by cleaning up element.style after finish of effect #2133 [agr30 AT uni-koeln DOT de]
+
+* Add "internal" events to effects, to make them more easily extendable [Martin Bialasinski]
+
+* Set container element height to auto on finishing Effect.BlindDown und Effect.SlideDown #2123 [Tony Arnold]
+
+* Fixed a weird char in dragdrop.js
+
+* Controls.js Autocompleter.Base.updateElement() hook #2116 [Rob Wills]
+
+* Refactoring to use the Prototype enumerable extensions
+
+* Update to Prototype 1.4.0_pre4
+
+*V1.5.0_pre4*
+
+* Added a queue option to effects for easy stacking and simple timeline building. Valid values are "front", "end" and "parallel" (default), see for test/functional/effects_queue_test.html for usage
+
+* Added a setup function to the core effects that gets called by Effect.Base when first entering into running state, which allows them to query the current state of an element or other page properties when queuing and/or delays are used
+
+* Added a state instance variable to Effect.Base that indicates whether a effect that uses the queue is idle, running or finished
+
+* Fixed a flicker with Effect.Puff
+
+* General code cleaning to get rid of (legitimate) Mozilla strict javascript warnings
+
+* Changes to assertVisible in unittest.js
+
+* Slight refactoring of Effect.Text, now known as Effect.multiple(), change first parameter to also accept an array of strings or elements, or a NodeList of elements (if a single element or a string is given, defaults to $('element').childNodes)
+
+* Made tagifyText work with IE. defaults to a style of "position: relative; zoom:1;" for the created SPAN wrappers. It also replaces spaces with non-breakable spaces. These sit-ups are required to work around problems with rendering elements with the proprietary IE "layout" and non-quirksmode documents.
+
+* Add a break to scriptaculous.js when the includes are done [thx to Danilo Celic]
+
+* Fixed a problem with the Autocompleter when hitting ESC would select the entry in IE and redisplay the entries box in Safari
+
+* Fixed that the onDrop callback on Droppables didn't receive the dopped element as second parameter
+
+* Make check for correct Prototype version on loading script.aculo.us
+
+* Changed implementation of Builder to an innerHTML-based approach to make it work with IE6 (note: removed special "style" handling for now)
+
+* Changed non-sync Effects to use a common setInterval call for better timing and page update speeds. See the new Effect.Queue object.
+
+* Fixed a problem with setting opacity in Effect.Opacity to very small values
+
+* Changed the implemention of Effect.Base to use setInterval
+
+* Set version number to 1.5_pre4_trunk
+
+* Added experimental Effect.Text function that allows to start delayed text effects, see test/functional/texteffects_test.html.
+
+* Added experimental Effect.tagifyText(element) which wraps an elements text nodes characters in relatively positioned span elements
+
+* Added "delay" option to Effect.Base to start an effect only after a specified delay
+
+* Finetuning unittest.js + even more unit tests
+
+* Added support for Firefox and Konqueror automatic unit testing on Linux [Michael Schuerig]
+
+* Added basic unit test files for Effects, updated unit testing tests
+
+* Fix typo in lib/prototype.js fix in R2069 (whoops)
+
+* Added unit test for Position.clone
+
+* Made the Postition.cumulative override recognize KHTML and AppleWebKit
+
+* Fix the "hide form controls" iframe fix on the Autocompleter on Internet Explorer
+
+*V1.5.0_pre3*
+
+* More positioning fixes, expanded Element.clone [thx to Michael Schuerig]
+
+* Fixed some JavaScript warnings about redeclared vars [Courtenay]
+
+* Fixed a problem with autocompleting update divs not correctly positioned inside positioned elements [thx to Jonathan Feinberg]
+
+* Workaround for a Safari bug on absolutely positioned children of the BODY element
+
+* Added test/run_functional_test.html to more easily find your way around in the functional tests
+
+* Fixed some missing var declarations in effects.js
+
+* Support for automatic unit testing on IE/Win [Jon Tirsen]
+
+* Added loading the text for the Ajax.InPlaceEditor from the server, more CSS support [Richard Livsey, Jon Tirsen]
+
+* Made builder_test.html unit test work with Safari, fixed (one of two) caching issues with javascripttest.rb, added ajax_autocompleter_test.html to Rakefile unittests
+
+* Fixed Element.Class getting false matches on class names like classA-foobar, added unit tests [Martin Bialasinski]
+
+* Added a test to evluate the Fade/Appear effects across browsers and elements (test/functional/effects6_test.html)
+
+* Framework for completely self-running in-browser unit tests on Mac OS X (try "rake unittest") [Jon Tirsen]
+
+* Updates to Ajax.InPlaceEditor (Highlighting, Ajax options, more) [Jon Tirsen]
+
+* Made event registering on Draggables happen per drag for improved performance [thx to Cathy]
+
+* Moved Element.collectTextNodesIgnoreClass to util.js (preparation for refactoring)
+
+* Made sortable onChange option work again
+
+* Fixed a bug with Sortables resulting in wrong result when using Sortable.serialize with onUpdate on ghostly Sortables [thx Richard Livsey, Caleb Buxton]
+
+* Changed version number in scriptaculous.js to 1.5_pre3
+
+* Moved setting focus in Autocompleter to updateElement function to make it overridable [Brian Palmer]
+
+* Added special handling for style attributes to Builder [Michael Schuerig]
+
+* Changed opacity=1.0 check back to be inline with its original (pre 1.5) implementation to prevent flickering in Firefox < 1.1 on opacity-based effects (this also fixes flickering with drag-and-drop, sortable lists and autocompleting text fields). Note that this potentially breaks correct colors in some situations. [thx to David Zülke]
+
+* Automatically deactivate browser built-in autocompletion on autocompleting textfields, fixes part of Rails #1824.
+
+* Fixed a problem with Ajax.InPlaceEditor causing a JavaScript exception on Safari [thx to Patrick Lenz]
+
+*V1.5.0_pre2*
+
+* Fixed a weird character in dragdrop.js, added check to allow empty containers on Sortables (useful with dropOnEmpty option) [thx to Dave Strus]
+
+* Added unit test runner file test/run_unit_tests.html, new unit test files must be listed in test/unit/index.html
+
+* Added unit tests for Prototype string functions
+
+*V1.5.0_pre1*
+
+* Prepared README for V1.5.0_pre1
+
+* Added a main scriptaculous.js file to load in the other libraries transparently:
+
+ <script src="path/to/prototype.js" type="text/javascript"></script>
+ <script src="path/to/scriptaculous.js" type="text/javascript"></script>
+
+ in the HEAD section of an HTML file is now all that's needed to include all of the script.aculo.us libraries,
+ given that they all can be accessed by the same path as scriptaculous.js is.
+
+* Fixed possible problem with greedy Droppables when using the dropOnEmpty option on Sortable.create
+
+* Added new CSS/background color features to Ajax.InPlaceEditor [Jon Tirsen]
+
+* Added unit test for Autocompleter, first Version
+
+* Added Event.simulateKey/s to unittest.js. Note that due to a bug in Firefox this will only work with Firefox up to v1.0.4 (see https://bugzilla.mozilla.org/show_bug.cgi?id=289940)
+
+* Fixed a condition where standard a href=xxx links wouldn't work in autocomplete results. These do now, the onclick event is not cancelled. [thx to Jasper Slits]
+
+* Fix showing ghosting marker only on ghosting Sortables
+
+* Some more Builder stuff, expanded builder unit tests
+
+* Moved stuff that didn't belong into specific libs into util.js; util.js is now required for all script.aculo.us libs
+
+* Corrected weirdness in unittest.js
+
+* Added dropOnEmpty option to Sortables to allow dropping on empty lists (see test/functional/sortable3_test.html)
+
+* Changed algoritm for drag/drop position setting
+
+* Changed workaround for class attributes (fixes a Firefox 1.0 error) from klass to className to be more Javascriptesque [thx to Martin Bialasinski]
+
+* Fixed a typo in ajax_inplaceeditor_test.html
+
+* Updated Rakefile to add unittest.js and util.js to the package
+
+* Added util.js which contains various utlity functions and extensions to Prototype
+
+* Major restructuring
+
+* Added TEXTAREA support to Ajax.InPlaceEditor [Sanford Barr]
+
+* Added Ghost Train alpha 0.1.0. See ghosttrain/test.html.
+
+* More features for Ajax.InPlaceEditor [Jon Tirsen]
+
+* Tweaks to unittest.css [Thomas Fuchs]
+
+* Refactoring and new features in unittest.js [Thomas Fuchs] [Jon Tirsen]
+
+* Fixed a wrong variable reference in Effect.Scale
+
+* Fix Element.makePositioned to recognize the 'static' position
+
+* Allow to choose the parameter name for Ajax.Autocompleter [Cameron Braid]
+
+* Changed resolving indicator DOM element more flexibility [Cameron Braid]
+
+* Fixed a reference in Ajax.InPlaceEditor
+
+* Added contributors to unittest.js
+
+* Souped-up Ajax.InPlaceEditor, added support for a form id and specifying all the texts through options [Jon Tirsen]
+
+* Make unit testing look good [Michael Schuerig]
+
+* Changed default revert duration for Draggables to distance-dependent algorithm [suggested by San]
+
+* Fix double unescaping in Autocompleter
+
+* Refactoring auf Autocompleter classes to use camelCase (note: changes the syntax of some of the options)
+
+* Add updateElement option to Autocompleter [Rob Sharp]
+
+* Updated Ajax.InPlaceEditor, refactoring of unit testing [Jon Tirsen]
+
+* Added preliminary version of Ajax.InPlaceEditor to controls.js; added experimental Firefox only functional testing for it (inplaceeditor_result.html) [Jon Tirsen]
+
+* Added some addtional test files.
+
+* Fixes a bug with Droppables not recognizing a drop if no hoverclass is given [thanks drewie]
+
+* Fixes to ghosting marker, allow a predefined marker (element with id "dropmarker").
+
+* Changed Effect.Opacity to better handle 100% opacity
+
+* Various fixes to ghosting, improves compatiblity with Safari and IE. [thanks to David Zülke]
+
+* Added experimental ghosting option to Sortables. See sortable_functional_ghosting.html for usage.
+
+* Renamed the clone option on Draggables to "ghosting".
+
+* Added experimental "clone" option to Draggable to so that a "clone" stays in place while dragging a translucent version of the draggable element. Currently, this requires relatively positioned elements, and doesn't work with sortable lists (but should after some tweaking). See dragdrop_function_4.html test file for details.
+
+* Added Element.getStyle to find computed CSS styles of an element. Note: doesn't work in all cases in Safari, see my bug report at http://bugzilla.opendarwin.org/show_bug.cgi?id=4125
+
+*1.1beta1*
+
+* Fixed rendering of last frame of animation when from/to is not 0.0/1.0. [thanks to David Zülke]
+
+* Updated internal Prototype JavaScript framework to version 1.4.0_pre2 (patched w/ workaround for Ajax.Updater init bug)
+
+* Some refactoring of controls.js to get rid of "dirty" implementation detail (dont' ask)
+
+* Added returning the generated combined effects to allow for .cancel() on all effects
+
+* Updated internal Prototype JavaScript framework to version 1.4.0_pre2
+
+*Rails 0.13.1*
+
+* Updated Ajax.Autocompleter to deal with parameters options correctly [Martin Marinschek]
+
+* Updated controls.js to allow multple matches in local localcompletion [Ivan Krstic]
+
+* Make version of prototype.js in lib have a nicer Event object [David Zülke]
+
+* Added incremental and local autocompleting and loads of documentation to controls.js [Ivan Krstic]
+
+* Experimental: make version of prototype.js in lib destroy events on page unload to prevent browser memory leaks
+
+* Fixed a possible memory leak in dragdrop.js
+
+* Make version of prototype.js in lib compatible with some 3rd-party JavaScript libraries (like IE7) by refactoring to use Object.extend() for testing [David Zülke]
+
+* Make effects.js, dragdrop.js and controls.js compatible with some 3rd-party JavaScript libraries (like IE7) by refactoring to use Object.extend() [David Zülke]
+
+* Changed some tests to work better
+
+* Always reset background color on Effect.Highlight; this make change backwards-compatibility, to be sure include style="background-color:(target-color)" on your elements or else elements will fall back to their CSS rules (which is a good thing in most circumstances)
+
+* Removed a possible memory leaks with IE with sortables and droppables (removed references from elements)
+
+* Changes to class extension in effects.js
+
+* Make Effect.Highlight restore any previously set background color when finishing (makes effect work with set CSS classes)
+
+* Added capability to remove draggables/droppables and redeclare sortables in dragdrop.js
+
+* Added Effect.ScrollTo to smoothly scroll the page to an element
+
+* Better Firefox flickering handling on SlideUp/SlideDown
+
+* Some cleaning up in effects.js
+
+* Removed a possible memory leak in IE with draggables
+
+* Added support for cancelling dragging my hitting ESC
+
+* Changed logic of drag-and-drop to only include the last referenced droppable when firing a drop event. This change also offers slight performance gains. [Dominik Wagner]
+
+* Added addtional effects test page, added tests for scriptfragment matching
+
+*1.0.0*
+
+* Changed auto-hiding update div in Ajax.Autocompleter
+
+* Changed default serialization on Ajax.Autocompleter to use Form.Element.serialize
+
+* Added test file for drag/drop inside scrolled elements
+
+* Fixed dragging of unpositioned elements in Internet Explorer
+
+* Change default behaviour of Ajax.Autocompleter to do automatic overlapping, sizing and appear/fade effects
+
+* Fixed Internet Explorer hide-windowed-controls iframe handling
+
+* Changed Ajax.Autocompleter event handling
+
+* Added onShow/onHide callbacks to Ajax.Autocompleter to allow for customized handling/effects
+
+* Fixed SlideUp/SlideDown to restore the overflow CSS property (note: Firefox 1.0.X is buggy, set overflow:hidden as a workaround)
+
+* Fixed BlindUp/BlindDown to restore the overflow CSS property (note: Firefox 1.0.X is buggy, set overflow:hidden as a workaround)
+
+* Fixed draggables with revert:false on repeated drags behaving badly
+
+* Expanded the revert option on draggables to optionally take a function and revert only if it returns true
+
+* Added the dragged element as a parameter to the Draggables.notify callbacks [Michael Sokolov]
+
+* Removed a deprecated reference to Effect2 om Effect.Fold
+
+* Make the percentage on Element.setContentZoom absolute
+
+* Corrected rendering of Ajax.AutoCompleter when focus is lost while updating
+
+* Added (crude) functional tests
+
+* Some slight refactoring in controls.js
+
+* Changed dragdrop.js to use the Effect namespace for its effects
+
+* Updated to Prototype 1.3.0: removal of prototype-ext.js; refactoring.
+
+* Fixed behaviour of cursor keys in Safari on autocomplete script
+
+* Fixed Position.within_including_scrolloffsets
+
+* Fixed sortables that are absolutely positioned
+
+* Fixed unhandled whitespace in Ajax.Autocompleter
+
+* Updated prototype-ext.js to include additions for Ajax.Autocompleter
+
+* Added controls.js, contains AJAX autocompleting text fields from #960
+
+* Refactored Event object
+
+* Renamed effects2.js to effects.js
+
+* Fixed draggables on pages with no droppables
+
+* Moved Event, Position and Element.Class to prototype-ext.js in preparation to Rails 0.13
+
+* Added Effect.Transitions.pulse
+
+* Added Effect.Pulsate and Effect.Fold effect by Justin Palmer
+
+* Added transitions by Mark Pilgrim: .full, .none
+
+* Added effects by Mark Pilgrim: Effect.Grow, Effect.Shrink
+
+* Changed effects namespace to Effect. (Effect2 is deprecated, but works too)
+
+* Changed old Effect.ContentZoom class to Element.setContentZoom() function
+
+* Greatly expanded Effect.Highlight to have user-defined colors and autodetecting the background color
+
+* Converted remaining effects (Squish, Highlight) to new format
+
+* Sortable.create now passes the zindex, starteffect, reverteffect and endeffect options to the underlying Draggables
+
+* Sortable.serialize now honors the only option on Sortable.create
+
+* New overridable options on Draggables: zindex, starteffect, reverteffect, endeffect
+
+* Fix a Gecko engine flicker on Sortables in dragdrop.js
+
+* Fixed event.isLeftClick
+
+* Some small changes in effects2.js
+
+* Refactoring of dragdrop.js
+
+* Added an Object.prototype.inspect() and more verbose messages for js unit testing
+
+* Added test/unittest.js and initial tests in test/html.
+
+* Cleaning up of effects2.js (convert tabs to spaces)
+
+* Added Rakefile for distribution packaging (default task = make distribution, rake clean for cleaning up)
+
+* Initial check-in and directory layout for the script.aculo.us JavaScripts \ No newline at end of file
diff --git a/framework/Web/Javascripts/effects/MIT-LICENSE b/framework/Web/Javascripts/effects/MIT-LICENSE
new file mode 100644
index 00000000..27a25f8c
--- /dev/null
+++ b/framework/Web/Javascripts/effects/MIT-LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file
diff --git a/framework/Web/Javascripts/effects/README b/framework/Web/Javascripts/effects/README
new file mode 100644
index 00000000..7141a34a
--- /dev/null
+++ b/framework/Web/Javascripts/effects/README
@@ -0,0 +1,57 @@
+== script.aculo.us web 2.0 javascript
+
+The Web is changing. The 30-year-old terminal-like technology it was originally
+is gradually giving way to new ways of doing things. The power of AJAX allows
+for rich user interaction without the trouble that has bugged traditional
+web applications.
+
+Building upon the wonderful Prototype JavaScript library, script.aculo.us
+provides you with some great additional ingredients to mix in.
+
+For more information, see http://script.aculo.us/
+
+== What's new in this release?
+
+See the CHANGELOG file for information on what's new.
+
+== Installation/Usage
+
+This pre-release version of script.aculo.us includes the
+Prototype framework 1.4.0_rc3. You can use later versions,
+as they become available (see http://prototype.conio.net).
+
+Put prototype.js, and the six files scriptaculous.js,
+builder.js, effects.js, dragdrop.js, controls.js and slider.js
+in a directory of your website, e.g. /javascripts.
+
+(The unittest.js file is optional and is only needed if you
+want to do unit testing on your own javascripts).
+
+Now, you can include the scripts by adding the following
+tags to the HEAD section of your HTML pages:
+
+ <script src="/javascripts/prototype.js" type="text/javascript"></script>
+ <script src="/javascripts/scriptaculous.js" type="text/javascript"></script>
+
+scriptaculous.js will automatically load the other files of the
+script.aculo.us distribution in, provided they are accessible
+via the same path.
+
+See http://wiki.script.aculo.us/scriptaculous/show/Usage for detailed
+usage instructions.
+
+== The distribution
+
+Besides the script.aculo.us files in src, there's a complete
+test tree included which holds functional and unit tests for
+script.aculo.us.
+
+If you need examples on how to implement things, the best place to
+start is by opening test/run_functional_tests.html or
+test/run_unit_tests.html in your browser, and looking at
+the sources of the examples provided.
+
+== License
+
+script.aculo.us is licensed under the terms of the MIT License,
+see the included MIT-LICENSE file. \ No newline at end of file
diff --git a/framework/Web/Javascripts/effects/builder.js b/framework/Web/Javascripts/effects/builder.js
new file mode 100644
index 00000000..7c3a4538
--- /dev/null
+++ b/framework/Web/Javascripts/effects/builder.js
@@ -0,0 +1,101 @@
+// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+//
+// See scriptaculous.js for full license.
+
+var Builder = {
+ NODEMAP: {
+ AREA: 'map',
+ CAPTION: 'table',
+ COL: 'table',
+ COLGROUP: 'table',
+ LEGEND: 'fieldset',
+ OPTGROUP: 'select',
+ OPTION: 'select',
+ PARAM: 'object',
+ TBODY: 'table',
+ TD: 'table',
+ TFOOT: 'table',
+ TH: 'table',
+ THEAD: 'table',
+ TR: 'table'
+ },
+ // note: For Firefox < 1.5, OPTION and OPTGROUP tags are currently broken,
+ // due to a Firefox bug
+ node: function(elementName) {
+ elementName = elementName.toUpperCase();
+
+ // try innerHTML approach
+ var parentTag = this.NODEMAP[elementName] || 'div';
+ var parentElement = document.createElement(parentTag);
+ try { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707
+ parentElement.innerHTML = "<" + elementName + "></" + elementName + ">";
+ } catch(e) {}
+ var element = parentElement.firstChild || null;
+
+ // see if browser added wrapping tags
+ if(element && (element.tagName != elementName))
+ element = element.getElementsByTagName(elementName)[0];
+
+ // fallback to createElement approach
+ if(!element) element = document.createElement(elementName);
+
+ // abort if nothing could be created
+ if(!element) return;
+
+ // attributes (or text)
+ if(arguments[1])
+ if(this._isStringOrNumber(arguments[1]) ||
+ (arguments[1] instanceof Array)) {
+ this._children(element, arguments[1]);
+ } else {
+ var attrs = this._attributes(arguments[1]);
+ if(attrs.length) {
+ try { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707
+ parentElement.innerHTML = "<" +elementName + " " +
+ attrs + "></" + elementName + ">";
+ } catch(e) {}
+ element = parentElement.firstChild || null;
+ // workaround firefox 1.0.X bug
+ if(!element) {
+ element = document.createElement(elementName);
+ for(attr in arguments[1])
+ element[attr == 'class' ? 'className' : attr] = arguments[1][attr];
+ }
+ if(element.tagName != elementName)
+ element = parentElement.getElementsByTagName(elementName)[0];
+ }
+ }
+
+ // text, or array of children
+ if(arguments[2])
+ this._children(element, arguments[2]);
+
+ return element;
+ },
+ _text: function(text) {
+ return document.createTextNode(text);
+ },
+ _attributes: function(attributes) {
+ var attrs = [];
+ for(attribute in attributes)
+ attrs.push((attribute=='className' ? 'class' : attribute) +
+ '="' + attributes[attribute].toString().escapeHTML() + '"');
+ return attrs.join(" ");
+ },
+ _children: function(element, children) {
+ if(typeof children=='object') { // array can hold nodes and text
+ children.flatten().each( function(e) {
+ if(typeof e=='object')
+ element.appendChild(e)
+ else
+ if(Builder._isStringOrNumber(e))
+ element.appendChild(Builder._text(e));
+ });
+ } else
+ if(Builder._isStringOrNumber(children))
+ element.appendChild(Builder._text(children));
+ },
+ _isStringOrNumber: function(param) {
+ return(typeof param=='string' || typeof param=='number');
+ }
+} \ No newline at end of file
diff --git a/framework/Web/Javascripts/effects/controls.js b/framework/Web/Javascripts/effects/controls.js
index 5212df51..9a67bc7f 100644
--- a/framework/Web/Javascripts/effects/controls.js
+++ b/framework/Web/Javascripts/effects/controls.js
@@ -80,7 +80,10 @@ Autocompleter.Base.prototype = {
show: function() {
if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update);
- if(!this.iefix && (navigator.appVersion.indexOf('MSIE')>0) && (Element.getStyle(this.update, 'position')=='absolute')) {
+ if(!this.iefix &&
+ (navigator.appVersion.indexOf('MSIE')>0) &&
+ (navigator.userAgent.indexOf('Opera')<0) &&
+ (Element.getStyle(this.update, 'position')=='absolute')) {
new Insertion.After(this.update,
'<iframe id="' + this.update.id + '_iefix" '+
'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" ' +
@@ -184,7 +187,10 @@ Autocompleter.Base.prototype = {
this.show();
this.active = true;
}
- } else this.hide();
+ } else {
+ this.active = false;
+ this.hide();
+ }
},
markPrevious: function() {
@@ -296,7 +302,6 @@ Autocompleter.Base.prototype = {
}
}
-/*
Ajax.Autocompleter = Class.create();
Object.extend(Object.extend(Ajax.Autocompleter.prototype, Autocompleter.Base.prototype), {
initialize: function(element, update, url, options) {
@@ -325,7 +330,6 @@ Object.extend(Object.extend(Ajax.Autocompleter.prototype, Autocompleter.Base.pro
}
});
-*/
// The local array autocompleter. Used when you'd prefer to
// inject an array of autocompletion options into the page, rather
@@ -426,7 +430,16 @@ Autocompleter.Local.prototype = Object.extend(new Autocompleter.Base(), {
// AJAX in-place editor
//
// see documentation on http://wiki.script.aculo.us/scriptaculous/show/Ajax.InPlaceEditor
-/*
+
+// Use this if you notice weird scrolling problems on some browsers,
+// the DOM might be a bit confused when this gets called so do this
+// waits 1 ms (with setTimeout) until it does the activation
+Field.scrollFreeActivate = function(field) {
+ setTimeout(function() {
+ Field.activate(field);
+ }, 1);
+}
+
Ajax.InPlaceEditor = Class.create();
Ajax.InPlaceEditor.defaultHighlightColor = "#FFFF99";
Ajax.InPlaceEditor.prototype = {
@@ -492,7 +505,7 @@ Ajax.InPlaceEditor.prototype = {
Event.observe(this.options.externalControl, 'mouseout', this.mouseoutListener);
}
},
- enterEditMode: function() {
+ enterEditMode: function(evt) {
if (this.saving) return;
if (this.editing) return;
this.editing = true;
@@ -503,11 +516,12 @@ Ajax.InPlaceEditor.prototype = {
Element.hide(this.element);
this.createForm();
this.element.parentNode.insertBefore(this.form, this.element);
- Field.focus(this.editField);
+ Field.scrollFreeActivate(this.editField);
// stop the event to avoid a page refresh in Safari
- if (arguments.length > 1) {
- Event.stop(arguments[0]);
+ if (evt) {
+ Event.stop(evt);
}
+ return false;
},
createForm: function() {
this.form = document.createElement("form");
@@ -708,4 +722,29 @@ Ajax.InPlaceEditor.prototype = {
}
}
};
-*/ \ No newline at end of file
+
+// Delayed observer, like Form.Element.Observer,
+// but waits for delay after last key input
+// Ideal for live-search fields
+
+Form.Element.DelayedObserver = Class.create();
+Form.Element.DelayedObserver.prototype = {
+ initialize: function(element, delay, callback) {
+ this.delay = delay || 0.5;
+ this.element = $(element);
+ this.callback = callback;
+ this.timer = null;
+ this.lastValue = $F(this.element);
+ Event.observe(this.element,'keyup',this.delayedListener.bindAsEventListener(this));
+ },
+ delayedListener: function(event) {
+ if(this.lastValue == $F(this.element)) return;
+ if(this.timer) clearTimeout(this.timer);
+ this.timer = setTimeout(this.onTimerEvent.bind(this), this.delay * 1000);
+ this.lastValue = $F(this.element);
+ },
+ onTimerEvent: function() {
+ this.timer = null;
+ this.callback(this.element, $F(this.element));
+ }
+}; \ No newline at end of file
diff --git a/framework/Web/Javascripts/effects/dragdrop.js b/framework/Web/Javascripts/effects/dragdrop.js
index bfb6e8e9..5b4dc883 100644
--- a/framework/Web/Javascripts/effects/dragdrop.js
+++ b/framework/Web/Javascripts/effects/dragdrop.js
@@ -1,7 +1,5 @@
// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
//
-// Element.Class part Copyright (c) 2005 by Rick Olson
-//
// See scriptaculous.js for full license.
/*--------------------------------------------------------------------------*/
@@ -10,7 +8,7 @@ var Droppables = {
drops: [],
remove: function(element) {
- this.drops = this.drops.reject(function(d) { return d.element==element });
+ this.drops = this.drops.reject(function(d) { return d.element==$(element) });
},
add: function(element) {
@@ -31,6 +29,8 @@ var Droppables = {
options._containers.push($(containment));
}
}
+
+ if(options.accept) options.accept = [options.accept].flatten();
Element.makePositioned(element); // fix IE
options.element = element;
@@ -43,55 +43,51 @@ var Droppables = {
return drop._containers.detect(function(c) { return parentNode == c });
},
- isAffected: function(pX, pY, element, drop) {
+ isAffected: function(point, element, drop) {
return (
(drop.element!=element) &&
((!drop._containers) ||
this.isContained(element, drop)) &&
((!drop.accept) ||
- (Element.Class.has_any(element, drop.accept))) &&
- Position.within(drop.element, pX, pY) );
+ (Element.classNames(element).detect(
+ function(v) { return drop.accept.include(v) } ) )) &&
+ Position.within(drop.element, point[0], point[1]) );
},
deactivate: function(drop) {
if(drop.hoverclass)
- Element.Class.remove(drop.element, drop.hoverclass);
+ Element.removeClassName(drop.element, drop.hoverclass);
this.last_active = null;
},
activate: function(drop) {
- if(this.last_active) this.deactivate(this.last_active);
if(drop.hoverclass)
- Element.Class.add(drop.element, drop.hoverclass);
+ Element.addClassName(drop.element, drop.hoverclass);
this.last_active = drop;
},
- show: function(event, element) {
+ show: function(point, element) {
if(!this.drops.length) return;
- var pX = Event.pointerX(event);
- var pY = Event.pointerY(event);
- Position.prepare();
-
- var i = this.drops.length-1; do {
- var drop = this.drops[i];
- if(this.isAffected(pX, pY, element, drop)) {
+
+ if(this.last_active) this.deactivate(this.last_active);
+ this.drops.each( function(drop) {
+ if(Droppables.isAffected(point, element, drop)) {
if(drop.onHover)
drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element));
if(drop.greedy) {
- this.activate(drop);
- return;
+ Droppables.activate(drop);
+ //why throw an exception?
+ //throw $break;
}
}
- } while (i--);
-
- if(this.last_active) this.deactivate(this.last_active);
+ });
},
fire: function(event, element) {
if(!this.last_active) return;
Position.prepare();
- if (this.isAffected(Event.pointerX(event), Event.pointerY(event), element, this.last_active))
+ if (this.isAffected([Event.pointerX(event), Event.pointerY(event)], element, this.last_active))
if (this.last_active.onDrop)
this.last_active.onDrop(element, this.last_active.element, event);
},
@@ -103,15 +99,84 @@ var Droppables = {
}
var Draggables = {
+ drags: [],
observers: [],
+
+ register: function(draggable) {
+ if(this.drags.length == 0) {
+ this.eventMouseUp = this.endDrag.bindAsEventListener(this);
+ this.eventMouseMove = this.updateDrag.bindAsEventListener(this);
+ this.eventKeypress = this.keyPress.bindAsEventListener(this);
+
+ Event.observe(document, "mouseup", this.eventMouseUp);
+ Event.observe(document, "mousemove", this.eventMouseMove);
+ Event.observe(document, "keypress", this.eventKeypress);
+ }
+ this.drags.push(draggable);
+ },
+
+ unregister: function(draggable) {
+ this.drags = this.drags.reject(function(d) { return d==draggable });
+ if(this.drags.length == 0) {
+ Event.stopObserving(document, "mouseup", this.eventMouseUp);
+ Event.stopObserving(document, "mousemove", this.eventMouseMove);
+ Event.stopObserving(document, "keypress", this.eventKeypress);
+ }
+ },
+
+ activate: function(draggable) {
+ window.focus(); // allows keypress events if window isn't currently focused, fails for Safari
+ this.activeDraggable = draggable;
+ },
+
+ deactivate: function(draggbale) {
+ this.activeDraggable = null;
+ },
+
+ updateDrag: function(event) {
+ if(!this.activeDraggable) return;
+ var pointer = [Event.pointerX(event), Event.pointerY(event)];
+ // Mozilla-based browsers fire successive mousemove events with
+ // the same coordinates, prevent needless redrawing (moz bug?)
+ if(this._lastPointer && (this._lastPointer.inspect() == pointer.inspect())) return;
+ this._lastPointer = pointer;
+ this.activeDraggable.updateDrag(event, pointer);
+ },
+
+ endDrag: function(event) {
+ if(!this.activeDraggable) return;
+ this._lastPointer = null;
+ this.activeDraggable.endDrag(event);
+ },
+
+ keyPress: function(event) {
+ if(this.activeDraggable)
+ this.activeDraggable.keyPress(event);
+ },
+
addObserver: function(observer) {
- this.observers.push(observer);
+ this.observers.push(observer);
+ this._cacheObserverCallbacks();
},
- removeObserver: function(element) { // element instead of obsever fixes mem leaks
+
+ removeObserver: function(element) { // element instead of observer fixes mem leaks
this.observers = this.observers.reject( function(o) { return o.element==element });
+ this._cacheObserverCallbacks();
+ },
+
+ notify: function(eventName, draggable, event) { // 'onStart', 'onEnd', 'onDrag'
+ if(this[eventName+'Count'] > 0)
+ this.observers.each( function(o) {
+ if(o[eventName]) o[eventName](eventName, draggable, event);
+ });
},
- notify: function(eventName, draggable) { // 'onStart', 'onEnd'
- this.observers.invoke(eventName, draggable);
+
+ _cacheObserverCallbacks: function() {
+ ['onStart','onEnd','onDrag'].each( function(eventName) {
+ Draggables[eventName+'Count'] = Draggables.observers.select(
+ function(o) { return o[eventName]; }
+ ).length;
+ });
}
}
@@ -120,7 +185,7 @@ var Draggables = {
var Draggable = Class.create();
Draggable.prototype = {
initialize: function(element) {
- this.element = $(element);
+ this.element = $(element);
var options = Object.extend({
handle: false,
starteffect: function(element) {
@@ -128,67 +193,46 @@ Draggable.prototype = {
},
reverteffect: function(element, top_offset, left_offset) {
var dur = Math.sqrt(Math.abs(top_offset^2)+Math.abs(left_offset^2))*0.02;
- new Effect.MoveBy(element, -top_offset, -left_offset, {duration:dur});
+ element._revert = new Effect.MoveBy(element, -top_offset, -left_offset, {duration:dur});
},
endeffect: function(element) {
- new Effect.Opacity(element, {duration:0.2, from:0.7, to:1.0});
+ new Effect.Opacity(element, {duration:0.2, from:0.7, to:1.0});
},
zindex: 1000,
- revert: false
+ revert: false,
+ snap: false // false, or xy or [x,y] or function(x,y){ return [x,y] }
}, arguments[1] || {});
-
+
if(options.handle && (typeof options.handle == 'string'))
- this.handle = Element.Class.childrenWith(this.element, options.handle)[0];
-
+ this.handle = Element.childrenWithClassName(this.element, options.handle)[0];
if(!this.handle) this.handle = $(options.handle);
if(!this.handle) this.handle = this.element;
Element.makePositioned(this.element); // fix IE
- this.offsetX = 0;
- this.offsetY = 0;
- this.originalLeft = this.currentLeft();
- this.originalTop = this.currentTop();
- this.originalX = this.element.offsetLeft;
- this.originalY = this.element.offsetTop;
-
- this.options = options;
+ this.delta = this.currentDelta();
+ this.options = options;
+ this.dragging = false;
- this.active = false;
- this.dragging = false;
-
- this.eventMouseDown = this.startDrag.bindAsEventListener(this);
- this.eventMouseUp = this.endDrag.bindAsEventListener(this);
- this.eventMouseMove = this.update.bindAsEventListener(this);
- this.eventKeypress = this.keyPress.bindAsEventListener(this);
+ this.eventMouseDown = this.initDrag.bindAsEventListener(this);
+ Event.observe(this.handle, "mousedown", this.eventMouseDown);
- this.registerEvents();
+ Draggables.register(this);
},
+
destroy: function() {
Event.stopObserving(this.handle, "mousedown", this.eventMouseDown);
- this.unregisterEvents();
+ Draggables.unregister(this);
},
- registerEvents: function() {
- Event.observe(document, "mouseup", this.eventMouseUp);
- Event.observe(document, "mousemove", this.eventMouseMove);
- Event.observe(document, "keypress", this.eventKeypress);
- Event.observe(this.handle, "mousedown", this.eventMouseDown);
- },
- unregisterEvents: function() {
- //if(!this.active) return;
- //Event.stopObserving(document, "mouseup", this.eventMouseUp);
- //Event.stopObserving(document, "mousemove", this.eventMouseMove);
- //Event.stopObserving(document, "keypress", this.eventKeypress);
- },
- currentLeft: function() {
- return parseInt(this.element.style.left || '0');
+
+ currentDelta: function() {
+ return([
+ parseInt(this.element.style.left || '0'),
+ parseInt(this.element.style.top || '0')]);
},
- currentTop: function() {
- return parseInt(this.element.style.top || '0')
- },
- startDrag: function(event) {
- if(Event.isLeftClick(event)) {
-
+
+ initDrag: function(event) {
+ if(Event.isLeftClick(event)) {
// abort on form elements, fixes a Firefox issue
var src = Event.element(event);
if(src.tagName && (
@@ -196,20 +240,53 @@ Draggable.prototype = {
src.tagName=='SELECT' ||
src.tagName=='BUTTON' ||
src.tagName=='TEXTAREA')) return;
+
+ if(this.element._revert) {
+ this.element._revert.cancel();
+ this.element._revert = null;
+ }
- // this.registerEvents();
- this.active = true;
var pointer = [Event.pointerX(event), Event.pointerY(event)];
- var offsets = Position.cumulativeOffset(this.element);
- this.offsetX = (pointer[0] - offsets[0]);
- this.offsetY = (pointer[1] - offsets[1]);
+ var pos = Position.cumulativeOffset(this.element);
+ this.offset = [0,1].map( function(i) { return (pointer[i] - pos[i]) });
+
+ Draggables.activate(this);
Event.stop(event);
}
},
+
+ startDrag: function(event) {
+ this.dragging = true;
+
+ if(this.options.zindex) {
+ this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0);
+ this.element.style.zIndex = this.options.zindex;
+ }
+
+ if(this.options.ghosting) {
+ this._clone = this.element.cloneNode(true);
+ Position.absolutize(this.element);
+ this.element.parentNode.insertBefore(this._clone, this.element);
+ }
+
+ Draggables.notify('onStart', this, event);
+ if(this.options.starteffect) this.options.starteffect(this.element);
+ },
+
+ updateDrag: function(event, pointer) {
+ if(!this.dragging) this.startDrag(event);
+ Position.prepare();
+ Droppables.show(pointer, this.element);
+ Draggables.notify('onDrag', this, event);
+ this.draw(pointer);
+ if(this.options.change) this.options.change(this);
+
+ // fix AppleWebKit rendering
+ if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
+ Event.stop(event);
+ },
+
finishDrag: function(event, success) {
- // this.unregisterEvents();
-
- this.active = false;
this.dragging = false;
if(this.options.ghosting) {
@@ -219,18 +296,17 @@ Draggable.prototype = {
}
if(success) Droppables.fire(event, this.element);
- Draggables.notify('onEnd', this);
+ Draggables.notify('onEnd', this, event);
var revert = this.options.revert;
if(revert && typeof revert == 'function') revert = revert(this.element);
-
+
+ var d = this.currentDelta();
if(revert && this.options.reverteffect) {
this.options.reverteffect(this.element,
- this.currentTop()-this.originalTop,
- this.currentLeft()-this.originalLeft);
+ d[1]-this.delta[1], d[0]-this.delta[0]);
} else {
- this.originalLeft = this.currentLeft();
- this.originalTop = this.currentTop();
+ this.delta = d;
}
if(this.options.zindex)
@@ -239,70 +315,48 @@ Draggable.prototype = {
if(this.options.endeffect)
this.options.endeffect(this.element);
-
+ Draggables.deactivate(this);
Droppables.reset();
},
+
keyPress: function(event) {
- if(this.active) {
- if(event.keyCode==Event.KEY_ESC) {
- this.finishDrag(event, false);
- Event.stop(event);
- }
- }
+ if(!event.keyCode==Event.KEY_ESC) return;
+ this.finishDrag(event, false);
+ Event.stop(event);
},
+
endDrag: function(event) {
- if(this.active && this.dragging) {
- this.finishDrag(event, true);
- Event.stop(event);
- }
- this.active = false;
- this.dragging = false;
+ if(!this.dragging) return;
+ this.finishDrag(event, true);
+ Event.stop(event);
},
- draw: function(event) {
- var pointer = [Event.pointerX(event), Event.pointerY(event)];
- var offsets = Position.cumulativeOffset(this.element);
- offsets[0] -= this.currentLeft();
- offsets[1] -= this.currentTop();
+
+ draw: function(point) {
+ var pos = Position.cumulativeOffset(this.element);
+ var d = this.currentDelta();
+ pos[0] -= d[0]; pos[1] -= d[1];
+
+ var p = [0,1].map(function(i){ return (point[i]-pos[i]-this.offset[i]) }.bind(this));
+
+ if(this.options.snap) {
+ if(typeof this.options.snap == 'function') {
+ p = this.options.snap(p[0],p[1]);
+ } else {
+ if(this.options.snap instanceof Array) {
+ p = p.map( function(v, i) {
+ return Math.round(v/this.options.snap[i])*this.options.snap[i] }.bind(this))
+ } else {
+ p = p.map( function(v) {
+ return Math.round(v/this.options.snap)*this.options.snap }.bind(this))
+ }
+ }}
+
var style = this.element.style;
if((!this.options.constraint) || (this.options.constraint=='horizontal'))
- style.left = (pointer[0] - offsets[0] - this.offsetX) + "px";
+ style.left = p[0] + "px";
if((!this.options.constraint) || (this.options.constraint=='vertical'))
- style.top = (pointer[1] - offsets[1] - this.offsetY) + "px";
+ style.top = p[1] + "px";
if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering
- },
- update: function(event) {
- if(this.active) {
- if(!this.dragging) {
- var style = this.element.style;
- this.dragging = true;
-
- if(Element.getStyle(this.element,'position')=='')
- style.position = "relative";
-
- if(this.options.zindex) {
- this.options.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0);
- style.zIndex = this.options.zindex;
- }
-
- if(this.options.ghosting) {
- this._clone = this.element.cloneNode(true);
- Position.absolutize(this.element);
- this.element.parentNode.insertBefore(this._clone, this.element);
- }
-
- Draggables.notify('onStart', this);
- if(this.options.starteffect) this.options.starteffect(this.element);
- }
-
- Droppables.show(event, this.element);
- this.draw(event);
- if(this.options.change) this.options.change(this);
-
- // fix AppleWebKit rendering
- if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
-
- Event.stop(event);
- }
}
}
@@ -315,9 +369,11 @@ SortableObserver.prototype = {
this.observer = observer;
this.lastValue = Sortable.serialize(this.element);
},
+
onStart: function() {
this.lastValue = Sortable.serialize(this.element);
},
+
onEnd: function() {
Sortable.unmark();
if(this.lastValue != Sortable.serialize(this.element))
@@ -327,10 +383,12 @@ SortableObserver.prototype = {
var Sortable = {
sortables: new Array(),
+
options: function(element){
element = $(element);
return this.sortables.detect(function(s) { return s.element == element });
},
+
destroy: function(element){
element = $(element);
this.sortables.findAll(function(s) { return s.element == element }).each(function(s){
@@ -340,6 +398,7 @@ var Sortable = {
});
this.sortables = this.sortables.reject(function(s) { return s.element == element });
},
+
create: function(element) {
element = $(element);
var options = Object.extend({
@@ -355,8 +414,8 @@ var Sortable = {
hoverclass: null,
ghosting: false,
format: null,
- onChange: function() {},
- onUpdate: function() {}
+ onChange: Prototype.emptyFunction,
+ onUpdate: Prototype.emptyFunction
}, arguments[1] || {});
// clear any old sortable with same element
@@ -413,7 +472,7 @@ var Sortable = {
(this.findElements(element, options) || []).each( function(e) {
// handles are per-draggable
var handle = options.handle ?
- Element.Class.childrenWith(e, options.handle)[0] : e;
+ Element.childrenWithClassName(e, options.handle)[0] : e;
options.draggables.push(
new Draggable(e, Object.extend(options_for_draggable, { handle: handle })));
Droppables.add(e, options_for_droppable);
@@ -433,8 +492,8 @@ var Sortable = {
if(!element.hasChildNodes()) return null;
var elements = [];
$A(element.childNodes).each( function(e) {
- if(e.tagName && e.tagName==options.tag.toUpperCase() &&
- (!options.only || (Element.Class.has(e, options.only))))
+ if(e.tagName && e.tagName.toUpperCase()==options.tag.toUpperCase() &&
+ (!options.only || (Element.hasClassName(e, options.only))))
elements.push(e);
if(options.tree) {
var grandchildren = this.findElements(e, options);
@@ -472,7 +531,10 @@ var Sortable = {
onEmptyHover: function(element, dropon) {
if(element.parentNode!=dropon) {
+ var oldParentNode = element.parentNode;
dropon.appendChild(element);
+ Sortable.options(oldParentNode).onChange(element);
+ Sortable.options(dropon).onChange(element);
}
},
@@ -488,14 +550,20 @@ var Sortable = {
if(!Sortable._marker) {
Sortable._marker = $('dropmarker') || document.createElement('DIV');
Element.hide(Sortable._marker);
- Element.Class.add(Sortable._marker, 'dropmarker');
+ Element.addClassName(Sortable._marker, 'dropmarker');
Sortable._marker.style.position = 'absolute';
document.getElementsByTagName("body").item(0).appendChild(Sortable._marker);
}
var offsets = Position.cumulativeOffset(dropon);
- Sortable._marker.style.top = offsets[1] + 'px';
- if(position=='after') Sortable._marker.style.top = (offsets[1]+dropon.clientHeight) + 'px';
Sortable._marker.style.left = offsets[0] + 'px';
+ Sortable._marker.style.top = offsets[1] + 'px';
+
+ if(position=='after')
+ if(sortable.overlap == 'horizontal')
+ Sortable._marker.style.left = (offsets[0]+dropon.clientWidth) + 'px';
+ else
+ Sortable._marker.style.top = (offsets[1]+dropon.clientHeight) + 'px';
+
Element.show(Sortable._marker);
},
@@ -508,9 +576,9 @@ var Sortable = {
name: element.id,
format: sortableOptions.format || /^[^_]*_(.*)$/
}, arguments[1] || {});
- return $(this.findElements(element, options) || []).collect( function(item) {
+ return $(this.findElements(element, options) || []).map( function(item) {
return (encodeURIComponent(options.name) + "[]=" +
encodeURIComponent(item.id.match(options.format) ? item.id.match(options.format)[1] : ''));
}).join("&");
}
-} \ No newline at end of file
+} \ No newline at end of file
diff --git a/framework/Web/Javascripts/effects/effects.js b/framework/Web/Javascripts/effects/effects.js
index 62aa9a3e..10f4fa7e 100644
--- a/framework/Web/Javascripts/effects/effects.js
+++ b/framework/Web/Javascripts/effects/effects.js
@@ -4,19 +4,107 @@
// Mark Pilgrim (http://diveintomark.org/)
// Martin Bialasinki
//
-// See scriptaculous.js for full license.
+// See scriptaculous.js for full license.
+
+/* ------------- element ext -------------- */
+
+// converts rgb() and #xxx to #xxxxxx format,
+// returns self (or first argument) if not convertable
+String.prototype.parseColor = function() {
+ var color = '#';
+ if(this.slice(0,4) == 'rgb(') {
+ var cols = this.slice(4,this.length-1).split(',');
+ var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3);
+ } else {
+ if(this.slice(0,1) == '#') {
+ if(this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase();
+ if(this.length==7) color = this.toLowerCase();
+ }
+ }
+ return(color.length==7 ? color : (arguments[0] || this));
+}
+
+Element.collectTextNodesIgnoreClass = function(element, ignoreclass) {
+ var children = $(element).childNodes;
+ var text = '';
+ var classtest = new RegExp('^([^ ]+ )*' + ignoreclass+ '( [^ ]+)*$','i');
+
+ for (var i = 0; i < children.length; i++) {
+ if(children[i].nodeType==3) {
+ text+=children[i].nodeValue;
+ } else {
+ if((!children[i].className.match(classtest)) && children[i].hasChildNodes())
+ text += Element.collectTextNodesIgnoreClass(children[i], ignoreclass);
+ }
+ }
+
+ return text;
+}
+
+Element.setStyle = function(element, style) {
+ element = $(element);
+ for(k in style) element.style[k.camelize()] = style[k];
+}
+
+Element.setContentZoom = function(element, percent) {
+ Element.setStyle(element, {fontSize: (percent/100) + 'em'});
+ if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
+}
+
+Element.getOpacity = function(element){
+ var opacity;
+ if (opacity = Element.getStyle(element, 'opacity'))
+ return parseFloat(opacity);
+ if (opacity = (Element.getStyle(element, 'filter') || '').match(/alpha\(opacity=(.*)\)/))
+ if(opacity[1]) return parseFloat(opacity[1]) / 100;
+ return 1.0;
+}
+
+Element.setOpacity = function(element, value){
+ element= $(element);
+ if (value == 1){
+ Element.setStyle(element, { opacity:
+ (/Gecko/.test(navigator.userAgent) && !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ?
+ 0.999999 : null });
+ if(/MSIE/.test(navigator.userAgent))
+ Element.setStyle(element, {filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'')});
+ } else {
+ if(value < 0.00001) value = 0;
+ Element.setStyle(element, {opacity: value});
+ if(/MSIE/.test(navigator.userAgent))
+ Element.setStyle(element,
+ { filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'') +
+ 'alpha(opacity='+value*100+')' });
+ }
+}
+
+Element.getInlineOpacity = function(element){
+ return $(element).style.opacity || '';
+}
+
+Element.childrenWithClassName = function(element, className) {
+ return $A($(element).getElementsByTagName('*')).select(
+ function(c) { return Element.hasClassName(c, className) });
+}
+
+Array.prototype.call = function() {
+ var args = arguments;
+ this.each(function(f){ f.apply(this, args) });
+}
+
+/*--------------------------------------------------------------------------*/
var Effect = {
tagifyText: function(element) {
- var tagifyStyle = "position:relative";
- if(/MSIE/.test(navigator.userAgent)) tagifyStyle += ";zoom:1";
+ var tagifyStyle = 'position:relative';
+ if(/MSIE/.test(navigator.userAgent)) tagifyStyle += ';zoom:1';
element = $(element);
$A(element.childNodes).each( function(child) {
if(child.nodeType==3) {
child.nodeValue.toArray().each( function(character) {
element.insertBefore(
Builder.node('span',{style: tagifyStyle},
- character == " " ? String.fromCharCode(160) : character),
+ character == ' ' ? String.fromCharCode(160) : character),
child);
});
Element.remove(child);
@@ -36,11 +124,10 @@ var Effect = {
speed: 0.1,
delay: 0.0
}, arguments[2] || {});
- var speed = options.speed;
- var delay = options.delay;
+ var masterDelay = options.delay;
$A(elements).each( function(element, index) {
- new effect(element, Object.extend(options, { delay: delay + index * speed }));
+ new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay }));
});
}
};
@@ -81,6 +168,9 @@ Effect.Transitions.full = function(pos) {
Effect.Queue = {
effects: [],
+ _each: function(iterator) {
+ this.effects._each(iterator);
+ },
interval: null,
add: function(effect) {
var timestamp = new Date().getTime();
@@ -117,6 +207,7 @@ Effect.Queue = {
this.effects.invoke('loop', timePos);
}
}
+Object.extend(Effect.Queue, Enumerable);
Effect.Base = function() {};
Effect.Base.prototype = {
@@ -167,13 +258,15 @@ Effect.Base.prototype = {
if(this.setup) this.setup();
this.event('afterSetup');
}
- if(this.options.transition) pos = this.options.transition(pos);
- pos *= (this.options.to-this.options.from);
- pos += this.options.from;
- this.position = pos;
- this.event('beforeUpdate');
- if(this.update) this.update(pos);
- this.event('afterUpdate');
+ if(this.state == 'running') {
+ if(this.options.transition) pos = this.options.transition(pos);
+ pos *= (this.options.to-this.options.from);
+ pos += this.options.from;
+ this.position = pos;
+ this.event('beforeUpdate');
+ if(this.update) this.update(pos);
+ this.event('afterUpdate');
+ }
},
cancel: function() {
if(!this.options.sync) Effect.Queue.remove(this);
@@ -182,6 +275,9 @@ Effect.Base.prototype = {
event: function(eventName) {
if(this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this);
if(this.options[eventName]) this.options[eventName](this);
+ },
+ inspect: function() {
+ return '#<Effect:' + $H(this).inspect() + ',options:' + $H(this.options).inspect() + '>';
}
}
@@ -211,7 +307,7 @@ Object.extend(Object.extend(Effect.Opacity.prototype, Effect.Base.prototype), {
this.element = $(element);
// make this work on IE on elements without 'layout'
if(/MSIE/.test(navigator.userAgent) && (!this.element.hasLayout))
- this.element.style.zoom = 1;
+ Element.setStyle(this.element, {zoom: 1});
var options = Object.extend({
from: Element.getOpacity(this.element) || 0.0,
to: 1.0
@@ -235,20 +331,16 @@ Object.extend(Object.extend(Effect.MoveBy.prototype, Effect.Base.prototype), {
// Bug in Opera: Opera returns the "real" position of a static element or
// relative element that does not have top/left explicitly set.
// ==> Always set top and left for position relative elements in your stylesheets
- // (to 0 if you do not need them)
-
+ // (to 0 if you do not need them)
Element.makePositioned(this.element);
this.originalTop = parseFloat(Element.getStyle(this.element,'top') || '0');
this.originalLeft = parseFloat(Element.getStyle(this.element,'left') || '0');
},
update: function(position) {
- var topd = this.toTop * position + this.originalTop;
- var leftd = this.toLeft * position + this.originalLeft;
- this.setPosition(topd, leftd);
- },
- setPosition: function(topd, leftd) {
- this.element.style.top = topd + "px";
- this.element.style.left = leftd + "px";
+ Element.setStyle(this.element, {
+ top: this.toTop * position + this.originalTop + 'px',
+ left: this.toLeft * position + this.originalLeft + 'px'
+ });
}
});
@@ -268,33 +360,31 @@ Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), {
this.start(options);
},
setup: function() {
- var effect = this;
-
this.restoreAfterFinish = this.options.restoreAfterFinish || false;
this.elementPositioning = Element.getStyle(this.element,'position');
- effect.originalStyle = {};
+ this.originalStyle = {};
['top','left','width','height','fontSize'].each( function(k) {
- effect.originalStyle[k] = effect.element.style[k];
- });
+ this.originalStyle[k] = this.element.style[k];
+ }.bind(this));
this.originalTop = this.element.offsetTop;
this.originalLeft = this.element.offsetLeft;
- var fontSize = Element.getStyle(this.element,'font-size') || "100%";
+ var fontSize = Element.getStyle(this.element,'font-size') || '100%';
['em','px','%'].each( function(fontSizeType) {
if(fontSize.indexOf(fontSizeType)>0) {
- effect.fontSize = parseFloat(fontSize);
- effect.fontSizeType = fontSizeType;
+ this.fontSize = parseFloat(fontSize);
+ this.fontSizeType = fontSizeType;
}
- });
+ }.bind(this));
this.factor = (this.options.scaleTo - this.options.scaleFrom)/100;
this.dims = null;
if(this.options.scaleMode=='box')
- this.dims = [this.element.clientHeight, this.element.clientWidth];
- if(this.options.scaleMode=='content')
+ this.dims = [this.element.offsetHeight, this.element.offsetWidth];
+ if(/^content/.test(this.options.scaleMode))
this.dims = [this.element.scrollHeight, this.element.scrollWidth];
if(!this.dims)
this.dims = [this.options.scaleMode.originalHeight,
@@ -303,32 +393,28 @@ Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), {
update: function(position) {
var currentScale = (this.options.scaleFrom/100.0) + (this.factor * position);
if(this.options.scaleContent && this.fontSize)
- this.element.style.fontSize = this.fontSize*currentScale + this.fontSizeType;
+ Element.setStyle(this.element, {fontSize: this.fontSize * currentScale + this.fontSizeType });
this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale);
},
finish: function(position) {
- if (this.restoreAfterFinish) {
- var effect = this;
- ['top','left','width','height','fontSize'].each( function(k) {
- effect.element.style[k] = effect.originalStyle[k];
- });
- }
+ if (this.restoreAfterFinish) Element.setStyle(this.element, this.originalStyle);
},
setDimensions: function(height, width) {
- var els = this.element.style;
- if(this.options.scaleX) els.width = width + 'px';
- if(this.options.scaleY) els.height = height + 'px';
+ var d = {};
+ if(this.options.scaleX) d.width = width + 'px';
+ if(this.options.scaleY) d.height = height + 'px';
if(this.options.scaleFromCenter) {
var topd = (height - this.dims[0])/2;
var leftd = (width - this.dims[1])/2;
if(this.elementPositioning == 'absolute') {
- if(this.options.scaleY) els.top = this.originalTop-topd + "px";
- if(this.options.scaleX) els.left = this.originalLeft-leftd + "px";
+ if(this.options.scaleY) d.top = this.originalTop-topd + 'px';
+ if(this.options.scaleX) d.left = this.originalLeft-leftd + 'px';
} else {
- if(this.options.scaleY) els.top = -topd + "px";
- if(this.options.scaleX) els.left = -leftd + "px";
+ if(this.options.scaleY) d.top = -topd + 'px';
+ if(this.options.scaleX) d.left = -leftd + 'px';
}
}
+ Element.setStyle(this.element, d);
}
});
@@ -336,39 +422,32 @@ Effect.Highlight = Class.create();
Object.extend(Object.extend(Effect.Highlight.prototype, Effect.Base.prototype), {
initialize: function(element) {
this.element = $(element);
- var options = Object.extend({
- startcolor: "#ffff99"
- }, arguments[1] || {});
+ var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || {});
this.start(options);
},
setup: function() {
+ // Prevent executing on elements not in the layout flow
+ if(Element.getStyle(this.element, 'display')=='none') { this.cancel(); return; }
// Disable background image during the effect
- this.oldBgImage = this.element.style.backgroundImage;
- this.element.style.backgroundImage = "none";
+ this.oldStyle = {
+ backgroundImage: Element.getStyle(this.element, 'background-image') };
+ Element.setStyle(this.element, {backgroundImage: 'none'});
if(!this.options.endcolor)
this.options.endcolor = Element.getStyle(this.element, 'background-color').parseColor('#ffffff');
- if (typeof this.options.restorecolor == "undefined")
- this.options.restorecolor = this.element.style.backgroundColor;
+ if(!this.options.restorecolor)
+ this.options.restorecolor = Element.getStyle(this.element, 'background-color');
// init color calculations
- this.colors_base = [
- parseInt(this.options.startcolor.slice(1,3),16),
- parseInt(this.options.startcolor.slice(3,5),16),
- parseInt(this.options.startcolor.slice(5),16) ];
- this.colors_delta = [
- parseInt(this.options.endcolor.slice(1,3),16)-this.colors_base[0],
- parseInt(this.options.endcolor.slice(3,5),16)-this.colors_base[1],
- parseInt(this.options.endcolor.slice(5),16)-this.colors_base[2]];
+ this._base = $R(0,2).map(function(i){ return parseInt(this.options.startcolor.slice(i*2+1,i*2+3),16) }.bind(this));
+ this._delta = $R(0,2).map(function(i){ return parseInt(this.options.endcolor.slice(i*2+1,i*2+3),16)-this._base[i] }.bind(this));
},
update: function(position) {
- var effect = this; var colors = $R(0,2).map( function(i){
- return Math.round(effect.colors_base[i]+(effect.colors_delta[i]*position))
- });
- this.element.style.backgroundColor = "#" +
- colors[0].toColorPart() + colors[1].toColorPart() + colors[2].toColorPart();
+ Element.setStyle(this.element,{backgroundColor: $R(0,2).inject('#',function(m,v,i){
+ return m+(Math.round(this._base[i]+(this._delta[i]*position)).toColorPart()); }.bind(this)) });
},
finish: function() {
- this.element.style.backgroundColor = this.options.restorecolor;
- this.element.style.backgroundImage = this.oldBgImage;
+ Element.setStyle(this.element, Object.extend(this.oldStyle, {
+ backgroundColor: this.options.restorecolor
+ }));
}
});
@@ -381,6 +460,7 @@ Object.extend(Object.extend(Effect.ScrollTo.prototype, Effect.Base.prototype), {
setup: function() {
Position.prepare();
var offsets = Position.cumulativeOffset(this.element);
+ if(this.options.offset) offsets[1] += this.options.offset;
var max = window.innerHeight ?
window.height - window.innerHeight :
document.body.scrollHeight -
@@ -403,42 +483,38 @@ Effect.Fade = function(element) {
var options = Object.extend({
from: Element.getOpacity(element) || 1.0,
to: 0.0,
- afterFinishInternal: function(effect)
- { if (effect.options.to == 0) {
- Element.hide(effect.element);
- Element.setInlineOpacity(effect.element, oldOpacity);
- }
- }
+ afterFinishInternal: function(effect) { with(Element) {
+ if(effect.options.to!=0) return;
+ hide(effect.element);
+ setStyle(effect.element, {opacity: oldOpacity}); }}
}, arguments[1] || {});
return new Effect.Opacity(element,options);
}
Effect.Appear = function(element) {
var options = Object.extend({
- from: (Element.getStyle(element, "display") == "none" ? 0.0 : Element.getOpacity(element) || 0.0),
+ from: (Element.getStyle(element, 'display') == 'none' ? 0.0 : Element.getOpacity(element) || 0.0),
to: 1.0,
- beforeSetup: function(effect)
- { Element.setOpacity(effect.element, effect.options.from);
- Element.show(effect.element); }
+ beforeSetup: function(effect) { with(Element) {
+ setOpacity(effect.element, effect.options.from);
+ show(effect.element); }}
}, arguments[1] || {});
return new Effect.Opacity(element,options);
}
Effect.Puff = function(element) {
element = $(element);
- var oldOpacity = Element.getInlineOpacity(element);
- var oldPosition = element.style.position;
+ var oldStyle = { opacity: Element.getInlineOpacity(element), position: Element.getStyle(element, 'position') };
return new Effect.Parallel(
[ new Effect.Scale(element, 200,
{ sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }),
new Effect.Opacity(element, { sync: true, to: 0.0 } ) ],
Object.extend({ duration: 1.0,
- beforeSetupInternal: function(effect)
- { effect.effects[0].element.style.position = 'absolute'; },
- afterFinishInternal: function(effect)
- { Element.hide(effect.effects[0].element);
- effect.effects[0].element.style.position = oldPosition;
- Element.setInlineOpacity(effect.effects[0].element, oldOpacity); }
+ beforeSetupInternal: function(effect) { with(Element) {
+ setStyle(effect.effects[0].element, {position: 'absolute'}); }},
+ afterFinishInternal: function(effect) { with(Element) {
+ hide(effect.effects[0].element);
+ setStyle(effect.effects[0].element, oldStyle); }}
}, arguments[1] || {})
);
}
@@ -450,18 +526,15 @@ Effect.BlindUp = function(element) {
Object.extend({ scaleContent: false,
scaleX: false,
restoreAfterFinish: true,
- afterFinishInternal: function(effect)
- {
- Element.hide(effect.element);
- Element.undoClipping(effect.element);
- }
+ afterFinishInternal: function(effect) { with(Element) {
+ [hide, undoClipping].call(effect.element); }}
}, arguments[1] || {})
);
}
Effect.BlindDown = function(element) {
element = $(element);
- var oldHeight = element.style.height;
+ var oldHeight = Element.getStyle(element, 'height');
var elementDimensions = Element.getDimensions(element);
return new Effect.Scale(element, 100,
Object.extend({ scaleContent: false,
@@ -469,15 +542,15 @@ Effect.BlindDown = function(element) {
scaleFrom: 0,
scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
restoreAfterFinish: true,
- afterSetup: function(effect) {
- Element.makeClipping(effect.element);
- effect.element.style.height = "0px";
- Element.show(effect.element);
- },
- afterFinishInternal: function(effect) {
- Element.undoClipping(effect.element);
- effect.element.style.height = oldHeight;
- }
+ afterSetup: function(effect) { with(Element) {
+ makeClipping(effect.element);
+ setStyle(effect.element, {height: '0px'});
+ show(effect.element);
+ }},
+ afterFinishInternal: function(effect) { with(Element) {
+ undoClipping(effect.element);
+ setStyle(effect.element, {height: oldHeight});
+ }}
}, arguments[1] || {})
);
}
@@ -493,16 +566,13 @@ Effect.SwitchOff = function(element) {
new Effect.Scale(effect.element, 1, {
duration: 0.3, scaleFromCenter: true,
scaleX: false, scaleContent: false, restoreAfterFinish: true,
- beforeSetup: function(effect) {
- Element.makePositioned(effect.element);
- Element.makeClipping(effect.element);
- },
- afterFinishInternal: function(effect) {
- Element.hide(effect.element);
- Element.undoClipping(effect.element);
- Element.undoPositioned(effect.element);
- Element.setInlineOpacity(effect.element, oldOpacity);
- }
+ beforeSetup: function(effect) { with(Element) {
+ [makePositioned,makeClipping].call(effect.element);
+ }},
+ afterFinishInternal: function(effect) { with(Element) {
+ [hide,undoClipping,undoPositioned].call(effect.element);
+ setStyle(effect.element, {opacity: oldOpacity});
+ }}
})
}
});
@@ -510,29 +580,28 @@ Effect.SwitchOff = function(element) {
Effect.DropOut = function(element) {
element = $(element);
- var oldTop = element.style.top;
- var oldLeft = element.style.left;
- var oldOpacity = Element.getInlineOpacity(element);
+ var oldStyle = {
+ top: Element.getStyle(element, 'top'),
+ left: Element.getStyle(element, 'left'),
+ opacity: Element.getInlineOpacity(element) };
return new Effect.Parallel(
[ new Effect.MoveBy(element, 100, 0, { sync: true }),
new Effect.Opacity(element, { sync: true, to: 0.0 }) ],
Object.extend(
{ duration: 0.5,
- beforeSetup: function(effect) {
- Element.makePositioned(effect.effects[0].element); },
- afterFinishInternal: function(effect) {
- Element.hide(effect.effects[0].element);
- Element.undoPositioned(effect.effects[0].element);
- effect.effects[0].element.style.left = oldLeft;
- effect.effects[0].element.style.top = oldTop;
- Element.setInlineOpacity(effect.effects[0].element, oldOpacity); }
+ beforeSetup: function(effect) { with(Element) {
+ makePositioned(effect.effects[0].element); }},
+ afterFinishInternal: function(effect) { with(Element) {
+ [hide, undoPositioned].call(effect.effects[0].element);
+ setStyle(effect.effects[0].element, oldStyle); }}
}, arguments[1] || {}));
}
Effect.Shake = function(element) {
element = $(element);
- var oldTop = element.style.top;
- var oldLeft = element.style.left;
+ var oldStyle = {
+ top: Element.getStyle(element, 'top'),
+ left: Element.getStyle(element, 'left') };
return new Effect.MoveBy(element, 0, 20,
{ duration: 0.05, afterFinishInternal: function(effect) {
new Effect.MoveBy(effect.element, 0, -40,
@@ -544,39 +613,39 @@ Effect.Shake = function(element) {
new Effect.MoveBy(effect.element, 0, 40,
{ duration: 0.1, afterFinishInternal: function(effect) {
new Effect.MoveBy(effect.element, 0, -20,
- { duration: 0.05, afterFinishInternal: function(effect) {
- Element.undoPositioned(effect.element);
- effect.element.style.left = oldLeft;
- effect.element.style.top = oldTop;
- }}) }}) }}) }}) }}) }});
+ { duration: 0.05, afterFinishInternal: function(effect) { with(Element) {
+ undoPositioned(effect.element);
+ setStyle(effect.element, oldStyle);
+ }}}) }}) }}) }}) }}) }});
}
Effect.SlideDown = function(element) {
element = $(element);
Element.cleanWhitespace(element);
// SlideDown need to have the content of the element wrapped in a container element with fixed height!
- var oldInnerBottom = element.firstChild.style.bottom;
+ var oldInnerBottom = Element.getStyle(element.firstChild, 'bottom');
var elementDimensions = Element.getDimensions(element);
- return new Effect.Scale(element, 100,
- Object.extend({ scaleContent: false,
+ return new Effect.Scale(element, 100, Object.extend({
+ scaleContent: false,
scaleX: false,
scaleFrom: 0,
- scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
+ scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
restoreAfterFinish: true,
- afterSetup: function(effect) {
- Element.makePositioned(effect.element.firstChild);
- if (window.opera) effect.element.firstChild.style.top = "";
- Element.makeClipping(effect.element);
- element.style.height = '0';
- Element.show(element);
- },
- afterUpdateInternal: function(effect) {
- effect.element.firstChild.style.bottom =
- (effect.originalHeight - effect.element.clientHeight) + 'px'; },
- afterFinishInternal: function(effect) {
- Element.undoClipping(effect.element);
- Element.undoPositioned(effect.element.firstChild);
- effect.element.firstChild.style.bottom = oldInnerBottom; }
+ afterSetup: function(effect) { with(Element) {
+ makePositioned(effect.element);
+ makePositioned(effect.element.firstChild);
+ if(window.opera) setStyle(effect.element, {top: ''});
+ makeClipping(effect.element);
+ setStyle(effect.element, {height: '0px'});
+ show(element); }},
+ afterUpdateInternal: function(effect) { with(Element) {
+ setStyle(effect.element.firstChild, {bottom:
+ (effect.dims[0] - effect.element.clientHeight) + 'px' }); }},
+ afterFinishInternal: function(effect) { with(Element) {
+ undoClipping(effect.element);
+ undoPositioned(effect.element.firstChild);
+ undoPositioned(effect.element);
+ setStyle(effect.element.firstChild, {bottom: oldInnerBottom}); }}
}, arguments[1] || {})
);
}
@@ -584,122 +653,111 @@ Effect.SlideDown = function(element) {
Effect.SlideUp = function(element) {
element = $(element);
Element.cleanWhitespace(element);
- var oldInnerBottom = element.firstChild.style.bottom;
+ var oldInnerBottom = Element.getStyle(element.firstChild, 'bottom');
return new Effect.Scale(element, 0,
Object.extend({ scaleContent: false,
scaleX: false,
scaleMode: 'box',
scaleFrom: 100,
restoreAfterFinish: true,
- beforeStartInternal: function(effect) {
- Element.makePositioned(effect.element.firstChild);
- if (window.opera) effect.element.firstChild.style.top = "";
- Element.makeClipping(effect.element);
- Element.show(element);
- },
- afterUpdateInternal: function(effect) {
- effect.element.firstChild.style.bottom =
- (effect.originalHeight - effect.element.clientHeight) + 'px'; },
- afterFinishInternal: function(effect) {
- Element.hide(effect.element);
- Element.undoClipping(effect.element);
- Element.undoPositioned(effect.element.firstChild);
- effect.element.firstChild.style.bottom = oldInnerBottom; }
+ beforeStartInternal: function(effect) { with(Element) {
+ makePositioned(effect.element);
+ makePositioned(effect.element.firstChild);
+ if(window.opera) setStyle(effect.element, {top: ''});
+ makeClipping(effect.element);
+ show(element); }},
+ afterUpdateInternal: function(effect) { with(Element) {
+ setStyle(effect.element.firstChild, {bottom:
+ (effect.dims[0] - effect.element.clientHeight) + 'px' }); }},
+ afterFinishInternal: function(effect) { with(Element) {
+ [hide, undoClipping].call(effect.element);
+ undoPositioned(effect.element.firstChild);
+ undoPositioned(effect.element);
+ setStyle(effect.element.firstChild, {bottom: oldInnerBottom}); }}
}, arguments[1] || {})
);
}
+// Bug in opera makes the TD containing this element expand for a instance after finish
Effect.Squish = function(element) {
- // Bug in opera makes the TD containing this element expand for a instance after finish
return new Effect.Scale(element, window.opera ? 1 : 0,
{ restoreAfterFinish: true,
- beforeSetup: function(effect) {
- Element.makeClipping(effect.element); },
- afterFinishInternal: function(effect) {
- Element.hide(effect.element);
- Element.undoClipping(effect.element); }
+ beforeSetup: function(effect) { with(Element) {
+ makeClipping(effect.element); }},
+ afterFinishInternal: function(effect) { with(Element) {
+ hide(effect.element);
+ undoClipping(effect.element); }}
});
}
Effect.Grow = function(element) {
element = $(element);
- var options = arguments[1] || {};
-
- var elementDimensions = Element.getDimensions(element);
- var originalWidth = elementDimensions.width;
- var originalHeight = elementDimensions.height;
- var oldTop = element.style.top;
- var oldLeft = element.style.left;
- var oldHeight = element.style.height;
- var oldWidth = element.style.width;
- var oldOpacity = Element.getInlineOpacity(element);
-
- var direction = options.direction || 'center';
- var moveTransition = options.moveTransition || Effect.Transitions.sinoidal;
- var scaleTransition = options.scaleTransition || Effect.Transitions.sinoidal;
- var opacityTransition = options.opacityTransition || Effect.Transitions.full;
-
+ var options = Object.extend({
+ direction: 'center',
+ moveTransistion: Effect.Transitions.sinoidal,
+ scaleTransition: Effect.Transitions.sinoidal,
+ opacityTransition: Effect.Transitions.full
+ }, arguments[1] || {});
+ var oldStyle = {
+ top: element.style.top,
+ left: element.style.left,
+ height: element.style.height,
+ width: element.style.width,
+ opacity: Element.getInlineOpacity(element) };
+
+ var dims = Element.getDimensions(element);
var initialMoveX, initialMoveY;
var moveX, moveY;
- switch (direction) {
+ switch (options.direction) {
case 'top-left':
initialMoveX = initialMoveY = moveX = moveY = 0;
break;
case 'top-right':
- initialMoveX = originalWidth;
+ initialMoveX = dims.width;
initialMoveY = moveY = 0;
- moveX = -originalWidth;
+ moveX = -dims.width;
break;
case 'bottom-left':
initialMoveX = moveX = 0;
- initialMoveY = originalHeight;
- moveY = -originalHeight;
+ initialMoveY = dims.height;
+ moveY = -dims.height;
break;
case 'bottom-right':
- initialMoveX = originalWidth;
- initialMoveY = originalHeight;
- moveX = -originalWidth;
- moveY = -originalHeight;
+ initialMoveX = dims.width;
+ initialMoveY = dims.height;
+ moveX = -dims.width;
+ moveY = -dims.height;
break;
case 'center':
- initialMoveX = originalWidth / 2;
- initialMoveY = originalHeight / 2;
- moveX = -originalWidth / 2;
- moveY = -originalHeight / 2;
+ initialMoveX = dims.width / 2;
+ initialMoveY = dims.height / 2;
+ moveX = -dims.width / 2;
+ moveY = -dims.height / 2;
break;
}
return new Effect.MoveBy(element, initialMoveY, initialMoveX, {
duration: 0.01,
- beforeSetup: function(effect) {
- Element.hide(effect.element);
- Element.makeClipping(effect.element);
- Element.makePositioned(effect.element);
- },
+ beforeSetup: function(effect) { with(Element) {
+ hide(effect.element);
+ makeClipping(effect.element);
+ makePositioned(effect.element);
+ }},
afterFinishInternal: function(effect) {
new Effect.Parallel(
- [ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: opacityTransition }),
- new Effect.MoveBy(effect.element, moveY, moveX, { sync: true, transition: moveTransition }),
+ [ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }),
+ new Effect.MoveBy(effect.element, moveY, moveX, { sync: true, transition: options.moveTransition }),
new Effect.Scale(effect.element, 100, {
- scaleMode: { originalHeight: originalHeight, originalWidth: originalWidth },
- sync: true, scaleFrom: window.opera ? 1 : 0, transition: scaleTransition, restoreAfterFinish: true})
+ scaleMode: { originalHeight: dims.height, originalWidth: dims.width },
+ sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true})
], Object.extend({
- beforeSetup: function(effect) {
- effect.effects[0].element.style.height = 0;
- Element.show(effect.effects[0].element);
- },
- afterFinishInternal: function(effect) {
- var el = effect.effects[0].element;
- var els = el.style;
- Element.undoClipping(el);
- Element.undoPositioned(el);
- els.top = oldTop;
- els.left = oldLeft;
- els.height = oldHeight;
- els.width = originalWidth;
- Element.setInlineOpacity(el, oldOpacity);
- }
+ beforeSetup: function(effect) { with(Element) {
+ setStyle(effect.effects[0].element, {height: '0px'});
+ show(effect.effects[0].element); }},
+ afterFinishInternal: function(effect) { with(Element) {
+ [undoClipping, undoPositioned].call(effect.effects[0].element);
+ setStyle(effect.effects[0].element, oldStyle); }}
}, options)
)
}
@@ -708,66 +766,54 @@ Effect.Grow = function(element) {
Effect.Shrink = function(element) {
element = $(element);
- var options = arguments[1] || {};
-
- var originalWidth = element.clientWidth;
- var originalHeight = element.clientHeight;
- var oldTop = element.style.top;
- var oldLeft = element.style.left;
- var oldHeight = element.style.height;
- var oldWidth = element.style.width;
- var oldOpacity = Element.getInlineOpacity(element);
+ var options = Object.extend({
+ direction: 'center',
+ moveTransistion: Effect.Transitions.sinoidal,
+ scaleTransition: Effect.Transitions.sinoidal,
+ opacityTransition: Effect.Transitions.none
+ }, arguments[1] || {});
+ var oldStyle = {
+ top: element.style.top,
+ left: element.style.left,
+ height: element.style.height,
+ width: element.style.width,
+ opacity: Element.getInlineOpacity(element) };
- var direction = options.direction || 'center';
- var moveTransition = options.moveTransition || Effect.Transitions.sinoidal;
- var scaleTransition = options.scaleTransition || Effect.Transitions.sinoidal;
- var opacityTransition = options.opacityTransition || Effect.Transitions.none;
-
+ var dims = Element.getDimensions(element);
var moveX, moveY;
- switch (direction) {
+ switch (options.direction) {
case 'top-left':
moveX = moveY = 0;
break;
case 'top-right':
- moveX = originalWidth;
+ moveX = dims.width;
moveY = 0;
break;
case 'bottom-left':
moveX = 0;
- moveY = originalHeight;
+ moveY = dims.height;
break;
case 'bottom-right':
- moveX = originalWidth;
- moveY = originalHeight;
+ moveX = dims.width;
+ moveY = dims.height;
break;
case 'center':
- moveX = originalWidth / 2;
- moveY = originalHeight / 2;
+ moveX = dims.width / 2;
+ moveY = dims.height / 2;
break;
}
return new Effect.Parallel(
- [ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: opacityTransition }),
- new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: scaleTransition, restoreAfterFinish: true}),
- new Effect.MoveBy(element, moveY, moveX, { sync: true, transition: moveTransition })
+ [ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }),
+ new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}),
+ new Effect.MoveBy(element, moveY, moveX, { sync: true, transition: options.moveTransition })
], Object.extend({
- beforeStartInternal: function(effect) {
- Element.makePositioned(effect.effects[0].element);
- Element.makeClipping(effect.effects[0].element);
- },
- afterFinishInternal: function(effect) {
- var el = effect.effects[0].element;
- var els = el.style;
- Element.hide(el);
- Element.undoClipping(el);
- Element.undoPositioned(el);
- els.top = oldTop;
- els.left = oldLeft;
- els.height = oldHeight;
- els.width = oldWidth;
- Element.setInlineOpacity(el, oldOpacity);
- }
+ beforeStartInternal: function(effect) { with(Element) {
+ [makePositioned, makeClipping].call(effect.effects[0].element) }},
+ afterFinishInternal: function(effect) { with(Element) {
+ [hide, undoClipping, undoPositioned].call(effect.effects[0].element);
+ setStyle(effect.effects[0].element, oldStyle); }}
}, options)
);
}
@@ -781,16 +827,17 @@ Effect.Pulsate = function(element) {
reverser.bind(transition);
return new Effect.Opacity(element,
Object.extend(Object.extend({ duration: 3.0, from: 0,
- afterFinishInternal: function(effect) { Element.setInlineOpacity(effect.element, oldOpacity); }
+ afterFinishInternal: function(effect) { Element.setStyle(effect.element, {opacity: oldOpacity}); }
}, options), {transition: reverser}));
}
Effect.Fold = function(element) {
element = $(element);
- var originalTop = element.style.top;
- var originalLeft = element.style.left;
- var originalWidth = element.style.width;
- var originalHeight = element.style.height;
+ var oldStyle = {
+ top: element.style.top,
+ left: element.style.left,
+ width: element.style.width,
+ height: element.style.height };
Element.makeClipping(element);
return new Effect.Scale(element, 5, Object.extend({
scaleContent: false,
@@ -799,13 +846,9 @@ Effect.Fold = function(element) {
new Effect.Scale(element, 1, {
scaleContent: false,
scaleY: false,
- afterFinishInternal: function(effect) {
- Element.hide(effect.element);
- Element.undoClipping(effect.element);
- effect.element.style.top = originalTop;
- effect.element.style.left = originalLeft;
- effect.element.style.width = originalWidth;
- effect.element.style.height = originalHeight;
- } });
+ afterFinishInternal: function(effect) { with(Element) {
+ [hide, undoClipping].call(effect.element);
+ setStyle(effect.element, oldStyle);
+ }} });
}}, arguments[1] || {}));
}
diff --git a/framework/Web/Javascripts/effects/rico.js b/framework/Web/Javascripts/effects/rico.js
index 4253d4b0..cd8f32e7 100644
--- a/framework/Web/Javascripts/effects/rico.js
+++ b/framework/Web/Javascripts/effects/rico.js
@@ -1,5 +1,3 @@
-/* openrico.org rico.js */
-
/**
*
* Copyright 2005 Sabre Airline Solutions
@@ -15,21 +13,29 @@
* and limitations under the License.
**/
-// rico.js --------------------
+//-------------------- rico.js
var Rico = {
- Version: '1.1-beta'
+ Version: '1.1rc1',
+ prototypeVersion: parseFloat(Prototype.Version.split(".")[0] + "." + Prototype.Version.split(".")[1])
}
+/*
+if((typeof Prototype=='undefined') || Rico.prototypeVersion < 1.3)
+ throw("Rico requires the Prototype JavaScript framework >= 1.3");
+*/
Rico.ArrayExtensions = new Array();
if (Object.prototype.extend) {
- // in prototype.js...
Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Object.prototype.extend;
+}else{
+ Object.prototype.extend = function(object) {
+ return Object.extend.apply(this, [this, object]);
+ }
+ Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Object.prototype.extend;
}
if (Array.prototype.push) {
- // in prototype.js...
Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.push;
}
@@ -122,11 +128,9 @@ document.getElementsByTagAndClassName = function(tagName, className) {
return elements;
}
-
-
-// ricoAccordion.js --------------------
-
+
+//-------------------- ricoAccordion.js
Rico.Accordion = Class.create();
Rico.Accordion.prototype = {
@@ -137,19 +141,40 @@ Rico.Accordion.prototype = {
this.accordionTabs = new Array();
this.setOptions(options);
this._attachBehaviors();
+ if(!container) return;
this.container.style.borderBottom = '1px solid ' + this.options.borderColor;
+ // validate onloadShowTab
+ if (this.options.onLoadShowTab >= this.accordionTabs.length)
+ this.options.onLoadShowTab = 0;
// set the initial visual state...
- for ( var i=1 ; i < this.accordionTabs.length ; i++ )
+ for ( var i=0 ; i < this.accordionTabs.length ; i++ )
{
+ if (i != this.options.onLoadShowTab){
this.accordionTabs[i].collapse();
this.accordionTabs[i].content.style.display = 'none';
+ }
}
- this.lastExpandedTab = this.accordionTabs[0];
+ this.lastExpandedTab = this.accordionTabs[this.options.onLoadShowTab];
+ if (this.options.panelHeight == 'auto'){
+ var tabToCheck = (this.options.onloadShowTab === 0)? 1 : 0;
+ var titleBarSize = parseInt(RicoUtil.getElementsComputedStyle(this.accordionTabs[tabToCheck].titleBar, 'height'));
+ if (isNaN(titleBarSize))
+ titleBarSize = this.accordionTabs[tabToCheck].titleBar.offsetHeight;
+
+ var totalTitleBarSize = this.accordionTabs.length * titleBarSize;
+ var parentHeight = parseInt(RicoUtil.getElementsComputedStyle(this.container.parentNode, 'height'));
+ if (isNaN(parentHeight))
+ parentHeight = this.container.parentNode.offsetHeight;
+
+ this.options.panelHeight = parentHeight - totalTitleBarSize-2;
+ }
+
this.lastExpandedTab.content.style.height = this.options.panelHeight + "px";
this.lastExpandedTab.showExpanded();
this.lastExpandedTab.titleBar.style.fontWeight = this.options.expandedFontWeight;
+
},
setOptions: function(options) {
@@ -166,8 +191,10 @@ Rico.Accordion.prototype = {
borderColor : '#1f669b',
panelHeight : 200,
onHideTab : null,
- onShowTab : null
- }.extend(options || {});
+ onShowTab : null,
+ onLoadShowTab : 0
+ }
+ Object.extend(this.options, options || {});
},
showTabByIndex: function( anIndex, animate ) {
@@ -182,7 +209,7 @@ Rico.Accordion.prototype = {
if ( this.options.onHideTab )
this.options.onHideTab(this.lastExpandedTab);
- this.lastExpandedTab.showCollapsed();
+ this.lastExpandedTab.showCollapsed();
var accordion = this;
var lastExpandedTab = this.lastExpandedTab;
@@ -305,11 +332,10 @@ Rico.Accordion.Tab.prototype = {
}
};
-
-
-// ricoAjaxEngine.js --------------------
-
+
+//-------------------- ricoAjaxEngine.js
+/*
Rico.AjaxEngine = Class.create();
Rico.AjaxEngine.prototype = {
@@ -318,10 +344,11 @@ Rico.AjaxEngine.prototype = {
this.ajaxElements = new Array();
this.ajaxObjects = new Array();
this.requestURLS = new Array();
+ this.options = {};
},
registerAjaxElement: function( anId, anElement ) {
- if ( arguments.length == 1 )
+ if ( !anElement )
anElement = $(anId);
this.ajaxElements[anId] = anElement;
},
@@ -334,44 +361,34 @@ Rico.AjaxEngine.prototype = {
this.requestURLS[requestLogicalName] = requestURL;
},
- sendRequest: function(requestName) {
- var requestURL = this.requestURLS[requestName];
- if ( requestURL == null )
- return;
-
- var queryString = "";
- if ( arguments.length > 1 )
- queryString = this._createQueryString(arguments, 1);
-
- new Ajax.Request(requestURL, this._requestOptions(queryString));
+ sendRequest: function(requestName, options) {
+ // Allow for backwards Compatibility
+ if ( arguments.length >= 2 )
+ if (typeof arguments[1] == 'string')
+ options = {parameters: this._createQueryString(arguments, 1)};
+ this.sendRequestWithData(requestName, null, options);
},
- sendRequestWithData: function(requestName, xmlDocument) {
+ sendRequestWithData: function(requestName, xmlDocument, options) {
var requestURL = this.requestURLS[requestName];
if ( requestURL == null )
return;
- var queryString = "";
- if ( arguments.length > 2 )
- queryString = this._createQueryString(arguments, 2);
+ // Allow for backwards Compatibility
+ if ( arguments.length >= 3 )
+ if (typeof arguments[2] == 'string')
+ options.parameters = this._createQueryString(arguments, 2);
- new Ajax.Request(requestURL + "?" + queryString, this._requestOptions(null,xmlDocument));
+ new Ajax.Request(requestURL, this._requestOptions(options,xmlDocument));
},
sendRequestAndUpdate: function(requestName,container,options) {
- var requestURL = this.requestURLS[requestName];
- if ( requestURL == null )
- return;
-
- var queryString = "";
- if ( arguments.length > 3 )
- queryString = this._createQueryString(arguments, 3);
-
- var updaterOptions = this._requestOptions(queryString);
- updaterOptions.onComplete = null;
- updaterOptions.extend(options);
+ // Allow for backwards Compatibility
+ if ( arguments.length >= 3 )
+ if (typeof arguments[2] == 'string')
+ options.parameters = this._createQueryString(arguments, 2);
- new Ajax.Updater(container, requestURL, updaterOptions);
+ this.sendRequestWithDataAndUpdate(requestName, null, container, options);
},
sendRequestWithDataAndUpdate: function(requestName,xmlDocument,container,options) {
@@ -379,39 +396,54 @@ Rico.AjaxEngine.prototype = {
if ( requestURL == null )
return;
- var queryString = "";
- if ( arguments.length > 4 )
- queryString = this._createQueryString(arguments, 4);
-
+ // Allow for backwards Compatibility
+ if ( arguments.length >= 4 )
+ if (typeof arguments[3] == 'string')
+ options.parameters = this._createQueryString(arguments, 3);
- var updaterOptions = this._requestOptions(queryString,xmlDocument);
- updaterOptions.onComplete = null;
- updaterOptions.extend(options);
+ var updaterOptions = this._requestOptions(options,xmlDocument);
+ // Turn off onComplete
+ //updaterOptions.onComplete = null;
- new Ajax.Updater(container, requestURL + "?" + queryString, updaterOptions);
+ new Ajax.Updater(container, requestURL, updaterOptions);
},
// Private -- not part of intended engine API --------------------------------------------------------------------
- _requestOptions: function(queryString,xmlDoc) {
- var self = this;
-
+ _requestOptions: function(options,xmlDoc) {
var requestHeaders = ['X-Rico-Version', Rico.Version ];
- var sendMethod = "post";
- if ( arguments[1] )
- requestHeaders.push( 'Content-type', 'text/xml' );
+ var sendMethod = 'post';
+ if ( xmlDoc == null )
+ if (Rico.prototypeVersion < 1.4)
+ requestHeaders.push( 'Content-type', 'text/xml' );
+ else
+ sendMethod = 'get';
+ (!options) ? options = {} : '';
+
+ // Check and keep any user onComplete functions
+ if (options.onComplete)
+ options.onRicoComplete = options.onComplete;
+ // Fix onComplete
+ if (options.overrideOnComplete)
+ options.onComplete = options.overrideOnComplete;
else
- sendMethod = "get";
+ options.onComplete = this._onRequestComplete.bind(this);
- return { requestHeaders: requestHeaders,
- parameters: queryString,
- postBody: arguments[1] ? xmlDoc : null,
- method: sendMethod,
- onComplete: self._onRequestComplete.bind(self) };
+ // Set the default options and extend with any user options
+ this.options = {
+ requestHeaders: requestHeaders,
+ parameters: options.parameters,
+ postBody: xmlDoc,
+ method: sendMethod,
+ onComplete: options.onComplete
+ };
+ // Set any user options:
+ Object.extend(this.options, options);
+ return this.options;
},
_createQueryString: function( theArgs, offset ) {
- var queryString = "";
+ var queryString = ""
for ( var i = offset ; i < theArgs.length ; i++ ) {
if ( i != offset )
queryString += "&";
@@ -428,13 +460,13 @@ Rico.AjaxEngine.prototype = {
queryString += argName + "=" + escape(argValue);
}
}
-
return queryString;
},
_onRequestComplete : function(request) {
-
- //!!TODO: error handling infrastructure??
+ if(!request)
+ return;
+ // User can set an onFailure option - which will be called by prototype
if (request.status != 200)
return;
@@ -442,6 +474,11 @@ Rico.AjaxEngine.prototype = {
if (response == null || response.length != 1)
return;
this._processAjaxResponse( response[0].childNodes );
+
+ // Check if user has set a onComplete function
+ var onRicoComplete = this.options.onRicoComplete;
+ if (onRicoComplete != null)
+ onRicoComplete();
},
_processAjaxResponse: function( xmlResponseElements ) {
@@ -469,34 +506,15 @@ Rico.AjaxEngine.prototype = {
},
_processAjaxElementUpdate: function( ajaxElement, responseElement ) {
- if ( responseElement.xml != undefined )
- this._processAjaxElementUpdateIE( ajaxElement, responseElement );
- else
- this._processAjaxElementUpdateMozilla( ajaxElement, responseElement );
- },
-
- _processAjaxElementUpdateIE: function( ajaxElement, responseElement ) {
- var newHTML = "";
- for ( var i = 0 ; i < responseElement.childNodes.length ; i++ )
- newHTML += responseElement.childNodes[i].xml;
-
- ajaxElement.innerHTML = newHTML;
- },
-
- _processAjaxElementUpdateMozilla: function( ajaxElement, responseElement ) {
- var xmlSerializer = new XMLSerializer();
- var newHTML = "";
- for ( var i = 0 ; i < responseElement.childNodes.length ; i++ )
- newHTML += xmlSerializer.serializeToString(responseElement.childNodes[i]);
-
- ajaxElement.innerHTML = newHTML;
+ ajaxElement.innerHTML = RicoUtil.getContentAsString(responseElement);
}
+
}
-var ajaxEngine = new Rico.AjaxEngine();
-
-// ricoColor.js --------------------
-
+var ajaxEngine = new Rico.AjaxEngine();
+*/
+
+//-------------------- ricoColor.js
Rico.Color = Class.create();
Rico.Color.prototype = {
@@ -725,11 +743,10 @@ Rico.Color.RGBtoHSB = function(r, g, b) {
}
return { h : hue, s : saturation, b : brightness };
-}
-
-// ricoCorner.js --------------------
-
+}
+
+//-------------------- ricoCorner.js
Rico.Corner = {
round: function(e, options) {
@@ -817,7 +834,6 @@ Rico.Corner = {
this._setMargin(slice, n, position);
this._setBorder(slice, n, position);
-
return slice;
},
@@ -829,7 +845,8 @@ Rico.Corner = {
blend : true,
border : false,
compact : false
- }.extend(options || {});
+ }
+ Object.extend(this.options, options || {});
this.options.numSlices = this.options.compact ? 2 : 4;
if ( this._isTransparent() )
@@ -894,7 +911,6 @@ Rico.Corner = {
_setBorder: function(el,n,corners) {
var borderSize = this._borderSize(n);
var whichSide = corners == "top" ? this._whichSideTop() : this._whichSideBottom();
-
if ( whichSide == "left" ) {
el.style.borderLeftWidth = borderSize + "px"; el.style.borderRightWidth = "0px";
}
@@ -904,6 +920,8 @@ Rico.Corner = {
else {
el.style.borderLeftWidth = borderSize + "px"; el.style.borderRightWidth = borderSize + "px";
}
+ if (this.options.border != false)
+ el.style.borderLeftWidth = borderSize + "px"; el.style.borderRightWidth = borderSize + "px";
},
_marginSize: function(n) {
@@ -951,10 +969,11 @@ Rico.Corner = {
_isTopRounded: function() { return this._hasString(this.options.corners, "all", "top", "tl", "tr"); },
_isBottomRounded: function() { return this._hasString(this.options.corners, "all", "bottom", "bl", "br"); },
_hasSingleTextChild: function(el) { return el.childNodes.length == 1 && el.childNodes[0].nodeType == 3; }
-}
-
-// ricoDragAndDrop.js --------------------
-
+}
+
+
+//-------------------- ricoDragAndDrop.js
+/*
Rico.DragAndDrop = Class.create();
Rico.DragAndDrop.prototype = {
@@ -967,6 +986,9 @@ Rico.DragAndDrop.prototype = {
this.lastSelectedDraggable = null;
this.currentDragObjectVisible = false;
this.interestedInMotionEvents = false;
+ this._mouseDown = this._mouseDownHandler.bindAsEventListener(this);
+ this._mouseMove = this._mouseMoveHandler.bindAsEventListener(this);
+ this._mouseUp = this._mouseUpHandler.bindAsEventListener(this);
},
registerDropZone: function(aDropZone) {
@@ -1006,8 +1028,8 @@ Rico.DragAndDrop.prototype = {
setStartDragFromElement: function( e, mouseDownElement ) {
this.origPos = RicoUtil.toDocumentPosition(mouseDownElement);
- this.startx = e.screenX - this.origPos.x;
- this.starty = e.screenY - this.origPos.y;
+ this.startx = e.screenX - this.origPos.x
+ this.starty = e.screenY - this.origPos.y
//this.startComponentX = e.layerX ? e.layerX : e.offsetX;
//this.startComponentY = e.layerY ? e.layerY : e.offsetY;
//this.adjustedForDraggableSize = false;
@@ -1042,8 +1064,17 @@ Rico.DragAndDrop.prototype = {
if ( (nsEvent && e.which != 1) || (!nsEvent && e.button != 1))
return;
- var eventTarget = e.target ? e.target : e.srcElement;
- var draggableObject = eventTarget.draggable;
+ var eventTarget = e.target ? e.target : e.srcElement;
+ var draggableObject = eventTarget.draggable;
+
+ var candidate = eventTarget;
+ while (draggableObject == null && candidate.parentNode) {
+ candidate = candidate.parentNode;
+ draggableObject = candidate.draggable;
+ }
+
+ if ( draggableObject == null )
+ return;
this.updateSelection( draggableObject, e.ctrlKey );
@@ -1059,7 +1090,7 @@ Rico.DragAndDrop.prototype = {
_mouseMoveHandler: function(e) {
var nsEvent = e.which != undefined;
if ( !this.interestedInMotionEvents ) {
- this._terminateEvent(e);
+ //this._terminateEvent(e);
return;
}
@@ -1119,10 +1150,10 @@ Rico.DragAndDrop.prototype = {
this.adjustedForDraggableSize = true;
},
**/
-
+/*
_updateDraggableLocation: function(e) {
var dragObjectStyle = this.dragElement.style;
- dragObjectStyle.left = (e.screenX - this.startx) + "px";
+ dragObjectStyle.left = (e.screenX - this.startx) + "px"
dragObjectStyle.top = (e.screenY - this.starty) + "px";
},
@@ -1174,6 +1205,13 @@ Rico.DragAndDrop.prototype = {
20,
{ complete : this._doCancelDragProcessing.bind(this) } );
}
+
+ Event.stopObserving(document.body, "mousemove", this._mouseMove);
+ Event.stopObserving(document.body, "mouseup", this._mouseUp);
+ },
+
+ _retTrue: function () {
+ return true;
},
_completeDropOperation: function(e) {
@@ -1193,11 +1231,10 @@ Rico.DragAndDrop.prototype = {
_doCancelDragProcessing: function() {
this._cancelDrag();
- if ( this.dragElement != this.currentDragObjects[0].getMouseDownHTMLElement() ) {
- if ( this.dragElement.parentNode != null ) {
- this.dragElement.parentNode.removeChild(this.dragElement);
- }
- }
+ if ( this.dragElement != this.currentDragObjects[0].getMouseDownHTMLElement() && this.dragElement)
+ if ( this.dragElement.parentNode != null )
+ this.dragElement.parentNode.removeChild(this.dragElement);
+
this._deactivateRegisteredDropZones();
this.dragElement = null;
@@ -1243,10 +1280,11 @@ Rico.DragAndDrop.prototype = {
_addMouseDownHandler: function( aDraggable )
{
- var htmlElement = aDraggable.getMouseDownHTMLElement();
- if ( htmlElement != null ) {
+ htmlElement = aDraggable.getMouseDownHTMLElement();
+ if ( htmlElement != null ) {
htmlElement.draggable = aDraggable;
- this._addMouseDownEvent( htmlElement );
+ Event.observe(htmlElement , "mousedown", this._onmousedown.bindAsEventListener(this));
+ Event.observe(htmlElement, "mousedown", this._mouseDown);
}
},
@@ -1268,16 +1306,9 @@ Rico.DragAndDrop.prototype = {
this.activatedDropZones = false;
},
- _addMouseDownEvent: function( htmlElement ) {
- if ( typeof document.implementation != "undefined" &&
- document.implementation.hasFeature("HTML", "1.0") &&
- document.implementation.hasFeature("Events", "2.0") &&
- document.implementation.hasFeature("CSS", "2.0") ) {
- htmlElement.addEventListener("mousedown", this._mouseDownHandler.bindAsEventListener(this), false);
- }
- else {
- htmlElement.attachEvent( "onmousedown", this._mouseDownHandler.bindAsEventListener(this) );
- }
+ _onmousedown: function () {
+ Event.observe(document.body, "mousemove", this._mouseMove);
+ Event.observe(document.body, "mouseup", this._mouseUp);
},
_terminateEvent: function(e) {
@@ -1289,31 +1320,204 @@ Rico.DragAndDrop.prototype = {
if ( e.preventDefault != undefined )
e.preventDefault();
else
- {
e.returnValue = false;
- }
+ }
+
+}
+
+Rico.Draggable = Class.create();
+
+Rico.Draggable.prototype = {
+
+ initialize: function( type, htmlElement ) {
+ this.type = type;
+ this.htmlElement = $(htmlElement);
+ this.selected = false;
+ },
+
+ /**
+ * Returns the HTML element that should have a mouse down event
+ * added to it in order to initiate a drag operation
+ *
+ **//*
+ getMouseDownHTMLElement: function() {
+ return this.htmlElement;
+ },
+
+ select: function() {
+ this.selected = true;
+
+ if ( this.showingSelected )
+ return;
+
+ var htmlElement = this.getMouseDownHTMLElement();
+
+ var color = Rico.Color.createColorFromBackground(htmlElement);
+ color.isBright() ? color.darken(0.033) : color.brighten(0.033);
+
+ this.saveBackground = RicoUtil.getElementsComputedStyle(htmlElement, "backgroundColor", "background-color");
+ htmlElement.style.backgroundColor = color.asHex();
+ this.showingSelected = true;
+ },
+
+ deselect: function() {
+ this.selected = false;
+ if ( !this.showingSelected )
+ return;
+
+ var htmlElement = this.getMouseDownHTMLElement();
+
+ htmlElement.style.backgroundColor = this.saveBackground;
+ this.showingSelected = false;
+ },
+
+ isSelected: function() {
+ return this.selected;
+ },
+
+ startDrag: function() {
+ },
+
+ cancelDrag: function() {
+ },
+
+ endDrag: function() {
+ },
+
+ getSingleObjectDragGUI: function() {
+ return this.htmlElement;
+ },
+
+ getMultiObjectDragGUI: function( draggables ) {
+ return this.htmlElement;
+ },
+
+ getDroppedGUI: function() {
+ return this.htmlElement;
+ },
+
+ toString: function() {
+ return this.type + ":" + this.htmlElement + ":";
+ }
+
+}
+
+Rico.Dropzone = Class.create();
+
+Rico.Dropzone.prototype = {
+
+ initialize: function( htmlElement ) {
+ this.htmlElement = $(htmlElement);
+ this.absoluteRect = null;
},
- initializeEventHandlers: function() {
- if ( typeof document.implementation != "undefined" &&
- document.implementation.hasFeature("HTML", "1.0") &&
- document.implementation.hasFeature("Events", "2.0") &&
- document.implementation.hasFeature("CSS", "2.0") ) {
- document.addEventListener("mouseup", this._mouseUpHandler.bindAsEventListener(this), false);
- document.addEventListener("mousemove", this._mouseMoveHandler.bindAsEventListener(this), false);
+ getHTMLElement: function() {
+ return this.htmlElement;
+ },
+
+ clearPositionCache: function() {
+ this.absoluteRect = null;
+ },
+
+ getAbsoluteRect: function() {
+ if ( this.absoluteRect == null ) {
+ var htmlElement = this.getHTMLElement();
+ var pos = RicoUtil.toViewportPosition(htmlElement);
+
+ this.absoluteRect = {
+ top: pos.y,
+ left: pos.x,
+ bottom: pos.y + htmlElement.offsetHeight,
+ right: pos.x + htmlElement.offsetWidth
+ };
}
+ return this.absoluteRect;
+ },
+
+ activate: function() {
+ var htmlElement = this.getHTMLElement();
+ if (htmlElement == null || this.showingActive)
+ return;
+
+ this.showingActive = true;
+ this.saveBackgroundColor = htmlElement.style.backgroundColor;
+
+ var fallbackColor = "#ffea84";
+ var currentColor = Rico.Color.createColorFromBackground(htmlElement);
+ if ( currentColor == null )
+ htmlElement.style.backgroundColor = fallbackColor;
else {
- document.attachEvent( "onmouseup", this._mouseUpHandler.bindAsEventListener(this) );
- document.attachEvent( "onmousemove", this._mouseMoveHandler.bindAsEventListener(this) );
+ currentColor.isBright() ? currentColor.darken(0.2) : currentColor.brighten(0.2);
+ htmlElement.style.backgroundColor = currentColor.asHex();
+ }
+ },
+
+ deactivate: function() {
+ var htmlElement = this.getHTMLElement();
+ if (htmlElement == null || !this.showingActive)
+ return;
+
+ htmlElement.style.backgroundColor = this.saveBackgroundColor;
+ this.showingActive = false;
+ this.saveBackgroundColor = null;
+ },
+
+ showHover: function() {
+ var htmlElement = this.getHTMLElement();
+ if ( htmlElement == null || this.showingHover )
+ return;
+
+ this.saveBorderWidth = htmlElement.style.borderWidth;
+ this.saveBorderStyle = htmlElement.style.borderStyle;
+ this.saveBorderColor = htmlElement.style.borderColor;
+
+ this.showingHover = true;
+ htmlElement.style.borderWidth = "1px";
+ htmlElement.style.borderStyle = "solid";
+ //htmlElement.style.borderColor = "#ff9900";
+ htmlElement.style.borderColor = "#ffff00";
+ },
+
+ hideHover: function() {
+ var htmlElement = this.getHTMLElement();
+ if ( htmlElement == null || !this.showingHover )
+ return;
+
+ htmlElement.style.borderWidth = this.saveBorderWidth;
+ htmlElement.style.borderStyle = this.saveBorderStyle;
+ htmlElement.style.borderColor = this.saveBorderColor;
+ this.showingHover = false;
+ },
+
+ canAccept: function(draggableObjects) {
+ return true;
+ },
+
+ accept: function(draggableObjects) {
+ var htmlElement = this.getHTMLElement();
+ if ( htmlElement == null )
+ return;
+
+ n = draggableObjects.length;
+ for ( var i = 0 ; i < n ; i++ )
+ {
+ var theGUI = draggableObjects[i].getDroppedGUI();
+ if ( RicoUtil.getElementsComputedStyle( theGUI, "position" ) == "absolute" )
+ {
+ theGUI.style.position = "static";
+ theGUI.style.top = "";
+ theGUI.style.top = "";
+ }
+ htmlElement.appendChild(theGUI);
}
}
-};
+}
var dndMgr = new Rico.DragAndDrop();
-dndMgr.initializeEventHandlers();
-
-// ricoDraggable.js --------------------
-
+
+
+
+//-------------------- ricoDraggable.js
Rico.Draggable = Class.create();
Rico.Draggable.prototype = {
@@ -1328,7 +1532,7 @@ Rico.Draggable.prototype = {
* Returns the HTML element that should have a mouse down event
* added to it in order to initiate a drag operation
*
- **/
+ **//*
getMouseDownHTMLElement: function() {
return this.htmlElement;
},
@@ -1389,10 +1593,10 @@ Rico.Draggable.prototype = {
return this.type + ":" + this.htmlElement + ":";
}
-}
-
-// ricoDropzone.js --------------------
-
+}
+
+
+//-------------------- ricoDropzone.js
Rico.Dropzone = Class.create();
Rico.Dropzone.prototype = {
@@ -1502,10 +1706,19 @@ Rico.Dropzone.prototype = {
htmlElement.appendChild(theGUI);
}
}
-}
-
-// ricoEffects.js --------------------
-
+}
+*/
+
+
+//-------------------- ricoEffect.js
+
+/**
+ * Use the Effect namespace for effects. If using scriptaculous effects
+ * this will already be defined, otherwise we'll just create an empty
+ * object for it...
+ **/
+if ( window.Effect == undefined )
+ Effect = {};
Effect.SizeAndPosition = Class.create();
Effect.SizeAndPosition.prototype = {
@@ -1665,18 +1878,243 @@ Effect.FadeTo.prototype = {
getElementOpacity: function() {
if ( this.element.ricoOpacity == undefined ) {
- var opacity;
- if ( this.element.currentStyle ) {
- opacity = this.element.currentStyle.opacity;
- }
- else if ( document.defaultView.getComputedStyle != undefined ) {
- var computedStyle = document.defaultView.getComputedStyle;
- opacity = computedStyle(this.element, null).getPropertyValue('opacity');
- }
-
+ var opacity = RicoUtil.getElementsComputedStyle(this.element, 'opacity');
this.element.ricoOpacity = opacity != undefined ? opacity : 1.0;
}
+ return parseFloat(this.element.ricoOpacity);
+ }
+}
+
+Effect.AccordionSize = Class.create();
+
+Effect.AccordionSize.prototype = {
+
+ initialize: function(e1, e2, start, end, duration, steps, options) {
+ this.e1 = $(e1);
+ this.e2 = $(e2);
+ this.start = start;
+ this.end = end;
+ this.duration = duration;
+ this.steps = steps;
+ this.options = arguments[6] || {};
+
+ this.accordionSize();
+ },
+
+ accordionSize: function() {
+
+ if (this.isFinished()) {
+ // just in case there are round errors or such...
+ this.e1.style.height = this.start + "px";
+ this.e2.style.height = this.end + "px";
+
+ if(this.options.complete)
+ this.options.complete(this);
+ return;
+ }
+
+ if (this.timer)
+ clearTimeout(this.timer);
+
+ var stepDuration = Math.round(this.duration/this.steps) ;
+
+ var diff = this.steps > 0 ? (parseInt(this.e1.offsetHeight) - this.start)/this.steps : 0;
+ this.resizeBy(diff);
+
+ this.duration -= stepDuration;
+ this.steps--;
+
+ this.timer = setTimeout(this.accordionSize.bind(this), stepDuration);
+ },
+
+ isFinished: function() {
+ return this.steps <= 0;
+ },
+
+ resizeBy: function(diff) {
+ var h1Height = this.e1.offsetHeight;
+ var h2Height = this.e2.offsetHeight;
+ var intDiff = parseInt(diff);
+ if ( diff != 0 ) {
+ this.e1.style.height = (h1Height - intDiff) + "px";
+ this.e2.style.height = (h2Height + intDiff) + "px";
+ }
+ }
+
+};
+
+
+//-------------------- ricoEffects.js
+
+/**
+ * Use the Effect namespace for effects. If using scriptaculous effects
+ * this will already be defined, otherwise we'll just create an empty
+ * object for it...
+ **/
+if ( window.Effect == undefined )
+ Effect = {};
+
+Effect.SizeAndPosition = Class.create();
+Effect.SizeAndPosition.prototype = {
+
+ initialize: function(element, x, y, w, h, duration, steps, options) {
+ this.element = $(element);
+ this.x = x;
+ this.y = y;
+ this.w = w;
+ this.h = h;
+ this.duration = duration;
+ this.steps = steps;
+ this.options = arguments[7] || {};
+
+ this.sizeAndPosition();
+ },
+
+ sizeAndPosition: function() {
+ if (this.isFinished()) {
+ if(this.options.complete) this.options.complete(this);
+ return;
+ }
+
+ if (this.timer)
+ clearTimeout(this.timer);
+
+ var stepDuration = Math.round(this.duration/this.steps) ;
+
+ // Get original values: x,y = top left corner; w,h = width height
+ var currentX = this.element.offsetLeft;
+ var currentY = this.element.offsetTop;
+ var currentW = this.element.offsetWidth;
+ var currentH = this.element.offsetHeight;
+
+ // If values not set, or zero, we do not modify them, and take original as final as well
+ this.x = (this.x) ? this.x : currentX;
+ this.y = (this.y) ? this.y : currentY;
+ this.w = (this.w) ? this.w : currentW;
+ this.h = (this.h) ? this.h : currentH;
+
+ // how much do we need to modify our values for each step?
+ var difX = this.steps > 0 ? (this.x - currentX)/this.steps : 0;
+ var difY = this.steps > 0 ? (this.y - currentY)/this.steps : 0;
+ var difW = this.steps > 0 ? (this.w - currentW)/this.steps : 0;
+ var difH = this.steps > 0 ? (this.h - currentH)/this.steps : 0;
+
+ this.moveBy(difX, difY);
+ this.resizeBy(difW, difH);
+
+ this.duration -= stepDuration;
+ this.steps--;
+
+ this.timer = setTimeout(this.sizeAndPosition.bind(this), stepDuration);
+ },
+
+ isFinished: function() {
+ return this.steps <= 0;
+ },
+
+ moveBy: function( difX, difY ) {
+ var currentLeft = this.element.offsetLeft;
+ var currentTop = this.element.offsetTop;
+ var intDifX = parseInt(difX);
+ var intDifY = parseInt(difY);
+
+ var style = this.element.style;
+ if ( intDifX != 0 )
+ style.left = (currentLeft + intDifX) + "px";
+ if ( intDifY != 0 )
+ style.top = (currentTop + intDifY) + "px";
+ },
+
+ resizeBy: function( difW, difH ) {
+ var currentWidth = this.element.offsetWidth;
+ var currentHeight = this.element.offsetHeight;
+ var intDifW = parseInt(difW);
+ var intDifH = parseInt(difH);
+
+ var style = this.element.style;
+ if ( intDifW != 0 )
+ style.width = (currentWidth + intDifW) + "px";
+ if ( intDifH != 0 )
+ style.height = (currentHeight + intDifH) + "px";
+ }
+}
+
+Effect.Size = Class.create();
+Effect.Size.prototype = {
+
+ initialize: function(element, w, h, duration, steps, options) {
+ new Effect.SizeAndPosition(element, null, null, w, h, duration, steps, options);
+ }
+}
+
+Effect.Position = Class.create();
+Effect.Position.prototype = {
+
+ initialize: function(element, x, y, duration, steps, options) {
+ new Effect.SizeAndPosition(element, x, y, null, null, duration, steps, options);
+ }
+}
+
+Effect.Round = Class.create();
+Effect.Round.prototype = {
+
+ initialize: function(tagName, className, options) {
+ var elements = document.getElementsByTagAndClassName(tagName,className);
+ for ( var i = 0 ; i < elements.length ; i++ )
+ Rico.Corner.round( elements[i], options );
+ }
+};
+
+Effect.FadeTo = Class.create();
+Effect.FadeTo.prototype = {
+
+ initialize: function( element, opacity, duration, steps, options) {
+ this.element = $(element);
+ this.opacity = opacity;
+ this.duration = duration;
+ this.steps = steps;
+ this.options = arguments[4] || {};
+ this.fadeTo();
+ },
+
+ fadeTo: function() {
+ if (this.isFinished()) {
+ if(this.options.complete) this.options.complete(this);
+ return;
+ }
+
+ if (this.timer)
+ clearTimeout(this.timer);
+
+ var stepDuration = Math.round(this.duration/this.steps) ;
+ var currentOpacity = this.getElementOpacity();
+ var delta = this.steps > 0 ? (this.opacity - currentOpacity)/this.steps : 0;
+
+ this.changeOpacityBy(delta);
+ this.duration -= stepDuration;
+ this.steps--;
+
+ this.timer = setTimeout(this.fadeTo.bind(this), stepDuration);
+ },
+
+ changeOpacityBy: function(v) {
+ var currentOpacity = this.getElementOpacity();
+ var newOpacity = Math.max(0, Math.min(currentOpacity+v, 1));
+ this.element.ricoOpacity = newOpacity;
+ this.element.style.filter = "alpha(opacity:"+Math.round(newOpacity*100)+")";
+ this.element.style.opacity = newOpacity; /*//*/;
+ },
+
+ isFinished: function() {
+ return this.steps <= 0;
+ },
+
+ getElementOpacity: function() {
+ if ( this.element.ricoOpacity == undefined ) {
+ var opacity = RicoUtil.getElementsComputedStyle(this.element, 'opacity');
+ this.element.ricoOpacity = opacity != undefined ? opacity : 1.0;
+ }
return parseFloat(this.element.ricoOpacity);
}
}
@@ -1738,30 +2176,29 @@ Effect.AccordionSize.prototype = {
}
};
-
-
-// ricoLiveGrid.js --------------------
-
+
+//-------------------- ricoLiveGrid.js
// Rico.LiveGridMetaData -----------------------------------------------------
Rico.LiveGridMetaData = Class.create();
Rico.LiveGridMetaData.prototype = {
- initialize: function( pageSize, totalRows, options ) {
+ initialize: function( pageSize, totalRows, columnCount, options ) {
this.pageSize = pageSize;
this.totalRows = totalRows;
this.setOptions(options);
- this.scrollArrowHeight = 16;
+ this.ArrowHeight = 16;
+ this.columnCount = columnCount;
},
setOptions: function(options) {
this.options = {
largeBufferSize : 7.0, // 7 pages
- smallBufferSize : 1.0, // 1 page
nearLimitFactor : 0.2 // 20% of buffer
- }.extend(options || {});
+ };
+ Object.extend(this.options, options || {});
},
getPageSize: function() {
@@ -1780,17 +2217,9 @@ Rico.LiveGridMetaData.prototype = {
return parseInt(this.options.largeBufferSize * this.pageSize);
},
- getSmallBufferSize: function() {
- return parseInt(this.options.smallBufferSize * this.pageSize);
- },
-
getLimitTolerance: function() {
return parseInt(this.getLargeBufferSize() * this.options.nearLimitFactor);
- },
-
- getBufferSize: function(isFull) {
- return isFull ? this.getLargeBufferSize() : this.getSmallBufferSize();
- }
+ }
};
// Rico.LiveGridScroller -----------------------------------------------------
@@ -1799,14 +2228,15 @@ Rico.LiveGridScroller = Class.create();
Rico.LiveGridScroller.prototype = {
- initialize: function(liveGrid) {
+ initialize: function(liveGrid, viewPort) {
this.isIE = navigator.userAgent.toLowerCase().indexOf("msie") >= 0;
this.liveGrid = liveGrid;
this.metaData = liveGrid.metaData;
this.createScrollBar();
this.scrollTimeout = null;
- //this.sizeIEHeaderHack();
this.lastScrollPos = 0;
+ this.viewPort = viewPort;
+ this.rows = new Array();
},
isUnPlugged: function() {
@@ -1830,13 +2260,11 @@ Rico.LiveGridScroller.prototype = {
},
createScrollBar: function() {
- var table = this.liveGrid.table;
- var visibleHeight = table.offsetHeight;
-
+ var visibleHeight = this.liveGrid.viewPort.visibleHeight();
// create the outer div...
this.scrollerDiv = document.createElement("div");
var scrollerStyle = this.scrollerDiv.style;
- scrollerStyle.borderRight = "1px solid #ababab"; // hard coded color!!!
+ scrollerStyle.borderRight = this.liveGrid.options.scrollerBorderRight;
scrollerStyle.position = "relative";
scrollerStyle.left = this.isIE ? "-6px" : "-3px";
scrollerStyle.width = "19px";
@@ -1846,47 +2274,70 @@ Rico.LiveGridScroller.prototype = {
// create the inner div...
this.heightDiv = document.createElement("div");
this.heightDiv.style.width = "1px";
+
this.heightDiv.style.height = parseInt(visibleHeight *
this.metaData.getTotalRows()/this.metaData.getPageSize()) + "px" ;
- this.lineHeight = visibleHeight/this.metaData.getPageSize();
-
this.scrollerDiv.appendChild(this.heightDiv);
this.scrollerDiv.onscroll = this.handleScroll.bindAsEventListener(this);
- table.parentNode.insertBefore( this.scrollerDiv, table.nextSibling );
- },
+
+ var table = this.liveGrid.table;
+ table.parentNode.parentNode.insertBefore( this.scrollerDiv, table.parentNode.nextSibling );
+ var eventName = this.isIE ? "mousewheel" : "DOMMouseScroll";
+ Event.observe(table, eventName,
+ function(evt) {
+ if (evt.wheelDelta>=0 || evt.detail < 0) //wheel-up
+ this.scrollerDiv.scrollTop -= (2*this.viewPort.rowHeight);
+ else
+ this.scrollerDiv.scrollTop += (2*this.viewPort.rowHeight);
+ this.handleScroll(false);
+ }.bindAsEventListener(this),
+ false);
+ },
updateSize: function() {
var table = this.liveGrid.table;
- var visibleHeight = table.offsetHeight;
+ var visibleHeight = this.viewPort.visibleHeight();
this.heightDiv.style.height = parseInt(visibleHeight *
this.metaData.getTotalRows()/this.metaData.getPageSize()) + "px";
},
- adjustScrollTop: function() {
- this.unplug();
- var rem = this.scrollerDiv.scrollTop % this.lineHeight;
- if (rem != 0) {
- if (this.lastScrollPos < this.scrollerDiv.scrollTop)
- this.scrollerDiv.scrollTop = this.scrollerDiv.scrollTop + this.lineHeight -rem;
- else
- this.scrollerDiv.scrollTop = this.scrollerDiv.scrollTop - rem;
- }
- this.lastScrollPos = this.scrollerDiv.scrollTop;
- this.plugin();
+ rowToPixel: function(rowOffset) {
+ return (rowOffset / this.metaData.getTotalRows()) * this.heightDiv.offsetHeight
+ },
+
+ moveScroll: function(rowOffset) {
+ this.scrollerDiv.scrollTop = this.rowToPixel(rowOffset);
+ if ( this.metaData.options.onscroll )
+ this.metaData.options.onscroll( this.liveGrid, rowOffset );
},
handleScroll: function() {
- if ( this.scrollTimeout )
+ if ( this.scrollTimeout )
clearTimeout( this.scrollTimeout );
- //this.adjustScrollTop();
- var contentOffset = parseInt(this.scrollerDiv.scrollTop *
- this.metaData.getTotalRows() / this.heightDiv.offsetHeight);
- this.liveGrid.requestContentRefresh(contentOffset);
- if ( this.metaData.options.onscroll )
- this.metaData.options.onscroll( contentOffset, this.metaData );
+ var scrollDiff = this.lastScrollPos-this.scrollerDiv.scrollTop;
+ if (scrollDiff != 0.00) {
+ var r = this.scrollerDiv.scrollTop % this.viewPort.rowHeight;
+ if (r != 0) {
+ this.unplug();
+ if ( scrollDiff < 0 ) {
+ this.scrollerDiv.scrollTop += (this.viewPort.rowHeight-r);
+ } else {
+ this.scrollerDiv.scrollTop -= r;
+ }
+ this.plugin();
+ }
+ }
+ var contentOffset = parseInt(this.scrollerDiv.scrollTop / this.viewPort.rowHeight);
+ this.liveGrid.requestContentRefresh(contentOffset);
+ this.viewPort.scrollTo(this.scrollerDiv.scrollTop);
+
+ if ( this.metaData.options.onscroll )
+ this.metaData.options.onscroll( this.liveGrid, contentOffset );
+
+ this.scrollTimeout = setTimeout(this.scrollIdle.bind(this), 1200 );
+ this.lastScrollPos = this.scrollerDiv.scrollTop;
- this.scrollTimeout = setTimeout( this.scrollIdle.bind(this), 1200 );
},
scrollIdle: function() {
@@ -1901,60 +2352,105 @@ Rico.LiveGridBuffer = Class.create();
Rico.LiveGridBuffer.prototype = {
- initialize: function(metaData) {
+ initialize: function(metaData, viewPort) {
this.startPos = 0;
this.size = 0;
this.metaData = metaData;
this.rows = new Array();
this.updateInProgress = false;
+ this.viewPort = viewPort;
+ this.maxBufferSize = metaData.getLargeBufferSize() * 2;
+ this.maxFetchSize = metaData.getLargeBufferSize();
+ this.lastOffset = 0;
},
- update: function(ajaxResponse,start) {
-
- this.startPos = start;
- this.rows = new Array();
+ getBlankRow: function() {
+ if (!this.blankRow ) {
+ this.blankRow = new Array();
+ for ( var i=0; i < this.metaData.columnCount ; i++ )
+ this.blankRow[i] = "&nbsp;";
+ }
+ return this.blankRow;
+ },
+ loadRows: function(ajaxResponse) {
var rowsElement = ajaxResponse.getElementsByTagName('rows')[0];
- this.updateUI = rowsElement.getAttribute("update_ui") == "true";
+ this.updateUI = rowsElement.getAttribute("update_ui") == "true"
+ var newRows = new Array()
var trs = rowsElement.getElementsByTagName("tr");
for ( var i=0 ; i < trs.length; i++ ) {
- var row = this.rows[i] = new Array();
+ var row = newRows[i] = new Array();
var cells = trs[i].getElementsByTagName("td");
for ( var j=0; j < cells.length ; j++ ) {
var cell = cells[j];
var convertSpaces = cell.getAttribute("convert_spaces") == "true";
- var cellContent = cell.text != undefined ? cell.text : cell.textContent;
+ var cellContent = RicoUtil.getContentAsString(cell);
row[j] = convertSpaces ? this.convertSpaces(cellContent) : cellContent;
+ if (!row[j])
+ row[j] = '&nbsp;';
}
}
- this.size = trs.length;
+ return newRows;
},
- isFullP: function() {
- return this.metaData.pageSize != this.size;
- },
+ update: function(ajaxResponse, start) {
+ var newRows = this.loadRows(ajaxResponse);
+ if (this.rows.length == 0) { // initial load
+ this.rows = newRows;
+ this.size = this.rows.length;
+ this.startPos = start;
+ return;
+ }
+ if (start > this.startPos) { //appending
+ if (this.startPos + this.rows.length < start) {
+ this.rows = newRows;
+ this.startPos = start;//
+ } else {
+ this.rows = this.rows.concat( newRows.slice(0, newRows.length));
+ if (this.rows.length > this.maxBufferSize) {
+ var fullSize = this.rows.length;
+ this.rows = this.rows.slice(this.rows.length - this.maxBufferSize, this.rows.length)
+ this.startPos = this.startPos + (fullSize - this.rows.length);
+ }
+ }
+ } else { //prepending
+ if (start + newRows.length < this.startPos) {
+ this.rows = newRows;
+ } else {
+ this.rows = newRows.slice(0, this.startPos).concat(this.rows);
+ if (this.rows.length > this.maxBufferSize)
+ this.rows = this.rows.slice(0, this.maxBufferSize)
+ }
+ this.startPos = start;
+ }
+ this.size = this.rows.length;
+ },
- isClose: function(start) {
- return (start < this.startPos + this.size + (this.size/2)) &&
- (start + this.size + (this.size/2) > this.startPos)
- },
+ clear: function() {
+ this.rows = new Array();
+ this.startPos = 0;
+ this.size = 0;
+ },
- isInRange: function(start, count) {
- return (start < this.startPos + this.size) && (start + count > this.startPos)
+ isOverlapping: function(start, size) {
+ return ((start < this.endPos()) && (this.startPos < start + size)) || (this.endPos() == 0)
},
- isFullyInRange: function(position) {
- return (position >= this.startPos) && (position+this.metaData.getPageSize()) <= (this.startPos + this.size)
+ isInRange: function(position) {
+ return (position >= this.startPos) && (position + this.metaData.getPageSize() <= this.endPos());
+ //&& this.size() != 0;
},
isNearingTopLimit: function(position) {
return position - this.startPos < this.metaData.getLimitTolerance();
},
+ endPos: function() {
+ return this.startPos + this.rows.length;
+ },
+
isNearingBottomLimit: function(position) {
- var myEnd = position + this.metaData.getPageSize();
- var bufferEnd = this.startPos + this.size;
- return bufferEnd - myEnd < this.metaData.getLimitTolerance();
+ return this.endPos() - (position + this.metaData.getPageSize()) < this.metaData.getLimitTolerance();
},
isAtTop: function() {
@@ -1962,7 +2458,7 @@ Rico.LiveGridBuffer.prototype = {
},
isAtBottom: function() {
- return this.startPos + this.size == this.metaData.getTotalRows();
+ return this.endPos() == this.metaData.getTotalRows();
},
isNearingLimit: function(position) {
@@ -1970,15 +2466,49 @@ Rico.LiveGridBuffer.prototype = {
( !this.isAtBottom() && this.isNearingBottomLimit(position) )
},
+ getFetchSize: function(offset) {
+ var adjustedOffset = this.getFetchOffset(offset);
+ var adjustedSize = 0;
+ if (adjustedOffset >= this.startPos) { //apending
+ var endFetchOffset = this.maxFetchSize + adjustedOffset;
+ if (endFetchOffset > this.metaData.totalRows)
+ endFetchOffset = this.metaData.totalRows;
+ adjustedSize = endFetchOffset - adjustedOffset;
+ if(adjustedOffset == 0 && adjustedSize < this.maxFetchSize){
+ adjustedSize = this.maxFetchSize;
+ }
+ } else {//prepending
+ var adjustedSize = this.startPos - adjustedOffset;
+ if (adjustedSize > this.maxFetchSize)
+ adjustedSize = this.maxFetchSize;
+ }
+ return adjustedSize;
+ },
+
+ getFetchOffset: function(offset) {
+ var adjustedOffset = offset;
+ if (offset > this.startPos) //apending
+ adjustedOffset = (offset > this.endPos()) ? offset : this.endPos();
+ else { //prepending
+ if (offset + this.maxFetchSize >= this.startPos) {
+ var adjustedOffset = this.startPos - this.maxFetchSize;
+ if (adjustedOffset < 0)
+ adjustedOffset = 0;
+ }
+ }
+ this.lastOffset = adjustedOffset;
+ return adjustedOffset;
+ },
+
getRows: function(start, count) {
- var begPos = start - this.startPos;
- var endPos = begPos + count;
+ var begPos = start - this.startPos
+ var endPos = begPos + count
// er? need more data...
if ( endPos > this.size )
- endPos = this.size;
+ endPos = this.size
- var results = new Array();
+ var results = new Array()
var index = 0;
for ( var i=begPos ; i < endPos; i++ ) {
results[index++] = this.rows[i]
@@ -1992,10 +2522,111 @@ Rico.LiveGridBuffer.prototype = {
};
+
+//Rico.GridViewPort --------------------------------------------------
+Rico.GridViewPort = Class.create();
+
+Rico.GridViewPort.prototype = {
+
+ initialize: function(table, rowHeight, visibleRows, buffer, liveGrid) {
+ this.lastDisplayedStartPos = 0;
+ this.div = table.parentNode;
+ this.table = table
+ this.rowHeight = rowHeight;
+ this.div.style.height = this.rowHeight * visibleRows;
+ this.div.style.overflow = "hidden";
+ this.buffer = buffer;
+ this.liveGrid = liveGrid;
+ this.visibleRows = visibleRows + 1;
+ this.lastPixelOffset = 0;
+ this.startPos = 0;
+ },
+
+ populateRow: function(htmlRow, row) {
+ for (var j=0; j < row.length; j++) {
+ htmlRow.cells[j].innerHTML = row[j]
+ }
+ },
+
+ bufferChanged: function() {
+ this.refreshContents( parseInt(this.lastPixelOffset / this.rowHeight));
+ },
+
+ clearRows: function() {
+ if (!this.isBlank) {
+ this.liveGrid.table.className = this.liveGrid.options.loadingClass;
+ for (var i=0; i < this.visibleRows; i++)
+ this.populateRow(this.table.rows[i], this.buffer.getBlankRow());
+ this.isBlank = true;
+ }
+ },
+
+ clearContents: function() {
+ this.clearRows();
+ this.scrollTo(0);
+ this.startPos = 0;
+ this.lastStartPos = -1;
+ },
+
+ refreshContents: function(startPos) {
+ if (startPos == this.lastRowPos && !this.isPartialBlank && !this.isBlank) {
+ return;
+ }
+ if ((startPos + this.visibleRows < this.buffer.startPos)
+ || (this.buffer.startPos + this.buffer.size < startPos)
+ || (this.buffer.size == 0)) {
+ this.clearRows();
+ return;
+ }
+ this.isBlank = false;
+ var viewPrecedesBuffer = this.buffer.startPos > startPos
+ var contentStartPos = viewPrecedesBuffer ? this.buffer.startPos: startPos;
+ var contentEndPos = (this.buffer.startPos + this.buffer.size < startPos + this.visibleRows)
+ ? this.buffer.startPos + this.buffer.size
+ : startPos + this.visibleRows;
+ var rowSize = contentEndPos - contentStartPos;
+ var rows = this.buffer.getRows(contentStartPos, rowSize );
+ var blankSize = this.visibleRows - rowSize;
+ var blankOffset = viewPrecedesBuffer ? 0: rowSize;
+ var contentOffset = viewPrecedesBuffer ? blankSize: 0;
+
+ for (var i=0; i < rows.length; i++) {//initialize what we have
+ this.populateRow(this.table.rows[i + contentOffset], rows[i]);
+ }
+ for (var i=0; i < blankSize; i++) {// blank out the rest
+ this.populateRow(this.table.rows[i + blankOffset], this.buffer.getBlankRow());
+ }
+ this.isPartialBlank = blankSize > 0;
+ this.lastRowPos = startPos;
+
+ this.liveGrid.table.className = this.liveGrid.options.tableClass;
+ // Check if user has set a onRefreshComplete function
+ var onRefreshComplete = this.liveGrid.options.onRefreshComplete;
+ if (onRefreshComplete != null)
+ onRefreshComplete();
+ },
+
+ scrollTo: function(pixelOffset) {
+ if (this.lastPixelOffset == pixelOffset)
+ return;
+
+ this.refreshContents(parseInt(pixelOffset / this.rowHeight))
+ this.div.scrollTop = pixelOffset % this.rowHeight
+
+ this.lastPixelOffset = pixelOffset;
+ },
+
+ visibleHeight: function() {
+ return parseInt(RicoUtil.getElementsComputedStyle(this.div, 'height'));
+ }
+
+};
+
+
Rico.LiveGridRequest = Class.create();
Rico.LiveGridRequest.prototype = {
initialize: function( requestOffset, options ) {
- this.requestOffset = requestOffset;
+ this.requestOffset = requestOffset;
}
};
@@ -2005,36 +2636,103 @@ Rico.LiveGrid = Class.create();
Rico.LiveGrid.prototype = {
- initialize: function( tableId, visibleRows, totalRows, url, options ) {
-
- if ( options == null )
- options = {};
+ initialize: function( tableId, visibleRows, totalRows, url, options, ajaxOptions ) {
+
+ this.options = {
+ tableClass: $(tableId).className,
+ loadingClass: $(tableId).className,
+ scrollerBorderRight: '1px solid #ababab',
+ bufferTimeout: 20000,
+ sortAscendImg: 'images/sort_asc.gif',
+ sortDescendImg: 'images/sort_desc.gif',
+ sortImageWidth: 9,
+ sortImageHeight: 5,
+ ajaxSortURLParms: [],
+ onRefreshComplete: null,
+ requestParameters: null,
+ inlineStyles: true
+ };
+ Object.extend(this.options, options || {});
+
+ this.ajaxOptions = {parameters: null};
+ Object.extend(this.ajaxOptions, ajaxOptions || {});
this.tableId = tableId;
this.table = $(tableId);
- this.metaData = new Rico.LiveGridMetaData(visibleRows, totalRows, options);
+
+ this.addLiveGridHtml();
+
+ var columnCount = this.table.rows[0].cells.length;
+ this.metaData = new Rico.LiveGridMetaData(visibleRows, totalRows, columnCount, options);
this.buffer = new Rico.LiveGridBuffer(this.metaData);
- this.scroller = new Rico.LiveGridScroller(this);
- this.lastDisplayedStartPos = 0;
- this.timeoutHander = null;
- this.additionalParms = options.requestParameters || [];
+ var rowCount = this.table.rows.length;
+ this.viewPort = new Rico.GridViewPort(this.table,
+ this.table.offsetHeight/rowCount,
+ visibleRows,
+ this.buffer, this);
+ this.scroller = new Rico.LiveGridScroller(this,this.viewPort);
+ this.options.sortHandler = this.sortHandler.bind(this);
+
+ if ( $(tableId + '_header') )
+ this.sort = new Rico.LiveGridSort(tableId + '_header', this.options)
this.processingRequest = null;
this.unprocessedRequest = null;
this.initAjax(url);
- if ( options.prefetchBuffer )
- this.fetchBuffer(0, true);
+ if ( this.options.prefetchBuffer || this.options.prefetchOffset > 0) {
+ var offset = 0;
+ if (this.options.offset ) {
+ offset = this.options.offset;
+ this.scroller.moveScroll(offset);
+ this.viewPort.scrollTo(this.scroller.rowToPixel(offset));
+ }
+ if (this.options.sortCol) {
+ this.sortCol = options.sortCol;
+ this.sortDir = options.sortDir;
+ }
+ this.requestContentRefresh(offset);
+ }
},
- setRequestParams: function() {
- this.additionalParms = [];
- for ( var i=0 ; i < arguments.length ; i++ )
- this.additionalParms[i] = arguments[i];
+ addLiveGridHtml: function() {
+ // Check to see if need to create a header table.
+ if (this.table.getElementsByTagName("thead").length > 0){
+ // Create Table this.tableId+'_header'
+ var tableHeader = this.table.cloneNode(true);
+ tableHeader.setAttribute('id', this.tableId+'_header');
+ tableHeader.setAttribute('class', this.table.className+'_header');
+
+ // Clean up and insert
+ for( var i = 0; i < tableHeader.tBodies.length; i++ )
+ tableHeader.removeChild(tableHeader.tBodies[i]);
+ this.table.deleteTHead();
+ this.table.parentNode.insertBefore(tableHeader,this.table);
+ }
+
+ new Insertion.Before(this.table, "<div id='"+this.tableId+"_container'></div>");
+ this.table.previousSibling.appendChild(this.table);
+ new Insertion.Before(this.table,"<div id='"+this.tableId+"_viewport' style='float:left;'></div>");
+ this.table.previousSibling.appendChild(this.table);
+ },
+
+ resetContents: function() {
+ this.scroller.moveScroll(0);
+ this.buffer.clear();
+ this.viewPort.clearContents();
+ },
+
+ sortHandler: function(column) {
+ this.sortCol = column.name;
+ this.sortDir = column.currentSort;
+
+ this.resetContents();
+ this.requestContentRefresh(0)
},
setTotalRows: function( newTotalRows ) {
+ this.resetContents();
this.metaData.setTotalRows(newTotalRows);
this.scroller.updateSize();
},
@@ -2047,95 +2745,399 @@ Rico.LiveGrid.prototype = {
invokeAjax: function() {
},
- largeBufferWindowStart: function(offset) {
- val = offset - ( (.5 * this.metaData.getLargeBufferSize()) - (.5 * this.metaData.getPageSize()) );
- return Math.max(parseInt(val), 0);
- },
-
handleTimedOut: function() {
//server did not respond in 4 seconds... assume that there could have been
//an error or something, and allow requests to be processed again...
this.processingRequest = null;
+ this.processQueuedRequest();
},
- fetchBuffer: function(offset, fullBufferp) {
+ fetchBuffer: function(offset) {
+ if ( this.buffer.isInRange(offset) &&
+ !this.buffer.isNearingLimit(offset)) {
+ return;
+ }
if (this.processingRequest) {
- this.unprocessedRequest = new Rico.LiveGridRequest(offset);
- return;
+ this.unprocessedRequest = new Rico.LiveGridRequest(offset);
+ return;
}
-
- var fetchSize = this.metaData.getBufferSize(fullBufferp);
- bufferStartPos = Math.max(0,fullBufferp ? this.largeBufferWindowStart(offset) : offset);
-
+ var bufferStartPos = this.buffer.getFetchOffset(offset);
this.processingRequest = new Rico.LiveGridRequest(offset);
this.processingRequest.bufferOffset = bufferStartPos;
+ var fetchSize = this.buffer.getFetchSize(offset);
+ var partialLoaded = false;
+
+ var queryString
+ if (this.options.requestParameters)
+ queryString = this._createQueryString(this.options.requestParameters, 0);
+
+ queryString = (queryString == null) ? '' : queryString+'&';
+ queryString = queryString+'id='+this.tableId+'&page_size='+fetchSize+'&offset='+bufferStartPos;
+ if (this.sortCol)
+ queryString = queryString+'&sort_col='+escape(this.sortCol)+'&sort_dir='+this.sortDir;
- var callParms = [];
- callParms.push(this.tableId + '_request');
- callParms.push('id=' + this.tableId);
- callParms.push('page_size=' + fetchSize);
- callParms.push('offset=' + bufferStartPos);
+ this.ajaxOptions.parameters = queryString;
- for( var i=0 ; i < this.additionalParms.length ; i++ )
- callParms.push(this.additionalParms[i]);
+ ajaxEngine.sendRequest( this.tableId + '_request', this.ajaxOptions );
+
+ this.timeoutHandler = setTimeout( this.handleTimedOut.bind(this), this.options.bufferTimeout);
+
+ },
- ajaxEngine.sendRequest.apply( ajaxEngine, callParms );
- this.timeoutHandler = setTimeout( this.handleTimedOut.bind(this), 4000 );
+ setRequestParams: function() {
+ this.options.requestParameters = [];
+ for ( var i=0 ; i < arguments.length ; i++ )
+ this.options.requestParameters[i] = arguments[i];
},
requestContentRefresh: function(contentOffset) {
- if ( this.buffer && this.buffer.isFullyInRange(contentOffset) ) {
- this.updateContent(contentOffset);
- if (this.buffer.isNearingLimit(contentOffset))
- this.fetchBuffer(contentOffset, true);
- }
- else if (this.buffer && this.buffer.isClose(contentOffset))
- this.fetchBuffer(contentOffset, true);
- else
- this.fetchBuffer(contentOffset, false);
+ this.fetchBuffer(contentOffset);
},
ajaxUpdate: function(ajaxResponse) {
try {
clearTimeout( this.timeoutHandler );
- this.buffer = new Rico.LiveGridBuffer(this.metaData);
this.buffer.update(ajaxResponse,this.processingRequest.bufferOffset);
- if (this.unprocessedRequest == null) {
- offset = this.processingRequest.requestOffset;
- this.updateContent (offset);
+ this.viewPort.bufferChanged();
+ }
+ catch(err) {}
+ finally {this.processingRequest = null; }
+ this.processQueuedRequest();
+ },
+
+ _createQueryString: function( theArgs, offset ) {
+ var queryString = ""
+ if (!theArgs)
+ return queryString;
+
+ for ( var i = offset ; i < theArgs.length ; i++ ) {
+ if ( i != offset )
+ queryString += "&";
+
+ var anArg = theArgs[i];
+
+ if ( anArg.name != undefined && anArg.value != undefined ) {
+ queryString += anArg.name + "=" + escape(anArg.value);
+ }
+ else {
+ var ePos = anArg.indexOf('=');
+ var argName = anArg.substring( 0, ePos );
+ var argValue = anArg.substring( ePos + 1 );
+ queryString += argName + "=" + escape(argValue);
+ }
+ }
+ return queryString;
+ },
+
+ processQueuedRequest: function() {
+ if (this.unprocessedRequest != null) {
+ this.requestContentRefresh(this.unprocessedRequest.requestOffset);
+ this.unprocessedRequest = null
+ }
+ }
+};
+
+
+//-------------------- ricoLiveGridSort.js
+Rico.LiveGridSort = Class.create();
+
+Rico.LiveGridSort.prototype = {
+
+ initialize: function(headerTableId, options) {
+ this.headerTableId = headerTableId;
+ this.headerTable = $(headerTableId);
+ this.options = options;
+ this.setOptions();
+ this.applySortBehavior();
+
+ if ( this.options.sortCol ) {
+ this.setSortUI( this.options.sortCol, this.options.sortDir );
+ }
+ },
+
+ setSortUI: function( columnName, sortDirection ) {
+ var cols = this.options.columns;
+ for ( var i = 0 ; i < cols.length ; i++ ) {
+ if ( cols[i].name == columnName ) {
+ this.setColumnSort(i, sortDirection);
+ break;
}
- this.processingRequest = null;
- if (this.unprocessedRequest != null) {
- this.requestContentRefresh(this.unprocessedRequest.requestOffset);
- this.unprocessedRequest = null
+ }
+ },
+
+ setOptions: function() {
+ // preload the images...
+ new Image().src = this.options.sortAscendImg;
+ new Image().src = this.options.sortDescendImg;
+
+ this.sort = this.options.sortHandler;
+ if ( !this.options.columns )
+ this.options.columns = this.introspectForColumnInfo();
+ else {
+ // allow client to pass { columns: [ ["a", true], ["b", false] ] }
+ // and convert to an array of Rico.TableColumn objs...
+ this.options.columns = this.convertToTableColumns(this.options.columns);
+ }
+ },
+
+ applySortBehavior: function() {
+ var headerRow = this.headerTable.rows[0];
+ var headerCells = headerRow.cells;
+ for ( var i = 0 ; i < headerCells.length ; i++ ) {
+ this.addSortBehaviorToColumn( i, headerCells[i] );
+ }
+ },
+
+ addSortBehaviorToColumn: function( n, cell ) {
+ if ( this.options.columns[n].isSortable() ) {
+ cell.id = this.headerTableId + '_' + n;
+ cell.style.cursor = 'pointer';
+ cell.onclick = this.headerCellClicked.bindAsEventListener(this);
+ cell.innerHTML = cell.innerHTML + '<span id="' + this.headerTableId + '_img_' + n + '">'
+ + '&nbsp;&nbsp;&nbsp;</span>';
+ }
+ },
+
+ // event handler....
+ headerCellClicked: function(evt) {
+ var eventTarget = evt.target ? evt.target : evt.srcElement;
+ var cellId = eventTarget.id;
+ var columnNumber = parseInt(cellId.substring( cellId.lastIndexOf('_') + 1 ));
+ var sortedColumnIndex = this.getSortedColumnIndex();
+ if ( sortedColumnIndex != -1 ) {
+ if ( sortedColumnIndex != columnNumber ) {
+ this.removeColumnSort(sortedColumnIndex);
+ this.setColumnSort(columnNumber, Rico.TableColumn.SORT_ASC);
}
+ else
+ this.toggleColumnSort(sortedColumnIndex);
}
- catch(err) {
+ else
+ this.setColumnSort(columnNumber, Rico.TableColumn.SORT_ASC);
+
+ if (this.options.sortHandler) {
+ this.options.sortHandler(this.options.columns[columnNumber]);
}
},
- updateContent: function( offset ) {
- this.replaceCellContents(this.buffer, offset);
+ removeColumnSort: function(n) {
+ this.options.columns[n].setUnsorted();
+ this.setSortImage(n);
},
- replaceCellContents: function(buffer, startPos) {
- if (startPos == this.lastDisplayedStartPos){
- return;
+ setColumnSort: function(n, direction) {
+ this.options.columns[n].setSorted(direction);
+ this.setSortImage(n);
+ },
+
+ toggleColumnSort: function(n) {
+ this.options.columns[n].toggleSort();
+ this.setSortImage(n);
+ },
+
+ setSortImage: function(n) {
+ var sortDirection = this.options.columns[n].getSortDirection();
+
+ var sortImageSpan = $( this.headerTableId + '_img_' + n );
+ if ( sortDirection == Rico.TableColumn.UNSORTED )
+ sortImageSpan.innerHTML = '&nbsp;&nbsp;';
+ else if ( sortDirection == Rico.TableColumn.SORT_ASC )
+ sortImageSpan.innerHTML = '&nbsp;&nbsp;<img width="' + this.options.sortImageWidth + '" ' +
+ 'height="'+ this.options.sortImageHeight + '" ' +
+ 'src="' + this.options.sortAscendImg + '"/>';
+ else if ( sortDirection == Rico.TableColumn.SORT_DESC )
+ sortImageSpan.innerHTML = '&nbsp;&nbsp;<img width="' + this.options.sortImageWidth + '" ' +
+ 'height="'+ this.options.sortImageHeight + '" ' +
+ 'src="' + this.options.sortDescendImg + '"/>';
+ },
+
+ getSortedColumnIndex: function() {
+ var cols = this.options.columns;
+ for ( var i = 0 ; i < cols.length ; i++ ) {
+ if ( cols[i].isSorted() )
+ return i;
}
- this.lastDisplayedStartPos = startPos;
- var rows = buffer.getRows(startPos, this.metaData.getPageSize());
- for (var i=0; i < rows.length; i++) {
- var row = rows[i];
- for (var j=0; j < row.length; j++) {
- this.table.rows[i].cells[j].innerHTML = rows[i][j]
+ return -1;
+ },
+
+ introspectForColumnInfo: function() {
+ var columns = new Array();
+ var headerRow = this.headerTable.rows[0];
+ var headerCells = headerRow.cells;
+ for ( var i = 0 ; i < headerCells.length ; i++ )
+ columns.push( new Rico.TableColumn( this.deriveColumnNameFromCell(headerCells[i],i), true ) );
+ return columns;
+ },
+
+ convertToTableColumns: function(cols) {
+ var columns = new Array();
+ for ( var i = 0 ; i < cols.length ; i++ )
+ columns.push( new Rico.TableColumn( cols[i][0], cols[i][1] ) );
+ return columns;
+ },
+
+ deriveColumnNameFromCell: function(cell,columnNumber) {
+ var cellContent = cell.innerText != undefined ? cell.innerText : cell.textContent;
+ return cellContent ? cellContent.toLowerCase().split(' ').join('_') : "col_" + columnNumber;
+ }
+};
+
+Rico.TableColumn = Class.create();
+
+Rico.TableColumn.UNSORTED = 0;
+Rico.TableColumn.SORT_ASC = "ASC";
+Rico.TableColumn.SORT_DESC = "DESC";
+
+Rico.TableColumn.prototype = {
+ initialize: function(name, sortable) {
+ this.name = name;
+ this.sortable = sortable;
+ this.currentSort = Rico.TableColumn.UNSORTED;
+ },
+
+ isSortable: function() {
+ return this.sortable;
+ },
+
+ isSorted: function() {
+ return this.currentSort != Rico.TableColumn.UNSORTED;
+ },
+
+ getSortDirection: function() {
+ return this.currentSort;
+ },
+
+ toggleSort: function() {
+ if ( this.currentSort == Rico.TableColumn.UNSORTED || this.currentSort == Rico.TableColumn.SORT_DESC )
+ this.currentSort = Rico.TableColumn.SORT_ASC;
+ else if ( this.currentSort == Rico.TableColumn.SORT_ASC )
+ this.currentSort = Rico.TableColumn.SORT_DESC;
+ },
+
+ setUnsorted: function(direction) {
+ this.setSorted(Rico.TableColumn.UNSORTED);
+ },
+
+ setSorted: function(direction) {
+ // direction must by one of Rico.TableColumn.UNSORTED, .SORT_ASC, or .SORT_DESC...
+ this.currentSort = direction;
+ }
+
+};
+
+
+//-------------------- ricoUtil.js
+Rico.ArrayExtensions = new Array();
+
+if (Object.prototype.extend) {
+ // in prototype.js...
+ Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Object.prototype.extend;
+}else{
+ Object.prototype.extend = function(object) {
+ return Object.extend.apply(this, [this, object]);
+ }
+ Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Object.prototype.extend;
+}
+
+if (Array.prototype.push) {
+ // in prototype.js...
+ Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.push;
+}
+
+if (!Array.prototype.remove) {
+ Array.prototype.remove = function(dx) {
+ if( isNaN(dx) || dx > this.length )
+ return false;
+ for( var i=0,n=0; i<this.length; i++ )
+ if( i != dx )
+ this[n++]=this[i];
+ this.length-=1;
+ };
+ Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.remove;
+}
+
+if (!Array.prototype.removeItem) {
+ Array.prototype.removeItem = function(item) {
+ for ( var i = 0 ; i < this.length ; i++ )
+ if ( this[i] == item ) {
+ this.remove(i);
+ break;
+ }
+ };
+ Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.removeItem;
+}
+
+if (!Array.prototype.indices) {
+ Array.prototype.indices = function() {
+ var indexArray = new Array();
+ for ( index in this ) {
+ var ignoreThis = false;
+ for ( var i = 0 ; i < Rico.ArrayExtensions.length ; i++ ) {
+ if ( this[index] == Rico.ArrayExtensions[i] ) {
+ ignoreThis = true;
+ break;
+ }
}
+ if ( !ignoreThis )
+ indexArray[ indexArray.length ] = index;
}
+ return indexArray;
}
-};
-
-// ricoUtil.js --------------------
-
+ Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.indices;
+}
+
+ Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.unique;
+ Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.inArray;
+
+
+// Create the loadXML method and xml getter for Mozilla
+if ( window.DOMParser &&
+ window.XMLSerializer &&
+ window.Node && Node.prototype && Node.prototype.__defineGetter__ ) {
+
+ if (!Document.prototype.loadXML) {
+ Document.prototype.loadXML = function (s) {
+ var doc2 = (new DOMParser()).parseFromString(s, "text/xml");
+ while (this.hasChildNodes())
+ this.removeChild(this.lastChild);
+
+ for (var i = 0; i < doc2.childNodes.length; i++) {
+ this.appendChild(this.importNode(doc2.childNodes[i], true));
+ }
+ };
+ }
+
+ Document.prototype.__defineGetter__( "xml",
+ function () {
+ return (new XMLSerializer()).serializeToString(this);
+ }
+ );
+}
+
+document.getElementsByTagAndClassName = function(tagName, className) {
+ if ( tagName == null )
+ tagName = '*';
+
+ var children = document.getElementsByTagName(tagName) || document.all;
+ var elements = new Array();
+
+ if ( className == null )
+ return children;
+
+ for (var i = 0; i < children.length; i++) {
+ var child = children[i];
+ var classNames = child.className.split(' ');
+ for (var j = 0; j < classNames.length; j++) {
+ if (classNames[j] == className) {
+ elements.push(child);
+ break;
+ }
+ }
+ }
+
+ return elements;
+}
var RicoUtil = {
@@ -2177,6 +3179,41 @@ var RicoUtil = {
return null;
},
+ getContentAsString: function( parentNode ) {
+ return parentNode.xml != undefined ?
+ this._getContentAsStringIE(parentNode) :
+ this._getContentAsStringMozilla(parentNode);
+ },
+
+ _getContentAsStringIE: function(parentNode) {
+ var contentStr = "";
+ for ( var i = 0 ; i < parentNode.childNodes.length ; i++ ) {
+ var n = parentNode.childNodes[i];
+ if (n.nodeType == 4) {
+ contentStr += n.nodeValue;
+ }
+ else {
+ contentStr += n.xml;
+ }
+ }
+ return contentStr;
+ },
+
+ _getContentAsStringMozilla: function(parentNode) {
+ var xmlSerializer = new XMLSerializer();
+ var contentStr = "";
+ for ( var i = 0 ; i < parentNode.childNodes.length ; i++ ) {
+ var n = parentNode.childNodes[i];
+ if (n.nodeType == 4) { // CDATA node
+ contentStr += n.nodeValue;
+ }
+ else {
+ contentStr += xmlSerializer.serializeToString(n);
+ }
+ }
+ return contentStr;
+ },
+
toViewportPosition: function(element) {
return this._toAbsolute(element,true);
},
diff --git a/framework/Web/Javascripts/effects/slider.js b/framework/Web/Javascripts/effects/slider.js
index dc3ccab4..937f75b2 100644
--- a/framework/Web/Javascripts/effects/slider.js
+++ b/framework/Web/Javascripts/effects/slider.js
@@ -1,184 +1,251 @@
-// Copyright (c) 2005 Marty Haught
+// Copyright (c) 2005 Marty Haught, Thomas Fuchs
+//
+// See http://script.aculo.us for more info
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
//
-// See scriptaculous.js for full license.
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
if(!Control) var Control = {};
Control.Slider = Class.create();
// options:
// axis: 'vertical', or 'horizontal' (default)
-// increment: (default: 1)
-// step: (default: 1)
//
// callbacks:
// onChange(value)
// onSlide(value)
Control.Slider.prototype = {
initialize: function(handle, track, options) {
- this.handle = $(handle);
+ var slider = this;
+
+ if(handle instanceof Array) {
+ this.handles = handle.collect( function(e) { return $(e) });
+ } else {
+ this.handles = [$(handle)];
+ }
+
this.track = $(track);
-
this.options = options || {};
this.axis = this.options.axis || 'horizontal';
this.increment = this.options.increment || 1;
- this.step = parseInt(this.options.step) || 1;
- this.value = 0;
-
- var defaultMaximum = Math.round(this.track.offsetWidth / this.increment);
- if(this.isVertical()) defaultMaximum = Math.round(this.track.offsetHeight / this.increment);
+ this.step = parseInt(this.options.step || '1');
+ this.range = this.options.range || $R(0,1);
- this.maximum = this.options.maximum || defaultMaximum;
- this.minimum = this.options.minimum || 0;
-
- // Will be used to align the handle onto the track, if necessary
- this.alignX = parseInt (this.options.alignX) || 0;
- this.alignY = parseInt (this.options.alignY) || 0;
-
- // Zero out the slider position
- this.setCurrentLeft(Position.cumulativeOffset(this.track)[0] - Position.cumulativeOffset(this.handle)[0] + this.alignX);
- this.setCurrentTop(this.trackTop() - Position.cumulativeOffset(this.handle)[1] + this.alignY);
+ this.value = 0; // assure backwards compat
+ this.values = this.handles.map( function() { return 0 });
+ this.spans = this.options.spans ? this.options.spans.map(function(s){ return $(s) }) : false;
+ this.options.startSpan = $(this.options.startSpan || null);
+ this.options.endSpan = $(this.options.endSpan || null);
- this.offsetX = 0;
- this.offsetY = 0;
+ this.restricted = this.options.restricted || false;
- this.originalLeft = this.currentLeft();
- this.originalTop = this.currentTop();
- this.originalZ = parseInt(this.handle.style.zIndex || "0");
+ this.maximum = this.options.maximum || this.range.end;
+ this.minimum = this.options.minimum || this.range.start;
- // Prepopulate Slider value
- this.setSliderValue(parseInt(this.options.sliderValue) || 0);
+ // Will be used to align the handle onto the track, if necessary
+ this.alignX = parseInt(this.options.alignX || '0');
+ this.alignY = parseInt(this.options.alignY || '0');
+
+ this.trackLength = this.maximumOffset() - this.minimumOffset();
+ this.handleLength = this.isVertical() ? this.handles[0].offsetHeight : this.handles[0].offsetWidth;
this.active = false;
this.dragging = false;
this.disabled = false;
- // FIXME: use css
- this.handleImage = $(this.options.handleImage) || false;
- this.handleDisabled = this.options.handleDisabled || false;
- this.handleEnabled = false;
- if(this.handleImage)
- this.handleEnabled = this.handleImage.src || false;
-
- if(this.options.disabled)
- this.setDisabled();
-
- // Value Array
- this.values = this.options.values || false; // Add method to validate and sort??
+ if(this.options.disabled) this.setDisabled();
- Element.makePositioned(this.handle); // fix IE
+ // Allowed values array
+ this.allowedValues = this.options.values ? this.options.values.sortBy(Prototype.K) : false;
+ if(this.allowedValues) {
+ this.minimum = this.allowedValues.min();
+ this.maximum = this.allowedValues.max();
+ }
this.eventMouseDown = this.startDrag.bindAsEventListener(this);
this.eventMouseUp = this.endDrag.bindAsEventListener(this);
this.eventMouseMove = this.update.bindAsEventListener(this);
- this.eventKeypress = this.keyPress.bindAsEventListener(this);
- Event.observe(this.handle, "mousedown", this.eventMouseDown);
+ // Initialize handles in reverse (make sure first handle is active)
+ this.handles.each( function(h,i) {
+ i = slider.handles.length-1-i;
+ slider.setValue(parseFloat(
+ (slider.options.sliderValue instanceof Array ?
+ slider.options.sliderValue[i] : slider.options.sliderValue) ||
+ slider.range.start), i);
+ Element.makePositioned(h); // fix IE
+ Event.observe(h, "mousedown", slider.eventMouseDown);
+ });
+
+ Event.observe(this.track, "mousedown", this.eventMouseDown);
Event.observe(document, "mouseup", this.eventMouseUp);
Event.observe(document, "mousemove", this.eventMouseMove);
- Event.observe(document, "keypress", this.eventKeypress);
+
+ this.initialized = true;
},
dispose: function() {
- Event.stopObserving(this.handle, "mousedown", this.eventMouseDown);
+ var slider = this;
+ Event.stopObserving(this.track, "mousedown", this.eventMouseDown);
Event.stopObserving(document, "mouseup", this.eventMouseUp);
Event.stopObserving(document, "mousemove", this.eventMouseMove);
- Event.stopObserving(document, "keypress", this.eventKeypress);
+ this.handles.each( function(h) {
+ Event.stopObserving(h, "mousedown", slider.eventMouseDown);
+ });
},
setDisabled: function(){
this.disabled = true;
- if(this.handleDisabled)
- this.handleImage.src = this.handleDisabled;
},
setEnabled: function(){
this.disabled = false;
- if(this.handleEnabled)
- this.handleImage.src = this.handleEnabled;
},
- currentLeft: function() {
- return parseInt(this.handle.style.left || '0');
- },
- currentTop: function() {
- return parseInt(this.handle.style.top || '0');
- },
- setCurrentLeft: function(left) {
- this.handle.style.left = left +"px";
- },
- setCurrentTop: function(top) {
- this.handle.style.top = top +"px";
- },
- trackLeft: function(){
- return Position.cumulativeOffset(this.track)[0];
- },
- trackTop: function(){
- return Position.cumulativeOffset(this.track)[1];
- },
getNearestValue: function(value){
- if(this.values){
- var i = 0;
- var offset = Math.abs(this.values[0] - value);
- var newValue = this.values[0];
-
- for(i=0; i < this.values.length; i++){
- var currentOffset = Math.abs(this.values[i] - value);
- if(currentOffset < offset){
- newValue = this.values[i];
+ if(this.allowedValues){
+ if(value >= this.allowedValues.max()) return(this.allowedValues.max());
+ if(value <= this.allowedValues.min()) return(this.allowedValues.min());
+
+ var offset = Math.abs(this.allowedValues[0] - value);
+ var newValue = this.allowedValues[0];
+ this.allowedValues.each( function(v) {
+ var currentOffset = Math.abs(v - value);
+ if(currentOffset <= offset){
+ newValue = v;
offset = currentOffset;
- }
- }
+ }
+ });
return newValue;
}
+ if(value > this.range.end) return this.range.end;
+ if(value < this.range.start) return this.range.start;
return value;
},
- setSliderValue: function(sliderValue){
- // First check our max and minimum and nearest values
- sliderValue = this.getNearestValue(sliderValue);
- if(sliderValue > this.maximum) sliderValue = this.maximum;
- if(sliderValue < this.minimum) sliderValue = this.minimum;
- var offsetDiff = (sliderValue - (this.value||this.minimum)) * this.increment;
-
- if(this.isVertical()){
- this.setCurrentTop(offsetDiff + this.currentTop());
- } else {
- this.setCurrentLeft(offsetDiff + this.currentLeft());
+ setValue: function(sliderValue, handleIdx){
+ if(!this.active) {
+ this.activeHandle = this.handles[handleIdx];
+ this.activeHandleIdx = handleIdx;
+ this.updateStyles();
}
- this.value = sliderValue;
- this.updateFinished();
- },
+ handleIdx = handleIdx || this.activeHandleIdx || 0;
+ if(this.initialized && this.restricted) {
+ if((handleIdx>0) && (sliderValue<this.values[handleIdx-1]))
+ sliderValue = this.values[handleIdx-1];
+ if((handleIdx < (this.handles.length-1)) && (sliderValue>this.values[handleIdx+1]))
+ sliderValue = this.values[handleIdx+1];
+ }
+ sliderValue = this.getNearestValue(sliderValue);
+ this.values[handleIdx] = sliderValue;
+ this.value = this.values[0]; // assure backwards compat
+
+ this.handles[handleIdx].style[this.isVertical() ? 'top' : 'left'] =
+ this.translateToPx(sliderValue);
+
+ this.drawSpans();
+ if(!this.dragging || !this.event) this.updateFinished();
+ },
+ setValueBy: function(delta, handleIdx) {
+ this.setValue(this.values[handleIdx || this.activeHandleIdx || 0] + delta,
+ handleIdx || this.activeHandleIdx || 0);
+ },
+ translateToPx: function(value) {
+ return Math.round(
+ ((this.trackLength-this.handleLength)/(this.range.end-this.range.start)) *
+ (value - this.range.start)) + "px";
+ },
+ translateToValue: function(offset) {
+ return ((offset/(this.trackLength-this.handleLength) *
+ (this.range.end-this.range.start)) + this.range.start);
+ },
+ getRange: function(range) {
+ var v = this.values.sortBy(Prototype.K);
+ range = range || 0;
+ return $R(v[range],v[range+1]);
+ },
minimumOffset: function(){
- return(this.isVertical() ?
- this.trackTop() + this.alignY :
- this.trackLeft() + this.alignX);
+ return(this.isVertical() ? this.alignY : this.alignX);
},
maximumOffset: function(){
return(this.isVertical() ?
- this.trackTop() + this.alignY + (this.maximum - this.minimum) * this.increment :
- this.trackLeft() + this.alignX + (this.maximum - this.minimum) * this.increment);
+ this.track.offsetHeight - this.alignY : this.track.offsetWidth - this.alignX);
},
isVertical: function(){
return (this.axis == 'vertical');
},
+ drawSpans: function() {
+ var slider = this;
+ if(this.spans)
+ $R(0, this.spans.length-1).each(function(r) { slider.setSpan(slider.spans[r], slider.getRange(r)) });
+ if(this.options.startSpan)
+ this.setSpan(this.options.startSpan,
+ $R(0, this.values.length>1 ? this.getRange(0).min() : this.value ));
+ if(this.options.endSpan)
+ this.setSpan(this.options.endSpan,
+ $R(this.values.length>1 ? this.getRange(this.spans.length-1).max() : this.value, this.maximum));
+ },
+ setSpan: function(span, range) {
+ if(this.isVertical()) {
+ span.style.top = this.translateToPx(range.start);
+ span.style.height = this.translateToPx(range.end - range.start);
+ } else {
+ span.style.left = this.translateToPx(range.start);
+ span.style.width = this.translateToPx(range.end - range.start);
+ }
+ },
+ updateStyles: function() {
+ this.handles.each( function(h){ Element.removeClassName(h, 'selected') });
+ Element.addClassName(this.activeHandle, 'selected');
+ },
startDrag: function(event) {
if(Event.isLeftClick(event)) {
if(!this.disabled){
this.active = true;
- var pointer = [Event.pointerX(event), Event.pointerY(event)];
- var offsets = Position.cumulativeOffset(this.handle);
- this.offsetX = (pointer[0] - offsets[0]);
- this.offsetY = (pointer[1] - offsets[1]);
- this.originalLeft = this.currentLeft();
- this.originalTop = this.currentTop();
+
+ var handle = Event.element(event);
+ var pointer = [Event.pointerX(event), Event.pointerY(event)];
+ if(handle==this.track) {
+ var offsets = Position.cumulativeOffset(this.track);
+ this.event = event;
+ this.setValue(this.translateToValue(
+ (this.isVertical() ? pointer[1]-offsets[1] : pointer[0]-offsets[0])-(this.handleLength/2)
+ ));
+ var offsets = Position.cumulativeOffset(this.activeHandle);
+ this.offsetX = (pointer[0] - offsets[0]);
+ this.offsetY = (pointer[1] - offsets[1]);
+ } else {
+ // find the handle (prevents issues with Safari)
+ while((this.handles.indexOf(handle) == -1) && handle.parentNode)
+ handle = handle.parentNode;
+
+ this.activeHandle = handle;
+ this.activeHandleIdx = this.handles.indexOf(this.activeHandle);
+ this.updateStyles();
+
+ var offsets = Position.cumulativeOffset(this.activeHandle);
+ this.offsetX = (pointer[0] - offsets[0]);
+ this.offsetY = (pointer[1] - offsets[1]);
+ }
}
Event.stop(event);
}
},
update: function(event) {
if(this.active) {
- if(!this.dragging) {
- var style = this.handle.style;
- this.dragging = true;
- if(style.position=="") style.position = "relative";
- style.zIndex = this.options.zindex;
- }
+ if(!this.dragging) this.dragging = true;
this.draw(event);
// fix AppleWebKit rendering
if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
@@ -187,43 +254,13 @@ Control.Slider.prototype = {
},
draw: function(event) {
var pointer = [Event.pointerX(event), Event.pointerY(event)];
- var offsets = Position.cumulativeOffset(this.handle);
-
- offsets[0] -= this.currentLeft();
- offsets[1] -= this.currentTop();
-
- // Adjust for the pointer's position on the handle
- pointer[0] -= this.offsetX;
- pointer[1] -= this.offsetY;
- var style = this.handle.style;
-
- if(this.isVertical()){
- if(pointer[1] > this.maximumOffset())
- pointer[1] = this.maximumOffset();
- if(pointer[1] < this.minimumOffset())
- pointer[1] = this.minimumOffset();
-
- // Increment by values
- if(this.values){
- this.value = this.getNearestValue(Math.round((pointer[1] - this.minimumOffset()) / this.increment) + this.minimum);
- pointer[1] = this.trackTop() + this.alignY + (this.value - this.minimum) * this.increment;
- } else {
- this.value = Math.round((pointer[1] - this.minimumOffset()) / this.increment) + this.minimum;
- }
- style.top = pointer[1] - offsets[1] + "px";
- } else {
- if(pointer[0] > this.maximumOffset()) pointer[0] = this.maximumOffset();
- if(pointer[0] < this.minimumOffset()) pointer[0] = this.minimumOffset();
- // Increment by values
- if(this.values){
- this.value = this.getNearestValue(Math.round((pointer[0] - this.minimumOffset()) / this.increment) + this.minimum);
- pointer[0] = this.trackLeft() + this.alignX + (this.value - this.minimum) * this.increment;
- } else {
- this.value = Math.round((pointer[0] - this.minimumOffset()) / this.increment) + this.minimum;
- }
- style.left = (pointer[0] - offsets[0]) + "px";
- }
- if(this.options.onSlide) this.options.onSlide(this.value);
+ var offsets = Position.cumulativeOffset(this.track);
+ pointer[0] -= this.offsetX + offsets[0];
+ pointer[1] -= this.offsetY + offsets[1];
+ this.event = event;
+ this.setValue(this.translateToValue( this.isVertical() ? pointer[1] : pointer[0] ));
+ if(this.initialized && this.options.onSlide)
+ this.options.onSlide(this.values.length>1 ? this.values : this.value, this);
},
endDrag: function(event) {
if(this.active && this.dragging) {
@@ -236,23 +273,11 @@ Control.Slider.prototype = {
finishDrag: function(event, success) {
this.active = false;
this.dragging = false;
- this.handle.style.zIndex = this.originalZ;
- this.originalLeft = this.currentLeft();
- this.originalTop = this.currentTop();
this.updateFinished();
},
updateFinished: function() {
- if(this.options.onChange) this.options.onChange(this.value);
- },
- keyPress: function(event) {
- if(this.active && !this.disabled) {
- switch(event.keyCode) {
- case Event.KEY_ESC:
- this.finishDrag(event, false);
- Event.stop(event);
- break;
- }
- if(navigator.appVersion.indexOf('AppleWebKit')>0) Event.stop(event);
- }
+ if(this.initialized && this.options.onChange)
+ this.options.onChange(this.values.length>1 ? this.values : this.value, this);
+ this.event = null;
}
-}
+} \ No newline at end of file
diff --git a/framework/Web/Javascripts/extended/dom.js b/framework/Web/Javascripts/extended/dom.js
index 4c664de7..de5ae056 100644
--- a/framework/Web/Javascripts/extended/dom.js
+++ b/framework/Web/Javascripts/extended/dom.js
@@ -3,4 +3,226 @@ Object.extend(Element, {
{
(cond?Element.addClassName:Element.removeClassName)(element,className);
}
+});
+
+Prado.Element =
+{
+ /**
+ * Set the value of a particular element.
+ * @param string element id
+ * @param string new element value.
+ */
+ setValue : function(element, value)
+ {
+ var el = $(element);
+ if(el && typeof(el.value) != "undefined")
+ el.value = value;
+ },
+
+ select : function(element, method, value)
+ {
+ var el = $(element);
+ var isList = element.indexOf('[]') > -1;
+ if(!el && !isList) return;
+ method = isList ? 'check'+method : el.tagName.toLowerCase()+method;
+ var selection = Prado.Element.Selection;
+ if(isFunction(selection[method]))
+ selection[method](isList ? element : el,value);
+ },
+
+ click : function(element)
+ {
+ var el = $(element);
+ //Logger.info(el);
+ if(!el) return;
+ if(document.createEvent)
+ {
+ var evt = document.createEvent('HTMLEvents');
+ evt.initEvent('click', true, true);
+ el.dispatchEvent(evt);
+ //Logger.warn("dispatching click for "+el.id);
+ }
+ else if(el.fireEvent)
+ {
+ el.fireEvent('onclick');
+ if(isFunction(el.onclick))
+ el.onclick();
+ }
+ },
+
+ setAttribute : function(element, attribute, value)
+ {
+ var el = $(element);
+ if(attribute == "disabled" && value==false)
+ el.removeAttribute(attribute);
+ else
+ el.setAttribute(attribute, value);
+ },
+
+ setOptions : function(element, options)
+ {
+ var el = $(element);
+ if(el && el.tagName.toLowerCase() == "select")
+ {
+ while(el.length > 0)
+ el.remove(0);
+ for(var i = 0; i<options.length; i++)
+ el.options[el.options.length] = new Option(options[i][0],options[i][1]);
+ }
+ }
+}
+
+Prado.Element.Selection =
+{
+ inputValue : function(el, value)
+ {
+ switch(el.type.toLowerCase())
+ {
+ case 'checkbox':
+ case 'radio':
+ return el.checked = value;
+ }
+ },
+
+ selectValue : function(el, value)
+ {
+ $A(el.options).each(function(option)
+ {
+ option.selected = option.value == value;
+ });
+ },
+
+ selectIndex : function(el, index)
+ {
+ if(el.type == 'select-one')
+ el.selectedIndex = index;
+ else
+ {
+ for(var i = 0; i<el.length; i++)
+ {
+ if(i == index)
+ el.options[i].selected = true;
+ }
+ }
+ },
+
+ selectClear : function(el)
+ {
+ el.selectedIndex = -1;
+ },
+
+ selectAll : function(el)
+ {
+ $A(el.options).each(function(option)
+ {
+ option.selected = true;
+ Logger.warn(option.value);
+ });
+ },
+
+ selectInvert : function(el)
+ {
+ $A(el.options).each(function(option)
+ {
+ option.selected = !option.selected;
+ });
+ },
+
+ checkValue : function(name, value)
+ {
+ $A(document.getElementsByName(name)).each(function(el)
+ {
+ el.checked = el.value == value
+ });
+ },
+
+ checkIndex : function(name, index)
+ {
+ var elements = $A(document.getElementsByName(name));
+ for(var i = 0; i<elements.length; i++)
+ {
+ if(i == index)
+ elements[i].checked = true;
+ }
+ },
+
+ checkClear : function(name)
+ {
+ $A(document.getElementsByName(name)).each(function(el)
+ {
+ el.checked = false;
+ });
+ },
+
+ checkAll : function(name)
+ {
+ $A(document.getElementsByName(name)).each(function(el)
+ {
+ el.checked = true;
+ });
+ },
+ checkInvert : function(name)
+ {
+ $A(document.getElementsByName(name)).each(function(el)
+ {
+ el.checked = !el.checked;
+ });
+ }
+};
+
+
+/**
+ * Alias some of the prototype functions.
+ * Insert a html fragment relative to an element.
+ */
+Object.extend(Prado.Element,
+{
+ /**
+ *
+ */
+ Insert :
+ {
+ /**
+ * Insert directly after the element.
+ */
+ After : function(element, innerHTML)
+ {
+ new Insertion.After(element, innerHTML);
+ },
+
+ /**
+ * Insert directly after the element
+ */
+ Before : function(element, innerHTML)
+ {
+ new Insertion.Before(element. innerHTML);
+ },
+
+ /**
+ * Insert below the element container.
+ */
+ Below : function(element, innerHTML)
+ {
+ new Insertion.Bottom(element, innerHTML);
+ },
+
+ /**
+ * Insert above the element container.
+ */
+ Above : function(element, innerHTML)
+ {
+ new Insertion.Top(element, innerHTML);
+ }
+ },
+ CssClass :
+ {
+ /**
+ * Set the css class name of an element.
+ */
+ set : function(element, cssClass)
+ {
+ element = new Element.ClassNames(element);
+ element.set(cssClass);
+ }
+ }
}); \ No newline at end of file
diff --git a/framework/Web/Javascripts/extended/event.js b/framework/Web/Javascripts/extended/event.js
index 30123efc..a7f58fae 100644
--- a/framework/Web/Javascripts/extended/event.js
+++ b/framework/Web/Javascripts/extended/event.js
@@ -5,7 +5,6 @@ Object.extend(Event, {
Event.__observe(w,'load',fn);
},
observe: function(elements, name, observer, useCapture) {
-
if(!isList(elements))
return this.__observe(elements, name, observer, useCapture);
for(var i=0; i<elements.length; i++)
@@ -19,6 +18,7 @@ Object.extend(Event, {
((navigator.appVersion.indexOf('AppleWebKit') > 0)
|| element.attachEvent))
name = 'keydown';
+
this._observeAndCache(element, name, observer, useCapture);
}
}); \ No newline at end of file
diff --git a/framework/Web/Javascripts/extended/string.js b/framework/Web/Javascripts/extended/string.js
index f79072fb..fe586cfb 100644
--- a/framework/Web/Javascripts/extended/string.js
+++ b/framework/Web/Javascripts/extended/string.js
@@ -32,6 +32,31 @@ Object.extend(String.prototype, {
trimRight : function() {
return this.replace(/\s+$/,'');
+ },
+
+ /**
+ * Convert period separated function names into a function reference.
+ * e.g. "Prado.AJAX.Callback.Action.setValue".toFunction() will return
+ * the actual function Prado.AJAX.Callback.Action.setValue()
+ * @return Function the corresponding function represented by the string.
+ */
+ toFunction : function()
+ {
+ var commands = this.split(/\./);
+ var command = window;
+ commands.each(function(action)
+ {
+ if(command[new String(action)])
+ command=command[new String(action)];
+ });
+ if(isFunction(command))
+ return command;
+ else
+ {
+ if(typeof Logger != "undefined")
+ Logger.error("Missing function", this);
+ return Prototype.emptyFunction;
+ }
}
});
diff --git a/framework/Web/Javascripts/extra/behaviour.js b/framework/Web/Javascripts/extra/behaviour.js
index 0004c5db..ac9adeda 100644
--- a/framework/Web/Javascripts/extra/behaviour.js
+++ b/framework/Web/Javascripts/extra/behaviour.js
@@ -45,9 +45,7 @@ var Behaviour = {
},
start : function(){
- Behaviour.addLoadEvent(function(){
- Behaviour.apply();
- });
+ Event.OnLoad(Behaviour.apply);
},
apply : function(){
@@ -64,19 +62,6 @@ var Behaviour = {
}
}
}
- },
-
- addLoadEvent : function(func){
- var oldonload = window.onload;
-
- if (typeof window.onload != 'function') {
- window.onload = func;
- } else {
- window.onload = function() {
- oldonload();
- func();
- }
- }
}
}
diff --git a/framework/Web/Javascripts/extra/logger.js b/framework/Web/Javascripts/extra/logger.js
index 438772e9..f6383480 100644
--- a/framework/Web/Javascripts/extra/logger.js
+++ b/framework/Web/Javascripts/extra/logger.js
@@ -427,51 +427,109 @@ LogConsole.prototype = {
else {
this.commandIndex = 0
}
- }
+ }
}
// Load the Console when the window loads
-Event.observe(window, "load", function() {logConsole = new LogConsole()})
+var logConsole;
+Event.OnLoad(function() { logConsole = new LogConsole()});
+
+
+
// -------------------------
// Helper Functions And Junk
// -------------------------
-function inspect(element, hideProperties, showMethods) {
- var properties = []
- var methods = []
-
+function inspect(o)
+{
+ var objtype = typeof(o);
+ if (objtype == "undefined") {
+ return "undefined";
+ } else if (objtype == "number" || objtype == "boolean") {
+ return o + "";
+ } else if (o === null) {
+ return "null";
+ }
- for(var internal in element) {
- if(internal == '______array') continue;
- try {
- if (element[internal] instanceof Function) {
- if (showMethods)
- methods.push(internal + ":\t" + element[internal] )
- }
- else if(element[internal] instanceof Object)
- {
- methods.push(internal + ":\t" + inspect(element[internal], hideProperties, showMethods));
- }
- else {
- if (!hideProperties)
- properties.push(internal + ":\t" + element[internal] )
- }
+ try {
+ var ostring = (o + "");
+ } catch (e) {
+ return "[" + typeof(o) + "]";
+ }
+
+ if (typeof(o) == "function")
+ {
+ o = ostring.replace(/^\s+/, "");
+ var idx = o.indexOf("{");
+ if (idx != -1) {
+ o = o.substr(0, idx) + "{...}";
+ }
+ return o;
+ }
+
+ var reprString = function (o)
+ {
+ return ('"' + o.replace(/(["\\])/g, '\\$1') + '"'
+ ).replace(/[\f]/g, "\\f"
+ ).replace(/[\b]/g, "\\b"
+ ).replace(/[\n]/g, "\\n"
+ ).replace(/[\t]/g, "\\t"
+ ).replace(/[\r]/g, "\\r");
+ };
+
+ if (objtype == "string") {
+ return reprString(o);
+ }
+ // recurse
+ var me = arguments.callee;
+ // short-circuit for objects that support "json" serialization
+ // if they return "self" then just pass-through...
+ var newObj;
+ if (typeof(o.__json__) == "function") {
+ newObj = o.__json__();
+ if (o !== newObj) {
+ return me(newObj);
}
- catch (e) {
- Logger.error("Excetion thrown while inspecting object.", e)
+ }
+ if (typeof(o.json) == "function") {
+ newObj = o.json();
+ if (o !== newObj) {
+ return me(newObj);
}
}
-
- properties.sort()
- methods.sort()
-
- var internals = properties.concat(methods)
- var output = ""
- for (var i = 0; i < internals.length; i++) {
- output += (internals[i] + "\n")
+ // array
+ if (objtype != "function" && typeof(o.length) == "number") {
+ var res = [];
+ for (var i = 0; i < o.length; i++) {
+ var val = me(o[i]);
+ if (typeof(val) != "string") {
+ val = "undefined";
+ }
+ res.push(val);
+ }
+ return "[" + res.join(", ") + "]";
}
-
- return output
+
+ // generic object code path
+ res = [];
+ for (var k in o) {
+ var useKey;
+ if (typeof(k) == "number") {
+ useKey = '"' + k + '"';
+ } else if (typeof(k) == "string") {
+ useKey = reprString(k);
+ } else {
+ // skip non-string or number keys
+ continue;
+ }
+ val = me(o[k]);
+ if (typeof(val) != "string") {
+ // skip non-serializable values
+ continue;
+ }
+ res.push(useKey + ":" + val);
+ }
+ return "{" + res.join(", ") + "}";
}
Array.prototype.contains = function(object) {
@@ -511,8 +569,10 @@ Prado.Inspector =
hidden : new Array(),
opera : window.opera,
displaying : '',
+ nameList : new Array(),
format : function(str) {
+ if(typeof(str) != "string") return str;
str=str.replace(/</g,"&lt;");
str=str.replace(/>/g,"&gt;");
return str;
@@ -525,20 +585,22 @@ Prado.Inspector =
this.displaying = name ? name : win.toString();
for(js in win) {
try {
- if(win[js] && js.toString().indexOf("Inspector")==-1 && win[js].toString().indexOf("[native code]")==-1) {
+ if(win[js] && js.toString().indexOf("Inspector")==-1 && (win[js]+"").indexOf("[native code]")==-1) {
+
t=typeof(win[js]);
if(!this.objs[t.toString()]) {
- this.types[this.types.length]=t;;
- this.objs[t]=new Array();
+ this.types[this.types.length]=t;
+ this.objs[t]={};
+ this.nameList[t] = new Array();
}
- index=this.objs[t].length
- this.objs[t][index]=new Array();
- this.objs[t][index][0]=js;
- this.objs[t][index][1]=this.format(win[js].toString());
+ this.nameList[t].push(js);
+ this.objs[t][js] = this.format(win[js]+"");
}
} catch(err) { }
}
-
+
+ for(i=0;i<this.types.length;i++)
+ this.nameList[this.types[i]].sort();
},
show : function(objID) {
@@ -574,19 +636,23 @@ Prado.Inspector =
mHTML +="<ul class=\"topLevel\">";
this.types.sort();
var so_objIndex=0;
- for(i=0;i<this.types.length;i++) {
- mHTML+="<li style=\"cursor:pointer;\" onclick=\"Prado.Inspector.show('ul"+i+"');Prado.Inspector.changeSpan('sp" + i + "')\"><span id=\"sp" + i + "\">[+]</span><b>" + this.types[i] + "</b> (" + this.objs[this.types[i]].length + ")</li><ul style=\"display:none;\" id=\"ul"+i+"\">";
+ for(i=0;i<this.types.length;i++)
+ {
+ mHTML+="<li style=\"cursor:pointer;\" onclick=\"Prado.Inspector.show('ul"+i+"');Prado.Inspector.changeSpan('sp" + i + "')\"><span id=\"sp" + i + "\">[+]</span><b>" + this.types[i] + "</b> (" + this.nameList[this.types[i]].length + ")</li><ul style=\"display:none;\" id=\"ul"+i+"\">";
this.hidden["ul"+i]=0;
- for(e=0;e<this.objs[this.types[i]].length;e++) {
+ for(e=0;e<this.nameList[this.types[i]].length;e++)
+ {
+ var prop = this.nameList[this.types[i]][e];
+ var value = this.objs[this.types[i]][prop]
var more = "";
- if(this.objs[this.types[i]][e][1].indexOf("[object ") >= 0 && /^[a-zA-Z_]/.test(this.objs[this.types[i]][e][0][0]))
+ if(value.indexOf("[object ") >= 0 && /^[a-zA-Z_]/.test(prop))
{
if(this.displaying.indexOf("[object ") < 0)
- more = " <a href=\"javascript:var_dump('"+this.displaying+"."+this.objs[this.types[i]][e][0]+"')\"><b>more</b></a>";
+ more = " <a href=\"javascript:var_dump('"+this.displaying+"."+prop+"')\"><b>more</b></a>";
else if(this.displaying.indexOf("[object Window]") >= 0)
- more = " <a href=\"javascript:var_dump('"+this.objs[this.types[i]][e][0]+"')\"><b>more</b></a>";
+ more = " <a href=\"javascript:var_dump('"+prop+"')\"><b>more</b></a>";
}
- mHTML+="<li style=\"cursor:pointer;\" onclick=\"Prado.Inspector.show('mul" + so_objIndex + "');Prado.Inspector.changeSpan('sk" + so_objIndex + "')\"><span id=\"sk" + so_objIndex + "\">[+]</span>" + this.objs[this.types[i]][e][0] + "</li><ul id=\"mul" + so_objIndex + "\" style=\"display:none;\"><li style=\"list-style-type:none;\"><pre>" + this.objs[this.types[i]][e][1] + more + "</pre></li></ul>";
+ mHTML+="<li style=\"cursor:pointer;\" onclick=\"Prado.Inspector.show('mul" + so_objIndex + "');Prado.Inspector.changeSpan('sk" + so_objIndex + "')\"><span id=\"sk" + so_objIndex + "\">[+]</span>" + prop + "</li><ul id=\"mul" + so_objIndex + "\" style=\"display:none;\"><li style=\"list-style-type:none;\"><pre>" + value + more + "</pre></li></ul>";
this.hidden["mul"+so_objIndex]=0;
so_objIndex++;
}
@@ -653,7 +719,11 @@ Prado.Inspector =
"#so_mContainer .credits a { font:9px verdana; font-weight:bold; color:#004465; text-decoration:none; background-color:transparent; }"
}
+//similar function to var_dump in PHP, brings up the javascript object tree UI.
function var_dump(obj)
{
Prado.Inspector.inspect(obj);
-} \ No newline at end of file
+}
+
+//similar function to print_r for PHP
+var print_r = inspect; \ No newline at end of file
diff --git a/framework/Web/Javascripts/js/validator.js b/framework/Web/Javascripts/js/validator.js
index 5b25118f..7e81feea 100644
--- a/framework/Web/Javascripts/js/validator.js
+++ b/framework/Web/Javascripts/js/validator.js
@@ -330,6 +330,7 @@ _63[i].show(_62);
}
};
Prado.Validation.OnSubmit=function(ev){
+Logger.info("submit");
if(typeof tinyMCE!="undefined"){
tinyMCE.triggerSave();
}
diff --git a/framework/Web/Javascripts/prototype/AUTHORS b/framework/Web/Javascripts/prototype/AUTHORS
new file mode 100644
index 00000000..5fea268f
--- /dev/null
+++ b/framework/Web/Javascripts/prototype/AUTHORS
@@ -0,0 +1,12 @@
+Creator and maintainer
+
+* Sam Stephenson -- http://conio.net/
+
+Contributors
+
+* Thomas Fuchs -- http://mir.aculo.us/
+* David Heinemeier Hansson -- http://www.loudthinking.com/
+* Matthew McCray -- http://www.mattmccray.com/
+* Michael Schuerig -- http://www.schuerig.de/michael/
+* Sean Treadway -- http://sean.treadway.info/
+* flash@vanklinkenbergsoftware.nl
diff --git a/framework/Web/Javascripts/prototype/LICENSE b/framework/Web/Javascripts/prototype/LICENSE
new file mode 100644
index 00000000..6c4c6312
--- /dev/null
+++ b/framework/Web/Javascripts/prototype/LICENSE
@@ -0,0 +1,16 @@
+Copyright (c) 2005 Sam Stephenson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/framework/Web/Javascripts/prototype/README b/framework/Web/Javascripts/prototype/README
new file mode 100644
index 00000000..74761a82
--- /dev/null
+++ b/framework/Web/Javascripts/prototype/README
@@ -0,0 +1,64 @@
+= Prototype
+==== An object-oriented JavaScript framework
+
+(c) 2005 Sam Stephenson (mailto:sam@conio.net)
+
+Prototype is a JavaScript framework that aims to ease development of dynamic
+web applications. Its development is driven heavily by the Ruby on Rails
+framework, but it can be used in any environment.
+
+=== Targeted platforms
+
+Prototype currently targets the following platforms:
+
+* Microsoft Internet Explorer for Windows, version 6.0 and higher
+* Mozilla Firefox 1.0/Mozilla 1.7 and higher
+* Apple Safari 1.2 and higher
+
+== Using Prototype
+
+To use Prototype in your application, download the latest release from the
+Prototype web site (http://prototype.conio.net/) and copy
+<tt>dist/prototype.js</tt> to a suitable location. Then include it in your HTML
+like so:
+
+ <script type="text/javascript" src="/path/to/prototype.js"></script>
+
+=== Building Prototype from source
+
+<tt>prototype.js</tt> is a composite file generated from many source files in
+the <tt>src/</tt> directory. To build Prototype, you'll need:
+
+* a copy of the Prototype source tree, either from a distribution tarball or
+ from the darcs repository (see below)
+* Ruby 1.8.2 or higher (http://www.ruby-lang.org/)
+* Rake -- Ruby Make (http://rake.rubyforge.org/)
+* RDoc, if your Ruby distribution does not include it
+* darcs 1.0.1 or higher (http://abridgegame.org/darcs/; static binaries
+ available at http://www.scannedinavian.org/DarcsWiki/CategoryBinaries)
+
+From the root Prototype directory,
+
+* <tt>rake dist</tt> will preprocess the Prototype source using ERB and
+ generate the composite <tt>dist/prototype.js</tt>.
+* <tt>rake package</tt> will create a distribution tarball in the
+ <tt>pkg/</tt> directory.
+
+== Contributing to Prototype
+
+You'll need the tools mentioned above. Modify the files in <tt>src/</tt>, add
+tests in <tt>test/</tt> if possible, generate a new dist file, and record the
+changes with <tt>darcs record -al</tt>. Then email patches to
+mailto:sam@conio.net using <tt>darcs send</tt>.
+
+== Documentation
+
+Prototype is embarrassingly lacking in documentation. (The source code should
+be fairly easy to comprehend; I'm committed to using a clean style with
+meaningful identifiers. But I know that only goes so far.)
+
+Much of the problem is that there is no easy way to document it from within the
+source code itself. I've tried JSDoc[http://jsdoc.sf.net/] and a Perl script
+included with JsUnit[http://www.edwardh.com/jsunit/]; neither groks Prototype's
+hash-style class definitions or inheritance scheme. Making them work would
+require major changes, and I don't have the time for that right now.
diff --git a/framework/Web/Javascripts/prototype/THANKS b/framework/Web/Javascripts/prototype/THANKS
new file mode 100644
index 00000000..d36adacb
--- /dev/null
+++ b/framework/Web/Javascripts/prototype/THANKS
@@ -0,0 +1,21 @@
+Special thanks are in order for Mikael and Daniel Brockman, whose patterns
+heavily influenced the design and implementation of this library.
+* Daniel Brockman -- http://www.deepwood.net/
+* Mikael Brockman -- http://www.phubuh.org/
+---
+* Scott Barron -- http://scott.elitists.net/
+* Hemant Bhanoo
+* Jamis Buck -- http://jamis.jamisbuck.org/
+* Lucas Carlson -- http://www.rufy.com/
+* Jon Casey
+* Patrick Corcoran
+* Alper Cugun
+* Darren James -- http://www.openrico.org/
+* Marcel Molina Jr. -- http://vernix.org/marcel/
+* Alex Russell
+* Chriztian Steinmeier
+* Dan Webb
+* Gary Wright
+
+and anyone else who has sent patches or bug reports. If your name isn't on this
+list, please forgive my oversight and send me an email (sam at conio.net). \ No newline at end of file
diff --git a/framework/Web/Javascripts/prototype/ajax.js b/framework/Web/Javascripts/prototype/ajax.js
index 1fe0dab9..6abef835 100644
--- a/framework/Web/Javascripts/prototype/ajax.js
+++ b/framework/Web/Javascripts/prototype/ajax.js
@@ -31,8 +31,7 @@ Ajax.Responders = {
if (responder[callback] && typeof responder[callback] == 'function') {
try {
responder[callback].apply(responder, [request, transport, json]);
- } catch (e) {
- }
+ } catch (e) {}
}
});
}
@@ -108,8 +107,7 @@ Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
this.transport.send(this.options.method == 'post' ? body : null);
} catch (e) {
- (this.options.onException || Prototype.emptyFunction)(this, e);
- Ajax.Responders.dispatch('onException', this, e);
+ this.dispatchException(e);
}
},
@@ -143,12 +141,23 @@ Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
this.respondToReadyState(this.transport.readyState);
},
+ header: function(name) {
+ try {
+ return this.transport.getResponseHeader(name);
+ } catch (e) {}
+ },
+
evalJSON: function() {
try {
- var json = this.transport.getResponseHeader('X-JSON'), object;
- object = eval(json);
- return object;
+ return eval(this.header('X-JSON'));
+ } catch (e) {}
+ },
+
+ evalResponse: function() {
+ try {
+ return eval(this.transport.responseText);
} catch (e) {
+ this.dispatchException(e);
}
},
@@ -156,22 +165,38 @@ Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
var event = Ajax.Request.Events[readyState];
var transport = this.transport, json = this.evalJSON();
- if (event == 'Complete')
- (this.options['on' + this.transport.status]
- || this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')]
- || Prototype.emptyFunction)(transport, json);
-
- (this.options['on' + event] || Prototype.emptyFunction)(transport, json);
- Ajax.Responders.dispatch('on' + event, this, transport, json);
-
+ if (event == 'Complete') {
+ try {
+ (this.options['on' + this.transport.status]
+ || this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')]
+ || Prototype.emptyFunction)(transport, json);
+ } catch (e) {
+ this.dispatchException(e);
+ }
+
+ if ((this.header('Content-type') || '').match(/^text\/javascript/i))
+ this.evalResponse();
+ }
+
+ try {
+ (this.options['on' + event] || Prototype.emptyFunction)(transport, json);
+ Ajax.Responders.dispatch('on' + event, this, transport, json);
+ } catch (e) {
+ this.dispatchException(e);
+ }
+
/* Avoid memory leak in MSIE: clean up the oncomplete event handler */
if (event == 'Complete')
this.transport.onreadystatechange = Prototype.emptyFunction;
+ },
+
+ dispatchException: function(exception) {
+ (this.options.onException || Prototype.emptyFunction)(this, exception);
+ Ajax.Responders.dispatch('onException', this, exception);
}
});
Ajax.Updater = Class.create();
-Ajax.Updater.ScriptFragment = '(?:<script.*?>)((\n|.)*?)(?:<\/script>)';
Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {
initialize: function(container, url, options) {
@@ -196,16 +221,16 @@ Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {
updateContent: function() {
var receiver = this.responseIsSuccess() ?
this.containers.success : this.containers.failure;
-
- var match = new RegExp(Ajax.Updater.ScriptFragment, 'img');
- var response = this.transport.responseText.replace(match, '');
- var scripts = this.transport.responseText.match(match);
+ var response = this.transport.responseText;
+
+ if (!this.options.evalScripts)
+ response = response.stripScripts();
if (receiver) {
if (this.options.insertion) {
new this.options.insertion(receiver, response);
} else {
- receiver.innerHTML = response;
+ Element.update(receiver, response);
}
}
@@ -213,14 +238,6 @@ Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {
if (this.onComplete)
setTimeout(this.onComplete.bind(this), 10);
}
-
- if (this.options.evalScripts && scripts) {
- match = new RegExp(Ajax.Updater.ScriptFragment, 'im');
- setTimeout((function() {
- for (var i = 0; i < scripts.length; i++)
- eval(scripts[i].match(match)[1]);
- }).bind(this), 10);
- }
}
});
diff --git a/framework/Web/Javascripts/prototype/array.js b/framework/Web/Javascripts/prototype/array.js
index 397afbbf..f5694c05 100644
--- a/framework/Web/Javascripts/prototype/array.js
+++ b/framework/Web/Javascripts/prototype/array.js
@@ -1,4 +1,5 @@
var $A = Array.from = function(iterable) {
+ if (!iterable) return [];
if (iterable.toArray) {
return iterable.toArray();
} else {
@@ -11,12 +12,19 @@ var $A = Array.from = function(iterable) {
Object.extend(Array.prototype, Enumerable);
+Array.prototype._reverse = Array.prototype.reverse;
+
Object.extend(Array.prototype, {
_each: function(iterator) {
for (var i = 0; i < this.length; i++)
iterator(this[i]);
},
+ clear: function() {
+ this.length = 0;
+ return this;
+ },
+
first: function() {
return this[0];
},
@@ -48,16 +56,21 @@ Object.extend(Array.prototype, {
indexOf: function(object) {
for (var i = 0; i < this.length; i++)
if (this[i] == object) return i;
- return false;
+ return -1;
},
- reverse: function() {
- var result = [];
- for (var i = this.length; i > 0; i--)
- result.push(this[i-1]);
- return result;
+ reverse: function(inline) {
+ return (inline !== false ? this : this.toArray())._reverse();
},
+ shift: function() {
+ var result = this[0];
+ for (var i = 0; i < this.length - 1; i++)
+ this[i] = this[i + 1];
+ this.length--;
+ return result;
+ },
+
inspect: function() {
return '[' + this.map(Object.inspect).join(', ') + ']';
}
diff --git a/framework/Web/Javascripts/prototype/base.js b/framework/Web/Javascripts/prototype/base.js
index 70f92add..9ac55c73 100644
--- a/framework/Web/Javascripts/prototype/base.js
+++ b/framework/Web/Javascripts/prototype/base.js
@@ -26,10 +26,10 @@ Object.inspect = function(object) {
}
}
-Function.prototype.bind = function(object) {
- var __method = this;
+Function.prototype.bind = function() {
+ var __method = this, args = $A(arguments), object = args.shift();
return function() {
- return __method.apply(object, arguments);
+ return __method.apply(object, args.concat($A(arguments)));
}
}
diff --git a/framework/Web/Javascripts/prototype/dom.js b/framework/Web/Javascripts/prototype/dom.js
index 282fbfe0..3587a8da 100644
--- a/framework/Web/Javascripts/prototype/dom.js
+++ b/framework/Web/Javascripts/prototype/dom.js
@@ -1,7 +1,7 @@
document.getElementsByClassName = function(className, parentElement) {
var children = ($(parentElement) || document.body).getElementsByTagName('*');
return $A(children).inject([], function(elements, child) {
- if (Element.hasClassName(child, className))
+ if (child.className.match(new RegExp("(^|\\s)" + className + "(\\s|$)")))
elements.push(child);
return elements;
});
@@ -43,6 +43,11 @@ Object.extend(Element, {
element = $(element);
element.parentNode.removeChild(element);
},
+
+ update: function(element, html) {
+ $(element).innerHTML = html.stripScripts();
+ setTimeout(function() {html.evalScripts()}, 10);
+ },
getHeight: function(element) {
element = $(element);
@@ -70,12 +75,11 @@ Object.extend(Element, {
// removes whitespace-only text node children
cleanWhitespace: function(element) {
- if(undef(element) || isNull(element)) return;
element = $(element);
for (var i = 0; i < element.childNodes.length; i++) {
var node = element.childNodes[i];
if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
- node.parentNode.removeChild(node);
+ Element.remove(node);
}
},
@@ -108,6 +112,12 @@ Object.extend(Element, {
return value == 'auto' ? null : value;
},
+ setStyle: function(element, style) {
+ element = $(element);
+ for (name in style)
+ element.style[name.camelize()] = style[name];
+ },
+
getDimensions: function(element) {
element = $(element);
if (Element.getStyle(element, 'display') != 'none')
@@ -152,7 +162,7 @@ Object.extend(Element, {
element.style.top =
element.style.left =
element.style.bottom =
- element.style.right = '';
+ element.style.right = '';
}
},
@@ -184,7 +194,7 @@ Abstract.Insertion = function(adjacency) {
Abstract.Insertion.prototype = {
initialize: function(element, content) {
this.element = $(element);
- this.content = content;
+ this.content = content.stripScripts();
if (this.adjacency && this.element.insertAdjacentHTML) {
try {
@@ -201,6 +211,8 @@ Abstract.Insertion.prototype = {
if (this.initializeRange) this.initializeRange();
this.insertContent([this.range.createContextualFragment(this.content)]);
}
+
+ setTimeout(function() {content.evalScripts()}, 10);
},
contentFromAnonymousTable: function() {
@@ -233,7 +245,7 @@ Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), {
},
insertContent: function(fragments) {
- fragments.reverse().each((function(fragment) {
+ fragments.reverse(false).each((function(fragment) {
this.element.insertBefore(fragment, this.element.firstChild);
}).bind(this));
}
@@ -294,7 +306,7 @@ Element.ClassNames.prototype = {
if (!this.include(classNameToRemove)) return;
this.set(this.select(function(className) {
return className != classNameToRemove;
- }));
+ }).join(' '));
},
toString: function() {
diff --git a/framework/Web/Javascripts/prototype/enumerable.js b/framework/Web/Javascripts/prototype/enumerable.js
index edeb297b..78afa842 100644
--- a/framework/Web/Javascripts/prototype/enumerable.js
+++ b/framework/Web/Javascripts/prototype/enumerable.js
@@ -20,8 +20,8 @@ var Enumerable = {
all: function(iterator) {
var result = true;
this.each(function(value, index) {
- if (!(result &= (iterator || Prototype.K)(value, index)))
- throw $break;
+ result = result && !!(iterator || Prototype.K)(value, index);
+ if (!result) throw $break;
});
return result;
},
@@ -29,7 +29,7 @@ var Enumerable = {
any: function(iterator) {
var result = true;
this.each(function(value, index) {
- if (result &= (iterator || Prototype.K)(value, index))
+ if (result = !!(iterator || Prototype.K)(value, index))
throw $break;
});
return result;
diff --git a/framework/Web/Javascripts/prototype/form.js b/framework/Web/Javascripts/prototype/form.js
index 92a5d91a..4fa00ae2 100644
--- a/framework/Web/Javascripts/prototype/form.js
+++ b/framework/Web/Javascripts/prototype/form.js
@@ -19,8 +19,10 @@ var Field = {
},
activate: function(element) {
- $(element).focus();
- $(element).select();
+ element = $(element);
+ element.focus();
+ if (element.select)
+ element.select();
}
}
@@ -41,7 +43,7 @@ var Form = {
},
getElements: function(form) {
- var form = $(form);
+ form = $(form);
var elements = new Array();
for (tagName in Form.Element.Serializers) {
@@ -53,7 +55,7 @@ var Form = {
},
getInputs: function(form, typeName, name) {
- var form = $(form);
+ form = $(form);
var inputs = form.getElementsByTagName('input');
if (!typeName && !name)
@@ -88,16 +90,15 @@ var Form = {
}
},
+ findFirstElement: function(form) {
+ return Form.getElements(form).find(function(element) {
+ return element.type != 'hidden' && !element.disabled &&
+ ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
+ });
+ },
+
focusFirstElement: function(form) {
- var form = $(form);
- var elements = Form.getElements(form);
- for (var i = 0; i < elements.length; i++) {
- var element = elements[i];
- if (element.type != 'hidden' && !element.disabled) {
- Field.activate(element);
- break;
- }
- }
+ Field.activate(Form.findFirstElement(form));
},
reset: function(form) {
@@ -107,21 +108,29 @@ var Form = {
Form.Element = {
serialize: function(element) {
- var element = $(element);
+ element = $(element);
var method = element.tagName.toLowerCase();
var parameter = Form.Element.Serializers[method](element);
- if (parameter)
- return encodeURIComponent(parameter[0]) + '=' +
- encodeURIComponent(parameter[1]);
+ if (parameter) {
+ var key = encodeURIComponent(parameter[0]);
+ if (key.length == 0) return;
+
+ if (parameter[1].constructor != Array)
+ parameter[1] = [parameter[1]];
+
+ return parameter[1].map(function(value) {
+ return key + '=' + encodeURIComponent(value);
+ }).join('&');
+ }
},
getValue: function(element) {
- var element = $(element);
+ element = $(element);
var method = element.tagName.toLowerCase();
var parameter = Form.Element.Serializers[method](element);
- if (parameter)
+ if (parameter)
return parameter[1];
}
}
@@ -259,24 +268,14 @@ Abstract.EventObserver.prototype = {
switch (element.type.toLowerCase()) {
case 'checkbox':
case 'radio':
- element.target = this;
- element.prev_onclick = element.onclick || Prototype.emptyFunction;
- element.onclick = function() {
- this.prev_onclick();
- this.target.onElementEvent();
- }
+ Event.observe(element, 'click', this.onElementEvent.bind(this));
break;
case 'password':
case 'text':
case 'textarea':
case 'select-one':
case 'select-multiple':
- element.target = this;
- element.prev_onchange = element.onchange || Prototype.emptyFunction;
- element.onchange = function() {
- this.prev_onchange();
- this.target.onElementEvent();
- }
+ Event.observe(element, 'change', this.onElementEvent.bind(this));
break;
}
}
diff --git a/framework/Web/Javascripts/prototype/prototype.js b/framework/Web/Javascripts/prototype/prototype.js
index 8beb4d43..6ae99602 100644
--- a/framework/Web/Javascripts/prototype/prototype.js
+++ b/framework/Web/Javascripts/prototype/prototype.js
@@ -1,5 +1,19 @@
+/* Prototype JavaScript framework, version 1.4.0
+ * (c) 2005 Sam Stephenson <sam@conio.net>
+ *
+ * THIS FILE IS AUTOMATICALLY GENERATED. When sending patches, please diff
+ * against the source tree, available from the Prototype darcs repository.
+ *
+ * Prototype is freely distributable under the terms of an MIT-style license.
+ *
+ * For details, see the Prototype web site: http://prototype.conio.net/
+ *
+/*--------------------------------------------------------------------------*/
+
var Prototype = {
- Version: '1.4.0_rc1',
+ Version: '1.4.0',
+ ScriptFragment: '(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)',
+
emptyFunction: function() {},
K: function(x) {return x}
} \ No newline at end of file
diff --git a/framework/Web/Javascripts/prototype/range.js b/framework/Web/Javascripts/prototype/range.js
index f7c87166..e824e32a 100644
--- a/framework/Web/Javascripts/prototype/range.js
+++ b/framework/Web/Javascripts/prototype/range.js
@@ -1,6 +1,6 @@
-var Range = Class.create();
-Object.extend(Range.prototype, Enumerable);
-Object.extend(Range.prototype, {
+ObjectRange = Class.create();
+Object.extend(ObjectRange.prototype, Enumerable);
+Object.extend(ObjectRange.prototype, {
initialize: function(start, end, exclusive) {
this.start = start;
this.end = end;
@@ -25,5 +25,5 @@ Object.extend(Range.prototype, {
});
var $R = function(start, end, exclusive) {
- return new Range(start, end, exclusive);
+ return new ObjectRange(start, end, exclusive);
} \ No newline at end of file
diff --git a/framework/Web/Javascripts/prototype/string.js b/framework/Web/Javascripts/prototype/string.js
index c869e7db..f7b74710 100644
--- a/framework/Web/Javascripts/prototype/string.js
+++ b/framework/Web/Javascripts/prototype/string.js
@@ -3,6 +3,22 @@ Object.extend(String.prototype, {
return this.replace(/<\/?[^>]+>/gi, '');
},
+ stripScripts: function() {
+ return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
+ },
+
+ extractScripts: function() {
+ var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
+ var matchOne = new RegExp(Prototype.ScriptFragment, 'im');
+ return (this.match(matchAll) || []).map(function(scriptTag) {
+ return (scriptTag.match(matchOne) || ['', ''])[1];
+ });
+ },
+
+ evalScripts: function() {
+ return this.extractScripts().map(eval);
+ },
+
escapeHTML: function() {
var div = document.createElement('div');
var text = document.createTextNode(this);
diff --git a/framework/Web/Javascripts/tests/CompareValidator.html b/framework/Web/Javascripts/tests/CompareValidator.html
deleted file mode 100644
index 1a41fd11..00000000
--- a/framework/Web/Javascripts/tests/CompareValidator.html
+++ /dev/null
@@ -1,95 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-
-<html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="Content-type" content="text/html; charset=UTF-8" />
- <meta http-equiv="Content-Style-Type" content="text/css" />
- <title>Prado Client-Side CompareValidator Tests</title>
-<!-- base files -->
-<script type="text/javascript" src="../../base.js"></script>
-<script type="text/javascript" src="../../dom.js"></script>
-<script type="text/javascript" src="../prado/validation.js"></script>
-<script type="text/javascript" src="../prado/validators.js"></script>
-<style type="text/css">
-/*<![CDATA[*/
-
- .message
- {
- color: red;
- }
- .required, .required1, .required2
- {
- border: 1px solid red;
- }
-/*]]>*/
-</style>
- </head>
-
- <body>
- <h1>Prado Client-Side CompareValidator Tests</h1>
-
-<form id="form1" action="#">
-
-<!-- group 1 -->
-<div>
- <div>
- <input type="text" id="text1" name="text1" />
- <input type="text" id="text2" name="text2" />
- <span id="validator1" class="message" style="display:none">Must match</span>
- </div>
-
- <div>
- <input type="text" id="text3" name="text3" />
- <span id="validator2" class="message" style="display:none">Must equal "me!"</span>
- </div>
-
- <div>
- <input type="text" id="text4" name="text4" />
- <span id="validator3" class="message" style="display:none">Must be a date (d/m/Y)</span>
- </div>
- <input type="submit" value="Test" id="submit1" />
-</div>
- <script type="text/javascript">
- <!--
- /*]]>*/
- if(typeof(Prado) != "undefined" && typeof(Prado.Validation) != "undefined")
- {
- Prado.Validation.AddForm("form1");
-
- var val1 = {id : "validator1",
- controltovalidate : "text1",
- errormessage : "*",
- display : "Dynamic",
- controlcssclass : "required",
- controlhookup : "text2"};
- new Prado.Validation(Prado.Validation.TCompareValidator, val1);
-
- var val1 = {id : "validator2",
- controltovalidate : "text3",
- errormessage : "*",
- display : "Dynamic",
- controlcssclass : "required",
- valuetocompare : "me!"};
- new Prado.Validation(Prado.Validation.TCompareValidator, val1);
-
- var val1 = {id : "validator3",
- controltovalidate : "text4",
- errormessage : "*",
- display : "Dynamic",
- controlcssclass : "required",
- operator : "DataTypeCheck",
- type : "Date",
- dateformat : "%d/%m/%Y"};
- new Prado.Validation(Prado.Validation.TCompareValidator, val1);
-
- Prado.Validation.AddTarget("submit1");
- }
-
- /*]]>*/
- //-->
- </script>
-</form>
-
- </body>
-</html>
-
diff --git a/framework/Web/Javascripts/tests/CustomValidator.html b/framework/Web/Javascripts/tests/CustomValidator.html
deleted file mode 100644
index 34303781..00000000
--- a/framework/Web/Javascripts/tests/CustomValidator.html
+++ /dev/null
@@ -1,74 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-
-<html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="Content-type" content="text/html; charset=UTF-8" />
- <meta http-equiv="Content-Style-Type" content="text/css" />
- <title>Prado Client-Side CustomValidator Tests</title>
-<!-- base files -->
-<script type="text/javascript" src="../../base.js"></script>
-<script type="text/javascript" src="../../dom.js"></script>
-<script type="text/javascript" src="../prado/validation.js"></script>
-<script type="text/javascript" src="../prado/validators.js"></script>
-<style type="text/css">
-/*<![CDATA[*/
-
- .message
- {
- color: red;
- }
- .required, .required1, .required2
- {
- border: 1px solid red;
- }
-/*]]>*/
-</style>
- </head>
-
- <body>
- <h1>Prado Client-Side CustomValidator Tests</h1>
-
-<form id="form1" action="#">
-
-<!-- group 1 -->
-<div>
- <input type="text" id="text1" name="text1" />
- <span id="validator1" class="message" style="display:none">*</span>
- <input type="submit" value="Test" id="submit1" />
-</div>
- <script type="text/javascript">
- <!--
- /*]]>*/
- if(typeof(Prado) != "undefined" && typeof(Prado.Validation) != "undefined")
- {
- Prado.Validation.AddForm("form1");
-
- var val1 = {id : "validator1",
- controltovalidate : "text1",
- errormessage : "*",
- display : "Dynamic",
- controlcssclass : "required2",
- clientvalidationfunction : "CustomValidation"};
- new Prado.Validation(Prado.Validation.TCustomValidator, val1);
- Prado.Validation.AddTarget("submit1");
- }
-
- function CustomValidation(validator, value)
- {
- //call a custom callback function
- setTimeout(callback.bind(validator), 500);
- return false;
- }
-
- function callback()
- {
- this.setValid(true);
- }
- /*]]>*/
- //-->
- </script>
-</form>
-
- </body>
-</html>
-
diff --git a/framework/Web/Javascripts/tests/DatePicker.html b/framework/Web/Javascripts/tests/DatePicker.html
deleted file mode 100644
index d173006d..00000000
--- a/framework/Web/Javascripts/tests/DatePicker.html
+++ /dev/null
@@ -1,99 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head>
- <title>Prado Date Picker</title>
- <script type="text/javascript" src="../../base.js"></script>
- <script type="text/javascript" src="../../dom.js"></script>
- <script type="text/javascript" src="../../datepicker.js"></script>
-<script type="text/javascript">
-
- function init() {
- var options = { "trigger" : "button1", "format" : "dd-MM-yyyy" };
- var datepicker1 = new Prado.Calendar("textfield1", options);
- //datepicker1.format = "yyyy-MM-d";
- //datepicker1.create();
- //datepicker1.show("button1");
- //var button = $("button1");
- //Event.observe(button, "click", function(){datepicker1.show(button);});
- //var d = new Date();
- //alert(Prado.Calendar.Util.ISODate(d));
- var datepicker2 = new Prado.Calendar("textfield2");
- }
-
- /*var cal;
-
- function init() {
- cal = new Calendar();
- cal.setIncludeWeek(true);
- cal.setFormat("yyyy-MM-dd");
- //cal.setMonthNames(.....);
- //cal.setShortMonthNames(....);
- cal.create();
-
- var button = $("button1");
- button.onclick = function() {
- cal.toggle(button);
- }
- cal.onchange = function() {
- $("textfield1").value = cal.formatDate();
- }
- }*/
-
- window.onload = init;
- </script>
-</script>
-</head>
-
-<body>
-<form ID=Form1>
- <input type="text" name="textfield1" id="textfield1" />
- <input type="button" name="button1" id="button1" value="..." />
-</form>
-
-
-as<br/>
-dv<br/>
-as<br/>
-d<br/>
-as<br/>
-d<br/>
-asd<br/>
-a<br/>
-sd<br/>
-dv<br/>
-as<br/>
-d<br/>
-as<br/>
-d<br/>
-asd<br/>
-a<br/>
-sd<br/>
-dv<br/>
-as<br/>
-d<br/>
-as<br/>
-d<br/>
-asd<br/>
-a<br/>
-sd<br/>
-<form>
- <input type="text" name="textfield2" id="text1" />
- <input type="button" name="button2" id="button2" value="..." />
-</form>
-d<br/>
-as<br/>
-d<br/>
-asd<br/>
-a<br/>
-sd<br/>
-dv<br/>
-as<br/>
-d<br/>
-as<br/>
-d<br/>
-asd<br/>
-a<br/>
-sd<br/>
-</body>
-</html>
diff --git a/framework/Web/Javascripts/tests/Effects.html b/framework/Web/Javascripts/tests/Effects.html
deleted file mode 100644
index 6ee5324b..00000000
--- a/framework/Web/Javascripts/tests/Effects.html
+++ /dev/null
@@ -1,124 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-
-<head>
- <title>Effects demo page</title>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <script type="text/javascript" src="../../base.js"></script>
- <script type="text/javascript" src="../../dom.js"></script>
- <script type="text/javascript" src="../../effects.js"></script>
-</head>
-
-<body style="font: 0.9em Arial;background: #f5f5f5;">
-<h1>Effect.Fade()</h1>
-
-<p>Call with <code>new Effect.Fade(element)</code></p>
-<p>Example: <code>onclick="new Effect.Fade(this)"</code></p>
-
-<div id="fade" onclick="new Effect.Fade(this)" style="border:1px solid red; padding:1em;">
- Click here or the image to start effect
-</div>
-
-
-<h1>Effect.Highlight()</h1>
-
-<p>Call with <code>new Effect.Highlight(element)</code></p>
-<p>Example: <code>onclick="new Effect.Highlight(this)"</code></p>
-
-<div id="fade" onclick="new Effect.Highlight(this)" style="border:1px solid red; padding:1em;">
- Click here or the image to start effect
-</div>
-
-<h1>Effect.Appear()</h1>
-
-<p>Call with <code>new Effect.Appear(element)</code></p>
-<p>Example: <code>onclick="new Effect.Appear('appear')"</code></p>
-
-<a href="#" onclick="new Effect.Appear('appear')">Start effect</a>
-
-<div id="appear" style="border:1px solid red; padding:1em;display:none;background:#fff;">
- This is just some text
-</div>
-
-<h1>Effect.Scale()</h1>
-
-<p>Call with <code>new Effect.Scale(element, percent)</code></p>
-<p>Note: if you scale a div, all contained elements must have width or height set with <tt>em</tt>. If you
-scale an image, width and height are not required to be set. Also, Effect.Scale is aware of other scaling effects done on
-the target element, and will act accordingly. The <tt>percent</tt> parameter is always relative of the original size of the element.</p>
-<p>Example: <code>onmouseover="new Effect.Scale('scale',150)" onmouseout="new Effect.Scale('scale',100)"</code></p>
-
-<div style="height:100px">
-<img src="fungii_logo.gif" style="width:130px;" onmouseover="new Effect.Scale(this,150)" onmouseout="new Effect.Scale(this,100)"/>
-<img src="fungii_logo.gif" style="width:130px;" onmouseover="new Effect.Scale(this,150)" onmouseout="new Effect.Scale(this,100)"/>
-<img src="fungii_logo.gif" style="width:130px;" onmouseover="new Effect.Scale(this,150)" onmouseout="new Effect.Scale(this,100)"/>
-<img src="fungii_logo.gif" style="width:130px;" onmouseover="new Effect.Scale(this,150)" onmouseout="new Effect.Scale(this,100)"/>
-</div>
-
-<h1>Effect.Squish()</h1>
-<p>Call with <code>new Effect.Squish(element)</code></p>
-<div id="squish" style="border:1px solid red; width:250px; height:150px;background:#fff;" onclick="new Effect.Squish(this)">
- Click me to squish.<br/>
- <img src="fungii_logo.gif" style="width:100%;" />
-
-</div>
-
-<h1>Effect.Puff()</h1>
-<p>Call with <code>new Effect.Puff(element)</code></p>
-<p>Works with absolute and relative positioned elements. In this example, divs with <tt>float:left</tt> are used.</p>
-<div id="puff1" style="float:left;margin-right:1em;border:1px solid red; padding:1em;width:10em;height:5em;background:#fff;" onclick="new Effect.Puff(this)">
- (floating) Click me to puff.<br/>
- <img src="fungii_logo.gif" style="width:8em" />
-
-</div>
-<div id="puff2" style="float:left;margin-right:1em;border:1px solid red; padding:1em;width:10em;height:5em;background:#f8f;" onclick="new Effect.Puff(this)">
- (floating) Click me to puff.<br/>
- <img src="fungii_logo.gif" style="width:8em" />
-</div>
-<div id="puff3" style="float:left;margin-right:1em;border:1px solid red; padding:1em;width:10em;height:5em;background:#ff8;" onclick="new Effect.Puff(this)">
- (floating) Click me to puff.<br/>
- <img src="fungii_logo.gif" style="width:8em" />
-</div>
-<div id="puff4" style="float:left;margin-right:1em;border:1px solid red; padding:1em;width:10em;height:5em;background:#fff;" onclick="new Effect.Puff(this)">
- (floating) Click me to puff.<br/>
-
- <img src="fungii_logo.gif" style="width:8em" />
-</div>
-<div id="puff5" style="float:left;margin-right:1em;border:1px solid red; padding:1em;width:10em;height:5em;background:#f8f;" onclick="new Effect.Puff(this)">
- (floating) Click me to puff.<br/>
- <img src="fungii_logo.gif" style="width:8em" />
-</div>
-<div id="puff6" style="float:left;margin-right:1em;border:1px solid red; padding:1em;width:10em;height:5em;background:#ff8;" onclick="new Effect.Puff(this)">
- (floating) Click me to puff.<br/>
- <img src="fungii_logo.gif" style="width:8em" />
-</div>
-
-<div id="puff11" style="float:left;margin-right:1em;border:1px solid red; padding:1em;width:10em;height:5em;background:#fff;" onclick="new Effect.Puff(this)">
- (floating) Click me to puff.<br/>
- <img src="fungii_logo.gif" style="width:8em" />
-</div>
-<div id="puff12" style="float:left;margin-right:1em;border:1px solid red; padding:1em;width:10em;height:5em;background:#f8f;" onclick="new Effect.Puff(this)">
- (floating) Click me to puff.<br/>
- <img src="fungii_logo.gif" style="width:8em" />
-</div>
-<div id="puff13" style="float:left;margin-right:1em;border:1px solid red; padding:1em;width:10em;height:5em;background:#ff8;" onclick="new Effect.Puff(this)">
- (floating) Click me to puff.<br/>
-
- <img src="fungii_logo.gif" style="width:8em" />
-</div>
-<div id="puff14" style="float:left;margin-right:1em;border:1px solid red; padding:1em;width:10em;height:5em;background:#fff;" onclick="new Effect.Puff(this)">
- (floating) Click me to puff.<br/>
- <img src="fungii_logo.gif" style="width:8em" />
-</div>
-<div id="puff15" style="float:left;margin-right:1em;border:1px solid red; padding:1em;width:10em;height:5em;background:#f8f;" onclick="new Effect.Puff(this)">
- (floating) Click me to puff.<br/>
- <img src="fungii_logo.gif" style="width:8em" />
-</div>
-
-<div id="puff16" style="float:left;margin-right:1em;border:1px solid red; padding:1em;width:10em;height:5em;background:#ff8;" onclick="new Effect.Puff(this)">
- (floating) Click me to puff.<br/>
- <img src="fungii_logo.gif" style="width:8em" />
-</div>
-
-</body>
-</html> \ No newline at end of file
diff --git a/framework/Web/Javascripts/tests/Form.disable.html b/framework/Web/Javascripts/tests/Form.disable.html
deleted file mode 100644
index 5ff5f7d6..00000000
--- a/framework/Web/Javascripts/tests/Form.disable.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-
-<head>
- <title>Form disable test</title>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <script src="../dist/prototype.js"></script>
-</head>
-
-<body style="font: 0.9em Arial;background: #f5f5f5;">
-
-<form id="test" method="post">
-Number
- <select name="guest[size]">
- <option value="0"
- > 0
- </option>
- <option value="1"
- selected > 1
- </option>
- <option value="2"
- > 2
- </option>
- </select>
-
-<label for="text">Text</label></td>
-<input id="form_text" name="form[text]" size="30" type="text" value="" /><br/>
-<label for="form_radio">Radio</label></td>
-<td>
- <input id="form_radio_yes" name="form[radio]" size="30" type="radio" value="1" />yes
- <input id="form_radio_no" name="form[radio]" size="30" type="radio" value="0" />no
-
-</td>
-</form>
-<p>
-<a href="#" onClick="Form.disable(document.forms['test']);">disable</a>
-<a href="#" onClick="Form.enable(document.forms['test']);">enable</a>
diff --git a/framework/Web/Javascripts/tests/Insertion.html b/framework/Web/Javascripts/tests/Insertion.html
deleted file mode 100644
index 1aefd3aa..00000000
--- a/framework/Web/Javascripts/tests/Insertion.html
+++ /dev/null
@@ -1,47 +0,0 @@
-<html>
-<head>
- <script type="text/javascript" src="../../base.js"></script>
- <script type="text/javascript" src="../../dom.js"></script>
- <script type="text/javascript" src="../../form.js"></script>
- <script type="text/javascript">
- function test() {
- var type = Form.Element.getValue('type');
- var html = '<div>' + Form.Element.getValue('content') + '</div>';
- new Insertion[type]($('a'), html);
- return false;
- }
- </script>
-
- <style type="text/css">
- div#a {
- border: 2px solid blue;
- padding: 10px;
- margin-bottom: 10px;
- }
-
- div#a div {
- border: 1px solid red;
- padding: 5px;
- }
-
- textarea {
- display: block;
- }
- </style>
-</head>
-<body>
- <div id="a">
- content
- </div>
- <fieldset>
- <textarea id="content" rows="10" cols="60"></textarea>
- <select id="type">
- <option value="Before">Before</option>
- <option value="Top">Top</option>
- <option value="Bottom">Bottom</option>
- <option value="After">After</option>
- </select>
- <button onclick="return test()">Create Insertion</button>
- </fieldset>
-</body>
-</html> \ No newline at end of file
diff --git a/framework/Web/Javascripts/tests/PradoTestSuite.html b/framework/Web/Javascripts/tests/PradoTestSuite.html
deleted file mode 100644
index 8b3c8ccf..00000000
--- a/framework/Web/Javascripts/tests/PradoTestSuite.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
-"http://www.w3.org/TR/html4/loose.dtd">
-
-<html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
- <title>Prado Javascript Test Suite</title>
- <link rel="stylesheet" type="text/css" href="jsunit/css/jsUnitStyle.css">
-<script language="JavaScript" type="text/javascript" src="jsunit/app/jsUnitCore.js"></script>
-<script language="JavaScript" type="text/javascript">
-function coreTestSuite() {
- var newsuite = new top.jsUnitTestSuite();
- return newsuite;
-}
-
-function validationTestSuite() {
- var newsuite = new top.jsUnitTestSuite();
- return newsuite;
-}
-
-function suite() {
- var newsuite = new top.jsUnitTestSuite();
- newsuite.addTestSuite(coreTestSuite());
- newsuite.addTestSuite(validationTestSuite());
- return newsuite;
-}
-</script>
- </head>
-
- <body>
- <h1>Prado Javascript Test Suite</h1>
-
- <p>This page contains a suite of tests for testing
- Prado javascripts.</p>
- </body>
-</html>
-
diff --git a/framework/Web/Javascripts/tests/RangeValidator.html b/framework/Web/Javascripts/tests/RangeValidator.html
deleted file mode 100644
index 0dd3c283..00000000
--- a/framework/Web/Javascripts/tests/RangeValidator.html
+++ /dev/null
@@ -1,65 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-
-<html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="Content-type" content="text/html; charset=UTF-8" />
- <meta http-equiv="Content-Style-Type" content="text/css" />
- <title>Prado Client-Side RangeValidator Tests</title>
-<!-- base files -->
-<script type="text/javascript" src="../../base.js"></script>
-<script type="text/javascript" src="../../dom.js"></script>
-<script type="text/javascript" src="../prado/validation.js"></script>
-<script type="text/javascript" src="../prado/validators.js"></script>
-<style type="text/css">
-/*<![CDATA[*/
-
- .message
- {
- color: red;
- }
- .required, .required1, .required2
- {
- border: 1px solid red;
- }
-/*]]>*/
-</style>
- </head>
-
- <body>
- <h1>Prado Client-Side RangeValidator Tests</h1>
-
-<form id="form1" action="#">
-
-<!-- group 1 -->
-<div>
- <input type="text" id="text1" name="text1" />
- <span id="validator1" class="message" style="display:none">Numbers between 1 and 4</span>
- <input type="submit" value="Test" id="submit1" />
-</div>
- <script type="text/javascript">
- <!--
- /*]]>*/
- if(typeof(Prado) != "undefined" && typeof(Prado.Validation) != "undefined")
- {
- Prado.Validation.AddForm("form1");
-
- var val1 = {id : "validator1",
- controltovalidate : "text1",
- errormessage : "*",
- display : "Dynamic",
- controlcssclass : "required2",
- minimumvalue : "1",
- maximumvalue : "4",
- type : "Integer"};
- new Prado.Validation(Prado.Validation.TRangeValidator, val1);
- Prado.Validation.AddTarget("submit1");
- }
-
- /*]]>*/
- //-->
- </script>
-</form>
-
- </body>
-</html>
-
diff --git a/framework/Web/Javascripts/tests/RegularExpressionValidator.html b/framework/Web/Javascripts/tests/RegularExpressionValidator.html
deleted file mode 100644
index 619ec6f5..00000000
--- a/framework/Web/Javascripts/tests/RegularExpressionValidator.html
+++ /dev/null
@@ -1,72 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-
-<html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="Content-type" content="text/html; charset=UTF-8" />
- <meta http-equiv="Content-Style-Type" content="text/css" />
- <title>Prado Client-Side RegularExpressionValidator Tests</title>
-<!-- base files -->
-<script type="text/javascript" src="../../base.js"></script>
-<script type="text/javascript" src="../../dom.js"></script>
-<script type="text/javascript" src="../prado/validation.js"></script>
-<script type="text/javascript" src="../prado/validators.js"></script>
-<style type="text/css">
-/*<![CDATA[*/
-
- .message
- {
- color: red;
- }
- .required, .required1, .required2
- {
- border: 1px solid red;
- }
-/*]]>*/
-</style>
- </head>
-
- <body>
- <h1>Prado Client-Side RegularExpressionValidator Tests</h1>
-
-<form id="form1" action="#">
-
-<!-- group 1 -->
-<div>
- <input type="text" id="text1" name="text1" />
- <span id="validator1" class="message" style="display:none">5 digits</span>
- <span id="validator2" class="message" style="display:none">*</span>
- <input type="submit" value="Test 1" id="submit1" />
- <input type="submit" value="Test 2" id="submit2" />
- <input type="submit" value="Test 3" id="submit3" />
-</div>
- <script type="text/javascript">
- <!--
- /*]]>*/
- if(typeof(Prado) != "undefined" && typeof(Prado.Validation) != "undefined")
- {
- Prado.Validation.AddForm("form1");
- var val1 = {id : "validator1",
- controltovalidate : "text1",
- errormessage : "5 digits",
- display : "Dynamic",
- controlcssclass : "required1",
- validationexpression : "^\\d{5}$"};
- var val2 = {id : "validator2",
- controltovalidate : "text1",
- errormessage : "*",
- display : "Dynamic",
- controlcssclass : "required2",
- initialvalue : ""};
- new Prado.Validation(Prado.Validation.TRegularExpressionValidator, val1);
- //new Prado.Validation(Prado.Validation.TRequiredFieldValidator, val2);
- Prado.Validation.AddTarget("submit1");
- Prado.Validation.AddTarget("submit2");
- }
- /*]]>*/
- //-->
- </script>
-</form>
-
- </body>
-</html>
-
diff --git a/framework/Web/Javascripts/tests/RequiredFieldValidator.html b/framework/Web/Javascripts/tests/RequiredFieldValidator.html
deleted file mode 100644
index ae99d355..00000000
--- a/framework/Web/Javascripts/tests/RequiredFieldValidator.html
+++ /dev/null
@@ -1,95 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-
-<html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="Content-type" content="text/html; charset=UTF-8" />
- <meta http-equiv="Content-Style-Type" content="text/css" />
- <title>Prado Client-Side RequiredFieldValidator Tests</title>
-<style type="text/css">
-/*<![CDATA[*/
-
- .message
- {
- color: red;
- }
- .required
- {
- border: 1px solid red;
- }
-/*]]>*/
-</style>
-
- </head>
-
- <body>
- <h1>Prado Client-Side RequiredFieldValidator Tests</h1>
-
-<form action="" method="post" enctype="multipart/form-data" id="form1">
-<script type="text/javascript" src="../../js/base.js"></script>
-<script type="text/javascript" src="../../js/dom.js"></script>
-<script type="text/javascript" src="../prado/validation.js"></script>
-<script type="text/javascript" src="../prado/validators.js"></script>
-
-
-<!-- group 1 -->
-<div id="summary1"></div>
-<div>
- <input id="text1" name="text1" type="text" value=""/>
- <span id="validator1" class="message" style="display:none;"><a href="#text1" onclick="javascript:Prado.Validation.Util.focus('text1'); return false;" >text1!</a></span>
-
- <span><input id="check1" type="checkbox" name="check1"/></span>
- <span id="validator2" class="message" style="display:none;">check 1!</span>
-
- <input id="submit1" type="submit" name="submit1" value="Group1"></input>
-
-</div>
-<!-- group 2 -->
-<div id="summary2"></div>
-<div>
- <input id="text2" name="text2" type="text" value=""/>
- <span id="validator3" class="message" style="visibility:hidden;">text2!</span>
-
- <span><input id="check2" type="checkbox" name="check2"/></span>
- <span id="validator4" class="message" style="visibility:hidden;">check 2!</span>
-
- <input id="submit2" type="submit" name="submit2" value="Group2"></input>
-
-</div>
-
-<div id="summary3"></div>
-
-
-<input id="submit3" type="submit" name="submit3" value="Submit All"></input>
-<input id="submit4" type="submit" name="submit4" value="Submit By Pass"></input>
-
-
-
-<script type="text/javascript">
-//<![CDATA[
-
- if(typeof(Prado) == 'undefined')
- alert("Unable to find Prado javascript library '../../base.js'.");
- else if(Prado.Version != 2.0)
- alert("Prado javascript library version 2.0 required.");
- else if(typeof(Prado.Validation) == 'undefined')
- alert("Unable to find validation javascript library '../../validator.js'.");
- else
- Prado.Validation.AddForm('form1');
-
-new Prado.Validation.Summary({id:"summary1", form:"form1", displaymode:"BulletList", group:"group1"});
-new Prado.Validation(Prado.Validation.TRequiredFieldValidator, {id:"validator1", controltovalidate:"text1", errormessage:"<a href=\"#text1\" onclick=\"javascript:Prado.Validation.Util.focus(\'text1\'); return false;\" >text1!</a>", display:"Dynamic", controlcssclass:"required", initialvalue:""});
-new Prado.Validation(Prado.Validation.TRequiredFieldValidator, {id:"validator2", controltovalidate:"check1", errormessage:"check 1!", display:"Dynamic", controlcssclass:"required", initialvalue:""});
-Prado.Validation.AddGroup({id:"group1", target:"submit1"}, ["validator1", "validator2"]);
-Prado.Validation.AddTarget('submit1');
-
-new Prado.Validation.Summary({id:"summary2", form:"form1", displaymode:"BulletList", group:"group2"});
-new Prado.Validation(Prado.Validation.TRequiredFieldValidator, {id:"validator3", controltovalidate:"text2", errormessage:"text2!", controlcssclass:"required", initialvalue:""});
-new Prado.Validation(Prado.Validation.TRequiredFieldValidator, {id:"validator4", controltovalidate:"check2", errormessage:"check 2!", controlcssclass:"required", initialvalue:""});
-Prado.Validation.AddGroup({id:"group2", target:"submit2"}, ["validator3", "validator4"]);
-Prado.Validation.AddTarget('submit2');
-
-new Prado.Validation.Summary({id:"summary3", form:"form1", displaymode:"BulletList"});
-Prado.Validation.AddTarget('submit3');
-//]]>
-</script>
-</form> \ No newline at end of file
diff --git a/framework/Web/Javascripts/tests/RequiredListValidator.html b/framework/Web/Javascripts/tests/RequiredListValidator.html
deleted file mode 100644
index 7e79e4af..00000000
--- a/framework/Web/Javascripts/tests/RequiredListValidator.html
+++ /dev/null
@@ -1,110 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-
-<html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="Content-type" content="text/html; charset=UTF-8" />
- <meta http-equiv="Content-Style-Type" content="text/css" />
- <title>Prado Client-Side RequiredListValidator Tests</title>
-<!-- base files -->
-<script type="text/javascript" src="../../base.js"></script>
-<script type="text/javascript" src="../prototype/dom.js"></script>
-<script type="text/javascript" src="../extended/dom.js"></script>
-<script type="text/javascript" src="../prototype/event.js"></script>
-<script type="text/javascript" src="../extended/event.js"></script>
-<script type="text/javascript" src="../prototype/form.js"></script>
-<script type="text/javascript" src="../prototype/position.js"></script>
-<script type="text/javascript" src="../prototype/string.js"></script>
-<script type="text/javascript" src="../extra/getElementsBySelector.js"></script>
-<script type="text/javascript" src="../extra/behaviour.js"></script>
-<script type="text/javascript" src="../prado/validation.js"></script>
-<script type="text/javascript" src="../prado/validators.js"></script>
-<style type="text/css">
-/*<![CDATA[*/
-
- .message
- {
- color: red;
- }
- .required, .required1, .required2
- {
- border: 1px solid red;
- }
- .requirede
- {
- background-color: red;
- }
-/*]]>*/
-</style>
- </head>
-
- <body>
- <h1>Prado Client-Side RequiredListValidator Tests</h1>
-
-<form id="form1" action="#">
-
-<!-- group 1 -->
-<div>
- <div id="checks">
- <input type="checkbox" id="check1" name="check1[]" value="1" />1
- <input type="checkbox" id="check2" name="check1[]" value="2" />2
- <input type="checkbox" id="check3" name="check1[]" value="3" />3
- <input type="checkbox" id="check4" name="check1[]" value="4" />4
- <span id="validator1" class="message" style="display:none">Must select at least 1 and no more than 3</span>
- </div>
-
- <div>
- <select id="select1" name="select1[]" multiple="multiple" size="5" style="width:10em">
- <option value="one">one</option>
- <option value="two">two</option>
- <option value="three">three</option>
- <option value="four">four</option>
- <option value="five">five</option>
- </select>
- <span id="validator2" class="message" style="display:none">Must select at least 2 and no more than 3 and value "two"</span>
- </div>
-
- <input type="submit" value="Test" id="submit1" />
-</div>
- <script type="text/javascript">
- <!--
- /*]]>*/
- if(typeof(Prado) != "undefined" && typeof(Prado.Validation) != "undefined")
- {
- Prado.Validation.AddForm("form1");
-
- var val1 = {id : "validator1",
- controltovalidate : "checks",
- selector : "check1[]",
- errormessage : "*",
- display : "Dynamic",
- controlcssclass : "required",
- //elementcssclass : "requirede",
- min : "1",
- max : "3"
- };
- new Prado.Validation(Prado.Validation.TRequiredListValidator, val1);
-
- var val1 = {id : "validator2",
- controltovalidate : "select1",
- selector : "select1[]",
- errormessage : "*",
- display : "Dynamic",
- controlcssclass : "required",
- //elementcssclass : "requirede",
- min : "2",
- max : "3",
- required : "two"
- };
- new Prado.Validation(Prado.Validation.TRequiredListValidator, val1);
- Prado.Validation.AddTarget("submit1");
-
- }
-
- /*]]>*/
- //-->
- </script>
-</form>
-
- </body>
-</html>
-
diff --git a/framework/Web/Javascripts/tests/ValidationTests.html b/framework/Web/Javascripts/tests/ValidationTests.html
deleted file mode 100644
index 67c9aecb..00000000
--- a/framework/Web/Javascripts/tests/ValidationTests.html
+++ /dev/null
@@ -1,79 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
-"http://www.w3.org/TR/html4/loose.dtd">
-
-<html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
- <title>Prado Client-Side Validation Tests</title>
- <link rel="stylesheet" type="text/css" href="jsunit/css/jsUnitStyle.css">
- <script language="JavaScript" type="text/javascript" src="jsunit/app/jsUnitCore.js"></script>
-<!-- unit tests -->
-<!-- base files -->
-<script language="JavaScript" Type="text/javascript" src="../../base.js"></script>
-<script language="JavaScript" Type="text/javascript" src="../../dom.js"></script>
-<!-- library file -->
-<script language="JavaScript" Type="text/javascript" src="../library/validation/validator.js"></script>
-<script language="JavaScript" type="text/javascript">
-
- function testConvertInteger()
- {
- var convert = Prado.Validation.Util;
-
- //test integers
- assertEquals("Integer 10", 10, convert.toInteger("10"));
- assertNull("Not an integer", convert.toInteger("10.0"));
- assertEquals("+ integer", 10, convert.toInteger(" +10 "));
- }
-
- function testConvertDouble()
- {
- var convert = Prado.Validation.Util;
-
- //test doubles
- assertEquals("Double 10.0", 10.0, convert.toDouble("10.0","."));
- assertNull("Not a double", convert.toDouble("10.0s"));
- assertEquals("+ double", 10.2, convert.toDouble(" +10.2 "));
- }
-
- function testConvertAsCurrency()
- {
- var convert = Prado.Validation.Util;
-
- //test currency convert
- assertEquals("10 Dollars", 10, convert.toCurrency("10.00"));
- assertEquals("10,000 Dollars", 10000.10, convert.toCurrency("10,000.10"));
-
- //using space as grouping
- assertEquals("10 000 Dollars", 10000.10, convert.toCurrency("10 000.10", " "));
-
- assertEquals("1 0000 Yen", 10000, convert.toCurrency("1 0000", " ",0));
-
- assertNull("Not 10 Dollars", convert.toCurrency("$10.0"));
- }
-
- function testConvertToDate()
- {
- var convert = Prado.Validation.Util;
-
- //test dates !! Months are zero based for javascript Date objects !!
- var testDate = (new Date(2005, 05, 20)).valueOf();
- assertEquals("Matching date 2005 May 20", testDate, convert.toDate("2005-06-20", "%Y-%m-%d"));
- }
-
- function testValidatorConversion()
- {
- var validator = new Prado.Validation(null, {id : "", controltovalidate : "", groupchar: " ", digits : 0});
- assertEquals("Integer 10", 10, validator.convert("Integer", "10"));
- assertEquals("10 000 Yen", 10000, validator.convert("Currency", "10 000"));
- }
-</script>
- </head>
-
- <body>
- <h1>Prado Client-Side Validation Tests</h1>
-
- <p>This page contains tests for the utility functions
- that JsUnit uses. To see them, take a look at the source.</p>
- </body>
-</html>
-
diff --git a/framework/Web/Javascripts/tests/calendar_system.css b/framework/Web/Javascripts/tests/calendar_system.css
deleted file mode 100644
index a797372e..00000000
--- a/framework/Web/Javascripts/tests/calendar_system.css
+++ /dev/null
@@ -1,70 +0,0 @@
-div.Prado_Calendar
-{
- border: 1px solid WindowText;
- position: absolute;
- text-align: center;
- background-color: Window;
- z-index: 1000;
- font: small-caption;
- font-weight: normal;
- width: 20em;
-}
-
-div.Prado_Calendar .calendarHeader
-{
- background-color: ActiveCaption;
- padding: 1px;
- border-bottom: 1px solid WindowText;
-}
-
-div.Prado_Calendar table
-{
- width: 100%;
-}
-
-div.Prado_Calendar .date
-{
- font-weight: normal;
- cursor: pointer;
-}
-
-div.Prado_Calendar .selected
-{
- border: 1px solid WindowText;
-}
-
-div.Prado_Calendar .today
-{
- font-weight: bold;
-}
-
-div.Prado_Calendar .current
-{
- border: 1px dotted WindowText;
-}
-
-div.Prado_Calendar .calendarBody td
-{
- padding: 2px 0;
-}
-
-div.Prado_Calendar .hover
-{
- background-color: Highlight;
- color: HighlightText;
-}
-
-div.Prado_Calendar td.empty
-{
- background-color: Window;
-}
-
-div.Prado_Calendar .grid td
-{
- width: 14%;
-}
-
-div.Prado_Calendar .grid
-{
- border-spacing: 0;
-} \ No newline at end of file
diff --git a/framework/Web/Javascripts/tests/compression.html b/framework/Web/Javascripts/tests/compression.html
deleted file mode 100644
index 66e10a97..00000000
--- a/framework/Web/Javascripts/tests/compression.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<title>Test all compressed JS</title>
-<script type="text/javascript" src="../../base.js"></script>
-<script type="text/javascript" src="../../dom.js"></script>
-<script type="text/javascript" src="../../effects.js"></script>
-<script type="text/javascript" src="../../rico.js"></script>
-<script type="text/javascript" src="../../template.js"></script>
-<script type="text/javascript" src="../../validator.js"></script>
-
-</head>
-<body>
-OK
-</body>
-</html>
diff --git a/framework/Web/Javascripts/tests/console.html b/framework/Web/Javascripts/tests/console.html
deleted file mode 100644
index e6aed30f..00000000
--- a/framework/Web/Javascripts/tests/console.html
+++ /dev/null
@@ -1,30 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
- "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
- <head>
- <title>Prototype Console</title>
- <script src="../dist/prototype.js" type="text/javascript"></script>
- <script type="text/javascript">
- function test() {
- var out = $('out');
- try {
- input = $F('input');
- out.innerHTML += input.escapeHTML() + '<br />';
- value = eval(input);
- out.innerHTML += '=> ' + value.toString().escapeHTML() + '<br />';
- } catch (e) {
- out.innerHTML += 'Error: ' + e.toString().escapeHTML() + '<br />';
- }
- $('input').value = '';
- }
- </script>
- </head>
- <body>
- <form onsubmit="test(); return false">
- <input type="text" size="60" id="input" />
- <input type="submit" value="Execute" />
- </form>
- <div id="test"></div>
- <div id="out"></div>
- </body>
-</html>
diff --git a/framework/Web/Javascripts/tests/fungii_logo.gif b/framework/Web/Javascripts/tests/fungii_logo.gif
deleted file mode 100644
index b667c73e..00000000
--- a/framework/Web/Javascripts/tests/fungii_logo.gif
+++ /dev/null
Binary files differ
diff --git a/framework/Web/Javascripts/tests/getElementsByClassName.html b/framework/Web/Javascripts/tests/getElementsByClassName.html
deleted file mode 100644
index b764aac4..00000000
--- a/framework/Web/Javascripts/tests/getElementsByClassName.html
+++ /dev/null
@@ -1,28 +0,0 @@
-<html>
-<head>
- <script type="text/javascript" src="../../base.js"></script>
- <script type="text/javascript" src="../../dom.js"></script>
- <script type="text/javascript">
- function test() {
- var elements = document.getElementsByClassName($('class-name').value);
- for (var i = 0; i < elements.length; i++) elements[i] = elements[i].id;
- alert(elements.join(', '));
- return false;
- }
- </script>
-</head>
-<body>
- <div id="a" class="foo">a: foo</div>
- <div id="b" class="foo bar">b: foo, bar</div>
- <div id="c" class="bar">c: bar</div>
- <div id="d" class="bar baz">d: bar, baz</div>
- <div id="e" class="baz">e: baz</div>
- <div id="f" class="foo baz">f: foo, baz</div>
-
- <fieldset>
- <label for="class-name">Class name:</label>
- <input id="class-name" type="text" value="foo" />
- <button onclick="return test()">Find</button>
- </fieldset>
-</body>
-</html>
diff --git a/framework/Web/Javascripts/tests/getElementsBySelector.html b/framework/Web/Javascripts/tests/getElementsBySelector.html
deleted file mode 100644
index e8f716fc..00000000
--- a/framework/Web/Javascripts/tests/getElementsBySelector.html
+++ /dev/null
@@ -1,55 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<title>document.getElementsBySelector Demo</title>
-<style type="text/css">
-body {
- margin: 1em 3em;
- font-family: georgia;
-}
-div#foo {
- border: 2px solid red;
-}
-</style>
-<script type="text/javascript" src="../../base.js"></script>
-<script type="text/javascript" src="../../dom.js"></script>
-<script type="text/javascript">
-function show(a) {
- str = '';
- for (i = 0; i != a.length; i++) {
- str = str + a[i].toString() + '\n';
- }
- alert(str);
-}
-</script>
-</head>
-<body>
-<h1>document.getElementsBySelector Demo</h1>
-<p>See <a href="http://simon.incutio.com/archive/2003/03/25/#getElementsBySelector" rel="bookmark">this blog entry</a> for more information.</p>
-<p>Here are some links in a normal paragraph: <a href="http://www.google.com/" title="Google!">Google</a>, <a href="http://groups.google.com/">Google Groups</a>. This link has <code>class="blog"</code>: <a href="http://diveintomark.org/" class="blog">diveintomark</a></p>
-<div id="foo">
-<p>Everything inside the red border is inside a div with <code>id="foo"</code>.</p>
-<p>This is a normal link: <a href="http://www.yahoo.com/">Yahoo</a></p>
-
-<p>This link has <code>class="blog"</code>: <a href="http://simon.incutio.com/" class="blog">Simon Willison's Weblog</a></p>
-</div>
-
-<form action="" method="get" onsubmit="return false;">
-<p>Try them out: </p>
-<ul>
-<li><input type="submit" value="document.getElementsBySelector('a')" onclick="show(document.getElementsBySelector('a'))" /></li>
-<li><input type="submit" value="document.getElementsBySelector('p a.blog')" onclick="show(document.getElementsBySelector('p a.blog'))" /></li>
-<li><input type="submit" value="document.getElementsBySelector('div#foo a')" onclick="show(document.getElementsBySelector('div#foo a'))" /></li>
-<li><input type="submit" value="document.getElementsBySelector('#foo a.blog')" onclick="show(document.getElementsBySelector('#foo a.blog'))" /></li>
-<li><input type="submit" value="document.getElementsBySelector('.blog')" onclick="show(document.getElementsBySelector('.blog'))" /></li>
-<li><input type="submit" value="document.getElementsBySelector('a[href^=&quot;http://www&quot;]')" onclick="show(document.getElementsBySelector('a[href*=&quot;http://www&quot;]'))" /></li>
-<li><input type="submit" value="document.getElementsBySelector('a[href$=&quot;org/&quot;]')" onclick="show(document.getElementsBySelector('a[href$=&quot;org/&quot;]'))" /> (fails in Opera 7)</li>
-<li><input type="submit" value="document.getElementsBySelector('a[href*=&quot;google&quot;]')" onclick="show(document.getElementsBySelector('a[href*=&quot;google&quot;]'))" /></li>
-<li><input type="submit" value="document.getElementsBySelector('a[rel=&quot;bookmark&quot;]')" onclick="show(document.getElementsBySelector('a[rel=&quot;bookmark&quot;]'))" /></li>
-<li><input type="submit" value="document.getElementsBySelector('a[title]')" onclick="show(document.getElementsBySelector('a[title]'))" /></li>
-</ul>
-</form>
-</body>
-</html>
diff --git a/framework/Web/Javascripts/tests/index.html b/framework/Web/Javascripts/tests/index.html
deleted file mode 100644
index 2ca89cc6..00000000
--- a/framework/Web/Javascripts/tests/index.html
+++ /dev/null
@@ -1,138 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
-<html>
-<head>
-<HTA:APPLICATION ID="SeleniumTestRunner" APPLICATIONNAME="Selenium" >
-<!-- the previous line is only relevant if you rename this
- file to "TestRunner.hta" -->
-
-<!-- The copyright notice and other comments have been moved to after the HTA declaration,
- to work-around a bug in IE on Win2K whereby the HTA application doesn't function correctly -->
-<!--
-Copyright 2004 ThoughtWorks, Inc
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<meta content="text/html; charset=ISO-8859-1" http-equiv="content-type" />
-
-<title>Selenium Functional Test Runner</title>
-<script language="JavaScript" type="text/javascript" src="../../../tests/selenium/html-xpath/html-xpath-patched.js"></script>
-<script language="JavaScript" type="text/javascript" src="../../../tests/selenium/selenium-browserbot.js"></script>
-<script language="JavaScript" type="text/javascript" src="../../../tests/selenium/selenium-api.js"></script>
-<script language="JavaScript" type="text/javascript" src="../../../tests/selenium/selenium-commandhandlers.js"></script>
-<script language="JavaScript" type="text/javascript" src="../../../tests/selenium/selenium-executionloop.js"></script>
-<script language="JavaScript" type="text/javascript" src="../../../tests/selenium/selenium-fitrunner.js"></script>
-<script language="JavaScript" type="text/javascript" src="../../../tests/selenium/selenium-logging.js"></script>
-<script language="JavaScript" type="text/javascript" src="../../../tests/selenium/htmlutils.js"></script>
-<script language="JavaScript" type="text/javascript" src="../../../tests/selenium/xpath.js"></script>
-<script language="JavaScript" type="text/javascript">
- function openDomViewer() {
- var autFrame = document.getElementById('myiframe');
- var autFrameDocument = getIframeDocument(autFrame);
- var domViewer = window.open('../../../tests/selenium/domviewer.html');
- domViewer.rootDocument = autFrameDocument;
- return false;
- }
-</script>
-<link rel="stylesheet" type="text/css" href="../../../tests/selenium/selenium.css" />
-</head>
-
-<body onload="start();">
-
- <table class="layout">
- <form action="" name="controlPanel">
-
- <!-- Suite, Test, Control Panel -->
-
- <tr class="selenium">
- <td width="25%" height="30%" rowspan="2"><iframe name="testSuiteFrame" id="testSuiteFrame" src="test_scripts/TestSuite.html"></iframe></td>
- <td width="50%" height="30%" rowspan="2"><iframe name="testFrame" id="testFrame"></iframe></td>
- <th width="25%" height="1" class="header">
- <h1><a href="http://selenium.thoughtworks.com" title="The Selenium Project">Selenium</a> TestRunner</h1>
- </th>
- </tr>
-
- <tr class="selenium">
- <td width="25%" height="30%" id="controlPanel">
-
- <table id="controls">
- <tr>
- <td>
- <b>Run:</b>
- <button type="button" id="runTest" onclick="runSingleTest();"><em>Selected</em> Test</button>
- <button type="button" id="runSuite" onclick="startTestSuite();"><strong>All</strong> Tests</button>
- </td>
- </tr>
- <tr>
- <td>
- <b>Mode:</b>
- <label><input id="modeRun" type="radio" name="runMode" value="0" checked="checked"/>Run</label>
- <label><input id="modeWalk" type="radio" name="runMode" value="500" />Walk</label>
- <label><input id="modeStep" type="radio" name="runMode" value="-1" />Step</label>
- </td>
- </tr>
- <tr>
- <td>
- <button type="button" id="domViewer1" onclick="openDomViewer();">View DOM</button>
- <button type="button" id="continueTest" disabled="disabled">Next/Continue</button>
- </td>
- </tr>
- </table>
-
- <table id="stats" align="center">
- <tr>
- <td colspan="2" align="right">Elapsed:</td>
- <td id="elapsedTime" colspan="2">00.00</td>
- </tr>
- <tr>
- <th colspan="2">Tests</th>
- <th colspan="2">Commands</th>
- </tr>
- <tr>
- <td class="count" id="testRuns">0</td>
- <td>run</td>
- <td class="count" id="commandPasses">0</td>
- <td>passed</td>
- </tr>
- <tr>
- <td class="count" id="testFailures">0</td>
- <td>failed</td>
- <td class="count" id="commandFailures">0</td>
- <td>failed</td>
- </tr>
- <tr>
- <td colspan="2"></td>
- <td class="count" id="commandErrors">0</td>
- <td>incomplete</td>
- </tr>
- </table>
- </td>
- </tr>
-
- <!-- AUT -->
-
- <tr>
- <td colspan="3" height="70%"><iframe name="myiframe" id="myiframe" src="../../../tests/selenium/TestRunner-splash.html"></iframe></td>
- </tr>
- </form>
- </table>
-
- <div id="logging-console">
- <h1>Javascript Log Console (<a id="closeLog" href="javascript:LOG.hide()">Close</a> <a href="javascript:LOG.clear();LOG.hide();">Clear</a>)</h1>
- <ul id="log-list"/>
- </div>
- <script language="javascript">
- LOG = new Logger(LEVEL_WARN);
- LOG.hide();
- </script>
-</body>
-</html>
diff --git a/framework/Web/Javascripts/tests/librarytest.html b/framework/Web/Javascripts/tests/librarytest.html
deleted file mode 100644
index 14a024a2..00000000
--- a/framework/Web/Javascripts/tests/librarytest.html
+++ /dev/null
@@ -1,49 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<title>Test all compressed JS</title>
-<script type="text/javascript" src="../prototype/prototype.js"></script>
-<script type="text/javascript" src="../prototype/compat.js"></script>
-<script type="text/javascript" src="../prototype/base.js"></script>
-<script type="text/javascript" src="../extended/base.js"></script>
-<script type="text/javascript" src="../extended/string.js"></script>
-<script type="text/javascript" src="../extended/util.js"></script>
-<script type="text/javascript" src="../extended/array.js"></script>
-<script type="text/javascript" src="../extended/functional.js"></script>
-<script type="text/javascript" src="../prado/prado.js"></script>
-
-<script type="text/javascript" src="../prototype/dom.js"></script>
-<script type="text/javascript" src="../extended/dom.js"></script>
-<script type="text/javascript" src="../prototype/event.js"></script>
-<script type="text/javascript" src="../extended/event.js"></script>
-<script type="text/javascript" src="../prototype/form.js"></script>
-<script type="text/javascript" src="../prototype/position.js"></script>
-<script type="text/javascript" src="../prototype/string.js"></script>
-<script type="text/javascript" src="../extra/getElementsBySelector.js"></script>
-<script type="text/javascript" src="../extra/behaviour.js"></script>
-
-
-<script type="text/javascript" src="../../effects.js"></script>
-<!--<script type="text/javascript" src="../../rico.js"></script>-->
-<script type="text/javascript" src="../../template.js"></script>
-
-<script type="text/javascript" src="../prado/validation.js"></script>
-<script type="text/javascript" src="../prado/validators.js"></script>
-
-
-<script type="text/javascript">
-
- var a = [ "one", "two"];
- for(var i in a)
- alert(i+":"+a[i]);
-
- alert(a.contains("two"));
-</script>
-
-</head>
-<body>
-OK
-</body>
-</html>
diff --git a/framework/Web/Javascripts/tests/test_scripts/TestRequiredFieldValidator.html b/framework/Web/Javascripts/tests/test_scripts/TestRequiredFieldValidator.html
deleted file mode 100644
index f9895a23..00000000
--- a/framework/Web/Javascripts/tests/test_scripts/TestRequiredFieldValidator.html
+++ /dev/null
@@ -1,85 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><!--Copyright 2004 ThoughtWorks, Inc Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.-->
-<html>
-<head>
-<title>Test Open</title>
- <meta content="text/html; charset=ISO-8859-1" http-equiv="content-type">
-</head>
-<body>
-<table cellpadding="1" cellspacing="1" border="1" id=TABLE1>
- <tbody>
- <tr>
- <td rowspan="1" colspan="3">Test Open<br>
- </td>
- </tr>
- <tr>
- <td>open</td>
- <td>../tests/RequiredFieldValidator.html</td>
- <td>&nbsp;</td>
- </tr>
- <tr>
- <td>assertLocation</td>
- <td>RequiredFieldValidator.html</td>
- <td>&nbsp;</td>
- </tr>
- <tr>
- <td>assertTextPresent</td>
- <td> RequiredFieldValidator Tests
- </td>
- <td>&nbsp;</td>
- </tr>
- <tr>
- <td>assertNotVisible</td>
- <td>validator1</td>
- <td></td></tr>
- <tr>
- <td>assertNotVisible</td>
- <td>validator2</td>
- <td></td></tr>
- <tr>
- <td>click</td>
- <td>submit1</td>
- <td></td></tr>
- <tr>
- <td>assertVisible</td>
- <td>validator1</td>
- <td></td></tr>
- <tr>
- <td>assertVisible</td>
- <td>validator2</td>
- <td></td></tr>
- <tr>
- <td>type</td>
- <td>text1</td>
- <td>testing</td></tr>
- <tr>
- <td>click</td>
- <td>submit1</td>
- <td></td></tr>
- <tr>
- <td>assertNotVisible</td>
- <td>validator1</td>
- <td></td></tr>
- <tr>
- <td>click</td>
- <td>submit2</td>
- <td></td></tr>
- <tr>
- <td>assertNotVisible</td>
- <td>validator1</td>
- <td></td></tr>
- <tr>
- <td>assertNotVisible</td>
- <td>validator2</td>
- <td></td></tr>
- <tr>
- <td>assertVisible</td>
- <td>validator3</td>
- <td></td></tr>
- <tr>
- <td>assertVisible</td>
- <td>validator4</td>
- <td></td></tr>
- </tbody>
-</table>
-</body>
-</html> \ No newline at end of file
diff --git a/framework/Web/Javascripts/tests/test_scripts/TestSuite.html b/framework/Web/Javascripts/tests/test_scripts/TestSuite.html
deleted file mode 100644
index 9b8b8918..00000000
--- a/framework/Web/Javascripts/tests/test_scripts/TestSuite.html
+++ /dev/null
@@ -1,36 +0,0 @@
-<!--
-Copyright 2004 ThoughtWorks, Inc
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<html>
-<head>
-<meta content="text/html; charset=ISO-8859-1"
-http-equiv="content-type">
-<title>Test Suite</title>
-
-</head>
-
-<body>
-
-<table cellpadding="1"
- cellspacing="1"
- border="1">
- <tbody>
- <tr><td><b>Test Suite</b></td></tr>
- <tr><td><a href="./TestRequiredFieldValidator.html">TestTRequiredFieldValidator</a></td></tr>
- </tbody>
- </table>
-
-</body>
-</html>