Author: pyaschenko
Date: 2010-10-22 11:24:57 -0400 (Fri, 22 Oct 2010)
New Revision: 19655
Added:
branches/RF-8742/ui/validator/ui/src/main/resources/
branches/RF-8742/ui/validator/ui/src/main/resources/META-INF/
branches/RF-8742/ui/validator/ui/src/main/resources/META-INF/resources/
branches/RF-8742/ui/validator/ui/src/main/resources/META-INF/resources/org.richfaces/
branches/RF-8742/ui/validator/ui/src/main/resources/META-INF/resources/org.richfaces/converter-number.js
branches/RF-8742/ui/validator/ui/src/main/resources/META-INF/resources/org.richfaces/length.js
branches/RF-8742/ui/validator/ui/src/main/resources/META-INF/resources/org.richfaces/richfaces-csv.js
branches/RF-8742/ui/validator/ui/src/main/resources/META-INF/resources/org.richfaces/richfaces.js
branches/RF-8742/ui/validator/ui/src/main/resources/META-INF/resources/org.richfaces/validator-length.js
branches/RF-8742/ui/validator/ui/src/test/java/org/richfaces/convert/NumberConverterTest.java
Removed:
branches/RF-8742/ui/validator/impl/src/main/resources/META-INF/resources/
Modified:
branches/RF-8742/ui/validator/ui/pom.xml
branches/RF-8742/ui/validator/ui/src/test/java/org/richfaces/convert/BaseConverterTest.java
branches/RF-8742/ui/validator/ui/src/test/java/org/richfaces/convert/DateTimeConverterTest.java
branches/RF-8742/ui/validator/ui/src/test/java/org/richfaces/renderkit/html/RendererGetClientSideScriptTest.java
branches/RF-8742/ui/validator/ui/src/test/java/org/richfaces/renderkit/html/RendererGetComponentScriptTest.java
branches/RF-8742/ui/validator/ui/src/test/resources/org/richfaces/convert/test.xhtml
Log:
https://jira.jboss.org/browse/RF-8742
https://jira.jboss.org/browse/RF-9215
Modified: branches/RF-8742/ui/validator/ui/pom.xml
===================================================================
--- branches/RF-8742/ui/validator/ui/pom.xml 2010-10-22 15:08:12 UTC (rev 19654)
+++ branches/RF-8742/ui/validator/ui/pom.xml 2010-10-22 15:24:57 UTC (rev 19655)
@@ -84,7 +84,24 @@
<scope>test</scope>
</dependency>
<dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <version>1.5.11</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-simple</artifactId>
+ <version>1.5.11</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
<groupId>org.jboss.test-jsf</groupId>
+ <artifactId>jsf-test-jetty</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.test-jsf</groupId>
<artifactId>jsf-mock</artifactId>
<version>1.0.5-SNAPSHOT</version>
<scope>test</scope>
Added:
branches/RF-8742/ui/validator/ui/src/main/resources/META-INF/resources/org.richfaces/converter-number.js
===================================================================
---
branches/RF-8742/ui/validator/ui/src/main/resources/META-INF/resources/org.richfaces/converter-number.js
(rev 0)
+++
branches/RF-8742/ui/validator/ui/src/main/resources/META-INF/resources/org.richfaces/converter-number.js 2010-10-22
15:24:57 UTC (rev 19655)
@@ -0,0 +1,13 @@
+RichFaces.csv.addConverter({"number":
+(function(rf) {
+ return function (value, params) {
+ var result;
+ if (isNaN(value)) {
+ throw rf.csv.getMessage(params.customMessages, 'NumberConverter.isNaN',
[value]);
+ } else {
+ result = parseInt(value);
+ }
+ return result;
+ }
+})(window.RichFaces || (window.RichFaces={}))
+});
\ No newline at end of file
Added:
branches/RF-8742/ui/validator/ui/src/main/resources/META-INF/resources/org.richfaces/length.js
===================================================================
---
branches/RF-8742/ui/validator/ui/src/main/resources/META-INF/resources/org.richfaces/length.js
(rev 0)
+++
branches/RF-8742/ui/validator/ui/src/main/resources/META-INF/resources/org.richfaces/length.js 2010-10-22
15:24:57 UTC (rev 19655)
@@ -0,0 +1,78 @@
+(function($, rf) {
+
+ rf.csv = rf.csv || {};
+
+ var _messages = {};
+ var _validators = {};
+ var _converters = {};
+
+ var RE_MESSAGE_PATTERN = /\{(\d+)\}/g;
+
+ $.extend(rf.csv, {
+ // Messages API
+ addMessage: function (messagesObject) {
+ $.extend(_messages, messagesObject);
+ },
+ getMessage: function(customMessages, id, values) {
+ var message = (customMessages && customMessages[id]) || _messages[id] ||
"";
+ if (message) {
+ var msgObject =
message.replace(RE_MESSAGE_PATTERN,"\n$1\n").split("\n");
+ var value;
+ for (var i=1; i<msgObject.length; i+=2) {
+ value = values[msgObject[i]];
+ msgObject[i] = typeof value == "undefined" ? "" : value;
+ }
+ message = msgObject.join('');
+ }
+ return message;
+ },
+ // Validators API
+ addValidator: function (validatorFunctions) {
+ $.extend(_validators, validatorFunctions);
+ },
+ validate: function (event, id, validatorList, messageComponentList, options) {
+ var value;
+ var element = rf.getDomElement(id);
+ if (element.value) {
+ value = element.value;
+ } else {
+ var component = rf.$(element);
+ value = component && typeof component["getValue"] ==
"function" ? component.getValue() : "";
+ }
+ var result;
+ var messageComponentsUpdated = false;
+ var validatorFunction;
+ for (var validator in validatorList) {
+ validatorFunction = _validators[validator];
+ if (validatorFunction) {
+ result = validatorFunction(value, validatorList[validator]);
+ }
+ if (result && result.length>0) {
+ messageComponentsUpdated = true;
+ //updateMessageComponents(messageElementIds, result);
+ alert(result);
+ break;
+ }
+ }
+ !messageComponentsUpdated && alert("no message from
validators");//updateMessageComponents(messageElementIds, "");
+ },
+ addFormValidators: function (formId, callValidatorFunctions) {
+
+ }
+ });
+})(jQuery, window.RichFaces || (window.RichFaces={}));
+
+
+RichFaces.csv.addValidator({"length":
+(function(rf) {
+ return function (value, params) {
+ var result = "";
+ if (value.length<params.min) {
+ result = rf.csv.getMessage(params.customMessages, 'LengthValidator.MINIMUM',
[params.min,value]);
+ } else if (value.length>params.max){
+ result = rf.csv.getMessage(params.customMessages, 'LengthValidator.MAXIMUM',
[params.max,value]);
+ }
+ return result;
+ }
+})(window.RichFaces || (window.RichFaces={}))
+});
\ No newline at end of file
Added:
branches/RF-8742/ui/validator/ui/src/main/resources/META-INF/resources/org.richfaces/richfaces-csv.js
===================================================================
---
branches/RF-8742/ui/validator/ui/src/main/resources/META-INF/resources/org.richfaces/richfaces-csv.js
(rev 0)
+++
branches/RF-8742/ui/validator/ui/src/main/resources/META-INF/resources/org.richfaces/richfaces-csv.js 2010-10-22
15:24:57 UTC (rev 19655)
@@ -0,0 +1,144 @@
+(function($, rf) {
+
+ rf.csv = rf.csv || {};
+
+ var _messages = {};
+ var _validators = {};
+ var _converters = {};
+
+ var RE_MESSAGE_PATTERN = /\{(\d+)\}/g;
+
+ $.extend(rf.csv, {
+ // Messages API
+ addMessage: function (messagesObject) {
+ $.extend(_messages, messagesObject);
+ },
+ getMessage: function(customMessages, id, values) {
+ var message = (customMessages && customMessages[id]) || _messages[id] ||
"";
+ if (message) {
+ var msgObject =
message.replace(RE_MESSAGE_PATTERN,"\n$1\n").split("\n");
+ var value;
+ for (var i=1; i<msgObject.length; i+=2) {
+ value = values[msgObject[i]];
+ msgObject[i] = typeof value == "undefined" ? "" : value;
+ }
+ message = msgObject.join('');
+ }
+ return message;
+ },
+ sendMessage: function (componentId, message) {
+ //rf.messageManager.send(componentId, message);
+ //rf.Event.fire("onMessage.RichFaces.componentId");
+ },
+ // Converters API
+ addConverter: function (converterFunctions) {
+ $.extend(_converters, converterFunctions);
+ },
+ getConverter: function (name) {
+ return _converters[name];
+ },
+ // Validators API
+ addValidator: function (validatorFunctions) {
+ $.extend(_validators, validatorFunctions);
+ },
+ validate: function (event, id, converter, validatorList) {
+ var value;
+ var element = rf.getDomElement(id);
+ if (element.value) {
+ value = element.value;
+ } else {
+ var component = rf.$(element);
+ // TODO: add getValue to baseComponent and change jsdocs
+ value = component && typeof component["getValue"] ==
"function" ? component.getValue() : "";
+ }
+ if (converter) {
+ try {
+ value = getConverter([converter.name])(value, converter.options);
+ } catch (e){
+ sendMessage(id, id+":"+e);
+ return false;
+ }
+ }
+ if (!validatorList) return true;
+ var validatorFunction;
+ var result;
+ for (var validator in validatorList) {
+ validatorFunction = _validators[validator];
+ if (validatorFunction) {
+ result = validatorFunction(value, validatorList[validator]);
+ }
+ if (result && result.length>0) {
+ sendMessage(id, id+":"+result);
+ return false;
+ }
+ }
+ return true;
+ },
+ addFormValidators: function (formId, callValidatorFunctions) {
+
+ }
+ });
+
+ /*
+ // component ids hash that can send messages
+ // each hash item contains array of message component id that receive messages from the
component
+ _componentIds = {};
+ // array of message component id that will receive messages from all components
+ _messageComponentIds = {};
+
+ var messageDispatchers = {};
+ var addDispatcher = function (dispatcherId) {
+ };
+ var removeDispatcher: function (dispatcherId) {
+ };
+
+ rf.MessageDispatcher = function(id) {
+ this.id = id;
+ };
+ rf.BaseComponent.extend(rf.MessageDispatcher);
+
+ $.extend(rf.MessageDispatcher.prototype, {
+ register: function (messageComponentId, componentIds) {
+ if (!componentIds || componentIds.length==0) {
+ // global message listener
+ _messageComponents.push(messageComponentId);
+ }
+ var messageComponents;
+ for (var i=0;i<componentIds.length;i++) {
+ messageComponents = _components[componentIds[i]];
+ if (!messageComponents) {
+ messageComponents = _components[componentIds[i]] = [];
+ }
+ messageComponents.push(messageComponentId);
+ }
+ },
+ unregister: function (messageComponentId) {
+ var messageComponents;
+ for (var i=0;i<_components.length;i++) {
+ messageComponents = _components[i];
+ if (!messageComponents) {
+ messageComponents = _components[componentIds[i]] = [];
+ }
+ messageComponents.push(messageComponentId);
+ }
+ },
+ send: function (componentId, message) {
+ var messageComponents = _components[componentId];
+ if (messageComponents) {
+ for (var i=0;i<messageComponents.length;i++) {
+ rf.$(messageComponents[id]).update(message);
+ }
+ }
+ }
+ });
+ */
+
+ /*
+ * message.constructor () {
+ * rf.Event.bindById(this.id, "onMessage:RichFaces.global", onMessage );
+ * rf.Event.bindById(this.id, "onMessage.RichFaces.componentId", onMessage
);
+ * }
+ *
+ */
+
+})(jQuery, window.RichFaces || (window.RichFaces={}));
\ No newline at end of file
Added:
branches/RF-8742/ui/validator/ui/src/main/resources/META-INF/resources/org.richfaces/richfaces.js
===================================================================
---
branches/RF-8742/ui/validator/ui/src/main/resources/META-INF/resources/org.richfaces/richfaces.js
(rev 0)
+++
branches/RF-8742/ui/validator/ui/src/main/resources/META-INF/resources/org.richfaces/richfaces.js 2010-10-22
15:24:57 UTC (rev 19655)
@@ -0,0 +1,749 @@
+
+if (!window.RichFaces) {
+ /**
+ * Global object container for RichFaces API.
+ * All classes should be defined here.
+ * @class
+ * @name RichFaces
+ * @static
+ *
+ * */
+ window.RichFaces = {};
+}
+
+(function(jQuery, richfaces) {
+
+ // get DOM element by id or DOM element or jQuery object
+ richfaces.getDomElement = function (source) {
+ var type = typeof source;
+ var element;
+ if (type == "string") {
+ // id
+ element = document.getElementById(source);
+ } else if (type == "object") {
+ if (source.nodeType) {
+ // DOM element
+ element = source;
+ } else
+ if (source instanceof jQuery) {
+ // jQuery object
+ element = source.get(0);
+ }
+ }
+ return element;
+ }
+
+ // get RichFaces component object by component id or DOM element or jQuery object
+ richfaces.$ = function (source) {
+ var element = richfaces.getDomElement(source);
+
+ if (element) {
+ return (element["richfaces"] || {})["component"];
+ }
+ }
+
+ // find component and call his method
+ richfaces.invokeMethod = function(source, method) {
+ var c = richfaces.$(source);
+ if (c) {
+ var f = c[method];
+ if (typeof f == "function") {
+ return f.apply(c, Array.prototype.slice.call(arguments, 2));
+ }
+ }
+ }
+
+ //dom cleaner
+ richfaces.cleanDom = function(source) {
+ var e = (typeof source == "string") ? document.getElementById(source) :
jQuery('body').get(0);
+ if (e) {
+ var elements = e.getElementsByTagName("*");
+ if (elements.length) {
+ jQuery.cleanData(elements);
+ jQuery.cleanData([e]);
+ jQuery.each(elements, function(index) {
+ richfaces.invokeMethod(this, "destroy");
+ });
+ richfaces.invokeMethod(e, "destroy");
+ }
+ }
+ }
+
+ //form.js
+ richfaces.submitForm = function(form, parameters, target) {
+ if (typeof form === "string") { form = jQuery(form) };
+ var initialTarget = form.attr("target");
+ var parameterInputs = new Array();
+ try {
+ form.attr("target", target);
+
+ if (parameters) {
+ for (var parameterName in parameters) {
+ var parameterValue = parameters[parameterName];
+
+ var input = jQuery("input[name='" + parameterName +
"']", form);
+ if (input.length == 0) {
+ var newInput = jQuery("<input />").attr({type: 'hidden',
name: parameterName, value: parameterValue});
+ if (parameterName === 'javax.faces.portletbridge.STATE_ID' /* fix for
fileUpload in portlets */) {
+ input = newInput.prependTo(form);
+ } else {
+ input = newInput.appendTo(form);
+ }
+ } else {
+ input.val(parameterValue);
+ }
+
+ input.each(function() {parameterInputs.push(this)});
+ }
+ }
+
+ //TODO: inline onsubmit handler is not triggered -
http://dev.jquery.com/ticket/4930
+ form.trigger("submit");
+ } finally {
+ form.attr("target", initialTarget);
+ jQuery(parameterInputs).remove();
+ }
+ };
+ //
+
+ //utils.js
+ jQuery.fn.toXML = function () {
+ var out = '';
+
+ if (this.length > 0) {
+ if (typeof XMLSerializer == 'function' ||
+ typeof XMLSerializer == 'object') {
+
+ var xs = new XMLSerializer();
+ this.each(function() { out += xs.serializeToString(this); });
+ } else if (this[0].xml !== undefined) {
+ this.each(function() { out += this.xml; });
+ } else {
+ this.each( function() { out += this; } );
+ }
+ }
+
+ return out;
+ };
+
+ //there is the same pattern in server-side code:
+ //org.ajax4jsf.javascript.ScriptUtils.escapeCSSMetachars(String)
+ var CSS_METACHARS_PATTERN = /([#;&,.+*~':"!^$\[\]()=>|\/])/g;
+
+ /**
+ * Escapes CSS meta-characters in string according to
+ * <a
href="http://api.jquery.com/category/selectors/">jQuery
selectors</a> document.
+ *
+ * @param s - string to escape meta-characters in
+ * @return string with meta-characters escaped
+ */
+ richfaces.escapeCSSMetachars = function(s) {
+ //TODO nick - cache results
+
+ return s.replace(CSS_METACHARS_PATTERN, "\\$1");
+ };
+
+ var logImpl;
+
+ richfaces.setLog = function(newLogImpl) {
+ logImpl = newLogImpl;
+ };
+
+ richfaces.log = {
+ debug: function(text) {
+ if (logImpl) {
+ logImpl.debug(text);
+ }
+ },
+
+ info: function(text) {
+ if (logImpl) {
+ logImpl.info(text);
+ }
+ },
+
+ warn: function(text) {
+ if (logImpl) {
+ logImpl.warn(text);
+ }
+ },
+
+ error: function(text) {
+ if (logImpl) {
+ logImpl.error(text);
+ }
+ },
+
+ setLevel: function(level) {
+ if (logImpl) {
+ logImpl.setLevel(level);
+ }
+ },
+
+ getLevel: function() {
+ if (logImpl) {
+ return logImpl.getLevel();
+ }
+ return 'info';
+ },
+
+ clear: function() {
+ if (logImpl) {
+ logImpl.clear();
+ }
+ }
+ };
+
+ /**
+ * Evaluates chained properties for the "base" object.
+ * For example, window.document.location is equivalent to
+ * "propertyNamesString" = "document.location" and "base"
= window
+ * Evaluation is safe, so it stops on the first null or undefined object
+ *
+ * @param propertyNamesArray - array of strings that contains names of the properties to
evaluate
+ * @param base - base object to evaluate properties on
+ * @return returns result of evaluation or empty string
+ */
+ richfaces.getValue = function(propertyNamesArray, base) {
+ var result = base;
+ var c = 0;
+ do {
+ result = result[propertyNamesArray[c++]];
+ } while (result && c != propertyNamesArray.length);
+
+ return result;
+ };
+
+ var VARIABLE_NAME_PATTERN_STRING = "[_A-Z,a-z]\\w*";
+ var VARIABLES_CHAIN = new
RegExp("^\\s*"+VARIABLE_NAME_PATTERN_STRING+"(?:\\s*\\.\\s*"+VARIABLE_NAME_PATTERN_STRING+")*\\s*$");
+ var DOT_SEPARATOR = /\s*\.\s*/;
+
+ richfaces.evalMacro = function(macro, base) {
+ var value = "";
+ // variable evaluation
+ if (VARIABLES_CHAIN.test(macro)) {
+ // object's variable evaluation
+ var propertyNamesArray = jQuery.trim(macro).split(DOT_SEPARATOR);
+ value = richfaces.getValue(propertyNamesArray, base);
+ if (!value) {
+ value = richfaces.getValue(propertyNamesArray, window);
+ }
+ } else {
+ //js string evaluation
+ try {
+ if (base.eval) {
+ value = base.eval(macro);
+ } else with (base) {
+ value = eval(macro) ;
+ }
+ } catch (e) {
+ richfaces.log.warn("Exception: " + e.message + "\n[" + macro +
"]");
+ }
+ }
+
+ if (typeof value == 'function') {
+ value = value(base);
+ }
+ //TODO 0 and false are also treated as null values
+ return value || "";
+ };
+
+ var ALPHA_NUMERIC_MULTI_CHAR_REGEXP = /^\w+$/;
+
+ richfaces.interpolate = function (placeholders, context) {
+ var contextVarsArray = new Array();
+ for (var contextVar in context) {
+ if (ALPHA_NUMERIC_MULTI_CHAR_REGEXP.test(contextVar)) {
+ //guarantees that no escaping for the below RegExp is necessary
+ contextVarsArray.push(contextVar);
+ }
+ }
+
+ var regexp = new RegExp("\\{(" + contextVarsArray.join("|") +
")\\}", "g");
+ return placeholders.replace(regexp, function(str, contextVar) {return
context[contextVar];});
+ };
+
+ richfaces.clonePosition = function(element, baseElement, positioning, offset) {
+
+ };
+ //
+
+ var pollTracker = {};
+ richfaces.startPoll = function(options) {
+ var pollId = options.pollId;
+ var interval = options.pollinterval;
+ var ontimer = options.ontimer;
+ richfaces.stopPoll(pollId);
+
+ richfaces.setZeroRequestDelay(options);
+
+ pollTracker[pollId] = window.setTimeout(function(){
+ var pollElement = document.getElementById(pollId);
+ try {
+ ontimer.call(pollElement || window);
+ richfaces.startPoll(options);
+ } catch (e) {
+ // TODO: handle exception
+ }
+ },interval);
+ };
+
+ richfaces.stopPoll = function(id) {
+ if(pollTracker[id]){
+ window.clearTimeout(pollTracker[id]);
+ delete pollTracker[id];
+ }
+ };
+
+ var pushTracker = {};
+
+ richfaces.startPush = function(options) {
+ var clientId = options.clientId;
+ var pushResourceUrl = options.pushResourceUrl;
+ var pushId = options.pushId;
+ var interval = options.interval;
+ var ondataavailable = options.ondataavailable;
+ richfaces.setZeroRequestDelay(options);
+
+ richfaces.stopPush(pushId);
+
+ pushTracker[pushId] = setTimeout(function() { // TODO: define this function in
richfaces object to avoid definition every time when call startPush
+ var ajaxOptions = {
+ type: "HEAD",
+ //TODO - encodeURIComponent; URL sessionId handling check
+ //TODO - add pushUri supports
+ url: pushResourceUrl + "?id=" + pushId,
+ dataType: "text",
+ complete: function(xhr) {
+ var isPushActive = !!pushTracker[pushId];
+
+ //TODO may someone wish to stop push from dataavailable handler?
+ delete pushTracker[pushId];
+
+ if (xhr.status == 200 && xhr.getResponseHeader("Ajax-Push-Status")
== "READY") {
+ var pushElement = document.getElementById(clientId);
+ try {
+ ondataavailable.call(pushElement || window);
+ } catch (e) {
+ // TODO: handle exception
+ }
+ }
+
+ if (isPushActive) {
+ richfaces.startPush(options);
+ }
+ }
+ };
+
+ if (options.timeout) {
+ ajaxOptions.timeout = options.timeout;
+ }
+
+ jQuery.ajax(ajaxOptions);
+ }, interval);
+ };
+
+ richfaces.stopPush = function(id) {
+ if (pushTracker[id]){
+ window.clearTimeout(pushTracker[id]);
+ delete pushTracker[id];
+ }
+ };
+
+ var jsfEventsAdapterEventNames = {
+ event: {
+ 'begin': ['begin'],
+ 'complete': ['beforedomupdate'],
+ 'success': ['success', 'complete']
+ },
+ error: ['error', 'complete']
+ };
+
+ var getExtensionResponseElement = function(responseXML) {
+ return jQuery("partial-response > extension#org\\.richfaces\\.extension",
responseXML);
+ };
+
+ var JSON_STRING_START = /^\s*(\[|\{)/;
+
+ var getJSONData = function(extensionElement, elementName) {
+ var dataString = jQuery.trim(extensionElement.children(elementName).text());
+ extensionElement.end();
+ try {
+ if (dataString) {
+ if (JSON_STRING_START.test(dataString)) {
+ return jQuery.parseJSON(dataString);
+ } else {
+ var parsedData = jQuery.parseJSON("{\"root\": " + dataString +
"}");
+ return parsedData.root;
+ }
+ }
+ } catch (e) {
+ richfaces.log.warn("Error evaluating JSON data from element <" +
elementName + ">: " + e.message);
+ }
+ return null;
+ };
+
+ richfaces.createJSFEventsAdapter = function(handlers) {
+ //hash of handlers
+ //supported are:
+ // - begin
+ // - beforedomupdate
+ // - success
+ // - error
+ // - complete
+ handlers = handlers || {};
+
+ return function(eventData) {
+ var source = eventData.source;
+ //that's request status, not status control data
+ var status = eventData.status;
+ var type = eventData.type;
+
+ var typeHandlers = jsfEventsAdapterEventNames[type];
+ var handlerNames = (typeHandlers || {})[status] || typeHandlers;
+
+ if (handlerNames) {
+ for (var i = 0; i < handlerNames.length; i++) {
+ var eventType = handlerNames[i];
+ var handler = handlers[eventType];
+ if (handler) {
+ var event = {};
+ jQuery.extend(event, eventData);
+ event.type = eventType;
+ if (type != 'error') {
+ delete event.status;
+
+ if (event.responseXML) {
+ var xml = getExtensionResponseElement(event.responseXML);
+ var data = getJSONData(xml, "data");
+ var componentData = getJSONData(xml, "componentData");
+
+ event.data = data;
+ event.componentData = componentData || {};
+ }
+ }
+
+ handler.call(source, event);
+ }
+ }
+ }
+ };
+ };
+
+ var setGlobalStatusNameVariable = function(statusName) {
+ //TODO: parallel requests
+ if (statusName) {
+ richfaces['statusName'] = statusName;
+ } else {
+ delete richfaces['statusName'];
+ }
+ }
+
+ richfaces.setZeroRequestDelay = function(options) {
+ if (typeof options.requestDelay == "undefined") {
+ options.requestDelay = 0;
+ }
+ };
+
+ var getGlobalStatusNameVariable = function() {
+ return richfaces.statusName;
+ }
+
+ var chain = function() {
+ var functions = arguments;
+ if (functions.length == 1) {
+ return functions[0];
+ } else {
+ return function() {
+ var callResult;
+ for (var i = 0; i < functions.length; i++) {
+ var f = functions[i];
+ callResult = f.apply(this, arguments);
+ }
+
+ return callResult;
+ };
+ }
+ };
+
+ /**
+ * curry (g, a) (b) -> g(a, b)
+ */
+ var curry = function(g, a) {
+ var _g = g;
+ var _a = a;
+
+ return function(b) {
+ _g(_a, b);
+ };
+ };
+
+ var createEventHandler = function(handlerCode) {
+ if (handlerCode) {
+ return new Function("event", handlerCode);
+ }
+
+ return null;
+ };
+
+ //TODO take events just from .java code using EL-expression
+ var AJAX_EVENTS = (function() {
+ var serverEventHandler = function(clientHandler, event) {
+ var xml = getExtensionResponseElement(event.responseXML);
+
+ var serverHandler = createEventHandler(xml.children(event.type).text());
+ xml.end();
+
+ if (clientHandler) {
+ clientHandler.call(window, event);
+ }
+
+ if (serverHandler) {
+ serverHandler.call(window, event);
+ }
+ };
+
+ return {
+ 'begin': null,
+ 'complete': serverEventHandler,
+ 'beforedomupdate': serverEventHandler
+ }
+ }());
+
+ richfaces.ajax = function(source, event, options) {
+ var sourceId = (typeof source == 'object' && source.id) ? source.id :
source;
+
+ options = options || {};
+
+ parameters = options.parameters || {}; // TODO: change "parameters" to
"richfaces.ajax.params"
+ parameters.execute = "@component";
+ parameters.render = "@component";
+
+ if (!parameters["org.richfaces.ajax.component"]) {
+ parameters["org.richfaces.ajax.component"] = sourceId;
+ }
+
+ var eventHandlers;
+
+ for (var eventName in AJAX_EVENTS) {
+ var handlerCode = options[eventName];
+ var handler = typeof handlerCode == "function" ? handlerCode :
createEventHandler(handlerCode);
+
+ var serverHandler = AJAX_EVENTS[eventName];
+ if (serverHandler) {
+ handler = curry(serverHandler, handler);
+ }
+
+ if (handler) {
+ eventHandlers = eventHandlers || {};
+ eventHandlers[eventName] = handler;
+ }
+ }
+
+ if (options.status) {
+ var namedStatusEventHandler = function() {
setGlobalStatusNameVariable(options.status); };
+
+ //TODO add support for options.submit
+ eventHandlers = eventHandlers || {};
+ if (eventHandlers.begin) {
+ eventHandlers.begin = chain(namedStatusEventHandler, eventHandlers.begin);
+ } else {
+ eventHandlers.begin = namedStatusEventHandler;
+ }
+ }
+
+ if (options.incId) {
+ parameters[sourceId] = sourceId;
+ }
+
+ if (eventHandlers) {
+ var eventsAdapter = richfaces.createJSFEventsAdapter(eventHandlers);
+ parameters['onevent'] = eventsAdapter;
+ parameters['onerror'] = eventsAdapter;
+ }
+
+ if (richfaces.queue) {
+ parameters.queueId = options.queueId;
+ }
+
+ jsf.ajax.request(source, event, parameters);
+ };
+
+ var RICHFACES_AJAX_STATUS = "richfaces:ajaxStatus";
+
+ var getStatusDataAttributeName = function(statusName) {
+ return statusName ? (RICHFACES_AJAX_STATUS + "@" + statusName) :
RICHFACES_AJAX_STATUS;
+ };
+
+ var statusAjaxEventHandler = function(data, methodName) {
+ if (methodName) {
+ //global status name
+ var statusName = getGlobalStatusNameVariable();
+ var source = data.source;
+
+ var statusApplied = false;
+ var statusDataAttribute = getStatusDataAttributeName(statusName);
+
+ var statusContainers;
+ if (statusName) {
+ statusContainers = [jQuery(document)];
+ } else {
+ statusContainers = [jQuery(source).parents('form'), jQuery(document)];
+ }
+
+ for (var containerIdx = 0; containerIdx < statusContainers.length &&
!statusApplied;
+ containerIdx++) {
+
+ var statusContainer = statusContainers[containerIdx];
+ var statuses = statusContainer.data(statusDataAttribute);
+ if (statuses) {
+ for (var statusId in statuses) {
+ var status = statuses[statusId];
+ var result = status[methodName].apply(status, arguments);
+ if (result) {
+ statusApplied = true;
+ } else {
+ delete statuses[statusId];
+ }
+ }
+
+ if (!statusApplied) {
+ statusContainer.removeData(statusDataAttribute);
+ }
+ }
+ }
+ }
+ };
+
+ var initializeStatuses = function() {
+ var thisFunction = arguments.callee;
+ if (!thisFunction.initialized) {
+ thisFunction.initialized = true;
+
+ var jsfEventsListener = richfaces.createJSFEventsAdapter({
+ begin: function(event) { statusAjaxEventHandler(event, 'start'); },
+ error: function(event) { statusAjaxEventHandler(event, 'error'); },
+ success: function(event) { statusAjaxEventHandler(event, 'success'); },
+ complete: function() { setGlobalStatusNameVariable(null); }
+ });
+
+ jsf.ajax.addOnEvent(jsfEventsListener);
+ //TODO blocks default alert error handler
+ jsf.ajax.addOnError(jsfEventsListener);
+ }
+ };
+
+ richfaces.status = function(statusId, options) {
+ this.statusId = statusId;
+ this.options = options || {};
+ this.register();
+ };
+
+ jQuery.extend(richfaces.status.prototype, (function() {
+ //TODO - support for parallel requests
+
+ var getElement = function() {
+ var elt = document.getElementById(this.statusId);
+ return elt ? jQuery(elt) : null;
+ };
+
+ var showHide = function(selector) {
+ var element = getElement.call(this);
+ if (element) {
+ var statusElts = element.children();
+ statusElts.each(function() {
+ var t = jQuery(this);
+ t.css('display', t.is(selector) ? '': 'none');
+ });
+
+ return true;
+ }
+
+ return false;
+ };
+
+ return {
+ register: function() {
+ initializeStatuses();
+
+ var statusName = this.options.statusName;
+ var dataStatusAttribute = getStatusDataAttributeName(statusName);
+
+ var container;
+ if (statusName) {
+ container = jQuery(document);
+ } else {
+ container = getElement.call(this).parents('form');
+ if (container.length == 0) {
+ container = jQuery(document);
+ };
+ }
+
+ var statuses = container.data(dataStatusAttribute);
+ if (!statuses) {
+ statuses = {};
+ container.data(dataStatusAttribute, statuses);
+ }
+
+ statuses[this.statusId] = this;
+ },
+
+ start: function() {
+ if (this.options.onstart) {
+ this.options.onstart.apply(this, arguments);
+ }
+
+ return showHide.call(this, '.rich-status-start');
+ },
+
+ stop: function() {
+ if (this.options.onstop) {
+ this.options.onstop.apply(this, arguments);
+ }
+ },
+
+ success: function() {
+ if (this.options.onsuccess) {
+ this.options.onsuccess.apply(this, arguments);
+ }
+ this.stop();
+
+ return showHide.call(this, '.rich-status-stop');
+ },
+
+ error: function() {
+ if (this.options.onerror) {
+ this.options.onerror.apply(this, arguments);
+ }
+ this.stop();
+
+ return showHide.call(this, ':not(.rich-status-error) + .rich-status-stop,
.rich-status-error');
+ }
+ };
+ }()));
+
+ var ajaxOnComplete = function (data) {
+ var type = data.type;
+ var responseXML = data.responseXML;
+
+ if (data.type == 'event' && data.status == 'complete'
&& responseXML) {
+ var partialResponse = jQuery(responseXML).children("partial-response");
+ if (partialResponse && partialResponse.length) {
+ var elements = partialResponse.children('changes').children('update,
delete');
+ jQuery.each(elements, function () {
+ richfaces.cleanDom(jQuery(this).attr('id'));
+ });
+ }
+ }
+ };
+ // move this code to somewhere
+ if (typeof jsf != 'undefined') {
+ jsf.ajax.addOnEvent(ajaxOnComplete);
+ }
+ if (window.addEventListener) {
+ window.addEventListener("unload", richfaces.cleanDom, false);
+ } else {
+ window.attachEvent("onunload", richfaces.cleanDom);
+ }
+}(jQuery, RichFaces));
+
Added:
branches/RF-8742/ui/validator/ui/src/main/resources/META-INF/resources/org.richfaces/validator-length.js
===================================================================
---
branches/RF-8742/ui/validator/ui/src/main/resources/META-INF/resources/org.richfaces/validator-length.js
(rev 0)
+++
branches/RF-8742/ui/validator/ui/src/main/resources/META-INF/resources/org.richfaces/validator-length.js 2010-10-22
15:24:57 UTC (rev 19655)
@@ -0,0 +1,13 @@
+RichFaces.csv.addValidator({"length":
+(function(rf) {
+ return function (value, params) {
+ var result = "";
+ if (value.length<params.min) {
+ result = rf.csv.getMessage(params.customMessages, 'LengthValidator.MINIMUM',
[params.min,value]);
+ } else if (value.length>params.max){
+ result = rf.csv.getMessage(params.customMessages, 'LengthValidator.MAXIMUM',
[params.max,value]);
+ }
+ return result;
+ }
+})(window.RichFaces || (window.RichFaces={}))
+});
\ No newline at end of file
Modified:
branches/RF-8742/ui/validator/ui/src/test/java/org/richfaces/convert/BaseConverterTest.java
===================================================================
---
branches/RF-8742/ui/validator/ui/src/test/java/org/richfaces/convert/BaseConverterTest.java 2010-10-22
15:08:12 UTC (rev 19654)
+++
branches/RF-8742/ui/validator/ui/src/test/java/org/richfaces/convert/BaseConverterTest.java 2010-10-22
15:24:57 UTC (rev 19655)
@@ -46,6 +46,7 @@
import org.ajax4jsf.javascript.JSFunction;
import org.ajax4jsf.javascript.ScriptUtils;
import org.jboss.test.faces.htmlunit.HtmlUnitEnvironment;
+import org.jboss.test.faces.jetty.JettyServer;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
@@ -171,7 +172,10 @@
this.converterException = e;
}
- converterParametersString = ScriptUtils.toScript(attributes);
+ Map<String,Object> map = new HashMap<String,
Object>(attributes);
+ map.put("componentId", TEST_COMPONENT_LABEL);
+
+ converterParametersString = ScriptUtils.toScript(map);
}
}
@@ -196,7 +200,7 @@
public void setUp() throws Exception {
testBean = new TestBean();
- environment = new HtmlUnitEnvironment();
+ environment = new HtmlUnitEnvironment(new JettyServer());
environment.getServer().addResource("/test.xhtml",
BaseConverterTest.class.getResource("test.xhtml"));
environment.getServer().addResource("/resources/converter.js",
converterScriptName);
environment.getServer().addWebListener(new ServletRequestListener() {
Modified:
branches/RF-8742/ui/validator/ui/src/test/java/org/richfaces/convert/DateTimeConverterTest.java
===================================================================
---
branches/RF-8742/ui/validator/ui/src/test/java/org/richfaces/convert/DateTimeConverterTest.java 2010-10-22
15:08:12 UTC (rev 19654)
+++
branches/RF-8742/ui/validator/ui/src/test/java/org/richfaces/convert/DateTimeConverterTest.java 2010-10-22
15:24:57 UTC (rev 19655)
@@ -38,7 +38,7 @@
@Test
@TestDataHolder({
@TestData(submittedValue = "18-10-2010"),
- @TestData(submittedValue = "17-10-2010"),
+ @TestData(submittedValue = "17-10-2010")
})
public void testSuccess() throws Exception {
setClientConverterClassName("org.rf.DateTimeConverter");
Added:
branches/RF-8742/ui/validator/ui/src/test/java/org/richfaces/convert/NumberConverterTest.java
===================================================================
---
branches/RF-8742/ui/validator/ui/src/test/java/org/richfaces/convert/NumberConverterTest.java
(rev 0)
+++
branches/RF-8742/ui/validator/ui/src/test/java/org/richfaces/convert/NumberConverterTest.java 2010-10-22
15:24:57 UTC (rev 19655)
@@ -0,0 +1,64 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.richfaces.convert;
+
+import static org.junit.Assert.*;
+
+import javax.faces.convert.NumberConverter;
+
+import org.junit.Test;
+
+/**
+ * @author Pavel Yaschenko
+ *
+ */
+public class NumberConverterTest extends BaseConverterTest {
+
+ public NumberConverterTest() {
+ super("META-INF/resources/org.richfaces/converter-number.js");
+ }
+
+ @Test
+ @TestDataHolder({
+ @TestData(submittedValue = "111")
+ })
+ public void testSuccess() throws Exception {
+
setClientConverterClassName("RichFaces.csv.getConverter('number')");
+ setConverterId(NumberConverter.CONVERTER_ID);
+ //setAttribute("pattern", "dd-MM-yyyy");
+
+ assertConversionOk();
+ }
+
+ @Test
+ @TestDataHolder({
+ @TestData(submittedValue = "aaa", failureMessage = TEST_COMPONENT_LABEL
+ ": 'aaa' could not be understood as a number.")
+ })
+ public void testFailures() throws Exception {
+
setClientConverterClassName("RichFaces.csv.getConverter('number')");
+ setConverterId(NumberConverter.CONVERTER_ID);
+ //setConversionErrorMessage("");
+ //setAttribute("pattern", "dd-MM-yyyy");
+
+ assertConversionFailure();
+ }
+}
Modified:
branches/RF-8742/ui/validator/ui/src/test/java/org/richfaces/renderkit/html/RendererGetClientSideScriptTest.java
===================================================================
---
branches/RF-8742/ui/validator/ui/src/test/java/org/richfaces/renderkit/html/RendererGetClientSideScriptTest.java 2010-10-22
15:08:12 UTC (rev 19654)
+++
branches/RF-8742/ui/validator/ui/src/test/java/org/richfaces/renderkit/html/RendererGetClientSideScriptTest.java 2010-10-22
15:24:57 UTC (rev 19655)
@@ -3,6 +3,8 @@
import static org.easymock.EasyMock.*;
import static org.junit.Assert.*;
+import java.util.Collection;
+import java.util.Collections;
import java.util.Map;
import javax.faces.convert.NumberConverter;
@@ -21,7 +23,9 @@
import org.richfaces.validator.ScriptNotFoundException;
import org.richfaces.validator.ValidatorDescriptor;
+import com.google.common.collect.Iterables;
+
@RunWith(MockTestRunner.class)
public class RendererGetClientSideScriptTest extends RendererTestBase {
@@ -53,7 +57,7 @@
expect((Class) descriptor.getValidatorClass()).andReturn(RegexValidator.class);
expect(scriptService.getScript(RegexValidator.class)).andThrow(new
ScriptNotFoundException());
controller.replay();
- renderer.getClientSideValidatorScript(behaviorContext, descriptor);
+ renderer.getClientSideValidatorScript(behaviorContext,
Collections.singletonList(descriptor));
controller.verify();
}
@@ -77,7 +81,11 @@
expect(script.getName()).andReturn(REGEX_VALIDATOR);
expect(script.getLibrary()).andReturn(ORG_RICHFACES);
expect(script.getResourceName()).andReturn(CLIENT_VALIDATORS_JS);
- LibraryScriptFunction clientSideScript =
renderer.getClientSideValidatorScript(behaviorContext, descriptor);
+ Collection<LibraryScriptFunction> clientSideScriptCollection =
renderer.getClientSideValidatorScript(behaviorContext,
Collections.singletonList(descriptor));
+
+ assertNotNull(clientSideScriptCollection);
+ LibraryScriptFunction clientSideScript =
Iterables.getOnlyElement(clientSideScriptCollection);
+
assertEquals(ClientValidatorRenderer.CONVERTED_VALUE_VAR,
clientSideScript.getParameters().get(0));
assertEquals(VALIDATOR_MESSAGE, clientSideScript.getParameters().get(1));
assertEquals(VALIDATOR_PARAMS, clientSideScript.getParameters().get(2));
Modified:
branches/RF-8742/ui/validator/ui/src/test/java/org/richfaces/renderkit/html/RendererGetComponentScriptTest.java
===================================================================
---
branches/RF-8742/ui/validator/ui/src/test/java/org/richfaces/renderkit/html/RendererGetComponentScriptTest.java 2010-10-22
15:08:12 UTC (rev 19654)
+++
branches/RF-8742/ui/validator/ui/src/test/java/org/richfaces/renderkit/html/RendererGetComponentScriptTest.java 2010-10-22
15:24:57 UTC (rev 19655)
@@ -6,6 +6,8 @@
import static org.junit.matchers.JUnitMatchers.*;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
import java.util.Map;
import javax.faces.component.behavior.ClientBehaviorContext;
@@ -234,12 +236,12 @@
}
@Override
- LibraryScriptFunction getClientSideValidatorScript(ClientBehaviorContext
behaviorContext,
- ValidatorDescriptor validator) throws ScriptNotFoundException {
- if (validatorsCounter >= validatorFunctions.length) {
- throw new ScriptNotFoundException();
- }
- return validatorFunctions[validatorsCounter++];
+ Collection<LibraryScriptFunction>
getClientSideValidatorScript(ClientBehaviorContext behaviorContext,
+ Collection<ValidatorDescriptor> validators) {
+// if (validatorsCounter >= validatorFunctions.length) {
+// throw new ScriptNotFoundException();
+// }
+ return Arrays.asList(validatorFunctions);
}
};
}
Modified:
branches/RF-8742/ui/validator/ui/src/test/resources/org/richfaces/convert/test.xhtml
===================================================================
---
branches/RF-8742/ui/validator/ui/src/test/resources/org/richfaces/convert/test.xhtml 2010-10-22
15:08:12 UTC (rev 19654)
+++
branches/RF-8742/ui/validator/ui/src/test/resources/org/richfaces/convert/test.xhtml 2010-10-22
15:24:57 UTC (rev 19655)
@@ -9,6 +9,8 @@
<f:event type="preRenderView" listener="#{testBean.init}"/>
</f:metadata>
<h:head>
+ <h:outputScript name="jquery.js" />
+ <h:outputScript name="richfaces-csv.js"
library="org.richfaces"/>
<h:outputScript name="converter.js" />
</h:head>
<h:body>