jquery-file-upload-rails 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +20 -0
  3. data/README.md +55 -0
  4. data/Rakefile +32 -0
  5. data/app/views/jquery_file_upload/basic_plus_ui/_download.html.erb +43 -0
  6. data/app/views/jquery_file_upload/basic_plus_ui/_form.html.haml +35 -0
  7. data/app/views/jquery_file_upload/basic_plus_ui/_upload.html.erb +32 -0
  8. data/config/locales/jquery_file_upload.cs.yml +16 -0
  9. data/config/locales/jquery_file_upload.en.yml +16 -0
  10. data/lib/jquery-file-upload-rails.rb +1 -0
  11. data/lib/jquery_file_upload/rails.rb +6 -0
  12. data/lib/jquery_file_upload/rails/version.rb +5 -0
  13. data/test/dummy/README.rdoc +28 -0
  14. data/test/dummy/app/assets/javascripts/application.js +13 -0
  15. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  16. data/test/dummy/app/controllers/application_controller.rb +5 -0
  17. data/test/dummy/app/helpers/application_helper.rb +2 -0
  18. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  19. data/test/dummy/bin/bundle +3 -0
  20. data/test/dummy/bin/rails +4 -0
  21. data/test/dummy/bin/rake +4 -0
  22. data/test/dummy/config.ru +4 -0
  23. data/test/dummy/config/application.rb +22 -0
  24. data/test/dummy/config/boot.rb +5 -0
  25. data/test/dummy/config/database.yml +25 -0
  26. data/test/dummy/config/environment.rb +5 -0
  27. data/test/dummy/config/environments/development.rb +29 -0
  28. data/test/dummy/config/environments/production.rb +80 -0
  29. data/test/dummy/config/environments/test.rb +36 -0
  30. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  31. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  32. data/test/dummy/config/initializers/inflections.rb +16 -0
  33. data/test/dummy/config/initializers/mime_types.rb +5 -0
  34. data/test/dummy/config/initializers/secret_token.rb +12 -0
  35. data/test/dummy/config/initializers/session_store.rb +3 -0
  36. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  37. data/test/dummy/config/locales/en.yml +23 -0
  38. data/test/dummy/config/routes.rb +56 -0
  39. data/test/dummy/db/test.sqlite3 +0 -0
  40. data/test/jquery_file_upload_rails_test.rb +7 -0
  41. data/test/test_helper.rb +15 -0
  42. data/vendor/assets/images/jquery-file-upload/loading.gif +0 -0
  43. data/vendor/assets/images/jquery-file-upload/progressbar.gif +0 -0
  44. data/vendor/assets/javascripts/jquery-file-upload/app.js +101 -0
  45. data/vendor/assets/javascripts/jquery-file-upload/basic-plus-ui-no-widget.js.coffee +35 -0
  46. data/vendor/assets/javascripts/jquery-file-upload/basic-plus-ui.js.coffee +38 -0
  47. data/vendor/assets/javascripts/jquery-file-upload/cors/jquery.postmessage-transport.js +118 -0
  48. data/vendor/assets/javascripts/jquery-file-upload/cors/jquery.xdr-transport.js +87 -0
  49. data/vendor/assets/javascripts/jquery-file-upload/jquery.fileupload-angular.js +428 -0
  50. data/vendor/assets/javascripts/jquery-file-upload/jquery.fileupload-audio.js +106 -0
  51. data/vendor/assets/javascripts/jquery-file-upload/jquery.fileupload-image.js +295 -0
  52. data/vendor/assets/javascripts/jquery-file-upload/jquery.fileupload-jquery-ui.js +144 -0
  53. data/vendor/assets/javascripts/jquery-file-upload/jquery.fileupload-process.js +172 -0
  54. data/vendor/assets/javascripts/jquery-file-upload/jquery.fileupload-ui.js +699 -0
  55. data/vendor/assets/javascripts/jquery-file-upload/jquery.fileupload-validate.js +120 -0
  56. data/vendor/assets/javascripts/jquery-file-upload/jquery.fileupload-video.js +106 -0
  57. data/vendor/assets/javascripts/jquery-file-upload/jquery.fileupload.js +1416 -0
  58. data/vendor/assets/javascripts/jquery-file-upload/jquery.iframe-transport.js +210 -0
  59. data/vendor/assets/javascripts/jquery-file-upload/main.js.coffee +4 -0
  60. data/vendor/assets/javascripts/jquery-file-upload/vendor/canvas-to-blob/canvas-to-blob.js +95 -0
  61. data/vendor/assets/javascripts/jquery-file-upload/vendor/canvas-to-blob/canvas-to-blob.min.js +1 -0
  62. data/vendor/assets/javascripts/jquery-file-upload/vendor/jquery.ui.widget.js +530 -0
  63. data/vendor/assets/javascripts/jquery-file-upload/vendor/load-image/demo.js +138 -0
  64. data/vendor/assets/javascripts/jquery-file-upload/vendor/load-image/load-image-exif-map.js +384 -0
  65. data/vendor/assets/javascripts/jquery-file-upload/vendor/load-image/load-image-exif.js +299 -0
  66. data/vendor/assets/javascripts/jquery-file-upload/vendor/load-image/load-image-ios.js +181 -0
  67. data/vendor/assets/javascripts/jquery-file-upload/vendor/load-image/load-image-meta.js +137 -0
  68. data/vendor/assets/javascripts/jquery-file-upload/vendor/load-image/load-image-orientation.js +159 -0
  69. data/vendor/assets/javascripts/jquery-file-upload/vendor/load-image/load-image.js +276 -0
  70. data/vendor/assets/javascripts/jquery-file-upload/vendor/load-image/load-image.min.js +1 -0
  71. data/vendor/assets/javascripts/jquery-file-upload/vendor/load-image/vendor/jquery.Jcrop.js +1694 -0
  72. data/vendor/assets/javascripts/jquery-file-upload/vendor/templates/compile.js +84 -0
  73. data/vendor/assets/javascripts/jquery-file-upload/vendor/templates/demo.js +48 -0
  74. data/vendor/assets/javascripts/jquery-file-upload/vendor/templates/runtime.js +47 -0
  75. data/vendor/assets/javascripts/jquery-file-upload/vendor/templates/tmpl.js +87 -0
  76. data/vendor/assets/javascripts/jquery-file-upload/vendor/templates/tmpl.min.js +1 -0
  77. data/vendor/assets/stylesheets/jquery-file-upload/demo-ie8.css +21 -0
  78. data/vendor/assets/stylesheets/jquery-file-upload/demo.css +67 -0
  79. data/vendor/assets/stylesheets/jquery-file-upload/jquery.fileupload-noscript.css +22 -0
  80. data/vendor/assets/stylesheets/jquery-file-upload/jquery.fileupload-ui-noscript.css +17 -0
  81. data/vendor/assets/stylesheets/jquery-file-upload/jquery.fileupload-ui.css.scss +57 -0
  82. data/vendor/assets/stylesheets/jquery-file-upload/jquery.fileupload.css +36 -0
  83. data/vendor/assets/stylesheets/jquery-file-upload/style.css +15 -0
  84. metadata +196 -0
@@ -0,0 +1,299 @@
1
+ /*
2
+ * JavaScript Load Image Exif Parser 1.0.0
3
+ * https://github.com/blueimp/JavaScript-Load-Image
4
+ *
5
+ * Copyright 2013, Sebastian Tschan
6
+ * https://blueimp.net
7
+ *
8
+ * Licensed under the MIT license:
9
+ * http://www.opensource.org/licenses/MIT
10
+ */
11
+
12
+ /*jslint unparam: true */
13
+ /*global define, window, console */
14
+
15
+ (function (factory) {
16
+ 'use strict';
17
+ if (typeof define === 'function' && define.amd) {
18
+ // Register as an anonymous AMD module:
19
+ define(['load-image', 'load-image-meta'], factory);
20
+ } else {
21
+ // Browser globals:
22
+ factory(window.loadImage);
23
+ }
24
+ }(function (loadImage) {
25
+ 'use strict';
26
+
27
+ loadImage.ExifMap = function () {
28
+ return this;
29
+ };
30
+
31
+ loadImage.ExifMap.prototype.map = {
32
+ 'Orientation': 0x0112
33
+ };
34
+
35
+ loadImage.ExifMap.prototype.get = function (id) {
36
+ return this[id] || this[this.map[id]];
37
+ };
38
+
39
+ loadImage.getExifThumbnail = function (dataView, offset, length) {
40
+ var hexData,
41
+ i,
42
+ b;
43
+ if (!length || offset + length > dataView.byteLength) {
44
+ console.log('Invalid Exif data: Invalid thumbnail data.');
45
+ return;
46
+ }
47
+ hexData = [];
48
+ for (i = 0; i < length; i += 1) {
49
+ b = dataView.getUint8(offset + i);
50
+ hexData.push((b < 16 ? '0' : '') + b.toString(16));
51
+ }
52
+ return 'data:image/jpeg,%' + hexData.join('%');
53
+ };
54
+
55
+ loadImage.exifTagTypes = {
56
+ // byte, 8-bit unsigned int:
57
+ 1: {
58
+ getValue: function (dataView, dataOffset) {
59
+ return dataView.getUint8(dataOffset);
60
+ },
61
+ size: 1
62
+ },
63
+ // ascii, 8-bit byte:
64
+ 2: {
65
+ getValue: function (dataView, dataOffset) {
66
+ return String.fromCharCode(dataView.getUint8(dataOffset));
67
+ },
68
+ size: 1,
69
+ ascii: true
70
+ },
71
+ // short, 16 bit int:
72
+ 3: {
73
+ getValue: function (dataView, dataOffset, littleEndian) {
74
+ return dataView.getUint16(dataOffset, littleEndian);
75
+ },
76
+ size: 2
77
+ },
78
+ // long, 32 bit int:
79
+ 4: {
80
+ getValue: function (dataView, dataOffset, littleEndian) {
81
+ return dataView.getUint32(dataOffset, littleEndian);
82
+ },
83
+ size: 4
84
+ },
85
+ // rational = two long values, first is numerator, second is denominator:
86
+ 5: {
87
+ getValue: function (dataView, dataOffset, littleEndian) {
88
+ return dataView.getUint32(dataOffset, littleEndian) /
89
+ dataView.getUint32(dataOffset + 4, littleEndian);
90
+ },
91
+ size: 8
92
+ },
93
+ // slong, 32 bit signed int:
94
+ 9: {
95
+ getValue: function (dataView, dataOffset, littleEndian) {
96
+ return dataView.getInt32(dataOffset, littleEndian);
97
+ },
98
+ size: 4
99
+ },
100
+ // srational, two slongs, first is numerator, second is denominator:
101
+ 10: {
102
+ getValue: function (dataView, dataOffset, littleEndian) {
103
+ return dataView.getInt32(dataOffset, littleEndian) /
104
+ dataView.getInt32(dataOffset + 4, littleEndian);
105
+ },
106
+ size: 8
107
+ }
108
+ };
109
+ // undefined, 8-bit byte, value depending on field:
110
+ loadImage.exifTagTypes[7] = loadImage.exifTagTypes[1];
111
+
112
+ loadImage.getExifValue = function (dataView, tiffOffset, offset, type, length, littleEndian) {
113
+ var tagType = loadImage.exifTagTypes[type],
114
+ tagSize,
115
+ dataOffset,
116
+ values,
117
+ i,
118
+ str,
119
+ c;
120
+ if (!tagType) {
121
+ console.log('Invalid Exif data: Invalid tag type.');
122
+ return;
123
+ }
124
+ tagSize = tagType.size * length;
125
+ // Determine if the value is contained in the dataOffset bytes,
126
+ // or if the value at the dataOffset is a pointer to the actual data:
127
+ dataOffset = tagSize > 4 ?
128
+ tiffOffset + dataView.getUint32(offset + 8, littleEndian) : (offset + 8);
129
+ if (dataOffset + tagSize > dataView.byteLength) {
130
+ console.log('Invalid Exif data: Invalid data offset.');
131
+ return;
132
+ }
133
+ if (length === 1) {
134
+ return tagType.getValue(dataView, dataOffset, littleEndian);
135
+ }
136
+ values = [];
137
+ for (i = 0; i < length; i += 1) {
138
+ values[i] = tagType.getValue(dataView, dataOffset + i * tagType.size, littleEndian);
139
+ }
140
+ if (tagType.ascii) {
141
+ str = '';
142
+ // Concatenate the chars:
143
+ for (i = 0; i < values.length; i += 1) {
144
+ c = values[i];
145
+ // Ignore the terminating NULL byte(s):
146
+ if (c === '\u0000') {
147
+ break;
148
+ }
149
+ str += c;
150
+ }
151
+ return str;
152
+ }
153
+ return values;
154
+ };
155
+
156
+ loadImage.parseExifTag = function (dataView, tiffOffset, offset, littleEndian, data) {
157
+ var tag = dataView.getUint16(offset, littleEndian);
158
+ data.exif[tag] = loadImage.getExifValue(
159
+ dataView,
160
+ tiffOffset,
161
+ offset,
162
+ dataView.getUint16(offset + 2, littleEndian), // tag type
163
+ dataView.getUint32(offset + 4, littleEndian), // tag length
164
+ littleEndian
165
+ );
166
+ };
167
+
168
+ loadImage.parseExifTags = function (dataView, tiffOffset, dirOffset, littleEndian, data) {
169
+ var tagsNumber,
170
+ dirEndOffset,
171
+ i;
172
+ if (dirOffset + 6 > dataView.byteLength) {
173
+ console.log('Invalid Exif data: Invalid directory offset.');
174
+ return;
175
+ }
176
+ tagsNumber = dataView.getUint16(dirOffset, littleEndian);
177
+ dirEndOffset = dirOffset + 2 + 12 * tagsNumber;
178
+ if (dirEndOffset + 4 > dataView.byteLength) {
179
+ console.log('Invalid Exif data: Invalid directory size.');
180
+ return;
181
+ }
182
+ for (i = 0; i < tagsNumber; i += 1) {
183
+ this.parseExifTag(
184
+ dataView,
185
+ tiffOffset,
186
+ dirOffset + 2 + 12 * i, // tag offset
187
+ littleEndian,
188
+ data
189
+ );
190
+ }
191
+ // Return the offset to the next directory:
192
+ return dataView.getUint32(dirEndOffset, littleEndian);
193
+ };
194
+
195
+ loadImage.parseExifData = function (dataView, offset, length, data, options) {
196
+ if (options.disableExif) {
197
+ return;
198
+ }
199
+ var tiffOffset = offset + 10,
200
+ littleEndian,
201
+ dirOffset,
202
+ thumbnailData;
203
+ // Check for the ASCII code for "Exif" (0x45786966):
204
+ if (dataView.getUint32(offset + 4) !== 0x45786966) {
205
+ // No Exif data, might be XMP data instead
206
+ return;
207
+ }
208
+ if (tiffOffset + 8 > dataView.byteLength) {
209
+ console.log('Invalid Exif data: Invalid segment size.');
210
+ return;
211
+ }
212
+ // Check for the two null bytes:
213
+ if (dataView.getUint16(offset + 8) !== 0x0000) {
214
+ console.log('Invalid Exif data: Missing byte alignment offset.');
215
+ return;
216
+ }
217
+ // Check the byte alignment:
218
+ switch (dataView.getUint16(tiffOffset)) {
219
+ case 0x4949:
220
+ littleEndian = true;
221
+ break;
222
+ case 0x4D4D:
223
+ littleEndian = false;
224
+ break;
225
+ default:
226
+ console.log('Invalid Exif data: Invalid byte alignment marker.');
227
+ return;
228
+ }
229
+ // Check for the TIFF tag marker (0x002A):
230
+ if (dataView.getUint16(tiffOffset + 2, littleEndian) !== 0x002A) {
231
+ console.log('Invalid Exif data: Missing TIFF marker.');
232
+ return;
233
+ }
234
+ // Retrieve the directory offset bytes, usually 0x00000008 or 8 decimal:
235
+ dirOffset = dataView.getUint32(tiffOffset + 4, littleEndian);
236
+ // Create the exif object to store the tags:
237
+ data.exif = new loadImage.ExifMap();
238
+ // Parse the tags of the main image directory and retrieve the
239
+ // offset to the next directory, usually the thumbnail directory:
240
+ dirOffset = loadImage.parseExifTags(
241
+ dataView,
242
+ tiffOffset,
243
+ tiffOffset + dirOffset,
244
+ littleEndian,
245
+ data
246
+ );
247
+ if (dirOffset && !options.disableExifThumbnail) {
248
+ thumbnailData = {exif: {}};
249
+ dirOffset = loadImage.parseExifTags(
250
+ dataView,
251
+ tiffOffset,
252
+ tiffOffset + dirOffset,
253
+ littleEndian,
254
+ thumbnailData
255
+ );
256
+ // Check for JPEG Thumbnail offset:
257
+ if (thumbnailData.exif[0x0201]) {
258
+ data.exif.Thumbnail = loadImage.getExifThumbnail(
259
+ dataView,
260
+ tiffOffset + thumbnailData.exif[0x0201],
261
+ thumbnailData.exif[0x0202] // Thumbnail data length
262
+ );
263
+ }
264
+ }
265
+ // Check for Exif Sub IFD Pointer:
266
+ if (data.exif[0x8769] && !options.disableExifSub) {
267
+ loadImage.parseExifTags(
268
+ dataView,
269
+ tiffOffset,
270
+ tiffOffset + data.exif[0x8769], // directory offset
271
+ littleEndian,
272
+ data
273
+ );
274
+ }
275
+ // Check for GPS Info IFD Pointer:
276
+ if (data.exif[0x8825] && !options.disableExifGps) {
277
+ loadImage.parseExifTags(
278
+ dataView,
279
+ tiffOffset,
280
+ tiffOffset + data.exif[0x8825], // directory offset
281
+ littleEndian,
282
+ data
283
+ );
284
+ }
285
+ };
286
+
287
+ // Registers the Exif parser for the APP1 JPEG meta data segment:
288
+ loadImage.metaDataParsers.jpeg[0xffe1].push(loadImage.parseExifData);
289
+
290
+ // Adds the following properties to the parseMetaData callback data:
291
+ // * exif: The exif tags, parsed by the parseExifData method
292
+
293
+ // Adds the following options to the parseMetaData method:
294
+ // * disableExif: Disables Exif parsing.
295
+ // * disableExifThumbnail: Disables parsing of the Exif Thumbnail.
296
+ // * disableExifSub: Disables parsing of the Exif Sub IFD.
297
+ // * disableExifGps: Disables parsing of the Exif GPS Info IFD.
298
+
299
+ }));
@@ -0,0 +1,181 @@
1
+ /*
2
+ * JavaScript Load Image iOS scaling fixes 1.0.3
3
+ * https://github.com/blueimp/JavaScript-Load-Image
4
+ *
5
+ * Copyright 2013, Sebastian Tschan
6
+ * https://blueimp.net
7
+ *
8
+ * iOS image scaling fixes based on
9
+ * https://github.com/stomita/ios-imagefile-megapixel
10
+ *
11
+ * Licensed under the MIT license:
12
+ * http://www.opensource.org/licenses/MIT
13
+ */
14
+
15
+ /*jslint nomen: true, bitwise: true */
16
+ /*global define, window, document */
17
+
18
+ (function (factory) {
19
+ 'use strict';
20
+ if (typeof define === 'function' && define.amd) {
21
+ // Register as an anonymous AMD module:
22
+ define(['load-image'], factory);
23
+ } else {
24
+ // Browser globals:
25
+ factory(window.loadImage);
26
+ }
27
+ }(function (loadImage) {
28
+ 'use strict';
29
+
30
+ // Only apply fixes on the iOS platform:
31
+ if (!window.navigator || !window.navigator.platform ||
32
+ !(/iP(hone|od|ad)/).test(window.navigator.platform)) {
33
+ return;
34
+ }
35
+
36
+ var originalRenderMethod = loadImage.renderImageToCanvas;
37
+
38
+ // Detects subsampling in JPEG images:
39
+ loadImage.detectSubsampling = function (img) {
40
+ var canvas,
41
+ context;
42
+ if (img.width * img.height > 1024 * 1024) { // only consider mexapixel images
43
+ canvas = document.createElement('canvas');
44
+ canvas.width = canvas.height = 1;
45
+ context = canvas.getContext('2d');
46
+ context.drawImage(img, -img.width + 1, 0);
47
+ // subsampled image becomes half smaller in rendering size.
48
+ // check alpha channel value to confirm image is covering edge pixel or not.
49
+ // if alpha value is 0 image is not covering, hence subsampled.
50
+ return context.getImageData(0, 0, 1, 1).data[3] === 0;
51
+ }
52
+ return false;
53
+ };
54
+
55
+ // Detects vertical squash in JPEG images:
56
+ loadImage.detectVerticalSquash = function (img, subsampled) {
57
+ var naturalHeight = img.naturalHeight || img.height,
58
+ canvas = document.createElement('canvas'),
59
+ context = canvas.getContext('2d'),
60
+ data,
61
+ sy,
62
+ ey,
63
+ py,
64
+ alpha;
65
+ if (subsampled) {
66
+ naturalHeight /= 2;
67
+ }
68
+ canvas.width = 1;
69
+ canvas.height = naturalHeight;
70
+ context.drawImage(img, 0, 0);
71
+ data = context.getImageData(0, 0, 1, naturalHeight).data;
72
+ // search image edge pixel position in case it is squashed vertically:
73
+ sy = 0;
74
+ ey = naturalHeight;
75
+ py = naturalHeight;
76
+ while (py > sy) {
77
+ alpha = data[(py - 1) * 4 + 3];
78
+ if (alpha === 0) {
79
+ ey = py;
80
+ } else {
81
+ sy = py;
82
+ }
83
+ py = (ey + sy) >> 1;
84
+ }
85
+ return (py / naturalHeight) || 1;
86
+ };
87
+
88
+ // Renders image to canvas while working around iOS image scaling bugs:
89
+ // https://github.com/blueimp/JavaScript-Load-Image/issues/13
90
+ loadImage.renderImageToCanvas = function (
91
+ canvas,
92
+ img,
93
+ sourceX,
94
+ sourceY,
95
+ sourceWidth,
96
+ sourceHeight,
97
+ destX,
98
+ destY,
99
+ destWidth,
100
+ destHeight
101
+ ) {
102
+ if (img._type === 'image/jpeg') {
103
+ var context = canvas.getContext('2d'),
104
+ tmpCanvas = document.createElement('canvas'),
105
+ tileSize = 1024,
106
+ tmpContext = tmpCanvas.getContext('2d'),
107
+ subsampled,
108
+ vertSquashRatio,
109
+ tileX,
110
+ tileY;
111
+ tmpCanvas.width = tileSize;
112
+ tmpCanvas.height = tileSize;
113
+ context.save();
114
+ subsampled = loadImage.detectSubsampling(img);
115
+ if (subsampled) {
116
+ sourceX /= 2;
117
+ sourceY /= 2;
118
+ sourceWidth /= 2;
119
+ sourceHeight /= 2;
120
+ }
121
+ vertSquashRatio = loadImage.detectVerticalSquash(img, subsampled);
122
+ if (subsampled || vertSquashRatio !== 1) {
123
+ sourceY *= vertSquashRatio;
124
+ destWidth = Math.ceil(tileSize * destWidth / sourceWidth);
125
+ destHeight = Math.ceil(
126
+ tileSize * destHeight / sourceHeight / vertSquashRatio
127
+ );
128
+ destY = 0;
129
+ tileY = 0;
130
+ while (tileY < sourceHeight) {
131
+ destX = 0;
132
+ tileX = 0;
133
+ while (tileX < sourceWidth) {
134
+ tmpContext.clearRect(0, 0, tileSize, tileSize);
135
+ tmpContext.drawImage(
136
+ img,
137
+ sourceX,
138
+ sourceY,
139
+ sourceWidth,
140
+ sourceHeight,
141
+ -tileX,
142
+ -tileY,
143
+ sourceWidth,
144
+ sourceHeight
145
+ );
146
+ context.drawImage(
147
+ tmpCanvas,
148
+ 0,
149
+ 0,
150
+ tileSize,
151
+ tileSize,
152
+ destX,
153
+ destY,
154
+ destWidth,
155
+ destHeight
156
+ );
157
+ tileX += tileSize;
158
+ destX += destWidth;
159
+ }
160
+ tileY += tileSize;
161
+ destY += destHeight;
162
+ }
163
+ context.restore();
164
+ return canvas;
165
+ }
166
+ }
167
+ return originalRenderMethod(
168
+ canvas,
169
+ img,
170
+ sourceX,
171
+ sourceY,
172
+ sourceWidth,
173
+ sourceHeight,
174
+ destX,
175
+ destY,
176
+ destWidth,
177
+ destHeight
178
+ );
179
+ };
180
+
181
+ }));