webshims-rails 1.14.6 → 1.15.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/webshims-rails/version.rb +2 -2
- data/vendor/assets/javascripts/webshims/polyfiller.js +145 -139
- data/vendor/assets/javascripts/webshims/shims/canvas-blob.js +97 -0
- data/vendor/assets/javascripts/webshims/shims/combos/1.js +13 -15
- data/vendor/assets/javascripts/webshims/shims/combos/10.js +29 -28
- data/vendor/assets/javascripts/webshims/shims/combos/11.js +2 -1
- data/vendor/assets/javascripts/webshims/shims/combos/12.js +22 -10
- data/vendor/assets/javascripts/webshims/shims/combos/13.js +22 -10
- data/vendor/assets/javascripts/webshims/shims/combos/15.js +28 -43
- data/vendor/assets/javascripts/webshims/shims/combos/16.js +41 -44
- data/vendor/assets/javascripts/webshims/shims/combos/17.js +2 -1
- data/vendor/assets/javascripts/webshims/shims/combos/2.js +40 -42
- data/vendor/assets/javascripts/webshims/shims/combos/21.js +98 -71
- data/vendor/assets/javascripts/webshims/shims/combos/22.js +9 -9
- data/vendor/assets/javascripts/webshims/shims/combos/23.js +13 -1
- data/vendor/assets/javascripts/webshims/shims/combos/25.js +141 -51
- data/vendor/assets/javascripts/webshims/shims/combos/27.js +66 -12
- data/vendor/assets/javascripts/webshims/shims/combos/28.js +1 -2
- data/vendor/assets/javascripts/webshims/shims/combos/3.js +27 -41
- data/vendor/assets/javascripts/webshims/shims/combos/30.js +27 -41
- data/vendor/assets/javascripts/webshims/shims/combos/31.js +27 -41
- data/vendor/assets/javascripts/webshims/shims/combos/34.js +36 -36
- data/vendor/assets/javascripts/webshims/shims/combos/4.js +27 -27
- data/vendor/assets/javascripts/webshims/shims/combos/5.js +2 -1
- data/vendor/assets/javascripts/webshims/shims/combos/6.js +2 -1
- data/vendor/assets/javascripts/webshims/shims/combos/7.js +40 -42
- data/vendor/assets/javascripts/webshims/shims/combos/8.js +40 -42
- data/vendor/assets/javascripts/webshims/shims/combos/9.js +29 -28
- data/vendor/assets/javascripts/webshims/shims/combos/98.js +4 -2
- data/vendor/assets/javascripts/webshims/shims/combos/99.js +4 -2
- data/vendor/assets/javascripts/webshims/shims/dom-extend.js +27 -27
- data/vendor/assets/javascripts/webshims/shims/es6.js +23 -29
- data/vendor/assets/javascripts/webshims/shims/{filereader.js → filereader-xhr.js} +66 -12
- data/vendor/assets/javascripts/webshims/shims/form-core.js +0 -14
- data/vendor/assets/javascripts/webshims/shims/form-number-date-ui.js +2 -1
- data/vendor/assets/javascripts/webshims/shims/form-shim-extend.js +1 -2
- data/vendor/assets/javascripts/webshims/shims/form-validation.js +18 -5
- data/vendor/assets/javascripts/webshims/shims/form-validators.js +15 -14
- data/vendor/assets/javascripts/webshims/shims/geolocation.js +41 -50
- data/vendor/assets/javascripts/webshims/shims/jme/controls.css +4 -4
- data/vendor/assets/javascripts/webshims/shims/jme/controls.scss +2 -1
- data/vendor/assets/javascripts/webshims/shims/jme/mediacontrols.js +4 -2
- data/vendor/assets/javascripts/webshims/shims/mediacapture-picker.js +42 -0
- data/vendor/assets/javascripts/webshims/shims/mediacapture.js +159 -0
- data/vendor/assets/javascripts/webshims/shims/mediaelement-core.js +13 -1
- data/vendor/assets/javascripts/webshims/shims/mediaelement-jaris.js +48 -12
- data/vendor/assets/javascripts/webshims/shims/mediaelement-yt.js +20 -8
- data/vendor/assets/javascripts/webshims/shims/{combos/26.js → moxie/js/moxie-html4.js} +2121 -1257
- data/vendor/assets/javascripts/webshims/shims/moxie/js/{moxie.js → moxie-swf.js} +1125 -1741
- data/vendor/assets/javascripts/webshims/shims/sticky.js +585 -0
- data/vendor/assets/javascripts/webshims/shims/styles/forms-picker.css +20 -0
- data/vendor/assets/javascripts/webshims/shims/styles/scss/forms-picker.scss +23 -0
- data/vendor/assets/javascripts/webshims/shims/styles/scss/shim.scss +74 -34
- data/vendor/assets/javascripts/webshims/shims/styles/shim-ext.css +78 -31
- data/vendor/assets/javascripts/webshims/shims/styles/shim.css +78 -31
- data/vendor/assets/javascripts/webshims/shims/swf/JarisFLVPlayer.swf +0 -0
- data/vendor/assets/javascripts/webshims/shims/track-ui.js +214 -111
- data/vendor/assets/javascripts/webshims/shims/track.js +9 -9
- data/vendor/assets/javascripts/webshims/shims/usermedia-core.js +27 -0
- data/vendor/assets/javascripts/webshims/shims/usermedia-shim.js +34 -37
- metadata +9 -8
- data/vendor/assets/javascripts/webshims/shims/jajax.js +0 -1262
- data/vendor/assets/javascripts/webshims/shims/moxie/silverlight/Moxie.cdn.xap +0 -0
- data/vendor/assets/javascripts/webshims/shims/moxie/silverlight/Moxie.min.xap +0 -0
@@ -2,13 +2,21 @@ webshims.register('mediaelement-yt', function($, webshims, window, document, und
|
|
2
2
|
"use strict";
|
3
3
|
var mediaelement = webshims.mediaelement;
|
4
4
|
var ytAPI = $.Deferred();
|
5
|
+
var loadYTAPI = function(){
|
6
|
+
if(!window.YT){
|
7
|
+
webshims.loader.loadScript("https://www.youtube.com/player_api");
|
8
|
+
}
|
9
|
+
loadYTAPI = $.noop;
|
10
|
+
};
|
11
|
+
var modern = window.Modernizr;
|
12
|
+
var assumeYTBug = (!modern || !modern.videoautoplay) && /iP(hone|od|ad)|android/i.test(navigator.userAgent);
|
5
13
|
window.onYouTubePlayerAPIReady = function() {
|
6
14
|
ytAPI.resolve();
|
15
|
+
loadYTAPI = $.noop;
|
7
16
|
};
|
8
17
|
if(window.YT && YT.Player){
|
9
18
|
window.onYouTubePlayerAPIReady();
|
10
19
|
}
|
11
|
-
|
12
20
|
var getProps = {
|
13
21
|
paused: true,
|
14
22
|
ended: false,
|
@@ -45,7 +53,6 @@ var getSetProps = {
|
|
45
53
|
volume: 1,
|
46
54
|
muted: false
|
47
55
|
};
|
48
|
-
var getSetPropKeys = Object.keys(getSetProps);
|
49
56
|
|
50
57
|
var playerStateObj = $.extend({
|
51
58
|
isActive: 'html5',
|
@@ -193,7 +200,6 @@ var getComputedDimension = (function(){
|
|
193
200
|
|
194
201
|
var setElementDimension = function(data){
|
195
202
|
var dims;
|
196
|
-
var elem = data._elem;
|
197
203
|
var box = data.shadowElem;
|
198
204
|
if(data.isActive == 'third'){
|
199
205
|
if(data && data._ytAPI && data._ytAPI.getPlaybackQuality){
|
@@ -439,9 +445,9 @@ var addYtAPI = function(mediaElm, elemId, data, ytParams){
|
|
439
445
|
var currentTime = data._ytAPI.getCurrentTime();
|
440
446
|
if(data.currentTime != currentTime){
|
441
447
|
data.currentTime = currentTime;
|
442
|
-
|
448
|
+
$.event.trigger('timeupdate', null, mediaElm, true);
|
443
449
|
}
|
444
|
-
},
|
450
|
+
}, 270);
|
445
451
|
};
|
446
452
|
|
447
453
|
data._metatrys = 0;
|
@@ -569,7 +575,9 @@ mediaelement.createSWF = function(mediaElem, src, data){
|
|
569
575
|
var ytParams = getYtParams(src.src);
|
570
576
|
var hasControls = $.prop(mediaElem, 'controls');
|
571
577
|
var attrStyle = {};
|
572
|
-
|
578
|
+
|
579
|
+
loadYTAPI();
|
580
|
+
|
573
581
|
if((attrStyle.height = $.attr(mediaElem, 'height') || '') || (attrStyle.width = $.attr(mediaElem, 'width') || '')){
|
574
582
|
$(mediaElem).css(attrStyle);
|
575
583
|
webshims.warn("width or height content attributes used. Webshims prefers the usage of CSS (computed styles or inline styles) to detect size of a video/audio. It's really more powerfull.");
|
@@ -739,8 +747,12 @@ mediaelement.createSWF = function(mediaElem, src, data){
|
|
739
747
|
var data = getYtDataFromElem(this);
|
740
748
|
if(data){
|
741
749
|
if(data._ytAPI && data._ytAPI[ytName]){
|
742
|
-
data.
|
743
|
-
|
750
|
+
if(assumeYTBug && !data.readyState && !data.networkState && data._ppFlag === undefined){
|
751
|
+
webshims.warn('youtube video play needs to be directly activated by user, if you use a video overlay set pointer-events to none.');
|
752
|
+
} else {
|
753
|
+
data._ytAPI[ytName]();
|
754
|
+
handlePlayPauseState(name, data);
|
755
|
+
}
|
744
756
|
}
|
745
757
|
} else {
|
746
758
|
return mediaSup[name].prop._supvalue.apply(this, arguments);
|
@@ -5131,436 +5131,6 @@ define("moxie/xhr/XMLHttpRequest", [
|
|
5131
5131
|
return XMLHttpRequest;
|
5132
5132
|
});
|
5133
5133
|
|
5134
|
-
// Included from: src/javascript/runtime/flash/Runtime.js
|
5135
|
-
|
5136
|
-
/**
|
5137
|
-
* Runtime.js
|
5138
|
-
*
|
5139
|
-
* Copyright 2013, Moxiecode Systems AB
|
5140
|
-
* Released under GPL License.
|
5141
|
-
*
|
5142
|
-
* License: http://www.plupload.com/license
|
5143
|
-
* Contributing: http://www.plupload.com/contributing
|
5144
|
-
*/
|
5145
|
-
|
5146
|
-
/*global ActiveXObject:true */
|
5147
|
-
|
5148
|
-
/**
|
5149
|
-
Defines constructor for Flash runtime.
|
5150
|
-
|
5151
|
-
@class moxie/runtime/flash/Runtime
|
5152
|
-
@private
|
5153
|
-
*/
|
5154
|
-
define("moxie/runtime/flash/Runtime", [
|
5155
|
-
"moxie/core/utils/Basic",
|
5156
|
-
"moxie/core/utils/Env",
|
5157
|
-
"moxie/core/utils/Dom",
|
5158
|
-
"moxie/core/Exceptions",
|
5159
|
-
"moxie/runtime/Runtime"
|
5160
|
-
], function(Basic, Env, Dom, x, Runtime) {
|
5161
|
-
|
5162
|
-
var type = 'flash', extensions = {};
|
5163
|
-
|
5164
|
-
/**
|
5165
|
-
Get the version of the Flash Player
|
5166
|
-
|
5167
|
-
@method getShimVersion
|
5168
|
-
@private
|
5169
|
-
@return {Number} Flash Player version
|
5170
|
-
*/
|
5171
|
-
function getShimVersion() {
|
5172
|
-
var version;
|
5173
|
-
|
5174
|
-
try {
|
5175
|
-
version = navigator.plugins['Shockwave Flash'];
|
5176
|
-
version = version.description;
|
5177
|
-
} catch (e1) {
|
5178
|
-
try {
|
5179
|
-
version = new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version');
|
5180
|
-
} catch (e2) {
|
5181
|
-
version = '0.0';
|
5182
|
-
}
|
5183
|
-
}
|
5184
|
-
version = version.match(/\d+/g);
|
5185
|
-
return parseFloat(version[0] + '.' + version[1]);
|
5186
|
-
}
|
5187
|
-
|
5188
|
-
/**
|
5189
|
-
Constructor for the Flash Runtime
|
5190
|
-
|
5191
|
-
@class FlashRuntime
|
5192
|
-
@extends Runtime
|
5193
|
-
*/
|
5194
|
-
function FlashRuntime(options) {
|
5195
|
-
var I = this, initTimer;
|
5196
|
-
|
5197
|
-
options = Basic.extend({ swf_url: Env.swf_url }, options);
|
5198
|
-
|
5199
|
-
Runtime.call(this, options, type, {
|
5200
|
-
access_binary: function(value) {
|
5201
|
-
return value && I.mode === 'browser';
|
5202
|
-
},
|
5203
|
-
access_image_binary: function(value) {
|
5204
|
-
return value && I.mode === 'browser';
|
5205
|
-
},
|
5206
|
-
display_media: Runtime.capTrue,
|
5207
|
-
do_cors: Runtime.capTrue,
|
5208
|
-
drag_and_drop: false,
|
5209
|
-
report_upload_progress: function() {
|
5210
|
-
return I.mode === 'client';
|
5211
|
-
},
|
5212
|
-
resize_image: Runtime.capTrue,
|
5213
|
-
return_response_headers: false,
|
5214
|
-
return_response_type: function(responseType) {
|
5215
|
-
if (responseType === 'json' && !!window.JSON) {
|
5216
|
-
return true;
|
5217
|
-
}
|
5218
|
-
return !Basic.arrayDiff(responseType, ['', 'text', 'document']) || I.mode === 'browser';
|
5219
|
-
},
|
5220
|
-
return_status_code: function(code) {
|
5221
|
-
return I.mode === 'browser' || !Basic.arrayDiff(code, [200, 404]);
|
5222
|
-
},
|
5223
|
-
select_file: Runtime.capTrue,
|
5224
|
-
select_multiple: Runtime.capTrue,
|
5225
|
-
send_binary_string: function(value) {
|
5226
|
-
return value && I.mode === 'browser';
|
5227
|
-
},
|
5228
|
-
send_browser_cookies: function(value) {
|
5229
|
-
return value && I.mode === 'browser';
|
5230
|
-
},
|
5231
|
-
send_custom_headers: function(value) {
|
5232
|
-
return value && I.mode === 'browser';
|
5233
|
-
},
|
5234
|
-
send_multipart: Runtime.capTrue,
|
5235
|
-
slice_blob: function(value) {
|
5236
|
-
return value && I.mode === 'browser';
|
5237
|
-
},
|
5238
|
-
stream_upload: function(value) {
|
5239
|
-
return value && I.mode === 'browser';
|
5240
|
-
},
|
5241
|
-
summon_file_dialog: false,
|
5242
|
-
upload_filesize: function(size) {
|
5243
|
-
return Basic.parseSizeStr(size) <= 2097152 || I.mode === 'client';
|
5244
|
-
},
|
5245
|
-
use_http_method: function(methods) {
|
5246
|
-
return !Basic.arrayDiff(methods, ['GET', 'POST']);
|
5247
|
-
}
|
5248
|
-
}, {
|
5249
|
-
// capabilities that require specific mode
|
5250
|
-
access_binary: function(value) {
|
5251
|
-
return value ? 'browser' : 'client';
|
5252
|
-
},
|
5253
|
-
access_image_binary: function(value) {
|
5254
|
-
return value ? 'browser' : 'client';
|
5255
|
-
},
|
5256
|
-
report_upload_progress: function(value) {
|
5257
|
-
return value ? 'browser' : 'client';
|
5258
|
-
},
|
5259
|
-
return_response_type: function(responseType) {
|
5260
|
-
return Basic.arrayDiff(responseType, ['', 'text', 'json', 'document']) ? 'browser' : ['client', 'browser'];
|
5261
|
-
},
|
5262
|
-
return_status_code: function(code) {
|
5263
|
-
return Basic.arrayDiff(code, [200, 404]) ? 'browser' : ['client', 'browser'];
|
5264
|
-
},
|
5265
|
-
send_binary_string: function(value) {
|
5266
|
-
return value ? 'browser' : 'client';
|
5267
|
-
},
|
5268
|
-
send_browser_cookies: function(value) {
|
5269
|
-
return value ? 'browser' : 'client';
|
5270
|
-
},
|
5271
|
-
send_custom_headers: function(value) {
|
5272
|
-
return value ? 'browser' : 'client';
|
5273
|
-
},
|
5274
|
-
stream_upload: function(value) {
|
5275
|
-
return value ? 'client' : 'browser';
|
5276
|
-
},
|
5277
|
-
upload_filesize: function(size) {
|
5278
|
-
return Basic.parseSizeStr(size) >= 2097152 ? 'client' : 'browser';
|
5279
|
-
}
|
5280
|
-
}, 'client');
|
5281
|
-
|
5282
|
-
|
5283
|
-
// minimal requirement for Flash Player version
|
5284
|
-
if (getShimVersion() < 10) {
|
5285
|
-
this.mode = false; // with falsy mode, runtime won't operable, no matter what the mode was before
|
5286
|
-
}
|
5287
|
-
|
5288
|
-
|
5289
|
-
Basic.extend(this, {
|
5290
|
-
|
5291
|
-
getShim: function() {
|
5292
|
-
return Dom.get(this.uid);
|
5293
|
-
},
|
5294
|
-
|
5295
|
-
shimExec: function(component, action) {
|
5296
|
-
var args = [].slice.call(arguments, 2);
|
5297
|
-
return I.getShim().exec(this.uid, component, action, args);
|
5298
|
-
},
|
5299
|
-
|
5300
|
-
init: function() {
|
5301
|
-
var html, el, container;
|
5302
|
-
|
5303
|
-
container = this.getShimContainer();
|
5304
|
-
|
5305
|
-
// if not the minimal height, shims are not initialized in older browsers (e.g FF3.6, IE6,7,8, Safari 4.0,5.0, etc)
|
5306
|
-
Basic.extend(container.style, {
|
5307
|
-
position: 'absolute',
|
5308
|
-
top: '-8px',
|
5309
|
-
left: '-8px',
|
5310
|
-
width: '9px',
|
5311
|
-
height: '9px',
|
5312
|
-
overflow: 'hidden'
|
5313
|
-
});
|
5314
|
-
|
5315
|
-
// insert flash object
|
5316
|
-
html = '<object id="' + this.uid + '" type="application/x-shockwave-flash" data="' + options.swf_url + '" ';
|
5317
|
-
|
5318
|
-
if (Env.browser === 'IE') {
|
5319
|
-
html += 'classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" ';
|
5320
|
-
}
|
5321
|
-
|
5322
|
-
html += 'width="100%" height="100%" style="outline:0">' +
|
5323
|
-
'<param name="movie" value="' + options.swf_url + '" />' +
|
5324
|
-
'<param name="flashvars" value="uid=' + escape(this.uid) + '&target=' + Env.global_event_dispatcher + '" />' +
|
5325
|
-
'<param name="wmode" value="transparent" />' +
|
5326
|
-
'<param name="allowscriptaccess" value="always" />' +
|
5327
|
-
'</object>';
|
5328
|
-
|
5329
|
-
if (Env.browser === 'IE') {
|
5330
|
-
el = document.createElement('div');
|
5331
|
-
container.appendChild(el);
|
5332
|
-
el.outerHTML = html;
|
5333
|
-
el = container = null; // just in case
|
5334
|
-
} else {
|
5335
|
-
container.innerHTML = html;
|
5336
|
-
}
|
5337
|
-
|
5338
|
-
// Init is dispatched by the shim
|
5339
|
-
initTimer = setTimeout(function() {
|
5340
|
-
if (I && !I.initialized) { // runtime might be already destroyed by this moment
|
5341
|
-
I.trigger("Error", new x.RuntimeError(x.RuntimeError.NOT_INIT_ERR));
|
5342
|
-
}
|
5343
|
-
}, 5000);
|
5344
|
-
},
|
5345
|
-
|
5346
|
-
destroy: (function(destroy) { // extend default destroy method
|
5347
|
-
return function() {
|
5348
|
-
destroy.call(I);
|
5349
|
-
clearTimeout(initTimer); // initialization check might be still onwait
|
5350
|
-
options = initTimer = destroy = I = null;
|
5351
|
-
};
|
5352
|
-
}(this.destroy))
|
5353
|
-
|
5354
|
-
}, extensions);
|
5355
|
-
}
|
5356
|
-
|
5357
|
-
Runtime.addConstructor(type, FlashRuntime);
|
5358
|
-
|
5359
|
-
return extensions;
|
5360
|
-
});
|
5361
|
-
|
5362
|
-
// Included from: src/javascript/runtime/flash/file/Blob.js
|
5363
|
-
|
5364
|
-
/**
|
5365
|
-
* Blob.js
|
5366
|
-
*
|
5367
|
-
* Copyright 2013, Moxiecode Systems AB
|
5368
|
-
* Released under GPL License.
|
5369
|
-
*
|
5370
|
-
* License: http://www.plupload.com/license
|
5371
|
-
* Contributing: http://www.plupload.com/contributing
|
5372
|
-
*/
|
5373
|
-
|
5374
|
-
/**
|
5375
|
-
@class moxie/runtime/flash/file/Blob
|
5376
|
-
@private
|
5377
|
-
*/
|
5378
|
-
define("moxie/runtime/flash/file/Blob", [
|
5379
|
-
"moxie/runtime/flash/Runtime",
|
5380
|
-
"moxie/file/Blob"
|
5381
|
-
], function(extensions, Blob) {
|
5382
|
-
|
5383
|
-
var FlashBlob = {
|
5384
|
-
slice: function(blob, start, end, type) {
|
5385
|
-
var self = this.getRuntime();
|
5386
|
-
|
5387
|
-
if (start < 0) {
|
5388
|
-
start = Math.max(blob.size + start, 0);
|
5389
|
-
} else if (start > 0) {
|
5390
|
-
start = Math.min(start, blob.size);
|
5391
|
-
}
|
5392
|
-
|
5393
|
-
if (end < 0) {
|
5394
|
-
end = Math.max(blob.size + end, 0);
|
5395
|
-
} else if (end > 0) {
|
5396
|
-
end = Math.min(end, blob.size);
|
5397
|
-
}
|
5398
|
-
|
5399
|
-
blob = self.shimExec.call(this, 'Blob', 'slice', start, end, type || '');
|
5400
|
-
|
5401
|
-
if (blob) {
|
5402
|
-
blob = new Blob(self.uid, blob);
|
5403
|
-
}
|
5404
|
-
return blob;
|
5405
|
-
}
|
5406
|
-
};
|
5407
|
-
|
5408
|
-
return (extensions.Blob = FlashBlob);
|
5409
|
-
});
|
5410
|
-
|
5411
|
-
// Included from: src/javascript/runtime/flash/file/FileInput.js
|
5412
|
-
|
5413
|
-
/**
|
5414
|
-
* FileInput.js
|
5415
|
-
*
|
5416
|
-
* Copyright 2013, Moxiecode Systems AB
|
5417
|
-
* Released under GPL License.
|
5418
|
-
*
|
5419
|
-
* License: http://www.plupload.com/license
|
5420
|
-
* Contributing: http://www.plupload.com/contributing
|
5421
|
-
*/
|
5422
|
-
|
5423
|
-
/**
|
5424
|
-
@class moxie/runtime/flash/file/FileInput
|
5425
|
-
@private
|
5426
|
-
*/
|
5427
|
-
define("moxie/runtime/flash/file/FileInput", [
|
5428
|
-
"moxie/runtime/flash/Runtime"
|
5429
|
-
], function(extensions) {
|
5430
|
-
|
5431
|
-
var FileInput = {
|
5432
|
-
init: function(options) {
|
5433
|
-
this.getRuntime().shimExec.call(this, 'FileInput', 'init', {
|
5434
|
-
name: options.name,
|
5435
|
-
accept: options.accept,
|
5436
|
-
multiple: options.multiple
|
5437
|
-
});
|
5438
|
-
this.trigger('ready');
|
5439
|
-
}
|
5440
|
-
};
|
5441
|
-
|
5442
|
-
return (extensions.FileInput = FileInput);
|
5443
|
-
});
|
5444
|
-
|
5445
|
-
// Included from: src/javascript/runtime/flash/file/FileReader.js
|
5446
|
-
|
5447
|
-
/**
|
5448
|
-
* FileReader.js
|
5449
|
-
*
|
5450
|
-
* Copyright 2013, Moxiecode Systems AB
|
5451
|
-
* Released under GPL License.
|
5452
|
-
*
|
5453
|
-
* License: http://www.plupload.com/license
|
5454
|
-
* Contributing: http://www.plupload.com/contributing
|
5455
|
-
*/
|
5456
|
-
|
5457
|
-
/**
|
5458
|
-
@class moxie/runtime/flash/file/FileReader
|
5459
|
-
@private
|
5460
|
-
*/
|
5461
|
-
define("moxie/runtime/flash/file/FileReader", [
|
5462
|
-
"moxie/runtime/flash/Runtime",
|
5463
|
-
"moxie/core/utils/Encode"
|
5464
|
-
], function(extensions, Encode) {
|
5465
|
-
|
5466
|
-
var _result = '';
|
5467
|
-
|
5468
|
-
function _formatData(data, op) {
|
5469
|
-
switch (op) {
|
5470
|
-
case 'readAsText':
|
5471
|
-
return Encode.atob(data, 'utf8');
|
5472
|
-
case 'readAsBinaryString':
|
5473
|
-
return Encode.atob(data);
|
5474
|
-
case 'readAsDataURL':
|
5475
|
-
return data;
|
5476
|
-
}
|
5477
|
-
return null;
|
5478
|
-
}
|
5479
|
-
|
5480
|
-
var FileReader = {
|
5481
|
-
read: function(op, blob) {
|
5482
|
-
var target = this, self = target.getRuntime();
|
5483
|
-
|
5484
|
-
// special prefix for DataURL read mode
|
5485
|
-
if (op === 'readAsDataURL') {
|
5486
|
-
_result = 'data:' + (blob.type || '') + ';base64,';
|
5487
|
-
}
|
5488
|
-
|
5489
|
-
target.bind('Progress', function(e, data) {
|
5490
|
-
if (data) {
|
5491
|
-
_result += _formatData(data, op);
|
5492
|
-
}
|
5493
|
-
});
|
5494
|
-
|
5495
|
-
return self.shimExec.call(this, 'FileReader', 'readAsBase64', blob.uid);
|
5496
|
-
},
|
5497
|
-
|
5498
|
-
getResult: function() {
|
5499
|
-
return _result;
|
5500
|
-
},
|
5501
|
-
|
5502
|
-
destroy: function() {
|
5503
|
-
_result = null;
|
5504
|
-
}
|
5505
|
-
};
|
5506
|
-
|
5507
|
-
return (extensions.FileReader = FileReader);
|
5508
|
-
});
|
5509
|
-
|
5510
|
-
// Included from: src/javascript/runtime/flash/file/FileReaderSync.js
|
5511
|
-
|
5512
|
-
/**
|
5513
|
-
* FileReaderSync.js
|
5514
|
-
*
|
5515
|
-
* Copyright 2013, Moxiecode Systems AB
|
5516
|
-
* Released under GPL License.
|
5517
|
-
*
|
5518
|
-
* License: http://www.plupload.com/license
|
5519
|
-
* Contributing: http://www.plupload.com/contributing
|
5520
|
-
*/
|
5521
|
-
|
5522
|
-
/**
|
5523
|
-
@class moxie/runtime/flash/file/FileReaderSync
|
5524
|
-
@private
|
5525
|
-
*/
|
5526
|
-
define("moxie/runtime/flash/file/FileReaderSync", [
|
5527
|
-
"moxie/runtime/flash/Runtime",
|
5528
|
-
"moxie/core/utils/Encode"
|
5529
|
-
], function(extensions, Encode) {
|
5530
|
-
|
5531
|
-
function _formatData(data, op) {
|
5532
|
-
switch (op) {
|
5533
|
-
case 'readAsText':
|
5534
|
-
return Encode.atob(data, 'utf8');
|
5535
|
-
case 'readAsBinaryString':
|
5536
|
-
return Encode.atob(data);
|
5537
|
-
case 'readAsDataURL':
|
5538
|
-
return data;
|
5539
|
-
}
|
5540
|
-
return null;
|
5541
|
-
}
|
5542
|
-
|
5543
|
-
var FileReaderSync = {
|
5544
|
-
read: function(op, blob) {
|
5545
|
-
var result, self = this.getRuntime();
|
5546
|
-
|
5547
|
-
result = self.shimExec.call(this, 'FileReaderSync', 'readAsBase64', blob.uid);
|
5548
|
-
if (!result) {
|
5549
|
-
return null; // or throw ex
|
5550
|
-
}
|
5551
|
-
|
5552
|
-
// special prefix for DataURL read mode
|
5553
|
-
if (op === 'readAsDataURL') {
|
5554
|
-
result = 'data:' + (blob.type || '') + ';base64,' + result;
|
5555
|
-
}
|
5556
|
-
|
5557
|
-
return _formatData(result, op, blob.type);
|
5558
|
-
}
|
5559
|
-
};
|
5560
|
-
|
5561
|
-
return (extensions.FileReaderSync = FileReaderSync);
|
5562
|
-
});
|
5563
|
-
|
5564
5134
|
// Included from: src/javascript/runtime/Transporter.js
|
5565
5135
|
|
5566
5136
|
/**
|
@@ -5698,10 +5268,10 @@ define("moxie/runtime/Transporter", [
|
|
5698
5268
|
return Transporter;
|
5699
5269
|
});
|
5700
5270
|
|
5701
|
-
// Included from: src/javascript/
|
5271
|
+
// Included from: src/javascript/image/Image.js
|
5702
5272
|
|
5703
5273
|
/**
|
5704
|
-
*
|
5274
|
+
* Image.js
|
5705
5275
|
*
|
5706
5276
|
* Copyright 2013, Moxiecode Systems AB
|
5707
5277
|
* Released under GPL License.
|
@@ -5710,141 +5280,598 @@ define("moxie/runtime/Transporter", [
|
|
5710
5280
|
* Contributing: http://www.plupload.com/contributing
|
5711
5281
|
*/
|
5712
5282
|
|
5713
|
-
|
5714
|
-
@class moxie/runtime/flash/xhr/XMLHttpRequest
|
5715
|
-
@private
|
5716
|
-
*/
|
5717
|
-
define("moxie/runtime/flash/xhr/XMLHttpRequest", [
|
5718
|
-
"moxie/runtime/flash/Runtime",
|
5283
|
+
define("moxie/image/Image", [
|
5719
5284
|
"moxie/core/utils/Basic",
|
5285
|
+
"moxie/core/utils/Dom",
|
5286
|
+
"moxie/core/Exceptions",
|
5287
|
+
"moxie/file/FileReaderSync",
|
5288
|
+
"moxie/xhr/XMLHttpRequest",
|
5289
|
+
"moxie/runtime/Runtime",
|
5290
|
+
"moxie/runtime/RuntimeClient",
|
5291
|
+
"moxie/runtime/Transporter",
|
5292
|
+
"moxie/core/utils/Env",
|
5293
|
+
"moxie/core/EventTarget",
|
5720
5294
|
"moxie/file/Blob",
|
5721
5295
|
"moxie/file/File",
|
5722
|
-
"moxie/
|
5723
|
-
|
5724
|
-
|
5725
|
-
|
5726
|
-
|
5727
|
-
var XMLHttpRequest = {
|
5296
|
+
"moxie/core/utils/Encode"
|
5297
|
+
], function(Basic, Dom, x, FileReaderSync, XMLHttpRequest, Runtime, RuntimeClient, Transporter, Env, EventTarget, Blob, File, Encode) {
|
5298
|
+
/**
|
5299
|
+
Image preloading and manipulation utility. Additionally it provides access to image meta info (Exif, GPS) and raw binary data.
|
5728
5300
|
|
5729
|
-
|
5730
|
-
|
5301
|
+
@class Image
|
5302
|
+
@constructor
|
5303
|
+
@extends EventTarget
|
5304
|
+
*/
|
5305
|
+
var dispatches = [
|
5306
|
+
'progress',
|
5731
5307
|
|
5732
|
-
|
5733
|
-
|
5734
|
-
self.shimExec.call(target, 'XMLHttpRequest', 'send', meta, data);
|
5735
|
-
}
|
5308
|
+
/**
|
5309
|
+
Dispatched when loading is complete.
|
5736
5310
|
|
5311
|
+
@event load
|
5312
|
+
@param {Object} event
|
5313
|
+
*/
|
5314
|
+
'load',
|
5737
5315
|
|
5738
|
-
|
5739
|
-
self.shimExec.call(target, 'XMLHttpRequest', 'appendBlob', name, blob.uid);
|
5740
|
-
data = null;
|
5741
|
-
send();
|
5742
|
-
}
|
5316
|
+
'error',
|
5743
5317
|
|
5318
|
+
/**
|
5319
|
+
Dispatched when resize operation is complete.
|
5320
|
+
|
5321
|
+
@event resize
|
5322
|
+
@param {Object} event
|
5323
|
+
*/
|
5324
|
+
'resize',
|
5744
5325
|
|
5745
|
-
|
5746
|
-
|
5326
|
+
/**
|
5327
|
+
Dispatched when visual representation of the image is successfully embedded
|
5328
|
+
into the corresponsing container.
|
5747
5329
|
|
5748
|
-
|
5749
|
-
|
5750
|
-
|
5330
|
+
@event embedded
|
5331
|
+
@param {Object} event
|
5332
|
+
*/
|
5333
|
+
'embedded'
|
5334
|
+
];
|
5751
5335
|
|
5752
|
-
|
5753
|
-
|
5754
|
-
});
|
5755
|
-
}
|
5336
|
+
function Image() {
|
5337
|
+
RuntimeClient.call(this);
|
5756
5338
|
|
5757
|
-
|
5758
|
-
|
5759
|
-
|
5760
|
-
self.shimExec.call(target, 'XMLHttpRequest', 'setRequestHeader', header, value.toString()); // Silverlight doesn't accept integers into the arguments of type object
|
5761
|
-
});
|
5762
|
-
}
|
5339
|
+
Basic.extend(this, {
|
5340
|
+
/**
|
5341
|
+
Unique id of the component
|
5763
5342
|
|
5764
|
-
|
5765
|
-
|
5766
|
-
|
5767
|
-
|
5768
|
-
|
5769
|
-
|
5770
|
-
|
5771
|
-
|
5772
|
-
|
5773
|
-
|
5343
|
+
@property uid
|
5344
|
+
@type {String}
|
5345
|
+
*/
|
5346
|
+
uid: Basic.guid('uid_'),
|
5347
|
+
|
5348
|
+
/**
|
5349
|
+
Unique id of the connected runtime, if any.
|
5350
|
+
|
5351
|
+
@property ruid
|
5352
|
+
@type {String}
|
5353
|
+
*/
|
5354
|
+
ruid: null,
|
5355
|
+
|
5356
|
+
/**
|
5357
|
+
Name of the file, that was used to create an image, if available. If not equals to empty string.
|
5358
|
+
|
5359
|
+
@property name
|
5360
|
+
@type {String}
|
5361
|
+
@default ""
|
5362
|
+
*/
|
5363
|
+
name: "",
|
5364
|
+
|
5365
|
+
/**
|
5366
|
+
Size of the image in bytes. Actual value is set only after image is preloaded.
|
5367
|
+
|
5368
|
+
@property size
|
5369
|
+
@type {Number}
|
5370
|
+
@default 0
|
5371
|
+
*/
|
5372
|
+
size: 0,
|
5373
|
+
|
5374
|
+
/**
|
5375
|
+
Width of the image. Actual value is set only after image is preloaded.
|
5376
|
+
|
5377
|
+
@property width
|
5378
|
+
@type {Number}
|
5379
|
+
@default 0
|
5380
|
+
*/
|
5381
|
+
width: 0,
|
5382
|
+
|
5383
|
+
/**
|
5384
|
+
Height of the image. Actual value is set only after image is preloaded.
|
5385
|
+
|
5386
|
+
@property height
|
5387
|
+
@type {Number}
|
5388
|
+
@default 0
|
5389
|
+
*/
|
5390
|
+
height: 0,
|
5391
|
+
|
5392
|
+
/**
|
5393
|
+
Mime type of the image. Currently only image/jpeg and image/png are supported. Actual value is set only after image is preloaded.
|
5394
|
+
|
5395
|
+
@property type
|
5396
|
+
@type {String}
|
5397
|
+
@default ""
|
5398
|
+
*/
|
5399
|
+
type: "",
|
5400
|
+
|
5401
|
+
/**
|
5402
|
+
Holds meta info (Exif, GPS). Is populated only for image/jpeg. Actual value is set only after image is preloaded.
|
5403
|
+
|
5404
|
+
@property meta
|
5405
|
+
@type {Object}
|
5406
|
+
@default {}
|
5407
|
+
*/
|
5408
|
+
meta: {},
|
5409
|
+
|
5410
|
+
/**
|
5411
|
+
Alias for load method, that takes another mOxie.Image object as a source (see load).
|
5412
|
+
|
5413
|
+
@method clone
|
5414
|
+
@param {Image} src Source for the image
|
5415
|
+
@param {Boolean} [exact=false] Whether to activate in-depth clone mode
|
5416
|
+
*/
|
5417
|
+
clone: function() {
|
5418
|
+
this.load.apply(this, arguments);
|
5419
|
+
},
|
5420
|
+
|
5421
|
+
/**
|
5422
|
+
Loads image from various sources. Currently the source for new image can be: mOxie.Image, mOxie.Blob/mOxie.File,
|
5423
|
+
native Blob/File, dataUrl or URL. Depending on the type of the source, arguments - differ. When source is URL,
|
5424
|
+
Image will be downloaded from remote destination and loaded in memory.
|
5425
|
+
|
5426
|
+
@example
|
5427
|
+
var img = new mOxie.Image();
|
5428
|
+
img.onload = function() {
|
5429
|
+
var blob = img.getAsBlob();
|
5430
|
+
|
5431
|
+
var formData = new mOxie.FormData();
|
5432
|
+
formData.append('file', blob);
|
5433
|
+
|
5434
|
+
var xhr = new mOxie.XMLHttpRequest();
|
5435
|
+
xhr.onload = function() {
|
5436
|
+
// upload complete
|
5437
|
+
};
|
5438
|
+
xhr.open('post', 'upload.php');
|
5439
|
+
xhr.send(formData);
|
5440
|
+
};
|
5441
|
+
img.load("http://www.moxiecode.com/images/mox-logo.jpg"); // notice file extension (.jpg)
|
5442
|
+
|
5443
|
+
|
5444
|
+
@method load
|
5445
|
+
@param {Image|Blob|File|String} src Source for the image
|
5446
|
+
@param {Boolean|Object} [mixed]
|
5447
|
+
*/
|
5448
|
+
load: function() {
|
5449
|
+
// this is here because to bind properly we need an uid first, which is created above
|
5450
|
+
this.bind('Load Resize', function() {
|
5451
|
+
_updateInfo.call(this);
|
5452
|
+
}, 999);
|
5453
|
+
|
5454
|
+
this.convertEventPropsToHandlers(dispatches);
|
5455
|
+
|
5456
|
+
_load.apply(this, arguments);
|
5457
|
+
},
|
5774
5458
|
|
5775
|
-
|
5776
|
-
|
5777
|
-
|
5459
|
+
/**
|
5460
|
+
Downsizes the image to fit the specified width/height. If crop is supplied, image will be cropped to exact dimensions.
|
5461
|
+
|
5462
|
+
@method downsize
|
5463
|
+
@param {Number} width Resulting width
|
5464
|
+
@param {Number} [height=width] Resulting height (optional, if not supplied will default to width)
|
5465
|
+
@param {Boolean} [crop=false] Whether to crop the image to exact dimensions
|
5466
|
+
@param {Boolean} [preserveHeaders=true] Whether to preserve meta headers (on JPEGs after resize)
|
5467
|
+
*/
|
5468
|
+
downsize: function(opts) {
|
5469
|
+
var defaults = {
|
5470
|
+
width: this.width,
|
5471
|
+
height: this.height,
|
5472
|
+
crop: false,
|
5473
|
+
preserveHeaders: true
|
5474
|
+
};
|
5475
|
+
|
5476
|
+
if (typeof(opts) === 'object') {
|
5477
|
+
opts = Basic.extend(defaults, opts);
|
5778
5478
|
} else {
|
5779
|
-
|
5780
|
-
|
5781
|
-
|
5782
|
-
|
5783
|
-
|
5784
|
-
|
5479
|
+
opts = Basic.extend(defaults, {
|
5480
|
+
width: arguments[0],
|
5481
|
+
height: arguments[1],
|
5482
|
+
crop: arguments[2],
|
5483
|
+
preserveHeaders: arguments[3]
|
5484
|
+
});
|
5485
|
+
}
|
5486
|
+
|
5487
|
+
try {
|
5488
|
+
if (!this.size) { // only preloaded image objects can be used as source
|
5489
|
+
throw new x.DOMException(x.DOMException.INVALID_STATE_ERR);
|
5490
|
+
}
|
5491
|
+
|
5492
|
+
// no way to reliably intercept the crash due to high resolution, so we simply avoid it
|
5493
|
+
if (this.width > Image.MAX_RESIZE_WIDTH || this.height > Image.MAX_RESIZE_HEIGHT) {
|
5494
|
+
throw new x.ImageError(x.ImageError.MAX_RESOLUTION_ERR);
|
5495
|
+
}
|
5496
|
+
|
5497
|
+
this.getRuntime().exec.call(this, 'Image', 'downsize', opts.width, opts.height, opts.crop, opts.preserveHeaders);
|
5498
|
+
} catch(ex) {
|
5499
|
+
// for now simply trigger error event
|
5500
|
+
this.trigger('error', ex.code);
|
5501
|
+
}
|
5502
|
+
},
|
5503
|
+
|
5504
|
+
/**
|
5505
|
+
Alias for downsize(width, height, true). (see downsize)
|
5506
|
+
|
5507
|
+
@method crop
|
5508
|
+
@param {Number} width Resulting width
|
5509
|
+
@param {Number} [height=width] Resulting height (optional, if not supplied will default to width)
|
5510
|
+
@param {Boolean} [preserveHeaders=true] Whether to preserve meta headers (on JPEGs after resize)
|
5511
|
+
*/
|
5512
|
+
crop: function(width, height, preserveHeaders) {
|
5513
|
+
this.downsize(width, height, true, preserveHeaders);
|
5514
|
+
},
|
5515
|
+
|
5516
|
+
getAsCanvas: function() {
|
5517
|
+
if (!Env.can('create_canvas')) {
|
5518
|
+
throw new x.RuntimeError(x.RuntimeError.NOT_SUPPORTED_ERR);
|
5519
|
+
}
|
5520
|
+
|
5521
|
+
var runtime = this.connectRuntime(this.ruid);
|
5522
|
+
return runtime.exec.call(this, 'Image', 'getAsCanvas');
|
5523
|
+
},
|
5524
|
+
|
5525
|
+
/**
|
5526
|
+
Retrieves image in it's current state as mOxie.Blob object. Cannot be run on empty or image in progress (throws
|
5527
|
+
DOMException.INVALID_STATE_ERR).
|
5528
|
+
|
5529
|
+
@method getAsBlob
|
5530
|
+
@param {String} [type="image/jpeg"] Mime type of resulting blob. Can either be image/jpeg or image/png
|
5531
|
+
@param {Number} [quality=90] Applicable only together with mime type image/jpeg
|
5532
|
+
@return {Blob} Image as Blob
|
5533
|
+
*/
|
5534
|
+
getAsBlob: function(type, quality) {
|
5535
|
+
if (!this.size) {
|
5536
|
+
throw new x.DOMException(x.DOMException.INVALID_STATE_ERR);
|
5537
|
+
}
|
5538
|
+
|
5539
|
+
if (!type) {
|
5540
|
+
type = 'image/jpeg';
|
5541
|
+
}
|
5542
|
+
|
5543
|
+
if (type === 'image/jpeg' && !quality) {
|
5544
|
+
quality = 90;
|
5545
|
+
}
|
5546
|
+
|
5547
|
+
return this.getRuntime().exec.call(this, 'Image', 'getAsBlob', type, quality);
|
5548
|
+
},
|
5549
|
+
|
5550
|
+
/**
|
5551
|
+
Retrieves image in it's current state as dataURL string. Cannot be run on empty or image in progress (throws
|
5552
|
+
DOMException.INVALID_STATE_ERR).
|
5553
|
+
|
5554
|
+
@method getAsDataURL
|
5555
|
+
@param {String} [type="image/jpeg"] Mime type of resulting blob. Can either be image/jpeg or image/png
|
5556
|
+
@param {Number} [quality=90] Applicable only together with mime type image/jpeg
|
5557
|
+
@return {String} Image as dataURL string
|
5558
|
+
*/
|
5559
|
+
getAsDataURL: function(type, quality) {
|
5560
|
+
if (!this.size) {
|
5561
|
+
throw new x.DOMException(x.DOMException.INVALID_STATE_ERR);
|
5562
|
+
}
|
5563
|
+
return this.getRuntime().exec.call(this, 'Image', 'getAsDataURL', type, quality);
|
5564
|
+
},
|
5565
|
+
|
5566
|
+
/**
|
5567
|
+
Retrieves image in it's current state as binary string. Cannot be run on empty or image in progress (throws
|
5568
|
+
DOMException.INVALID_STATE_ERR).
|
5569
|
+
|
5570
|
+
@method getAsBinaryString
|
5571
|
+
@param {String} [type="image/jpeg"] Mime type of resulting blob. Can either be image/jpeg or image/png
|
5572
|
+
@param {Number} [quality=90] Applicable only together with mime type image/jpeg
|
5573
|
+
@return {String} Image as binary string
|
5574
|
+
*/
|
5575
|
+
getAsBinaryString: function(type, quality) {
|
5576
|
+
var dataUrl = this.getAsDataURL(type, quality);
|
5577
|
+
return Encode.atob(dataUrl.substring(dataUrl.indexOf('base64,') + 7));
|
5578
|
+
},
|
5579
|
+
|
5580
|
+
/**
|
5581
|
+
Embeds a visual representation of the image into the specified node. Depending on the runtime,
|
5582
|
+
it might be a canvas, an img node or a thrid party shim object (Flash or SilverLight - very rare,
|
5583
|
+
can be used in legacy browsers that do not have canvas or proper dataURI support).
|
5584
|
+
|
5585
|
+
@method embed
|
5586
|
+
@param {DOMElement} el DOM element to insert the image object into
|
5587
|
+
@param {Object} [options]
|
5588
|
+
@param {Number} [options.width] The width of an embed (defaults to the image width)
|
5589
|
+
@param {Number} [options.height] The height of an embed (defaults to the image height)
|
5590
|
+
@param {String} [type="image/jpeg"] Mime type
|
5591
|
+
@param {Number} [quality=90] Quality of an embed, if mime type is image/jpeg
|
5592
|
+
@param {Boolean} [crop=false] Whether to crop an embed to the specified dimensions
|
5593
|
+
*/
|
5594
|
+
embed: function(el) {
|
5595
|
+
var self = this
|
5596
|
+
, imgCopy
|
5597
|
+
, type, quality, crop
|
5598
|
+
, options = arguments[1] || {}
|
5599
|
+
, width = this.width
|
5600
|
+
, height = this.height
|
5601
|
+
, runtime // this has to be outside of all the closures to contain proper runtime
|
5602
|
+
;
|
5603
|
+
|
5604
|
+
function onResize() {
|
5605
|
+
// if possible, embed a canvas element directly
|
5606
|
+
if (Env.can('create_canvas')) {
|
5607
|
+
var canvas = imgCopy.getAsCanvas();
|
5608
|
+
if (canvas) {
|
5609
|
+
el.appendChild(canvas);
|
5610
|
+
canvas = null;
|
5611
|
+
imgCopy.destroy();
|
5612
|
+
self.trigger('embedded');
|
5613
|
+
return;
|
5614
|
+
}
|
5615
|
+
}
|
5616
|
+
|
5617
|
+
var dataUrl = imgCopy.getAsDataURL(type, quality);
|
5618
|
+
if (!dataUrl) {
|
5619
|
+
throw new x.ImageError(x.ImageError.WRONG_FORMAT);
|
5620
|
+
}
|
5621
|
+
|
5622
|
+
if (Env.can('use_data_uri_of', dataUrl.length)) {
|
5623
|
+
el.innerHTML = '<img src="' + dataUrl + '" width="' + imgCopy.width + '" height="' + imgCopy.height + '" />';
|
5624
|
+
imgCopy.destroy();
|
5625
|
+
self.trigger('embedded');
|
5785
5626
|
} else {
|
5786
|
-
|
5627
|
+
var tr = new Transporter();
|
5628
|
+
|
5629
|
+
tr.bind("TransportingComplete", function() {
|
5630
|
+
runtime = self.connectRuntime(this.result.ruid);
|
5631
|
+
|
5632
|
+
self.bind("Embedded", function() {
|
5633
|
+
// position and size properly
|
5634
|
+
Basic.extend(runtime.getShimContainer().style, {
|
5635
|
+
//position: 'relative',
|
5636
|
+
top: '0px',
|
5637
|
+
left: '0px',
|
5638
|
+
width: imgCopy.width + 'px',
|
5639
|
+
height: imgCopy.height + 'px'
|
5640
|
+
});
|
5641
|
+
|
5642
|
+
// some shims (Flash/SilverLight) reinitialize, if parent element is hidden, reordered or it's
|
5643
|
+
// position type changes (in Gecko), but since we basically need this only in IEs 6/7 and
|
5644
|
+
// sometimes 8 and they do not have this problem, we can comment this for now
|
5645
|
+
/*tr.bind("RuntimeInit", function(e, runtime) {
|
5646
|
+
tr.destroy();
|
5647
|
+
runtime.destroy();
|
5648
|
+
onResize.call(self); // re-feed our image data
|
5649
|
+
});*/
|
5650
|
+
|
5651
|
+
runtime = null;
|
5652
|
+
}, 999);
|
5653
|
+
|
5654
|
+
runtime.exec.call(self, "ImageView", "display", this.result.uid, width, height);
|
5655
|
+
imgCopy.destroy();
|
5656
|
+
});
|
5657
|
+
|
5658
|
+
tr.transport(Encode.atob(dataUrl.substring(dataUrl.indexOf('base64,') + 7)), type, Basic.extend({}, options, {
|
5659
|
+
required_caps: {
|
5660
|
+
display_media: true
|
5661
|
+
},
|
5662
|
+
runtime_order: 'flash,silverlight',
|
5663
|
+
container: el
|
5664
|
+
}));
|
5787
5665
|
}
|
5788
5666
|
}
|
5789
|
-
|
5790
|
-
|
5791
|
-
|
5792
|
-
|
5793
|
-
|
5794
|
-
|
5667
|
+
|
5668
|
+
try {
|
5669
|
+
if (!(el = Dom.get(el))) {
|
5670
|
+
throw new x.DOMException(x.DOMException.INVALID_NODE_TYPE_ERR);
|
5671
|
+
}
|
5672
|
+
|
5673
|
+
if (!this.size) { // only preloaded image objects can be used as source
|
5674
|
+
throw new x.DOMException(x.DOMException.INVALID_STATE_ERR);
|
5675
|
+
}
|
5676
|
+
|
5677
|
+
if (this.width > Image.MAX_RESIZE_WIDTH || this.height > Image.MAX_RESIZE_HEIGHT) {
|
5678
|
+
throw new x.ImageError(x.ImageError.MAX_RESOLUTION_ERR);
|
5679
|
+
}
|
5680
|
+
|
5681
|
+
type = options.type || this.type || 'image/jpeg';
|
5682
|
+
quality = options.quality || 90;
|
5683
|
+
crop = Basic.typeOf(options.crop) !== 'undefined' ? options.crop : false;
|
5684
|
+
|
5685
|
+
// figure out dimensions for the thumb
|
5686
|
+
if (options.width) {
|
5687
|
+
width = options.width;
|
5688
|
+
height = options.height || width;
|
5689
|
+
} else {
|
5690
|
+
// if container element has measurable dimensions, use them
|
5691
|
+
var dimensions = Dom.getSize(el);
|
5692
|
+
if (dimensions.w && dimensions.h) { // both should be > 0
|
5693
|
+
width = dimensions.w;
|
5694
|
+
height = dimensions.h;
|
5695
|
+
}
|
5696
|
+
}
|
5697
|
+
|
5698
|
+
imgCopy = new Image();
|
5699
|
+
|
5700
|
+
imgCopy.bind("Resize", function() {
|
5701
|
+
onResize.call(self);
|
5795
5702
|
});
|
5796
|
-
|
5797
|
-
|
5798
|
-
|
5703
|
+
|
5704
|
+
imgCopy.bind("Load", function() {
|
5705
|
+
imgCopy.downsize(width, height, crop, false);
|
5706
|
+
});
|
5707
|
+
|
5708
|
+
imgCopy.clone(this, false);
|
5709
|
+
|
5710
|
+
return imgCopy;
|
5711
|
+
} catch(ex) {
|
5712
|
+
// for now simply trigger error event
|
5713
|
+
this.trigger('error', ex.code);
|
5799
5714
|
}
|
5800
|
-
}
|
5801
|
-
|
5715
|
+
},
|
5716
|
+
|
5717
|
+
/**
|
5718
|
+
Properly destroys the image and frees resources in use. If any. Recommended way to dispose mOxie.Image object.
|
5719
|
+
|
5720
|
+
@method destroy
|
5721
|
+
*/
|
5722
|
+
destroy: function() {
|
5723
|
+
if (this.ruid) {
|
5724
|
+
this.getRuntime().exec.call(this, 'Image', 'destroy');
|
5725
|
+
this.disconnectRuntime();
|
5726
|
+
}
|
5727
|
+
this.unbindAll();
|
5802
5728
|
}
|
5803
|
-
}
|
5729
|
+
});
|
5804
5730
|
|
5805
|
-
getResponse: function(responseType) {
|
5806
|
-
var frs, blob, self = this.getRuntime();
|
5807
5731
|
|
5808
|
-
|
5732
|
+
function _updateInfo(info) {
|
5733
|
+
if (!info) {
|
5734
|
+
info = this.getRuntime().exec.call(this, 'Image', 'getInfo');
|
5735
|
+
}
|
5809
5736
|
|
5810
|
-
|
5811
|
-
|
5737
|
+
this.size = info.size;
|
5738
|
+
this.width = info.width;
|
5739
|
+
this.height = info.height;
|
5740
|
+
this.type = info.type;
|
5741
|
+
this.meta = info.meta;
|
5812
5742
|
|
5813
|
-
|
5814
|
-
|
5815
|
-
|
5743
|
+
// update file name, only if empty
|
5744
|
+
if (this.name === '') {
|
5745
|
+
this.name = info.name;
|
5746
|
+
}
|
5747
|
+
}
|
5748
|
+
|
5816
5749
|
|
5817
|
-
|
5818
|
-
|
5750
|
+
function _load(src) {
|
5751
|
+
var srcType = Basic.typeOf(src);
|
5819
5752
|
|
5820
|
-
|
5821
|
-
|
5822
|
-
|
5823
|
-
|
5753
|
+
try {
|
5754
|
+
// if source is Image
|
5755
|
+
if (src instanceof Image) {
|
5756
|
+
if (!src.size) { // only preloaded image objects can be used as source
|
5757
|
+
throw new x.DOMException(x.DOMException.INVALID_STATE_ERR);
|
5758
|
+
}
|
5759
|
+
_loadFromImage.apply(this, arguments);
|
5760
|
+
}
|
5761
|
+
// if source is o.Blob/o.File
|
5762
|
+
else if (src instanceof Blob) {
|
5763
|
+
if (!~Basic.inArray(src.type, ['image/jpeg', 'image/png'])) {
|
5764
|
+
throw new x.ImageError(x.ImageError.WRONG_FORMAT);
|
5765
|
+
}
|
5766
|
+
_loadFromBlob.apply(this, arguments);
|
5767
|
+
}
|
5768
|
+
// if native blob/file
|
5769
|
+
else if (Basic.inArray(srcType, ['blob', 'file']) !== -1) {
|
5770
|
+
_load.call(this, new File(null, src), arguments[1]);
|
5771
|
+
}
|
5772
|
+
// if String
|
5773
|
+
else if (srcType === 'string') {
|
5774
|
+
// if dataUrl String
|
5775
|
+
if (/^data:[^;]*;base64,/.test(src)) {
|
5776
|
+
_load.call(this, new Blob(null, { data: src }), arguments[1]);
|
5777
|
+
}
|
5778
|
+
// else assume Url, either relative or absolute
|
5779
|
+
else {
|
5780
|
+
_loadFromUrl.apply(this, arguments);
|
5824
5781
|
}
|
5825
|
-
} finally {
|
5826
|
-
blob.destroy();
|
5827
5782
|
}
|
5783
|
+
// if source seems to be an img node
|
5784
|
+
else if (srcType === 'node' && src.nodeName.toLowerCase() === 'img') {
|
5785
|
+
_load.call(this, src.src, arguments[1]);
|
5786
|
+
}
|
5787
|
+
else {
|
5788
|
+
throw new x.DOMException(x.DOMException.TYPE_MISMATCH_ERR);
|
5789
|
+
}
|
5790
|
+
} catch(ex) {
|
5791
|
+
// for now simply trigger error event
|
5792
|
+
this.trigger('error', ex.code);
|
5828
5793
|
}
|
5829
|
-
|
5830
|
-
|
5794
|
+
}
|
5795
|
+
|
5796
|
+
|
5797
|
+
function _loadFromImage(img, exact) {
|
5798
|
+
var runtime = this.connectRuntime(img.ruid);
|
5799
|
+
this.ruid = runtime.uid;
|
5800
|
+
runtime.exec.call(this, 'Image', 'loadFromImage', img, (Basic.typeOf(exact) === 'undefined' ? true : exact));
|
5801
|
+
}
|
5802
|
+
|
5803
|
+
|
5804
|
+
function _loadFromBlob(blob, options) {
|
5805
|
+
var self = this;
|
5806
|
+
|
5807
|
+
self.name = blob.name || '';
|
5808
|
+
|
5809
|
+
function exec(runtime) {
|
5810
|
+
self.ruid = runtime.uid;
|
5811
|
+
runtime.exec.call(self, 'Image', 'loadFromBlob', blob);
|
5812
|
+
}
|
5813
|
+
|
5814
|
+
if (blob.isDetached()) {
|
5815
|
+
this.bind('RuntimeInit', function(e, runtime) {
|
5816
|
+
exec(runtime);
|
5817
|
+
});
|
5818
|
+
|
5819
|
+
// convert to object representation
|
5820
|
+
if (options && typeof(options.required_caps) === 'string') {
|
5821
|
+
options.required_caps = Runtime.parseCaps(options.required_caps);
|
5822
|
+
}
|
5831
5823
|
|
5832
|
-
|
5833
|
-
|
5824
|
+
this.connectRuntime(Basic.extend({
|
5825
|
+
required_caps: {
|
5826
|
+
access_image_binary: true,
|
5827
|
+
resize_image: true
|
5828
|
+
}
|
5829
|
+
}, options));
|
5830
|
+
} else {
|
5831
|
+
exec(this.connectRuntime(blob.ruid));
|
5832
|
+
}
|
5833
|
+
}
|
5834
|
+
|
5835
|
+
|
5836
|
+
function _loadFromUrl(url, options) {
|
5837
|
+
var self = this, xhr;
|
5838
|
+
|
5839
|
+
xhr = new XMLHttpRequest();
|
5834
5840
|
|
5835
|
-
|
5841
|
+
xhr.open('get', url);
|
5842
|
+
xhr.responseType = 'blob';
|
5843
|
+
|
5844
|
+
xhr.onprogress = function(e) {
|
5845
|
+
self.trigger(e);
|
5846
|
+
};
|
5847
|
+
|
5848
|
+
xhr.onload = function() {
|
5849
|
+
_loadFromBlob.call(self, xhr.response, true);
|
5850
|
+
};
|
5851
|
+
|
5852
|
+
xhr.onerror = function(e) {
|
5853
|
+
self.trigger(e);
|
5854
|
+
};
|
5855
|
+
|
5856
|
+
xhr.onloadend = function() {
|
5857
|
+
xhr.destroy();
|
5858
|
+
};
|
5836
5859
|
|
5837
|
-
|
5838
|
-
|
5839
|
-
|
5860
|
+
xhr.bind('RuntimeError', function(e, err) {
|
5861
|
+
self.trigger('RuntimeError', err);
|
5862
|
+
});
|
5840
5863
|
|
5841
|
-
|
5842
|
-
// this.dispatchEvent('uploadprogress');
|
5843
|
-
//}
|
5864
|
+
xhr.send(null, options);
|
5844
5865
|
}
|
5845
|
-
}
|
5866
|
+
}
|
5846
5867
|
|
5847
|
-
|
5868
|
+
// virtual world will crash on you if image has a resolution higher than this:
|
5869
|
+
Image.MAX_RESIZE_WIDTH = 6500;
|
5870
|
+
Image.MAX_RESIZE_HEIGHT = 6500;
|
5871
|
+
|
5872
|
+
Image.prototype = EventTarget.instance;
|
5873
|
+
|
5874
|
+
return Image;
|
5848
5875
|
});
|
5849
5876
|
|
5850
5877
|
// Included from: src/javascript/runtime/html4/Runtime.js
|
@@ -6836,10 +6863,10 @@ define("moxie/runtime/html4/xhr/XMLHttpRequest", [
|
|
6836
6863
|
return (extensions.XMLHttpRequest = XMLHttpRequest);
|
6837
6864
|
});
|
6838
6865
|
|
6839
|
-
// Included from: src/javascript/runtime/
|
6866
|
+
// Included from: src/javascript/runtime/html5/utils/BinaryReader.js
|
6840
6867
|
|
6841
6868
|
/**
|
6842
|
-
*
|
6869
|
+
* BinaryReader.js
|
6843
6870
|
*
|
6844
6871
|
* Copyright 2013, Moxiecode Systems AB
|
6845
6872
|
* Released under GPL License.
|
@@ -6848,318 +6875,1630 @@ define("moxie/runtime/html4/xhr/XMLHttpRequest", [
|
|
6848
6875
|
* Contributing: http://www.plupload.com/contributing
|
6849
6876
|
*/
|
6850
6877
|
|
6851
|
-
/*global ActiveXObject:true */
|
6852
|
-
|
6853
6878
|
/**
|
6854
|
-
|
6855
|
-
|
6856
|
-
@class moxie/runtime/silverlight/Runtime
|
6879
|
+
@class moxie/runtime/html5/utils/BinaryReader
|
6857
6880
|
@private
|
6858
6881
|
*/
|
6859
|
-
define("moxie/runtime/
|
6860
|
-
|
6861
|
-
|
6862
|
-
"moxie/core/utils/Dom",
|
6863
|
-
"moxie/core/Exceptions",
|
6864
|
-
"moxie/runtime/Runtime"
|
6865
|
-
], function(Basic, Env, Dom, x, Runtime) {
|
6866
|
-
|
6867
|
-
var type = "silverlight", extensions = {};
|
6882
|
+
define("moxie/runtime/html5/utils/BinaryReader", [], function() {
|
6883
|
+
return function() {
|
6884
|
+
var II = false, bin;
|
6868
6885
|
|
6869
|
-
|
6870
|
-
|
6871
|
-
|
6886
|
+
// Private functions
|
6887
|
+
function read(idx, size) {
|
6888
|
+
var mv = II ? 0 : -8 * (size - 1), sum = 0, i;
|
6872
6889
|
|
6873
|
-
|
6874
|
-
|
6875
|
-
|
6890
|
+
for (i = 0; i < size; i++) {
|
6891
|
+
sum |= (bin.charCodeAt(idx + i) << Math.abs(mv + i*8));
|
6892
|
+
}
|
6876
6893
|
|
6877
|
-
|
6878
|
-
|
6894
|
+
return sum;
|
6895
|
+
}
|
6896
|
+
|
6897
|
+
function putstr(segment, idx, length) {
|
6898
|
+
length = arguments.length === 3 ? length : bin.length - idx - 1;
|
6899
|
+
bin = bin.substr(0, idx) + segment + bin.substr(length + idx);
|
6900
|
+
}
|
6901
|
+
|
6902
|
+
function write(idx, num, size) {
|
6903
|
+
var str = '', mv = II ? 0 : -8 * (size - 1), i;
|
6904
|
+
|
6905
|
+
for (i = 0; i < size; i++) {
|
6906
|
+
str += String.fromCharCode((num >> Math.abs(mv + i*8)) & 255);
|
6907
|
+
}
|
6908
|
+
|
6909
|
+
putstr(str, idx, size);
|
6910
|
+
}
|
6911
|
+
|
6912
|
+
// Public functions
|
6913
|
+
return {
|
6914
|
+
II: function(order) {
|
6915
|
+
if (order === undefined) {
|
6916
|
+
return II;
|
6917
|
+
} else {
|
6918
|
+
II = order;
|
6919
|
+
}
|
6920
|
+
},
|
6921
|
+
|
6922
|
+
init: function(binData) {
|
6923
|
+
II = false;
|
6924
|
+
bin = binData;
|
6925
|
+
},
|
6926
|
+
|
6927
|
+
SEGMENT: function(idx, length, segment) {
|
6928
|
+
switch (arguments.length) {
|
6929
|
+
case 1:
|
6930
|
+
return bin.substr(idx, bin.length - idx - 1);
|
6931
|
+
case 2:
|
6932
|
+
return bin.substr(idx, length);
|
6933
|
+
case 3:
|
6934
|
+
putstr(segment, idx, length);
|
6935
|
+
break;
|
6936
|
+
default: return bin;
|
6937
|
+
}
|
6938
|
+
},
|
6939
|
+
|
6940
|
+
BYTE: function(idx) {
|
6941
|
+
return read(idx, 1);
|
6942
|
+
},
|
6943
|
+
|
6944
|
+
SHORT: function(idx) {
|
6945
|
+
return read(idx, 2);
|
6946
|
+
},
|
6947
|
+
|
6948
|
+
LONG: function(idx, num) {
|
6949
|
+
if (num === undefined) {
|
6950
|
+
return read(idx, 4);
|
6951
|
+
} else {
|
6952
|
+
write(idx, num, 4);
|
6953
|
+
}
|
6954
|
+
},
|
6955
|
+
|
6956
|
+
SLONG: function(idx) { // 2's complement notation
|
6957
|
+
var num = read(idx, 4);
|
6958
|
+
|
6959
|
+
return (num > 2147483647 ? num - 4294967296 : num);
|
6960
|
+
},
|
6961
|
+
|
6962
|
+
STRING: function(idx, size) {
|
6963
|
+
var str = '';
|
6964
|
+
|
6965
|
+
for (size += idx; idx < size; idx++) {
|
6966
|
+
str += String.fromCharCode(read(idx, 1));
|
6967
|
+
}
|
6968
|
+
|
6969
|
+
return str;
|
6970
|
+
}
|
6971
|
+
};
|
6972
|
+
};
|
6973
|
+
});
|
6974
|
+
|
6975
|
+
// Included from: src/javascript/runtime/html5/image/JPEGHeaders.js
|
6976
|
+
|
6977
|
+
/**
|
6978
|
+
* JPEGHeaders.js
|
6979
|
+
*
|
6980
|
+
* Copyright 2013, Moxiecode Systems AB
|
6981
|
+
* Released under GPL License.
|
6982
|
+
*
|
6983
|
+
* License: http://www.plupload.com/license
|
6984
|
+
* Contributing: http://www.plupload.com/contributing
|
6985
|
+
*/
|
6986
|
+
|
6987
|
+
/**
|
6988
|
+
@class moxie/runtime/html5/image/JPEGHeaders
|
6989
|
+
@private
|
6990
|
+
*/
|
6991
|
+
define("moxie/runtime/html5/image/JPEGHeaders", [
|
6992
|
+
"moxie/runtime/html5/utils/BinaryReader"
|
6993
|
+
], function(BinaryReader) {
|
6994
|
+
|
6995
|
+
return function JPEGHeaders(data) {
|
6996
|
+
var headers = [], read, idx, marker, length = 0;
|
6997
|
+
|
6998
|
+
read = new BinaryReader();
|
6999
|
+
read.init(data);
|
7000
|
+
|
7001
|
+
// Check if data is jpeg
|
7002
|
+
if (read.SHORT(0) !== 0xFFD8) {
|
7003
|
+
return;
|
7004
|
+
}
|
7005
|
+
|
7006
|
+
idx = 2;
|
7007
|
+
|
7008
|
+
while (idx <= data.length) {
|
7009
|
+
marker = read.SHORT(idx);
|
7010
|
+
|
7011
|
+
// omit RST (restart) markers
|
7012
|
+
if (marker >= 0xFFD0 && marker <= 0xFFD7) {
|
7013
|
+
idx += 2;
|
7014
|
+
continue;
|
7015
|
+
}
|
7016
|
+
|
7017
|
+
// no headers allowed after SOS marker
|
7018
|
+
if (marker === 0xFFDA || marker === 0xFFD9) {
|
7019
|
+
break;
|
7020
|
+
}
|
7021
|
+
|
7022
|
+
length = read.SHORT(idx + 2) + 2;
|
7023
|
+
|
7024
|
+
// APPn marker detected
|
7025
|
+
if (marker >= 0xFFE1 && marker <= 0xFFEF) {
|
7026
|
+
headers.push({
|
7027
|
+
hex: marker,
|
7028
|
+
name: 'APP' + (marker & 0x000F),
|
7029
|
+
start: idx,
|
7030
|
+
length: length,
|
7031
|
+
segment: read.SEGMENT(idx, length)
|
7032
|
+
});
|
7033
|
+
}
|
7034
|
+
|
7035
|
+
idx += length;
|
7036
|
+
}
|
7037
|
+
|
7038
|
+
read.init(null); // free memory
|
7039
|
+
|
7040
|
+
return {
|
7041
|
+
headers: headers,
|
7042
|
+
|
7043
|
+
restore: function(data) {
|
7044
|
+
var max, i;
|
7045
|
+
|
7046
|
+
read.init(data);
|
7047
|
+
|
7048
|
+
idx = read.SHORT(2) == 0xFFE0 ? 4 + read.SHORT(4) : 2;
|
7049
|
+
|
7050
|
+
for (i = 0, max = headers.length; i < max; i++) {
|
7051
|
+
read.SEGMENT(idx, 0, headers[i].segment);
|
7052
|
+
idx += headers[i].length;
|
7053
|
+
}
|
7054
|
+
|
7055
|
+
data = read.SEGMENT();
|
7056
|
+
read.init(null);
|
7057
|
+
return data;
|
7058
|
+
},
|
7059
|
+
|
7060
|
+
strip: function(data) {
|
7061
|
+
var headers, jpegHeaders, i;
|
7062
|
+
|
7063
|
+
jpegHeaders = new JPEGHeaders(data);
|
7064
|
+
headers = jpegHeaders.headers;
|
7065
|
+
jpegHeaders.purge();
|
7066
|
+
|
7067
|
+
read.init(data);
|
7068
|
+
|
7069
|
+
i = headers.length;
|
7070
|
+
while (i--) {
|
7071
|
+
read.SEGMENT(headers[i].start, headers[i].length, '');
|
7072
|
+
}
|
7073
|
+
|
7074
|
+
data = read.SEGMENT();
|
7075
|
+
read.init(null);
|
7076
|
+
return data;
|
7077
|
+
},
|
7078
|
+
|
7079
|
+
get: function(name) {
|
7080
|
+
var array = [];
|
7081
|
+
|
7082
|
+
for (var i = 0, max = headers.length; i < max; i++) {
|
7083
|
+
if (headers[i].name === name.toUpperCase()) {
|
7084
|
+
array.push(headers[i].segment);
|
7085
|
+
}
|
7086
|
+
}
|
7087
|
+
return array;
|
7088
|
+
},
|
7089
|
+
|
7090
|
+
set: function(name, segment) {
|
7091
|
+
var array = [], i, ii, max;
|
7092
|
+
|
7093
|
+
if (typeof(segment) === 'string') {
|
7094
|
+
array.push(segment);
|
7095
|
+
} else {
|
7096
|
+
array = segment;
|
7097
|
+
}
|
7098
|
+
|
7099
|
+
for (i = ii = 0, max = headers.length; i < max; i++) {
|
7100
|
+
if (headers[i].name === name.toUpperCase()) {
|
7101
|
+
headers[i].segment = array[ii];
|
7102
|
+
headers[i].length = array[ii].length;
|
7103
|
+
ii++;
|
7104
|
+
}
|
7105
|
+
if (ii >= array.length) {
|
7106
|
+
break;
|
7107
|
+
}
|
7108
|
+
}
|
7109
|
+
},
|
7110
|
+
|
7111
|
+
purge: function() {
|
7112
|
+
headers = [];
|
7113
|
+
read.init(null);
|
7114
|
+
read = null;
|
7115
|
+
}
|
7116
|
+
};
|
7117
|
+
};
|
7118
|
+
});
|
7119
|
+
|
7120
|
+
// Included from: src/javascript/runtime/html5/image/ExifParser.js
|
7121
|
+
|
7122
|
+
/**
|
7123
|
+
* ExifParser.js
|
7124
|
+
*
|
7125
|
+
* Copyright 2013, Moxiecode Systems AB
|
7126
|
+
* Released under GPL License.
|
7127
|
+
*
|
7128
|
+
* License: http://www.plupload.com/license
|
7129
|
+
* Contributing: http://www.plupload.com/contributing
|
7130
|
+
*/
|
7131
|
+
|
7132
|
+
/**
|
7133
|
+
@class moxie/runtime/html5/image/ExifParser
|
7134
|
+
@private
|
7135
|
+
*/
|
7136
|
+
define("moxie/runtime/html5/image/ExifParser", [
|
7137
|
+
"moxie/core/utils/Basic",
|
7138
|
+
"moxie/runtime/html5/utils/BinaryReader"
|
7139
|
+
], function(Basic, BinaryReader) {
|
7140
|
+
|
7141
|
+
return function ExifParser() {
|
7142
|
+
// Private ExifParser fields
|
7143
|
+
var data, tags, Tiff, offsets = {}, tagDescs;
|
7144
|
+
|
7145
|
+
data = new BinaryReader();
|
7146
|
+
|
7147
|
+
tags = {
|
7148
|
+
tiff : {
|
7149
|
+
/*
|
7150
|
+
The image orientation viewed in terms of rows and columns.
|
7151
|
+
|
7152
|
+
1 = The 0th row is at the visual top of the image, and the 0th column is the visual left-hand side.
|
7153
|
+
2 = The 0th row is at the visual top of the image, and the 0th column is the visual right-hand side.
|
7154
|
+
3 = The 0th row is at the visual bottom of the image, and the 0th column is the visual right-hand side.
|
7155
|
+
4 = The 0th row is at the visual bottom of the image, and the 0th column is the visual left-hand side.
|
7156
|
+
5 = The 0th row is the visual left-hand side of the image, and the 0th column is the visual top.
|
7157
|
+
6 = The 0th row is the visual right-hand side of the image, and the 0th column is the visual top.
|
7158
|
+
7 = The 0th row is the visual right-hand side of the image, and the 0th column is the visual bottom.
|
7159
|
+
8 = The 0th row is the visual left-hand side of the image, and the 0th column is the visual bottom.
|
7160
|
+
*/
|
7161
|
+
0x0112: 'Orientation',
|
7162
|
+
0x010E: 'ImageDescription',
|
7163
|
+
0x010F: 'Make',
|
7164
|
+
0x0110: 'Model',
|
7165
|
+
0x0131: 'Software',
|
7166
|
+
0x8769: 'ExifIFDPointer',
|
7167
|
+
0x8825: 'GPSInfoIFDPointer'
|
7168
|
+
},
|
7169
|
+
exif : {
|
7170
|
+
0x9000: 'ExifVersion',
|
7171
|
+
0xA001: 'ColorSpace',
|
7172
|
+
0xA002: 'PixelXDimension',
|
7173
|
+
0xA003: 'PixelYDimension',
|
7174
|
+
0x9003: 'DateTimeOriginal',
|
7175
|
+
0x829A: 'ExposureTime',
|
7176
|
+
0x829D: 'FNumber',
|
7177
|
+
0x8827: 'ISOSpeedRatings',
|
7178
|
+
0x9201: 'ShutterSpeedValue',
|
7179
|
+
0x9202: 'ApertureValue' ,
|
7180
|
+
0x9207: 'MeteringMode',
|
7181
|
+
0x9208: 'LightSource',
|
7182
|
+
0x9209: 'Flash',
|
7183
|
+
0x920A: 'FocalLength',
|
7184
|
+
0xA402: 'ExposureMode',
|
7185
|
+
0xA403: 'WhiteBalance',
|
7186
|
+
0xA406: 'SceneCaptureType',
|
7187
|
+
0xA404: 'DigitalZoomRatio',
|
7188
|
+
0xA408: 'Contrast',
|
7189
|
+
0xA409: 'Saturation',
|
7190
|
+
0xA40A: 'Sharpness'
|
7191
|
+
},
|
7192
|
+
gps : {
|
7193
|
+
0x0000: 'GPSVersionID',
|
7194
|
+
0x0001: 'GPSLatitudeRef',
|
7195
|
+
0x0002: 'GPSLatitude',
|
7196
|
+
0x0003: 'GPSLongitudeRef',
|
7197
|
+
0x0004: 'GPSLongitude'
|
7198
|
+
}
|
7199
|
+
};
|
7200
|
+
|
7201
|
+
tagDescs = {
|
7202
|
+
'ColorSpace': {
|
7203
|
+
1: 'sRGB',
|
7204
|
+
0: 'Uncalibrated'
|
7205
|
+
},
|
7206
|
+
|
7207
|
+
'MeteringMode': {
|
7208
|
+
0: 'Unknown',
|
7209
|
+
1: 'Average',
|
7210
|
+
2: 'CenterWeightedAverage',
|
7211
|
+
3: 'Spot',
|
7212
|
+
4: 'MultiSpot',
|
7213
|
+
5: 'Pattern',
|
7214
|
+
6: 'Partial',
|
7215
|
+
255: 'Other'
|
7216
|
+
},
|
7217
|
+
|
7218
|
+
'LightSource': {
|
7219
|
+
1: 'Daylight',
|
7220
|
+
2: 'Fliorescent',
|
7221
|
+
3: 'Tungsten',
|
7222
|
+
4: 'Flash',
|
7223
|
+
9: 'Fine weather',
|
7224
|
+
10: 'Cloudy weather',
|
7225
|
+
11: 'Shade',
|
7226
|
+
12: 'Daylight fluorescent (D 5700 - 7100K)',
|
7227
|
+
13: 'Day white fluorescent (N 4600 -5400K)',
|
7228
|
+
14: 'Cool white fluorescent (W 3900 - 4500K)',
|
7229
|
+
15: 'White fluorescent (WW 3200 - 3700K)',
|
7230
|
+
17: 'Standard light A',
|
7231
|
+
18: 'Standard light B',
|
7232
|
+
19: 'Standard light C',
|
7233
|
+
20: 'D55',
|
7234
|
+
21: 'D65',
|
7235
|
+
22: 'D75',
|
7236
|
+
23: 'D50',
|
7237
|
+
24: 'ISO studio tungsten',
|
7238
|
+
255: 'Other'
|
7239
|
+
},
|
7240
|
+
|
7241
|
+
'Flash': {
|
7242
|
+
0x0000: 'Flash did not fire.',
|
7243
|
+
0x0001: 'Flash fired.',
|
7244
|
+
0x0005: 'Strobe return light not detected.',
|
7245
|
+
0x0007: 'Strobe return light detected.',
|
7246
|
+
0x0009: 'Flash fired, compulsory flash mode',
|
7247
|
+
0x000D: 'Flash fired, compulsory flash mode, return light not detected',
|
7248
|
+
0x000F: 'Flash fired, compulsory flash mode, return light detected',
|
7249
|
+
0x0010: 'Flash did not fire, compulsory flash mode',
|
7250
|
+
0x0018: 'Flash did not fire, auto mode',
|
7251
|
+
0x0019: 'Flash fired, auto mode',
|
7252
|
+
0x001D: 'Flash fired, auto mode, return light not detected',
|
7253
|
+
0x001F: 'Flash fired, auto mode, return light detected',
|
7254
|
+
0x0020: 'No flash function',
|
7255
|
+
0x0041: 'Flash fired, red-eye reduction mode',
|
7256
|
+
0x0045: 'Flash fired, red-eye reduction mode, return light not detected',
|
7257
|
+
0x0047: 'Flash fired, red-eye reduction mode, return light detected',
|
7258
|
+
0x0049: 'Flash fired, compulsory flash mode, red-eye reduction mode',
|
7259
|
+
0x004D: 'Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected',
|
7260
|
+
0x004F: 'Flash fired, compulsory flash mode, red-eye reduction mode, return light detected',
|
7261
|
+
0x0059: 'Flash fired, auto mode, red-eye reduction mode',
|
7262
|
+
0x005D: 'Flash fired, auto mode, return light not detected, red-eye reduction mode',
|
7263
|
+
0x005F: 'Flash fired, auto mode, return light detected, red-eye reduction mode'
|
7264
|
+
},
|
7265
|
+
|
7266
|
+
'ExposureMode': {
|
7267
|
+
0: 'Auto exposure',
|
7268
|
+
1: 'Manual exposure',
|
7269
|
+
2: 'Auto bracket'
|
7270
|
+
},
|
7271
|
+
|
7272
|
+
'WhiteBalance': {
|
7273
|
+
0: 'Auto white balance',
|
7274
|
+
1: 'Manual white balance'
|
7275
|
+
},
|
7276
|
+
|
7277
|
+
'SceneCaptureType': {
|
7278
|
+
0: 'Standard',
|
7279
|
+
1: 'Landscape',
|
7280
|
+
2: 'Portrait',
|
7281
|
+
3: 'Night scene'
|
7282
|
+
},
|
7283
|
+
|
7284
|
+
'Contrast': {
|
7285
|
+
0: 'Normal',
|
7286
|
+
1: 'Soft',
|
7287
|
+
2: 'Hard'
|
7288
|
+
},
|
7289
|
+
|
7290
|
+
'Saturation': {
|
7291
|
+
0: 'Normal',
|
7292
|
+
1: 'Low saturation',
|
7293
|
+
2: 'High saturation'
|
7294
|
+
},
|
7295
|
+
|
7296
|
+
'Sharpness': {
|
7297
|
+
0: 'Normal',
|
7298
|
+
1: 'Soft',
|
7299
|
+
2: 'Hard'
|
7300
|
+
},
|
7301
|
+
|
7302
|
+
// GPS related
|
7303
|
+
'GPSLatitudeRef': {
|
7304
|
+
N: 'North latitude',
|
7305
|
+
S: 'South latitude'
|
7306
|
+
},
|
7307
|
+
|
7308
|
+
'GPSLongitudeRef': {
|
7309
|
+
E: 'East longitude',
|
7310
|
+
W: 'West longitude'
|
7311
|
+
}
|
7312
|
+
};
|
7313
|
+
|
7314
|
+
function extractTags(IFD_offset, tags2extract) {
|
7315
|
+
var length = data.SHORT(IFD_offset), i, ii,
|
7316
|
+
tag, type, count, tagOffset, offset, value, values = [], hash = {};
|
7317
|
+
|
7318
|
+
for (i = 0; i < length; i++) {
|
7319
|
+
// Set binary reader pointer to beginning of the next tag
|
7320
|
+
offset = tagOffset = IFD_offset + 12 * i + 2;
|
7321
|
+
|
7322
|
+
tag = tags2extract[data.SHORT(offset)];
|
7323
|
+
|
7324
|
+
if (tag === undefined) {
|
7325
|
+
continue; // Not the tag we requested
|
7326
|
+
}
|
7327
|
+
|
7328
|
+
type = data.SHORT(offset+=2);
|
7329
|
+
count = data.LONG(offset+=2);
|
7330
|
+
|
7331
|
+
offset += 4;
|
7332
|
+
values = [];
|
7333
|
+
|
7334
|
+
switch (type) {
|
7335
|
+
case 1: // BYTE
|
7336
|
+
case 7: // UNDEFINED
|
7337
|
+
if (count > 4) {
|
7338
|
+
offset = data.LONG(offset) + offsets.tiffHeader;
|
7339
|
+
}
|
7340
|
+
|
7341
|
+
for (ii = 0; ii < count; ii++) {
|
7342
|
+
values[ii] = data.BYTE(offset + ii);
|
7343
|
+
}
|
7344
|
+
|
7345
|
+
break;
|
7346
|
+
|
7347
|
+
case 2: // STRING
|
7348
|
+
if (count > 4) {
|
7349
|
+
offset = data.LONG(offset) + offsets.tiffHeader;
|
7350
|
+
}
|
7351
|
+
|
7352
|
+
hash[tag] = data.STRING(offset, count - 1);
|
7353
|
+
|
7354
|
+
continue;
|
7355
|
+
|
7356
|
+
case 3: // SHORT
|
7357
|
+
if (count > 2) {
|
7358
|
+
offset = data.LONG(offset) + offsets.tiffHeader;
|
7359
|
+
}
|
7360
|
+
|
7361
|
+
for (ii = 0; ii < count; ii++) {
|
7362
|
+
values[ii] = data.SHORT(offset + ii*2);
|
7363
|
+
}
|
7364
|
+
|
7365
|
+
break;
|
7366
|
+
|
7367
|
+
case 4: // LONG
|
7368
|
+
if (count > 1) {
|
7369
|
+
offset = data.LONG(offset) + offsets.tiffHeader;
|
7370
|
+
}
|
7371
|
+
|
7372
|
+
for (ii = 0; ii < count; ii++) {
|
7373
|
+
values[ii] = data.LONG(offset + ii*4);
|
7374
|
+
}
|
7375
|
+
|
7376
|
+
break;
|
7377
|
+
|
7378
|
+
case 5: // RATIONAL
|
7379
|
+
offset = data.LONG(offset) + offsets.tiffHeader;
|
7380
|
+
|
7381
|
+
for (ii = 0; ii < count; ii++) {
|
7382
|
+
values[ii] = data.LONG(offset + ii*4) / data.LONG(offset + ii*4 + 4);
|
7383
|
+
}
|
7384
|
+
|
7385
|
+
break;
|
7386
|
+
|
7387
|
+
case 9: // SLONG
|
7388
|
+
offset = data.LONG(offset) + offsets.tiffHeader;
|
7389
|
+
|
7390
|
+
for (ii = 0; ii < count; ii++) {
|
7391
|
+
values[ii] = data.SLONG(offset + ii*4);
|
7392
|
+
}
|
7393
|
+
|
7394
|
+
break;
|
7395
|
+
|
7396
|
+
case 10: // SRATIONAL
|
7397
|
+
offset = data.LONG(offset) + offsets.tiffHeader;
|
7398
|
+
|
7399
|
+
for (ii = 0; ii < count; ii++) {
|
7400
|
+
values[ii] = data.SLONG(offset + ii*4) / data.SLONG(offset + ii*4 + 4);
|
7401
|
+
}
|
7402
|
+
|
7403
|
+
break;
|
7404
|
+
|
7405
|
+
default:
|
7406
|
+
continue;
|
7407
|
+
}
|
7408
|
+
|
7409
|
+
value = (count == 1 ? values[0] : values);
|
7410
|
+
|
7411
|
+
if (tagDescs.hasOwnProperty(tag) && typeof value != 'object') {
|
7412
|
+
hash[tag] = tagDescs[tag][value];
|
7413
|
+
} else {
|
7414
|
+
hash[tag] = value;
|
7415
|
+
}
|
7416
|
+
}
|
7417
|
+
|
7418
|
+
return hash;
|
7419
|
+
}
|
7420
|
+
|
7421
|
+
function getIFDOffsets() {
|
7422
|
+
var idx = offsets.tiffHeader;
|
7423
|
+
|
7424
|
+
// Set read order of multi-byte data
|
7425
|
+
data.II(data.SHORT(idx) == 0x4949);
|
7426
|
+
|
7427
|
+
// Check if always present bytes are indeed present
|
7428
|
+
if (data.SHORT(idx+=2) !== 0x002A) {
|
7429
|
+
return false;
|
7430
|
+
}
|
7431
|
+
|
7432
|
+
offsets.IFD0 = offsets.tiffHeader + data.LONG(idx += 2);
|
7433
|
+
Tiff = extractTags(offsets.IFD0, tags.tiff);
|
7434
|
+
|
7435
|
+
if ('ExifIFDPointer' in Tiff) {
|
7436
|
+
offsets.exifIFD = offsets.tiffHeader + Tiff.ExifIFDPointer;
|
7437
|
+
delete Tiff.ExifIFDPointer;
|
7438
|
+
}
|
7439
|
+
|
7440
|
+
if ('GPSInfoIFDPointer' in Tiff) {
|
7441
|
+
offsets.gpsIFD = offsets.tiffHeader + Tiff.GPSInfoIFDPointer;
|
7442
|
+
delete Tiff.GPSInfoIFDPointer;
|
7443
|
+
}
|
7444
|
+
return true;
|
7445
|
+
}
|
7446
|
+
|
7447
|
+
// At the moment only setting of simple (LONG) values, that do not require offset recalculation, is supported
|
7448
|
+
function setTag(ifd, tag, value) {
|
7449
|
+
var offset, length, tagOffset, valueOffset = 0;
|
7450
|
+
|
7451
|
+
// If tag name passed translate into hex key
|
7452
|
+
if (typeof(tag) === 'string') {
|
7453
|
+
var tmpTags = tags[ifd.toLowerCase()];
|
7454
|
+
for (var hex in tmpTags) {
|
7455
|
+
if (tmpTags[hex] === tag) {
|
7456
|
+
tag = hex;
|
7457
|
+
break;
|
7458
|
+
}
|
7459
|
+
}
|
7460
|
+
}
|
7461
|
+
offset = offsets[ifd.toLowerCase() + 'IFD'];
|
7462
|
+
length = data.SHORT(offset);
|
7463
|
+
|
7464
|
+
for (var i = 0; i < length; i++) {
|
7465
|
+
tagOffset = offset + 12 * i + 2;
|
7466
|
+
|
7467
|
+
if (data.SHORT(tagOffset) == tag) {
|
7468
|
+
valueOffset = tagOffset + 8;
|
7469
|
+
break;
|
7470
|
+
}
|
7471
|
+
}
|
7472
|
+
|
7473
|
+
if (!valueOffset) {
|
7474
|
+
return false;
|
7475
|
+
}
|
7476
|
+
|
7477
|
+
data.LONG(valueOffset, value);
|
7478
|
+
return true;
|
7479
|
+
}
|
7480
|
+
|
7481
|
+
|
7482
|
+
// Public functions
|
7483
|
+
return {
|
7484
|
+
init: function(segment) {
|
7485
|
+
// Reset internal data
|
7486
|
+
offsets = {
|
7487
|
+
tiffHeader: 10
|
7488
|
+
};
|
7489
|
+
|
7490
|
+
if (segment === undefined || !segment.length) {
|
7491
|
+
return false;
|
7492
|
+
}
|
7493
|
+
|
7494
|
+
data.init(segment);
|
7495
|
+
|
7496
|
+
// Check if that's APP1 and that it has EXIF
|
7497
|
+
if (data.SHORT(0) === 0xFFE1 && data.STRING(4, 5).toUpperCase() === "EXIF\0") {
|
7498
|
+
return getIFDOffsets();
|
7499
|
+
}
|
7500
|
+
return false;
|
7501
|
+
},
|
7502
|
+
|
7503
|
+
TIFF: function() {
|
7504
|
+
return Tiff;
|
7505
|
+
},
|
7506
|
+
|
7507
|
+
EXIF: function() {
|
7508
|
+
var Exif;
|
7509
|
+
|
7510
|
+
// Populate EXIF hash
|
7511
|
+
Exif = extractTags(offsets.exifIFD, tags.exif);
|
7512
|
+
|
7513
|
+
// Fix formatting of some tags
|
7514
|
+
if (Exif.ExifVersion && Basic.typeOf(Exif.ExifVersion) === 'array') {
|
7515
|
+
for (var i = 0, exifVersion = ''; i < Exif.ExifVersion.length; i++) {
|
7516
|
+
exifVersion += String.fromCharCode(Exif.ExifVersion[i]);
|
7517
|
+
}
|
7518
|
+
Exif.ExifVersion = exifVersion;
|
7519
|
+
}
|
7520
|
+
|
7521
|
+
return Exif;
|
7522
|
+
},
|
7523
|
+
|
7524
|
+
GPS: function() {
|
7525
|
+
var GPS;
|
7526
|
+
|
7527
|
+
GPS = extractTags(offsets.gpsIFD, tags.gps);
|
7528
|
+
|
7529
|
+
// iOS devices (and probably some others) do not put in GPSVersionID tag (why?..)
|
7530
|
+
if (GPS.GPSVersionID && Basic.typeOf(GPS.GPSVersionID) === 'array') {
|
7531
|
+
GPS.GPSVersionID = GPS.GPSVersionID.join('.');
|
7532
|
+
}
|
7533
|
+
|
7534
|
+
return GPS;
|
7535
|
+
},
|
7536
|
+
|
7537
|
+
setExif: function(tag, value) {
|
7538
|
+
// Right now only setting of width/height is possible
|
7539
|
+
if (tag !== 'PixelXDimension' && tag !== 'PixelYDimension') {return false;}
|
7540
|
+
|
7541
|
+
return setTag('exif', tag, value);
|
7542
|
+
},
|
7543
|
+
|
7544
|
+
|
7545
|
+
getBinary: function() {
|
7546
|
+
return data.SEGMENT();
|
7547
|
+
},
|
7548
|
+
|
7549
|
+
purge: function() {
|
7550
|
+
data.init(null);
|
7551
|
+
data = Tiff = null;
|
7552
|
+
offsets = {};
|
7553
|
+
}
|
7554
|
+
};
|
7555
|
+
};
|
7556
|
+
});
|
7557
|
+
|
7558
|
+
// Included from: src/javascript/runtime/html5/image/JPEG.js
|
7559
|
+
|
7560
|
+
/**
|
7561
|
+
* JPEG.js
|
7562
|
+
*
|
7563
|
+
* Copyright 2013, Moxiecode Systems AB
|
7564
|
+
* Released under GPL License.
|
7565
|
+
*
|
7566
|
+
* License: http://www.plupload.com/license
|
7567
|
+
* Contributing: http://www.plupload.com/contributing
|
7568
|
+
*/
|
7569
|
+
|
7570
|
+
/**
|
7571
|
+
@class moxie/runtime/html5/image/JPEG
|
7572
|
+
@private
|
7573
|
+
*/
|
7574
|
+
define("moxie/runtime/html5/image/JPEG", [
|
7575
|
+
"moxie/core/utils/Basic",
|
7576
|
+
"moxie/core/Exceptions",
|
7577
|
+
"moxie/runtime/html5/image/JPEGHeaders",
|
7578
|
+
"moxie/runtime/html5/utils/BinaryReader",
|
7579
|
+
"moxie/runtime/html5/image/ExifParser"
|
7580
|
+
], function(Basic, x, JPEGHeaders, BinaryReader, ExifParser) {
|
7581
|
+
|
7582
|
+
function JPEG(binstr) {
|
7583
|
+
var _binstr, _br, _hm, _ep, _info, hasExif;
|
7584
|
+
|
7585
|
+
function _getDimensions() {
|
7586
|
+
var idx = 0, marker, length;
|
7587
|
+
|
7588
|
+
// examine all through the end, since some images might have very large APP segments
|
7589
|
+
while (idx <= _binstr.length) {
|
7590
|
+
marker = _br.SHORT(idx += 2);
|
7591
|
+
|
7592
|
+
if (marker >= 0xFFC0 && marker <= 0xFFC3) { // SOFn
|
7593
|
+
idx += 5; // marker (2 bytes) + length (2 bytes) + Sample precision (1 byte)
|
7594
|
+
return {
|
7595
|
+
height: _br.SHORT(idx),
|
7596
|
+
width: _br.SHORT(idx += 2)
|
7597
|
+
};
|
7598
|
+
}
|
7599
|
+
length = _br.SHORT(idx += 2);
|
7600
|
+
idx += length - 2;
|
7601
|
+
}
|
7602
|
+
return null;
|
7603
|
+
}
|
7604
|
+
|
7605
|
+
_binstr = binstr;
|
7606
|
+
|
7607
|
+
_br = new BinaryReader();
|
7608
|
+
_br.init(_binstr);
|
7609
|
+
|
7610
|
+
// check if it is jpeg
|
7611
|
+
if (_br.SHORT(0) !== 0xFFD8) {
|
7612
|
+
throw new x.ImageError(x.ImageError.WRONG_FORMAT);
|
7613
|
+
}
|
7614
|
+
|
7615
|
+
// backup headers
|
7616
|
+
_hm = new JPEGHeaders(binstr);
|
7617
|
+
|
7618
|
+
// extract exif info
|
7619
|
+
_ep = new ExifParser();
|
7620
|
+
hasExif = !!_ep.init(_hm.get('app1')[0]);
|
7621
|
+
|
7622
|
+
// get dimensions
|
7623
|
+
_info = _getDimensions.call(this);
|
7624
|
+
|
7625
|
+
Basic.extend(this, {
|
7626
|
+
type: 'image/jpeg',
|
7627
|
+
|
7628
|
+
size: _binstr.length,
|
7629
|
+
|
7630
|
+
width: _info && _info.width || 0,
|
7631
|
+
|
7632
|
+
height: _info && _info.height || 0,
|
7633
|
+
|
7634
|
+
setExif: function(tag, value) {
|
7635
|
+
if (!hasExif) {
|
7636
|
+
return false; // or throw an exception
|
7637
|
+
}
|
7638
|
+
|
7639
|
+
if (Basic.typeOf(tag) === 'object') {
|
7640
|
+
Basic.each(tag, function(value, tag) {
|
7641
|
+
_ep.setExif(tag, value);
|
7642
|
+
});
|
7643
|
+
} else {
|
7644
|
+
_ep.setExif(tag, value);
|
7645
|
+
}
|
7646
|
+
|
7647
|
+
// update internal headers
|
7648
|
+
_hm.set('app1', _ep.getBinary());
|
7649
|
+
},
|
7650
|
+
|
7651
|
+
writeHeaders: function() {
|
7652
|
+
if (!arguments.length) {
|
7653
|
+
// if no arguments passed, update headers internally
|
7654
|
+
return (_binstr = _hm.restore(_binstr));
|
7655
|
+
}
|
7656
|
+
return _hm.restore(arguments[0]);
|
7657
|
+
},
|
7658
|
+
|
7659
|
+
stripHeaders: function(binstr) {
|
7660
|
+
return _hm.strip(binstr);
|
7661
|
+
},
|
7662
|
+
|
7663
|
+
purge: function() {
|
7664
|
+
_purge.call(this);
|
7665
|
+
}
|
7666
|
+
});
|
7667
|
+
|
7668
|
+
if (hasExif) {
|
7669
|
+
this.meta = {
|
7670
|
+
tiff: _ep.TIFF(),
|
7671
|
+
exif: _ep.EXIF(),
|
7672
|
+
gps: _ep.GPS()
|
7673
|
+
};
|
7674
|
+
}
|
7675
|
+
|
7676
|
+
function _purge() {
|
7677
|
+
if (!_ep || !_hm || !_br) {
|
7678
|
+
return; // ignore any repeating purge requests
|
7679
|
+
}
|
7680
|
+
_ep.purge();
|
7681
|
+
_hm.purge();
|
7682
|
+
_br.init(null);
|
7683
|
+
_binstr = _info = _hm = _ep = _br = null;
|
7684
|
+
}
|
7685
|
+
}
|
7686
|
+
|
7687
|
+
return JPEG;
|
7688
|
+
});
|
7689
|
+
|
7690
|
+
// Included from: src/javascript/runtime/html5/image/PNG.js
|
7691
|
+
|
7692
|
+
/**
|
7693
|
+
* PNG.js
|
7694
|
+
*
|
7695
|
+
* Copyright 2013, Moxiecode Systems AB
|
7696
|
+
* Released under GPL License.
|
7697
|
+
*
|
7698
|
+
* License: http://www.plupload.com/license
|
7699
|
+
* Contributing: http://www.plupload.com/contributing
|
7700
|
+
*/
|
7701
|
+
|
7702
|
+
/**
|
7703
|
+
@class moxie/runtime/html5/image/PNG
|
7704
|
+
@private
|
7705
|
+
*/
|
7706
|
+
define("moxie/runtime/html5/image/PNG", [
|
7707
|
+
"moxie/core/Exceptions",
|
7708
|
+
"moxie/core/utils/Basic",
|
7709
|
+
"moxie/runtime/html5/utils/BinaryReader"
|
7710
|
+
], function(x, Basic, BinaryReader) {
|
7711
|
+
|
7712
|
+
function PNG(binstr) {
|
7713
|
+
var _binstr, _br, _hm, _ep, _info;
|
7714
|
+
|
7715
|
+
_binstr = binstr;
|
7716
|
+
|
7717
|
+
_br = new BinaryReader();
|
7718
|
+
_br.init(_binstr);
|
7719
|
+
|
7720
|
+
// check if it's png
|
7721
|
+
(function() {
|
7722
|
+
var idx = 0, i = 0
|
7723
|
+
, signature = [0x8950, 0x4E47, 0x0D0A, 0x1A0A]
|
7724
|
+
;
|
7725
|
+
|
7726
|
+
for (i = 0; i < signature.length; i++, idx += 2) {
|
7727
|
+
if (signature[i] != _br.SHORT(idx)) {
|
7728
|
+
throw new x.ImageError(x.ImageError.WRONG_FORMAT);
|
6879
7729
|
}
|
7730
|
+
}
|
7731
|
+
}());
|
7732
|
+
|
7733
|
+
function _getDimensions() {
|
7734
|
+
var chunk, idx;
|
7735
|
+
|
7736
|
+
chunk = _getChunkAt.call(this, 8);
|
6880
7737
|
|
6881
|
-
|
6882
|
-
|
6883
|
-
|
7738
|
+
if (chunk.type == 'IHDR') {
|
7739
|
+
idx = chunk.start;
|
7740
|
+
return {
|
7741
|
+
width: _br.LONG(idx),
|
7742
|
+
height: _br.LONG(idx += 4)
|
7743
|
+
};
|
7744
|
+
}
|
7745
|
+
return null;
|
7746
|
+
}
|
6884
7747
|
|
6885
|
-
|
6886
|
-
|
7748
|
+
function _purge() {
|
7749
|
+
if (!_br) {
|
7750
|
+
return; // ignore any repeating purge requests
|
7751
|
+
}
|
7752
|
+
_br.init(null);
|
7753
|
+
_binstr = _info = _hm = _ep = _br = null;
|
7754
|
+
}
|
6887
7755
|
|
6888
|
-
|
6889
|
-
actualVer = "2.0.30226.2";
|
6890
|
-
}
|
7756
|
+
_info = _getDimensions.call(this);
|
6891
7757
|
|
6892
|
-
|
7758
|
+
Basic.extend(this, {
|
7759
|
+
type: 'image/png',
|
6893
7760
|
|
6894
|
-
|
6895
|
-
actualVerArray.pop();
|
6896
|
-
}
|
7761
|
+
size: _binstr.length,
|
6897
7762
|
|
6898
|
-
|
6899
|
-
actualVerArray.push(0);
|
6900
|
-
}
|
7763
|
+
width: _info.width,
|
6901
7764
|
|
6902
|
-
|
7765
|
+
height: _info.height,
|
6903
7766
|
|
6904
|
-
|
6905
|
-
|
6906
|
-
|
7767
|
+
purge: function() {
|
7768
|
+
_purge.call(this);
|
7769
|
+
}
|
7770
|
+
});
|
6907
7771
|
|
6908
|
-
|
6909
|
-
|
6910
|
-
actualVersionPart = parseInt(actualVerArray[index], 10);
|
6911
|
-
index++;
|
6912
|
-
} while (index < reqVerArray.length && requiredVersionPart === actualVersionPart);
|
7772
|
+
// for PNG we can safely trigger purge automatically, as we do not keep any data for later
|
7773
|
+
_purge.call(this);
|
6913
7774
|
|
6914
|
-
|
6915
|
-
|
6916
|
-
|
7775
|
+
function _getChunkAt(idx) {
|
7776
|
+
var length, type, start, CRC;
|
7777
|
+
|
7778
|
+
length = _br.LONG(idx);
|
7779
|
+
type = _br.STRING(idx += 4, 4);
|
7780
|
+
start = idx += 4;
|
7781
|
+
CRC = _br.LONG(idx + length);
|
7782
|
+
|
7783
|
+
return {
|
7784
|
+
length: length,
|
7785
|
+
type: type,
|
7786
|
+
start: start,
|
7787
|
+
CRC: CRC
|
7788
|
+
};
|
7789
|
+
}
|
7790
|
+
}
|
7791
|
+
|
7792
|
+
return PNG;
|
7793
|
+
});
|
7794
|
+
|
7795
|
+
// Included from: src/javascript/runtime/html5/image/ImageInfo.js
|
7796
|
+
|
7797
|
+
/**
|
7798
|
+
* ImageInfo.js
|
7799
|
+
*
|
7800
|
+
* Copyright 2013, Moxiecode Systems AB
|
7801
|
+
* Released under GPL License.
|
7802
|
+
*
|
7803
|
+
* License: http://www.plupload.com/license
|
7804
|
+
* Contributing: http://www.plupload.com/contributing
|
7805
|
+
*/
|
7806
|
+
|
7807
|
+
/**
|
7808
|
+
@class moxie/runtime/html5/image/ImageInfo
|
7809
|
+
@private
|
7810
|
+
*/
|
7811
|
+
define("moxie/runtime/html5/image/ImageInfo", [
|
7812
|
+
"moxie/core/utils/Basic",
|
7813
|
+
"moxie/core/Exceptions",
|
7814
|
+
"moxie/runtime/html5/image/JPEG",
|
7815
|
+
"moxie/runtime/html5/image/PNG"
|
7816
|
+
], function(Basic, x, JPEG, PNG) {
|
7817
|
+
/**
|
7818
|
+
Optional image investigation tool for HTML5 runtime. Provides the following features:
|
7819
|
+
- ability to distinguish image type (JPEG or PNG) by signature
|
7820
|
+
- ability to extract image width/height directly from it's internals, without preloading in memory (fast)
|
7821
|
+
- ability to extract APP headers from JPEGs (Exif, GPS, etc)
|
7822
|
+
- ability to replace width/height tags in extracted JPEG headers
|
7823
|
+
- ability to restore APP headers, that were for example stripped during image manipulation
|
7824
|
+
|
7825
|
+
@class ImageInfo
|
7826
|
+
@constructor
|
7827
|
+
@param {String} binstr Image source as binary string
|
7828
|
+
*/
|
7829
|
+
return function(binstr) {
|
7830
|
+
var _cs = [JPEG, PNG], _img;
|
7831
|
+
|
7832
|
+
// figure out the format, throw: ImageError.WRONG_FORMAT if not supported
|
7833
|
+
_img = (function() {
|
7834
|
+
for (var i = 0; i < _cs.length; i++) {
|
7835
|
+
try {
|
7836
|
+
return new _cs[i](binstr);
|
7837
|
+
} catch (ex) {
|
7838
|
+
// console.info(ex);
|
6917
7839
|
}
|
6918
7840
|
}
|
6919
|
-
|
6920
|
-
|
7841
|
+
throw new x.ImageError(x.ImageError.WRONG_FORMAT);
|
7842
|
+
}());
|
7843
|
+
|
7844
|
+
Basic.extend(this, {
|
7845
|
+
/**
|
7846
|
+
Image Mime Type extracted from it's depths
|
7847
|
+
|
7848
|
+
@property type
|
7849
|
+
@type {String}
|
7850
|
+
@default ''
|
7851
|
+
*/
|
7852
|
+
type: '',
|
7853
|
+
|
7854
|
+
/**
|
7855
|
+
Image size in bytes
|
7856
|
+
|
7857
|
+
@property size
|
7858
|
+
@type {Number}
|
7859
|
+
@default 0
|
7860
|
+
*/
|
7861
|
+
size: 0,
|
7862
|
+
|
7863
|
+
/**
|
7864
|
+
Image width extracted from image source
|
7865
|
+
|
7866
|
+
@property width
|
7867
|
+
@type {Number}
|
7868
|
+
@default 0
|
7869
|
+
*/
|
7870
|
+
width: 0,
|
7871
|
+
|
7872
|
+
/**
|
7873
|
+
Image height extracted from image source
|
7874
|
+
|
7875
|
+
@property height
|
7876
|
+
@type {Number}
|
7877
|
+
@default 0
|
7878
|
+
*/
|
7879
|
+
height: 0,
|
7880
|
+
|
7881
|
+
/**
|
7882
|
+
Sets Exif tag. Currently applicable only for width and height tags. Obviously works only with JPEGs.
|
7883
|
+
|
7884
|
+
@method setExif
|
7885
|
+
@param {String} tag Tag to set
|
7886
|
+
@param {Mixed} value Value to assign to the tag
|
7887
|
+
*/
|
7888
|
+
setExif: function() {},
|
7889
|
+
|
7890
|
+
/**
|
7891
|
+
Restores headers to the source.
|
7892
|
+
|
7893
|
+
@method writeHeaders
|
7894
|
+
@param {String} data Image source as binary string
|
7895
|
+
@return {String} Updated binary string
|
7896
|
+
*/
|
7897
|
+
writeHeaders: function(data) {
|
7898
|
+
return data;
|
7899
|
+
},
|
7900
|
+
|
7901
|
+
/**
|
7902
|
+
Strip all headers from the source.
|
7903
|
+
|
7904
|
+
@method stripHeaders
|
7905
|
+
@param {String} data Image source as binary string
|
7906
|
+
@return {String} Updated binary string
|
7907
|
+
*/
|
7908
|
+
stripHeaders: function(data) {
|
7909
|
+
return data;
|
7910
|
+
},
|
7911
|
+
|
7912
|
+
/**
|
7913
|
+
Dispose resources.
|
7914
|
+
|
7915
|
+
@method purge
|
7916
|
+
*/
|
7917
|
+
purge: function() {}
|
7918
|
+
});
|
7919
|
+
|
7920
|
+
Basic.extend(this, _img);
|
7921
|
+
|
7922
|
+
this.purge = function() {
|
7923
|
+
_img.purge();
|
7924
|
+
_img = null;
|
7925
|
+
};
|
7926
|
+
};
|
7927
|
+
});
|
7928
|
+
|
7929
|
+
// Included from: src/javascript/runtime/html5/image/MegaPixel.js
|
7930
|
+
|
7931
|
+
/**
|
7932
|
+
(The MIT License)
|
7933
|
+
|
7934
|
+
Copyright (c) 2012 Shinichi Tomita <shinichi.tomita@gmail.com>;
|
7935
|
+
|
7936
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
7937
|
+
a copy of this software and associated documentation files (the
|
7938
|
+
'Software'), to deal in the Software without restriction, including
|
7939
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7940
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
7941
|
+
permit persons to whom the Software is furnished to do so, subject to
|
7942
|
+
the following conditions:
|
7943
|
+
|
7944
|
+
The above copyright notice and this permission notice shall be
|
7945
|
+
included in all copies or substantial portions of the Software.
|
7946
|
+
|
7947
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
7948
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
7949
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
7950
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
7951
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
7952
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
7953
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
7954
|
+
*/
|
7955
|
+
|
7956
|
+
/**
|
7957
|
+
* Mega pixel image rendering library for iOS6 Safari
|
7958
|
+
*
|
7959
|
+
* Fixes iOS6 Safari's image file rendering issue for large size image (over mega-pixel),
|
7960
|
+
* which causes unexpected subsampling when drawing it in canvas.
|
7961
|
+
* By using this library, you can safely render the image with proper stretching.
|
7962
|
+
*
|
7963
|
+
* Copyright (c) 2012 Shinichi Tomita <shinichi.tomita@gmail.com>
|
7964
|
+
* Released under the MIT license
|
7965
|
+
*/
|
7966
|
+
|
7967
|
+
/**
|
7968
|
+
@class moxie/runtime/html5/image/MegaPixel
|
7969
|
+
@private
|
7970
|
+
*/
|
7971
|
+
define("moxie/runtime/html5/image/MegaPixel", [], function() {
|
7972
|
+
|
7973
|
+
/**
|
7974
|
+
* Rendering image element (with resizing) into the canvas element
|
7975
|
+
*/
|
7976
|
+
function renderImageToCanvas(img, canvas, options) {
|
7977
|
+
var iw = img.naturalWidth, ih = img.naturalHeight;
|
7978
|
+
var width = options.width, height = options.height;
|
7979
|
+
var x = options.x || 0, y = options.y || 0;
|
7980
|
+
var ctx = canvas.getContext('2d');
|
7981
|
+
if (detectSubsampling(img)) {
|
7982
|
+
iw /= 2;
|
7983
|
+
ih /= 2;
|
7984
|
+
}
|
7985
|
+
var d = 1024; // size of tiling canvas
|
7986
|
+
var tmpCanvas = document.createElement('canvas');
|
7987
|
+
tmpCanvas.width = tmpCanvas.height = d;
|
7988
|
+
var tmpCtx = tmpCanvas.getContext('2d');
|
7989
|
+
var vertSquashRatio = detectVerticalSquash(img, iw, ih);
|
7990
|
+
var sy = 0;
|
7991
|
+
while (sy < ih) {
|
7992
|
+
var sh = sy + d > ih ? ih - sy : d;
|
7993
|
+
var sx = 0;
|
7994
|
+
while (sx < iw) {
|
7995
|
+
var sw = sx + d > iw ? iw - sx : d;
|
7996
|
+
tmpCtx.clearRect(0, 0, d, d);
|
7997
|
+
tmpCtx.drawImage(img, -sx, -sy);
|
7998
|
+
var dx = (sx * width / iw + x) << 0;
|
7999
|
+
var dw = Math.ceil(sw * width / iw);
|
8000
|
+
var dy = (sy * height / ih / vertSquashRatio + y) << 0;
|
8001
|
+
var dh = Math.ceil(sh * height / ih / vertSquashRatio);
|
8002
|
+
ctx.drawImage(tmpCanvas, 0, 0, sw, sh, dx, dy, dw, dh);
|
8003
|
+
sx += d;
|
8004
|
+
}
|
8005
|
+
sy += d;
|
6921
8006
|
}
|
8007
|
+
tmpCanvas = tmpCtx = null;
|
8008
|
+
}
|
6922
8009
|
|
6923
|
-
|
8010
|
+
/**
|
8011
|
+
* Detect subsampling in loaded image.
|
8012
|
+
* In iOS, larger images than 2M pixels may be subsampled in rendering.
|
8013
|
+
*/
|
8014
|
+
function detectSubsampling(img) {
|
8015
|
+
var iw = img.naturalWidth, ih = img.naturalHeight;
|
8016
|
+
if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image
|
8017
|
+
var canvas = document.createElement('canvas');
|
8018
|
+
canvas.width = canvas.height = 1;
|
8019
|
+
var ctx = canvas.getContext('2d');
|
8020
|
+
ctx.drawImage(img, -iw + 1, 0);
|
8021
|
+
// subsampled image becomes half smaller in rendering size.
|
8022
|
+
// check alpha channel value to confirm image is covering edge pixel or not.
|
8023
|
+
// if alpha value is 0 image is not covering, hence subsampled.
|
8024
|
+
return ctx.getImageData(0, 0, 1, 1).data[3] === 0;
|
8025
|
+
} else {
|
8026
|
+
return false;
|
8027
|
+
}
|
6924
8028
|
}
|
6925
8029
|
|
8030
|
+
|
6926
8031
|
/**
|
6927
|
-
|
8032
|
+
* Detecting vertical squash in loaded image.
|
8033
|
+
* Fixes a bug which squash image vertically while drawing into canvas for some images.
|
8034
|
+
*/
|
8035
|
+
function detectVerticalSquash(img, iw, ih) {
|
8036
|
+
var canvas = document.createElement('canvas');
|
8037
|
+
canvas.width = 1;
|
8038
|
+
canvas.height = ih;
|
8039
|
+
var ctx = canvas.getContext('2d');
|
8040
|
+
ctx.drawImage(img, 0, 0);
|
8041
|
+
var data = ctx.getImageData(0, 0, 1, ih).data;
|
8042
|
+
// search image edge pixel position in case it is squashed vertically.
|
8043
|
+
var sy = 0;
|
8044
|
+
var ey = ih;
|
8045
|
+
var py = ih;
|
8046
|
+
while (py > sy) {
|
8047
|
+
var alpha = data[(py - 1) * 4 + 3];
|
8048
|
+
if (alpha === 0) {
|
8049
|
+
ey = py;
|
8050
|
+
} else {
|
8051
|
+
sy = py;
|
8052
|
+
}
|
8053
|
+
py = (ey + sy) >> 1;
|
8054
|
+
}
|
8055
|
+
canvas = null;
|
8056
|
+
var ratio = (py / ih);
|
8057
|
+
return (ratio === 0) ? 1 : ratio;
|
8058
|
+
}
|
6928
8059
|
|
6929
|
-
|
6930
|
-
|
6931
|
-
|
6932
|
-
|
6933
|
-
|
8060
|
+
return {
|
8061
|
+
isSubsampled: detectSubsampling,
|
8062
|
+
renderTo: renderImageToCanvas
|
8063
|
+
};
|
8064
|
+
});
|
6934
8065
|
|
6935
|
-
|
8066
|
+
// Included from: src/javascript/runtime/html5/image/Image.js
|
6936
8067
|
|
6937
|
-
|
6938
|
-
|
6939
|
-
|
6940
|
-
|
6941
|
-
|
6942
|
-
|
6943
|
-
|
6944
|
-
|
6945
|
-
|
6946
|
-
|
6947
|
-
|
6948
|
-
|
6949
|
-
|
6950
|
-
|
8068
|
+
/**
|
8069
|
+
* Image.js
|
8070
|
+
*
|
8071
|
+
* Copyright 2013, Moxiecode Systems AB
|
8072
|
+
* Released under GPL License.
|
8073
|
+
*
|
8074
|
+
* License: http://www.plupload.com/license
|
8075
|
+
* Contributing: http://www.plupload.com/contributing
|
8076
|
+
*/
|
8077
|
+
|
8078
|
+
/**
|
8079
|
+
@class moxie/runtime/html5/image/Image
|
8080
|
+
@private
|
8081
|
+
*/
|
8082
|
+
define("moxie/runtime/html5/image/Image", [
|
8083
|
+
"moxie/runtime/html5/Runtime",
|
8084
|
+
"moxie/core/utils/Basic",
|
8085
|
+
"moxie/core/Exceptions",
|
8086
|
+
"moxie/core/utils/Encode",
|
8087
|
+
"moxie/file/File",
|
8088
|
+
"moxie/runtime/html5/image/ImageInfo",
|
8089
|
+
"moxie/runtime/html5/image/MegaPixel",
|
8090
|
+
"moxie/core/utils/Mime",
|
8091
|
+
"moxie/core/utils/Env"
|
8092
|
+
], function(extensions, Basic, x, Encode, File, ImageInfo, MegaPixel, Mime, Env) {
|
8093
|
+
|
8094
|
+
function HTML5Image() {
|
8095
|
+
var me = this
|
8096
|
+
, _img, _imgInfo, _canvas, _binStr, _blob
|
8097
|
+
, _modified = false // is set true whenever image is modified
|
8098
|
+
, _preserveHeaders = true
|
8099
|
+
;
|
8100
|
+
|
8101
|
+
Basic.extend(this, {
|
8102
|
+
loadFromBlob: function(blob) {
|
8103
|
+
var comp = this, I = comp.getRuntime()
|
8104
|
+
, asBinary = arguments.length > 1 ? arguments[1] : true
|
8105
|
+
;
|
8106
|
+
|
8107
|
+
if (!I.can('access_binary')) {
|
8108
|
+
throw new x.RuntimeError(x.RuntimeError.NOT_SUPPORTED_ERR);
|
8109
|
+
}
|
8110
|
+
|
8111
|
+
_blob = blob;
|
8112
|
+
|
8113
|
+
if (blob.isDetached()) {
|
8114
|
+
_binStr = blob.getSource();
|
8115
|
+
_preload.call(this, _binStr);
|
8116
|
+
return;
|
6951
8117
|
} else {
|
6952
|
-
|
8118
|
+
_readAsDataUrl.call(this, blob.getSource(), function(dataUrl) {
|
8119
|
+
if (asBinary) {
|
8120
|
+
_binStr = _toBinary(dataUrl);
|
8121
|
+
}
|
8122
|
+
_preload.call(comp, dataUrl);
|
8123
|
+
});
|
6953
8124
|
}
|
6954
8125
|
},
|
6955
|
-
|
6956
|
-
|
8126
|
+
|
8127
|
+
loadFromImage: function(img, exact) {
|
8128
|
+
this.meta = img.meta;
|
8129
|
+
|
8130
|
+
_blob = new File(null, {
|
8131
|
+
name: img.name,
|
8132
|
+
size: img.size,
|
8133
|
+
type: img.type
|
8134
|
+
});
|
8135
|
+
|
8136
|
+
_preload.call(this, exact ? (_binStr = img.getAsBinaryString()) : img.getAsDataURL());
|
6957
8137
|
},
|
6958
|
-
|
6959
|
-
|
6960
|
-
|
6961
|
-
|
6962
|
-
|
8138
|
+
|
8139
|
+
getInfo: function() {
|
8140
|
+
var I = this.getRuntime(), info;
|
8141
|
+
|
8142
|
+
if (!_imgInfo && _binStr && I.can('access_image_binary')) {
|
8143
|
+
_imgInfo = new ImageInfo(_binStr);
|
8144
|
+
}
|
8145
|
+
|
8146
|
+
info = {
|
8147
|
+
width: _getImg().width || 0,
|
8148
|
+
height: _getImg().height || 0,
|
8149
|
+
type: _blob.type || Mime.getFileMime(_blob.name),
|
8150
|
+
size: _binStr && _binStr.length || _blob.size || 0,
|
8151
|
+
name: _blob.name || '',
|
8152
|
+
meta: _imgInfo && _imgInfo.meta || this.meta || {}
|
8153
|
+
};
|
8154
|
+
|
8155
|
+
return info;
|
6963
8156
|
},
|
6964
|
-
|
6965
|
-
|
8157
|
+
|
8158
|
+
downsize: function() {
|
8159
|
+
_downsize.apply(this, arguments);
|
6966
8160
|
},
|
6967
|
-
|
6968
|
-
|
6969
|
-
|
6970
|
-
|
6971
|
-
|
6972
|
-
|
6973
|
-
return I.mode === 'client' || !Basic.arrayDiff(methods, ['GET', 'POST']);
|
6974
|
-
}
|
6975
|
-
}, {
|
6976
|
-
// capabilities that require specific mode
|
6977
|
-
return_response_headers: function(value) {
|
6978
|
-
return value ? 'client' : 'browser';
|
8161
|
+
|
8162
|
+
getAsCanvas: function() {
|
8163
|
+
if (_canvas) {
|
8164
|
+
_canvas.id = this.uid + '_canvas';
|
8165
|
+
}
|
8166
|
+
return _canvas;
|
6979
8167
|
},
|
6980
|
-
|
6981
|
-
|
8168
|
+
|
8169
|
+
getAsBlob: function(type, quality) {
|
8170
|
+
if (type !== this.type) {
|
8171
|
+
// if different mime type requested prepare image for conversion
|
8172
|
+
_downsize.call(this, this.width, this.height, false);
|
8173
|
+
}
|
8174
|
+
return new File(null, {
|
8175
|
+
name: _blob.name || '',
|
8176
|
+
type: type,
|
8177
|
+
data: me.getAsBinaryString.call(this, type, quality)
|
8178
|
+
});
|
6982
8179
|
},
|
6983
|
-
|
6984
|
-
|
8180
|
+
|
8181
|
+
getAsDataURL: function(type) {
|
8182
|
+
var quality = arguments[1] || 90;
|
8183
|
+
|
8184
|
+
// if image has not been modified, return the source right away
|
8185
|
+
if (!_modified) {
|
8186
|
+
return _img.src;
|
8187
|
+
}
|
8188
|
+
|
8189
|
+
if ('image/jpeg' !== type) {
|
8190
|
+
return _canvas.toDataURL('image/png');
|
8191
|
+
} else {
|
8192
|
+
try {
|
8193
|
+
// older Geckos used to result in an exception on quality argument
|
8194
|
+
return _canvas.toDataURL('image/jpeg', quality/100);
|
8195
|
+
} catch (ex) {
|
8196
|
+
return _canvas.toDataURL('image/jpeg');
|
8197
|
+
}
|
8198
|
+
}
|
6985
8199
|
},
|
6986
|
-
|
6987
|
-
|
8200
|
+
|
8201
|
+
getAsBinaryString: function(type, quality) {
|
8202
|
+
// if image has not been modified, return the source right away
|
8203
|
+
if (!_modified) {
|
8204
|
+
// if image was not loaded from binary string
|
8205
|
+
if (!_binStr) {
|
8206
|
+
_binStr = _toBinary(me.getAsDataURL(type, quality));
|
8207
|
+
}
|
8208
|
+
return _binStr;
|
8209
|
+
}
|
8210
|
+
|
8211
|
+
if ('image/jpeg' !== type) {
|
8212
|
+
_binStr = _toBinary(me.getAsDataURL(type, quality));
|
8213
|
+
} else {
|
8214
|
+
var dataUrl;
|
8215
|
+
|
8216
|
+
// if jpeg
|
8217
|
+
if (!quality) {
|
8218
|
+
quality = 90;
|
8219
|
+
}
|
8220
|
+
|
8221
|
+
try {
|
8222
|
+
// older Geckos used to result in an exception on quality argument
|
8223
|
+
dataUrl = _canvas.toDataURL('image/jpeg', quality/100);
|
8224
|
+
} catch (ex) {
|
8225
|
+
dataUrl = _canvas.toDataURL('image/jpeg');
|
8226
|
+
}
|
8227
|
+
|
8228
|
+
_binStr = _toBinary(dataUrl);
|
8229
|
+
|
8230
|
+
if (_imgInfo) {
|
8231
|
+
_binStr = _imgInfo.stripHeaders(_binStr);
|
8232
|
+
|
8233
|
+
if (_preserveHeaders) {
|
8234
|
+
// update dimensions info in exif
|
8235
|
+
if (_imgInfo.meta && _imgInfo.meta.exif) {
|
8236
|
+
_imgInfo.setExif({
|
8237
|
+
PixelXDimension: this.width,
|
8238
|
+
PixelYDimension: this.height
|
8239
|
+
});
|
8240
|
+
}
|
8241
|
+
|
8242
|
+
// re-inject the headers
|
8243
|
+
_binStr = _imgInfo.writeHeaders(_binStr);
|
8244
|
+
}
|
8245
|
+
|
8246
|
+
// will be re-created from fresh on next getInfo call
|
8247
|
+
_imgInfo.purge();
|
8248
|
+
_imgInfo = null;
|
8249
|
+
}
|
8250
|
+
}
|
8251
|
+
|
8252
|
+
_modified = false;
|
8253
|
+
|
8254
|
+
return _binStr;
|
6988
8255
|
},
|
6989
|
-
|
6990
|
-
|
8256
|
+
|
8257
|
+
destroy: function() {
|
8258
|
+
me = null;
|
8259
|
+
_purge.call(this);
|
8260
|
+
this.getRuntime().getShim().removeInstance(this.uid);
|
6991
8261
|
}
|
6992
8262
|
});
|
6993
8263
|
|
6994
8264
|
|
6995
|
-
|
6996
|
-
|
6997
|
-
|
8265
|
+
function _getImg() {
|
8266
|
+
if (!_canvas && !_img) {
|
8267
|
+
throw new x.ImageError(x.DOMException.INVALID_STATE_ERR);
|
8268
|
+
}
|
8269
|
+
return _canvas || _img;
|
6998
8270
|
}
|
6999
8271
|
|
7000
8272
|
|
7001
|
-
|
7002
|
-
|
7003
|
-
|
7004
|
-
},
|
8273
|
+
function _toBinary(str) {
|
8274
|
+
return Encode.atob(str.substring(str.indexOf('base64,') + 7));
|
8275
|
+
}
|
7005
8276
|
|
7006
|
-
shimExec: function(component, action) {
|
7007
|
-
var args = [].slice.call(arguments, 2);
|
7008
|
-
return I.getShim().exec(this.uid, component, action, args);
|
7009
|
-
},
|
7010
8277
|
|
7011
|
-
|
7012
|
-
|
7013
|
-
|
7014
|
-
|
7015
|
-
|
7016
|
-
|
7017
|
-
|
7018
|
-
|
7019
|
-
|
7020
|
-
|
7021
|
-
|
7022
|
-
'
|
7023
|
-
|
7024
|
-
|
7025
|
-
|
7026
|
-
|
7027
|
-
|
7028
|
-
|
7029
|
-
|
7030
|
-
|
8278
|
+
function _toDataUrl(str, type) {
|
8279
|
+
return 'data:' + (type || '') + ';base64,' + Encode.btoa(str);
|
8280
|
+
}
|
8281
|
+
|
8282
|
+
|
8283
|
+
function _preload(str) {
|
8284
|
+
var comp = this;
|
8285
|
+
|
8286
|
+
_img = new Image();
|
8287
|
+
_img.onerror = function() {
|
8288
|
+
_purge.call(this);
|
8289
|
+
comp.trigger('error', x.ImageError.WRONG_FORMAT);
|
8290
|
+
};
|
8291
|
+
_img.onload = function() {
|
8292
|
+
comp.trigger('load');
|
8293
|
+
};
|
8294
|
+
|
8295
|
+
_img.src = /^data:[^;]*;base64,/.test(str) ? str : _toDataUrl(str, _blob.type);
|
8296
|
+
}
|
8297
|
+
|
8298
|
+
|
8299
|
+
function _readAsDataUrl(file, callback) {
|
8300
|
+
var comp = this, fr;
|
8301
|
+
|
8302
|
+
// use FileReader if it's available
|
8303
|
+
if (window.FileReader) {
|
8304
|
+
fr = new FileReader();
|
8305
|
+
fr.onload = function() {
|
8306
|
+
callback(this.result);
|
8307
|
+
};
|
8308
|
+
fr.onerror = function() {
|
8309
|
+
comp.trigger('error', x.ImageError.WRONG_FORMAT);
|
8310
|
+
};
|
8311
|
+
fr.readAsDataURL(file);
|
8312
|
+
} else {
|
8313
|
+
return callback(file.getAsDataURL());
|
8314
|
+
}
|
8315
|
+
}
|
8316
|
+
|
8317
|
+
function _downsize(width, height, crop, preserveHeaders) {
|
8318
|
+
var self = this
|
8319
|
+
, scale
|
8320
|
+
, mathFn
|
8321
|
+
, x = 0
|
8322
|
+
, y = 0
|
8323
|
+
, img
|
8324
|
+
, destWidth
|
8325
|
+
, destHeight
|
8326
|
+
, orientation
|
8327
|
+
;
|
8328
|
+
|
8329
|
+
_preserveHeaders = preserveHeaders; // we will need to check this on export (see getAsBinaryString())
|
8330
|
+
|
8331
|
+
// take into account orientation tag
|
8332
|
+
orientation = (this.meta && this.meta.tiff && this.meta.tiff.Orientation) || 1;
|
8333
|
+
|
8334
|
+
if (Basic.inArray(orientation, [5,6,7,8]) !== -1) { // values that require 90 degree rotation
|
8335
|
+
// swap dimensions
|
8336
|
+
var tmp = width;
|
8337
|
+
width = height;
|
8338
|
+
height = tmp;
|
8339
|
+
}
|
8340
|
+
|
8341
|
+
img = _getImg();
|
8342
|
+
|
8343
|
+
// unify dimensions
|
8344
|
+
if (!crop) {
|
8345
|
+
scale = Math.min(width/img.width, height/img.height);
|
8346
|
+
} else {
|
8347
|
+
// one of the dimensions may exceed the actual image dimensions - we need to take the smallest value
|
8348
|
+
width = Math.min(width, img.width);
|
8349
|
+
height = Math.min(height, img.height);
|
7031
8350
|
|
7032
|
-
|
7033
|
-
|
7034
|
-
|
7035
|
-
|
7036
|
-
|
7037
|
-
|
7038
|
-
|
8351
|
+
scale = Math.max(width/img.width, height/img.height);
|
8352
|
+
}
|
8353
|
+
|
8354
|
+
// we only downsize here
|
8355
|
+
if (scale > 1 && !crop && preserveHeaders) {
|
8356
|
+
this.trigger('Resize');
|
8357
|
+
return;
|
8358
|
+
}
|
7039
8359
|
|
7040
|
-
|
7041
|
-
|
8360
|
+
// prepare canvas if necessary
|
8361
|
+
if (!_canvas) {
|
8362
|
+
_canvas = document.createElement("canvas");
|
8363
|
+
}
|
7042
8364
|
|
7043
|
-
|
8365
|
+
// calculate dimensions of proportionally resized image
|
8366
|
+
destWidth = Math.round(img.width * scale);
|
8367
|
+
destHeight = Math.round(img.height * scale);
|
7044
8368
|
|
7045
|
-
|
7046
|
-
|
8369
|
+
// scale image and canvas
|
8370
|
+
if (crop) {
|
8371
|
+
_canvas.width = width;
|
8372
|
+
_canvas.height = height;
|
7047
8373
|
|
7048
|
-
//
|
8374
|
+
// if dimensions of the resulting image still larger than canvas, center it
|
8375
|
+
if (destWidth > width) {
|
8376
|
+
x = Math.round((destWidth - width) / 2);
|
8377
|
+
}
|
7049
8378
|
|
7050
|
-
|
7051
|
-
|
7052
|
-
|
7053
|
-
|
7054
|
-
|
7055
|
-
|
7056
|
-
|
7057
|
-
* Contributing: http://www.plupload.com/contributing
|
7058
|
-
*/
|
8379
|
+
if (destHeight > height) {
|
8380
|
+
y = Math.round((destHeight - height) / 2);
|
8381
|
+
}
|
8382
|
+
} else {
|
8383
|
+
_canvas.width = destWidth;
|
8384
|
+
_canvas.height = destHeight;
|
8385
|
+
}
|
7059
8386
|
|
7060
|
-
|
7061
|
-
|
7062
|
-
|
7063
|
-
|
7064
|
-
define("moxie/runtime/silverlight/file/Blob", [
|
7065
|
-
"moxie/runtime/silverlight/Runtime",
|
7066
|
-
"moxie/core/utils/Basic",
|
7067
|
-
"moxie/runtime/flash/file/Blob"
|
7068
|
-
], function(extensions, Basic, Blob) {
|
7069
|
-
return (extensions.Blob = Basic.extend({}, Blob));
|
7070
|
-
});
|
8387
|
+
// rotate if required, according to orientation tag
|
8388
|
+
if (!_preserveHeaders) {
|
8389
|
+
_rotateToOrientaion(_canvas.width, _canvas.height, orientation);
|
8390
|
+
}
|
7071
8391
|
|
7072
|
-
|
8392
|
+
_drawToCanvas.call(this, img, _canvas, -x, -y, destWidth, destHeight);
|
7073
8393
|
|
7074
|
-
|
7075
|
-
|
7076
|
-
*
|
7077
|
-
* Copyright 2013, Moxiecode Systems AB
|
7078
|
-
* Released under GPL License.
|
7079
|
-
*
|
7080
|
-
* License: http://www.plupload.com/license
|
7081
|
-
* Contributing: http://www.plupload.com/contributing
|
7082
|
-
*/
|
8394
|
+
this.width = _canvas.width;
|
8395
|
+
this.height = _canvas.height;
|
7083
8396
|
|
7084
|
-
|
7085
|
-
|
7086
|
-
|
7087
|
-
*/
|
7088
|
-
define("moxie/runtime/silverlight/file/FileInput", [
|
7089
|
-
"moxie/runtime/silverlight/Runtime"
|
7090
|
-
], function(extensions) {
|
7091
|
-
|
7092
|
-
var FileInput = {
|
7093
|
-
init: function(options) {
|
8397
|
+
_modified = true;
|
8398
|
+
self.trigger('Resize');
|
8399
|
+
}
|
7094
8400
|
|
7095
|
-
|
7096
|
-
|
7097
|
-
|
7098
|
-
|
7099
|
-
}
|
7100
|
-
|
8401
|
+
|
8402
|
+
function _drawToCanvas(img, canvas, x, y, w, h) {
|
8403
|
+
if (Env.OS === 'iOS') {
|
8404
|
+
// avoid squish bug in iOS6
|
8405
|
+
MegaPixel.renderTo(img, canvas, { width: w, height: h, x: x, y: y });
|
8406
|
+
} else {
|
8407
|
+
var ctx = canvas.getContext('2d');
|
8408
|
+
ctx.drawImage(img, x, y, w, h);
|
7101
8409
|
}
|
7102
|
-
|
7103
|
-
this.getRuntime().shimExec.call(this, 'FileInput', 'init', toFilters(options.accept), options.name, options.multiple);
|
7104
|
-
this.trigger('ready');
|
7105
8410
|
}
|
7106
|
-
};
|
7107
8411
|
|
7108
|
-
return (extensions.FileInput = FileInput);
|
7109
|
-
});
|
7110
8412
|
|
7111
|
-
|
8413
|
+
/**
|
8414
|
+
* Transform canvas coordination according to specified frame size and orientation
|
8415
|
+
* Orientation value is from EXIF tag
|
8416
|
+
* @author Shinichi Tomita <shinichi.tomita@gmail.com>
|
8417
|
+
*/
|
8418
|
+
function _rotateToOrientaion(width, height, orientation) {
|
8419
|
+
switch (orientation) {
|
8420
|
+
case 5:
|
8421
|
+
case 6:
|
8422
|
+
case 7:
|
8423
|
+
case 8:
|
8424
|
+
_canvas.width = height;
|
8425
|
+
_canvas.height = width;
|
8426
|
+
break;
|
8427
|
+
default:
|
8428
|
+
_canvas.width = width;
|
8429
|
+
_canvas.height = height;
|
8430
|
+
}
|
7112
8431
|
|
7113
|
-
/**
|
7114
|
-
|
7115
|
-
|
7116
|
-
|
7117
|
-
|
7118
|
-
|
7119
|
-
|
7120
|
-
|
7121
|
-
|
8432
|
+
/**
|
8433
|
+
1 = The 0th row is at the visual top of the image, and the 0th column is the visual left-hand side.
|
8434
|
+
2 = The 0th row is at the visual top of the image, and the 0th column is the visual right-hand side.
|
8435
|
+
3 = The 0th row is at the visual bottom of the image, and the 0th column is the visual right-hand side.
|
8436
|
+
4 = The 0th row is at the visual bottom of the image, and the 0th column is the visual left-hand side.
|
8437
|
+
5 = The 0th row is the visual left-hand side of the image, and the 0th column is the visual top.
|
8438
|
+
6 = The 0th row is the visual right-hand side of the image, and the 0th column is the visual top.
|
8439
|
+
7 = The 0th row is the visual right-hand side of the image, and the 0th column is the visual bottom.
|
8440
|
+
8 = The 0th row is the visual left-hand side of the image, and the 0th column is the visual bottom.
|
8441
|
+
*/
|
7122
8442
|
|
7123
|
-
|
7124
|
-
|
7125
|
-
|
7126
|
-
|
7127
|
-
|
7128
|
-
|
7129
|
-
|
7130
|
-
|
7131
|
-
|
7132
|
-
|
7133
|
-
|
8443
|
+
var ctx = _canvas.getContext('2d');
|
8444
|
+
switch (orientation) {
|
8445
|
+
case 2:
|
8446
|
+
// horizontal flip
|
8447
|
+
ctx.translate(width, 0);
|
8448
|
+
ctx.scale(-1, 1);
|
8449
|
+
break;
|
8450
|
+
case 3:
|
8451
|
+
// 180 rotate left
|
8452
|
+
ctx.translate(width, height);
|
8453
|
+
ctx.rotate(Math.PI);
|
8454
|
+
break;
|
8455
|
+
case 4:
|
8456
|
+
// vertical flip
|
8457
|
+
ctx.translate(0, height);
|
8458
|
+
ctx.scale(1, -1);
|
8459
|
+
break;
|
8460
|
+
case 5:
|
8461
|
+
// vertical flip + 90 rotate right
|
8462
|
+
ctx.rotate(0.5 * Math.PI);
|
8463
|
+
ctx.scale(1, -1);
|
8464
|
+
break;
|
8465
|
+
case 6:
|
8466
|
+
// 90 rotate right
|
8467
|
+
ctx.rotate(0.5 * Math.PI);
|
8468
|
+
ctx.translate(0, -height);
|
8469
|
+
break;
|
8470
|
+
case 7:
|
8471
|
+
// horizontal flip + 90 rotate right
|
8472
|
+
ctx.rotate(0.5 * Math.PI);
|
8473
|
+
ctx.translate(width, -height);
|
8474
|
+
ctx.scale(-1, 1);
|
8475
|
+
break;
|
8476
|
+
case 8:
|
8477
|
+
// 90 rotate left
|
8478
|
+
ctx.rotate(-0.5 * Math.PI);
|
8479
|
+
ctx.translate(-width, 0);
|
8480
|
+
break;
|
8481
|
+
}
|
8482
|
+
}
|
7134
8483
|
|
7135
|
-
// Included from: src/javascript/runtime/silverlight/file/FileReaderSync.js
|
7136
8484
|
|
7137
|
-
|
7138
|
-
|
7139
|
-
|
7140
|
-
|
7141
|
-
|
7142
|
-
|
7143
|
-
|
7144
|
-
|
7145
|
-
|
8485
|
+
function _purge() {
|
8486
|
+
if (_imgInfo) {
|
8487
|
+
_imgInfo.purge();
|
8488
|
+
_imgInfo = null;
|
8489
|
+
}
|
8490
|
+
_binStr = _img = _canvas = _blob = null;
|
8491
|
+
_modified = false;
|
8492
|
+
}
|
8493
|
+
}
|
7146
8494
|
|
7147
|
-
|
7148
|
-
@class moxie/runtime/silverlight/file/FileReaderSync
|
7149
|
-
@private
|
7150
|
-
*/
|
7151
|
-
define("moxie/runtime/silverlight/file/FileReaderSync", [
|
7152
|
-
"moxie/runtime/silverlight/Runtime",
|
7153
|
-
"moxie/core/utils/Basic",
|
7154
|
-
"moxie/runtime/flash/file/FileReaderSync"
|
7155
|
-
], function(extensions, Basic, FileReaderSync) {
|
7156
|
-
return (extensions.FileReaderSync = Basic.extend({}, FileReaderSync));
|
8495
|
+
return (extensions.Image = HTML5Image);
|
7157
8496
|
});
|
7158
8497
|
|
7159
|
-
// Included from: src/javascript/runtime/
|
8498
|
+
// Included from: src/javascript/runtime/html4/image/Image.js
|
7160
8499
|
|
7161
8500
|
/**
|
7162
|
-
*
|
8501
|
+
* Image.js
|
7163
8502
|
*
|
7164
8503
|
* Copyright 2013, Moxiecode Systems AB
|
7165
8504
|
* Released under GPL License.
|
@@ -7169,18 +8508,17 @@ define("moxie/runtime/silverlight/file/FileReaderSync", [
|
|
7169
8508
|
*/
|
7170
8509
|
|
7171
8510
|
/**
|
7172
|
-
@class moxie/runtime/
|
8511
|
+
@class moxie/runtime/html4/image/Image
|
7173
8512
|
@private
|
7174
8513
|
*/
|
7175
|
-
define("moxie/runtime/
|
7176
|
-
"moxie/runtime/
|
7177
|
-
"moxie/
|
7178
|
-
|
7179
|
-
|
7180
|
-
return (extensions.XMLHttpRequest = Basic.extend({}, XMLHttpRequest));
|
8514
|
+
define("moxie/runtime/html4/image/Image", [
|
8515
|
+
"moxie/runtime/html4/Runtime",
|
8516
|
+
"moxie/runtime/html5/image/Image"
|
8517
|
+
], function(extensions, Image) {
|
8518
|
+
return (extensions.Image = Image);
|
7181
8519
|
});
|
7182
8520
|
|
7183
|
-
expose(["moxie/core/utils/Basic","moxie/core/I18n","moxie/core/utils/Mime","moxie/core/utils/Env","moxie/core/utils/Dom","moxie/core/Exceptions","moxie/core/EventTarget","moxie/core/utils/Encode","moxie/runtime/Runtime","moxie/runtime/RuntimeClient","moxie/file/Blob","moxie/file/File","moxie/file/FileInput","moxie/runtime/RuntimeTarget","moxie/file/FileReader","moxie/core/utils/Url","moxie/file/FileReaderSync","moxie/xhr/FormData","moxie/xhr/XMLHttpRequest","moxie/runtime/Transporter","moxie/core/utils/Events"]);
|
8521
|
+
expose(["moxie/core/utils/Basic","moxie/core/I18n","moxie/core/utils/Mime","moxie/core/utils/Env","moxie/core/utils/Dom","moxie/core/Exceptions","moxie/core/EventTarget","moxie/core/utils/Encode","moxie/runtime/Runtime","moxie/runtime/RuntimeClient","moxie/file/Blob","moxie/file/File","moxie/file/FileInput","moxie/runtime/RuntimeTarget","moxie/file/FileReader","moxie/core/utils/Url","moxie/file/FileReaderSync","moxie/xhr/FormData","moxie/xhr/XMLHttpRequest","moxie/runtime/Transporter","moxie/image/Image","moxie/core/utils/Events"]);
|
7184
8522
|
})(this);/**
|
7185
8523
|
* o.js
|
7186
8524
|
*
|
@@ -7231,477 +8569,3 @@ Globally exposed namespace with the most frequently used public classes and hand
|
|
7231
8569
|
}
|
7232
8570
|
return o;
|
7233
8571
|
})(this);
|
7234
|
-
;webshim.register('filereader', function($, webshim, window, document, undefined, featureOptions){
|
7235
|
-
"use strict";
|
7236
|
-
var mOxie, moxie, hasXDomain;
|
7237
|
-
var FormData = $.noop;
|
7238
|
-
var sel = 'input[type="file"].ws-filereader';
|
7239
|
-
var loadMoxie = function (){
|
7240
|
-
webshim.loader.loadList(['moxie']);
|
7241
|
-
};
|
7242
|
-
var _createFilePicker = function(){
|
7243
|
-
var $input, picker, $parent, onReset;
|
7244
|
-
var input = this;
|
7245
|
-
|
7246
|
-
if(webshim.implement(input, 'filepicker')){
|
7247
|
-
|
7248
|
-
input = this;
|
7249
|
-
$input = $(this);
|
7250
|
-
$parent = $input.parent();
|
7251
|
-
onReset = function(){
|
7252
|
-
if(!input.value){
|
7253
|
-
$input.prop('value', '');
|
7254
|
-
}
|
7255
|
-
};
|
7256
|
-
|
7257
|
-
$input.attr('tabindex', '-1').on('mousedown.filereaderwaiting click.filereaderwaiting', false);
|
7258
|
-
$parent.addClass('ws-loading');
|
7259
|
-
picker = new mOxie.FileInput({
|
7260
|
-
browse_button: this,
|
7261
|
-
accept: $.prop(this, 'accept'),
|
7262
|
-
multiple: $.prop(this, 'multiple')
|
7263
|
-
});
|
7264
|
-
|
7265
|
-
$input.jProp('form').on('reset', function(){
|
7266
|
-
setTimeout(onReset);
|
7267
|
-
});
|
7268
|
-
picker.onready = function(){
|
7269
|
-
$input.off('.fileraderwaiting');
|
7270
|
-
$parent.removeClass('ws-waiting');
|
7271
|
-
};
|
7272
|
-
|
7273
|
-
picker.onchange = function(e){
|
7274
|
-
webshim.data(input, 'fileList', e.target.files);
|
7275
|
-
$input.trigger('change');
|
7276
|
-
};
|
7277
|
-
picker.onmouseenter = function(){
|
7278
|
-
$input.trigger('mouseover');
|
7279
|
-
$parent.addClass('ws-mouseenter');
|
7280
|
-
};
|
7281
|
-
picker.onmouseleave = function(){
|
7282
|
-
$input.trigger('mouseout');
|
7283
|
-
$parent.removeClass('ws-mouseenter');
|
7284
|
-
};
|
7285
|
-
picker.onmousedown = function(){
|
7286
|
-
$input.trigger('mousedown');
|
7287
|
-
$parent.addClass('ws-active');
|
7288
|
-
};
|
7289
|
-
picker.onmouseup = function(){
|
7290
|
-
$input.trigger('mouseup');
|
7291
|
-
$parent.removeClass('ws-active');
|
7292
|
-
};
|
7293
|
-
|
7294
|
-
webshim.data(input, 'filePicker', picker);
|
7295
|
-
|
7296
|
-
webshim.ready('WINDOWLOAD', function(){
|
7297
|
-
var lastWidth;
|
7298
|
-
$input.onWSOff('updateshadowdom', function(){
|
7299
|
-
var curWitdth = input.offsetWidth;
|
7300
|
-
if(curWitdth && lastWidth != curWitdth){
|
7301
|
-
lastWidth = curWitdth;
|
7302
|
-
picker.refresh();
|
7303
|
-
}
|
7304
|
-
});
|
7305
|
-
});
|
7306
|
-
|
7307
|
-
webshim.addShadowDom();
|
7308
|
-
|
7309
|
-
picker.init();
|
7310
|
-
if(input.disabled){
|
7311
|
-
picker.disable(true);
|
7312
|
-
}
|
7313
|
-
}
|
7314
|
-
};
|
7315
|
-
var getFileNames = function(file){
|
7316
|
-
return file.name;
|
7317
|
-
};
|
7318
|
-
var createFilePicker = function(){
|
7319
|
-
var elem = this;
|
7320
|
-
loadMoxie();
|
7321
|
-
$(elem)
|
7322
|
-
.on('mousedown.filereaderwaiting click.filereaderwaiting', false)
|
7323
|
-
.parent()
|
7324
|
-
.addClass('ws-loading')
|
7325
|
-
;
|
7326
|
-
webshim.ready('moxie', function(){
|
7327
|
-
createFilePicker.call(elem);
|
7328
|
-
});
|
7329
|
-
};
|
7330
|
-
var noxhr = /^(?:script|jsonp)$/i;
|
7331
|
-
var notReadyYet = function(){
|
7332
|
-
loadMoxie();
|
7333
|
-
webshim.error('filereader/formdata not ready yet. please wait for moxie to load `webshim.ready("moxie", callbackFn);`` or wait for the first change event on input[type="file"].ws-filereader.')
|
7334
|
-
};
|
7335
|
-
var inputValueDesc = webshim.defineNodeNameProperty('input', 'value', {
|
7336
|
-
prop: {
|
7337
|
-
get: function(){
|
7338
|
-
var fileList = webshim.data(this, 'fileList');
|
7339
|
-
|
7340
|
-
if(fileList && fileList.map){
|
7341
|
-
return fileList.map(getFileNames).join(', ');
|
7342
|
-
}
|
7343
|
-
|
7344
|
-
return inputValueDesc.prop._supget.call(this);
|
7345
|
-
}
|
7346
|
-
}
|
7347
|
-
}
|
7348
|
-
);
|
7349
|
-
var shimMoxiePath = webshim.cfg.basePath+'moxie/';
|
7350
|
-
var crossXMLMessage = 'You nedd a crossdomain.xml to get all "filereader" / "XHR2" / "CORS" features to work. Or host moxie.swf/moxie.xap on your server an configure filereader options: "swfpath"/"xappath"';
|
7351
|
-
var testMoxie = function(options){
|
7352
|
-
return (options.wsType == 'moxie' || (options.data && options.data instanceof mOxie.FormData) || (options.crossDomain && $.support.cors !== false && hasXDomain != 'no' && !noxhr.test(options.dataType || '')));
|
7353
|
-
};
|
7354
|
-
var createMoxieTransport = function (options){
|
7355
|
-
|
7356
|
-
if(testMoxie(options)){
|
7357
|
-
var ajax;
|
7358
|
-
webshim.info('moxie transfer used for $.ajax');
|
7359
|
-
if(hasXDomain == 'no'){
|
7360
|
-
webshim.error(crossXMLMessage);
|
7361
|
-
}
|
7362
|
-
return {
|
7363
|
-
send: function( headers, completeCallback ) {
|
7364
|
-
|
7365
|
-
var proressEvent = function(obj, name){
|
7366
|
-
if(options[name]){
|
7367
|
-
var called = false;
|
7368
|
-
ajax.addEventListener('load', function(e){
|
7369
|
-
if(!called){
|
7370
|
-
options[name]({type: 'progress', lengthComputable: true, total: 1, loaded: 1});
|
7371
|
-
} else if(called.lengthComputable && called.total > called.loaded){
|
7372
|
-
options[name]({type: 'progress', lengthComputable: true, total: called.total, loaded: called.total});
|
7373
|
-
}
|
7374
|
-
});
|
7375
|
-
obj.addEventListener('progress', function(e){
|
7376
|
-
called = e;
|
7377
|
-
options[name](e);
|
7378
|
-
});
|
7379
|
-
}
|
7380
|
-
};
|
7381
|
-
ajax = new moxie.xhr.XMLHttpRequest();
|
7382
|
-
|
7383
|
-
ajax.open(options.type, options.url, options.async, options.username, options.password);
|
7384
|
-
|
7385
|
-
proressEvent(ajax.upload, featureOptions.uploadprogress);
|
7386
|
-
proressEvent(ajax.upload, featureOptions.progress);
|
7387
|
-
|
7388
|
-
ajax.addEventListener('load', function(e){
|
7389
|
-
var responses = {
|
7390
|
-
text: ajax.responseText,
|
7391
|
-
xml: ajax.responseXML
|
7392
|
-
};
|
7393
|
-
completeCallback(ajax.status, ajax.statusText, responses, ajax.getAllResponseHeaders());
|
7394
|
-
});
|
7395
|
-
|
7396
|
-
if(options.xhrFields && options.xhrFields.withCredentials){
|
7397
|
-
ajax.withCredentials = true;
|
7398
|
-
}
|
7399
|
-
|
7400
|
-
if(options.timeout){
|
7401
|
-
ajax.timeout = options.timeout;
|
7402
|
-
}
|
7403
|
-
|
7404
|
-
$.each(headers, function(name, value){
|
7405
|
-
ajax.setRequestHeader(name, value);
|
7406
|
-
});
|
7407
|
-
|
7408
|
-
|
7409
|
-
ajax.send(options.data);
|
7410
|
-
|
7411
|
-
},
|
7412
|
-
abort: function() {
|
7413
|
-
if(ajax){
|
7414
|
-
ajax.abort();
|
7415
|
-
}
|
7416
|
-
}
|
7417
|
-
};
|
7418
|
-
}
|
7419
|
-
};
|
7420
|
-
var transports = {
|
7421
|
-
//based on script: https://github.com/MoonScript/jQuery-ajaxTransport-XDomainRequest
|
7422
|
-
xdomain: (function(){
|
7423
|
-
var httpRegEx = /^https?:\/\//i;
|
7424
|
-
var getOrPostRegEx = /^get|post$/i;
|
7425
|
-
var sameSchemeRegEx = new RegExp('^'+location.protocol, 'i');
|
7426
|
-
return function(options, userOptions, jqXHR) {
|
7427
|
-
|
7428
|
-
// Only continue if the request is: asynchronous, uses GET or POST method, has HTTP or HTTPS protocol, and has the same scheme as the calling page
|
7429
|
-
if (!options.crossDomain || options.username || (options.xhrFields && options.xhrFields.withCredentials) || !options.async || !getOrPostRegEx.test(options.type) || !httpRegEx.test(options.url) || !sameSchemeRegEx.test(options.url) || (options.data && options.data instanceof mOxie.FormData) || noxhr.test(options.dataType || '')) {
|
7430
|
-
return;
|
7431
|
-
}
|
7432
|
-
|
7433
|
-
var xdr = null;
|
7434
|
-
webshim.info('xdomain transport used.');
|
7435
|
-
|
7436
|
-
return {
|
7437
|
-
send: function(headers, complete) {
|
7438
|
-
var postData = '';
|
7439
|
-
var userType = (userOptions.dataType || '').toLowerCase();
|
7440
|
-
|
7441
|
-
xdr = new XDomainRequest();
|
7442
|
-
if (/^\d+$/.test(userOptions.timeout)) {
|
7443
|
-
xdr.timeout = userOptions.timeout;
|
7444
|
-
}
|
7445
|
-
|
7446
|
-
xdr.ontimeout = function() {
|
7447
|
-
complete(500, 'timeout');
|
7448
|
-
};
|
7449
|
-
|
7450
|
-
xdr.onload = function() {
|
7451
|
-
var allResponseHeaders = 'Content-Length: ' + xdr.responseText.length + '\r\nContent-Type: ' + xdr.contentType;
|
7452
|
-
var status = {
|
7453
|
-
code: xdr.status || 200,
|
7454
|
-
message: xdr.statusText || 'OK'
|
7455
|
-
};
|
7456
|
-
var responses = {
|
7457
|
-
text: xdr.responseText,
|
7458
|
-
xml: xdr.responseXML
|
7459
|
-
};
|
7460
|
-
try {
|
7461
|
-
if (userType === 'html' || /text\/html/i.test(xdr.contentType)) {
|
7462
|
-
responses.html = xdr.responseText;
|
7463
|
-
} else if (userType === 'json' || (userType !== 'text' && /\/json/i.test(xdr.contentType))) {
|
7464
|
-
try {
|
7465
|
-
responses.json = $.parseJSON(xdr.responseText);
|
7466
|
-
} catch(e) {
|
7467
|
-
|
7468
|
-
}
|
7469
|
-
} else if (userType === 'xml' && !xdr.responseXML) {
|
7470
|
-
var doc;
|
7471
|
-
try {
|
7472
|
-
doc = new ActiveXObject('Microsoft.XMLDOM');
|
7473
|
-
doc.async = false;
|
7474
|
-
doc.loadXML(xdr.responseText);
|
7475
|
-
} catch(e) {
|
7476
|
-
|
7477
|
-
}
|
7478
|
-
|
7479
|
-
responses.xml = doc;
|
7480
|
-
}
|
7481
|
-
} catch(parseMessage) {}
|
7482
|
-
complete(status.code, status.message, responses, allResponseHeaders);
|
7483
|
-
};
|
7484
|
-
|
7485
|
-
// set an empty handler for 'onprogress' so requests don't get aborted
|
7486
|
-
xdr.onprogress = function(){};
|
7487
|
-
xdr.onerror = function() {
|
7488
|
-
complete(500, 'error', {
|
7489
|
-
text: xdr.responseText
|
7490
|
-
});
|
7491
|
-
};
|
7492
|
-
|
7493
|
-
if (userOptions.data) {
|
7494
|
-
postData = ($.type(userOptions.data) === 'string') ? userOptions.data : $.param(userOptions.data);
|
7495
|
-
}
|
7496
|
-
xdr.open(options.type, options.url);
|
7497
|
-
xdr.send(postData);
|
7498
|
-
},
|
7499
|
-
abort: function() {
|
7500
|
-
if (xdr) {
|
7501
|
-
xdr.abort();
|
7502
|
-
}
|
7503
|
-
}
|
7504
|
-
};
|
7505
|
-
};
|
7506
|
-
})(),
|
7507
|
-
moxie: function (options, originalOptions, jqXHR){
|
7508
|
-
if(testMoxie(options)){
|
7509
|
-
loadMoxie(options);
|
7510
|
-
var ajax;
|
7511
|
-
|
7512
|
-
var tmpTransport = {
|
7513
|
-
send: function( headers, completeCallback ) {
|
7514
|
-
ajax = true;
|
7515
|
-
webshim.ready('moxie', function(){
|
7516
|
-
if(ajax){
|
7517
|
-
ajax = createMoxieTransport(options, originalOptions, jqXHR);
|
7518
|
-
tmpTransport.send = ajax.send;
|
7519
|
-
tmpTransport.abort = ajax.abort;
|
7520
|
-
ajax.send(headers, completeCallback);
|
7521
|
-
}
|
7522
|
-
});
|
7523
|
-
},
|
7524
|
-
abort: function() {
|
7525
|
-
ajax = false;
|
7526
|
-
}
|
7527
|
-
};
|
7528
|
-
return tmpTransport;
|
7529
|
-
}
|
7530
|
-
}
|
7531
|
-
};
|
7532
|
-
|
7533
|
-
if(!featureOptions.progress){
|
7534
|
-
featureOptions.progress = 'onprogress';
|
7535
|
-
}
|
7536
|
-
|
7537
|
-
if(!featureOptions.uploadprogress){
|
7538
|
-
featureOptions.uploadprogress = 'onuploadprogress';
|
7539
|
-
}
|
7540
|
-
|
7541
|
-
if(!featureOptions.swfpath){
|
7542
|
-
featureOptions.swfpath = shimMoxiePath+'flash/Moxie.min.swf';
|
7543
|
-
}
|
7544
|
-
if(!featureOptions.xappath){
|
7545
|
-
featureOptions.xappath = shimMoxiePath+'silverlight/Moxie.min.xap';
|
7546
|
-
}
|
7547
|
-
|
7548
|
-
if($.support.cors !== false || !window.XDomainRequest){
|
7549
|
-
delete transports.xdomain;
|
7550
|
-
}
|
7551
|
-
|
7552
|
-
|
7553
|
-
$.ajaxTransport("+*", function( options, originalOptions, jqXHR ) {
|
7554
|
-
var ajax, type;
|
7555
|
-
|
7556
|
-
if(options.wsType || transports[transports]){
|
7557
|
-
ajax = transports[transports](options, originalOptions, jqXHR);
|
7558
|
-
}
|
7559
|
-
if(!ajax){
|
7560
|
-
for(type in transports){
|
7561
|
-
ajax = transports[type](options, originalOptions, jqXHR);
|
7562
|
-
if(ajax){break;}
|
7563
|
-
}
|
7564
|
-
}
|
7565
|
-
return ajax;
|
7566
|
-
});
|
7567
|
-
|
7568
|
-
webshim.defineNodeNameProperty('input', 'files', {
|
7569
|
-
prop: {
|
7570
|
-
writeable: false,
|
7571
|
-
get: function(){
|
7572
|
-
if(this.type != 'file'){return null;}
|
7573
|
-
if(!$(this).hasClass('ws-filereader')){
|
7574
|
-
webshim.info("please add the 'ws-filereader' class to your input[type='file'] to implement files-property");
|
7575
|
-
}
|
7576
|
-
return webshim.data(this, 'fileList') || [];
|
7577
|
-
}
|
7578
|
-
}
|
7579
|
-
}
|
7580
|
-
);
|
7581
|
-
|
7582
|
-
webshim.reflectProperties(['input'], ['accept']);
|
7583
|
-
|
7584
|
-
if($('<input />').prop('multiple') == null){
|
7585
|
-
webshim.defineNodeNamesBooleanProperty(['input'], ['multiple']);
|
7586
|
-
}
|
7587
|
-
|
7588
|
-
webshim.onNodeNamesPropertyModify('input', 'disabled', function(value, boolVal, type){
|
7589
|
-
var picker = webshim.data(this, 'filePicker');
|
7590
|
-
if(picker){
|
7591
|
-
picker.disable(boolVal);
|
7592
|
-
}
|
7593
|
-
});
|
7594
|
-
|
7595
|
-
webshim.onNodeNamesPropertyModify('input', 'value', function(value, boolVal, type){
|
7596
|
-
if(value === '' && this.type == 'file' && $(this).hasClass('ws-filereader')){
|
7597
|
-
webshim.data(this, 'fileList', []);
|
7598
|
-
}
|
7599
|
-
});
|
7600
|
-
|
7601
|
-
|
7602
|
-
window.FileReader = notReadyYet;
|
7603
|
-
window.FormData = notReadyYet;
|
7604
|
-
webshim.ready('moxie', function(){
|
7605
|
-
var wsMimes = 'application/xml,xml';
|
7606
|
-
moxie = window.moxie;
|
7607
|
-
mOxie = window.mOxie;
|
7608
|
-
|
7609
|
-
mOxie.Env.swf_url = featureOptions.swfpath;
|
7610
|
-
mOxie.Env.xap_url = featureOptions.xappath;
|
7611
|
-
|
7612
|
-
window.FileReader = mOxie.FileReader;
|
7613
|
-
|
7614
|
-
window.FormData = function(form){
|
7615
|
-
var appendData, i, len, files, fileI, fileLen, inputName;
|
7616
|
-
var moxieData = new mOxie.FormData();
|
7617
|
-
if(form && $.nodeName(form, 'form')){
|
7618
|
-
appendData = $(form).serializeArray();
|
7619
|
-
for(i = 0; i < appendData.length; i++){
|
7620
|
-
if(Array.isArray(appendData[i].value)){
|
7621
|
-
appendData[i].value.forEach(function(val){
|
7622
|
-
moxieData.append(appendData[i].name, val);
|
7623
|
-
});
|
7624
|
-
} else {
|
7625
|
-
moxieData.append(appendData[i].name, appendData[i].value);
|
7626
|
-
}
|
7627
|
-
}
|
7628
|
-
|
7629
|
-
appendData = form.querySelectorAll('input[type="file"][name]');
|
7630
|
-
|
7631
|
-
for(i = 0, len = appendData.length; i < appendData.length; i++){
|
7632
|
-
inputName = appendData[i].name;
|
7633
|
-
if(inputName && !$(appendData[i]).is(':disabled')){
|
7634
|
-
files = $.prop(appendData[i], 'files') || [];
|
7635
|
-
if(files.length){
|
7636
|
-
if(files.length > 1 || (moxieData.hasBlob && moxieData.hasBlob())){
|
7637
|
-
webshim.error('FormData shim can only handle one file per ajax. Use multiple ajax request. One per file.');
|
7638
|
-
}
|
7639
|
-
for(fileI = 0, fileLen = files.length; fileI < fileLen; fileI++){
|
7640
|
-
moxieData.append(inputName, files[fileI]);
|
7641
|
-
}
|
7642
|
-
}
|
7643
|
-
}
|
7644
|
-
}
|
7645
|
-
}
|
7646
|
-
|
7647
|
-
return moxieData;
|
7648
|
-
};
|
7649
|
-
FormData = window.FormData;
|
7650
|
-
|
7651
|
-
createFilePicker = _createFilePicker;
|
7652
|
-
transports.moxie = createMoxieTransport;
|
7653
|
-
|
7654
|
-
featureOptions.mimeTypes = (featureOptions.mimeTypes) ? wsMimes+','+featureOptions.mimeTypes : wsMimes;
|
7655
|
-
try {
|
7656
|
-
mOxie.Mime.addMimeType(featureOptions.mimeTypes);
|
7657
|
-
} catch(e){
|
7658
|
-
webshim.warn('mimetype to moxie error: '+e);
|
7659
|
-
}
|
7660
|
-
|
7661
|
-
});
|
7662
|
-
|
7663
|
-
webshim.addReady(function(context, contextElem){
|
7664
|
-
$(context.querySelectorAll(sel)).add(contextElem.filter(sel)).each(createFilePicker);
|
7665
|
-
});
|
7666
|
-
webshim.ready('WINDOWLOAD', loadMoxie);
|
7667
|
-
|
7668
|
-
if(webshim.cfg.debug !== false && featureOptions.swfpath.indexOf((location.protocol+'//'+location.hostname)) && featureOptions.swfpath.indexOf(('https://'+location.hostname))){
|
7669
|
-
webshim.ready('WINDOWLOAD', function(){
|
7670
|
-
|
7671
|
-
var printMessage = function(){
|
7672
|
-
if(hasXDomain == 'no'){
|
7673
|
-
webshim.error(crossXMLMessage);
|
7674
|
-
}
|
7675
|
-
};
|
7676
|
-
|
7677
|
-
try {
|
7678
|
-
hasXDomain = sessionStorage.getItem('wsXdomain.xml');
|
7679
|
-
} catch(e){}
|
7680
|
-
printMessage();
|
7681
|
-
if(hasXDomain == null){
|
7682
|
-
try {
|
7683
|
-
$.ajax({
|
7684
|
-
url: 'crossdomain.xml',
|
7685
|
-
type: 'HEAD',
|
7686
|
-
dataType: 'xml',
|
7687
|
-
success: function(){
|
7688
|
-
hasXDomain = 'yes';
|
7689
|
-
},
|
7690
|
-
error: function(){
|
7691
|
-
hasXDomain = 'no';
|
7692
|
-
},
|
7693
|
-
complete: function(){
|
7694
|
-
try {
|
7695
|
-
sessionStorage.setItem('wsXdomain.xml', hasXDomain);
|
7696
|
-
} catch(e){}
|
7697
|
-
printMessage();
|
7698
|
-
}
|
7699
|
-
});
|
7700
|
-
} catch(e){}
|
7701
|
-
}
|
7702
|
-
});
|
7703
|
-
}
|
7704
|
-
if(document.readyState == 'complete'){
|
7705
|
-
webshims.isReady('WINDOWLOAD', true);
|
7706
|
-
}
|
7707
|
-
});
|