1/** 2 * ImageUploader.js 3 * 4 * Anticipated markup: 5 * 6 <div class="ui-imageuploader" data-ui="imageuploader"> 7 <div class="input-wrap"> 8 <input type="file" name="file"> 9 </div> 10 </div> 11 * 12 */ 13(function($) { 14 var ImageUploader = function($el, overrides) { 15 var settings, 16 defaults = { 17 wrapperSelector: '.ui-imageuploader', 18 widgetSelector: '.input-wrap', 19 multiple: false, 20 actions: { 21 add: { 22 icon: 'icon-image', 23 label: 'Add image', 24 callback: function(uploader) { 25 uploader.element.trigger('click'); 26 } 27 }, 28 remove: { 29 icon: 'icon-remove', 30 label: 'Remove image', 31 callback: function(uploader) { 32 uploader.element.trigger('removeAsset'); 33 } 34 } 35 } 36 }; 37 38 // passed overrides parameter takes highest precedence 39 this.settings = settings = $.extend(true, defaults, overrides); 40 this.wrapper = $el.closest(settings.wrapperSelector); 41 this.isForm = this.wrapper.attr('data-form') || false 42 this.widget = $el.closest(settings.widgetSelector); 43 this.element = $el; 44 this.asset = this.wrapper.attr('data-asset'); 45 this.init(); 46 }; 47 48 49 /** 50 * Initialize the image uploader 51 * @return {void} 52 */ 53 ImageUploader.prototype.init = function() { 54 var uploader = this; 55 56 $(document).bind('drop dragover', function (e) { 57 e.preventDefault(); 58 }); 59 uploader.addLabels(); 60 61 // Add the asset field 62 if (uploader.isForm) { 63 uploader.assetField = $('<input type="hidden" name="' + uploader.getUploaderName() + '">'); 64 uploader.wrapper.append(this.assetField); 65 } 66 67 // insert current asset value 68 if (typeof uploader.asset !== 'undefined' && uploader.asset.length > 0) { 69 uploader.defaultAsset = $('<div class="default-asset"><img src="' + uploader.getAssetEndpoint(uploader.asset) + '" /></div>'); 70 uploader.widget.append(uploader.defaultAsset); 71 uploader.widget.addClass('is-complete'); 72 } 73 74 // Remove asset event handler 75 uploader.element.bind('removeAsset', function(e) { 76 if (uploader.widget.hasClass('is-complete') || uploader.widget.hasClass('is-failed')) { 77 uploader.widget.removeClass('is-complete is-failed'); 78 uploader.setAssetValue(null); 79 $('.default-asset', uploader.wrapper).remove(); 80 uploader.element.trigger('uploadRemove'); 81 if (typeof uploader.progressWrapper !== 'undefined') { 82 uploader.element.WebEditionXHRUpload('reset', uploader.progressWrapper); 83 } 84 } 85 }); 86 87 // Label click event handler 88 uploader.labels.each(function() { 89 var action = $(this).data('action'); 90 $(this).bind('click', function(e) { 91 e.preventDefault(); 92 if (typeof uploader.settings.actions[action].callback === 'function') { 93 uploader.settings.actions[action].callback(uploader); 94 } 95 }); 96 }); 97 98 // Initialize the actual uploader 99 uploader.createUploader(); 100 uploader.setAssetValue(this.asset); 101 }; 102 103 104 /** 105 * Create our actual image uploader, levaraging the XHRUpload object 106 * @return {this} 107 */ 108 ImageUploader.prototype.createUploader = function () { 109 var uploader = this; 110 this.element.WebEditionXHRUpload({ 111 multiple: uploader.settings.multiple, 112 wrapper: uploader.widgetSelector, 113 upload: function(file, $progressWrapper, e) { 114 var image = new Image(); 115 uploader.uploadingasset = e.target.result; 116 image.src = uploader.uploadingasset; 117 if (uploader.defaultAsset) { 118 uploader.defaultAsset.detach(); 119 } 120 $progressWrapper.prepend(image); 121 uploader.progressWrapper = $progressWrapper; 122 uploader.element.trigger('uploadStart'); 123 uploader.element.WebEditionXHRUpload('upload', file, $progressWrapper); 124 }, 125 success: function(data, $progressWrapper) { 126 uploader.uploadingasset = null; 127 if (typeof data.status !== 'undefined' && data.status) { 128 uploader.setAssetValue(data.payload.asset); 129 uploader.element.trigger('uploadSuccess'); 130 } else { 131 Webe.message("Error: could not upload this image.", {status: "error", delay: 5000}); 132 } 133 }, 134 error: function(wrapper, errorMessage) { 135 uploader.uploadingasset = null; 136 uploader.element.trigger('uploadFailed', errorMessage); 137 Webe.message(errorMessage, {status: 'error'}); 138 } 139 }); 140 return this; 141 } 142 143 144 /** 145 * Add labels to the uploader 146 * @return {this} 147 */ 148 ImageUploader.prototype.addLabels = function () { 149 var uploader = this,
150 $labels = $('<div class="labels"></div>'); 151 for (var action in uploader.settings.actions) { 152 $labels.append('<div class="label" data-action="' + action + '"><span class="icon ' + uploader.settings.actions[action].icon + '"></span><span class="text">' + uploader.settings.actions[action].label + '</span></div>'); 153 } 154 uploader.element.after($labels); 155 uploader.labels = $labels.find('.label'); 156 return this; 157 } 158 159 160 /** 161 * Set the asset value of the current uploader 162 * @return {this} 163 */ 164 ImageUploader.prototype.setAssetValue = function (asset) { 165 var uploader = this; 166 uploader.asset = asset; 167 if (asset) { 168 uploader.wrapper.attr('data-asset', asset); 169 } else { 170 uploader.wrapper.removeAttr('data-asset'); 171 } 172 if (uploader.isForm) { 173 uploader.assetField.val(asset || ""); 174 uploader.assetField.trigger('change'); 175 } 176 uploader.wrapper.trigger('change.webe'); 177 return this; 178 } 179 180 181 /** 182 * Get the asset 183 * @return {string} 184 */ 185 ImageUploader.prototype.getAsset = function() { 186 return this.asset; 187 }; 188 189 190 /** 191 * Get the uploading asset 192 * @return {string} 193 */ 194 ImageUploader.prototype.getUploadingAsset = function() { 195 return this.uploadingasset; 196 }; 197 198 199 /** 200 * Get an uploader name, or make one up. GUID genorator credit: 201 * http://stackoverflow.com/questions/105034/create-guid-uuid-in-javascript#answer-2117523 202 * @return {string} 203 */ 204 ImageUploader.prototype.getUploaderName = function () { 205 return this.wrapper.attr('data-name') || 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { 206 var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8); 207 return v.toString(16); 208 }); 209 } 210 211 212 /** 213 * Get a fully qualified endpoint, generally this will be to the cdn 214 */ 215 ImageUploader.prototype.getAssetEndpoint = function(asset) { 216 return '/images/' + asset; 217 }; 218 219 220 /** 221 * Assign the class to the Webe global object 222 */ 223 Webe.ImageUploader = ImageUploader; 224 225 226 /* 227 * Attach the ImageUploader object to Webe to be 228 * instantiated by other scripts 229 */ 230 $(document).ready(function() { 231 $('[data-ui="imageuploader"][data-auto] input[type="file"]').each(function() { 232 var imageuploader = new Webe.ImageUploader($(this)); 233 $(this).data('imageuploader', imageuploader); 234 }); 235 }); 236 237})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.