[zeam.form.silva][Sylvain Viollon] Use jsonp, refactor.

[email protected]
Newsgroups gmane.comp.web.zope.silva.cvs
Message-ID <[email protected]>
author:    Sylvain Viollon
date:      Thu Aug 08 18:15:55 2013 +0200
revision:  418:b0c59e194a40 in zeam.form.silva
branch:    2.4
details:   https://hg.infrae.com/zeam.form.silva?cmd=changeset;node=b0c59e194a40
modified:  src/zeam/form/silva/widgets/file.py src/zeam/form/silva/widgets/static/upload.js
added:     
removed:   
log:       Use jsonp, refactor.


diffstat:

 src/zeam/form/silva/widgets/file.py          |  14 ++--
 src/zeam/form/silva/widgets/static/upload.js |  80 +++++++++++++++------------
 2 files changed, 51 insertions(+), 43 deletions(-)

diffs (230 lines):

diff -r ae943470430d -r b0c59e194a40 src/zeam/form/silva/widgets/file.py
--- a/src/zeam/form/silva/widgets/file.py	Mon Jul 29 16:13:34 2013 +0200
+++ b/src/zeam/form/silva/widgets/file.py	Thu Aug 08 18:15:55 2013 +0200
@@ -109,6 +109,11 @@
         return str(uuid.uuid1())
 
     def uploadURL(self):
+        manager = self.request.environ.get('infrae.fileupload.manager')
+        if manager is None:
+            raise interfaces.Error('The upload component is not available')
+        if manager.upload_url:
+            return manager.upload_url
         if ISubForm.providedBy(self.form):
             form = self.form.getComposedForm()
         else:
@@ -195,12 +200,7 @@
         info = self.request.environ['infrae.fileupload.current'].get_status()
         return """
             <html>
-                <body>
-                    <script>
-                        (function($, document) {
-                            $(document).trigger('upload-%s-done', %s);
-                        })(window.parent.jQuery, window.parent.document);
-                    </script>
+                <body data-upload-identifier="%s" data-upload-info="%s">
                 </body>
             </html>
-        """ % (info['identifier'], json.dumps(info))
+        """ % (str(info['identifier']), json.dumps(info).replace('"', '\\"'))
diff -r ae943470430d -r b0c59e194a40 src/zeam/form/silva/widgets/static/upload.js
--- a/src/zeam/form/silva/widgets/static/upload.js	Mon Jul 29 16:13:34 2013 +0200
+++ b/src/zeam/form/silva/widgets/static/upload.js	Thu Aug 08 18:15:55 2013 +0200
@@ -1,5 +1,6 @@
 (function($, jsontemplate) {
-    var POLL_NETWORK_RETRIES = 5,
+    var IDENTIFIER_KEY = 'X-Progress-ID',
+        POLL_NETWORK_RETRIES = 5,
         POLL_NETWORK_DELAY = 500,
         POLL_MISSING_RETRIES = 20,
         DONT_NEED_POPUP = (function () {
@@ -28,24 +29,24 @@
                 // Poll status from the server.
                 $.ajax({
                     type: 'GET',
-                    dataType: 'json',
-                    url: url + '?status&identifier=' + identifier
+                    dataType: 'jsonp',
+                    url: url + '/status?' + IDENTIFIER_KEY + '=' + identifier
                 }).then(function(info){
                     var error = null;
 
                     result.notify(info);
-                    if (info['missing']) {
+                    if (info['state'] == 'starting') {
                         missing_retries -= 1;
                         if (!missing_retries) {
-                            error = info['upload-error'] || 'Upload does not start';
+                            error = info['error'] || 'Upload does not start';
                             deferred.reject({message: 'Upload failed ('+ error + ').'});
                         };
                     };
-                    if (info['upload-finished'] || info['upload-error']) {
-                        if (info['upload-finished'] && !info['upload-error']) {
+                    if (info['state'] == 'done'|| info['state'] == 'error') {
+                        if (info['state'] == 'done') {
                             deferred.resolve(info);
                         } else {
-                            error = info['upload-error'] || 'Unknow error';
+                            error = info['error'] || 'Unknow error';
                             deferred.reject({message: 'Upload failed ('+ error + ').'});
                         };
                     } else if (result.state() == "pending" && missing_retries) {
@@ -79,25 +80,33 @@
         };
     };
 
-    var IFrameStatusChecker = function($iframe, name, result)  {
-        // helper to bind an event on iframe load
+    var IFrameStatusChecker = function($iframe, identifier, result)  {
+        // Check the status of the upload with the iframe. This never works.
         var iframe = $iframe.get(0),
             iframe_window = iframe.contentWindow,
             iframe_document = iframe_window.document,
             deferred = $.Deferred();
 
         var fail = function() {
-            deferred.reject({message: 'Upload failed (File too big or server error).'});
+            setTimeout(function() {
+                deferred.reject({message: 'Upload failed (File too big or server error).'});
+            }, POLL_NETWORK_DELAY);
+        };
+        var load = function() {
+            var $body = $(iframe_document.body);
+
+            if ($body.data('upload-identifier') == identifier) {
+                deferred.resolve($body.data('upload-info'));
+            } else {
+                fail();
+            };
         };
 
-        $(document).one(name, function(event, data) {
-            deferred.resolve(data);
-        });
         if (iframe_window.addEventListener) {
-            iframe_window.addEventListener("load", fail, false);
+            iframe_window.addEventListener("load", load, false);
             iframe_window.addEventListener("error", fail, false);
         } else {
-            iframe_window.attachEvent("onload", fail);
+            iframe_window.attachEvent("onload", load);
             iframe_window.attachEvent("onerror", fail);
         };
         return {
@@ -118,12 +127,13 @@
             uploading = jsontemplate.Template($uploading.children('i').text(), {}),
             done = jsontemplate.Template($done.children('i').text(), {}),
             state = 'empty',
+            defaults = {'filename': '', 'content-type': 'n/a'},
             original = $display.data('upload-status');
 
         var api = {
             start: function(data) {
                 if (state != 'starting') {
-                    $uploading.children('i').text(uploading.expand(data));
+                    $uploading.children('i').text(uploading.expand($.extend({}, defaults, data)));
                     $empty.hide();
                     $done.hide();
                     $uploading.show();
@@ -131,15 +141,15 @@
                 }
             },
             progress: function(data) {
-                if (state != 'uploading' && !data.missing) {
+                if (state != 'uploading' && data.state == 'uploading') {
                     // Refresh information on the first notification of progress.
-                    $uploading.children('i').text(uploading.expand(data));
+                    $uploading.children('i').text(uploading.expand($.extend({}, defaults, data)));
                     state = 'uploading';
                 };
             },
             done: function(data) {
                 if (state != 'done') {
-                    $done.children('i').text(done.expand(data));
+                    $done.children('i').text(done.expand($.extend({}, defaults, data)));
                     $empty.hide();
                     $uploading.hide();
                     $done.show();
@@ -175,8 +185,8 @@
             progress: function(data) {
                 var updated = 0;
 
-                if (!data['missing']) {
-                    updated = data['uploaded-length'] * 100 / data['request-length'];
+                if (data['state'] == 'uploading') {
+                    updated = data['received'] * 100 / data['size'];
                 };
                 if (updated != progress) {
                     $progress.progressbar({value: updated});
@@ -233,8 +243,8 @@
                                     progress: function(data) {
                                         var updated = 0;
 
-                                        if (!data['missing']) {
-                                            updated = data['uploaded-length'] * 100 / data['request-length'];
+                                        if (data['state'] == 'uploading') {
+                                            updated = data['received'] * 100 / data['size'];
                                         };
                                         if (updated != progress) {
                                             $progress.progressbar({value: updated});
@@ -290,7 +300,7 @@
                         'src="about:blank" class="upload-iframe" name="upload-' +
                         identifier + '-iframe"></iframe>' +
                         '<form class="upload-form" enctype="multipart/form-data"' +
-                        'method="POST" action="' + url + '?identifier=' + identifier +
+                        'method="POST" action="' + url + '?' + IDENTIFIER_KEY + '=' + identifier +
                         '" target="upload-' + identifier +
                         '-iframe" id="upload-' + identifier + '-form">' +
                         '<input type="reset" class="upload-reset" /></form></div>'),
@@ -306,16 +316,15 @@
                 start: function() {
                     $.ajax({
                         type: 'GET',
-                        dataType: 'json',
-                        url: url + '?clear&identifier=' + identifier}).then(function () {
+                        dataType: 'jsonp',
+                        url: url + '?clear&' + IDENTIFIER_KEY + '=' + identifier}).then(function () {
                             $('body').append($upload);
                             $field.attr('form', 'upload-' + identifier + '-form');
                             start.done(function() {
-                                api.register(IFrameStatusChecker($upload.find('iframe'), 'upload-' + identifier + '-done'));
+                                api.register(IFrameStatusChecker($upload.find('iframe'), identifier, result));
                                 api.register(PollStatusChecker(url, identifier, result));
                                 $upload.find('form').submit();
-                            }).resolve({
-                                'uploaded-length': 0, 'content-type': 'n/a', 'request-length': 0, 'filename': ''});
+                            }).resolve({state: 'starting', received: 0, size: 0});
                         }, function() {
                             result.reject({message: 'Upload failed.'});
                         });
@@ -350,7 +359,7 @@
         // It will trigger callbacks uring various steps of the progress.
         var $popup = $('<div  title="Upload a file">' +
                        '<form class="upload-form" enctype="multipart/form-data"' +
-                       'method="POST" action="' + url + '?identifier=' + identifier +
+                       'method="POST" action="' + url + '?' + IDENTIFIER_KEY+ '=' + identifier +
                         '" target="upload-' + identifier +
                        '-iframe" id="upload-' + identifier + '-form">' +
                        '<input type="file" name="file-we-are-uploading" class="upload-file" /></form>'+
@@ -368,15 +377,14 @@
                     var send = function() {
                         $.ajax({
                             type: 'GET',
-                            dataType: 'json',
-                            url: url + '?clear&identifier=' + identifier}).then(function() {
+                            dataType: 'jsonp',
+                            url: url + '?clear&' + IDENTIFIER_KEY + '=' + identifier}).then(function() {
                                 start.done(function() {
                                     $popup.dialog('close');
-                                    api.register(IFrameStatusChecker($popup.find('iframe'), 'upload-' + identifier + '-done'));
+                                    api.register(IFrameStatusChecker($popup.find('iframe'), identifier, result));
                                     api.register(PollStatusChecker(url, identifier, result));
                                     $popup.find('form').submit();
-                                }).resolve({
-                                    'uploaded-length': 0, 'content-type': 'n/a', 'request-length': 0, 'filename': ''});
+                                }).resolve({state: 'starting', received: 0, size: 0});
                             }, function() {
                                 result.reject({message: 'Upload failed.'});
                             });
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.