%PDF- %PDF-
| Direktori : /home/bitrix/www/bitrix/js/main/core/core_uploader/ |
| Current File : //home/bitrix/www/bitrix/js/main/core/core_uploader/file.js |
;(function(window){
if (window.BX["UploaderFile"])
return false;
var getOrientation = (function(){
var exif = {
tags : {
// 0x0100 : "ImageWidth",
// 0x0101 : "ImageHeight",
// 0x8769 : "ExifIFDPointer",
// 0x8825 : "GPSInfoIFDPointer",
// 0xA005 : "InteroperabilityIFDPointer",
// 0x0102 : "BitsPerSample",
// 0x0103 : "Compression",
// 0x0106 : "PhotometricInterpretation",
0x0112 : "Orientation",
// 0x0115 : "SamplesPerPixel",
// 0x011C : "PlanarConfiguration",
// 0x0212 : "YCbCrSubSampling",
// 0x0213 : "YCbCrPositioning",
// 0x011A : "XResolution",
// 0x011B : "YResolution",
// 0x0128 : "ResolutionUnit",
// 0x0111 : "StripOffsets",
// 0x0116 : "RowsPerStrip",
// 0x0117 : "StripByteCounts",
// 0x0201 : "JPEGInterchangeFormat",
// 0x0202 : "JPEGInterchangeFormatLength",
// 0x012D : "TransferFunction",
// 0x013E : "WhitePoint",
// 0x013F : "PrimaryChromaticities",
// 0x0211 : "YCbCrCoefficients",
// 0x0214 : "ReferenceBlackWhite",
// 0x0132 : "DateTime",
// 0x010E : "ImageDescription",
// 0x010F : "Make",
// 0x0110 : "Model",
// 0x0131 : "Software",
// 0x013B : "Artist",
// 0x8298 : "Copyright"
},
getStringFromDB : function (buffer, start, length) {
var outstr = "", n;
for (n = start; n < start+length; n++) {
outstr += String.fromCharCode(buffer.getUint8(n));
}
return outstr;
},
readTags : function(file, tiffStart, dirStart, strings, bigEnd) {
var entries = file.getUint16(dirStart, !bigEnd),
tags = {},
entryOffset, tag,
i,
l = 0;
for (i in strings)
{
if (strings.hasOwnProperty(i))
l++;
}
for (i = 0; i < entries; i++)
{
entryOffset = dirStart + i*12 + 2;
tag = strings[file.getUint16(entryOffset, !bigEnd)];
tags[tag] = exif.readTagValue(file, entryOffset, tiffStart, dirStart, bigEnd);
l--;
if (l <= 0)
break;
}
return tags;
},
readTagValue : function(file, entryOffset, tiffStart, dirStart, bigEnd) {
var type = file.getUint16(entryOffset+2, !bigEnd),
numValues = file.getUint32(entryOffset+4, !bigEnd),
valueOffset = file.getUint32(entryOffset+8, !bigEnd) + tiffStart,
offset,
vals, val, n,
numerator, denominator;
switch (type)
{
case 1: // byte, 8-bit unsigned int
case 7: // undefined, 8-bit byte, value depending on field
if (numValues == 1) {
return file.getUint8(entryOffset + 8, !bigEnd);
} else {
offset = numValues > 4 ? valueOffset : (entryOffset + 8);
vals = [];
for (n=0;n<numValues;n++) {
vals[n] = file.getUint8(offset + n);
}
return vals;
}
case 2: // ascii, 8-bit byte
offset = numValues > 4 ? valueOffset : (entryOffset + 8);
return exif.getStringFromDB(file, offset, numValues-1);
case 3: // short, 16 bit int
if (numValues == 1) {
return file.getUint16(entryOffset + 8, !bigEnd);
} else {
offset = numValues > 2 ? valueOffset : (entryOffset + 8);
vals = [];
for (n=0;n<numValues;n++) {
vals[n] = file.getUint16(offset + 2*n, !bigEnd);
}
return vals;
}
case 4: // long, 32 bit int
if (numValues == 1) {
return file.getUint32(entryOffset + 8, !bigEnd);
} else {
vals = [];
for (n=0;n<numValues;n++) {
vals[n] = file.getUint32(valueOffset + 4*n, !bigEnd);
}
return vals;
}
case 5: // rational = two long values, first is numerator, second is denominator
if (numValues == 1) {
numerator = file.getUint32(valueOffset, !bigEnd);
denominator = file.getUint32(valueOffset+4, !bigEnd);
val = new Number(numerator / denominator);
val.numerator = numerator;
val.denominator = denominator;
return val;
} else {
vals = [];
for (n=0;n<numValues;n++) {
numerator = file.getUint32(valueOffset + 8*n, !bigEnd);
denominator = file.getUint32(valueOffset+4 + 8*n, !bigEnd);
vals[n] = new Number(numerator / denominator);
vals[n].numerator = numerator;
vals[n].denominator = denominator;
}
return vals;
}
case 9: // slong, 32 bit signed int
if (numValues == 1) {
return file.getInt32(entryOffset + 8, !bigEnd);
} else {
vals = [];
for (n=0;n<numValues;n++) {
vals[n] = file.getInt32(valueOffset + 4*n, !bigEnd);
}
return vals;
}
case 10: // signed rational, two slongs, first is numerator, second is denominator
if (numValues == 1) {
return file.getInt32(valueOffset, !bigEnd) / file.getInt32(valueOffset+4, !bigEnd);
} else {
vals = [];
for (n=0;n<numValues;n++) {
vals[n] = file.getInt32(valueOffset + 8*n, !bigEnd) / file.getInt32(valueOffset+4 + 8*n, !bigEnd);
}
return vals;
}
}
},
readData : function (file, start) {
if (exif.getStringFromDB(file, start, 4) != "Exif")
{
return false;
}
var bigEnd,
tiffOffset = start + 6;
// test for TIFF validity and endianness
if (file.getUint16(tiffOffset) == 0x4949)
{
bigEnd = false;
}
else if (file.getUint16(tiffOffset) == 0x4D4D)
{
bigEnd = true;
}
else
{
return false;
}
if (file.getUint16(tiffOffset+2, !bigEnd) != 0x002A)
{
return false;
}
var firstIFDOffset = file.getUint32(tiffOffset + 4, !bigEnd);
if (firstIFDOffset < 0x00000008)
{
return false;
}
return exif.readTags(file, tiffOffset, tiffOffset + firstIFDOffset, exif.tags, bigEnd);
},
readBase64 : function (base64)
{
base64 = base64.replace(/^data\:([^\;]+)\;base64,/gmi, '');
var binary_string = window.atob(base64), //decode base64
len = binary_string.length,
bytes = new Uint8Array(len);
for (var i = 0; i < len; i++) {
bytes[i] = binary_string.charCodeAt(i);
}
var dataView = new DataView(bytes.buffer);
if ((dataView.getUint8(0) != 0xFF) || (dataView.getUint8(1) != 0xD8))
{
return false; // not a valid jpeg
}
var offset = 2,
length = bytes.buffer.byteLength,
marker,
result = false;
while (offset < length)
{
if (dataView.getUint8(offset) != 0xFF) {
break; // not a valid marker, something is wrong
}
marker = dataView.getUint8(offset + 1);
// we could implement handling for other markers here,
// but we're only looking for 0xFFE1 for EXIF data
if (marker == 225)
{
result = exif.readData(dataView, offset + 4, dataView.getUint16(offset + 2) - 2);
break;
}
else
{
offset += 2 + dataView.getUint16(offset+2);
}
}
return result;
}
};
return function(base64){
if (BX.type.isString(base64))
{
try {
var tags = exif.readBase64(base64);
if(tags && tags["Orientation"])
return tags["Orientation"];
}
catch (e)
{
}
}
return false;
};
})(),
setOrientation = function(image, cnv, ctx, exifOrientation) {
var width = image.width,
height = image.height;
if ([5,6,7,8].indexOf(exifOrientation) >= 0)
{
width = image.height;
height = image.width;
}
BX.adjust(cnv, {props: {width: width, height: height}});
ctx.save();
switch(exifOrientation) {
case 2:
// $img.addClass('flip');
ctx.scale(-1, 1);
ctx.translate(-cnv.width, 0);
break;
case 3:
// $img.addClass('rotate-180');
ctx.translate(cnv.width, cnv.height);
ctx.rotate(Math.PI);
break;
case 4:
// $img.addClass('flip-and-rotate-180');
ctx.scale(-1, 1);
ctx.translate(0, cnv.height);
ctx.rotate(Math.PI);
break;
case 5:
// $img.addClass('flip-and-rotate-90');
ctx.scale(-1, 1);
ctx.translate(0, 0);
ctx.rotate(Math.PI / 2);
break;
case 6:
// $img.addClass('rotate-90');
ctx.translate(cnv.width, 0);
ctx.rotate(Math.PI / 2);
break;
case 7:
// $img.addClass('flip-and-rotate-90');
ctx.scale(-1, 1);
ctx.translate(-cnv.width, cnv.height);
ctx.rotate(Math.PI * 3 / 2);
break;
case 8:
// $img.addClass('rotate-270');
ctx.translate(0, cnv.height);
ctx.rotate(Math.PI * 3 / 2);
break;
}
ctx.drawImage(image, 0, 0);
ctx.restore();
};
var BX = window.BX,
statuses = { "new" : 0, ready : 1, preparing : 2, inprogress : 3, done : 4, failed : 5, stopped : 6, changed : 7, uploaded : 8},
cnvConstr = (function(){
var cnvConstructor = function(timelimit) {
this.timeLimit = (typeof timelimit === "number" && timelimit > 0 ? timelimit : 50);
this.status = statuses.ready;
this.queue = new BX.UploaderUtils.Hash();
this.id = (new Date()).getTime();
};
cnvConstructor.prototype = {
counter : 0,
active : null,
image : null,
getImage : function() {
if (!this.image)
this.image = new Image();
return this.image;
},
canvas : null,
getCanvas : function() {
if (!this.canvas)
{
this.canvas = BX.create('CANVAS', {style : {display: "none"}});
document.body.appendChild(this.canvas);
}
return this.canvas;
},
context : null,
getContext : function() {
if (!this.context && this.getCanvas()["getContext"])
this.context = this.getCanvas().getContext('2d');
return this.context;
},
reader : null,
getReader : function() {
if (!this.reader && window["FileReader"])
this.reader = new FileReader();
return this.reader;
},
load : function(file, callback, id, callbackFail) {
if (this.active !== null || (this.getReader() && this.getReader().readyState == 1))
return;
this.counter++;
this.active = file;
var image = this.getImage();
BX.unbindAll(image);
image.onload = function(){};
image.onerror = function(){};
/* Almost all browsers cache images from local resource except of FF on 06.03.2017. It appears that
FF collect src and does not abort image uploading when src is changed. And we had a bug when in
onload event we got e.target.src of one element but source of image was from '/bitrix/images/1.gif'. */
// TODO check if chrome and other browsers cache local files for now. If it does not then delete next 2 strings
if (!BX.browser.IsFirefox())
image.src = '/bitrix/images/1.gif';
/** For Garbage collector */
this.onload = null;
delete this.onload;
this.onerror = null;
delete this.onerror;
this.onload = BX.delegate(function(e){
if (e && e.target && e.target.src && e.target.src.substr(-20) == "/bitrix/images/1.gif")
return;
if (!!callback)
{
try {
callback(BX.proxy_context, this.getCanvas(), this.getContext(), getOrientation((((e && e.target && e.target.src) ? e.target.src : (BX.proxy_context || null)))));
}
catch (e)
{
BX.debug(e);
}
}
if (!!id)
{
this.queue.removeItem(id);
setTimeout(BX.proxy(function() {
this.active = null;
this.exec();
}, this), this.timeLimit);
}
else
this.active = null;
}, this);
this.onerror = BX.delegate(function(){
if (!!callbackFail)
{
try
{
callbackFail(BX.proxy_context);
}
catch (e)
{
BX.debug(e);
}
}
if (!!id)
{
this.queue.removeItem(id);
setTimeout(BX.proxy(function() {
this.active = null;
this.exec();
}, this), this.timeLimit);
}
else
this.active = null;
}, this);
image.name = file.name;
image.onload = this.onload;
image.onerror = this.onerror;
var res = Object.prototype.toString.call(file);
if (file["tmp_url"])
{
image.src = file["tmp_url"] + (file["tmp_url"].indexOf("?") > 0 ? '&' : '?') + 'imageUploader' + this.id + this.counter;
}
else if (res !== '[object File]' && res !== '[object Blob]')
{
this.onerror(null);
}
else if (window["URL"])
{
image.src = window["URL"]["createObjectURL"](file);
}
else if (this.getReader() !== null)
{
this.__readerOnLoad = null;
delete this.__readerOnLoad;
this.__readerOnLoad = BX.delegate(function(e) {
this.__readerOnLoad = null;
delete this.__readerOnLoad;
image.src = e.target.result;
}, this);
this.getReader().onloadend = this.__readerOnLoad;
this.getReader().onerror = BX.proxy(function(e) { this.onerror(null); }, this);
this.getReader().readAsDataURL(file);
}
},
push : function(file, callback, failCallback) {
var id = BX.UploaderUtils.getId();
this.queue.setItem(id, [id, file, callback, failCallback]);
this.exec();
},
exec : function() {
var item = this.queue.getFirst();
if (!!item)
this.load(item[1], item[2], item[0], item[3]);
},
pack : function(fileType) {
return BX.UploaderUtils.dataURLToBlob(this.getCanvas().toDataURL(fileType));
}
};
return cnvConstructor;
})();
BX.UploaderFileCnvConstr = cnvConstr;
BX.UploaderFileFileLoader = (function(){
var d = function(timelimit) {
this.timeLimit = (typeof timelimit === "number" && timelimit > 0 ? timelimit : 50);
this.status = statuses.ready;
this.queue = new BX.UploaderUtils.Hash();
this._exec = BX.delegate(this.exec, this);
};
d.prototype = {
xhr : null,
goToNext : function(id)
{
delete this.xhr;
this.xhr = null;
this.queue.removeItem(id);
this.status = statuses.ready;
setTimeout(this._exec, this.timeLimit);
},
load : function(id, path, onsuccess, onfailure)
{
if (this.status != statuses.ready)
return;
this.status = statuses.inprogress;
var _this = this;
this.xhr = BX.ajax({
'method': 'GET',
'data' : '',
'url': path,
'onsuccess': function(blob){if (blob === null){onfailure(blob);} else {onsuccess(blob);} _this.goToNext(id);},
'onfailure': function(blob){onfailure(blob); _this.goToNext(id);},
'start': false,
'preparePost':false,
'processData':false
});
this.xhr.withCredentials = true;
this.xhr.responseType = 'blob';
this.xhr.send();
},
push : function(path, onsuccess, onfailure)
{
var id = BX.UploaderUtils.getId();
this.queue.setItem(id, [id, path, onsuccess, onfailure]);
this.exec();
},
exec : function()
{
var item = this.queue.getFirst();
if (!!item)
this.load(item[0], item[1], item[2], item[3]);
}
};
return d;
})();
var prvw = new cnvConstr(), upld = new cnvConstr(), edtr = new cnvConstr(), canvas = BX.create('CANVAS'), ctx;
/**
* @return {BX.UploaderFile}
* @file file
* @params array
* @limits array
* @caller {BX.Uploader}
* You should work with params["fields"] in case you want to change visual part
*/
var mobileNames = {};
BX.UploaderFile = function (file, params, limits, caller)
{
this.dialogName = (this.dialogName ? this.dialogName : "BX.UploaderFile");
this.file = file;
this.id = (file['id'] || 'file' + BX.UploaderUtils.getId());
this.name = file.name;
this.isNode = false;
if (BX.type.isDomNode(file))
{
this.isNode = true;
this.name = BX.UploaderUtils.getFileNameOnly(file.value);
if (/\[(.+?)\]/.test(file.name))
{
var tmp = /\[(.+?)\]/.exec(file.name);
this.id = tmp[1];
}
this.file.bxuHandler = this;
}
else if (file["tmp_url"] && !file["name"])
{
this.name = BX.UploaderUtils.getFileNameOnly(file["tmp_url"]);
}
this.preview = '<span id="' + this.id + 'Canvas" class="bx-bxu-canvas"></span>';
this.nameWithoutExt = (this.name.lastIndexOf('.') > 0 ? this.name.substr(0, this.name.lastIndexOf('.')) : this.name);
this.ext = this.name.substr(this.nameWithoutExt.length + 1);
if (/iPhone|iPad|iPod/i.test(navigator.userAgent) && this.nameWithoutExt == "image")
{
var nameWithoutExt = 'mobile_' + BX.date.format("Ymd_His");
mobileNames[nameWithoutExt] = (mobileNames[nameWithoutExt] || 0);
this.nameWithoutExt = nameWithoutExt + (mobileNames[nameWithoutExt] > 0 ? ("_" + mobileNames[nameWithoutExt]) : "");
this.name = this.nameWithoutExt + (BX.type.isNotEmptyString(this.ext) ? ("." + this.ext) : "");
mobileNames[nameWithoutExt]++;
}
this.size = '';
if (file.size)
this.size = BX.UploaderUtils.getFormattedSize(file.size, 0);
this.type = file.type;
this.status = statuses["new"];
this.limits = limits;
this.caller = caller;
this.fields = {
thumb : {
tagName : 'SPAN',
template : '<div class="someclass">#preview#<div>#name#</div>',
editorTemplate : '<div class="someeditorclass"><div>#name#</div>',
className : "bx-bxu-thumb-thumb",
placeHolder : null
},
preview : {
params : { width : 400, height : 400 },
template : "#preview#",
editorParams : { width : 1024, height : 860 },
editorTemplate : '<span>#preview#</span>',
className : "bx-bxu-thumb-preview",
placeHolder : null,
events : {
click : BX.delegate(this.clickFile, this)
},
type : "html"
},
name : {
template : "#name#",
editorTemplate : '<span><input type="text" name="name" value="#name#" /></span>',
className : "bx-bxu-thumb-name",
placeHolder : null
},
type : {
template : "#type#",
editorTemplate : '#type#',
className : "bx-bxu-thumb-type",
placeHolder : null
}
};
if (!!params["fields"])
{
var ij, key;
for (var ii in params["fields"])
{
if (params["fields"].hasOwnProperty(ii))
{
if (!!this.fields[ii])
{
for (ij in params["fields"][ii])
{
if (params["fields"][ii].hasOwnProperty(ij))
{
this.fields[ii][ij] = params["fields"][ii][ij];
}
}
}
else
this.fields[ii] = params["fields"][ii];
key = ii + '';
if (key.toLowerCase() != "thumb" && key.toLowerCase() != "preview")
{
this[key.toLowerCase()] = (!!params["fields"][ii]["value"] ? params["fields"][ii]["value"] : "");
this.log(key.toLowerCase() + ': ' + this[key.toLowerCase()]);
}
}
}
}
BX.onCustomEvent(this, "onFileIsCreated", [this.id, this, this.caller]);
BX.onCustomEvent(this.caller, "onFileIsCreated", [this.id, this, this.caller]);
this.makePreview();
this.preparationStatus = statuses.done;
return this;
};
BX.UploaderFile.prototype = {
log : function(text)
{
BX.UploaderUtils.log('file ' + this.name, text);
},
makeThumb : function()
{
var template = this.fields.thumb.template, name, ii, events = {}, node, jj;
for (ii in this.fields)
{
if (this.fields.hasOwnProperty(ii))
{
if (this.fields[ii].template && this.fields[ii].template.indexOf('#' + ii + '#') >= 0)
{
name = this.id + ii.toUpperCase().substr(0, 1) + ii.substr(1);
node = this.setProps(ii, this[ii], true);
template = template.replace('#' + ii + '#', '<span id="' + name + '" class="' + this.fields[ii]["className"] + '">' + (
BX.type.isNotEmptyString(node.html) ? node.html.replace("#", "<\x19>") : node.html) + '</span>');
for (jj in node.events)
{
if (node.events.hasOwnProperty(jj))
{
events[jj] = node.events[jj];
}
}
if (!!this.fields[ii].events)
events[name] = this.fields[ii].events;
}
}
}
var res, patt = [], repl = [], tmp;
while ((res = /#([^\\<\\>\\"\\']+?)#/gi.exec(template)) && !!res)
{
if (this[res[1]] !== undefined)
{
template = template.replace(res[0], BX.type.isNotEmptyString(this[res[1]]) ? this[res[1]].replace("#", "<\x19>") : this[res[1]]);
}
else
{
tmp = "<\x18" + patt.length + ">";
patt.push(tmp);
repl.push(res[0]);
template = template.replace(res[0], tmp);
}
}
while ((res = patt.shift()) && res)
{
tmp = repl.shift();
template = template.replace(res, tmp);
}
template = template.replace("<\x19>", "#");
if (!!this.fields.thumb.tagName)
{
res = BX.create(this.fields.thumb.tagName, {
attrs : {
id : (this.id + 'Thumb'),
className : this.fields.thumb.className
},
events : this.fields.thumb.events,
html : template
}
);
}
else
{
res = template;
}
this.__makeThumbEventsObj = events;
this.__makeThumbEvents = BX.delegate(function()
{
var ii, jj;
for (ii in events)
{
if (events.hasOwnProperty(ii) && BX(ii))
{
for (jj in events[ii])
{
if (events[ii].hasOwnProperty(jj))
{
BX.bind(BX(ii), jj, events[ii][jj]);
}
}
}
}
this.__makeThumbEvents = null;
delete this.__makeThumbEvents;
}, this);
BX.addCustomEvent(this, "onFileIsAppended", this.__makeThumbEvents);
if (BX.type.isDomNode(this.file))
{
if (BX.type.isString(template))
{
this.__bindFileNode = BX.delegate(function(id)
{
var node = BX(id + 'Item');
if (node.tagName == 'TR')
node.cells[0].appendChild(this.file);
else if (node.tagName == 'TABLE')
node.rows[0].cells[0].appendChild(this.file);
else
BX(id + 'Item').appendChild(this.file);
this.__bindFileNode = null;
delete this.__bindFileNode;
}, this);
BX.addCustomEvent(this, "onFileIsAppended", this.__bindFileNode);
}
else
{
res.appendChild(this.file);
}
}
return res;
},
checkProps : function()
{
var el2 = BX.UploaderUtils.FormToArray({elements : [BX.proxy_context]}), ii;
for (ii in el2.data)
{
if (el2.data.hasOwnProperty(ii))
this[ii] = el2.data[ii];
}
},
setProps : function(name, val, bReturn)
{
if (typeof name == "string")
{
if (name == "size")
val = BX.UploaderUtils.getFormattedSize(this.file.size, 0);
if (typeof this[name] != "undefined" && typeof this.fields[name] != "undefined")
{
this[name] = val;
var template = this.fields[name].template.
replace('#' + name + '#', this.fields[name]["type"] === "html" ? (val || '') : BX.util.htmlspecialchars(val || '')).
replace(/#id#/gi, this.id),
fii, fjj, el, result = {html : template, events : {}};
this.hiddenForm = (!!this.hiddenForm ? this.hiddenForm : BX.create("FORM", { style : { display : "none" } } ));
this._checkProps = (!!this._checkProps ? this._checkProps : BX.delegate(this.checkProps, this));
this.hiddenForm.innerHTML = template;
if (this.hiddenForm.elements.length > 0)
{
for (fii = 0; fii < this.hiddenForm.elements.length; fii++)
{
el = this.hiddenForm.elements[fii];
if (typeof this[el.name] != "undefined")
{
if (!el.hasAttribute("id"))
el.setAttribute("id", this.id + name + BX.UploaderUtils.getId());
result.events[el.id] = {
blur : this._checkProps
}
}
}
result.html = this.hiddenForm.innerHTML;
}
if (BX(this.hiddenForm))
BX.remove(this.hiddenForm);
this.hiddenForm = null;
delete this.hiddenForm;
if (bReturn)
return result;
var node = this.getPH(name);
if (!!node)
{
node.innerHTML = result.html;
for (fii in result.events)
{
if (result.events.hasOwnProperty(fii))
{
for (fjj in result.events[fii])
{
if (result.events[fii].hasOwnProperty(fjj))
{
BX.bind(BX(fii), fjj, result.events[fii][fjj]);
}
}
}
}
}
}
}
else if (!!name)
{
for (var ij in name)
{
if (name.hasOwnProperty(ij))
{
if (this.fields.hasOwnProperty(ij) && ij !== "preview")
this.setProps(ij, name[ij]);
}
}
}
return true;
},
getProps : function(name)
{
if (name == "canvas")
{
return BX(this.id + "ProperCanvas");
}
else if (typeof name == "string")
{
return this[name];
}
var data = {};
for (var ii in this.fields)
{
if (this.fields.hasOwnProperty(ii) && (ii !== "preview" && ii !== "thumb"))
{
data[ii] = this[ii];
}
}
data["size"] = this.file["size"];
data["type"] = this["type"];
if (!!this.copies)
{
var copy;
data["canvases"] = {};
while ((copy = this.copies.getNext()) && !!copy)
{
data["canvases"][copy.id] = { width : copy.width, height : copy.height, name : copy.name };
}
}
return data;
},
getThumbs : function()
{
return null;
},
getPH : function(name)
{
name = (typeof name === "string" ? name : "");
name = name.toLowerCase();
if (this.fields.hasOwnProperty(name))
{
var id = name.substr(0, 1).toUpperCase() + name.substr(1);
this.fields[name]["placeHolder"] = BX(this.id + id);
return this.fields[name]["placeHolder"];
}
return null;
},
clickFile : function ()
{
return false;
},
makePreview: function()
{
this.status = statuses.ready;
BX.onCustomEvent(this, "onFileIsInited", [this.id, this, this.caller]);
BX.onCustomEvent(this.caller, "onFileIsInited", [this.id, this, this.caller]);
this.log('is initialized as a file');
},
preparationStatus : statuses.ready,
deleteFile: function()
{
var ii, events = this.__makeThumbEventsObj;
for (ii in this.fields)
{
if (this.fields.hasOwnProperty(ii))
{
if (!!this.fields[ii]["placeHolder"])
{
this.fields[ii]["placeHolder"] = null;
BX.unbindAll(this.fields[ii]["placeHolder"]);
delete this.fields[ii]["placeHolder"];
}
}
}
for (ii in events)
{
if (events.hasOwnProperty(ii) && BX(ii))
{
BX.unbindAll(BX(ii));
}
}
this.file = null;
delete this.file;
BX.remove(this.canvas);
this.canvas = null;
delete this.canvas;
BX.onCustomEvent(this.caller, "onFileIsDeleted", [this.id, this, this.caller]);
BX.onCustomEvent(this, "onFileIsDeleted", [this, this.caller]);
}
};
BX.UploaderImage = function(file, params, limits, caller)
{
this.dialogName = "BX.UploaderImage";
BX.UploaderImage.superclass.constructor.apply(this, arguments);
this.isImage = true;
this.copies = new BX.UploaderUtils.Hash();
this.caller = caller;
if (!this.isNode && BX.Uploader.getInstanceName() == "BX.Uploader")
{
if (!!params["copies"])
{
var copies = params["copies"], copy;
for (var ii in copies)
{
if (copies.hasOwnProperty(ii) && !!copies[ii])
{
copy = { width : parseInt(copies[ii]['width']), height : parseInt(copies[ii]["height"]), id : ii };
if (copy['width'] > 0 && copy["height"] > 0)
{
this.copies.setItem(ii, copy);
}
}
}
}
this.preparationStatus = statuses["new"];
BX.addCustomEvent(this, "onFileHasToBePrepared", BX.delegate(function()
{
this.preparationStatus = statuses.inprogress;
if (this.status != statuses["new"])
{
upld.push(this.file, BX.delegate(this.makeCopies, this));
}
}, this));
BX.addCustomEvent(this, "onUploadDone", BX.delegate(function()
{
var copy;
while ((copy = this.copies.getNext()) && !!copy)
{
copy.file = null;
delete copy.file;
}
this.preparationStatus = statuses["new"];
}, this));
this.canvas = BX.create('CANVAS', {attrs : { id : this.id + "ProperCanvas" } } );
}
else
{
this.preparationStatus = statuses.done;
this.canvas = null;
}
return this;
};
BX.extend(BX.UploaderImage, BX.UploaderFile);
BX.UploaderImage.prototype.makePreviewImageWork = function(image, cnv, ctx, exifOrientation)
{
exifOrientation = parseInt(exifOrientation);
var result = null,
width = cnv.width,
height = cnv.height;
if (this.file)
{
this.file.width = cnv.width;
this.file.height = cnv.height;
}
if (!!this.canvas)
{
setOrientation(image, cnv, ctx, exifOrientation);
if (this.file)
{
this.file.width = cnv.width;
this.file.height = cnv.height;
if (exifOrientation)
{
this.file.exif = {
Orientation : exifOrientation
}
}
}
this.applyFile(cnv, false);
result = this.canvas;
}
else if (BX(this.id + 'Canvas'))
{
var res2 = BX.UploaderUtils.scaleImage({width : width, height : height}, this.fields.preview.params),
props = {
props : { width : res2.destin.width, height : res2.destin.height, src : image.src },
attrs : {
className : (this.file.width > this.file.height ? "landscape" : "portrait")
}
};
switch (exifOrientation)
{
case 2:
props.attrs.className += ' flip'; break;
case 3:
props.attrs.className += ' rotate-180'; break;
case 4:
props.attrs.className += ' flip-and-rotate-180'; break;
case 5:
props.attrs.className += ' flip-and-rotate-270'; break;
case 6:
props.attrs.className += ' rotate-90'; break;
case 7:
props.attrs.className += ' flip-and-rotate-90'; break;
case 8:
props.attrs.className += ' rotate-270'; break;
}
result = BX.create("IMG", props);
}
BX.onCustomEvent(this, "onFileCanvasIsLoaded", [this.id, this, this.caller, image]);
BX.onCustomEvent(this.caller, "onFileCanvasIsLoaded", [this.id, this, this.caller, image]);
if (BX(this.id + 'Canvas'))
BX(this.id + 'Canvas').appendChild(result);
return result;
};
BX.UploaderImage.prototype.makePreviewImageLoadHandler = function(image, canvas, context, exifOrientation){
this.makePreviewImageWork(image, canvas, context, exifOrientation);
this.status = statuses.ready;
BX.onCustomEvent(this, "onFileIsInited", [this.id, this, this.caller]);
BX.onCustomEvent(this.caller, "onFileIsInited", [this.id, this, this.caller]);
this.log('is initialized as an image with preview');
if (this.preparationStatus == statuses.inprogress)
this.makeCopies(image, canvas, context, exifOrientation);
if (this["_makePreviewImageLoadHandler"])
{
this._makePreviewImageLoadHandler = null;
delete this._makePreviewImageLoadHandler;
}
if (this["_makePreviewImageFailedHandler"])
{
this._makePreviewImageFailedHandler = null;
delete this._makePreviewImageFailedHandler;
}
};
BX.UploaderImage.prototype.makePreviewImageFailedHandler = function(){
this.status = statuses.ready;
this.preparationStatus = statuses.done;
BX.onCustomEvent(this, "onFileIsInited", [this.id, this, this.caller]);
BX.onCustomEvent(this.caller, "onFileIsInited", [this.id, this, this.caller]);
this.log('is initialized without canvas');
if (this["_makePreviewImageLoadHandler"])
{
this._makePreviewImageLoadHandler = null;
delete this._makePreviewImageLoadHandler;
}
if (this["_makePreviewImageFailedHandler"])
{
this._makePreviewImageFailedHandler = null;
delete this._makePreviewImageFailedHandler;
}
};
BX.UploaderImage.prototype.makePreview = function()
{
if (!this.isNode)
{
this._makePreviewImageLoadHandler = BX.delegate(this.makePreviewImageLoadHandler, this);
this._makePreviewImageFailedHandler = BX.delegate(this.makePreviewImageFailedHandler, this);
prvw.push(this.file, this._makePreviewImageLoadHandler, this._makePreviewImageFailedHandler);
}
else
{
this.status = statuses.ready;
BX.onCustomEvent(this, "onFileIsInited", [this.id, this, this.caller]);
BX.onCustomEvent(this.caller, "onFileIsInited", [this.id, this, this.caller]);
this.log('is initialized as an image without preview');
if (this.caller.queue.placeHolder)
{
this._onFileHasGotPreview = BX.delegate(function(id, item) {
BX.removeCustomEvent(this, "onFileHasGotPreview", this._onFileHasGotPreview);
BX.removeCustomEvent(this, "onFileHasNotGotPreview", this._onFileHasNotGotPreview);
this._makePreviewImageLoadHandler = BX.delegate(function(image){
image = this.makePreviewImageWork(image);
BX.onCustomEvent(this, "onFileHasPreview", [item.id, item, image]);
delete this._makePreviewImageLoadHandler;
delete this._makePreviewImageFailedHandler;
}, this);
this._makePreviewImageFailedHandler = BX.delegate(function(image){
delete this._makePreviewImageLoadHandler;
delete this._makePreviewImageFailedHandler;
}, this);
prvw.push({tmp_url : item.file.url}, this._makePreviewImageLoadHandler, this._makePreviewImageFailedHandler);
}, this);
this._onFileHasNotGotPreview = BX.delegate(function(id){
if (id == this.id)
{
BX.removeCustomEvent(this, "onFileHasGotPreview", this._onFileHasGotPreview);
BX.removeCustomEvent(this, "onFileHasNotGotPreview", this._onFileHasNotGotPreview);
}
}, this);
BX.addCustomEvent(this, "onFileHasGotPreview", this._onFileHasGotPreview);
BX.addCustomEvent(this, "onFileHasNotGotPreview", this._onFileHasNotGotPreview);
BX.onCustomEvent(this.caller, "onFileNeedsPreview", [this.id, this, this.caller]);
}
}
return true;
};
BX.UploaderImage.prototype.checkPreview = function()
{
// TODO check preview
};
BX.UploaderImage.prototype.applyFile = function(cnv, params)
{
this.checkPreview();
if (!!params && params.data )
this.setProps(params.data);
var realScale = BX.UploaderUtils.scaleImage(cnv, {width : this.limits["uploadFileWidth"], height : this.limits["uploadFileHeight"]}),
prvwScale = BX.UploaderUtils.scaleImage(cnv, this.fields.preview.params),
prvwProps = {
props : { width : prvwScale.destin.width, height : prvwScale.destin.height },
attrs : {
className : "bx-bxu-proper-canvas"+(prvwScale.destin.width > prvwScale.destin.height ? " landscape" : " portrait")
}
};
if (realScale.bNeedCreatePicture || !!params)
{
BX.adjust(canvas, { props : { width : realScale.destin.width, height : realScale.destin.height } } );
ctx = canvas.getContext('2d');
ctx.drawImage(cnv,
realScale.source.x, realScale.source.y, realScale.source.width, realScale.source.height,
realScale.destin.x, realScale.destin.y, realScale.destin.width, realScale.destin.height
);
var dataURI = canvas.toDataURL(this.file.type);
this.file = BX.UploaderUtils.dataURLToBlob(dataURI);
}
this.file.name = this.name;
this.file.width = realScale.destin.width;
this.file.height = realScale.destin.height;
BX.adjust(this.canvas, prvwProps);
ctx = this.canvas.getContext('2d');
ctx.drawImage(cnv,
prvwScale.source.x, prvwScale.source.y, prvwScale.source.width, prvwScale.source.height,
prvwScale.destin.x, prvwScale.destin.y, prvwScale.destin.width, prvwScale.destin.height
);
ctx = null;
cnv = null;
this.setProps('size');
this.status = statuses.changed;
};
BX.UploaderImage.prototype.clickFile = function()
{
if (!this.canvas || !BX["CanvasEditor"] || this.status == statuses["new"])
return false;
if (!this.__showEditor)
{
this.__showEditor = BX.delegate(this.showEditor, this);
this.eFunc = {
"apply" : BX.delegate(this.applyFile, this),
"delete" : BX.delegate(this.deleteFile, this),
"clear" : BX.delegate(function()
{
BX.removeCustomEvent(editor, "onApplyCanvas", this.eFunc["apply"]);
BX.removeCustomEvent(editor, "onDeleteCanvas", this.eFunc["delete"]);
BX.removeCustomEvent(editor, "onClose", this.eFunc["clear"]);
}, this)
};
}
var template = this.fields.thumb.editorTemplate, name;
for (var ii in this.fields)
{
if (this.fields.hasOwnProperty(ii))
{
name = ii.substr(0, 1).toUpperCase() + ii.substr(1);
template = template.replace('#' + ii + '#',
(ii === "preview" ? "" :
('<span id="' + this.id + name + 'Editor" class="' + this.fields[ii]["className"] + '">' +
this.fields[ii]["editorTemplate"].replace('#' + ii + '#', (!!this[ii] ? BX.util.htmlspecialchars(this[ii]) : '')) + '</span>')));
}
}
BX.adjust(edtr.getCanvas(), { props : { width : this.file.width, height : this.file.height } } );
edtr.getContext().drawImage(this.canvas,
0, 0, this.canvas.width, this.canvas.height,
0, 0, edtr.getCanvas().width, edtr.getCanvas().height);
var editor = BX.CanvasEditor.show(edtr.getCanvas(), {title : this.name, template : template});
BX.addCustomEvent(editor, "onApplyCanvas", this.eFunc["apply"]);
BX.addCustomEvent(editor, "onDeleteCanvas", this.eFunc["delete"]);
BX.addCustomEvent(editor, "onClose", this.eFunc["clear"]);
BX.onCustomEvent(this, "onCanvasEditorIsCreated", [editor, this]);
edtr.push(this.file, this.__showEditor);
this.editor = editor;
return false;
};
BX.UploaderImage.prototype.showEditor = function(image, canvas, context, exifOrientation)
{
BX.adjust(canvas, { props : { width : this.file.width, height : this.file.height } } );
setOrientation(image, canvas, context, exifOrientation);
this.editor.copyCanvas(canvas);
};
BX.UploaderImage.prototype.makeCopies = function(image, cnv, ctx, exifOrientation)
{
var copy, res, dataURI, result,
context = canvas.getContext('2d');
setOrientation(image, canvas, context, exifOrientation);
while ((copy = this.copies.getNext()) && !!copy)
{
res = BX.UploaderUtils.scaleImage(canvas, copy);
BX.adjust(cnv, {props : { width : res.destin.width, height : res.destin.height } } );
ctx.drawImage(canvas,
res.source.x, res.source.y, res.source.width, res.source.height,
res.destin.x, res.destin.y, res.destin.width, res.destin.height
);
dataURI = cnv.toDataURL(this.file.type);
result = BX.UploaderUtils.dataURLToBlob(dataURI);
result.width = cnv.width;
result.height = cnv.height;
result.name = this.name;
result.thumb = copy.id;
result.canvases = this.copies.length;
result.canvas = this.copies.pointer - 1;
copy.file = result;
}
this.preparationStatus = statuses.done;
};
BX.UploaderImage.prototype.getThumbs = function(name)
{
if (name == "getCount")
return this.copies.length;
var res = (typeof name == "string" ? this.copies.getItem(name) : this.copies.getNext());
if (!!res)
return res.file;
return null;
};
return true;
}(window));