[richfaces-svn-commits] JBoss Rich Faces SVN: r6100 - in trunk/sandbox/ui/fileUpload/src/main: java/org/richfaces/org/jboss/seam/web and 3 other directories.

richfaces-svn-commits at lists.jboss.org richfaces-svn-commits at lists.jboss.org
Thu Feb 14 19:46:21 EST 2008


Author: nbelaevski
Date: 2008-02-14 19:46:21 -0500 (Thu, 14 Feb 2008)
New Revision: 6100

Modified:
   trunk/sandbox/ui/fileUpload/src/main/java/org/richfaces/org/jboss/seam/ui/renderkit/FileUploadRendererBase.java
   trunk/sandbox/ui/fileUpload/src/main/java/org/richfaces/org/jboss/seam/web/MultipartFilter.java
   trunk/sandbox/ui/fileUpload/src/main/java/org/richfaces/org/jboss/seam/web/MultipartRequest.java
   trunk/sandbox/ui/fileUpload/src/main/resources/org/richfaces/renderkit/html/css/fileUpload.xcss
   trunk/sandbox/ui/fileUpload/src/main/resources/org/richfaces/renderkit/html/js/FileUpload.js
   trunk/sandbox/ui/fileUpload/src/main/templates/org/richfaces/fileUpload.jspx
Log:
latest changes for file upload

Modified: trunk/sandbox/ui/fileUpload/src/main/java/org/richfaces/org/jboss/seam/ui/renderkit/FileUploadRendererBase.java
===================================================================
--- trunk/sandbox/ui/fileUpload/src/main/java/org/richfaces/org/jboss/seam/ui/renderkit/FileUploadRendererBase.java	2008-02-15 00:46:11 UTC (rev 6099)
+++ trunk/sandbox/ui/fileUpload/src/main/java/org/richfaces/org/jboss/seam/ui/renderkit/FileUploadRendererBase.java	2008-02-15 00:46:21 UTC (rev 6100)
@@ -1,15 +1,11 @@
 package org.richfaces.org.jboss.seam.ui.renderkit;
 
 import java.io.IOException;
-import java.io.InputStream;
 import java.io.Writer;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Date;
 import java.util.HashMap;
 import java.util.Iterator;
-import java.util.List;
 import java.util.Map;
 
 import javax.el.ValueExpression;
@@ -17,8 +13,6 @@
 import javax.faces.context.FacesContext;
 import javax.faces.context.ResponseWriter;
 import javax.servlet.ServletRequest;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpSession;
 
 import org.ajax4jsf.context.AjaxContext;
@@ -26,11 +20,8 @@
 import org.ajax4jsf.event.AjaxEvent;
 import org.ajax4jsf.javascript.JSFunction;
 import org.ajax4jsf.javascript.JSFunctionDefinition;
+import org.ajax4jsf.javascript.JSReference;
 import org.ajax4jsf.renderkit.AjaxRendererUtils;
-import org.ajax4jsf.renderkit.ComponentVariables;
-import org.ajax4jsf.renderkit.ComponentsVariableResolver;
-import org.ajax4jsf.renderkit.RendererUtils;
-import org.apache.commons.digester.SetRootRule;
 import org.richfaces.component.UIProgressBar;
 import org.richfaces.org.jboss.seam.ui.component.FileItem;
 import org.richfaces.org.jboss.seam.ui.component.ProgressData;
@@ -38,8 +29,6 @@
 import org.richfaces.org.jboss.seam.web.MultipartRequest;
 import org.richfaces.renderkit.TemplateEncoderRendererBase;
 
-import sun.security.action.GetLongAction;
-
 /**
  * Class provides base renderer for upload file component
  * @author "Andrey Markavtsov"
@@ -367,6 +356,22 @@
 	return name.replaceAll("[\\\\]{1}", "\\\\\\\\");
     }
 
+    public String getStopScript(FacesContext context, UIComponent component)
+    	throws IOException {
+
+    	JSFunction ajaxFunction = AjaxRendererUtils.buildAjaxFunction(component, context);
+    	Map options = AjaxRendererUtils.buildEventOptions(context, component);
+    	((Map) options.get("parameters")).put("action", "stop");
+    	((Map) options.get("parameters")).put("uid", new JSReference("uid"));
+    	ajaxFunction.addParameter(options);
+    	
+    	JSFunctionDefinition function = new JSFunctionDefinition("uid");
+    	function.addParameter("event");
+    	function.addToBody(ajaxFunction.toScript());
+    	
+    	return function.toScript();
+    }
+
     public void encodeInitialScript(FacesContext context, UIComponent component)
 	    throws IOException {
 	Writer writer = context.getResponseWriter();
@@ -411,25 +416,25 @@
     
     public void encodeUpdateButtonScript(FacesContext context, UIComponent component)
     	    throws IOException {
-	UIFileUpload fileUpload = (UIFileUpload) component;
-	String cliendId = fileUpload.getClientId(context);
-	Writer writer = context.getResponseWriter();
-	
-	StringBuffer buffer = new StringBuffer();
-	buffer.append(getJSScriptStart(cliendId));
-	boolean hasFileInProgress = fileUpload.hasFilesInProgress();
-	buffer.append(".updateUploadButton(").append(hasFileInProgress)
-	      .append(",")
-	      .append(hasFileInProgress ? false : !fileUpload.isCanUploadAll())
-	      .append(");\n");
-	
-	buffer.append(getJSScriptStart(cliendId)).append(".updateAddButton(")
-		.append(!fileUpload.isCanAdd()).append(");\n");
-		
-	buffer.append(getJSScriptStart(cliendId)).append(".updateCleanButton(")
-	.append(!fileUpload.isCanCleanAll()).append(");\n");
-	
-	writer.write(buffer.toString());
+//	UIFileUpload fileUpload = (UIFileUpload) component;
+//	String cliendId = fileUpload.getClientId(context);
+//	Writer writer = context.getResponseWriter();
+//	
+//	StringBuffer buffer = new StringBuffer();
+//	buffer.append(getJSScriptStart(cliendId));
+//	boolean hasFileInProgress = fileUpload.hasFilesInProgress();
+//	buffer.append(".updateUploadButton(").append(hasFileInProgress)
+//	      .append(",")
+//	      .append(hasFileInProgress ? false : !fileUpload.isCanUploadAll())
+//	      .append(");\n");
+//	
+//	buffer.append(getJSScriptStart(cliendId)).append(".updateAddButton(")
+//		.append(!fileUpload.isCanAdd()).append(");\n");
+//		
+//	buffer.append(getJSScriptStart(cliendId)).append(".updateCleanButton(")
+//	.append(!fileUpload.isCanCleanAll()).append(");\n");
+//	
+//	writer.write(buffer.toString());
     }
 
 
@@ -488,12 +493,13 @@
 	}
     }
 
-    public void renderProgress(FacesContext context, UIComponent component,
-	    FileItem item) throws IOException {
-	if (item.getStatus() == FileItem.Status.IN_PROGRESS) {
+    public String getProgressBarId(FacesContext context, UIComponent component) throws IOException {
+    	return getProgressBar(context, component).getClientId(context);
+    }
+    
+    public void renderProgress(FacesContext context, UIComponent component) throws IOException {
 	    UIComponent progressBar = getProgressBar(context, component);
 	    renderChild(context, progressBar);
-	}
     }
     
     public boolean isCanClear (FileItem item) {

Modified: trunk/sandbox/ui/fileUpload/src/main/java/org/richfaces/org/jboss/seam/web/MultipartFilter.java
===================================================================
--- trunk/sandbox/ui/fileUpload/src/main/java/org/richfaces/org/jboss/seam/web/MultipartFilter.java	2008-02-15 00:46:11 UTC (rev 6099)
+++ trunk/sandbox/ui/fileUpload/src/main/java/org/richfaces/org/jboss/seam/web/MultipartFilter.java	2008-02-15 00:46:21 UTC (rev 6100)
@@ -1,6 +1,10 @@
 package org.richfaces.org.jboss.seam.web;
 
 import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
 
 import javax.servlet.Filter;
 import javax.servlet.FilterChain;
@@ -10,6 +14,7 @@
 import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
 
 /**
  * A filter for decoding multipart requests, for
@@ -57,26 +62,73 @@
       this.maxRequestSize = maxFileSize;
    }   
    
-   public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
-            throws IOException, ServletException
-   {
-      if (!(response instanceof HttpServletResponse))
-      {
-         chain.doFilter(request, response);
-         return;
-      }
+   public void doFilter(ServletRequest request, ServletResponse response,
+			FilterChain chain) throws IOException, ServletException {
+		if (!(response instanceof HttpServletResponse)) {
+			chain.doFilter(request, response);
+			return;
+		}
 
-      HttpServletRequest httpRequest = (HttpServletRequest) request;
-      if (isMultipartRequest(httpRequest))
-      {
-         chain.doFilter(new MultipartRequest(httpRequest, createTempFiles, 
-                  maxRequestSize), response);
-      }
-      else
-      {
-         chain.doFilter(request, response);
-      }
-   }
+		HttpServletRequest httpRequest = (HttpServletRequest) request;
+		String uid = httpRequest.getParameter("uid");
+		if (isMultipartRequest(httpRequest)) {
+			MultipartRequest multipartRequest = new MultipartRequest(
+					httpRequest, createTempFiles, maxRequestSize);
+
+			Map<String, MultipartRequest> sessionsMap = null;
+			try {
+				HttpSession session = httpRequest.getSession();
+				synchronized (session) {
+					sessionsMap = (Map<String, MultipartRequest>) session
+							.getAttribute("_richfaces_upload_sessions");
+					if (sessionsMap == null) {
+						sessionsMap = Collections.synchronizedMap(new HashMap<String, MultipartRequest>());
+						session.setAttribute(
+										"_richfaces_upload_sessions", sessionsMap);
+					}
+				}
+
+				sessionsMap.put(uid, multipartRequest);
+
+				if (multipartRequest.parseRequest()) {
+					chain.doFilter(multipartRequest, response);
+				} else {
+					// TODO
+					HttpServletResponse httpResponse = (HttpServletResponse) response;
+					httpResponse.setStatus(HttpServletResponse.SC_OK);
+					httpResponse.setContentType("text/html");
+
+					PrintWriter writer = httpResponse.getWriter();
+					writer
+							.write("<html id=\"_richfaces_file_upload_stopped\"><body><script>alert('stopped');</script></body></html>");
+					writer.close();
+				}
+			} finally {
+				if (sessionsMap != null) {
+					sessionsMap.remove(uid);
+				}
+			}
+		} else {
+			if ("stop".equals(httpRequest.getParameter("action"))) {
+				HttpSession session = httpRequest.getSession();
+				Map<String, MultipartRequest> sessions = (Map<String, MultipartRequest>) session
+					.getAttribute("_richfaces_upload_sessions");
+
+				if (sessions != null) {
+					MultipartRequest multipartRequest = sessions.get(uid);
+					if (multipartRequest != null) {
+						multipartRequest.stop();
+					}
+				}
+
+				HttpServletResponse httpResponse = (HttpServletResponse) response;
+				httpResponse.setStatus(HttpServletResponse.SC_NO_CONTENT);
+				httpResponse.getOutputStream().close();
+			} else {
+				chain.doFilter(request, response);
+			}
+		}
+	}
    
    private boolean isMultipartRequest(HttpServletRequest request)
    {

Modified: trunk/sandbox/ui/fileUpload/src/main/java/org/richfaces/org/jboss/seam/web/MultipartRequest.java
===================================================================
--- trunk/sandbox/ui/fileUpload/src/main/java/org/richfaces/org/jboss/seam/web/MultipartRequest.java	2008-02-15 00:46:11 UTC (rev 6099)
+++ trunk/sandbox/ui/fileUpload/src/main/java/org/richfaces/org/jboss/seam/web/MultipartRequest.java	2008-02-15 00:46:21 UTC (rev 6100)
@@ -241,6 +241,7 @@
     private long time;
     
     private ProgressData progressData = null;
+	private boolean shouldStop = false;
 
     public MultipartRequest(HttpServletRequest request,
 	    boolean createTempFiles, int maxRequestSize) {
@@ -277,142 +278,152 @@
 	return fileName;
     }
 
-    private void parseRequest() {
-	byte[] boundaryMarker = getBoundaryMarker(request.getContentType());
-	if (boundaryMarker == null) {
-	    throw new FileUploadException("The request was rejected because "
-		    + "no multipart boundary was found");
-	}
+    public boolean parseRequest() {
+    	byte[] boundaryMarker = getBoundaryMarker(request.getContentType());
+    	if (boundaryMarker == null) {
+    		throw new FileUploadException("The request was rejected because "
+    				+ "no multipart boundary was found");
+    	}
 
-	encoding = request.getCharacterEncoding();
+    	encoding = request.getCharacterEncoding();
 
-	parameters = new HashMap<String, Param>();
+    	parameters = new HashMap<String, Param>();
 
-	try {
-	    byte[] buffer = new byte[BUFFER_SIZE];
-	    Map<String, String> headers = new HashMap<String, String>();
+    	try {
+    		byte[] buffer = new byte[BUFFER_SIZE];
+    		Map<String, String> headers = new HashMap<String, String>();
 
-	    ReadState readState = ReadState.BOUNDARY;
+    		ReadState readState = ReadState.BOUNDARY;
 
-	    InputStream input = request.getInputStream();
-	    int read = input.read(buffer);
-	    int pos = 0;
+    		InputStream input = request.getInputStream();
+    		if (!shouldStop) {
 
-	    Param p = null;
+    			int read = input.read(buffer);
+    			int pos = 0;
 
-	    while (read != -1) {
-		for (int i = 0; i < read; i++) {
-		    switch (readState) {
-		    case BOUNDARY: {
-			if (checkSequence(buffer, i, boundaryMarker)
-				&& checkSequence(buffer, i + 2, CR_LF)) {
-			    readState = ReadState.HEADERS;
-			    i += 2;
-			    pos = i + 1;
+    			Param p = null;
 
-			}
-			break;
-		    }
-		    case HEADERS: {
-			if (checkSequence(buffer, i, CR_LF)) {
-			    String param = (encoding == null) ? new String(
-				    buffer, pos, i - pos - 1) : new String(
-				    buffer, pos, i - pos - 1, encoding);
-			    parseParams(param, "; ", headers);
+    			while (read != -1) {
+    				for (int i = 0; i < read; i++) {
+    					switch (readState) {
+    					case BOUNDARY: {
+    						if (checkSequence(buffer, i, boundaryMarker)
+    								&& checkSequence(buffer, i + 2, CR_LF)) {
+    							readState = ReadState.HEADERS;
+    							i += 2;
+    							pos = i + 1;
 
-			    if (checkSequence(buffer, i + CR_LF.length, CR_LF)) {
-				readState = ReadState.DATA;
-				i += CR_LF.length;
-				pos = i + 1;
+    						}
+    						break;
+    					}
+    					case HEADERS: {
+    						if (checkSequence(buffer, i, CR_LF)) {
+    							String param = (encoding == null) ? new String(
+    									buffer, pos, i - pos - 1) : new String(
+    											buffer, pos, i - pos - 1, encoding);
+    									parseParams(param, "; ", headers);
 
-				String paramName = headers.get(PARAM_NAME);
-				if (paramName != null) {
-				    if (headers.containsKey(PARAM_FILENAME)) {
-					FileParam fp = new FileParam(paramName);
-					if (createTempFiles)
-					    fp.createTempFile();
-					fp.setContentType(headers
-						.get(PARAM_CONTENT_TYPE));
-					fp.setFilename(decodeFileName(headers
-						.get(PARAM_FILENAME)));
-					p = fp;
-				    } else {
-					if (parameters.containsKey(paramName)) {
-					    p = parameters.get(paramName);
-					} else {
-					    p = new ValueParam(paramName);
-					}
-				    }
+    									if (checkSequence(buffer, i + CR_LF.length, CR_LF)) {
+    										readState = ReadState.DATA;
+    										i += CR_LF.length;
+    										pos = i + 1;
 
-				    if (!parameters.containsKey(paramName)) {
-					parameters.put(paramName, p);
-				    }
-				}
+    										String paramName = headers.get(PARAM_NAME);
+    										if (paramName != null) {
+    											if (headers.containsKey(PARAM_FILENAME)) {
+    												FileParam fp = new FileParam(paramName);
+    												if (createTempFiles)
+    													fp.createTempFile();
+    												fp.setContentType(headers
+    														.get(PARAM_CONTENT_TYPE));
+    												fp.setFilename(decodeFileName(headers
+    														.get(PARAM_FILENAME)));
+    												p = fp;
+    											} else {
+    												if (parameters.containsKey(paramName)) {
+    													p = parameters.get(paramName);
+    												} else {
+    													p = new ValueParam(paramName);
+    												}
+    											}
 
-				headers.clear();
-			    } else {
-				pos = i + 1;
-			    }
-			}
-			break;
-		    }
-		    case DATA: {
-			// If we've encountered another boundary...
-			if (checkSequence(buffer, i - boundaryMarker.length
-				- CR_LF.length, CR_LF)
-				&& checkSequence(buffer, i, boundaryMarker)) {
-			    // Write any data before the boundary (that hasn't
-			    // already been written) to the param
-			    if (pos < i - boundaryMarker.length - CR_LF.length
-				    - 1) {
-				p.appendData(buffer, pos, i - pos
-					- boundaryMarker.length - CR_LF.length
-					- 1);
-			    }
+    											if (!parameters.containsKey(paramName)) {
+    												parameters.put(paramName, p);
+    											}
+    										}
 
-			    if (p instanceof ValueParam)
-				((ValueParam) p).complete();
+    										headers.clear();
+    									} else {
+    										pos = i + 1;
+    									}
+    						}
+    						break;
+    					}
+    					case DATA: {
+    						// If we've encountered another boundary...
+    						if (checkSequence(buffer, i - boundaryMarker.length
+    								- CR_LF.length, CR_LF)
+    								&& checkSequence(buffer, i, boundaryMarker)) {
+    							// Write any data before the boundary (that hasn't
+    							// already been written) to the param
+    							if (pos < i - boundaryMarker.length - CR_LF.length
+    									- 1) {
+    								p.appendData(buffer, pos, i - pos
+    										- boundaryMarker.length - CR_LF.length
+    										- 1);
+    							}
 
-			    if (checkSequence(buffer, i + CR_LF.length, CR_LF)) {
-				i += CR_LF.length;
-				pos = i + 1;
-			    } else {
-				pos = i;
-			    }
+    							if (p instanceof ValueParam)
+    								((ValueParam) p).complete();
 
-			    readState = ReadState.HEADERS;
-			}
-			// Otherwise write whatever data we have to the param
-			else if (i > (pos + boundaryMarker.length + CHUNK_SIZE + CR_LF.length)) {
-			    p.appendData(buffer, pos, CHUNK_SIZE);
-			    pos += CHUNK_SIZE;
+    							if (checkSequence(buffer, i + CR_LF.length, CR_LF)) {
+    								i += CR_LF.length;
+    								pos = i + 1;
+    							} else {
+    								pos = i;
+    							}
 
-			}
-			break;
-		    }
-		    }
-		}
+    							readState = ReadState.HEADERS;
+    						}
+    						// Otherwise write whatever data we have to the param
+    						else if (i > (pos + boundaryMarker.length + CHUNK_SIZE + CR_LF.length)) {
+    							p.appendData(buffer, pos, CHUNK_SIZE);
+    							pos += CHUNK_SIZE;
 
-		if (pos < read) {
-		    // move the bytes that weren't read to the start of the
-		    // buffer
-		    int bytesNotRead = read - pos;
-		    System.arraycopy(buffer, pos, buffer, 0, bytesNotRead);
-		    read = input.read(buffer, bytesNotRead, buffer.length
-			    - bytesNotRead);
-		    read += bytesNotRead;
-		} else {
-		    read = input.read(buffer);
-		}
-		this.read += pos;
-		pos = 0;
-		fillProgressInfo();
+    						}
+    						break;
+    					}
+    					}
+    				}
 
-	    }
-	} catch (IOException ex) {
-	    throw new FileUploadException("IO Error parsing multipart request",
-		    ex);
-	}
+    				if (!shouldStop) {
+    					if (pos < read) {
+    						// move the bytes that weren't read to the start of the
+    						// buffer
+    						int bytesNotRead = read - pos;
+    						System.arraycopy(buffer, pos, buffer, 0, bytesNotRead);
+    						read = input.read(buffer, bytesNotRead, buffer.length
+    								- bytesNotRead);
+    						read += bytesNotRead;
+    					} else {
+    						read = input.read(buffer);
+    					}
+    					this.read += pos;
+    					pos = 0;
+    					fillProgressInfo();
+    				} else {
+    					return false;
+    				}
+    			}
+
+    			return true;
+    		} else {
+    			return false;
+    		}
+    	} catch (IOException ex) {
+    		throw new FileUploadException("IO Error parsing multipart request",
+    				ex);
+    	}
     }
     
     private ProgressData getProgressData () {
@@ -626,4 +637,8 @@
 
 	return params;
     }
+    
+    public void stop() {
+    	shouldStop = true;
+    }
 }

Modified: trunk/sandbox/ui/fileUpload/src/main/resources/org/richfaces/renderkit/html/css/fileUpload.xcss
===================================================================
--- trunk/sandbox/ui/fileUpload/src/main/resources/org/richfaces/renderkit/html/css/fileUpload.xcss	2008-02-15 00:46:11 UTC (rev 6099)
+++ trunk/sandbox/ui/fileUpload/src/main/resources/org/richfaces/renderkit/html/css/fileUpload.xcss	2008-02-15 00:46:21 UTC (rev 6100)
@@ -23,6 +23,10 @@
 
 .upload_toolbar_decor{ background : #EAF0F8 /*additionalBackgroundColor*/;border-bottom:1px solid #c0c0c0 /*tableBorderColor*/;border-top:1px solid #FFFFFF /*tableBackgroundColor*/;border-left:1px solid #FFFFFF /*tableBackgroundColor*/;padding : 2px}
 
+input[type="file"][class~="hidden"]::-webkit-file-upload-button {
+	font-size: 10em;
+	-webkit-appearance: button;
+}
 
 .upload_button_border{
 	border : 1px solid #C0C0C0; /*tableBorderColor*/

Modified: trunk/sandbox/ui/fileUpload/src/main/resources/org/richfaces/renderkit/html/js/FileUpload.js
===================================================================
--- trunk/sandbox/ui/fileUpload/src/main/resources/org/richfaces/renderkit/html/js/FileUpload.js	2008-02-15 00:46:11 UTC (rev 6099)
+++ trunk/sandbox/ui/fileUpload/src/main/resources/org/richfaces/renderkit/html/js/FileUpload.js	2008-02-15 00:46:21 UTC (rev 6100)
@@ -1,3 +1,385 @@
+LoadWatcher = Class.create();
+Object.extend(LoadWatcher.prototype, {
+	initialize: function(iframe, success, failure) {
+		this.iframe = iframe;
+		this.success = success;
+		this.failure = failure;
+	
+		this.loadObserver = function() {
+			if (!this.stopped) {
+				this.stop();
+				this.success();
+			}
+		}.bind(this);
+
+		Event.observe(this.iframe, 'load', this.loadObserver);
+		
+		this.interval = setInterval(function() {
+			if (!this.stopped) {
+				var loaded = false;
+				var error = null;
+
+				try {
+					if (this.iframe.contentWindow && this.iframe.contentWindow.document) {
+						loaded = /complete/.test(this.iframe.contentWindow.document.readyState);
+					}
+				} catch (e) {
+					error = e;
+				}
+				
+				if (error) {
+					this.stop();
+					this.failure(error);
+				} else if (loaded) {
+					this.stop();
+					this.success();
+				}
+			}
+		}.bind(this), 50);
+	},
+	
+	stop: function() {
+		this.stopped = true;
+		
+		if (this.loadObserver) {
+			Event.stopObserving(this.iframe, 'load', this.loadObserver);
+			this.loadObserver = null;
+		}
+		
+		if (this.interval) {
+			clearInterval(this.interval);
+			this.interval = null;
+		}
+		
+		this.iframe = null;
+	}
+});
+
+
+FileUploadEntry = {};
+FileUploadEntry = Class.create();
+
+FileUploadEntry.template = 
+	[
+	 new E('table', 
+			 {'cellspacing':'0', 'cellpadding':'0', 'border':'0'},
+			 [
+			  new E('tbody',{},
+					  [
+					   new E('tr',{},
+							   [
+							    new E('td',{'className':'upload_font upload_name upload_table_td'},
+							    		[
+							    		 new E('div',{'className':'upload_name_padding'},
+							    				 [
+							    				  new ET(function (context) { return Richfaces.evalMacro("fileName", context)})
+							    				  ]),
+							    				  new E('div',{'id':'progress'}),
+							    				  new E('div',{'className':'upload_name_padding'},
+							    						  [
+							    						   new ET(function (context) { return Richfaces.evalMacro("label", context)})])
+							    		 ]),
+					    		 new E('td',{'style':'vertical-align: center;', 'className':'upload_table_td'},
+					    				 [
+					    				  new E('div',{'className':'upload_font upload_del'},
+					    						  [
+					    						   new E('a',{'style':'text-decoration: none; color:black', 'onclick':function (context) { return 'return $(\''+Richfaces.evalMacro("clientId", context)+'\').component.confirm(\''+Richfaces.evalMacro("clientId", context)+':cconfirm'+Richfaces.evalMacro("n", context)+'\',\''+Richfaces.evalMacro("clientId", context)+':clear'+Richfaces.evalMacro("n", context)+'\');';}, 'id':function (context) { return Richfaces.evalMacro("clientId", context)+':clear'+Richfaces.evalMacro("n", context);}, 'className':'upload_anc', 'href':'#'},
+					    								   [
+					    								    new T('Clear')
+					    								    ])
+					    						   ])
+					    				  ]),
+			    				  new E('td',{'className':'upload_table_td'},
+			    						  [
+			    						   new E('div',{'className':'upload_font upload_scroll'})
+			    						   ])
+							    ])
+					   ])
+			  ])
+	 ];
+
+
+FileUploadEntry.INITIALIZED = "initialized";
+
+FileUploadEntry.UPLOAD_IN_PROGRESS = "progress";
+
+FileUploadEntry.UPLOAD_CANCELED = "canceled";
+FileUploadEntry.UPLOAD_SUCCESS = "success";
+FileUploadEntry.UPLOAD_TRANSFER_ERROR = "transfer_error";
+FileUploadEntry.UPLOAD_SERVER_ERROR = "server_error";
+
+
+Object.extend(FileUploadEntry.prototype, {
+
+	element: null,
+	
+	uploadObject: null,
+
+	state: null,
+	
+	initialize: function(element, uploadObject) {
+		this.element = element;
+		this.uploadObject = uploadObject;
+		this.setState(FileUploadEntry.INITIALIZED);
+	
+		var content = FileUploadEntry.template.invoke('getContent', {fileName: $F(this.element)}).join('');
+		
+		Element.insert(this.uploadObject.items, content);
+	
+		this.entryElement = this.uploadObject.items.childNodes[this.uploadObject.items.childNodes.length - 1];
+	},
+	
+	upload: function() {
+		this.setState(FileUploadEntry.UPLOAD_IN_PROGRESS);
+		this.uploadObject.submitForm(this);
+	},
+	
+	stop: function() {
+		this.uploadObject.stopScript(this.uid);
+		this.setState(FileUploadEntry.UPLOAD_CANCELED);
+	},
+	
+	clear: function() {
+		//todo review
+		//this.uploadObject.remove(this);
+		this.element.parentNode.removeChild(this.element);
+		this.entryElement.parentNode.removeChild(this.entryElement);
+	},
+	
+	setState: function(newState) {
+		var oldState = this.state;
+		this.state = newState;
+		this.uploadObject.notifyStateChange(this, oldState);
+	}
+	
+});
+
+
+FileUpload1 = {};
+FileUpload1 = Class.create();
+
+Object.extend(FileUpload1.prototype, {
+	
+	idCounter: 0,
+	
+	progressBar: null,
+
+	iframe: null,
+	
+	element: null,
+	
+	entries: new Array(),
+	
+	activeEntry: null,
+	
+	options: null,
+	
+	runUpload: false,
+	
+	initialize: function(id, stopScript, progressBarId, options) {
+		this.id = id;
+		this.element = $(this.id);
+		this.progressBar = $(progressBarId).component;
+		
+		this.element.component = this;
+		
+		this.stopScript = stopScript;
+		
+		this.iframe = $(this.id + "_iframe");
+		this.items = $(this.id + ":fileItems");
+		this.options = options || {};
+		
+		this.setupAutoUpload();
+	},
+	
+	setupAutoUpload: function() {
+		this.runUpload = this.options.autoUpload;
+	},
+	
+	add: function(elt) {
+		this.entries.push(new FileUploadEntry(elt, this));
+		
+		var newUpload = elt.cloneNode(true);
+		newUpload.id = this.id + ":file" + (this.idCounter++);
+		$(this.id + ":add1").appendChild(newUpload);
+		
+		if (this.runUpload) {
+			this.upload();
+		}
+	},
+	
+	remove: function(entry) {
+		this.entries = this.entries.without(entry);
+	},
+	
+	_selectEntryForUpload: function() {
+		var l = this.entries.length;
+		for (var i = 0; i < l; i++) {
+			var entry = this.entries[i];
+			if (entry.state != FileUploadEntry.UPLOAD_SUCCESS) {
+
+				return entry;
+			}
+		}
+
+		return null;
+	},
+	
+	upload: function() {
+		this.runUpload = true;
+		
+		if (!this.activeEntry) {
+			//no upload is being run now
+			
+			var entry = this._selectEntryForUpload();
+			if (entry) {
+				entry.upload();
+			}
+		}
+	},
+	
+	stop: function() {
+		this.runUpload = false;
+		
+		if (this.activeEntry) {
+			this.activeEntry.stop();
+		}
+	},
+	
+	clear: function() {
+		for (var i = 0; i < this.entries.length; i++) {
+			var entry = this.entries[i];
+			if (entry.state != FileUploadEntry.UPLOAD_IN_PROGRESS) {
+				this.entries.splice(i--, 1);
+				entry.clear();
+			}
+		}
+
+		if (this.entries.length == 0) {
+			this.setupAutoUpload();
+		}
+	},
+
+	_endUpload: function() {
+		this.activeEntry = null;
+		this.progressBar.setValue(0);
+		this.progressBar.disable();
+	},
+	
+	notifyStateChange: function(entry, oldState) {
+		var newState = entry.state;
+		
+		if (newState == FileUploadEntry.UPLOAD_SUCCESS) {
+			//todo clear completed
+		
+			//if (this.activeEntry) {
+			//	this.activeEntry.clear();
+			//}
+			
+			this._endUpload();
+			
+			var entry = this._selectEntryForUpload();
+			if (entry) {
+				if (this.runUpload) {
+					entry.upload();
+				}
+			} else {
+				//we've uploaded all files sucessfully
+				//but this.runUpload can be false if upload
+				//has been requested to stop by user 
+				this.setupAutoUpload();
+			}
+			
+		} else if (newState == FileUploadEntry.UPLOAD_CANCELED ||
+				newState == FileUploadEntry.UPLOAD_TRANSFER_ERROR ||
+				newState == FileUploadEntry.UPLOAD_SERVER_ERROR) {
+
+
+			this._endUpload();
+
+			this.runUpload = false;
+			
+		} else if (newState == FileUploadEntry.UPLOAD_IN_PROGRESS) {
+		
+			this.activeEntry = entry;
+			this.progressBar.setValue(0);
+			this.progressBar.enable();
+			
+		} else if (newState == FileUploadEntry.INITIALIZED) {
+			//
+		}
+	},
+	
+	submitForm: function(entry) {
+		var parentForm = this.element;
+		while (parentForm.tagName && parentForm.tagName.toLowerCase() != 'form') {
+			parentForm = parentForm.parentNode;
+		}
+		
+		if (!parentForm) {
+			throw "No parent form found!";
+		}
+
+		entry.uid = encodeURIComponent(Math.random().toString());
+		
+		var oldTarget = parentForm.target;
+		var oldEnctype = parentForm.enctype;
+		var oldEncoding = parentForm.encoding;
+		var oldAction = parentForm.action;
+		
+		parentForm.encoding = "multipart/form-data"; 
+		parentForm.enctype = "multipart/form-data"; 
+		parentForm.target = this.id;
+		parentForm.action = oldAction + (/\?/.test(oldAction) ? '&uid' : '?uid') + '=' + encodeURI(entry.uid);
+
+		try {
+			var inputs = parentForm.elements;
+			var entryInput = entry.element;
+
+			var l = inputs.length;
+			for (var i = 0; i < l; i++) {
+				var input = inputs[i];
+				if ('hidden' != input.type && input != entryInput) {
+					input._name = input.name;
+					input.name = undefined;
+				}
+			}
+	
+			if (!parentForm.onsubmit || parentForm.onsubmit()) {
+				var iframe = this.iframe;
+				new LoadWatcher(iframe, 
+					function(){
+						alert('ready');	
+						this.setState(FileUploadEntry.UPLOAD_SUCCESS);
+					}.bind(entry), 
+					
+					function(e) {
+						alert('error! ' + e.message);
+					}
+				);
+				
+				parentForm.submit();
+			}
+			
+			for (var i = 0; i < l; i++) {
+				var input = inputs[i];
+				if ('hidden' != input.type && input != entryInput) {
+					if (input._name) {
+						input.name = input._name;
+						input._name = undefined;
+					}
+				}
+			}
+		} finally {
+			parentForm.action = oldAction;
+			parentForm.target = oldTarget;
+			parentForm.encoding = oldEncoding;
+			parentForm.enctype = oldEnctype;
+		}
+	}
+	
+});
+
 FileUpload = {};
 FileUpload = Class.create();
 FileUpload.Uploaders = {};
@@ -47,13 +429,19 @@
     	var d = $(this.id + ":upload1");
     	var l = $(this.id + ":upload2");
     	if (d && l) {
-    		var label = (isCancel) ? "<b>Cancel</b>" : "<b>Upload</b>";
-    		if (isCancel) {
-    			l.innerHTML = label;
+			var cancelButton = Element.firstDescendant(l);
+			var uploadButton = cancelButton.next();
+
+			if (isCancel) {
+    			cancelButton.show();
+    			uploadButton.hide();
+
     			this.updateButton(d,l,this.cancelStyle,this.cancelStyleDisabled,"start",disabled);
     			d.onclick = function () { this.stopAll(); }.bind(this);
     		}else {
-    			l.innerHTML = label;
+    			uploadButton.show();
+    			cancelButton.hide();
+
     			this.updateButton(d,l,this.uploadStyle,this.uploadStyleDisabled,"start",disabled);
     			d.onclick = function () { this.uploadAll(); }.bind(this);
     		}
@@ -205,7 +593,7 @@
 					}.bind(this); 
 	
 	
-		document.body.appendChild(fr);
+		document.body.insertBefore(fr, null);
 		
 		var f = document.createElement("form");
 		f.enctype = "multipart/form-data";
@@ -214,8 +602,6 @@
 		f.id = this.id + ":f";
 		f.target = this.id + ":fr";
 		
-		document.body.appendChild(f);
-		
 		var d = document.createElement("div");
 		d.id = this.id + ":files";
 		f.appendChild(d);
@@ -226,6 +612,7 @@
 		d.value = d.name;
 		f.appendChild(d);
 			
+		document.body.insertBefore(f, null);
 			//--			
 	},
 	getFilesCount: function () {

Modified: trunk/sandbox/ui/fileUpload/src/main/templates/org/richfaces/fileUpload.jspx
===================================================================
--- trunk/sandbox/ui/fileUpload/src/main/templates/org/richfaces/fileUpload.jspx	2008-02-15 00:46:11 UTC (rev 6099)
+++ trunk/sandbox/ui/fileUpload/src/main/templates/org/richfaces/fileUpload.jspx	2008-02-15 00:46:21 UTC (rev 6100)
@@ -17,52 +17,79 @@
 			/org/richfaces/renderkit/html/scripts/utils.js,
 			/org/richfaces/renderkit/html/scripts/json/json-dom.js,
 			/org/richfaces/renderkit/html/js/FileUpload.js,
-			/org/richfaces/renderkit/html/js/progressBar.js,
+			/org/richfaces/renderkit/html/js/progressBar.js
 	</h:scripts>
 	
 	<f:clientId var="clientId" />
 	
 <div class="upload_list_width upload_list_decor" id="#{clientId}">
+	<iframe name="#{clientId}" id="#{clientId}_iframe" />
 
 <span style="display: none">
 		<script type="text/javascript">
-			<f:call name="encodeInitialScript" />
+			/*<!-- f:call name="encodeInitialScript" / -->*/
 		</script>
 </span>
 
+	<jsp:scriptlet>
+		<![CDATA[
+	renderProgress(context, component);
+		  ]]>
+	</jsp:scriptlet>
+
 	<table class="upload_toolbar_decor">
 		<tr>
 			<td>
 				<div class="upload_button_border" style=" float:left;">
 					<div class="upload_button upload_font" onmouseover="this.className='upload_button_light upload_font'" onmousedown="this.className='upload_button_press upload_font'" onmouseup="this.className='upload_button upload_font'" onmouseout="this.className='upload_button upload_font'"
-						 style="position: relative; overflow: hidden; direction: rtl; width:70px"
+						 style="position: relative; overflow: hidden; width:70px"
 						 id="#{clientId}:add1">
 						<div class="upload_button_content upload_font upload_ico upload_ico_add"
-							 id="#{clientId}:add2">Add...</div>
-						<input type="file" style="cursor: pointer; z-index: 3; width: 0px; height: 22px; left: 0px; top: 0px; position: absolute" 
+							 id="#{clientId}:add2" style="direction: rtl;">Add...</div>
+						<input type="file" style="cursor: pointer; z-index: 3; right: -10px; top: -10px; font-size: 10em; position: absolute" 
 							   class="hidden"
 							   id="#{clientId}:file"
 							   name="fileName"
-							   onchange="return $('#{clientId}').component.add();"/>
+							   onchange="return $('#{clientId}').component.add(this);"/>
 					</div>
 				</div>
 				<div class="upload_button_border" style=" float:left;">
 					<div class="upload_button upload_font" onmouseover="this.className='upload_button_light upload_font'" onmousedown="this.className='upload_button_press upload_font'" onmouseup="this.className='upload_button upload_font'" 
 						 onmouseout="this.className='upload_button upload_font'"
 						 id="#{clientId}:upload1"
-						 onclick="return $('#{clientId}').component.uploadAll();">
+						 onclick="return $('#{clientId}').component.upload();">
 						<a href="#" class="upload_button_selection">
 							<div class="upload_button_content upload_font upload_ico upload_ico_start"
 								 id="#{clientId}:upload2">
+								<b style="display: none;">Cancel</b>
 								<b>Upload</b>
 							</div>
 						</a>
 					</div>
 				</div>
+				
+				<!-- todo review -->
+				
+				<div class="upload_button_border" style=" float:left;">
+					<div class="upload_button upload_font" onmouseover="this.className='upload_button_light upload_font'" onmousedown="this.className='upload_button_press upload_font'" onmouseup="this.className='upload_button upload_font'" 
+						 onmouseout="this.className='upload_button upload_font'"
+						 id="#{clientId}:upload3"
+						 onclick="return $('#{clientId}').component.stop();">
+						<a href="#" class="upload_button_selection">
+							<div class="upload_button_content upload_font upload_ico upload_ico_start"
+								 id="#{clientId}:upload4">
+								<b>Stop</b>
+							</div>
+						</a>
+					</div>
+				</div>
+
+				<!--  -->
+
 				<div class="upload_button_border" style=" float:right">
 					<div class="upload_button upload_font" onmouseover="this.className='upload_button_light upload_font'" onmousedown="this.className='upload_button_press upload_font'" onmouseup="this.className='upload_button upload_font'" 
 						 onmouseout="this.className='upload_button upload_font'"
-						 onclick="return $('#{clientId}').component.cleanAll();"
+						 onclick="return $('#{clientId}').component.clear();"
 						 id="#{clientId}:clean1">
 						<a href="#" class="upload_button_selection">
 							<div class="upload_button_content upload_font upload_ico upload_ico_clear"
@@ -76,7 +103,7 @@
 
 	<div class="upload_list_width upload_list_overflow" id="#{clientId}:fileItems">
 	
-	<jsp:scriptlet>
+	<!-- jsp:scriptlet>
 	<![CDATA[
 	 	Iterator<org.richfaces.org.jboss.seam.ui.component.FileItem> it = component.getFileItems().iterator();
 	 	Integer i = 0;
@@ -162,16 +189,18 @@
 	         i++;
 	 	}
 	]]>
-	</jsp:scriptlet>
+	</jsp:scriptlet-->
 	
 	</div>
 	<span>
 		<script type="text/javascript">
-			<f:call name="encodeUpdateButtonScript" />
+			new FileUpload1('#{clientId}', #{this:getStopScript(context, component)}, '#{this:getProgressBarId(context, component)}');
+			/*<!-- f:call name="encodeUpdateButtonScript" / -->*/
 		</script>
 	</span>
 	
 </div>
 	
 	
-</f:root>	
\ No newline at end of file
+</f:root>
+	
\ No newline at end of file




More information about the richfaces-svn-commits mailing list