changeset 7:35cacb3eaf6e

Add upload error callback
author Adam Chlipala <adam@chlipala.net>
date Sat, 31 Dec 2011 15:38:12 -0500
parents 78c426daaa89
children ccf9d9961e32
files examples/client.ur examples/server.ur include/ajaxUpload.h src/c/ajaxUpload.c src/js/ajaxUpload.js src/ur/ajaxUpload.ur src/ur/ajaxUpload.urs src/ur/ajaxUploadFfi.urs
diffstat 8 files changed, 33 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/examples/client.ur	Sat Dec 31 15:24:27 2011 -0500
+++ b/examples/client.ur	Sat Dec 31 15:38:12 2011 -0500
@@ -13,6 +13,7 @@
       <button value="Create new widget"
               onclick={au <- AjaxUpload.render {SubmitLabel = if b then None else Some "Upload it!",
                                                 OnBegin = set status <xml>Uploading</xml>,
+                                                OnError = set status <xml><b>Upload failed!</b></xml>,
                                                 OnSuccess = fn h =>
                                                                let
                                                                    fun addImage () =
--- a/examples/server.ur	Sat Dec 31 15:24:27 2011 -0500
+++ b/examples/server.ur	Sat Dec 31 15:38:12 2011 -0500
@@ -7,6 +7,7 @@
     status <- source <xml/>;
     au <- AjaxUpload.render {SubmitLabel = if b then None else Some "Upload it!",
                              OnBegin = set status <xml>Uploading</xml>,
+                             OnError = set status <xml><b>Upload failed!</b></xml>,
                              OnSuccess = fn h =>
                                             let
                                                 fun addImage () =
--- a/include/ajaxUpload.h	Sat Dec 31 15:24:27 2011 -0500
+++ b/include/ajaxUpload.h	Sat Dec 31 15:38:12 2011 -0500
@@ -2,6 +2,7 @@
 
 uw_Basis_string uw_AjaxUploadFfi_tweakForm(uw_context, uw_Basis_bool autoSubmit, uw_Basis_string iframeId, uw_Basis_string submitId);
 uw_Basis_string uw_AjaxUploadFfi_notifySuccess(uw_context, uw_Basis_string submitId, uw_Basis_int handle);
+uw_Basis_string uw_AjaxUploadFfi_notifyError(uw_context, uw_Basis_string submitId);
 
 uw_Basis_string uw_AjaxUploadFfi_idToString(uw_context, uw_Basis_string);
 uw_Basis_string uw_AjaxUploadFfi_stringToId(uw_context, uw_Basis_string);
--- a/src/c/ajaxUpload.c	Sat Dec 31 15:24:27 2011 -0500
+++ b/src/c/ajaxUpload.c	Sat Dec 31 15:38:12 2011 -0500
@@ -12,7 +12,7 @@
                           submitId,
                           "\"); subm.parentNode.target = \"",
                           iframeId,
-                          "\"; var onSub = subm.onmousedown; subm.onmousedown = undefined; subm.parentNode.onsubmit = function() { onSub(); return true; }; subm.withHandle = subm.onkeydown; subm.onkeydown = undefined; ",
+                          "\"; var onSub = subm.onmousedown; subm.onmousedown = undefined; subm.parentNode.onsubmit = function() { onSub(); return true; }; subm.withHandle = subm.onkeydown; subm.onkeydown = undefined; subm.withError = subm.onmouseup; subm.onmouseup = undefined; ",
                           autoSubmit
                           ? "subm.style.visibility = \"hidden\"; for (var node = subm.previousSibling; node.tagName != \"INPUT\"; node = node.previousSibling); node.onchange = function() { subm.parentNode.submit(); }; "
                           : "",
@@ -30,6 +30,14 @@
                           NULL);
 }
 
+uw_Basis_string uw_AjaxUploadFfi_notifyError(uw_context ctx, uw_Basis_string submitId) {
+  return uw_Basis_mstrcat(ctx,
+                          "<script type=\"text/javascript\">var subm = window.top.document.getElementById(\"",
+                          submitId,
+                          "\"); subm.withError(); </script>",
+                          NULL);
+}
+
 uw_Basis_string uw_AjaxUploadFfi_idToString(uw_context ctx, uw_Basis_string s) {
   return s;
 }
--- a/src/js/ajaxUpload.js	Sat Dec 31 15:24:27 2011 -0500
+++ b/src/js/ajaxUpload.js	Sat Dec 31 15:38:12 2011 -0500
@@ -27,6 +27,11 @@
         subm.onkeydown = undefined;
     }
 
+    if (subm.withError == undefined) {
+        subm.withError = subm.onmouseup;
+        subm.onmouseup = undefined;
+    }
+
     if (autoSubmit) {
         subm.style.visibility = "hidden";
         for (var node = subm.previousSibling; node.tagName != "INPUT"; node = node.previousSibling);
--- a/src/ur/ajaxUpload.ur	Sat Dec 31 15:24:27 2011 -0500
+++ b/src/ur/ajaxUpload.ur	Sat Dec 31 15:38:12 2011 -0500
@@ -40,23 +40,26 @@
                 None => NotFound
               | Some r => Found r)
 
-fun render {SubmitLabel = sl, OnBegin = ob, OnSuccess = os} =
+fun render {SubmitLabel = sl, OnBegin = ob, OnSuccess = os, OnError = oe} =
     iframeId <- fresh;
     submitId <- fresh;
     submitId' <- return (AjaxUploadFfi.idToString submitId);
     let
         fun upload r =
-            h <- nextval handles;
-            dml (INSERT INTO scratch (Handle, Filename, MimeType, Content, Created)
-                 VALUES ({[h]}, {[fileName r.File]}, {[fileMimeType r.File]}, {[fileData r.File]}, CURRENT_TIMESTAMP));
-            return <xml><body>
-              {AjaxUploadFfi.notifySuccess (AjaxUploadFfi.stringToId submitId') h}
-            </body></xml>
+            if Option.isNone (checkMime (fileMimeType r.File)) then
+                return <xml><body>{AjaxUploadFfi.notifyError (AjaxUploadFfi.stringToId submitId')}</body></xml>
+            else
+                h <- nextval handles;
+                dml (INSERT INTO scratch (Handle, Filename, MimeType, Content, Created)
+                     VALUES ({[h]}, {[fileName r.File]}, {[fileMimeType r.File]}, {[fileData r.File]}, CURRENT_TIMESTAMP));
+                return <xml><body>
+                  {AjaxUploadFfi.notifySuccess (AjaxUploadFfi.stringToId submitId') h}
+                </body></xml>
     in
         return <xml>
           <form>
             <upload{#File}/>
-            <submit value={Option.get "" sl} action={upload} id={submitId} onmousedown={ob} onkeydown={os}/>
+            <submit value={Option.get "" sl} action={upload} id={submitId} onmousedown={ob} onkeydown={os} onmouseup={oe}/>
           </form>
           {AjaxUploadFfi.tweakForm (Option.isNone sl) iframeId submitId}
         </xml>
--- a/src/ur/ajaxUpload.urs	Sat Dec 31 15:24:27 2011 -0500
+++ b/src/ur/ajaxUpload.urs	Sat Dec 31 15:38:12 2011 -0500
@@ -19,7 +19,9 @@
               (* Text for submit button, or [None] to auto-submit when selected file changes *)
               OnBegin : transaction {},
               (* Run this when an upload begins. *)
-              OnSuccess : handle -> transaction {}
-              (* Run this after a successful upload. *)}
+              OnSuccess : handle -> transaction {},
+              (* Run this after a successful upload. *)
+              OnError : transaction {}
+              (* Run this when upload fails (probably because of an unsupported MIME type). *)}
              -> transaction xbody
 (* Produce HTML for a file upload control *)
--- a/src/ur/ajaxUploadFfi.urs	Sat Dec 31 15:24:27 2011 -0500
+++ b/src/ur/ajaxUploadFfi.urs	Sat Dec 31 15:38:12 2011 -0500
@@ -1,5 +1,6 @@
 val tweakForm : bool -> id -> id -> xbody
 val notifySuccess : id -> int -> xbody
+val notifyError : id -> xbody
 
 val idToString : id -> string
 val stringToId : string -> id