]> git.mxchange.org Git - quix0rs-gnu-social.git/blobdiff - js/util.js
Fix for ticket #2942: character counter now updates on cut and paste operations made...
[quix0rs-gnu-social.git] / js / util.js
index 74eef4df170dac457a7e45f18fb47cc212fe4de1..035c59da00c8e5e2ecb601629c63f72c9a554c6b 100644 (file)
@@ -85,6 +85,19 @@ var SN = { // StatusNet
                     SN.U.Counter(form);
                 });
 
+                var delayedUpdate= function(e) {
+                    // Cut and paste events fire *before* the operation,
+                    // so we need to trigger an update in a little bit.
+                    // This would be so much easier if the 'change' event
+                    // actually fired every time the value changed. :P
+                    window.setTimeout(function() {
+                        SN.U.Counter(form);
+                    }, 50);
+                };
+                // Note there's still no event for mouse-triggered 'delete'.
+                NDT.bind('cut', delayedUpdate)
+                   .bind('paste', delayedUpdate);
+
                 NDT.bind('keydown', function(e) {
                     SN.U.SubmitOnReturn(e, form);
                 });
@@ -236,8 +249,9 @@ var SN = { // StatusNet
                         form.append('<p class="form_response error">Sorry! We had trouble sending your notice. The servers are overloaded. Please try again, and contact the site administrator if this problem persists.</p>');
                     }
                     else {
-                        if ($('.'+SN.C.S.Error, xhr.responseXML).length > 0) {
-                            form.append(document._importNode($('.'+SN.C.S.Error, xhr.responseXML)[0], true));
+                        var response = SN.U.GetResponseXML(xhr);
+                        if ($('.'+SN.C.S.Error, response).length > 0) {
+                            form.append(document._importNode($('.'+SN.C.S.Error, response)[0], true));
                         }
                         else {
                             if (parseInt(xhr.status) === 0 || jQuery.inArray(parseInt(xhr.status), SN.C.I.HTTP20x30x) >= 0) {
@@ -326,6 +340,16 @@ var SN = { // StatusNet
             });
         },
 
+        GetResponseXML: function(xhr) {
+            // Work around unavailable responseXML when document.domain
+            // has been modified by Meteor or other tools.
+            try {
+                return xhr.responseXML;
+            } catch (e) {
+                return (new DOMParser()).parseFromString(xhr.responseText, "text/xml");
+            }
+        },
+
         NoticeReply: function() {
             if ($('#'+SN.C.S.NoticeDataText).length > 0 && $('#content .notice_reply').length > 0) {
                 $('#content .notice').each(function() { SN.U.NoticeReplyTo($(this)); });
@@ -446,9 +470,103 @@ var SN = { // StatusNet
 
                     return false;
                 });
+                if (typeof this.files == "object") {
+                    // Some newer browsers will let us fetch the files for preview.
+                    for (var i = 0; i < this.files.length; i++) {
+                        SN.U.PreviewAttach(this.files[i]);
+                    }
+                }
             });
         },
 
+        /**
+         * For browsers with FileAPI support: make a thumbnail if possible,
+         * and append it into the attachment display widget.
+         *
+         * Known good:
+         * - Firefox 3.6.6, 4.0b7
+         * - Chrome 8.0.552.210
+         *
+         * Known ok metadata, can't get contents:
+         * - Safari 5.0.2
+         *
+         * Known fail:
+         * - Opera 10.63, 11 beta (no input.files interface)
+         *
+         * @param {File} file
+         *
+         * @todo use configured thumbnail size
+         * @todo detect pixel size?
+         * @todo should we render a thumbnail to a canvas and then use the smaller image?
+         */
+        PreviewAttach: function(file) {
+            var tooltip = file.type + ' ' + Math.round(file.size / 1024) + 'KB';
+            var preview = true;
+
+            var blobAsDataURL;
+            if (typeof window.createObjectURL != "undefined") {
+                /**
+                 * createObjectURL lets us reference the file directly from an <img>
+                 * This produces a compact URL with an opaque reference to the file,
+                 * which we can reference immediately.
+                 *
+                 * - Firefox 3.6.6: no
+                 * - Firefox 4.0b7: no
+                 * - Safari 5.0.2: no
+                 * - Chrome 8.0.552.210: works!
+                 */
+                blobAsDataURL = function(blob, callback) {
+                    callback(window.createObjectURL(blob));
+                }
+            } else if (typeof window.FileReader != "undefined") {
+                /**
+                 * FileAPI's FileReader can build a data URL from a blob's contents,
+                 * but it must read the file and build it asynchronously. This means
+                 * we'll be passing a giant data URL around, which may be inefficient.
+                 *
+                 * - Firefox 3.6.6: works!
+                 * - Firefox 4.0b7: works!
+                 * - Safari 5.0.2: no
+                 * - Chrome 8.0.552.210: works!
+                 */
+                blobAsDataURL = function(blob, callback) {
+                    var reader = new FileReader();
+                    reader.onload = function(event) {
+                        callback(reader.result);
+                    }
+                    reader.readAsDataURL(blob);
+                }
+            } else {
+                preview = false;
+            }
+
+            var imageTypes = ['image/png', 'image/jpeg', 'image/gif', 'image/svg+xml'];
+            if ($.inArray(file.type, imageTypes) == -1) {
+                // We probably don't know how to show the file.
+                preview = false;
+            }
+
+            var maxSize = 8 * 1024 * 1024;
+            if (file.size > maxSize) {
+                // Don't kill the browser trying to load some giant image.
+                preview = false;
+            }
+
+            if (preview) {
+                blobAsDataURL(file, function(url) {
+                    var img = $('<img>')
+                        .attr('title', tooltip)
+                        .attr('alt', tooltip)
+                        .attr('src', url)
+                        .attr('style', 'height: 120px');
+                    $('#'+SN.C.S.NoticeDataAttachSelected).append(img);
+                });
+            } else {
+                var img = $('<div></div>').text(tooltip);
+                $('#'+SN.C.S.NoticeDataAttachSelected).append(img);
+            }
+        },
+
         NoticeLocationAttach: function() {
             var NLat = $('#'+SN.C.S.NoticeLat).val();
             var NLon = $('#'+SN.C.S.NoticeLon).val();