You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by jk...@apache.org on 2008/02/04 23:08:37 UTC
svn commit: r618461 [42/43] - in
/tapestry/tapestry4/trunk/tapestry-framework/src/js:
dojo-0.4.3-custom-4.1.5/ dojo-0.4.3-custom-4.1.5/nls/
dojo-0.4.3-custom-4.1.5/src/ dojo-0.4.3-custom-4.1.5/src/animation/
dojo-0.4.3-custom-4.1.5/src/cal/ dojo-0.4.3-...
Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo-0.4.3-custom-4.1.5/src/xml/Parse.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo-0.4.3-custom-4.1.5/src/xml/Parse.js?rev=618461&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo-0.4.3-custom-4.1.5/src/xml/Parse.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo-0.4.3-custom-4.1.5/src/xml/Parse.js Mon Feb 4 14:07:13 2008
@@ -0,0 +1,152 @@
+dojo.provide("dojo.xml.Parse");
+dojo.require("dojo.dom");
+dojo.xml.Parse=function(){
+var _1=((dojo.render.html.capable)&&(dojo.render.html.ie));
+function getTagName(_2){
+try{
+return _2.tagName.toLowerCase();
+}
+catch(e){
+return "";
+}
+}
+function getDojoTagName(_3){
+var _4=getTagName(_3);
+if(!_4){
+return "";
+}
+if((dojo.widget)&&(dojo.widget.tags[_4])){
+return _4;
+}
+var p=_4.indexOf(":");
+if(p>=0){
+return _4;
+}
+if(_4.substr(0,5)=="dojo:"){
+return _4;
+}
+if(dojo.render.html.capable&&dojo.render.html.ie&&_3.scopeName!="HTML"){
+return _3.scopeName.toLowerCase()+":"+_4;
+}
+if(_4.substr(0,4)=="dojo"){
+return "dojo:"+_4.substring(4);
+}
+var _6=_3.getAttribute("dojoType")||_3.getAttribute("dojotype");
+if(_6){
+if(_6.indexOf(":")<0){
+_6="dojo:"+_6;
+}
+return _6.toLowerCase();
+}
+_6=_3.getAttributeNS&&_3.getAttributeNS(dojo.dom.dojoml,"type");
+if(_6){
+return "dojo:"+_6.toLowerCase();
+}
+try{
+_6=_3.getAttribute("dojo:type");
+}
+catch(e){
+}
+if(_6){
+return "dojo:"+_6.toLowerCase();
+}
+if((dj_global["djConfig"])&&(!djConfig["ignoreClassNames"])){
+var _7=_3.className||_3.getAttribute("class");
+if((_7)&&(_7.indexOf)&&(_7.indexOf("dojo-")!=-1)){
+var _8=_7.split(" ");
+for(var x=0,c=_8.length;x<c;x++){
+if(_8[x].slice(0,5)=="dojo-"){
+return "dojo:"+_8[x].substr(5).toLowerCase();
+}
+}
+}
+}
+return "";
+}
+this.parseElement=function(_b,_c,_d,_e){
+var _f=getTagName(_b);
+if(_1&&_f.indexOf("/")==0){
+return null;
+}
+try{
+var _10=_b.getAttribute("parseWidgets");
+if(_10&&_10.toLowerCase()=="false"){
+return {};
+}
+}
+catch(e){
+}
+var _11=true;
+if(_d){
+var _12=getDojoTagName(_b);
+_f=_12||_f;
+_11=Boolean(_12);
+}
+var _13={};
+_13[_f]=[];
+var pos=_f.indexOf(":");
+if(pos>0){
+var ns=_f.substring(0,pos);
+_13["ns"]=ns;
+if((dojo.ns)&&(!dojo.ns.allow(ns))){
+_11=false;
+}
+}
+if(_11){
+var _16=this.parseAttributes(_b);
+for(var _10 in _16){
+if((!_13[_f][_10])||(typeof _13[_f][_10]!="array")){
+_13[_f][_10]=[];
+}
+_13[_f][_10].push(_16[_10]);
+}
+_13[_f].nodeRef=_b;
+_13.tagName=_f;
+_13.index=_e||0;
+}
+var _17=0;
+for(var i=0;i<_b.childNodes.length;i++){
+var tcn=_b.childNodes.item(i);
+switch(tcn.nodeType){
+case dojo.dom.ELEMENT_NODE:
+var ctn=getDojoTagName(tcn)||getTagName(tcn);
+if(!_13[ctn]){
+_13[ctn]=[];
+}
+_13[ctn].push(this.parseElement(tcn,true,_d,_17));
+if((tcn.childNodes.length==1)&&(tcn.childNodes.item(0).nodeType==dojo.dom.TEXT_NODE)){
+_13[ctn][_13[ctn].length-1].value=tcn.childNodes.item(0).nodeValue;
+}
+_17++;
+break;
+case dojo.dom.TEXT_NODE:
+if(_b.childNodes.length==1){
+_13[_f].push({value:_b.childNodes.item(0).nodeValue});
+}
+break;
+default:
+break;
+}
+}
+return _13;
+};
+this.parseAttributes=function(_1b){
+var _1c={};
+var _1d=_1b.attributes;
+var _1e,i=0;
+while((_1e=_1d[i++])){
+if(_1){
+if(!_1e){
+continue;
+}
+if((typeof _1e=="object")&&(typeof _1e.nodeValue=="undefined")||(_1e.nodeValue==null)||(_1e.nodeValue=="")){
+continue;
+}
+}
+var nn=_1e.nodeName.split(":");
+nn=(nn.length==2)?nn[1]:_1e.nodeName;
+_1c[nn]={value:_1e.nodeValue};
+}
+return _1c;
+};
+};
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo-0.4.3-custom-4.1.5/src/xml/Parse.js
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo-0.4.3-custom-4.1.5/src/xml/Parse.js
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo-0.4.3-custom-4.1.5/src/xml/Parse.js
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo-0.4.3-custom-4.1.5/src/xml/XslTransform.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo-0.4.3-custom-4.1.5/src/xml/XslTransform.js?rev=618461&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo-0.4.3-custom-4.1.5/src/xml/XslTransform.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo-0.4.3-custom-4.1.5/src/xml/XslTransform.js Mon Feb 4 14:07:13 2008
@@ -0,0 +1,146 @@
+dojo.provide("dojo.xml.XslTransform");
+dojo.xml.XslTransform=function(_1){
+dojo.debug("XslTransform is supported by Internet Explorer and Mozilla, with limited support in Opera 9 (no document function support).");
+var _2=dojo.render.html.ie;
+var _3=["Msxml2.DOMDocument.5.0","Msxml2.DOMDocument.4.0","Msxml2.DOMDocument.3.0","MSXML2.DOMDocument","MSXML.DOMDocument","Microsoft.XMLDOM"];
+var _4=["Msxml2.FreeThreadedDOMDocument.5.0","MSXML2.FreeThreadedDOMDocument.4.0","MSXML2.FreeThreadedDOMDocument.3.0"];
+var _5=["Msxml2.XSLTemplate.5.0","Msxml2.XSLTemplate.4.0","MSXML2.XSLTemplate.3.0"];
+function getActiveXImpl(_6){
+for(var i=0;i<_6.length;i++){
+try{
+var _8=new ActiveXObject(_6[i]);
+if(_8){
+return _6[i];
+}
+}
+catch(e){
+}
+}
+dojo.raise("Could not find an ActiveX implementation in:\n\n "+_6);
+}
+if(_1==null||_1==undefined){
+dojo.raise("You must pass the URI String for the XSL file to be used!");
+return false;
+}
+var _9=null;
+var _a=null;
+if(_2){
+_9=new ActiveXObject(getActiveXImpl(_4));
+_9.async=false;
+}else{
+_a=new XSLTProcessor();
+_9=document.implementation.createDocument("","",null);
+_9.addEventListener("load",onXslLoad,false);
+}
+_9.load(_1);
+if(_2){
+var _b=new ActiveXObject(getActiveXImpl(_5));
+_b.stylesheet=_9;
+_a=_b.createProcessor();
+}
+function onXslLoad(){
+_a.importStylesheet(_9);
+}
+function getResultDom(_c,_d){
+if(_2){
+addIeParams(_d);
+var _e=getIeResultDom(_c);
+removeIeParams(_d);
+return _e;
+}else{
+return getMozillaResultDom(_c,_d);
+}
+}
+function addIeParams(_f){
+if(!_f){
+return;
+}
+for(var i=0;i<_f.length;i++){
+_a.addParameter(_f[i][0],_f[i][1]);
+}
+}
+function removeIeParams(_11){
+if(!_11){
+return;
+}
+for(var i=0;i<_11.length;i++){
+_a.addParameter(_11[i][0],"");
+}
+}
+function getIeResultDom(_13){
+_a.input=_13;
+var _14=new ActiveXObject(getActiveXImpl(_3));
+_14.async=false;
+_14.validateOnParse=false;
+_a.output=_14;
+_a.transform();
+if(_14.parseError.errorCode!=0){
+var err=_14.parseError;
+dojo.raise("err.errorCode: "+err.errorCode+"\n\nerr.reason: "+err.reason+"\n\nerr.url: "+err.url+"\n\nerr.srcText: "+err.srcText);
+}
+return _14;
+}
+function getIeResultStr(_16,_17){
+_a.input=_16;
+_a.transform();
+return _a.output;
+}
+function addMozillaParams(_18){
+if(!_18){
+return;
+}
+for(var i=0;i<_18.length;i++){
+_a.setParameter(null,_18[i][0],_18[i][1]);
+}
+}
+function getMozillaResultDom(_1a,_1b){
+addMozillaParams(_1b);
+var _1c=_a.transformToDocument(_1a);
+_a.clearParameters();
+return _1c;
+}
+function getMozillaResultStr(_1d,_1e,_1f){
+addMozillaParams(_1e);
+var _20=_a.transformToFragment(_1d,_1f);
+var _21=new XMLSerializer();
+_a.clearParameters();
+return _21.serializeToString(_20);
+}
+this.getResultString=function(_22,_23,_24){
+var _25=null;
+if(_2){
+addIeParams(_23);
+_25=getIeResultStr(_22,_23);
+removeIeParams(_23);
+}else{
+_25=getMozillaResultStr(_22,_23,_24);
+}
+return _25;
+};
+this.transformToContentPane=function(_26,_27,_28,_29){
+var _2a=this.getResultString(_26,_27,_29);
+_28.setContent(_2a);
+};
+this.transformToRegion=function(_2b,_2c,_2d,_2e){
+try{
+var _2f=this.getResultString(_2b,_2c,_2e);
+_2d.innerHTML=_2f;
+}
+catch(e){
+dojo.raise(e.message+"\n\n xsltUri: "+_1);
+}
+};
+this.transformToDocument=function(_30,_31){
+return getResultDom(_30,_31);
+};
+this.transformToWindow=function(_32,_33,_34,_35){
+try{
+_34.open();
+_34.write(this.getResultString(_32,_33,_35));
+_34.close();
+}
+catch(e){
+dojo.raise(e.message+"\n\n xsltUri: "+_1);
+}
+};
+};
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo-0.4.3-custom-4.1.5/src/xml/XslTransform.js
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo-0.4.3-custom-4.1.5/src/xml/XslTransform.js
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo-0.4.3-custom-4.1.5/src/xml/XslTransform.js
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo-0.4.3-custom-4.1.5/src/xml/__package__.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo-0.4.3-custom-4.1.5/src/xml/__package__.js?rev=618461&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo-0.4.3-custom-4.1.5/src/xml/__package__.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo-0.4.3-custom-4.1.5/src/xml/__package__.js Mon Feb 4 14:07:13 2008
@@ -0,0 +1,3 @@
+dojo.require("dojo.xml.Parse");
+dojo.kwCompoundRequire({common:["dojo.dom"],browser:["dojo.html.*"],dashboard:["dojo.html.*"]});
+dojo.provide("dojo.xml.*");
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo-0.4.3-custom-4.1.5/src/xml/__package__.js
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo-0.4.3-custom-4.1.5/src/xml/__package__.js
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo-0.4.3-custom-4.1.5/src/xml/__package__.js
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo-0.4.3-custom-4.1.5/storage_dialog.swf
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo-0.4.3-custom-4.1.5/storage_dialog.swf?rev=618461&view=auto
==============================================================================
Binary file - no diff available.
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo-0.4.3-custom-4.1.5/storage_dialog.swf
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry-4.1.5/core.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry-4.1.5/core.js?rev=618461&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry-4.1.5/core.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry-4.1.5/core.js Mon Feb 4 14:07:13 2008
@@ -0,0 +1,946 @@
+dojo.provide("tapestry.core");
+dojo.provide("tapestry.html");
+dojo.provide("tapestry.event");
+dojo.provide("tapestry.lang");
+
+dojo.require("dojo.lang.common");
+dojo.require("dojo.io.BrowserIO");
+dojo.require("dojo.event.browser");
+dojo.require("dojo.html.style");
+dojo.require("dojo.lang.func");
+dojo.require("dojo.string.extras");
+
+// redirect logging calls to standard debug if logging not enabled
+if (dj_undef("logging", dojo)) {
+ dojo.log = {
+ debug:function(){
+ dojo.debug.apply(this, arguments);
+ },
+ info:function(){
+ dojo.debug.apply(this, arguments);
+ },
+ warn:function(){
+ dojo.debug.apply(this, arguments);
+ },
+ err:function(){
+ dojo.debug.apply(this, arguments);
+ },
+ exception:function(){
+ dojo.debug.apply(this, arguments);
+ }
+ }
+}
+
+/**
+ * package: tapestry
+ * Provides the core functionality for the Tapestry javascript package libraries.
+ *
+ * Most of the functions in here are related to initiating and parsing IO
+ * requests.
+ */
+var tapestry={
+
+ // property: version
+ // The current client side library version, usually matching the current java library version. (ie 4.1, etc..)
+ version:"4.1.4",
+ scriptInFlight:false, // whether or not javascript is currently being eval'd, default false
+ ScriptFragment:new RegExp('(?:<script.*?>)((\n|.|\r)*?)(?:<\/script>)', 'im'), // regexp for script elements
+ GlobalScriptFragment:new RegExp('(?:<script.*?>)((\n|.|\r)*?)(?:<\/script>)', 'img'), // regexp for global script fragments
+ requestsInFlight:0, // how many ajax requests are currently in progress
+ isIE:dojo.render.html.ie,
+ isMozilla:dojo.render.html.mozilla,
+ // property: requestEncoding
+ // Defines the encoding that will be used in all Tapestry initiated XHR requests to encode
+ // URL or form data. Gets set by AjaxShellDelegate class on server on most requests by default.
+ requestEncoding:"UTF-8",
+
+ /**
+ * Function: bind
+ *
+ * Core XHR bind function for tapestry internals. The
+ * <error>/<load> functions defined in this package are used to handle
+ * load/error of dojo.io.bind.
+ *
+ * Parameters:
+ *
+ * url - The url to bind the request to.
+ * content - A properties map of optional extra content to send.
+ * json - Boolean, optional parameter specifying whether or not to create a
+ * json request. If not specified the default is to use XHR.
+ */
+ bind:function(url, content, json){
+ var parms = {
+ url:url,
+ content:content,
+ useCache:true,
+ preventCache:true,
+ encoding: tapestry.requestEncoding,
+ error: (function(){tapestry.error.apply(this, arguments);})
+ };
+
+ // setup content type
+ if (typeof json != "undefined" && json) {
+ parms.mimetype = "text/json";
+ parms.headers={"json":true};
+ parms.load=(function(){tapestry.loadJson.apply(this, arguments);});
+ } else {
+ parms.headers={"dojo-ajax-request":true};
+ parms.mimetype="text/xml";
+ parms.load=(function(){tapestry.load.apply(this, arguments);});
+ }
+
+ tapestry.requestsInFlight++;
+ dojo.io.queueBind(parms);
+ },
+
+ /**
+ * Function: error
+ *
+ * Global error handling function for dojo.io.bind requests. This function is mapped
+ * as the "error:functionName" part of a request in the dojo.io.bind arguments
+ * in <tapestry.bind> calls.
+ *
+ * See Also:
+ * <tapestry.bind>, <tapestry.load>
+ */
+ error:function(type, exception, http, kwArgs){
+ tapestry.requestsInFlight--;
+ dojo.log.exception("Error received in IO response.", exception);
+ },
+
+ /**
+ * Function: load
+ *
+ * Global load handling function for dojo.io.bind requests. This isn't typically
+ * called directly by anything, but passed in as the "load" argument to
+ * dojo.io.bind when making IO requests as the function that will handle the
+ * return response.
+ *
+ * Parameters:
+ * type - Type of request.
+ * data - The data returned, depending on the request type might be an xml document /
+ * plaintext / json / etc.
+ * http - The http object used in request, like XmlHttpRequest.
+ * kwArgs - The original set of arguments passed into dojo.io.bind({arg:val,arg1:val2}).
+ *
+ */
+ load:function(type, data, http, kwArgs){
+ dojo.log.debug("tapestry.load() Response received.", data);
+ tapestry.requestsInFlight--;
+ if (!data) {
+ dojo.log.warn("No data received in response.");
+ return;
+ }
+
+ var resp=data.getElementsByTagName("ajax-response");
+ if (!resp || resp.length < 1 || !resp[0].childNodes) {
+ dojo.log.warn("No ajax-response elements received.");
+ return;
+ }
+
+ var elms=resp[0].childNodes;
+ var bodyScripts=[];
+ var initScripts=[];
+ var rawData=[];
+ for (var i=0; i<elms.length; i++) {
+ var elmType=elms[i].getAttribute("type");
+ var id=elms[i].getAttribute("id");
+
+ if (elmType == "exception") {
+ dojo.log.err("Remote server exception received.");
+ tapestry.presentException(elms[i], kwArgs);
+ return;
+ } else if (elmType == "page") {
+ window.location=elms[i].getAttribute("url");
+ return;
+ } else if (elmType == "status") {
+ dojo.event.topic.publish(id, {message: tapestry.html.getContentAsString(elms[i])});
+ continue;
+ }
+
+ // handle javascript evaluations
+ if (elmType == "script") {
+
+ if (id == "initializationscript") {
+ initScripts.push(elms[i]);
+ continue;
+ } else if (id == "bodyscript") {
+ bodyScripts.push(elms[i]);
+ continue;
+ } else if (id == "includescript") {
+ // includes get processed immediately (synchronously)
+ var includes=elms[i].getElementsByTagName("include");
+ if (!includes){continue;}
+ for (var e=0; e<includes.length;e++) {
+ tapestry.loadScriptFromUrl(includes[e].getAttribute("url"));
+ }
+ continue;
+ }
+ } else {
+ rawData.push(elms[i]);
+ }
+
+ if (!id){
+ dojo.log.warn("No element id found in ajax-response node.");
+ continue;
+ }
+
+ var node=dojo.byId(id);
+ if (!node) {
+ dojo.log.warn("No node could be found to update content in with id " + id);
+ continue;
+ }
+
+ tapestry.loadContent(id, node, elms[i]);
+ }
+
+ // load body scripts before initialization
+ for (var i=0; i<bodyScripts.length; i++) {
+ tapestry.loadScriptContent(bodyScripts[i], true);
+ }
+
+ for (var i=0; i<rawData.length; i++) {
+ tapestry.loadScriptContent(rawData[i], true);
+ }
+
+ for (var i=0; i<initScripts.length; i++) {
+ tapestry.loadScriptContent(initScripts[i], true);
+ }
+ },
+
+ /**
+ * Function: loadJson
+ *
+ * Executed by default during JSON requests - default implementation does nothing but decrement
+ * the <tapestry.requestsInFlight> global variable.
+ *
+ * Parameters:
+ * type - Type of request.
+ * data - The data returned, depending on the request type might be an xml document /
+ * plaintext / json / etc.
+ * http - The http object used in request, like XmlHttpRequest.
+ * kwArgs - The original set of arguments passed into dojo.io.bind({arg:val,arg1:val2}).
+ */
+ loadJson:function(type, data, http, kwArgs) {
+ dojo.log.debug("tapestry.loadJson() Response received.", data);
+ tapestry.requestsInFlight--;
+ },
+
+ /**
+ * Function: loadContent
+ *
+ * Used by <tapestry.load> when handling xml responses to iterate over the tapestry
+ * specific xml response and appropriately load all content types / perform animations /
+ * execute scripts in the proper order / etc..
+ *
+ * Parameters:
+ * id - The element id that this content should be applied to in the existing document.
+ * node - The node that this new content will be applied to.
+ * element - The incoming xml node containing rules/content to apply to this node.
+ *
+ */
+ loadContent:function(id, node, element){
+ if (typeof element.childNodes != "undefined" && element.childNodes.length > 0) {
+ for (var i = 0; i < element.childNodes.length; i++) {
+ if (element.childNodes[i].nodeType != 1) { continue; }
+
+ var nodeId = element.childNodes[i].getAttribute("id");
+ if (nodeId) {
+ element=element.childNodes[i];
+ break;
+ }
+ }
+ }
+
+ var content=tapestry.html.getContentAsString(element);
+ if (djConfig["isDebug"]) {
+ dojo.log.debug("Received element content for id <" + id + "> of: " + content);
+ }
+
+ // on IE don't destroy event listeners on single element nodes like form input boxes/etc
+ if (!tapestry.isIE || (tapestry.isIE && node.childNodes && node.childNodes.length > 0)){
+ dojo.event.browser.clean(node); // prevent mem leaks in ie
+ }
+
+ // fix for IE - setting innerHTML does not work for SELECTs
+ if (tapestry.isIE && !dj_undef("outerHTML", node) && node.nodeName == "SELECT") {
+ node.outerHTML = node.outerHTML.replace(/(<SELECT[^<]*>).*(<\/SELECT>)/, '$1' + content + '$2');
+ node=dojo.byId(id);
+ } else if (content && content.length > 0
+ && (!tapestry.isIE || content.length > 1)){
+ node.innerHTML=content;
+ }
+
+ // copy attributes
+ var atts=element.attributes;
+ var attnode, i=0;
+ while((attnode=atts[i++])){
+ if(tapestry.isIE){
+ if(!attnode){ continue; }
+ if((typeof attnode == "object")&&
+ (typeof attnode.nodeValue == 'undefined')||
+ (attnode.nodeValue == null)||
+ (attnode.nodeValue == '')){
+ continue;
+ }
+ }
+
+ var nn = attnode.nodeName;
+ var nv = attnode.nodeValue;
+ if (nn == "id" || nn == "type" || nn == "name"){continue;}
+
+ if (nn == "style") {
+ dojo.html.setStyleText(node, nv);
+ } else if (nn == "class") {
+ dojo.html.setClass(node, nv);
+ } else if (nn == "value") {
+ node.value = nv;
+ } else {
+ node.setAttribute(nn, nv);
+ }
+ }
+
+ // apply disabled/not disabled
+ var disabled = element.getAttribute("disabled");
+ if (!disabled && node["disabled"]) {
+ node.disabled = false;
+ } else if (disabled) {
+ node.disabled = true;
+ }
+ },
+
+ /**
+ * Function: loadScriptContent
+ *
+ * Manages loading javascript content for a specific incoming xml element.
+ *
+ * Parameters:
+ * element - The element to parse javascript statements from and execute.
+ * async - Whether or not to process the script content asynchronously, meaning
+ * whether or not to execute the script in a block done in a setTimeout call
+ * so as to avoid IE specific issues.
+ */
+ loadScriptContent:function(element, async){
+ if (typeof async == "undefined") { async = true; }
+ async = this.isIE;
+
+ if (tapestry.scriptInFlight) {
+ dojo.log.debug("loadScriptContent(): scriptInFlight is true, sleeping");
+ setTimeout(function() { tapestry.loadScriptContent(element, async);}, 5);
+ return;
+ }
+
+ var text=tapestry.html.getContentAsString(element);
+ text.replace(this.GlobalScriptFragment, '');
+ var scripts = text.match(this.GlobalScriptFragment);
+
+ if (!scripts) { return; }
+
+ if (async) {
+ setTimeout(function() {
+ tapestry.evaluateScripts(scripts);
+ }, 60);
+ } else {
+ tapestry.evaluateScripts(scripts);
+ }
+ },
+
+ evaluateScripts:function(scripts){
+ tapestry.scriptInFlight = true;
+
+ for (var i=0; i<scripts.length; i++) {
+ var scr = scripts[i].match(this.ScriptFragment)[1];
+ if(!scr || scr.length <= 0){continue;}
+ try {
+ dojo.log.debug("evaluating script:", scr);
+ eval(scr);
+ } catch (e) {
+ tapestry.scriptInFlight = false;
+ dojo.log.exception("Error evaluating script: " + scr, e, false);
+ }
+ }
+
+ tapestry.scriptInFlight = false;
+ },
+
+ /**
+ * Function: loadScriptFromUrl
+ *
+ * Takes a url string and loads the javascript it points to as a normal
+ * document head script include section. ie:
+ *
+ * : <script type="text/javascript" src="http://localhost/js/foo.js"></script>
+ *
+ * Parameters:
+ * url - The url to the script to load into this documents head.
+ */
+ loadScriptFromUrl:function(url){
+ var scripts = window.document.getElementsByTagName("script");
+ if (scripts){
+ for (var i = 0; i < scripts.length; i++) {
+ var src = scripts[i].src;
+ if (src && src.length > 0 && src.indexOf(url)>=0 ) {
+ return;
+ }
+ }
+ }
+
+ if (djConfig.isDebug) {
+ dojo.log.debug("loadScriptFromUrl: " + url + " success?: " + dojo.hostenv.loadUri(url));
+ } else {
+ dojo.hostenv.loadUri(url);
+ }
+ },
+
+ /**
+ * Function: presentException
+ *
+ * When remote exceptions are caught on the server special xml blocks are returned to
+ * the client when the requests are initiated via async IO. This function takes the incoming
+ * Tapestry exception page content and dumps it into a modal dialog that is presented to the user.
+ *
+ * Parameters:
+ * node - The incoming xml exception node.
+ * kwArgs - The kwArgs used to initiate the original IO request.
+ */
+ presentException:function(node, kwArgs) {
+ dojo.require("dojo.widget.*");
+ dojo.require("dojo.widget.Dialog");
+
+ var excnode=document.createElement("div");
+ excnode.setAttribute("id", "exceptiondialog");
+ document.body.appendChild(excnode);
+
+ var contentnode=document.createElement("div");
+ contentnode.innerHTML=tapestry.html.getContentAsString(node);
+ dojo.html.setClass(contentnode, "exceptionDialog");
+
+ var navnode=document.createElement("div");
+ navnode.setAttribute("id", "exceptionDialogHandle");
+ dojo.html.setClass(navnode, "exceptionCloseLink");
+ navnode.appendChild(document.createTextNode("Close"));
+
+ excnode.appendChild(navnode);
+ excnode.appendChild(contentnode);
+
+ var dialog=dojo.widget.createWidget("Dialog", {widgetId:"exception"}, excnode);
+ dojo.event.connect(navnode, "onclick", dialog, "hide");
+ dojo.event.connect(dialog, "hide", dialog, "destroy");
+
+ setTimeout(function(){
+ dialog.show();
+ }, 100);
+ },
+
+ /**
+ * Function: cleanConnect
+ *
+ * Utility used to disconnect a previously connected event/function.
+ *
+ * This assumes that the incoming function name is being attached to
+ * the global namespace "tapestry".
+ */
+ cleanConnect:function(target, event, funcName){
+ target = dojo.byId(target);
+ if (!dj_undef(funcName, tapestry)){
+ dojo.event.disconnect(target, event, tapestry, funcName);
+ }
+ },
+
+ /**
+ * Function: cleanConnectWidget
+ */
+ cleanConnectWidget:function(target, event, funcName){
+ tapestry.cleanConnect(dojo.widget.byId(target), event, funcName);
+ },
+
+ /**
+ * Function: connect
+ *
+ * Utility used to connect an event/function.
+ *
+ * This assumes that the incoming function name is being attached to
+ * the global namespace "tapestry".
+ */
+ connect:function(target, event, funcName){
+ target = dojo.byId(target);
+ if (!dj_undef(funcName, tapestry)){
+ dojo.event.connect(target, event, tapestry, funcName);
+ }
+ },
+
+ /**
+ * Function: connectBefore
+ */
+ connectBefore:function(target, event, funcName){
+ target = dojo.byId(target);
+ if (!dj_undef(funcName, tapestry)){
+ dojo.event.connect("before", target, event, tapestry, funcName);
+ }
+ },
+
+ /**
+ * Function: connectWidget
+ */
+ connectWidget:function(target, event, funcName){
+ tapestry.connect(dojo.widget.byId(target), event, funcName);
+ },
+
+ /**
+ * Function: byId
+ */
+ byId:dojo.byId,
+
+ /**
+ * Function: raise
+ */
+ raise:dojo.raise,
+
+ /**
+ * Function: addOnLoad
+ */
+ addOnLoad:dojo.addOnLoad,
+
+ /**
+ * Function: provide
+ */
+ provide:dojo.provide,
+
+ /**
+ * Function: linkOnClick
+ */
+ linkOnClick:function(url, id, isJson, eventName){
+ var content={beventname:(eventName || "onClick")};
+ content["beventtarget.id"]=id;
+
+ tapestry.bind(url, content, isJson);
+ return false;
+ },
+
+ /**
+ * Function: isServingRequests
+ *
+ * Utility used to find out if there are any ajax requests in progress.
+ */
+ isServingRequests:function(){
+ return (this.requestsInFlight > 0);
+ }
+}
+
+/**
+ * package: tapestry.html
+ * Provides functionality related to parsing and rendering dom nodes.
+ */
+tapestry.html={
+
+ CompactElementRegexp:/<([a-zA-Z](?!nput)[a-zA-Z]*)([^>]*?)\/>/g, // regexp for compact html elements
+ CompactElementReplacer:'<$1$2></$1>', // replace pattern for compact html elements
+
+ /**
+ * Function: getContentAsString
+ *
+ * Takes a dom node and returns its contents rendered in a string.
+ *
+ * The resulting string does NOT contain any markup (or attributes) of
+ * the given node - only child nodes are rendered and returned.Content
+ *
+ * Implementation Note: This function tries to make use of browser
+ * specific features (the xml attribute of nodes in IE and the XMLSerializer
+ * object in Mozilla derivatives) - if those fails, a generic implementation
+ * is used that is guaranteed to work in all platforms.
+ *
+ * Parameters:
+ *
+ * node - The dom node.
+ * Returns:
+ *
+ * The string representation of the given node's contents.
+ */
+ getContentAsString:function(node){
+ if (typeof node.xml != "undefined") {
+ return this._getContentAsStringIE(node);
+ } else if (typeof XMLSerializer != "undefined" ) {
+ return this._getContentAsStringMozilla(node);
+ } else {
+ return this._getContentAsStringGeneric(node);
+ }
+ },
+
+ /**
+ * Function: getElementAsString
+ *
+ * Takes a dom node and returns itself and its contents rendered in a string.
+ *
+ * Implementation Note: This function uses a generic implementation in order
+ * to generate the returned string.
+ *
+ * Parameters:
+ *
+ * node - The dom node.
+ * Returns:
+ *
+ * The string representation of the given node.
+ */
+ getElementAsString:function(node){
+ if (!node) { return ""; }
+
+ var s='<' + node.nodeName;
+ // add attributes
+ if (node.attributes && node.attributes.length > 0) {
+ for (var i=0; i < node.attributes.length; i++) {
+ s += " " + node.attributes[i].name + "=\"" + node.attributes[i].value + "\"";
+ }
+ }
+ // close start tag
+ s += '>';
+ // content of tag
+ s += this._getContentAsStringGeneric(node);
+ // end tag
+ s += '</' + node.nodeName + '>';
+ return s;
+ },
+
+ /**
+ * Adds togglers and js effects to the exception page.
+ */
+ enhanceExceptionPage:function(){
+ // attach toggles + hide content
+
+ var elms=dojo.html.getElementsByClass('toggle');
+
+ if(elms && elms.length > 0){
+ for(var i=0;i<elms.length;i++){
+
+ dojo.event.connect(elms[i], "onclick", function(e) {
+ var thisLink = e.target;
+ dojo.html.toggleShowing(dojo.byId(thisLink.id + 'Data'));
+ if(dojo.html.hasClass(thisLink, "toggleSelected"))
+ dojo.html.removeClass(thisLink, "toggleSelected")
+ else
+ dojo.html.addClass(thisLink, "toggleSelected");
+ if (e.preventDefault)
+ dojo.event.browser.stopEvent(e);
+ return false;
+ });
+ dojo.html.toggleShowing(elms[i].id+'Data');
+ }
+ }
+
+ // but show last exception's content
+ elms=dojo.html.getElementsByClass('exception-link');
+ if(elms && elms.length > 0){
+ elms[elms.length-1].onclick({target:elms[elms.length-1]});
+ }
+ },
+
+ _getContentAsStringIE:function(node){
+ var s=" "; //blank works around an IE-bug
+ for (var i = 0; i < node.childNodes.length; i++){
+ s += node.childNodes[i].xml;
+ }
+ return s;
+ },
+
+ _getContentAsStringMozilla:function(node){
+ if (!this.xmlSerializer){ this.xmlSerializer = new XMLSerializer();}
+
+ var s = "";
+ for (var i = 0; i < node.childNodes.length; i++) {
+ s += this.xmlSerializer.serializeToString(node.childNodes[i]);
+ if (s == "undefined")
+ return this._getContentAsStringGeneric(node);
+ }
+
+ return this._processCompactElements(s);
+ },
+
+ _getContentAsStringGeneric:function(node){
+ var s="";
+ if (node == null) { return s; }
+ for (var i = 0; i < node.childNodes.length; i++) {
+ switch (node.childNodes[i].nodeType) {
+ case 1: // ELEMENT_NODE
+ case 5: // ENTITY_REFERENCE_NODE
+ s += this.getElementAsString(node.childNodes[i]);
+ break;
+ case 3: // TEXT_NODE
+ case 2: // ATTRIBUTE_NODE
+ case 4: // CDATA_SECTION_NODE
+ s += node.childNodes[i].nodeValue;
+ break;
+ default:
+ break;
+ }
+ }
+ return s;
+ },
+
+ _processCompactElements:function(htmlData)
+ {
+ return htmlData.replace(this.CompactElementRegexp, this.CompactElementReplacer);
+ }
+}
+
+/**
+ * package: tapestry.event
+ *
+ * Utility functions that handle converting javascript event objects into
+ * a name/value pair format that can be sent to the remote server.
+ */
+tapestry.event={
+
+ /**
+ * Function: buildEventProperties
+ *
+ * Takes an incoming browser generated event (like key/mouse events) and
+ * creates a js object holding the basic values of the event in order for
+ * it to be submitted to the server.
+ *
+ * Parameters:
+ *
+ * event - The javascript event method is based on, if it isn't a valid
+ * browser event it will be ignored.
+ * props - The existing property object to set the values on, if it doesn't
+ * exist one will be created.
+ * args - The arguments from an method-call interception
+ * Returns:
+ *
+ * The desired event properties bound to an object. Ie obj.target,obj.charCode, etc..
+ */
+ buildEventProperties:function(event, props, args){
+ if (!props) props={};
+
+ if (dojo.event.browser.isEvent(event)) {
+ if(event["type"]) props.beventtype=event.type;
+ if(event["keys"]) props.beventkeys=event.keys;
+ if(event["charCode"]) props.beventcharCode=event.charCode;
+ if(event["pageX"]) props.beventpageX=event.pageX;
+ if(event["pageY"]) props.beventpageY=event.pageY;
+ if(event["layerX"]) props.beventlayerX=event.layerX;
+ if(event["layerY"]) props.beventlayerY=event.layerY;
+
+ if (event["target"]) this.buildTargetProperties(props, event.target);
+ }
+
+ props.methodArguments = dojo.json.serialize( args );
+
+ return props;
+ },
+
+
+
+ /**
+ * Function: buildTargetProperties
+ *
+ * Generic function to build a properties object populated with
+ * relevent target data.
+ *
+ * Parameters:
+ *
+ * props - The object that event properties are being set on to return to
+ * the server.
+ * target - The javscript Event.target object that the original event was targeted for.
+ *
+ * Returns:
+ * The original props object passed in, populated with any data found.
+ */
+ buildTargetProperties:function(props, target){
+ if(!target) { return; }
+
+ if (dojo.dom.isNode(target)) {
+ return this.buildNodeProperties(props, target);
+ } else {
+ dojo.raise("buildTargetProperties() Unknown target type:" + target);
+ }
+ },
+
+ /**
+ * Function: buildNodeProperties
+ *
+ * Builds needed target node properties, like the node's id.
+ *
+ * Parameters:
+ * props - The object that event properties are being set on to return to
+ * the server.
+ * node - The dom node specified as the Event.target in a javascript event.
+ */
+ buildNodeProperties:function(props, node) {
+ if (node.getAttribute("id")) {
+ props["beventtarget.id"]=node.getAttribute("id");
+ }
+ },
+
+ /**
+ * Function: stopEvent
+ */
+ stopEvent:dojo.event.browser.stopEvent
+}
+
+tapestry.lang = {
+
+ /**
+ * Searches the specified list for an object with a matching propertyName/value pair.
+ * @param list The array of objects to search.
+ * @param properyName The object property key to match on. (ie object[propertyName])
+ * Can also be a template object to match in the form of {key:{key:value}} nested
+ * as deeply as you like.
+ * @param value The value to be matched against
+ * @return The matching array object found, or null.
+ */
+ find:function(list, property, value){
+ if (!list || !property || list.length < 1) return null;
+
+ // if not propMatch then template object was passed in
+ var propMatch=dojo.lang.isString(property);
+ if (propMatch && !value) return null; //if doing string/other non template match and no value
+
+ for (var i=0; i < list.length; i++) {
+ if (!list[i]) continue;
+ if (propMatch) {
+ if (list[i] && list[i][property] && list[i][property] == value) return list[i];
+ } else {
+ if (this.matchProperty(property, list[i])) return list[i];
+ }
+ }
+ return null;
+ },
+
+ // called recursively to match object properties
+ // partially stolen logic from dojo.widget.html.SortableTable.sort
+ matchProperty:function(template, object){
+ if(!dojo.lang.isObject(template) || !dojo.lang.isObject(object))
+ return template.valueOf() == object.valueOf();
+
+ for(var p in template){
+ if(!(p in object)) return false; // boolean
+ if (!this.matchProperty(template[p], object[p])) return false;
+ }
+ return true;
+ }
+}
+
+dojo.provide("dojo.AdapterRegistry");
+dojo.provide("dojo.json");
+
+dojo.AdapterRegistry = function (returnWrappers) {
+ this.pairs = [];
+ this.returnWrappers = returnWrappers || false;
+};
+dojo.lang.extend(dojo.AdapterRegistry, {register:function (name, check, wrap, directReturn, override) {
+ var type = (override) ? "unshift" : "push";
+ this.pairs[type]([name, check, wrap, directReturn]);
+}, match:function () {
+ for (var i = 0; i < this.pairs.length; i++) {
+ var pair = this.pairs[i];
+ if (pair[1].apply(this, arguments)) {
+ if ((pair[3]) || (this.returnWrappers)) {
+ return pair[2];
+ } else {
+ return pair[2].apply(this, arguments);
+ }
+ }
+ }
+ throw new Error("No match found");
+}, unregister:function (name) {
+ for (var i = 0; i < this.pairs.length; i++) {
+ var pair = this.pairs[i];
+ if (pair[0] == name) {
+ this.pairs.splice(i, 1);
+ return true;
+ }
+ }
+ return false;
+}});
+
+
+dojo.json = {
+ jsonRegistry:new dojo.AdapterRegistry(),
+ register:function (name, check, wrap, override) {
+ dojo.json.jsonRegistry.register(name, check, wrap, override);
+ },
+
+ evalJson:function (json) {
+ try {
+ return eval("(" + json + ")");
+ }
+ catch (e) {
+ dojo.debug(e);
+ return json;
+ }
+ },
+
+ serialize:function (o) {
+ var objtype = typeof (o);
+ if (objtype == "undefined") {
+ return "undefined";
+ } else {
+ if ((objtype == "number") || (objtype == "boolean")) {
+ return o + "";
+ } else {
+ if (o === null) {
+ return "null";
+ }
+ }
+ }
+ if (objtype == "string") {
+ return dojo.string.escapeString(o);
+ }
+ var me = arguments.callee;
+ var newObj;
+ if (typeof (o.__json__) == "function") {
+ newObj = o.__json__();
+ if (o !== newObj) {
+ return me(newObj);
+ }
+ }
+
+ if (typeof (o.json) == "function") {
+ newObj = o.json();
+ if (o !== newObj) {
+ return me(newObj);
+ }
+ }
+
+ if (objtype != "function" && typeof (o.length) == "number") {
+ var res = [];
+ for (var i = 0; i < o.length; i++) {
+ if (dojo.event.browser.isEvent(o[i]) || o[i]["stopPropagation"]){continue;}
+ var val = me(o[i]);
+ if (typeof (val) != "string") {
+ val = "undefined";
+ }
+ res.push(val);
+ }
+ return "[" + res.join(",") + "]";
+ }
+ try {
+ window.o = o;
+ newObj = dojo.json.jsonRegistry.match(o);
+ return me(newObj);
+ }
+ catch (e) {
+ }
+ if (objtype == "function") {
+ return null;
+ }
+
+ res = [];
+ for (var k in o) {
+ var useKey;
+ if (typeof (k) == "number") {
+ useKey = "\"" + k + "\"";
+ } else {
+ if (typeof (k) == "string") {
+ useKey = dojo.string.escapeString(k);
+ } else {
+ continue;
+ }
+ }
+ val = me(o[k]);
+ if (typeof (val) != "string") {
+ continue;
+ }
+ res.push(useKey + ":" + val);
+ }
+ return "{" + res.join(",") + "}";
+}};
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry-4.1.5/core.js
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry-4.1.5/core.js
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry-4.1.5/core.js
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry-4.1.5/form.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry-4.1.5/form.js?rev=618461&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry-4.1.5/form.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry-4.1.5/form.js Mon Feb 4 14:07:13 2008
@@ -0,0 +1,836 @@
+dojo.provide("tapestry.form");
+dojo.provide("tapestry.form.datetime");
+dojo.provide("tapestry.form.validation");
+
+dojo.require("dojo.event.browser");
+dojo.require("dojo.dom");
+dojo.require("dojo.html.selection");
+dojo.require("tapestry.core");
+dojo.require("dojo.date.format");
+dojo.require("dojo.validate.datetime");
+dojo.require("dojo.validate.check");
+dojo.require("dojo.html.style");
+
+/**
+ * package: tapestry.form
+ * Provides central handling of all client side form related logic.
+ */
+tapestry.form={
+
+ // property: forms
+ // Contains a reference to all registered Tapestry forms in the current document.
+ forms:{}, // registered form references
+ // property: currentFocus
+ // Reference to form element/element id of field that should currently recieve focus, if any
+ currentFocus:null,
+
+ /**
+ * Function: focusField
+ * If possible, brings keyboard input focus to the specified field.
+ *
+ * Parameters:
+ * field - The field(field id) of the field to focus.
+ *
+ * Note:
+ * Function deprecated in favor of dojo equivalent, like
+ * dojo.html.selectInputText(node).
+ */
+ focusField:function(field){
+ if (arguments.length < 1) {return;}
+ try{
+ var f=dojo.widget.byId(field);
+ if(f && !dj_undef("focus", f)){
+ if (dojo.html.isVisible(f)){
+ f.focus();
+ }
+ return;
+ } else {
+ f = dojo.byId(field);
+ }
+
+ if (!f) { return; }
+ if (field.disabled || field.clientWidth < 1) {
+ return;
+ }
+
+ if(!dj_undef("focus", f) && dojo.html.isShowing(f)){
+ f.focus();
+ return;
+ }
+
+ dojo.html.selectInputText(field);} catch(e){dojo.log.debug(e);}
+ },
+
+ /**
+ * Used by AlertDialog to focus the highest priority form field
+ * that failed validation. This happens because the field needs to
+ * be focused ~after~ the dialog is hidden.
+ */
+ _focusCurrentField:function(){
+ if(!this.currentFocus){return;}
+
+ this.focusField(this.currentFocus);
+ },
+
+ /**
+ * Function: registerForm
+ *
+ * Registers the form with the local <forms> property so
+ * that there is a central reference of all tapestry forms.
+ *
+ * Parameters:
+ *
+ * id - The form(form id) to register.
+ * async - Boolean, if true causes form submission to be asynchronous.
+ * json - Boolean, if true causes form submission to be asyncrhronous with an
+ * expected JSON response.
+ */
+ registerForm:function(id, async, json){
+ var form=dojo.byId(id);
+ if (!form) {
+ dojo.raise("Form not found with id " + id);
+ return;
+ }
+
+ // make sure id is correct just in case node passed in has only name
+ id=form.getAttribute("id");
+
+ // if previously connected, cleanup and reconnect
+ if (this.forms[id]) {
+ dojo.event.disconnect(form, "onsubmit", this, "onFormSubmit");
+ for(var i = 0; i < form.elements.length; i++) {
+ var node = form.elements[i];
+ if(node && node.type && dojo.lang.inArray(["submit", "button"],node.type.toLowerCase())) {
+ dojo.event.disconnect(node, "onclick", tapestry.form, "inputClicked");
+ }
+ }
+
+ var inputs = form.getElementsByTagName("input");
+ for(var i = 0; i < inputs.length; i++) {
+ var input = inputs[i];
+ if(input.type.toLowerCase() == "image" && input.form == form) {
+ dojo.event.disconnect(input, "onclick", tapestry.form, "inputClicked");
+ }
+ }
+
+ dojo.event.disconnect(form, "onsubmit", this, "overrideSubmit");
+ delete this.forms[id];
+ }
+
+ this.forms[id]={};
+ this.forms[id].validateForm=true;
+ this.forms[id].profiles=[];
+ this.forms[id].async=(typeof async != "undefined") ? async : false;
+ this.forms[id].json=(typeof json != "undefined") ? json : false;
+
+ if (!this.forms[id].async) {
+ dojo.event.connect(form, "onsubmit", this, "onFormSubmit");
+ } else {
+ for(var i = 0; i < form.elements.length; i++) {
+ var node = form.elements[i];
+ if(node && node.type && dojo.lang.inArray(["submit", "button"],node.type.toLowerCase())) {
+ dojo.event.connect(node, "onclick", tapestry.form, "inputClicked");
+ }
+ }
+
+ var inputs = form.getElementsByTagName("input");
+ for(var i = 0; i < inputs.length; i++) {
+ var input = inputs[i];
+ if(input.type.toLowerCase() == "image" && input.form == form) {
+ dojo.event.connect(input, "onclick", tapestry.form, "inputClicked");
+ }
+ }
+
+ dojo.event.connect(form, "onsubmit", this, "overrideSubmit");
+ }
+ },
+
+ overrideSubmit:function(e){
+ dojo.event.browser.stopEvent(e);
+ var elm = e.target;
+ if (!dj_undef("form", elm)){
+ dojo.log.debug("Submit event was generated from element: ", elm);
+ elm = elm.form;
+ }
+ tapestry.form.submitAsync(elm);
+ },
+
+ /**
+ * Function: registerProfile
+ *
+ * Registers a form validation/translation profile. There
+ * can potentially be more than one profile registered with
+ * a form.
+ *
+ * The profiles will be consulted at various points in the forms
+ * life, which currently only involves running the profile checks
+ * before form submission. (more points to be determined in the future)
+ *
+ * See Also:
+ * <dojo.validate.check>
+ *
+ * Parameters:
+ *
+ * id - The form(form id) to register profile with.
+ * profile - The object containing all of the validation/value constraints for the form.
+ */
+ registerProfile:function(id, profile){
+ if (!this.forms[id]) {
+ dojo.raise("registerProfile(" + id + ") No form previously registered with that id.");
+ return;
+ }
+
+ this.forms[id].profiles.push(profile);
+ },
+
+ /**
+ * Function: clearProfiles
+ *
+ * Clears any previously registered validation profiles
+ * on the specified form. Normally called during XHR requests
+ * by returned JS response to ensure new validation logic coming
+ * in from potentially new form fields is accounted for.
+ *
+ * Parameters:
+ *
+ * id - The form id to clear profiles for.
+ */
+ clearProfiles:function(id){
+ if (!this.forms[id]) return;
+
+ for (var i=0; i < this.forms[id].profiles.length; i++) {
+ delete this.forms[id].profiles[i];
+ }
+ this.forms[id].profiles=[];
+ },
+
+ inputClicked:function(e){
+ var node = e.currentTarget;
+ if(node.disabled || dj_undef("form", node)) { return; }
+ this.forms[node.form.getAttribute("id")].clickedButton = node;
+ },
+
+ /**
+ * Function: setFormValidating
+ *
+ * If a form registered with the specified formId
+ * exists a local property will be set that causes
+ * validation to be turned on/off depending on the argument.
+ *
+ * Parameters:
+ *
+ * formId - The id of the form to turn validation on/off for.
+ * validate - Boolean for whether or not to validate form, if not specified assumes true.
+ */
+ setFormValidating:function(formId, validate){
+ if (this.forms[formId]){
+ this.forms[formId].validateForm = validate;
+ }
+ },
+
+ /**
+ * Event connected function that is invoked when a form
+ * is submitted.
+ */
+ onFormSubmit:function(evt){
+ if(!evt || dj_undef("target", evt)) {
+ dojo.raise("No valid form event found with argument: " + evt);
+ return;
+ }
+
+ var id=evt.target.getAttribute("id");
+ if (!id) {
+ dojo.raise("Form had no id attribute.");
+ return;
+ }
+ var form = dojo.byId(id);
+
+ if (!dj_undef("value", form.submitmode)
+ && (form.submitmode.value == "cancel" || form.submitmode.value == "refresh")) {
+ return;
+ }
+
+ if (!tapestry.form.validation.validateForm(form, this.forms[id])) {
+ dojo.event.browser.stopEvent(evt);
+ }
+ },
+
+ /**
+ * Function: submit
+ *
+ * Submits the form specified, optionally setting the submitname
+ * hidden input field to the value of submitName to let the Form
+ * component on server know which button caused the submission. (For
+ * the case of submit button listeners).
+ *
+ * Parameters:
+ *
+ * form - The form(form id) to submit.
+ * submitName - Optional submit name string to use when submitting. This is used
+ * to associate a form submission with a particular component, like a
+ * Submit/LinkSubmit/etc..
+ * parms - Optional extra set of arguments that can control the form submission semantics
+ * such as url/async/json/etc.
+ */
+ submit:function(form, submitName, parms){
+ form=dojo.byId(form);
+ if (!form) {
+ dojo.raise("Form not found with id " + form);
+ return;
+ }
+ var id=form.getAttribute("id");
+ if (submitName){
+ form.submitname.value = submitName;
+ }
+
+ if (!dj_undef("value", form.submitmode)
+ && (form.submitmode.value == "cancel" || form.submitmode.value == "refresh")
+ && !parms) {
+ form.submit();
+ return;
+ }
+
+ if (!tapestry.form.validation.validateForm(form, this.forms[id])) {
+ return;
+ }
+
+ if (parms && !dj_undef("async", parms) && parms.async) {
+ tapestry.form.submitAsync(form, null, submitName, parms);
+ return;
+ } else if(!dj_undef(id, this.forms) && this.forms[id].async){
+ tapestry.form.submitAsync(form);
+ return;
+ }
+
+ form.submit();
+ },
+
+ /**
+ * Function: cancel
+ *
+ * Submits the form to the server in "cancel" mode, invoking any cancel listeners
+ * registered to the server side equivalent to the form passed in.
+ *
+ * Parameters:
+ *
+ * form - The form(form id) to cancel.
+ * submitName - Optional submit name string to use when submitting. This is used
+ * to associate a form submission with a particular component, like a
+ * Submit/LinkSubmit/etc..
+ * parms - Optional object parms passed through to tapestry.form.submit().
+ */
+ cancel:function(form, submitName, parms){
+ form=dojo.byId(form);
+ if (!form){
+ dojo.raise("Form not found with id " + form);
+ return;
+ }
+
+ var formName=form.getAttribute("id");
+ var validateState=tapestry.form.forms[formName].validateForm;
+ tapestry.form.setFormValidating(formName, false);
+
+ var previous = form.submitmode.value;
+ form.submitmode.value="cancel";
+
+ if (parms && !dj_undef("async", parms) && parms.async){
+ this.submitAsync(form, null, submitName, parms);
+ } else {
+ this.submit(form, submitName, parms);
+ }
+
+ form.submitmode.value = previous;
+ tapestry.form.setFormValidating(formName, validateState);
+ },
+
+ /**
+ * Function: refresh
+ *
+ * Submits the form to the server in "refresh" mode, invoking any refresh listeners
+ * registered to the server side equivalent to the form passed in.
+ *
+ * Parameters:
+ *
+ * form - The form(form id) to refresh.
+ * submitName - Optional submit name string to use when submitting. This is used
+ * to associate a form submission with a particular component, like a
+ * Submit/LinkSubmit/etc..
+ * parms - Optional object parms passed through to tapestry.form.submit().
+ */
+ refresh:function(form, submitName, parms){
+ form=dojo.byId(form);
+ if (!form){
+ dojo.raise("Form not found with id " + form);
+ return;
+ }
+
+ var formName=form.getAttribute("id");
+ var validateState=tapestry.form.forms[formName].validateForm;
+ tapestry.form.setFormValidating(formName, false);
+
+ var previous = form.submitmode.value;
+ form.submitmode.value="refresh";
+
+ if (parms && !dj_undef("async", parms) && parms.async){
+ this.submitAsync(form, null, submitName, parms);
+ } else {
+ this.submit(form, submitName, parms);
+ }
+
+ form.submitmode.value = previous;
+ tapestry.form.setFormValidating(formName, validateState);
+ },
+
+ /**
+ * Function: submitAsync
+ *
+ * Does almost the same thing as <tapestry.form.submit>,
+ * but submits the request via XHR to the server asynchronously.
+ *
+ * Parameters:
+ *
+ * form - The form(form id) to submit.
+ * content - Optional content map, mainly used to pass in browser
+ * event parameters to form submission, but can be any
+ * typical form/value pair.
+ * submitName - Optional submit name string to use when submitting.
+ * parms - Optional set of extra parms that can override the defautls for
+ * this specific form submission, like the url/async/json behaviour of
+ * the submission.
+ */
+ submitAsync:function(form, content, submitName, parms){
+ form=dojo.byId(form);
+ if (!form) {
+ dojo.raise("Form not found with id " + id);
+ return;
+ }
+ var formId=form.getAttribute("id");
+
+ if (!tapestry.form.validation.validateForm(form, this.forms[formId])) {
+ dojo.log.debug("Form validation failed for form with id " + formId);
+ return;
+ }
+
+ if (submitName){
+ var previous = form.submitname.value;
+ form.submitname.value=submitName;
+ if(!content){ content={}; }
+ if(form[submitName]){
+ content[submitName]=form[submitName].value;
+ }
+ }
+
+ // handle submissions from input buttons
+ if (!dj_undef("clickedButton", this.forms[formId])) {
+ if (!content) { content={}; }
+ content[this.forms[formId].clickedButton.getAttribute("name")]=this.forms[formId].clickedButton.getAttribute("value");
+ delete this.forms[formId].clickedButton;
+ }
+
+ var kwArgs={
+ formNode:form,
+ content:content,
+ useCache:true,
+ preventCache:true,
+ error: (function(){tapestry.error.apply(this, arguments);}),
+ encoding: tapestry.requestEncoding
+ };
+
+ // check for override
+ if (parms){
+ if (!dj_undef("url", parms)) { kwArgs.url=parms.url; }
+ }
+
+ if (this.forms[formId].json || parms && parms.json) {
+ kwArgs.headers={"json":true};
+ kwArgs.mimetype="text/json";
+ kwArgs.load=(function(){tapestry.loadJson.apply(this, arguments);});
+ } else {
+ kwArgs.headers={"dojo-ajax-request":true};
+ kwArgs.mimetype="text/xml";
+ kwArgs.load=(function(){tapestry.load.apply(this, arguments);});
+ }
+ tapestry.requestsInFlight++;
+ dojo.io.queueBind(kwArgs);
+
+ if (submitName){
+ form.submitname.value = previous;
+ }
+ }
+}
+
+tapestry.form.validation={
+
+ missingClass:"fieldMissing", // default css class that will be applied to fields missing a value
+ invalidClass:"fieldInvalid", // default css class applied to fields with invalid data
+
+ dialogName:"tapestry:AlertDialog",
+
+ /**
+ * Main entry point for running form validation. The
+ * props object passed in contains a number of fields that
+ * are managed by tapestry.form:
+ *
+ * props = {
+ * validateForm:[true|false] // whether to run validation at all
+ * profiles:[profile1, profile2] // set of dojo.validate.check() style profiles
+ * // that may have been registered with form
+ * }
+ *
+ * The individual profiles will contain any of the data described by the dojo documentation
+ * for dojo.validate.check(). In addition to that, each profile will also have a corresponding
+ * string message to display if the specified condition has been met. For example, if you have
+ * specified that a select field named "select1" was required your profile would look something
+ * like:
+ *
+ * profile = {
+ * "required":["select1"], // normal dojo.validate.check data
+ * "select1":{ // tapestry field/error type specific data
+ * "required":"You must select a value for select1."
+ * }
+ * }
+ *
+ * It is intended for you to call dojo.validate.check(form, profile) for each profile
+ * stored in the "profiles" field, as well as deciding how to display errors / warnings.
+ *
+ * @return Boolean indicating if form submission should continue. If false the form
+ * will ~not~ be submitted.
+ */
+ validateForm:function(form, props){
+ if (typeof form == "undefined") {return false;}
+ if (typeof props == "undefined") {return true;} // form exists but no profile? just submit I guess..
+ if (!props.validateForm) {return true;}
+
+ try {
+ this.clearValidationDecorations(form, props);
+
+ for (var i=0; i < props.profiles.length; i++) {
+ var results=dojo.validate.check(form, props.profiles[i]);
+ if (!this.processResults(form, results, props.profiles[i])) {
+ this.summarizeErrors(form, results, props.profiles[i]);
+ return false;
+ }
+ }
+ } catch (e) {
+ // since so many dynamic function calls may happen in here it's best that we
+ // catch all of them and log them or else peoples forms might still get submitted
+ // and they'd never be able to figure out what was wrong
+ dojo.log.exception("Error validating", e, true);
+ return false;
+ }
+
+ return true;
+ },
+
+ /**
+ * Called for each registered profile on a form after
+ * dojo.validate.check() has been called. This function is
+ * expected to do UI related notifications of fields in error.
+ *
+ * @param form The form that was validated.
+ * @param results The result of calling dojo.validate.check(form,profile)
+ * @param profile The original profile used to validate form, also holds
+ * validation error messages to be used for each field.
+ *
+ * @return Boolean, if false form should not be submitted and all validation
+ * should be stopped. If true validation will continue and eventually
+ * form will be submitted.
+ */
+ processResults:function(form, results, profile){
+ if (results.isSuccessful()) { return true; }
+
+ var formValid=true;
+ if (results.hasMissing()) {
+ var missing=results.getMissing();
+ for (var i=0; i < missing.length; i++) {
+ this.handleMissingField(missing[i], profile);
+ }
+
+ formValid=false;
+ }
+
+ if (results.hasInvalid()) {
+ var invalid=results.getInvalid();
+ for (var i=0; i < invalid.length; i++) {
+ this.handleInvalidField(invalid[i], profile);
+ }
+
+ formValid=false;
+ }
+
+ return formValid; // if got past successful everything is invalid
+ },
+
+ /**
+ * Default field decorator for missing fields.
+ *
+ * @param field The field element that was missing data.
+ * @param profile The form validation profile.
+ */
+ handleMissingField:function(field, profile){
+ field=dojo.byId(field);
+ if (dj_undef("type", field)) {return;}
+ dojo.html.removeClass(field, this.invalidClass);
+
+ if (!dojo.html.hasClass(field, this.missingClass)){
+ dojo.html.prependClass(field, this.missingClass);
+ }
+ },
+
+ /**
+ * Default field decorator for invalid fields.
+ *
+ * @param field The field element that had invalid data.
+ * @param profile The form validation profile.
+ */
+ handleInvalidField:function(field, profile){
+ field=dojo.byId(field);
+ if (dj_undef("type", field)) {return;}
+ dojo.html.removeClass(field, this.missingClass);
+
+ if (!dojo.html.hasClass(field, this.invalidClass)){
+ dojo.html.prependClass(field, this.invalidClass);
+ }
+ },
+
+ /**
+ * Clears out previous css classes set on fields
+ * in error.
+ */
+ clearValidationDecorations:function(form, props){
+
+ for (var i=0; i < props.profiles.length; i++) {
+
+ for (var fieldName in props.profiles[i]) {
+ if (dj_undef("type", form.elements[fieldName]) || typeof form.elements[fieldName].type == "undefined"
+ || form.elements[fieldName].type == "submit"
+ || form.elements[fieldName].type == "hidden") { continue; }
+
+ dojo.html.removeClass(form.elements[fieldName], this.missingClass);
+ dojo.html.removeClass(form.elements[fieldName], this.invalidClass);
+ }
+ }
+ },
+
+ /**
+ * Optionally allows an alert dialog/dhtml dialog/etc to
+ * be displayed to user to alert them to the invalid state
+ * of their form if validation errors have occurred.
+ *
+ * @param form The form being validated.
+ * @param results Returned value of dojo.validate.check(form, profile)
+ * @param profile Validation profile definition
+ */
+ summarizeErrors:function(form, results, profile){
+ var merrs=[];
+ var ierrs=[];
+ tapestry.form.currentFocus=null;
+
+ if (results.hasMissing()){
+ var fields=results.getMissing();
+ for (var i=0; i<fields.length; i++){
+ if(i==0 && !tapestry.form.currentFocus){
+ tapestry.form.currentFocus=fields[i];
+ }
+ if (profile[fields[i]] && profile[fields[i]]["required"]){
+ if (dojo.lang.isArray(profile[fields[i]]["required"])) {
+ for (var z=0; z < profile[fields[i]]["required"].length; z++)
+ merrs.push(profile[fields[i]]["required"][z]);
+ } else
+ merrs.push(profile[fields[i]]["required"]);
+ }
+ }
+ }
+ if (results.hasInvalid()){
+ var fields=results.getInvalid();
+ for (var i=0; i<fields.length; i++){
+ if(i==0 && !tapestry.form.currentFocus){
+ tapestry.form.currentFocus=fields[i];
+ }
+ if (profile[fields[i]] && profile[fields[i]]["constraints"]){
+ if (dojo.lang.isArray(profile[fields[i]]["constraints"])) {
+ for (var z=0; z < profile[fields[i]]["constraints"].length; z++)
+ ierrs.push(profile[fields[i]]["constraints"][z]);
+ } else
+ ierrs.push(profile[fields[i]]["constraints"]);
+ }
+ }
+ }
+
+ var msg="";
+ if (merrs.length > 0) {
+ msg+='<ul class="missingList">';
+ for (var i=0; i<merrs.length;i++) {
+ msg+="<li>"+merrs[i]+"</li>";
+ }
+ msg+="</ul>";
+ }
+ if (ierrs.length > 0) {
+ msg+='<ul class="invalidList">';
+ for (var i=0; i<ierrs.length;i++) {
+ msg+="<li>"+ierrs[i]+"</li>";
+ }
+ msg+="</ul>";
+ }
+
+ dojo.require("dojo.widget.*");
+ dojo.require("tapestry.widget.AlertDialog");
+
+ var ad=dojo.widget.byId("validationDialog");
+ if (ad) {
+ ad.setMessage(msg);
+ ad.show();
+ return;
+ }
+
+ var node=document.createElement("span");
+ document.body.appendChild(node);
+ var dialog=dojo.widget.createWidget(this.dialogName,
+ {
+ widgetId:"validationDialog",
+ message:msg
+ }, node);
+ dialog.show();
+ },
+
+ /**
+ * Validates that the input value matches the given
+ * regexp pattern.
+ *
+ * @param value The string value to be evaluated.
+ * @param pattern The regexp pattern used to match against value.
+ */
+ isValidPattern:function(value, pattern){
+ if (typeof value != "string" || typeof pattern != "string") { return false; }
+
+ var re = new RegExp(pattern);
+ return re.test(value);
+ },
+
+ isPalleteSelected:function(elem){
+ return elem.length > 0;
+ },
+
+ /**
+ * Validates that the input value is equal with the value of the given input control.
+ */
+ isEqual:function(value, other){
+ var otherValue = dojo.byId(other).value;
+ return value == otherValue;
+ },
+
+ /**
+ * Validates that the input value is not equal with the value of the given input control.
+ */
+ isNotEqual:function(value, other){
+ return !tapestry.form.validation.isEqual(value, other);
+ },
+
+ /**
+ * Checks that the value given is greater than or equal to the value of
+ * minString. Uses dojo.i18n.number.parse() to parse out the values using
+ * the locale settings configured for the current page.
+ */
+ greaterThanOrEqual:function(value, minString, flags){
+ dojo.require("dojo.i18n.number");
+ flags.validate=false;
+ var min = dojo.i18n.number.parse(minString, null, flags);
+ var num = dojo.i18n.number.parse(value, null, flags);
+ if (Number.NaN == num) { return false; }
+
+ return num >= min;
+ },
+
+ /**
+ * Checks that the value given is less than or equal to the value of
+ * maxString. Uses dojo.i18n.number.parse() to parse out the values using
+ * the locale settings configured for the current page.
+ */
+ lessThanOrEqual:function(value, maxString, flags){
+ dojo.require("dojo.i18n.number");
+ flags.validate=false;
+ var max = dojo.i18n.number.parse(maxString, null, flags);
+ var num = dojo.i18n.number.parse(value, null, flags);
+ if (Number.NaN == num) { return false; }
+
+ return num <= max;
+ },
+
+ isText:dojo.validate.isText,
+
+ isEmailAddress:function(){
+ dojo.require("dojo.validate.web");
+ return dojo.validate.isEmailAddress.apply(dojo.validate, arguments);
+ },
+
+ isReal:function(){
+ dojo.require("dojo.i18n.number");
+ return dojo.i18n.number.isReal.apply(dojo.i18n.number, arguments);
+ }
+
+}
+
+tapestry.form.datetime={
+
+ /**
+ * Checks if the specified value is a valid date, according to
+ * the flags passed in.
+ *
+ * @param value The string value of the date being validated.
+ * @param flags An object.
+ * flags.format A string format pattern that will be used to validate
+ * the incoming value via @link dojo.validate.isValidDate(value, format).
+ * flags.max A string date value representing the maximum date that can be selected.
+ * flags.min A string date value representing the minimum date that can be selected.
+ * @return Boolean. True if valid, false otherwise.
+ */
+ isValidDate:function(value, flags){
+ if(!value){return false;}
+
+ if (!flags){
+ dojo.raise("isValidDate: value and flags must be specified");
+ return;
+ }
+
+ // parse date value
+ var dateValue=null;
+ try {
+ dateValue = dojo.date.parse(value, flags);
+ } catch (e) {
+ dojo.log.exception("Error parsing input date.", e, true);
+ return false;
+ }
+
+ if(dateValue == null) { return false; }
+
+ // convert to format that is validatable
+ value=dojo.date.format(dateValue, flags);
+
+ // TODO: This is totally useless right now, doesn't even accept formats with string equivs
+ // See a better method http://www.mattkruse.com/javascript/date/source.html
+ // basic format validation
+ // if (!dojo.validate.isValidDate(value, flags.format))
+ // return false;
+
+ // max date
+ if (!dj_undef("max", flags)){
+ if (typeof flags.max == "string"){
+ flags.max=dojo.date.parse(flags.max, flags);
+ }
+ if (dojo.date.compare(dateValue, flags.max, dojo.date.compareTypes.DATE) > 0)
+ return false;
+ }
+
+ // min date
+ if (!dj_undef("min", flags)){
+ if (typeof flags.min == "string"){
+ flags.min=dojo.date.parse(flags.min, flags);
+ }
+ if (dojo.date.compare(dateValue, flags.min, dojo.date.compareTypes.DATE) < 0)
+ return false;
+ }
+
+ return true;
+ }
+
+}
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry-4.1.5/form.js
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry-4.1.5/form.js
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry-4.1.5/form.js
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry-4.1.5/fx.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry-4.1.5/fx.js?rev=618461&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry-4.1.5/fx.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry-4.1.5/fx.js Mon Feb 4 14:07:13 2008
@@ -0,0 +1,166 @@
+dojo.provide("tapestry.fx");
+dojo.require("tapestry.core");
+
+/**
+ * package: tapestry.fx
+ * Provides handling of effects applied before, during or after an XHR request/response.
+ */
+tapestry.fx={
+
+ // property: preEffects
+ // Contains a reference to all registered pre-effects, i.e. effects that are
+ // executed before an XHR request.
+ preEffects:{},
+ // property: postEffects
+ // Contains a reference to all registered post-effects, i.e. effects that are
+ // executed when new content arrives through an XHR response.
+ postEffects:{},
+ // property: ajaxStatusAction
+ ajaxStatusAction:'loading',
+
+ /**
+ * Function: attachPreEffect
+ * Schedules the execution of an effect when the specified link
+ * is clicked (and thus an XHR request begins).
+ *
+ * See Also:
+ * <tapestry.fx.attachPostEffect>
+ * <dojo.lfx.IAnimation>
+ *
+ * Parameters:
+ * triggerId - The clientId of the DirectLink that triggers the effect.
+ * animationFunc - A function that returns the animation to execute.
+ * async - Boolean for whether to execute the effect in parallel to the
+ * XHR request. Defaults to false, i.e. the XHR is blocked until
+ * the effect ends.
+ *
+ * Note:
+ * Here's an example usage:
+ * tapestry.fx.attachPreEffect("DirectLink",
+ * function(){return dojo.lfx.wipeOut("entry", 800, dojo.lfx.easeDefault) });
+ */
+ attachPreEffect:function(triggerId, animationFunc, async){
+ if (dojo.lang.isEmpty(this.preEffects))
+ this._initPreEffects();
+ this.preEffects[triggerId] = {async:async, animation:animationFunc};
+ },
+
+ /**
+ * Function: attachPostEffect
+ * Schedules the execution of an effect when the specified content
+ * is returned through an XHR response.
+ *
+ * See Also:
+ * <tapestry.fx.attachPreEffect>
+ * <dojo.lfx.IAnimation>
+ *
+ * Parameters:
+ * updateId - The id of a dom node that (when updated) triggers the effect.
+ * animationFunc - A function that returns the animation to execute.
+ *
+ * Note:
+ * Here's an example usage:
+ * tapestry.fx.attachPostEffect("entry",
+ * function(){return dojo.lfx.wipeIn("entry", 1500, dojo.lfx.easeDefault) });
+ */
+ attachPostEffect:function(updateId, animationFunc){
+ if (dojo.lang.isEmpty(this.postEffects))
+ this._initPostEffects();
+ this.postEffects[updateId] = {animation:animationFunc};
+ },
+
+ /**
+ * Function: removeAll
+ * Removes all registered effects (preEffects and postEffects).
+ */
+ removeAll:function(){
+ this.preEffects={};
+ this.postEffects={};
+ },
+
+ /**
+ * Function: attachAjaxStatus
+ * Allows specifying a dom node that will be shown or hidden while ajax requests
+ * are in progress or have finished.
+ * Alternatively, one can specify a custom
+ * function which will get invoked when an ajax request starts or ends - the first
+ * argument to that function will be a boolean corresponding to wheather the status
+ * element should be showing or not.
+ *
+ * Parameters:
+ * a1 - The dom id to show - hide, or the function to invoke when ajax starts or ends.
+ */
+ attachAjaxStatus:function(a1){
+ dojo.log.debug("Attaching ajax status listener");
+ if (dojo.lang.isString(a1)) {
+ tapestry.fx.ajaxStatusAction =
+ function(bShow){if (bShow) dojo.html.show(a1); else dojo.html.hide(a1);};
+ }
+ else if (dojo.lang.isFunction(a1)) {
+ tapestry.fx.ajaxStatusAction = a1;
+ }
+ else {
+ dojo.log.warn("Argument to tapestry.fx.attachAjaxStatus should be either a string or a function");
+ return;
+ }
+ dojo.event.connectOnce(dojo.io, "queueBind", tapestry.fx._processAjaxStatus);
+ dojo.event.connectOnce(tapestry, "error", tapestry.fx._processAjaxStatus);
+ dojo.event.connectOnce(tapestry, "load", tapestry.fx._processAjaxStatus);
+ dojo.event.connectOnce(tapestry, "loadJson", tapestry.fx._processAjaxStatus);
+ },
+
+ _processAjaxStatus:function(){
+ tapestry.fx.ajaxStatusAction.apply(this, [tapestry.isServingRequests()]);
+ },
+
+ _initPreEffects:function(){
+ dojo.log.debug("Advising tapestry.linkOnClick");
+ dojo.event.connectAround(tapestry, "linkOnClick", tapestry.fx, "_applyPreEffects");
+ },
+
+ _initPostEffects:function(){
+ dojo.log.debug("Advising tapestry.loadContent");
+ dojo.event.connectAround(tapestry, "loadContent", tapestry.fx, "_applyPostEffects");
+ },
+
+ _applyPreEffects:function(miObj){
+ var id = miObj.args[1];
+ var effect = this.preEffects[id];
+ if (effect){
+ dojo.log.debug("Found pre-effect:", effect, id);
+
+ var anim = effect.animation();
+
+ if (effect.async){
+ anim.play();
+ return miObj.proceed();
+ }
+ else{
+ anim.connect("onEnd", function(){ miObj.proceed(); });
+ anim.play();
+ return false;
+ }
+ }
+ else{
+ return miObj.proceed();
+ }
+ },
+
+ _applyPostEffects:function(miObj){
+ var id = miObj.args[0];
+ var effect = this.postEffects[id];
+ if (effect){
+ dojo.log.debug("Found post-effect:", effect, id);
+
+ var ret = miObj.proceed();
+
+ var anim = effect.animation();
+ anim.play();
+
+ return ret;
+ }
+ else{
+ return miObj.proceed();
+ }
+ }
+}
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry-4.1.5/fx.js
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry-4.1.5/fx.js
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry-4.1.5/fx.js
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry-4.1.5/namespace.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry-4.1.5/namespace.js?rev=618461&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry-4.1.5/namespace.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry-4.1.5/namespace.js Mon Feb 4 14:07:13 2008
@@ -0,0 +1,28 @@
+dojo.provide("tapestry.namespace");
+
+dojo.require("dojo.ns");
+
+(function(){
+
+ var map = {
+ html: {
+ "alertdialog": "tapestry.widget.AlertDialog",
+ "timepicker": "tapestry.widget.TimePicker"
+ }
+ };
+
+ function resolveNamespace(name, domain){
+ if(!domain){ domain="html"; }
+ if(!map[domain]){ return null; }
+ return map[domain][name];
+ }
+
+ var tpath;
+ if (dojo.hostenv.moduleHasPrefix("tapestry")){
+ tpath=dojo.hostenv.getModulePrefix("tapestry");
+ } else {
+ tpath="../tapestry";
+ }
+ dojo.registerNamespaceManifest("tapestry", tpath, "tapestry", "tapestry.widget");
+ dojo.registerNamespaceResolver("tapestry", resolveNamespace);
+})();
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry-4.1.5/namespace.js
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry-4.1.5/namespace.js
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry-4.1.5/namespace.js
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry-4.1.5/skeleton/core.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry-4.1.5/skeleton/core.js?rev=618461&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry-4.1.5/skeleton/core.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry-4.1.5/skeleton/core.js Mon Feb 4 14:07:13 2008
@@ -0,0 +1,165 @@
+/**
+ * This is a skeleton file. It contains the
+ * javascript objects and methods that tapestry requires.
+ *
+ * It should be used as a reference for building implementations
+ * specific to existing javascript frameworks.
+ */
+
+// the two required objects, dojo and tapestry
+var dojo={
+ // those methods should only be needed for the dojo implementations
+ // others will probably leave those empty
+ registerModulePath: function() {tapestry.log('dojo.registerModulePath', arguments);},
+ require: function() {tapestry.log('dojo.require', arguments);}
+};
+
+var tapestry={
+ // setup firebug logging - useful for finding unimplemented methods
+ log: function() {
+ if (window.console) console.log.apply(this, arguments);
+ },
+ /**
+ * Executes the passed function when the document has done loading
+ */
+ addOnLoad: function(fn) {
+ tapestry.log('t.addOnLoad');
+ },
+ /**
+ * Returns the dom node with the given id
+ */
+ byId: document.getElementById,
+
+ /**
+ * Makes sure that the given namespace (passed as a string) exists
+ * and is a valid javascript object.
+ */
+ provide: function() {tapestry.log('t.provide', arguments);},
+
+ /**
+ * Connects the event of the given target node to the given function of
+ * the global namespace "tapestry".
+ * Users of this method usually attach custom methods to the tapestry namespace
+ * before calling this.
+ *
+ * Parameters: target, event, funcName
+ */
+ connect: function() {tapestry.log('t.connect', arguments);},
+
+ /**
+ * Disconnects the event of the given target node from the given function of
+ * the global namespace "tapestry"
+ *
+ * Parameters: target, event, funcName
+ */
+ cleanConnect: function() {tapestry.log('t.cleanConnect', arguments);},
+
+ /**
+ * Perform an XHR.
+ * Implementation should set the mime-type to either "text/xml" or
+ * "text/json" and include the request headers described in the comments to the
+ * json parameter.
+ * Implementations are also responsible for handling the responses.
+ *
+ * Parameters:
+ * url - The url to bind the request to.
+ * content - A properties map of optional extra content to send.
+ * json - (Optional) Boolean parameter specifying whether or not to create a
+ * json request. If true, the request headers should include "json":true.
+ * If false or unspecified, they should contain "dojo-ajax-request":true
+ */
+ bind: function(url, content, json){tapestry.log('t.bind', arguments);},
+
+ /**
+ * Helper that builds the content from eventName and (triggered) id and then forwards
+ * execution to tapestry.bind
+ *
+ * @param url
+ * @param id
+ * @param json
+ * @param eventName
+ */
+ linkOnClick: function(url, id, json, eventName) {tapestry.log('t.linkOnClick', arguments);}
+};
+
+tapestry.form = {
+ /**
+ * Submits the specified form.
+ * Should check the value of form.submitmode to find out what type of
+ * submission (cancel, refresh or normal) to do and whether to run client validation.
+ *
+ * Parameters:
+ * form - The form or form id to submit.
+ * submitName - (Optional) Submit name to use when submitting. This is used
+ * to associate a form submission with a particular component.
+ * Implementations will typically just set form.submitname to this value.
+ * parms - (Optional) Extra set of parameters. Implementations can just look for
+ * the async key and if that's set to true, they should perform an async
+ * submission.
+ */
+ submit: function(formId, submitName, parms) {tapestry.log('t.f.submit', arguments);},
+
+ /** Same as submit, but forces cancel submission */
+ cancel: function(formId, submitName, parms) {tapestry.log('t.f.submit', arguments);},
+
+ /** Same as submit, but forces refresh submission */
+ refresh: function(formId, submitName, parms) {tapestry.log('t.f.submit', arguments);},
+
+ /**
+ * Registers a form and allows definition of its properties.
+ * Implementation should keep track of such properties and
+ * use them later on, when the form is submitted.
+ *
+ * Parameters:
+ * id - The form or form id to register.
+ * async - Boolean, if true form submission should be asynchronous.
+ * json - Boolean, if true form submission should be asyncrhronous json.
+ */
+ registerForm: function(formId, async, json) {tapestry.log('t.f.registerForm', arguments);},
+
+ /**
+ * Registers a form validation/translation profile.
+ * TODO: Describe profile structure.
+ *
+ * Parameters:
+ * formId - The form or form id to register profile with.
+ * profile - The object containing all of the validation/value constraints for the form.
+ */
+ registerProfile: function(formId, profile) {tapestry.log('t.f.registerProfile', arguments);},
+
+ /**
+ * Clears any previously registered validation profiles on the specified form.
+ *
+ * Parameters:
+ * formId - The form id to clear profiles for.
+ */
+ clearProfiles: function(formId) {tapestry.log('t.f.clearProfiles', arguments);},
+
+ /**
+ * Brings keyboard input focus to the specified field.
+ */
+ focusField: function(fieldId) {tapestry.log('t.f.focusField', arguments);},
+
+ // TODO: Describe validation methods
+ datetime: {
+ isValidDate: function(date) {tapestry.log('t.f.d.isValidDate', arguments);return true;}
+ },
+
+ validation: {
+ isReal: function() {tapestry.log('t.f.v.isReal', arguments);return true;},
+ greaterThanOrEqual: function() {tapestry.log('t.f.v.greaterThanOrEqual', arguments);return true;},
+ lessThanOrEqual: function() {tapestry.log('t.f.v.lessThanOrEqual', arguments);return true;},
+ isText: function() {tapestry.log('t.f.v.isText', arguments);return true;},
+ isEmailAddress: function() {tapestry.log('t.f.v.isEmailAddress', arguments);return true;},
+ isValidPattern: function() {tapestry.log('t.f.v.isValidPattern', arguments);return true;},
+ validateForm: function() {tapestry.log('t.f.v.validateForm', arguments);return true;}
+ }
+};
+
+tapestry.event = {
+ stopEvent: function() {tapestry.log('t.e.stopEvent', arguments);}
+};
+
+tapestry.widget = {
+ synchronizeWidgetState: function() {tapestry.log('t.w.synchronizeWidgetState', arguments);}
+};
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry-4.1.5/skeleton/core.js
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry-4.1.5/skeleton/core.js
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry-4.1.5/skeleton/core.js
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry-4.1.5/test.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry-4.1.5/test.js?rev=618461&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry-4.1.5/test.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry-4.1.5/test.js Mon Feb 4 14:07:13 2008
@@ -0,0 +1,33 @@
+dojo.provide("tapestry.test");
+
+dojo.require("dojo.logging.Logger");
+dojo.require("dojo.event.browser");
+
+djConfig.locale="en_US";
+
+// override to make sure our fake events pass
+dojo.event.browser.isEvent=function() { return true; }
+
+function lastMsgContains(str){
+ if (arguments.length < 1) return false;
+
+ var last=dojo.logging.logQueueHandler.data.pop();
+ if (!last || !last.message) return false;
+
+ return last.message.toUpperCase().indexOf(str.toUpperCase()) > -1;
+}
+
+// helper object for logging method calls
+function mock(){
+ this.mockArgs=arguments;
+ this.called=false;
+
+ this.intercept=function(){
+ this.called=true;
+ jum.assertEquals("mockArgLength", this.mockArgs.length, arguments.length);
+
+ for (var i=0; i < this.mockArgs.length; i++) {
+ jum.assertEquals("mockArgument", this.mockArgs[i], arguments[i]);
+ }
+ }
+}
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry-4.1.5/test.js
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry-4.1.5/test.js
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry-4.1.5/test.js
------------------------------------------------------------------------------
svn:mime-type = text/plain