From: Alan Date: Thu, 21 Jul 2022 04:36:26 +0000 (+0800) Subject: fix #7094 - dialog - upload cropbox add to classic roo library X-Git-Url: http://git.roojs.org/?p=roojs1;a=commitdiff_plain;h=523c9ff3c51eb8411c2decb2132d183f022b90d7 fix #7094 - dialog - upload cropbox add to classic roo library --- diff --git a/Roo/ContentPanel.js b/Roo/ContentPanel.js index 0984532b54..cc1b9d0ce5 100644 --- a/Roo/ContentPanel.js +++ b/Roo/ContentPanel.js @@ -41,7 +41,6 @@ */ Roo.ContentPanel = function(el, config, content){ - /* if(el.autoCreate || el.xtype){ // xtype is available if this is called from factory config = el; @@ -425,6 +424,14 @@ layout.addxtype({ */ addxtype : function(cfg) { + if(cfg.xtype.match(/^UploadCropbox$/)) { + + this.cropbox = new Roo.factory(cfg); + + this.cropbox.render(this.el); + + return this.cropbox; + } // add form.. if (cfg.xtype.match(/^Form$/)) { diff --git a/Roo/dialog/UploadCropbox.js b/Roo/dialog/UploadCropbox.js new file mode 100644 index 0000000000..7bc78e356b --- /dev/null +++ b/Roo/dialog/UploadCropbox.js @@ -0,0 +1,1805 @@ + +/* +* Licence: LGPL +*/ + +/** + * @class Roo.dialog.UploadCropbox + * @extends Roo.BoxComponent + * Dialog UploadCropbox class + * @cfg {String} emptyText show when image has been loaded + * @cfg {String} rotateNotify show when image too small to rotate + * @cfg {Number} errorTimeout default 3000 + * @cfg {Number} minWidth default 300 + * @cfg {Number} minHeight default 300 + * @cfg {Number} outputMaxWidth default 1200 + * @cfg {Number} windowSize default 300 + * @cfg {Array} buttons default ['rotateLeft', 'pictureBtn', 'rotateRight'] + * @cfg {Boolean} isDocument (true|false) default false + * @cfg {String} url action url + * @cfg {String} paramName default 'imageUpload' + * @cfg {String} method default POST + * @cfg {Boolean} loadMask (true|false) default true + * @cfg {Boolean} loadingText default 'Loading...' + * + * @constructor + * Create a new UploadCropbox + * @param {Object} config The config object + */ + + Roo.dialog.UploadCropbox = function(config){ + Roo.dialog.UploadCropbox.superclass.constructor.call(this, config); + + this.addEvents({ + /** + * @event beforeselectfile + * Fire before select file + * @param {Roo.dialog.UploadCropbox} this + */ + "beforeselectfile" : true, + /** + * @event initial + * Fire after initEvent + * @param {Roo.dialog.UploadCropbox} this + */ + "initial" : true, + /** + * @event crop + * Fire after initEvent + * @param {Roo.dialog.UploadCropbox} this + * @param {String} data + */ + "crop" : true, + /** + * @event prepare + * Fire when preparing the file data + * @param {Roo.dialog.UploadCropbox} this + * @param {Object} file + */ + "prepare" : true, + /** + * @event exception + * Fire when get exception + * @param {Roo.dialog.UploadCropbox} this + * @param {XMLHttpRequest} xhr + */ + "exception" : true, + /** + * @event beforeloadcanvas + * Fire before load the canvas + * @param {Roo.dialog.UploadCropbox} this + * @param {String} src + */ + "beforeloadcanvas" : true, + /** + * @event trash + * Fire when trash image + * @param {Roo.dialog.UploadCropbox} this + */ + "trash" : true, + /** + * @event download + * Fire when download the image + * @param {Roo.dialog.UploadCropbox} this + */ + "download" : true, + /** + * @event footerbuttonclick + * Fire when footerbuttonclick + * @param {Roo.dialog.UploadCropbox} this + * @param {String} type + */ + "footerbuttonclick" : true, + /** + * @event resize + * Fire when resize + * @param {Roo.dialog.UploadCropbox} this + */ + "resize" : true, + /** + * @event rotate + * Fire when rotate the image + * @param {Roo.dialog.UploadCropbox} this + * @param {String} pos + */ + "rotate" : true, + /** + * @event inspect + * Fire when inspect the file + * @param {Roo.dialog.UploadCropbox} this + * @param {Object} file + */ + "inspect" : true, + /** + * @event upload + * Fire when xhr upload the file + * @param {Roo.dialog.UploadCropbox} this + * @param {Object} data + */ + "upload" : true, + /** + * @event arrange + * Fire when arrange the file data + * @param {Roo.dialog.UploadCropbox} this + * @param {Object} formData + */ + "arrange" : true, + /** + * @event loadcanvas + * Fire after load the canvas + * @param {Roo.dialog.UploadCropbox} + * @param {Object} imgEl + */ + "loadcanvas" : true + }); + + this.buttons = this.buttons || Roo.dialog.UploadCropbox.footer.STANDARD; +}; + +Roo.extend(Roo.dialog.UploadCropbox, Roo.Component, { + + emptyText : 'Click to upload image', + rotateNotify : 'Image is too small to rotate', + errorTimeout : 3000, + scale : 0, + baseScale : 1, + rotate : 0, + dragable : false, + pinching : false, + mouseX : 0, + mouseY : 0, + cropData : false, + minWidth : 300, + minHeight : 300, + outputMaxWidth : 1200, + windowSize : 300, + file : false, + exif : {}, + baseRotate : 1, + cropType : 'image/jpeg', + buttons : false, + canvasLoaded : false, + isDocument : false, + method : 'POST', + paramName : 'imageUpload', + loadMask : true, + loadingText : 'Loading...', + maskEl : false, + + getAutoCreate : function() + { + var cfg = { + tag : 'div', + cls : 'roo-upload-cropbox', + cn : [ + { + tag : 'input', + cls : 'roo-upload-cropbox-selector', + type : 'file' + }, + { + tag : 'div', + cls : 'roo-upload-cropbox-body', + style : 'cursor:pointer', + cn : [ + { + tag : 'div', + cls : 'roo-upload-cropbox-preview' + }, + { + tag : 'div', + cls : 'roo-upload-cropbox-thumb' + }, + { + tag : 'div', + cls : 'roo-upload-cropbox-empty-notify', + html : this.emptyText + }, + { + tag : 'div', + cls : 'roo-upload-cropbox-error-notify alert alert-danger', + html : this.rotateNotify + } + ] + }, + { + tag : 'div', + cls : 'roo-upload-cropbox-footer', + cn : { + tag : 'div', + cls : 'btn-group btn-group-justified roo-upload-cropbox-btn-group', + cn : [] + } + } + ] + }; + + return cfg; + }, + + onRender : function(ct, position) + { + Roo.dialog.UploadCropbox.superclass.onRender.call(this, ct, position); + + if(this.el){ + if (this.el.attr('xtype')) { + this.el.attr('xtypex', this.el.attr('xtype')); + this.el.dom.removeAttribute('xtype'); + + this.initEvents(); + } + } + else { + var cfg = Roo.apply({}, this.getAutoCreate()); + + cfg.id = this.id || Roo.id(); + + if (this.cls) { + cfg.cls = (typeof(cfg.cls) == 'undefined' ? this.cls : cfg.cls) + ' ' + this.cls; + } + + if (this.style) { // fixme needs to support more complex style data. + cfg.style = (typeof(cfg.style) == 'undefined' ? this.style : cfg.style) + '; ' + this.style; + } + + this.el = ct.createChild(cfg, position); + + this.initEvents(); + } + + if (this.buttons.length) { + + Roo.each(this.buttons, function(bb) { + + var btn = this.el.select('.roo-upload-cropbox-footer div.roo-upload-cropbox-btn-group').first().createChild(bb); + + btn.on('click', this.onFooterButtonClick.createDelegate(this, [bb.action], true)); + + }, this); + } + + if(this.loadMask){ + this.maskEl = this.el; + } + }, + + initEvents : function() + { + this.urlAPI = (window.createObjectURL && window) || + (window.URL && URL.revokeObjectURL && URL) || + (window.webkitURL && webkitURL); + + this.bodyEl = this.el.select('.roo-upload-cropbox-body', true).first(); + this.bodyEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block'; + + this.selectorEl = this.el.select('.roo-upload-cropbox-selector', true).first(); + this.selectorEl.hide(); + + this.previewEl = this.el.select('.roo-upload-cropbox-preview', true).first(); + this.previewEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block'; + + this.thumbEl = this.el.select('.roo-upload-cropbox-thumb', true).first(); + this.thumbEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block'; + this.thumbEl.hide(); + + this.notifyEl = this.el.select('.roo-upload-cropbox-empty-notify', true).first(); + this.notifyEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block'; + + this.errorEl = this.el.select('.roo-upload-cropbox-error-notify', true).first(); + this.errorEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block'; + this.errorEl.hide(); + + this.footerEl = this.el.select('.roo-upload-cropbox-footer', true).first(); + this.footerEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block'; + this.footerEl.hide(); + + this.setThumbBoxSize(); + + this.bind(); + + this.resize(); + + this.fireEvent('initial', this); + }, + + bind : function() + { + var _this = this; + + window.addEventListener("resize", function() { _this.resize(); } ); + + this.bodyEl.on('click', this.beforeSelectFile, this); + + if(Roo.isTouch){ + this.bodyEl.on('touchstart', this.onTouchStart, this); + this.bodyEl.on('touchmove', this.onTouchMove, this); + this.bodyEl.on('touchend', this.onTouchEnd, this); + } + + if(!Roo.isTouch){ + this.bodyEl.on('mousedown', this.onMouseDown, this); + this.bodyEl.on('mousemove', this.onMouseMove, this); + var mousewheel = (/Firefox/i.test(navigator.userAgent))? 'DOMMouseScroll' : 'mousewheel'; + this.bodyEl.on(mousewheel, this.onMouseWheel, this); + Roo.get(document).on('mouseup', this.onMouseUp, this); + } + + this.selectorEl.on('change', this.onFileSelected, this); + }, + + reset : function() + { + this.scale = 0; + this.baseScale = 1; + this.rotate = 0; + this.baseRotate = 1; + this.dragable = false; + this.pinching = false; + this.mouseX = 0; + this.mouseY = 0; + this.cropData = false; + this.notifyEl.dom.innerHTML = this.emptyText; + + // this.selectorEl.dom.value = ''; + + }, + + resize : function() + { + if(this.fireEvent('resize', this) != false){ + this.setThumbBoxPosition(); + this.setCanvasPosition(); + } + }, + + onFooterButtonClick : function(e, el, o, type) + { + switch (type) { + case 'rotate-left' : + this.onRotateLeft(e); + break; + case 'rotate-right' : + this.onRotateRight(e); + break; + case 'picture' : + this.beforeSelectFile(e); + break; + case 'trash' : + this.trash(e); + break; + case 'crop' : + this.crop(e); + break; + case 'download' : + this.download(e); + break; + default : + break; + } + + this.fireEvent('footerbuttonclick', this, type); + }, + + beforeSelectFile : function(e) + { + e.preventDefault(); + + if(this.fireEvent('beforeselectfile', this) != false){ + this.selectorEl.dom.click(); + } + }, + + onFileSelected : function(e) + { + e.preventDefault(); + + if(typeof(this.selectorEl.dom.files) == 'undefined' || !this.selectorEl.dom.files.length){ + return; + } + + var file = this.selectorEl.dom.files[0]; + + if(this.fireEvent('inspect', this, file) != false){ + this.prepare(file); + } + + }, + + trash : function(e) + { + this.fireEvent('trash', this); + }, + + download : function(e) + { + this.fireEvent('download', this); + }, + + loadCanvas : function(src) + { + if(this.fireEvent('beforeloadcanvas', this, src) != false){ + + this.reset(); + + this.imageEl = document.createElement('img'); + + var _this = this; + + this.imageEl.addEventListener("load", function(){ _this.onLoadCanvas(); }); + + this.imageEl.src = src; + } + }, + + onLoadCanvas : function() + { + this.imageEl.OriginWidth = this.imageEl.naturalWidth || this.imageEl.width; + this.imageEl.OriginHeight = this.imageEl.naturalHeight || this.imageEl.height; + + if(this.fireEvent('loadcanvas', this, this.imageEl) != false){ + + this.bodyEl.un('click', this.beforeSelectFile, this); + + this.notifyEl.hide(); + this.thumbEl.show(); + this.footerEl.show(); + + this.baseRotateLevel(); + + if(this.isDocument){ + this.setThumbBoxSize(); + } + + this.setThumbBoxPosition(); + + this.baseScaleLevel(); + + this.draw(); + + this.resize(); + + this.canvasLoaded = true; + + } + + if(this.loadMask){ + this.maskEl.unmask(); + } + + }, + + setCanvasPosition : function() + { + if(!this.canvasEl){ + return; + } + + var pw = Math.ceil((this.bodyEl.getWidth() - this.canvasEl.width) / 2); + var ph = Math.ceil((this.bodyEl.getHeight() - this.canvasEl.height) / 2); + + this.previewEl.setLeft(pw); + this.previewEl.setTop(ph); + + }, + + onMouseDown : function(e) + { + e.stopEvent(); + + this.dragable = true; + this.pinching = false; + + if(this.isDocument && (this.canvasEl.width < this.thumbEl.getWidth() || this.canvasEl.height < this.thumbEl.getHeight())){ + this.dragable = false; + return; + } + + this.mouseX = Roo.isTouch ? e.browserEvent.touches[0].pageX : e.getPageX(); + this.mouseY = Roo.isTouch ? e.browserEvent.touches[0].pageY : e.getPageY(); + + }, + + onMouseMove : function(e) + { + e.stopEvent(); + + if(!this.canvasLoaded){ + return; + } + + if (!this.dragable){ + return; + } + + var minX = Math.ceil(this.thumbEl.getLeft(true)); + var minY = Math.ceil(this.thumbEl.getTop(true)); + + var maxX = Math.ceil(minX + this.thumbEl.getWidth() - this.canvasEl.width); + var maxY = Math.ceil(minY + this.thumbEl.getHeight() - this.canvasEl.height); + + if(minX > maxX) { + var tempX = minX; + minX = maxX; + maxX = tempX; + } + + if(minY > maxY) { + var tempY = minY; + minY = maxY; + maxY = tempY; + } + + var x = Roo.isTouch ? e.browserEvent.touches[0].pageX : e.getPageX(); + var y = Roo.isTouch ? e.browserEvent.touches[0].pageY : e.getPageY(); + + x = x - this.mouseX; + y = y - this.mouseY; + + var bgX = Math.ceil(x + this.previewEl.getLeft(true)); + var bgY = Math.ceil(y + this.previewEl.getTop(true)); + + bgX = (bgX < minX) ? minX : ((bgX > maxX) ? maxX : bgX); + bgY = (bgY < minY) ? minY : ((bgY > maxY) ? maxY : bgY); + + this.previewEl.setLeft(bgX); + this.previewEl.setTop(bgY); + + this.mouseX = Roo.isTouch ? e.browserEvent.touches[0].pageX : e.getPageX(); + this.mouseY = Roo.isTouch ? e.browserEvent.touches[0].pageY : e.getPageY(); + }, + + onMouseUp : function(e) + { + e.stopEvent(); + + this.dragable = false; + }, + + onMouseWheel : function(e) + { + e.stopEvent(); + + this.startScale = this.scale; + this.scale = (e.getWheelDelta() > 0) ? (this.scale + 1) : (this.scale - 1); + + if(!this.zoomable()){ + this.scale = this.startScale; + return; + } + + + this.draw(); + + return; + }, + + zoomable : function() + { + var minScale = this.thumbEl.getWidth() / this.minWidth; + + if(this.minWidth < this.minHeight){ + minScale = this.thumbEl.getHeight() / this.minHeight; + } + + var width = Math.ceil(this.imageEl.OriginWidth * this.getScaleLevel() / minScale); + var height = Math.ceil(this.imageEl.OriginHeight * this.getScaleLevel() / minScale); + + var maxWidth = this.imageEl.OriginWidth; + var maxHeight = this.imageEl.OriginHeight; + + if( + this.isDocument && + (this.rotate == 0 || this.rotate == 180) && + ( + width > this.imageEl.OriginWidth || + height > this.imageEl.OriginHeight || + (width < this.minWidth && height < this.minHeight) + ) + ){ + return false; + } + + if( + this.isDocument && + (this.rotate == 90 || this.rotate == 270) && + ( + width > this.imageEl.OriginWidth || + height > this.imageEl.OriginHeight || + (width < this.minHeight && height < this.minWidth) + ) + ){ + return false; + } + + if( + !this.isDocument && + (this.rotate == 0 || this.rotate == 180) && + ( + (this.imageEl.OriginWidth / this.imageEl.OriginHeight >= this.minWidth / this.minHeight) && width < this.minWidth || + (this.imageEl.OriginWidth / this.imageEl.OriginHeight <= this.minWidth / this.minHeight) && height < this.minHeight || + width > maxWidth || + height > maxHeight + ) + ){ + return false; + } + + if( + !this.isDocument && + (this.rotate == 90 || this.rotate == 270) && + ( + width < this.minHeight || + width > this.imageEl.OriginWidth || + height < this.minWidth || + height > this.imageEl.OriginHeight + ) + ){ + return false; + } + + return true; + + }, + + onRotateLeft : function(e) + { + if(!this.isDocument && (this.canvasEl.height < this.thumbEl.getWidth() || this.canvasEl.width < this.thumbEl.getHeight())){ + + var minScale = this.thumbEl.getWidth() / this.minWidth; + + var bw = Math.ceil(this.canvasEl.width / this.getScaleLevel()); + var bh = Math.ceil(this.canvasEl.height / this.getScaleLevel()); + + this.startScale = this.scale; + + while (this.getScaleLevel() < minScale){ + + this.scale = this.scale + 1; + + if(!this.zoomable()){ + break; + } + + if( + Math.ceil(bw * this.getScaleLevel()) < this.thumbEl.getHeight() || + Math.ceil(bh * this.getScaleLevel()) < this.thumbEl.getWidth() + ){ + continue; + } + + this.rotate = (this.rotate < 90) ? 270 : this.rotate - 90; + + this.draw(); + + return; + } + + this.scale = this.startScale; + + this.onRotateFail(); + + return false; + } + + this.rotate = (this.rotate < 90) ? 270 : this.rotate - 90; + + if(this.isDocument){ + this.setThumbBoxSize(); + this.setThumbBoxPosition(); + this.setCanvasPosition(); + } + + this.draw(); + + this.fireEvent('rotate', this, 'left'); + + }, + + onRotateRight : function(e) + { + if(!this.isDocument && (this.canvasEl.height < this.thumbEl.getWidth() || this.canvasEl.width < this.thumbEl.getHeight())){ + + var minScale = this.thumbEl.getWidth() / this.minWidth; + + var bw = Math.ceil(this.canvasEl.width / this.getScaleLevel()); + var bh = Math.ceil(this.canvasEl.height / this.getScaleLevel()); + + this.startScale = this.scale; + + while (this.getScaleLevel() < minScale){ + + this.scale = this.scale + 1; + + if(!this.zoomable()){ + break; + } + + if( + Math.ceil(bw * this.getScaleLevel()) < this.thumbEl.getHeight() || + Math.ceil(bh * this.getScaleLevel()) < this.thumbEl.getWidth() + ){ + continue; + } + + this.rotate = (this.rotate > 180) ? 0 : this.rotate + 90; + + this.draw(); + + return; + } + + this.scale = this.startScale; + + this.onRotateFail(); + + return false; + } + + this.rotate = (this.rotate > 180) ? 0 : this.rotate + 90; + + if(this.isDocument){ + this.setThumbBoxSize(); + this.setThumbBoxPosition(); + this.setCanvasPosition(); + } + + this.draw(); + + this.fireEvent('rotate', this, 'right'); + }, + + onRotateFail : function() + { + this.errorEl.show(true); + + var _this = this; + + (function() { _this.errorEl.hide(true); }).defer(this.errorTimeout); + }, + + draw : function() + { + this.previewEl.dom.innerHTML = ''; + + var canvasEl = document.createElement("canvas"); + + var contextEl = canvasEl.getContext("2d"); + + canvasEl.width = this.imageEl.OriginWidth * this.getScaleLevel(); + canvasEl.height = this.imageEl.OriginWidth * this.getScaleLevel(); + var center = this.imageEl.OriginWidth / 2; + + if(this.imageEl.OriginWidth < this.imageEl.OriginHeight){ + canvasEl.width = this.imageEl.OriginHeight * this.getScaleLevel(); + canvasEl.height = this.imageEl.OriginHeight * this.getScaleLevel(); + center = this.imageEl.OriginHeight / 2; + } + + contextEl.scale(this.getScaleLevel(), this.getScaleLevel()); + + contextEl.translate(center, center); + contextEl.rotate(this.rotate * Math.PI / 180); + + contextEl.drawImage(this.imageEl, 0, 0, this.imageEl.OriginWidth, this.imageEl.OriginHeight, center * -1, center * -1, this.imageEl.OriginWidth, this.imageEl.OriginHeight); + + this.canvasEl = document.createElement("canvas"); + + this.contextEl = this.canvasEl.getContext("2d"); + + switch (this.rotate) { + case 0 : + + this.canvasEl.width = this.imageEl.OriginWidth * this.getScaleLevel(); + this.canvasEl.height = this.imageEl.OriginHeight * this.getScaleLevel(); + + this.contextEl.drawImage(canvasEl, 0, 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height); + + break; + case 90 : + + this.canvasEl.width = this.imageEl.OriginHeight * this.getScaleLevel(); + this.canvasEl.height = this.imageEl.OriginWidth * this.getScaleLevel(); + + if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){ + this.contextEl.drawImage(canvasEl, Math.abs(this.canvasEl.width - this.canvasEl.height), 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height); + break; + } + + this.contextEl.drawImage(canvasEl, 0, 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height); + + break; + case 180 : + + this.canvasEl.width = this.imageEl.OriginWidth * this.getScaleLevel(); + this.canvasEl.height = this.imageEl.OriginHeight * this.getScaleLevel(); + + if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){ + this.contextEl.drawImage(canvasEl, 0, Math.abs(this.canvasEl.width - this.canvasEl.height), this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height); + break; + } + + this.contextEl.drawImage(canvasEl, Math.abs(this.canvasEl.width - this.canvasEl.height), 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height); + + break; + case 270 : + + this.canvasEl.width = this.imageEl.OriginHeight * this.getScaleLevel(); + this.canvasEl.height = this.imageEl.OriginWidth * this.getScaleLevel(); + + if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){ + this.contextEl.drawImage(canvasEl, 0, 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height); + break; + } + + this.contextEl.drawImage(canvasEl, 0, Math.abs(this.canvasEl.width - this.canvasEl.height), this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height); + + break; + default : + break; + } + + this.previewEl.appendChild(this.canvasEl); + + this.setCanvasPosition(); + }, + + crop : function() + { + if(!this.canvasLoaded){ + return; + } + + var imageCanvas = document.createElement("canvas"); + + var imageContext = imageCanvas.getContext("2d"); + + imageCanvas.width = (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? this.imageEl.OriginWidth : this.imageEl.OriginHeight; + imageCanvas.height = (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? this.imageEl.OriginWidth : this.imageEl.OriginHeight; + + var center = imageCanvas.width / 2; + + imageContext.translate(center, center); + + imageContext.rotate(this.rotate * Math.PI / 180); + + imageContext.drawImage(this.imageEl, 0, 0, this.imageEl.OriginWidth, this.imageEl.OriginHeight, center * -1, center * -1, this.imageEl.OriginWidth, this.imageEl.OriginHeight); + + var canvas = document.createElement("canvas"); + + var context = canvas.getContext("2d"); + + canvas.width = this.thumbEl.getWidth() / this.getScaleLevel(); + + canvas.height = this.thumbEl.getHeight() / this.getScaleLevel(); + + switch (this.rotate) { + case 0 : + + var width = (this.thumbEl.getWidth() / this.getScaleLevel() > this.imageEl.OriginWidth) ? this.imageEl.OriginWidth : (this.thumbEl.getWidth() / this.getScaleLevel()); + var height = (this.thumbEl.getHeight() / this.getScaleLevel() > this.imageEl.OriginHeight) ? this.imageEl.OriginHeight : (this.thumbEl.getHeight() / this.getScaleLevel()); + + var x = (this.thumbEl.getLeft(true) > this.previewEl.getLeft(true)) ? 0 : ((this.previewEl.getLeft(true) - this.thumbEl.getLeft(true)) / this.getScaleLevel()); + var y = (this.thumbEl.getTop(true) > this.previewEl.getTop(true)) ? 0 : ((this.previewEl.getTop(true) - this.thumbEl.getTop(true)) / this.getScaleLevel()); + + var sx = this.thumbEl.getLeft(true) - this.previewEl.getLeft(true); + var sy = this.thumbEl.getTop(true) - this.previewEl.getTop(true); + + sx = sx < 0 ? 0 : (sx / this.getScaleLevel()); + sy = sy < 0 ? 0 : (sy / this.getScaleLevel()); + + if(canvas.width > this.outputMaxWidth) { + var scale = this.outputMaxWidth / canvas.width; + canvas.width = canvas.width * scale; + canvas.height = canvas.height * scale; + context.scale(scale, scale); + } + + context.fillStyle = 'white'; + context.fillRect(0, 0, this.thumbEl.getWidth() / this.getScaleLevel(), this.thumbEl.getHeight() / this.getScaleLevel()); + + + context.drawImage(imageCanvas, sx, sy, width, height, x, y, width, height); + + break; + case 90 : + + var width = (this.thumbEl.getWidth() / this.getScaleLevel() > this.imageEl.OriginHeight) ? this.imageEl.OriginHeight : (this.thumbEl.getWidth() / this.getScaleLevel()); + var height = (this.thumbEl.getHeight() / this.getScaleLevel() > this.imageEl.OriginWidth) ? this.imageEl.OriginWidth : (this.thumbEl.getHeight() / this.getScaleLevel()); + + var x = (this.thumbEl.getLeft(true) > this.previewEl.getLeft(true)) ? 0 : ((this.previewEl.getLeft(true) - this.thumbEl.getLeft(true)) / this.getScaleLevel()); + var y = (this.thumbEl.getTop(true) > this.previewEl.getTop(true)) ? 0 : ((this.previewEl.getTop(true) - this.thumbEl.getTop(true)) / this.getScaleLevel()); + + var targetWidth = this.minWidth - 2 * x; + var targetHeight = this.minHeight - 2 * y; + + var scale = 1; + + if((x == 0 && y == 0) || (x == 0 && y > 0)){ + scale = targetWidth / width; + } + + if(x > 0 && y == 0){ + scale = targetHeight / height; + } + + if(x > 0 && y > 0){ + scale = targetWidth / width; + + if(width < height){ + scale = targetHeight / height; + } + } + + context.scale(scale, scale); + + var sx = Math.min(this.canvasEl.width - this.thumbEl.getWidth(), this.thumbEl.getLeft(true) - this.previewEl.getLeft(true)); + var sy = Math.min(this.canvasEl.height - this.thumbEl.getHeight(), this.thumbEl.getTop(true) - this.previewEl.getTop(true)); + + sx = sx < 0 ? 0 : (sx / this.getScaleLevel()); + sy = sy < 0 ? 0 : (sy / this.getScaleLevel()); + + sx += (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? Math.abs(this.imageEl.OriginWidth - this.imageEl.OriginHeight) : 0; + + context.drawImage(imageCanvas, sx, sy, width, height, x, y, width, height); + + break; + case 180 : + + var width = (this.thumbEl.getWidth() / this.getScaleLevel() > this.imageEl.OriginWidth) ? this.imageEl.OriginWidth : (this.thumbEl.getWidth() / this.getScaleLevel()); + var height = (this.thumbEl.getHeight() / this.getScaleLevel() > this.imageEl.OriginHeight) ? this.imageEl.OriginHeight : (this.thumbEl.getHeight() / this.getScaleLevel()); + + var x = (this.thumbEl.getLeft(true) > this.previewEl.getLeft(true)) ? 0 : ((this.previewEl.getLeft(true) - this.thumbEl.getLeft(true)) / this.getScaleLevel()); + var y = (this.thumbEl.getTop(true) > this.previewEl.getTop(true)) ? 0 : ((this.previewEl.getTop(true) - this.thumbEl.getTop(true)) / this.getScaleLevel()); + + var targetWidth = this.minWidth - 2 * x; + var targetHeight = this.minHeight - 2 * y; + + var scale = 1; + + if((x == 0 && y == 0) || (x == 0 && y > 0)){ + scale = targetWidth / width; + } + + if(x > 0 && y == 0){ + scale = targetHeight / height; + } + + if(x > 0 && y > 0){ + scale = targetWidth / width; + + if(width < height){ + scale = targetHeight / height; + } + } + + context.scale(scale, scale); + + var sx = Math.min(this.canvasEl.width - this.thumbEl.getWidth(), this.thumbEl.getLeft(true) - this.previewEl.getLeft(true)); + var sy = Math.min(this.canvasEl.height - this.thumbEl.getHeight(), this.thumbEl.getTop(true) - this.previewEl.getTop(true)); + + sx = sx < 0 ? 0 : (sx / this.getScaleLevel()); + sy = sy < 0 ? 0 : (sy / this.getScaleLevel()); + + sx += (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? 0 : Math.abs(this.imageEl.OriginWidth - this.imageEl.OriginHeight); + sy += (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? Math.abs(this.imageEl.OriginWidth - this.imageEl.OriginHeight) : 0; + + context.drawImage(imageCanvas, sx, sy, width, height, x, y, width, height); + + break; + case 270 : + + var width = (this.thumbEl.getWidth() / this.getScaleLevel() > this.imageEl.OriginHeight) ? this.imageEl.OriginHeight : (this.thumbEl.getWidth() / this.getScaleLevel()); + var height = (this.thumbEl.getHeight() / this.getScaleLevel() > this.imageEl.OriginWidth) ? this.imageEl.OriginWidth : (this.thumbEl.getHeight() / this.getScaleLevel()); + + var x = (this.thumbEl.getLeft(true) > this.previewEl.getLeft(true)) ? 0 : ((this.previewEl.getLeft(true) - this.thumbEl.getLeft(true)) / this.getScaleLevel()); + var y = (this.thumbEl.getTop(true) > this.previewEl.getTop(true)) ? 0 : ((this.previewEl.getTop(true) - this.thumbEl.getTop(true)) / this.getScaleLevel()); + + var targetWidth = this.minWidth - 2 * x; + var targetHeight = this.minHeight - 2 * y; + + var scale = 1; + + if((x == 0 && y == 0) || (x == 0 && y > 0)){ + scale = targetWidth / width; + } + + if(x > 0 && y == 0){ + scale = targetHeight / height; + } + + if(x > 0 && y > 0){ + scale = targetWidth / width; + + if(width < height){ + scale = targetHeight / height; + } + } + + context.scale(scale, scale); + var sx = Math.min(this.canvasEl.width - this.thumbEl.getWidth(), this.thumbEl.getLeft(true) - this.previewEl.getLeft(true)); + var sy = Math.min(this.canvasEl.height - this.thumbEl.getHeight(), this.thumbEl.getTop(true) - this.previewEl.getTop(true)); + + sx = sx < 0 ? 0 : (sx / this.getScaleLevel()); + sy = sy < 0 ? 0 : (sy / this.getScaleLevel()); + + sy += (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? 0 : Math.abs(this.imageEl.OriginWidth - this.imageEl.OriginHeight); + + context.drawImage(imageCanvas, sx, sy, width, height, x, y, width, height); + + break; + default : + break; + } + + this.cropData = canvas.toDataURL(this.cropType); + + if(this.fireEvent('crop', this, this.cropData) !== false){ + this.process(this.file, this.cropData); + } + + return; + + }, + + setThumbBoxSize : function() + { + var width, height; + + if(this.isDocument && typeof(this.imageEl) != 'undefined'){ + width = (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? Math.max(this.minWidth, this.minHeight) : Math.min(this.minWidth, this.minHeight); + height = (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? Math.min(this.minWidth, this.minHeight) : Math.max(this.minWidth, this.minHeight); + + this.minWidth = width; + this.minHeight = height; + + if(this.rotate == 90 || this.rotate == 270){ + this.minWidth = height; + this.minHeight = width; + } + } + + height = this.windowSize; + width = Math.ceil(this.minWidth * height / this.minHeight); + + if(this.minWidth > this.minHeight){ + width = this.windowSize; + height = Math.ceil(this.minHeight * width / this.minWidth); + } + + this.thumbEl.setStyle({ + width : width + 'px', + height : height + 'px' + }); + + return; + + }, + + setThumbBoxPosition : function() + { + var x = Math.ceil((this.bodyEl.getWidth() - this.thumbEl.getWidth()) / 2 ); + var y = Math.ceil((this.bodyEl.getHeight() - this.thumbEl.getHeight()) / 2); + + this.thumbEl.setLeft(x); + this.thumbEl.setTop(y); + + }, + + baseRotateLevel : function() + { + this.baseRotate = 1; + + if( + typeof(this.exif) != 'undefined' && + typeof(this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']]) != 'undefined' && + [1, 3, 6, 8].indexOf(this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']]) != -1 + ){ + this.baseRotate = this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']]; + } + + this.rotate = Roo.dialog.UploadCropbox['Orientation'][this.baseRotate]; + + }, + + baseScaleLevel : function() + { + var width, height; + + if(this.isDocument){ + + if(this.baseRotate == 6 || this.baseRotate == 8){ + + height = this.thumbEl.getHeight(); + this.baseScale = height / this.imageEl.OriginWidth; + + if(this.imageEl.OriginHeight * this.baseScale > this.thumbEl.getWidth()){ + width = this.thumbEl.getWidth(); + this.baseScale = width / this.imageEl.OriginHeight; + } + + return; + } + + height = this.thumbEl.getHeight(); + this.baseScale = height / this.imageEl.OriginHeight; + + if(this.imageEl.OriginWidth * this.baseScale > this.thumbEl.getWidth()){ + width = this.thumbEl.getWidth(); + this.baseScale = width / this.imageEl.OriginWidth; + } + + return; + } + + if(this.baseRotate == 6 || this.baseRotate == 8){ + + width = this.thumbEl.getHeight(); + this.baseScale = width / this.imageEl.OriginHeight; + + if(this.imageEl.OriginHeight * this.baseScale < this.thumbEl.getWidth()){ + height = this.thumbEl.getWidth(); + this.baseScale = height / this.imageEl.OriginHeight; + } + + if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){ + height = this.thumbEl.getWidth(); + this.baseScale = height / this.imageEl.OriginHeight; + + if(this.imageEl.OriginWidth * this.baseScale < this.thumbEl.getHeight()){ + width = this.thumbEl.getHeight(); + this.baseScale = width / this.imageEl.OriginWidth; + } + } + + return; + } + + width = this.thumbEl.getWidth(); + this.baseScale = width / this.imageEl.OriginWidth; + + if(this.imageEl.OriginHeight * this.baseScale < this.thumbEl.getHeight()){ + height = this.thumbEl.getHeight(); + this.baseScale = height / this.imageEl.OriginHeight; + } + + if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){ + + height = this.thumbEl.getHeight(); + this.baseScale = height / this.imageEl.OriginHeight; + + if(this.imageEl.OriginWidth * this.baseScale < this.thumbEl.getWidth()){ + width = this.thumbEl.getWidth(); + this.baseScale = width / this.imageEl.OriginWidth; + } + + } + + if(this.imageEl.OriginWidth < this.minWidth || this.imageEl.OriginHeight < this.minHeight) { + this.baseScale = width / this.minWidth; + } + + return; + }, + + getScaleLevel : function() + { + return this.baseScale * Math.pow(1.02, this.scale); + }, + + onTouchStart : function(e) + { + if(!this.canvasLoaded){ + this.beforeSelectFile(e); + return; + } + + var touches = e.browserEvent.touches; + + if(!touches){ + return; + } + + if(touches.length == 1){ + this.onMouseDown(e); + return; + } + + if(touches.length != 2){ + return; + } + + var coords = []; + + for(var i = 0, finger; finger = touches[i]; i++){ + coords.push(finger.pageX, finger.pageY); + } + + var x = Math.pow(coords[0] - coords[2], 2); + var y = Math.pow(coords[1] - coords[3], 2); + + this.startDistance = Math.sqrt(x + y); + + this.startScale = this.scale; + + this.pinching = true; + this.dragable = false; + + }, + + onTouchMove : function(e) + { + if(!this.pinching && !this.dragable){ + return; + } + + var touches = e.browserEvent.touches; + + if(!touches){ + return; + } + + if(this.dragable){ + this.onMouseMove(e); + return; + } + + var coords = []; + + for(var i = 0, finger; finger = touches[i]; i++){ + coords.push(finger.pageX, finger.pageY); + } + + var x = Math.pow(coords[0] - coords[2], 2); + var y = Math.pow(coords[1] - coords[3], 2); + + this.endDistance = Math.sqrt(x + y); + + this.scale = this.startScale + Math.floor(Math.log(this.endDistance / this.startDistance) / Math.log(1.1)); + + if(!this.zoomable()){ + this.scale = this.startScale; + return; + } + + this.draw(); + + }, + + onTouchEnd : function(e) + { + this.pinching = false; + this.dragable = false; + + }, + + process : function(file, crop) + { + if(this.loadMask){ + this.maskEl.mask(this.loadingText); + } + + this.xhr = new XMLHttpRequest(); + + file.xhr = this.xhr; + + this.xhr.open(this.method, this.url, true); + + var headers = { + "Accept": "application/json", + "Cache-Control": "no-cache", + "X-Requested-With": "XMLHttpRequest" + }; + + for (var headerName in headers) { + var headerValue = headers[headerName]; + if (headerValue) { + this.xhr.setRequestHeader(headerName, headerValue); + } + } + + var _this = this; + + this.xhr.onload = function() + { + _this.xhrOnLoad(_this.xhr); + } + + this.xhr.onerror = function() + { + _this.xhrOnError(_this.xhr); + } + + var formData = new FormData(); + + formData.append('returnHTML', 'NO'); + + if(crop){ + formData.append('crop', crop); + var blobBin = atob(crop.split(',')[1]); + var array = []; + for(var i = 0; i < blobBin.length; i++) { + array.push(blobBin.charCodeAt(i)); + } + var croppedFile =new Blob([new Uint8Array(array)], {type: this.cropType}); + formData.append(this.paramName, croppedFile, file.name); + } + + if(typeof(file.filename) != 'undefined'){ + formData.append('filename', file.filename); + } + + if(typeof(file.mimetype) != 'undefined'){ + formData.append('mimetype', file.mimetype); + } + + if(this.fireEvent('arrange', this, formData) != false){ + this.xhr.send(formData); + }; + }, + + xhrOnLoad : function(xhr) + { + if(this.loadMask){ + this.maskEl.unmask(); + } + + if (xhr.readyState !== 4) { + this.fireEvent('exception', this, xhr); + return; + } + + var response = Roo.decode(xhr.responseText); + + if(!response.success){ + this.fireEvent('exception', this, xhr); + return; + } + + var response = Roo.decode(xhr.responseText); + + this.fireEvent('upload', this, response); + + }, + + xhrOnError : function() + { + if(this.loadMask){ + this.maskEl.unmask(); + } + + Roo.log('xhr on error'); + + var response = Roo.decode(xhr.responseText); + + Roo.log(response); + + }, + + prepare : function(file) + { + if(this.loadMask){ + this.maskEl.mask(this.loadingText); + } + + this.file = false; + this.exif = {}; + + if(typeof(file) === 'string'){ + this.loadCanvas(file); + return; + } + + if(!file || !this.urlAPI){ + return; + } + + this.file = file; + if(typeof(file.type) != 'undefined' && file.type.length != 0) { + this.cropType = file.type; + } + + var _this = this; + + if(this.fireEvent('prepare', this, this.file) != false){ + + var reader = new FileReader(); + + reader.onload = function (e) { + if (e.target.error) { + Roo.log(e.target.error); + return; + } + + var buffer = e.target.result, + dataView = new DataView(buffer), + offset = 2, + maxOffset = dataView.byteLength - 4, + markerBytes, + markerLength; + + if (dataView.getUint16(0) === 0xffd8) { + while (offset < maxOffset) { + markerBytes = dataView.getUint16(offset); + + if ((markerBytes >= 0xffe0 && markerBytes <= 0xffef) || markerBytes === 0xfffe) { + markerLength = dataView.getUint16(offset + 2) + 2; + if (offset + markerLength > dataView.byteLength) { + Roo.log('Invalid meta data: Invalid segment size.'); + break; + } + + if(markerBytes == 0xffe1){ + _this.parseExifData( + dataView, + offset, + markerLength + ); + } + + offset += markerLength; + + continue; + } + + break; + } + + } + + var url = _this.urlAPI.createObjectURL(_this.file); + + _this.loadCanvas(url); + + return; + } + + reader.readAsArrayBuffer(this.file); + + } + + }, + + parseExifData : function(dataView, offset, length) + { + var tiffOffset = offset + 10, + littleEndian, + dirOffset; + + if (dataView.getUint32(offset + 4) !== 0x45786966) { + // No Exif data, might be XMP data instead + return; + } + + // Check for the ASCII code for "Exif" (0x45786966): + if (dataView.getUint32(offset + 4) !== 0x45786966) { + // No Exif data, might be XMP data instead + return; + } + if (tiffOffset + 8 > dataView.byteLength) { + Roo.log('Invalid Exif data: Invalid segment size.'); + return; + } + // Check for the two null bytes: + if (dataView.getUint16(offset + 8) !== 0x0000) { + Roo.log('Invalid Exif data: Missing byte alignment offset.'); + return; + } + // Check the byte alignment: + switch (dataView.getUint16(tiffOffset)) { + case 0x4949: + littleEndian = true; + break; + case 0x4D4D: + littleEndian = false; + break; + default: + Roo.log('Invalid Exif data: Invalid byte alignment marker.'); + return; + } + // Check for the TIFF tag marker (0x002A): + if (dataView.getUint16(tiffOffset + 2, littleEndian) !== 0x002A) { + Roo.log('Invalid Exif data: Missing TIFF marker.'); + return; + } + // Retrieve the directory offset bytes, usually 0x00000008 or 8 decimal: + dirOffset = dataView.getUint32(tiffOffset + 4, littleEndian); + + this.parseExifTags( + dataView, + tiffOffset, + tiffOffset + dirOffset, + littleEndian + ); + }, + + parseExifTags : function(dataView, tiffOffset, dirOffset, littleEndian) + { + var tagsNumber, + dirEndOffset, + i; + if (dirOffset + 6 > dataView.byteLength) { + Roo.log('Invalid Exif data: Invalid directory offset.'); + return; + } + tagsNumber = dataView.getUint16(dirOffset, littleEndian); + dirEndOffset = dirOffset + 2 + 12 * tagsNumber; + if (dirEndOffset + 4 > dataView.byteLength) { + Roo.log('Invalid Exif data: Invalid directory size.'); + return; + } + for (i = 0; i < tagsNumber; i += 1) { + this.parseExifTag( + dataView, + tiffOffset, + dirOffset + 2 + 12 * i, // tag offset + littleEndian + ); + } + // Return the offset to the next directory: + return dataView.getUint32(dirEndOffset, littleEndian); + }, + + parseExifTag : function (dataView, tiffOffset, offset, littleEndian) + { + var tag = dataView.getUint16(offset, littleEndian); + + this.exif[tag] = this.getExifValue( + dataView, + tiffOffset, + offset, + dataView.getUint16(offset + 2, littleEndian), // tag type + dataView.getUint32(offset + 4, littleEndian), // tag length + littleEndian + ); + }, + + getExifValue : function (dataView, tiffOffset, offset, type, length, littleEndian) + { + var tagType = Roo.dialog.UploadCropbox.exifTagTypes[type], + tagSize, + dataOffset, + values, + i, + str, + c; + + if (!tagType) { + Roo.log('Invalid Exif data: Invalid tag type.'); + return; + } + + tagSize = tagType.size * length; + // Determine if the value is contained in the dataOffset bytes, + // or if the value at the dataOffset is a pointer to the actual data: + dataOffset = tagSize > 4 ? + tiffOffset + dataView.getUint32(offset + 8, littleEndian) : (offset + 8); + if (dataOffset + tagSize > dataView.byteLength) { + Roo.log('Invalid Exif data: Invalid data offset.'); + return; + } + if (length === 1) { + return tagType.getValue(dataView, dataOffset, littleEndian); + } + values = []; + for (i = 0; i < length; i += 1) { + values[i] = tagType.getValue(dataView, dataOffset + i * tagType.size, littleEndian); + } + + if (tagType.ascii) { + str = ''; + // Concatenate the chars: + for (i = 0; i < values.length; i += 1) { + c = values[i]; + // Ignore the terminating NULL byte(s): + if (c === '\u0000') { + break; + } + str += c; + } + return str; + } + return values; + } + +}); + +Roo.apply(Roo.dialog.UploadCropbox, { + tags : { + 'Orientation': 0x0112 + }, + + Orientation: { + 1: 0, //'top-left', +// 2: 'top-right', + 3: 180, //'bottom-right', +// 4: 'bottom-left', +// 5: 'left-top', + 6: 90, //'right-top', +// 7: 'right-bottom', + 8: 270 //'left-bottom' + }, + + exifTagTypes : { + // byte, 8-bit unsigned int: + 1: { + getValue: function (dataView, dataOffset) { + return dataView.getUint8(dataOffset); + }, + size: 1 + }, + // ascii, 8-bit byte: + 2: { + getValue: function (dataView, dataOffset) { + return String.fromCharCode(dataView.getUint8(dataOffset)); + }, + size: 1, + ascii: true + }, + // short, 16 bit int: + 3: { + getValue: function (dataView, dataOffset, littleEndian) { + return dataView.getUint16(dataOffset, littleEndian); + }, + size: 2 + }, + // long, 32 bit int: + 4: { + getValue: function (dataView, dataOffset, littleEndian) { + return dataView.getUint32(dataOffset, littleEndian); + }, + size: 4 + }, + // rational = two long values, first is numerator, second is denominator: + 5: { + getValue: function (dataView, dataOffset, littleEndian) { + return dataView.getUint32(dataOffset, littleEndian) / + dataView.getUint32(dataOffset + 4, littleEndian); + }, + size: 8 + }, + // slong, 32 bit signed int: + 9: { + getValue: function (dataView, dataOffset, littleEndian) { + return dataView.getInt32(dataOffset, littleEndian); + }, + size: 4 + }, + // srational, two slongs, first is numerator, second is denominator: + 10: { + getValue: function (dataView, dataOffset, littleEndian) { + return dataView.getInt32(dataOffset, littleEndian) / + dataView.getInt32(dataOffset + 4, littleEndian); + }, + size: 8 + } + }, + + footer : { + STANDARD : [ + { + tag : 'div', + cls : 'btn-group roo-upload-cropbox-rotate-left', + action : 'rotate-left', + cn : [ + { + tag : 'button', + cls : 'btn btn-default', + html : '' + } + ] + }, + { + tag : 'div', + cls : 'btn-group roo-upload-cropbox-picture', + action : 'picture', + cn : [ + { + tag : 'button', + cls : 'btn btn-default', + html : '' + } + ] + }, + { + tag : 'div', + cls : 'btn-group roo-upload-cropbox-rotate-right', + action : 'rotate-right', + cn : [ + { + tag : 'button', + cls : 'btn btn-default', + html : '' + } + ] + } + ], + DOCUMENT : [ + { + tag : 'div', + cls : 'btn-group roo-upload-cropbox-rotate-left', + action : 'rotate-left', + cn : [ + { + tag : 'button', + cls : 'btn btn-default', + html : '' + } + ] + }, + { + tag : 'div', + cls : 'btn-group roo-upload-cropbox-download', + action : 'download', + cn : [ + { + tag : 'button', + cls : 'btn btn-default', + html : '' + } + ] + }, + { + tag : 'div', + cls : 'btn-group roo-upload-cropbox-crop', + action : 'crop', + cn : [ + { + tag : 'button', + cls : 'btn btn-default', + html : '' + } + ] + }, + { + tag : 'div', + cls : 'btn-group roo-upload-cropbox-trash', + action : 'trash', + cn : [ + { + tag : 'button', + cls : 'btn btn-default', + html : '' + } + ] + }, + { + tag : 'div', + cls : 'btn-group roo-upload-cropbox-rotate-right', + action : 'rotate-right', + cn : [ + { + tag : 'button', + cls : 'btn btn-default', + html : '' + } + ] + } + ], + ROTATOR : [ + { + tag : 'div', + cls : 'btn-group roo-upload-cropbox-rotate-left', + action : 'rotate-left', + cn : [ + { + tag : 'button', + cls : 'btn btn-default', + html : '' + } + ] + }, + { + tag : 'div', + cls : 'btn-group roo-upload-cropbox-rotate-right', + action : 'rotate-right', + cn : [ + { + tag : 'button', + cls : 'btn btn-default', + html : '' + } + ] + } + ] + } +}); diff --git a/Roo/dialog/namespace.js b/Roo/dialog/namespace.js new file mode 100644 index 0000000000..b04737593a --- /dev/null +++ b/Roo/dialog/namespace.js @@ -0,0 +1 @@ +Roo.dialog = {}; \ No newline at end of file diff --git a/buildSDK/dependancy_ui.txt b/buildSDK/dependancy_ui.txt index 5a8e5a9ac5..f89656e412 100644 --- a/buildSDK/dependancy_ui.txt +++ b/buildSDK/dependancy_ui.txt @@ -197,3 +197,6 @@ Roo.XTemplate // is this ready yet? - is it used? // Roo.Login + +Roo.dialog.namespace +Roo.dialog.UploadCropbox diff --git a/css/alert.css b/css/alert.css new file mode 100644 index 0000000000..0cc7751f02 --- /dev/null +++ b/css/alert.css @@ -0,0 +1,75 @@ +.alert { + padding: 15px; + margin-bottom: 20px; + border: 1px solid transparent; + border-radius: 4px; +} +.alert h4 { + margin-top: 0; + color: inherit; +} +.alert .alert-link { + font-weight: bold; +} +.alert > p, +.alert > ul { + margin-bottom: 0; +} +.alert > p + p { + margin-top: 5px; +} +.alert-dismissable, +.alert-dismissible { + padding-right: 35px; +} +.alert-dismissable .close, +.alert-dismissible .close { + position: relative; + top: -2px; + right: -21px; + color: inherit; +} +.alert-success { + background-color: #dff0d8; + border-color: #d6e9c6; + color: #3c763d; +} +.alert-success hr { + border-top-color: #c9e2b3; +} +.alert-success .alert-link { + color: #2b542c; +} +.alert-info { + background-color: #d9edf7; + border-color: #bce8f1; + color: #31708f; +} +.alert-info hr { + border-top-color: #a6e1ec; +} +.alert-info .alert-link { + color: #245269; +} +.alert-warning { + background-color: #fcf8e3; + border-color: #faebcc; + color: #8a6d3b; +} +.alert-warning hr { + border-top-color: #f7e1b5; +} +.alert-warning .alert-link { + color: #66512c; +} +.alert-danger { + background-color: #f2dede; + border-color: #ebccd1; + color: #a94442; +} +.alert-danger hr { + border-top-color: #e4b9c0; +} +.alert-danger .alert-link { + color: #843534; +} \ No newline at end of file diff --git a/css/button-groups.css b/css/button-groups.css new file mode 100644 index 0000000000..b725faf99b --- /dev/null +++ b/css/button-groups.css @@ -0,0 +1,171 @@ +.btn-group, +.btn-group-vertical { + position: relative; + display: inline-block; + vertical-align: middle; +} +.btn-group > .btn, +.btn-group-vertical > .btn { + position: relative; + float: left; +} +.btn-group > .btn:hover, +.btn-group-vertical > .btn:hover, +.btn-group > .btn:focus, +.btn-group-vertical > .btn:focus, +.btn-group > .btn:active, +.btn-group-vertical > .btn:active, +.btn-group > .btn.active, +.btn-group-vertical > .btn.active { + z-index: 2; +} +.btn-group .btn + .btn, +.btn-group .btn + .btn-group, +.btn-group .btn-group + .btn, +.btn-group .btn-group + .btn-group { + margin-left: -1px; +} +.btn-toolbar { + margin-left: -5px; +} +.btn-toolbar .btn, +.btn-toolbar .btn-group, +.btn-toolbar .input-group { + float: left; +} +.btn-toolbar > .btn, +.btn-toolbar > .btn-group, +.btn-toolbar > .input-group { + margin-left: 5px; +} +.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { + border-radius: 0; +} +.btn-group > .btn:first-child { + margin-left: 0; +} +.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) { + border-bottom-right-radius: 0; + border-top-right-radius: 0; +} +.btn-group > .btn:last-child:not(:first-child), +.btn-group > .dropdown-toggle:not(:first-child) { + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} +.btn-group > .btn-group { + float: left; +} +.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} +.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child, +.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle { + border-bottom-right-radius: 0; + border-top-right-radius: 0; +} +.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child { + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} +.btn-group .dropdown-toggle:active, +.btn-group.open .dropdown-toggle { + outline: 0; +} +.btn-group > .btn + .dropdown-toggle { + padding-left: 8px; + padding-right: 8px; +} +.btn-group > .btn-lg + .dropdown-toggle { + padding-left: 12px; + padding-right: 12px; +} +.btn-group.open .dropdown-toggle { + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); +} +.btn-group.open .dropdown-toggle.btn-link { + -webkit-box-shadow: none; + box-shadow: none; +} +.btn .caret { + margin-left: 0; +} +.btn-lg .caret { + border-width: 5px 5px 0; + border-bottom-width: 0; +} +.dropup .btn-lg .caret { + border-width: 0 5px 5px; +} +.btn-group-vertical > .btn, +.btn-group-vertical > .btn-group, +.btn-group-vertical > .btn-group > .btn { + display: block; + float: none; + width: 100%; + max-width: 100%; +} +.btn-group-vertical > .btn-group > .btn { + float: none; +} +.btn-group-vertical > .btn + .btn, +.btn-group-vertical > .btn + .btn-group, +.btn-group-vertical > .btn-group + .btn, +.btn-group-vertical > .btn-group + .btn-group { + margin-top: -1px; + margin-left: 0; +} +.btn-group-vertical > .btn:not(:first-child):not(:last-child) { + border-radius: 0; +} +.btn-group-vertical > .btn:first-child:not(:last-child) { + border-top-right-radius: 4px; + border-top-left-radius: 4px; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group-vertical > .btn:last-child:not(:first-child) { + border-top-right-radius: 0; + border-top-left-radius: 0; + border-bottom-right-radius: 4px; + border-bottom-left-radius: 4px; +} +.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} +.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child, +.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child { + border-top-right-radius: 0; + border-top-left-radius: 0; +} +.btn-group-justified { + display: table; + width: 100%; + table-layout: fixed; + border-collapse: separate; +} +.btn-group-justified > .btn, +.btn-group-justified > .btn-group { + float: none; + display: table-cell; + width: 1%; +} +.btn-group-justified > .btn-group .btn { + width: 100%; +} +.btn-group-justified > .btn-group .dropdown-menu { + left: auto; +} +[data-toggle="buttons"] > .btn input[type="radio"], +[data-toggle="buttons"] > .btn-group > .btn input[type="radio"], +[data-toggle="buttons"] > .btn input[type="checkbox"], +[data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] { + position: absolute; + clip: rect(0, 0, 0, 0); + pointer-events: none; +} \ No newline at end of file diff --git a/css/buttons.css b/css/buttons.css new file mode 100644 index 0000000000..42ec098feb --- /dev/null +++ b/css/buttons.css @@ -0,0 +1,463 @@ +.btn { + display: inline-block; + margin-bottom: 0; + font-weight: normal; + text-align: center; + vertical-align: middle; + touch-action: manipulation; + cursor: pointer; + background-image: none; + border: 1px solid transparent; + white-space: nowrap; + padding: 6px 12px; + font-size: 14px; + line-height: 1.42857143; + border-radius: 4px; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} +.btn:focus, +.btn:active:focus, +.btn.active:focus, +.btn.focus, +.btn:active.focus, +.btn.active.focus { + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +.btn:hover, +.btn:focus, +.btn.focus { + color: #333333; + text-decoration: none; +} +.btn:active, +.btn.active { + outline: 0; + background-image: none; + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); +} +.btn.disabled, +.btn[disabled], +fieldset[disabled] .btn { + cursor: not-allowed; + opacity: 0.65; + filter: alpha(opacity=65); + -webkit-box-shadow: none; + box-shadow: none; +} +a.btn.disabled, +fieldset[disabled] a.btn { + pointer-events: none; +} +.btn-default { + color: #333333; + background-color: #ffffff; + border-color: #cccccc; +} +.btn-default:focus, +.btn-default.focus { + color: #333333; + background-color: #e6e6e6; + border-color: #8c8c8c; +} +.btn-default:hover { + color: #333333; + background-color: #e6e6e6; + border-color: #adadad; +} +.btn-default:active, +.btn-default.active, +.open > .dropdown-toggle.btn-default { + color: #333333; + background-color: #e6e6e6; + border-color: #adadad; +} +.btn-default:active:hover, +.btn-default.active:hover, +.open > .dropdown-toggle.btn-default:hover, +.btn-default:active:focus, +.btn-default.active:focus, +.open > .dropdown-toggle.btn-default:focus, +.btn-default:active.focus, +.btn-default.active.focus, +.open > .dropdown-toggle.btn-default.focus { + color: #333333; + background-color: #d4d4d4; + border-color: #8c8c8c; +} +.btn-default:active, +.btn-default.active, +.open > .dropdown-toggle.btn-default { + background-image: none; +} +.btn-default.disabled:hover, +.btn-default[disabled]:hover, +fieldset[disabled] .btn-default:hover, +.btn-default.disabled:focus, +.btn-default[disabled]:focus, +fieldset[disabled] .btn-default:focus, +.btn-default.disabled.focus, +.btn-default[disabled].focus, +fieldset[disabled] .btn-default.focus { + background-color: #ffffff; + border-color: #cccccc; +} +.btn-default .badge { + color: #ffffff; + background-color: #333333; +} +.btn-primary { + color: #ffffff; + background-color: #337ab7; + border-color: #2e6da4; +} +.btn-primary:focus, +.btn-primary.focus { + color: #ffffff; + background-color: #286090; + border-color: #122b40; +} +.btn-primary:hover { + color: #ffffff; + background-color: #286090; + border-color: #204d74; +} +.btn-primary:active, +.btn-primary.active, +.open > .dropdown-toggle.btn-primary { + color: #ffffff; + background-color: #286090; + border-color: #204d74; +} +.btn-primary:active:hover, +.btn-primary.active:hover, +.open > .dropdown-toggle.btn-primary:hover, +.btn-primary:active:focus, +.btn-primary.active:focus, +.open > .dropdown-toggle.btn-primary:focus, +.btn-primary:active.focus, +.btn-primary.active.focus, +.open > .dropdown-toggle.btn-primary.focus { + color: #ffffff; + background-color: #204d74; + border-color: #122b40; +} +.btn-primary:active, +.btn-primary.active, +.open > .dropdown-toggle.btn-primary { + background-image: none; +} +.btn-primary.disabled:hover, +.btn-primary[disabled]:hover, +fieldset[disabled] .btn-primary:hover, +.btn-primary.disabled:focus, +.btn-primary[disabled]:focus, +fieldset[disabled] .btn-primary:focus, +.btn-primary.disabled.focus, +.btn-primary[disabled].focus, +fieldset[disabled] .btn-primary.focus { + background-color: #337ab7; + border-color: #2e6da4; +} +.btn-primary .badge { + color: #337ab7; + background-color: #ffffff; +} +.btn-success { + color: #ffffff; + background-color: #5cb85c; + border-color: #4cae4c; +} +.btn-success:focus, +.btn-success.focus { + color: #ffffff; + background-color: #449d44; + border-color: #255625; +} +.btn-success:hover { + color: #ffffff; + background-color: #449d44; + border-color: #398439; +} +.btn-success:active, +.btn-success.active, +.open > .dropdown-toggle.btn-success { + color: #ffffff; + background-color: #449d44; + border-color: #398439; +} +.btn-success:active:hover, +.btn-success.active:hover, +.open > .dropdown-toggle.btn-success:hover, +.btn-success:active:focus, +.btn-success.active:focus, +.open > .dropdown-toggle.btn-success:focus, +.btn-success:active.focus, +.btn-success.active.focus, +.open > .dropdown-toggle.btn-success.focus { + color: #ffffff; + background-color: #398439; + border-color: #255625; +} +.btn-success:active, +.btn-success.active, +.open > .dropdown-toggle.btn-success { + background-image: none; +} +.btn-success.disabled:hover, +.btn-success[disabled]:hover, +fieldset[disabled] .btn-success:hover, +.btn-success.disabled:focus, +.btn-success[disabled]:focus, +fieldset[disabled] .btn-success:focus, +.btn-success.disabled.focus, +.btn-success[disabled].focus, +fieldset[disabled] .btn-success.focus { + background-color: #5cb85c; + border-color: #4cae4c; +} +.btn-success .badge { + color: #5cb85c; + background-color: #ffffff; +} +.btn-info { + color: #ffffff; + background-color: #5bc0de; + border-color: #46b8da; +} +.btn-info:focus, +.btn-info.focus { + color: #ffffff; + background-color: #31b0d5; + border-color: #1b6d85; +} +.btn-info:hover { + color: #ffffff; + background-color: #31b0d5; + border-color: #269abc; +} +.btn-info:active, +.btn-info.active, +.open > .dropdown-toggle.btn-info { + color: #ffffff; + background-color: #31b0d5; + border-color: #269abc; +} +.btn-info:active:hover, +.btn-info.active:hover, +.open > .dropdown-toggle.btn-info:hover, +.btn-info:active:focus, +.btn-info.active:focus, +.open > .dropdown-toggle.btn-info:focus, +.btn-info:active.focus, +.btn-info.active.focus, +.open > .dropdown-toggle.btn-info.focus { + color: #ffffff; + background-color: #269abc; + border-color: #1b6d85; +} +.btn-info:active, +.btn-info.active, +.open > .dropdown-toggle.btn-info { + background-image: none; +} +.btn-info.disabled:hover, +.btn-info[disabled]:hover, +fieldset[disabled] .btn-info:hover, +.btn-info.disabled:focus, +.btn-info[disabled]:focus, +fieldset[disabled] .btn-info:focus, +.btn-info.disabled.focus, +.btn-info[disabled].focus, +fieldset[disabled] .btn-info.focus { + background-color: #5bc0de; + border-color: #46b8da; +} +.btn-info .badge { + color: #5bc0de; + background-color: #ffffff; +} +.btn-warning { + color: #ffffff; + background-color: #f0ad4e; + border-color: #eea236; +} +.btn-warning:focus, +.btn-warning.focus { + color: #ffffff; + background-color: #ec971f; + border-color: #985f0d; +} +.btn-warning:hover { + color: #ffffff; + background-color: #ec971f; + border-color: #d58512; +} +.btn-warning:active, +.btn-warning.active, +.open > .dropdown-toggle.btn-warning { + color: #ffffff; + background-color: #ec971f; + border-color: #d58512; +} +.btn-warning:active:hover, +.btn-warning.active:hover, +.open > .dropdown-toggle.btn-warning:hover, +.btn-warning:active:focus, +.btn-warning.active:focus, +.open > .dropdown-toggle.btn-warning:focus, +.btn-warning:active.focus, +.btn-warning.active.focus, +.open > .dropdown-toggle.btn-warning.focus { + color: #ffffff; + background-color: #d58512; + border-color: #985f0d; +} +.btn-warning:active, +.btn-warning.active, +.open > .dropdown-toggle.btn-warning { + background-image: none; +} +.btn-warning.disabled:hover, +.btn-warning[disabled]:hover, +fieldset[disabled] .btn-warning:hover, +.btn-warning.disabled:focus, +.btn-warning[disabled]:focus, +fieldset[disabled] .btn-warning:focus, +.btn-warning.disabled.focus, +.btn-warning[disabled].focus, +fieldset[disabled] .btn-warning.focus { + background-color: #f0ad4e; + border-color: #eea236; +} +.btn-warning .badge { + color: #f0ad4e; + background-color: #ffffff; +} +.btn-danger { + color: #ffffff; + background-color: #d9534f; + border-color: #d43f3a; +} +.btn-danger:focus, +.btn-danger.focus { + color: #ffffff; + background-color: #c9302c; + border-color: #761c19; +} +.btn-danger:hover { + color: #ffffff; + background-color: #c9302c; + border-color: #ac2925; +} +.btn-danger:active, +.btn-danger.active, +.open > .dropdown-toggle.btn-danger { + color: #ffffff; + background-color: #c9302c; + border-color: #ac2925; +} +.btn-danger:active:hover, +.btn-danger.active:hover, +.open > .dropdown-toggle.btn-danger:hover, +.btn-danger:active:focus, +.btn-danger.active:focus, +.open > .dropdown-toggle.btn-danger:focus, +.btn-danger:active.focus, +.btn-danger.active.focus, +.open > .dropdown-toggle.btn-danger.focus { + color: #ffffff; + background-color: #ac2925; + border-color: #761c19; +} +.btn-danger:active, +.btn-danger.active, +.open > .dropdown-toggle.btn-danger { + background-image: none; +} +.btn-danger.disabled:hover, +.btn-danger[disabled]:hover, +fieldset[disabled] .btn-danger:hover, +.btn-danger.disabled:focus, +.btn-danger[disabled]:focus, +fieldset[disabled] .btn-danger:focus, +.btn-danger.disabled.focus, +.btn-danger[disabled].focus, +fieldset[disabled] .btn-danger.focus { + background-color: #d9534f; + border-color: #d43f3a; +} +.btn-danger .badge { + color: #d9534f; + background-color: #ffffff; +} +.btn-link { + color: #337ab7; + font-weight: normal; + border-radius: 0; +} +.btn-link, +.btn-link:active, +.btn-link.active, +.btn-link[disabled], +fieldset[disabled] .btn-link { + background-color: transparent; + -webkit-box-shadow: none; + box-shadow: none; +} +.btn-link, +.btn-link:hover, +.btn-link:focus, +.btn-link:active { + border-color: transparent; +} +.btn-link:hover, +.btn-link:focus { + color: #23527c; + text-decoration: underline; + background-color: transparent; +} +.btn-link[disabled]:hover, +fieldset[disabled] .btn-link:hover, +.btn-link[disabled]:focus, +fieldset[disabled] .btn-link:focus { + color: #777777; + text-decoration: none; +} +.btn-lg, +.btn-group-lg > .btn { + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; + border-radius: 6px; +} +.btn-sm, +.btn-group-sm > .btn { + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +.btn-xs, +.btn-group-xs > .btn { + padding: 1px 5px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +.btn-block { + display: block; + width: 100%; +} +.btn-block + .btn-block { + margin-top: 5px; +} +input[type="submit"].btn-block, +input[type="reset"].btn-block, +input[type="button"].btn-block { + width: 100%; +} \ No newline at end of file diff --git a/css/roojs-debug.css b/css/roojs-debug.css index dd07311e1b..0263f35a8e 100644 --- a/css/roojs-debug.css +++ b/css/roojs-debug.css @@ -29,3 +29,9 @@ @import url("inline-editor.css"); @import url("undoreset.css"); + +/* css for Roo.dialog.UploadCropbox */ +@import url("alert.css"); +@import url("buttons.css"); +@import url("button-groups.css"); +@import url("upload-cropbox.css"); diff --git a/css/roojs.css b/css/roojs.css index 0e75e04f12..48adbba559 100644 --- a/css/roojs.css +++ b/css/roojs.css @@ -16,3 +16,7 @@ x-date{background:white;padding:2px;border:1px solid gray;z-index:12001;-moz-out .x-form-daypick-item td div{width:30px;text-align:center;}.x-form-daypick-icons td img{background:url(../images/default/menu/chk-sprite.gif) no-repeat 0 0;width:16px;height:16px;margin:0;margin-left:5px;cursor:pointer;}.x-form-daypick-icons td img.x-menu-item-checked{background-position:0 -16px;} .x-html-editor-wrap{background-color:#fff;border:1px solid #a3bac9;}.x-html-editor-tb{height:24px;}.x-html-editor-tb .x-toolbar{height:24px;}.x-html-editor-tb .x-toolbar>table{position:absolute;}.x-html-editor-tb .x-btn-text{background:transparent url(../images/default/form/htmleditor.gif) no-repeat scroll 0 0;}.x-html-editor-tb .x-btn-text{min-width:18px;}.x-html-editor-tb .x-edit-bold .x-btn-text{background-position:0 0;}.x-html-editor-tb .x-edit-italic .x-btn-text{background-position:0 -16px;}.x-html-editor-tb .x-edit-underline .x-btn-text{background-position:0 -32px;}.x-html-editor-tb .x-edit-strikethrough .x-btn-text{background-position:0 -223px;}.x-html-editor-tb .x-edit-increasefontsize .x-btn-text{background-position:0 -48px;}.x-html-editor-tb .x-edit-decreasefontsize .x-btn-text{background-position:0 -64px;}.x-html-editor-tb .x-edit-insertorderedlist .x-btn-text{background-position:0 -80px;}.x-html-editor-tb .x-edit-insertunorderedlist .x-btn-text{background-position:0 -96px;}.x-html-editor-tb .x-edit-justifyleft .x-btn-text{background-position:0 -112px;}.x-html-editor-tb .x-edit-justifycenter .x-btn-text{background-position:0 -128px;}.x-html-editor-tb .x-edit-justifyright .x-btn-text{background-position:0 -144px;}.x-html-editor-tb .x-edit-forecolor .x-btn-text{background-position:0 -160px;}.x-html-editor-tb .x-edit-backcolor .x-btn-text{background-position:0 -176px;}.x-html-editor-tb .x-edit-sourceedit .x-btn-text{background-position:0 -192px;}.x-html-editor-tb .x-edit-createlink .x-btn-text{background-position:0 -208px;}.x-html-editor-tb .x-edit-none .x-btn-text{background:transparent none 0 0;}.x-html-editor-tb .x-toolbar .x-btn{margin-left:0;margin-right:0;}.x-html-editor-wrap .x-toolbar{height:20px;}.x-html-editor-wrap .x-editor-context span{cursor:pointer;}.x-html-editor-wrap .x-editor-context span:hover{text-decoration:underline;}.roo-htmleditor-body ol li{list-style:decimal outside;}.roo-htmleditor-body ul li{list-style:disc outside;}.roo-htmleditor-body ol,.roo-htmleditor-body ul,.roo-htmleditor-body dl{margin-left:2em;}.roo-htmleditor-body::selection,.roo-htmleditor-body *::selection{background:#d9e8fb;}.roo-htmleditor-body table.roo-ed-selection,.roo-htmleditor-body td.roo-ed-selection{background-color:#d9e8fb;} .undoreset div,.undoreset span,.undoreset applet,.undoreset object,.undoreset iframe,.undoreset h1,.undoreset h2,.undoreset h3,.undoreset h4,.undoreset h5,.undoreset h6,.undoreset p,.undoreset blockquote,.undoreset pre,.undoreset a,.undoreset abbr,.undoreset acronym,.undoreset address,.undoreset big,.undoreset cite,.undoreset code,.undoreset del,.undoreset dfn,.undoreset em,.undoreset img,.undoreset ins,.undoreset kbd,.undoreset q,.undoreset s,.undoreset samp,.undoreset small,.undoreset strike,.undoreset strong,.undoreset sub,.undoreset sup,.undoreset tt,.undoreset var,.undoreset b,.undoreset u,.undoreset i,.undoreset center,.undoreset dl,.undoreset dt,.undoreset dd,.undoreset ol,.undoreset ul,.undoreset li,.undoreset fieldset,.undoreset form,.undoreset label,.undoreset legend,.undoreset table,.undoreset caption,.undoreset tbody,.undoreset tfoot,.undoreset thead,.undoreset tr,.undoreset th,.undoreset td,.undoreset article,.undoreset aside,.undoreset canvas,.undoreset details,.undoreset embed,.undoreset figure,.undoreset figcaption,.undoreset footer,.undoreset header,.undoreset hgroup,.undoreset menu,.undoreset nav,.undoreset output,.undoreset ruby,.undoreset section,.undoreset summary,.undoreset time,.undoreset mark,.undoreset audio,.undoreset video{margin-bottom:1em;}.undoreset strong,.undoreset th{font-weight:bold;}.undoreset em,.undoreset address,.undoreset caption,.undoreset cite{font-style:italic;}.undoreset table{display:table;border-spacing:2px;border-collapse:separate;}.undoreset tr{display:table-row;vertical-align:inherit;}.undoreset td{display:table-cell;border-spacing:2px;padding:2px;vertical-align:inherit;text-align:inherit;padding:1px;border-collapse:none;}.undoreset th{display:table-cell;vertical-align:inherit;font-weight:bold;padding:1px;border-collapse:none;}.undoreset p{display:block;margin:1em 0;}.undoreset blockquote{display:block;margin:1em 40px;}.undoreset address{display:block;font-style:italic;}.undoreset center{display:block;text-align:center;}.undoreset h1{display:block;font-size:2em;font-weight:bold;margin:.67em 0;}.undoreset h2{display:block;font-size:1.5em;font-weight:bold;margin:.83em 0;}.undoreset h3{display:block;font-size:1.17em;font-weight:bold;margin:1em 0;}.undoreset h4{display:block;font-weight:bold;margin:1.33em 0;}.undoreset h5{display:block;font-size:.83em;font-weight:bold;margin:1.67em 0;}.undoreset h6{display:block;font-size:.67em;font-weight:bold;margin:2.33em 0;}.undoreset ul{display:block;list-style-type:disc;margin:1em 0;padding-left:40px;}.undoreset ol{display:block;list-style-type:decimal;margin:1em 0;padding-left:40px;}.undoreset li{display:list-item;}.undoreset pre,.undoreset code{display:block;font-family:Courier New;white-space:pre;margin:1em 0;}.roo-htmleditor-body [contenteditable=true]:focus-visible{background-color:#fafafa;padding:0 5px;;}.roo-htmleditor-body [contenteditable=true]:hover{border:1px solid #ccc;} +.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px;}.alert h4{margin-top:0;color:inherit;}.alert .alert-link{font-weight:bold;}.alert>p,.alert>ul{margin-bottom:0;}.alert>p+p{margin-top:5px;}.alert-dismissable,.alert-dismissible{padding-right:35px;}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit;}.alert-success{background-color:#dff0d8;border-color:#d6e9c6;color:#3c763d;}.alert-success hr{border-top-color:#c9e2b3;}.alert-success .alert-link{color:#2b542c;}.alert-info{background-color:#d9edf7;border-color:#bce8f1;color:#31708f;}.alert-info hr{border-top-color:#a6e1ec;}.alert-info .alert-link{color:#245269;}.alert-warning{background-color:#fcf8e3;border-color:#faebcc;color:#8a6d3b;}.alert-warning hr{border-top-color:#f7e1b5;}.alert-warning .alert-link{color:#66512c;}.alert-danger{background-color:#f2dede;border-color:#ebccd1;color:#a94442;}.alert-danger hr{border-top-color:#e4b9c0;}.alert-danger .alert-link{color:#843534;} +.btn{display:inline-block;margin-bottom:0;font-weight:normal;text-align:center;vertical-align:middle;touch-action:manipulation;cursor:pointer;background-image:none;border:1px solid transparent;white-space:nowrap;padding:6px 12px;font-size:14px;line-height:1.42857143;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;}.btn:focus,.btn:active:focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn.active.focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px;}.btn:hover,.btn:focus,.btn.focus{color:#333;text-decoration:none;}.btn:active,.btn.active{outline:0;background-image:none;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none;}.btn-default{color:#333;background-color:#fff;border-color:#ccc;}.btn-default:focus,.btn-default.focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c;}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad;}.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad;}.btn-default:active:hover,.btn-default.active:hover,.open>.dropdown-toggle.btn-default:hover,.btn-default:active:focus,.btn-default.active:focus,.open>.dropdown-toggle.btn-default:focus,.btn-default:active.focus,.btn-default.active.focus,.open>.dropdown-toggle.btn-default.focus{color:#333;background-color:#d4d4d4;border-color:#8c8c8c;}.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{background-image:none;}.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled.focus,.btn-default[disabled].focus,fieldset[disabled] .btn-default.focus{background-color:#fff;border-color:#ccc;}.btn-default .badge{color:#fff;background-color:#333;}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4;}.btn-primary:focus,.btn-primary.focus{color:#fff;background-color:#286090;border-color:#122b40;}.btn-primary:hover{color:#fff;background-color:#286090;border-color:#204d74;}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74;}.btn-primary:active:hover,.btn-primary.active:hover,.open>.dropdown-toggle.btn-primary:hover,.btn-primary:active:focus,.btn-primary.active:focus,.open>.dropdown-toggle.btn-primary:focus,.btn-primary:active.focus,.btn-primary.active.focus,.open>.dropdown-toggle.btn-primary.focus{color:#fff;background-color:#204d74;border-color:#122b40;}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{background-image:none;}.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled.focus,.btn-primary[disabled].focus,fieldset[disabled] .btn-primary.focus{background-color:#337ab7;border-color:#2e6da4;}.btn-primary .badge{color:#337ab7;background-color:#fff;}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c;}.btn-success:focus,.btn-success.focus{color:#fff;background-color:#449d44;border-color:#255625;}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439;}.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439;}.btn-success:active:hover,.btn-success.active:hover,.open>.dropdown-toggle.btn-success:hover,.btn-success:active:focus,.btn-success.active:focus,.open>.dropdown-toggle.btn-success:focus,.btn-success:active.focus,.btn-success.active.focus,.open>.dropdown-toggle.btn-success.focus{color:#fff;background-color:#398439;border-color:#255625;}.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{background-image:none;}.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled.focus,.btn-success[disabled].focus,fieldset[disabled] .btn-success.focus{background-color:#5cb85c;border-color:#4cae4c;}.btn-success .badge{color:#5cb85c;background-color:#fff;}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da;}.btn-info:focus,.btn-info.focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85;}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc;}.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc;}.btn-info:active:hover,.btn-info.active:hover,.open>.dropdown-toggle.btn-info:hover,.btn-info:active:focus,.btn-info.active:focus,.open>.dropdown-toggle.btn-info:focus,.btn-info:active.focus,.btn-info.active.focus,.open>.dropdown-toggle.btn-info.focus{color:#fff;background-color:#269abc;border-color:#1b6d85;}.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{background-image:none;}.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled.focus,.btn-info[disabled].focus,fieldset[disabled] .btn-info.focus{background-color:#5bc0de;border-color:#46b8da;}.btn-info .badge{color:#5bc0de;background-color:#fff;}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236;}.btn-warning:focus,.btn-warning.focus{color:#fff;background-color:#ec971f;border-color:#985f0d;}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512;}.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512;}.btn-warning:active:hover,.btn-warning.active:hover,.open>.dropdown-toggle.btn-warning:hover,.btn-warning:active:focus,.btn-warning.active:focus,.open>.dropdown-toggle.btn-warning:focus,.btn-warning:active.focus,.btn-warning.active.focus,.open>.dropdown-toggle.btn-warning.focus{color:#fff;background-color:#d58512;border-color:#985f0d;}.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{background-image:none;}.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled.focus,.btn-warning[disabled].focus,fieldset[disabled] .btn-warning.focus{background-color:#f0ad4e;border-color:#eea236;}.btn-warning .badge{color:#f0ad4e;background-color:#fff;}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a;}.btn-danger:focus,.btn-danger.focus{color:#fff;background-color:#c9302c;border-color:#761c19;}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925;}.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925;}.btn-danger:active:hover,.btn-danger.active:hover,.open>.dropdown-toggle.btn-danger:hover,.btn-danger:active:focus,.btn-danger.active:focus,.open>.dropdown-toggle.btn-danger:focus,.btn-danger:active.focus,.btn-danger.active.focus,.open>.dropdown-toggle.btn-danger.focus{color:#fff;background-color:#ac2925;border-color:#761c19;}.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{background-image:none;}.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled.focus,.btn-danger[disabled].focus,fieldset[disabled] .btn-danger.focus{background-color:#d9534f;border-color:#d43f3a;}.btn-danger .badge{color:#d9534f;background-color:#fff;}.btn-link{color:#337ab7;font-weight:normal;border-radius:0;}.btn-link,.btn-link:active,.btn-link.active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none;}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent;}.btn-link:hover,.btn-link:focus{color:#23527c;text-decoration:underline;background-color:transparent;}.btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#777;text-decoration:none;}.btn-lg,.btn-group-lg>.btn{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px;}.btn-sm,.btn-group-sm>.btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px;}.btn-xs,.btn-group-xs>.btn{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px;}.btn-block{display:block;width:100%;}.btn-block+.btn-block{margin-top:5px;}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%;} +.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle;}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;float:left;}.btn-group>.btn:hover,.btn-group-vertical>.btn:hover,.btn-group>.btn:focus,.btn-group-vertical>.btn:focus,.btn-group>.btn:active,.btn-group-vertical>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn.active{z-index:2;}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px;}.btn-toolbar{margin-left:-5px;}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left;}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px;}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0;}.btn-group>.btn:first-child{margin-left:0;}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-top-right-radius:0;}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0;}.btn-group>.btn-group{float:left;}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0;}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-top-right-radius:0;}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-bottom-left-radius:0;border-top-left-radius:0;}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0;}.btn-group>.btn+.dropdown-toggle{padding-left:8px;padding-right:8px;}.btn-group>.btn-lg+.dropdown-toggle{padding-left:12px;padding-right:12px;}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none;}.btn .caret{margin-left:0;}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0;}.dropup .btn-lg .caret{border-width:0 5px 5px;}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%;}.btn-group-vertical>.btn-group>.btn{float:none;}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0;}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0;}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-top-left-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0;}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-right-radius:0;border-top-left-radius:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px;}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0;}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0;}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-right-radius:0;border-top-left-radius:0;}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate;}.btn-group-justified>.btn,.btn-group-justified>.btn-group{float:none;display:table-cell;width:1%;}.btn-group-justified>.btn-group .btn{width:100%;}.btn-group-justified>.btn-group .dropdown-menu{left:auto;}[data-toggle="buttons"]>.btn input[type="radio"],[data-toggle="buttons"]>.btn-group>.btn input[type="radio"],[data-toggle="buttons"]>.btn input[type="checkbox"],[data-toggle="buttons"]>.btn-group>.btn input[type="checkbox"]{position:absolute;clip:rect(0,0,0,0);pointer-events:none;} +.roo-upload-cropbox-selector{display:none!important;}.roo-upload-cropbox-dialog .modal-header,.roo-upload-cropbox-dialog .modal-footer{padding-top:5px;padding-bottom:5px;}.roo-upload-cropbox-body{background-color:#fff;border:1px solid #777;width:100%;height:450px;max-height:450px;position:relative;overflow:hidden;cursor:move;}.roo-upload-cropbox-preview{position:absolute;top:0;left:0;text-align:center;margin:0;padding:0;border:none;}.roo-upload-cropbox-body .roo-upload-cropbox-thumb{position:absolute;box-sizing:border-box;border:1px solid #777;box-shadow:0 0 0 1000px rgba(0,0,0,0.5);background:none repeat scroll 0 0 transparent;}.roo-upload-cropbox-body .roo-upload-cropbox-empty-notify{height:100%;background-color:rgba(0,0,0,0.5);color:#fff;font-weight:bold;font-size:24px;text-align:center;padding-top:50px;font-style:italic;}.roo-upload-cropbox-btn-group button{background-color:#000;color:#fff;border-color:#333;}.roo-upload-cropbox-error-notify{border-radius:0;text-align:center;padding:0!important;margin:0!important;position:absolute;top:0;left:0;} diff --git a/css/upload-cropbox.css b/css/upload-cropbox.css new file mode 100644 index 0000000000..c7dfbe76d5 --- /dev/null +++ b/css/upload-cropbox.css @@ -0,0 +1,61 @@ +.roo-upload-cropbox-selector { + display: none !important; +} +.roo-upload-cropbox-dialog .modal-header, +.roo-upload-cropbox-dialog .modal-footer { + padding-top: 5px; + padding-bottom: 5px; +} +.roo-upload-cropbox-body { + background-color: #ffffff; + border: 1px solid #777777; + width: 100%; + height: 450px; + max-height: 450px; + position: relative; + overflow: hidden; + cursor: move; +} +.roo-upload-cropbox-preview { + position: absolute; + top: 0px; + left: 0px; + text-align: center; + margin: 0px; + padding: 0px; + border: none; +} +.roo-upload-cropbox-body .roo-upload-cropbox-thumb { + position: absolute; + /* top: 50%; + left: 50%; + transform: translate(-50%, -50%);*/ + box-sizing: border-box; + border: 1px solid #777777; + box-shadow: 0 0 0 1000px rgba(0, 0, 0, 0.5); + background: none repeat scroll 0% 0% transparent; +} +.roo-upload-cropbox-body .roo-upload-cropbox-empty-notify { + height: 100%; + background-color: rgba(0, 0, 0, 0.5); + color: #ffffff; + font-weight: bold; + font-size: 24px; + text-align: center; + padding-top: 50px; + font-style: italic; +} +.roo-upload-cropbox-btn-group button { + background-color: #000000; + color: #ffffff; + border-color: #333333; +} +.roo-upload-cropbox-error-notify { + border-radius: 0px; + text-align: center; + padding: 0px !important; + margin: 0px !important; + position: absolute; + top: 0; + left: 0; +} \ No newline at end of file diff --git a/examples/dialog/hello.html b/examples/dialog/hello.html index ab43ed9999..ec001bf313 100644 --- a/examples/dialog/hello.html +++ b/examples/dialog/hello.html @@ -1,27 +1,27 @@ - - - - -Hello World Dialog Example + + + + +Hello World Dialog Example - - - - - - - - - -

Hello World Dialog

-

This example shows how to create a very simple modal BasicDialog with "autoTabs".

-

+ + + + + + + + + +

Hello World Dialog

+

This example shows how to create a very simple modal BasicDialog with "autoTabs".

+

Note that the js is not minified so it is readable. See -for the full source code.

-Here's snapshot of the code that creates the dialog: +for the full source code.

+Here's snapshot of the code that creates the dialog:
Roo.BLANK_IMAGE_URL  = "../../images/default/s.gif";
 
 
@@ -121,29 +121,29 @@ Roo.onReady(function() {
     Roo.get('show-dialog-btn').on('click',function () {
         HelloWorld.show({ _el : this});
     });
-});
-
- - - - - - +}); + + + + + + + diff --git a/examples/dialog/uploadCropbox.html b/examples/dialog/uploadCropbox.html new file mode 100644 index 0000000000..79ac18bc00 --- /dev/null +++ b/examples/dialog/uploadCropbox.html @@ -0,0 +1,31 @@ + + + + + Upload Cropbox Dialog Example + + + + + + + + + + + + + + + + + +

Upload Cropbox Dialog

+

This example shows how to create a very simple BasicDialog with "UploadCropbox".

+

+

Note that the js is not minified so it is readable. See +for the full source code.

+ + + + diff --git a/examples/dialog/uploadCropbox.js b/examples/dialog/uploadCropbox.js new file mode 100644 index 0000000000..8be50a9895 --- /dev/null +++ b/examples/dialog/uploadCropbox.js @@ -0,0 +1,180 @@ +var uploadCropbox = { + dialog : false, + callback : false, + + show : function(data, cb) + { + if (!this.dialog) { + this.create(); + } + + this.callback = cb; + this.data = data; + this.dialog.show(); + }, + + create : function() + { + var _this = this; + this.dialog = Roo.factory({ + xns : Roo, + xtype : 'LayoutDialog', + width : 700, + height : 600, + center : { + xns : Roo, + xtype : 'LayoutRegion' + }, + items : [ + { + xtype: 'ContentPanel', + xns: Roo, + region : "center", + items : [ + { + xtype : 'UploadCropbox', + xns : Roo.dialog, + minWidth : 720, + minHeight : 480, + outputMaxWidth : 1200, + windowSize : 300, + url: 'http://localhost/web.MediaOutreach/press.local.php/Roo/Images.php', + buttons: [], + listeners : { + render : function (_self) + { + _this.cropbox = _self; + }, + loadcanvas : function (_self, imageEl) + { + if(imageEl.OriginWidth < 720) { + Roo.Msg.show({ + title: 'Error', + msg: "Image width should be at least 720", + buttons: {ok : true}, + fn: function(res) { + _this.cropbox.selectorEl.dom.value = ''; + _this.cropbox.selectorEl.dom.click(); + } + }); + return false; + } + }, + arrange : function (_self, formData) + { + formData.append("onid", "43024"); + formData.append("ontable", "pressrelease_boilerplate"); + } + } + } + ] + } + ], + buttons : [ + { + xtype : 'Button', + xns : Roo, + text : 'Save', + listeners : { + click : function () { + _this.cropbox.crop(); + _this.dialog.hide(); + } + } + }, + { + xtype : 'Button', + xns : Roo, + text : 'Cancel', + listeners : { + click : function () { + _this.dialog.hide(); + } + } + } + ] + }); + } +} + +var test = { + + dialog : false, + callback : false, + + show : function(data, cb) + { + if (!this.dialog) { + this.create(); + } + + this.callback = cb; + this.data = data; + this.dialog.show(); + }, + + create : function() + { + var _this = this; + this.dialog = Roo.factory({ + xns : Roo, + xtype : 'LayoutDialog', + width : 600, + height : 450, + center : { + xns : Roo, + xtype : 'LayoutRegion' + }, + items : [ + { + xns : Roo, + xtype: 'GridPanel', + region : "center", + grid : { + xns : Roo.grid, + xtype : 'Grid', + cm : [ + { + xns : Roo.grid, + xtype : 'ColumnModel', + header : 'test' + } + ], + ds : { + xns: Roo.data, + xtype: 'Store' + }, + toolbar : { + xns: Roo, + xtype: 'Toolbar', + items : [ + { + xtype : 'Button', + text : 'Add', + listeners : { + click : function () { + uploadCropbox.show(); + document.body.onfocus = function(e) { + if(!uploadCropbox.cropbox.selectorEl.dom.files.length) { + uploadCropbox.dialog.hide(); + } + } + uploadCropbox.cropbox.selectorEl.dom.click(); + } + } + } + ] + } + } + } + ], + }); + } +} + +Roo.onReady(function() { + + Roo.get('show-dialog-btn').on('click',function () { + test.show({}); + }); +}); \ No newline at end of file diff --git a/roojs-all.js b/roojs-all.js index ab95b0181b..c62db20f99 100644 --- a/roojs-all.js +++ b/roojs-all.js @@ -2551,9 +2551,9 @@ return this.el.getUpdateManager();},_handleRefresh:function(A,B,C){if(!C||!this. te.setWidth(A);}if(this.adjustments){A+=this.adjustments[0];B+=this.adjustments[1];}return {"width":A,"height":B};},setSize:function(A,B){if(this.fitToFrame&&!this.ignoreResize(A,B)){if(this.fitContainer&&this.resizeEl!=this.el){this.el.setSize(A,B);}var C=this.adjustForComponents(A,B); this.resizeEl.setSize(this.autoWidth?"auto":C.width,this.autoHeight?"auto":C.height);this.fireEvent('resize',this,C.width,C.height);}},getTitle:function(){return this.title;},setTitle:function(A){this.title=A;if(this.region){this.region.updatePanelTitle(this,A); }},isClosable:function(){return this.closable;},beforeSlide:function(){this.el.clip();this.resizeEl.clip();},afterSlide:function(){this.el.unclip();this.resizeEl.unclip();},refresh:function(){if(this.refreshDelegate){this.loaded=false;this.refreshDelegate(); -}},destroy:function(){this.el.removeAllListeners();var A=document.createElement("span");A.appendChild(this.el.dom);A.innerHTML="";this.el.remove();this.el=null;},form:false,view:false,addxtype:function(A){if(A.xtype.match(/^Form$/)){var el;el=this.el.createChild(); -this.form=new Roo.form.Form(A);if(this.form.allItems.length){this.form.render(el.dom);}return this.form;}if(['View','JsonView','DatePicker'].indexOf(A.xtype)>-1){A.el=this.el.appendChild(document.createElement("div"));var B=new Roo.factory(A);B.render&&B.render(false,''); -this.view=B;return B;}return false;}}); +}},destroy:function(){this.el.removeAllListeners();var A=document.createElement("span");A.appendChild(this.el.dom);A.innerHTML="";this.el.remove();this.el=null;},form:false,view:false,addxtype:function(A){if(A.xtype.match(/^UploadCropbox$/)){this.cropbox=new Roo.factory(A); +this.cropbox.render(this.el);return this.cropbox;}if(A.xtype.match(/^Form$/)){var el;el=this.el.createChild();this.form=new Roo.form.Form(A);if(this.form.allItems.length){this.form.render(el.dom);}return this.form;}if(['View','JsonView','DatePicker'].indexOf(A.xtype)>-1){A.el=this.el.appendChild(document.createElement("div")); +var B=new Roo.factory(A);B.render&&B.render(false,'');this.view=B;return B;}return false;}}); // Roo/GridPanel.js Roo.GridPanel=function(A,B){if(typeof(A.grid)!='undefined'){B=A;A=B.grid;}this.wrapper=Roo.DomHelper.append(document.body,{tag:"div",cls:"x-layout-grid-wrapper x-layout-inactive-content"},true);this.wrapper.dom.appendChild(A.getGridEl().dom);Roo.GridPanel.superclass.constructor.call(this,this.wrapper,B); if(this.toolbar){this.toolbar.el.insertBefore(this.wrapper.dom.firstChild);}if(this.footer&&!this.footer.el&&this.footer.xtype){this.footer.container=this.grid.getView().getFooterPanel(true);this.footer.dataSource=this.grid.dataSource;this.footer=Roo.factory(this.footer,Roo); @@ -2882,3 +2882,105 @@ F.push("(typeof("+G+") == 'undefined')");});var H='(('+F.join(" || ")+") ? undef }return "'"+A+H+C+")"+A+"'";};var B;if(Roo.isGecko){B="tpl.compiled = function(values, parent){ with(values) { return '"+tpl.body.replace(/(\r\n|\n)/g,'\\n').replace(/'/g,"\\'").replace(this.re,fn)+"';};};";}else{B=["tpl.compiled = function(values, parent){ with (values) { return ['"]; B.push(tpl.body.replace(/(\r\n|\n)/g,'\\n').replace(/'/g,"\\'").replace(this.re,fn));B.push("'].join('');};};");B=B.join('');}Roo.debug&&Roo.log(B.replace(/\\n/,'\n'));eval(B);return this;},applyTemplate:function(A){return this.master.compiled.call(this,A,{} );},apply:function(){return this.applyTemplate.apply(this,arguments);}});Roo.XTemplate.from=function(el){el=Roo.getDom(el);return new Roo.XTemplate(el.value||el.innerHTML);}; +// Roo/dialog/namespace.js +Roo.dialog={}; +// Roo/dialog/UploadCropbox.js +Roo.dialog.UploadCropbox=function(A){Roo.dialog.UploadCropbox.superclass.constructor.call(this,A);this.addEvents({"beforeselectfile":true,"initial":true,"crop":true,"prepare":true,"exception":true,"beforeloadcanvas":true,"trash":true,"download":true,"footerbuttonclick":true,"resize":true,"rotate":true,"inspect":true,"upload":true,"arrange":true,"loadcanvas":true} +);this.buttons=this.buttons||Roo.dialog.UploadCropbox.footer.STANDARD;};Roo.extend(Roo.dialog.UploadCropbox,Roo.Component,{emptyText:'Click to upload image',rotateNotify:'Image is too small to rotate',errorTimeout:3000,scale:0,baseScale:1,rotate:0,dragable:false,pinching:false,mouseX:0,mouseY:0,cropData:false,minWidth:300,minHeight:300,outputMaxWidth:1200,windowSize:300,file:false,exif:{} +,baseRotate:1,cropType:'image/jpeg',buttons:false,canvasLoaded:false,isDocument:false,method:'POST',paramName:'imageUpload',loadMask:true,loadingText:'Loading...',maskEl:false,getAutoCreate:function(){var A={tag:'div',cls:'roo-upload-cropbox',cn:[{tag:'input',cls:'roo-upload-cropbox-selector',type:'file'} +,{tag:'div',cls:'roo-upload-cropbox-body',style:'cursor:pointer',cn:[{tag:'div',cls:'roo-upload-cropbox-preview'},{tag:'div',cls:'roo-upload-cropbox-thumb'},{tag:'div',cls:'roo-upload-cropbox-empty-notify',html:this.emptyText},{tag:'div',cls:'roo-upload-cropbox-error-notify alert alert-danger',html:this.rotateNotify} +]},{tag:'div',cls:'roo-upload-cropbox-footer',cn:{tag:'div',cls:'btn-group btn-group-justified roo-upload-cropbox-btn-group',cn:[]}}]};return A;},onRender:function(ct,A){Roo.dialog.UploadCropbox.superclass.onRender.call(this,ct,A);if(this.el){if(this.el.attr('xtype')){this.el.attr('xtypex',this.el.attr('xtype')); +this.el.dom.removeAttribute('xtype');this.initEvents();}}else{var B=Roo.apply({},this.getAutoCreate());B.id=this.id||Roo.id();if(this.cls){B.cls=(typeof(B.cls)=='undefined'?this.cls:B.cls)+' '+this.cls;}if(this.style){B.style=(typeof(B.style)=='undefined'?this.style:B.style)+'; '+this.style; +}this.el=ct.createChild(B,A);this.initEvents();}if(this.buttons.length){Roo.each(this.buttons,function(bb){var C=this.el.select('.roo-upload-cropbox-footer div.roo-upload-cropbox-btn-group').first().createChild(bb);C.on('click',this.onFooterButtonClick.createDelegate(this,[bb.action],true)); +},this);}if(this.loadMask){this.maskEl=this.el;}},initEvents:function(){this.urlAPI=(window.createObjectURL&&window)||(window.URL&&URL.revokeObjectURL&&URL)||(window.webkitURL&&webkitURL);this.bodyEl=this.el.select('.roo-upload-cropbox-body',true).first(); +this.bodyEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block';this.selectorEl=this.el.select('.roo-upload-cropbox-selector',true).first();this.selectorEl.hide();this.previewEl=this.el.select('.roo-upload-cropbox-preview',true).first();this.previewEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block'; +this.thumbEl=this.el.select('.roo-upload-cropbox-thumb',true).first();this.thumbEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block';this.thumbEl.hide();this.notifyEl=this.el.select('.roo-upload-cropbox-empty-notify',true).first();this.notifyEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block'; +this.errorEl=this.el.select('.roo-upload-cropbox-error-notify',true).first();this.errorEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block';this.errorEl.hide();this.footerEl=this.el.select('.roo-upload-cropbox-footer',true).first();this.footerEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block'; +this.footerEl.hide();this.setThumbBoxSize();this.bind();this.resize();this.fireEvent('initial',this);},bind:function(){var A=this;window.addEventListener("resize",function(){A.resize();});this.bodyEl.on('click',this.beforeSelectFile,this);if(Roo.isTouch){this.bodyEl.on('touchstart',this.onTouchStart,this); +this.bodyEl.on('touchmove',this.onTouchMove,this);this.bodyEl.on('touchend',this.onTouchEnd,this);}if(!Roo.isTouch){this.bodyEl.on('mousedown',this.onMouseDown,this);this.bodyEl.on('mousemove',this.onMouseMove,this);var B=(/Firefox/i.test(navigator.userAgent))?'DOMMouseScroll':'mousewheel'; +this.bodyEl.on(B,this.onMouseWheel,this);Roo.get(document).on('mouseup',this.onMouseUp,this);}this.selectorEl.on('change',this.onFileSelected,this);},reset:function(){this.scale=0;this.baseScale=1;this.rotate=0;this.baseRotate=1;this.dragable=false;this.pinching=false; +this.mouseX=0;this.mouseY=0;this.cropData=false;this.notifyEl.dom.innerHTML=this.emptyText;},resize:function(){if(this.fireEvent('resize',this)!=false){this.setThumbBoxPosition();this.setCanvasPosition();}},onFooterButtonClick:function(e,el,o,A){switch(A){case 'rotate-left':this.onRotateLeft(e); +break;case 'rotate-right':this.onRotateRight(e);break;case 'picture':this.beforeSelectFile(e);break;case 'trash':this.trash(e);break;case 'crop':this.crop(e);break;case 'download':this.download(e);break;default:break;}this.fireEvent('footerbuttonclick',this,A); +},beforeSelectFile:function(e){e.preventDefault();if(this.fireEvent('beforeselectfile',this)!=false){this.selectorEl.dom.click();}},onFileSelected:function(e){e.preventDefault();if(typeof(this.selectorEl.dom.files)=='undefined'||!this.selectorEl.dom.files.length){return; +}var A=this.selectorEl.dom.files[0];if(this.fireEvent('inspect',this,A)!=false){this.prepare(A);}},trash:function(e){this.fireEvent('trash',this);},download:function(e){this.fireEvent('download',this);},loadCanvas:function(A){if(this.fireEvent('beforeloadcanvas',this,A)!=false){this.reset(); +this.imageEl=document.createElement('img');var B=this;this.imageEl.addEventListener("load",function(){B.onLoadCanvas();});this.imageEl.src=A;}},onLoadCanvas:function(){this.imageEl.OriginWidth=this.imageEl.naturalWidth||this.imageEl.width;this.imageEl.OriginHeight=this.imageEl.naturalHeight||this.imageEl.height; +if(this.fireEvent('loadcanvas',this,this.imageEl)!=false){this.bodyEl.un('click',this.beforeSelectFile,this);this.notifyEl.hide();this.thumbEl.show();this.footerEl.show();this.baseRotateLevel();if(this.isDocument){this.setThumbBoxSize();}this.setThumbBoxPosition(); +this.baseScaleLevel();this.draw();this.resize();this.canvasLoaded=true;}if(this.loadMask){this.maskEl.unmask();}},setCanvasPosition:function(){if(!this.canvasEl){return;}var pw=Math.ceil((this.bodyEl.getWidth()-this.canvasEl.width)/2);var ph=Math.ceil((this.bodyEl.getHeight()-this.canvasEl.height)/2); +this.previewEl.setLeft(pw);this.previewEl.setTop(ph);},onMouseDown:function(e){e.stopEvent();this.dragable=true;this.pinching=false;if(this.isDocument&&(this.canvasEl.widthC){var E=A;A=C;C=E;}if(B>D){var F=B;B=D;D=F;}var x=Roo.isTouch?e.browserEvent.touches[0].pageX:e.getPageX(); +var y=Roo.isTouch?e.browserEvent.touches[0].pageY:e.getPageY();x=x-this.mouseX;y=y-this.mouseY;var G=Math.ceil(x+this.previewEl.getLeft(true));var H=Math.ceil(y+this.previewEl.getTop(true));G=(GC)?C:G);H=(HD)?D:H);this.previewEl.setLeft(G); +this.previewEl.setTop(H);this.mouseX=Roo.isTouch?e.browserEvent.touches[0].pageX:e.getPageX();this.mouseY=Roo.isTouch?e.browserEvent.touches[0].pageY:e.getPageY();},onMouseUp:function(e){e.stopEvent();this.dragable=false;},onMouseWheel:function(e){e.stopEvent(); +this.startScale=this.scale;this.scale=(e.getWheelDelta()>0)?(this.scale+1):(this.scale-1);if(!this.zoomable()){this.scale=this.startScale;return;}this.draw();return;},zoomable:function(){var A=this.thumbEl.getWidth()/this.minWidth;if(this.minWidththis.imageEl.OriginWidth||C>this.imageEl.OriginHeight||(Bthis.imageEl.OriginWidth||C>this.imageEl.OriginHeight||(B=this.minWidth/this.minHeight)&&BD||C>E)){return false; +}if(!this.isDocument&&(this.rotate==90||this.rotate==270)&&(Bthis.imageEl.OriginWidth||Cthis.imageEl.OriginHeight)){return false;}return true;},onRotateLeft:function(e){if(!this.isDocument&&(this.canvasEl.height180)?0:this.rotate+90;this.draw();return;}this.scale=this.startScale;this.onRotateFail();return false;}this.rotate=(this.rotate>180)?0:this.rotate+90;if(this.isDocument){this.setThumbBoxSize();this.setThumbBoxPosition();this.setCanvasPosition(); +}this.draw();this.fireEvent('rotate',this,'right');},onRotateFail:function(){this.errorEl.show(true);var A=this;(function(){A.errorEl.hide(true);}).defer(this.errorTimeout);},draw:function(){this.previewEl.dom.innerHTML='';var A=document.createElement("canvas"); +var B=A.getContext("2d");A.width=this.imageEl.OriginWidth*this.getScaleLevel();A.height=this.imageEl.OriginWidth*this.getScaleLevel();var C=this.imageEl.OriginWidth/2;if(this.imageEl.OriginWidththis.imageEl.OriginHeight){this.contextEl.drawImage(A,Math.abs(this.canvasEl.width-this.canvasEl.height),0,this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height); +break;}this.contextEl.drawImage(A,0,0,this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height);break;case 180:this.canvasEl.width=this.imageEl.OriginWidth*this.getScaleLevel();this.canvasEl.height=this.imageEl.OriginHeight*this.getScaleLevel(); +if(this.imageEl.OriginWidth>this.imageEl.OriginHeight){this.contextEl.drawImage(A,0,Math.abs(this.canvasEl.width-this.canvasEl.height),this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height);break;}this.contextEl.drawImage(A,Math.abs(this.canvasEl.width-this.canvasEl.height),0,this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height); +break;case 270:this.canvasEl.width=this.imageEl.OriginHeight*this.getScaleLevel();this.canvasEl.height=this.imageEl.OriginWidth*this.getScaleLevel();if(this.imageEl.OriginWidth>this.imageEl.OriginHeight){this.contextEl.drawImage(A,0,0,this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height); +break;}this.contextEl.drawImage(A,0,Math.abs(this.canvasEl.width-this.canvasEl.height),this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height);break;default:break;}this.previewEl.appendChild(this.canvasEl);this.setCanvasPosition(); +},crop:function(){if(!this.canvasLoaded){return;}var A=document.createElement("canvas");var B=A.getContext("2d");A.width=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?this.imageEl.OriginWidth:this.imageEl.OriginHeight;A.height=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?this.imageEl.OriginWidth:this.imageEl.OriginHeight; +var C=A.width/2;B.translate(C,C);B.rotate(this.rotate*Math.PI/180);B.drawImage(this.imageEl,0,0,this.imageEl.OriginWidth,this.imageEl.OriginHeight,C*-1,C*-1,this.imageEl.OriginWidth,this.imageEl.OriginHeight);var D=document.createElement("canvas");var E=D.getContext("2d"); +D.width=this.thumbEl.getWidth()/this.getScaleLevel();D.height=this.thumbEl.getHeight()/this.getScaleLevel();switch(this.rotate){case 0:var F=(this.thumbEl.getWidth()/this.getScaleLevel()>this.imageEl.OriginWidth)?this.imageEl.OriginWidth:(this.thumbEl.getWidth()/this.getScaleLevel()); +var G=(this.thumbEl.getHeight()/this.getScaleLevel()>this.imageEl.OriginHeight)?this.imageEl.OriginHeight:(this.thumbEl.getHeight()/this.getScaleLevel());var x=(this.thumbEl.getLeft(true)>this.previewEl.getLeft(true))?0:((this.previewEl.getLeft(true)-this.thumbEl.getLeft(true))/this.getScaleLevel()); +var y=(this.thumbEl.getTop(true)>this.previewEl.getTop(true))?0:((this.previewEl.getTop(true)-this.thumbEl.getTop(true))/this.getScaleLevel());var sx=this.thumbEl.getLeft(true)-this.previewEl.getLeft(true);var sy=this.thumbEl.getTop(true)-this.previewEl.getTop(true); +sx=sx<0?0:(sx/this.getScaleLevel());sy=sy<0?0:(sy/this.getScaleLevel());if(D.width>this.outputMaxWidth){var H=this.outputMaxWidth/D.width;D.width=D.width*H;D.height=D.height*H;E.scale(H,H);}E.fillStyle='white';E.fillRect(0,0,this.thumbEl.getWidth()/this.getScaleLevel(),this.thumbEl.getHeight()/this.getScaleLevel()); +E.drawImage(A,sx,sy,F,G,x,y,F,G);break;case 90:var F=(this.thumbEl.getWidth()/this.getScaleLevel()>this.imageEl.OriginHeight)?this.imageEl.OriginHeight:(this.thumbEl.getWidth()/this.getScaleLevel());var G=(this.thumbEl.getHeight()/this.getScaleLevel()>this.imageEl.OriginWidth)?this.imageEl.OriginWidth:(this.thumbEl.getHeight()/this.getScaleLevel()); +var x=(this.thumbEl.getLeft(true)>this.previewEl.getLeft(true))?0:((this.previewEl.getLeft(true)-this.thumbEl.getLeft(true))/this.getScaleLevel());var y=(this.thumbEl.getTop(true)>this.previewEl.getTop(true))?0:((this.previewEl.getTop(true)-this.thumbEl.getTop(true))/this.getScaleLevel()); +var I=this.minWidth-2*x;var J=this.minHeight-2*y;var H=1;if((x==0&&y==0)||(x==0&&y>0)){H=I/F;}if(x>0&&y==0){H=J/G;}if(x>0&&y>0){H=I/F;if(Fthis.imageEl.OriginHeight)?Math.abs(this.imageEl.OriginWidth-this.imageEl.OriginHeight):0; +E.drawImage(A,sx,sy,F,G,x,y,F,G);break;case 180:var F=(this.thumbEl.getWidth()/this.getScaleLevel()>this.imageEl.OriginWidth)?this.imageEl.OriginWidth:(this.thumbEl.getWidth()/this.getScaleLevel());var G=(this.thumbEl.getHeight()/this.getScaleLevel()>this.imageEl.OriginHeight)?this.imageEl.OriginHeight:(this.thumbEl.getHeight()/this.getScaleLevel()); +var x=(this.thumbEl.getLeft(true)>this.previewEl.getLeft(true))?0:((this.previewEl.getLeft(true)-this.thumbEl.getLeft(true))/this.getScaleLevel());var y=(this.thumbEl.getTop(true)>this.previewEl.getTop(true))?0:((this.previewEl.getTop(true)-this.thumbEl.getTop(true))/this.getScaleLevel()); +var I=this.minWidth-2*x;var J=this.minHeight-2*y;var H=1;if((x==0&&y==0)||(x==0&&y>0)){H=I/F;}if(x>0&&y==0){H=J/G;}if(x>0&&y>0){H=I/F;if(Fthis.imageEl.OriginHeight)?0:Math.abs(this.imageEl.OriginWidth-this.imageEl.OriginHeight); +sy+=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?Math.abs(this.imageEl.OriginWidth-this.imageEl.OriginHeight):0;E.drawImage(A,sx,sy,F,G,x,y,F,G);break;case 270:var F=(this.thumbEl.getWidth()/this.getScaleLevel()>this.imageEl.OriginHeight)?this.imageEl.OriginHeight:(this.thumbEl.getWidth()/this.getScaleLevel()); +var G=(this.thumbEl.getHeight()/this.getScaleLevel()>this.imageEl.OriginWidth)?this.imageEl.OriginWidth:(this.thumbEl.getHeight()/this.getScaleLevel());var x=(this.thumbEl.getLeft(true)>this.previewEl.getLeft(true))?0:((this.previewEl.getLeft(true)-this.thumbEl.getLeft(true))/this.getScaleLevel()); +var y=(this.thumbEl.getTop(true)>this.previewEl.getTop(true))?0:((this.previewEl.getTop(true)-this.thumbEl.getTop(true))/this.getScaleLevel());var I=this.minWidth-2*x;var J=this.minHeight-2*y;var H=1;if((x==0&&y==0)||(x==0&&y>0)){H=I/F;}if(x>0&&y==0){H=J/G; +}if(x>0&&y>0){H=I/F;if(Fthis.imageEl.OriginHeight)?0:Math.abs(this.imageEl.OriginWidth-this.imageEl.OriginHeight);E.drawImage(A,sx,sy,F,G,x,y,F,G);break;default:break;}this.cropData=D.toDataURL(this.cropType); +if(this.fireEvent('crop',this,this.cropData)!==false){this.process(this.file,this.cropData);}return;},setThumbBoxSize:function(){var A,B;if(this.isDocument&&typeof(this.imageEl)!='undefined'){A=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?Math.max(this.minWidth,this.minHeight):Math.min(this.minWidth,this.minHeight); +B=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?Math.min(this.minWidth,this.minHeight):Math.max(this.minWidth,this.minHeight);this.minWidth=A;this.minHeight=B;if(this.rotate==90||this.rotate==270){this.minWidth=B;this.minHeight=A;}}B=this.windowSize; +A=Math.ceil(this.minWidth*B/this.minHeight);if(this.minWidth>this.minHeight){A=this.windowSize;B=Math.ceil(this.minHeight*A/this.minWidth);}this.thumbEl.setStyle({width:A+'px',height:B+'px'});return;},setThumbBoxPosition:function(){var x=Math.ceil((this.bodyEl.getWidth()-this.thumbEl.getWidth())/2); +var y=Math.ceil((this.bodyEl.getHeight()-this.thumbEl.getHeight())/2);this.thumbEl.setLeft(x);this.thumbEl.setTop(y);},baseRotateLevel:function(){this.baseRotate=1;if(typeof(this.exif)!='undefined'&&typeof(this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']])!='undefined'&&[1,3,6,8].indexOf(this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']])!=-1){this.baseRotate=this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']]; +}this.rotate=Roo.dialog.UploadCropbox['Orientation'][this.baseRotate];},baseScaleLevel:function(){var A,B;if(this.isDocument){if(this.baseRotate==6||this.baseRotate==8){B=this.thumbEl.getHeight();this.baseScale=B/this.imageEl.OriginWidth;if(this.imageEl.OriginHeight*this.baseScale>this.thumbEl.getWidth()){A=this.thumbEl.getWidth(); +this.baseScale=A/this.imageEl.OriginHeight;}return;}B=this.thumbEl.getHeight();this.baseScale=B/this.imageEl.OriginHeight;if(this.imageEl.OriginWidth*this.baseScale>this.thumbEl.getWidth()){A=this.thumbEl.getWidth();this.baseScale=A/this.imageEl.OriginWidth; +}return;}if(this.baseRotate==6||this.baseRotate==8){A=this.thumbEl.getHeight();this.baseScale=A/this.imageEl.OriginHeight;if(this.imageEl.OriginHeight*this.baseScalethis.imageEl.OriginHeight){B=this.thumbEl.getWidth();this.baseScale=B/this.imageEl.OriginHeight;if(this.imageEl.OriginWidth*this.baseScalethis.imageEl.OriginHeight){B=this.thumbEl.getHeight(); +this.baseScale=B/this.imageEl.OriginHeight;if(this.imageEl.OriginWidth*this.baseScale=0xffe0&&H<=0xffef)||H===0xfffe){I=E.getUint16(F+2)+2;if(F+I>E.byteLength){Roo.log('Invalid meta data: Invalid segment size.');break;}if(H==0xffe1){B.parseExifData(E,F,I);}F+=I;continue;}break; +}}var J=B.urlAPI.createObjectURL(B.file);B.loadCanvas(J);return;};C.readAsArrayBuffer(this.file);}},parseExifData:function(A,B,C){var D=B+10,E,F;if(A.getUint32(B+4)!==0x45786966){return;}if(A.getUint32(B+4)!==0x45786966){return;}if(D+8>A.byteLength){Roo.log('Invalid Exif data: Invalid segment size.'); +return;}if(A.getUint16(B+8)!==0x0000){Roo.log('Invalid Exif data: Missing byte alignment offset.');return;}switch(A.getUint16(D)){case 0x4949:E=true;break;case 0x4D4D:E=false;break;default:Roo.log('Invalid Exif data: Invalid byte alignment marker.');return; +}if(A.getUint16(D+2,E)!==0x002A){Roo.log('Invalid Exif data: Missing TIFF marker.');return;}F=A.getUint32(D+4,E);this.parseExifTags(A,D,D+F,E);},parseExifTags:function(A,B,C,D){var E,F,i;if(C+6>A.byteLength){Roo.log('Invalid Exif data: Invalid directory offset.'); +return;}E=A.getUint16(C,D);F=C+2+12*E;if(F+4>A.byteLength){Roo.log('Invalid Exif data: Invalid directory size.');return;}for(i=0;i4?B+A.getUint32(C+8,F):(C+8);if(I+H>A.byteLength){Roo.log('Invalid Exif data: Invalid data offset.'); +return;}if(E===1){return G.getValue(A,I,F);}J=[];for(i=0;i'}]},{tag:'div',cls:'btn-group roo-upload-cropbox-picture',action:'picture',cn:[{tag:'button',cls:'btn btn-default',html:''} +]},{tag:'div',cls:'btn-group roo-upload-cropbox-rotate-right',action:'rotate-right',cn:[{tag:'button',cls:'btn btn-default',html:''}]}],DOCUMENT:[{tag:'div',cls:'btn-group roo-upload-cropbox-rotate-left',action:'rotate-left',cn:[{tag:'button',cls:'btn btn-default',html:''} +]},{tag:'div',cls:'btn-group roo-upload-cropbox-download',action:'download',cn:[{tag:'button',cls:'btn btn-default',html:''}]},{tag:'div',cls:'btn-group roo-upload-cropbox-crop',action:'crop',cn:[{tag:'button',cls:'btn btn-default',html:''} +]},{tag:'div',cls:'btn-group roo-upload-cropbox-trash',action:'trash',cn:[{tag:'button',cls:'btn btn-default',html:''}]},{tag:'div',cls:'btn-group roo-upload-cropbox-rotate-right',action:'rotate-right',cn:[{tag:'button',cls:'btn btn-default',html:''} +]}],ROTATOR:[{tag:'div',cls:'btn-group roo-upload-cropbox-rotate-left',action:'rotate-left',cn:[{tag:'button',cls:'btn btn-default',html:''}]},{tag:'div',cls:'btn-group roo-upload-cropbox-rotate-right',action:'rotate-right',cn:[{tag:'button',cls:'btn btn-default',html:''} +]}]}}); diff --git a/roojs-debug.js b/roojs-debug.js index 752cb43776..b3be73aa08 100644 --- a/roojs-debug.js +++ b/roojs-debug.js @@ -60557,7 +60557,6 @@ Roo.LayoutStateManager.prototype = { */ Roo.ContentPanel = function(el, config, content){ - /* if(el.autoCreate || el.xtype){ // xtype is available if this is called from factory config = el; @@ -60941,6 +60940,14 @@ layout.addxtype({ */ addxtype : function(cfg) { + if(cfg.xtype.match(/^UploadCropbox$/)) { + + this.cropbox = new Roo.factory(cfg); + + this.cropbox.render(this.el); + + return this.cropbox; + } // add form.. if (cfg.xtype.match(/^Form$/)) { @@ -68193,4 +68200,1808 @@ Roo.extend(Roo.XTemplate, Roo.Template, { Roo.XTemplate.from = function(el){ el = Roo.getDom(el); return new Roo.XTemplate(el.value || el.innerHTML); -}; \ No newline at end of file +};Roo.dialog = {}; +/* +* Licence: LGPL +*/ + +/** + * @class Roo.dialog.UploadCropbox + * @extends Roo.BoxComponent + * Dialog UploadCropbox class + * @cfg {String} emptyText show when image has been loaded + * @cfg {String} rotateNotify show when image too small to rotate + * @cfg {Number} errorTimeout default 3000 + * @cfg {Number} minWidth default 300 + * @cfg {Number} minHeight default 300 + * @cfg {Number} outputMaxWidth default 1200 + * @cfg {Number} windowSize default 300 + * @cfg {Array} buttons default ['rotateLeft', 'pictureBtn', 'rotateRight'] + * @cfg {Boolean} isDocument (true|false) default false + * @cfg {String} url action url + * @cfg {String} paramName default 'imageUpload' + * @cfg {String} method default POST + * @cfg {Boolean} loadMask (true|false) default true + * @cfg {Boolean} loadingText default 'Loading...' + * + * @constructor + * Create a new UploadCropbox + * @param {Object} config The config object + */ + + Roo.dialog.UploadCropbox = function(config){ + Roo.dialog.UploadCropbox.superclass.constructor.call(this, config); + + this.addEvents({ + /** + * @event beforeselectfile + * Fire before select file + * @param {Roo.dialog.UploadCropbox} this + */ + "beforeselectfile" : true, + /** + * @event initial + * Fire after initEvent + * @param {Roo.dialog.UploadCropbox} this + */ + "initial" : true, + /** + * @event crop + * Fire after initEvent + * @param {Roo.dialog.UploadCropbox} this + * @param {String} data + */ + "crop" : true, + /** + * @event prepare + * Fire when preparing the file data + * @param {Roo.dialog.UploadCropbox} this + * @param {Object} file + */ + "prepare" : true, + /** + * @event exception + * Fire when get exception + * @param {Roo.dialog.UploadCropbox} this + * @param {XMLHttpRequest} xhr + */ + "exception" : true, + /** + * @event beforeloadcanvas + * Fire before load the canvas + * @param {Roo.dialog.UploadCropbox} this + * @param {String} src + */ + "beforeloadcanvas" : true, + /** + * @event trash + * Fire when trash image + * @param {Roo.dialog.UploadCropbox} this + */ + "trash" : true, + /** + * @event download + * Fire when download the image + * @param {Roo.dialog.UploadCropbox} this + */ + "download" : true, + /** + * @event footerbuttonclick + * Fire when footerbuttonclick + * @param {Roo.dialog.UploadCropbox} this + * @param {String} type + */ + "footerbuttonclick" : true, + /** + * @event resize + * Fire when resize + * @param {Roo.dialog.UploadCropbox} this + */ + "resize" : true, + /** + * @event rotate + * Fire when rotate the image + * @param {Roo.dialog.UploadCropbox} this + * @param {String} pos + */ + "rotate" : true, + /** + * @event inspect + * Fire when inspect the file + * @param {Roo.dialog.UploadCropbox} this + * @param {Object} file + */ + "inspect" : true, + /** + * @event upload + * Fire when xhr upload the file + * @param {Roo.dialog.UploadCropbox} this + * @param {Object} data + */ + "upload" : true, + /** + * @event arrange + * Fire when arrange the file data + * @param {Roo.dialog.UploadCropbox} this + * @param {Object} formData + */ + "arrange" : true, + /** + * @event loadcanvas + * Fire after load the canvas + * @param {Roo.dialog.UploadCropbox} + * @param {Object} imgEl + */ + "loadcanvas" : true + }); + + this.buttons = this.buttons || Roo.dialog.UploadCropbox.footer.STANDARD; +}; + +Roo.extend(Roo.dialog.UploadCropbox, Roo.Component, { + + emptyText : 'Click to upload image', + rotateNotify : 'Image is too small to rotate', + errorTimeout : 3000, + scale : 0, + baseScale : 1, + rotate : 0, + dragable : false, + pinching : false, + mouseX : 0, + mouseY : 0, + cropData : false, + minWidth : 300, + minHeight : 300, + outputMaxWidth : 1200, + windowSize : 300, + file : false, + exif : {}, + baseRotate : 1, + cropType : 'image/jpeg', + buttons : false, + canvasLoaded : false, + isDocument : false, + method : 'POST', + paramName : 'imageUpload', + loadMask : true, + loadingText : 'Loading...', + maskEl : false, + + getAutoCreate : function() + { + var cfg = { + tag : 'div', + cls : 'roo-upload-cropbox', + cn : [ + { + tag : 'input', + cls : 'roo-upload-cropbox-selector', + type : 'file' + }, + { + tag : 'div', + cls : 'roo-upload-cropbox-body', + style : 'cursor:pointer', + cn : [ + { + tag : 'div', + cls : 'roo-upload-cropbox-preview' + }, + { + tag : 'div', + cls : 'roo-upload-cropbox-thumb' + }, + { + tag : 'div', + cls : 'roo-upload-cropbox-empty-notify', + html : this.emptyText + }, + { + tag : 'div', + cls : 'roo-upload-cropbox-error-notify alert alert-danger', + html : this.rotateNotify + } + ] + }, + { + tag : 'div', + cls : 'roo-upload-cropbox-footer', + cn : { + tag : 'div', + cls : 'btn-group btn-group-justified roo-upload-cropbox-btn-group', + cn : [] + } + } + ] + }; + + return cfg; + }, + + onRender : function(ct, position) + { + Roo.dialog.UploadCropbox.superclass.onRender.call(this, ct, position); + + if(this.el){ + if (this.el.attr('xtype')) { + this.el.attr('xtypex', this.el.attr('xtype')); + this.el.dom.removeAttribute('xtype'); + + this.initEvents(); + } + } + else { + var cfg = Roo.apply({}, this.getAutoCreate()); + + cfg.id = this.id || Roo.id(); + + if (this.cls) { + cfg.cls = (typeof(cfg.cls) == 'undefined' ? this.cls : cfg.cls) + ' ' + this.cls; + } + + if (this.style) { // fixme needs to support more complex style data. + cfg.style = (typeof(cfg.style) == 'undefined' ? this.style : cfg.style) + '; ' + this.style; + } + + this.el = ct.createChild(cfg, position); + + this.initEvents(); + } + + if (this.buttons.length) { + + Roo.each(this.buttons, function(bb) { + + var btn = this.el.select('.roo-upload-cropbox-footer div.roo-upload-cropbox-btn-group').first().createChild(bb); + + btn.on('click', this.onFooterButtonClick.createDelegate(this, [bb.action], true)); + + }, this); + } + + if(this.loadMask){ + this.maskEl = this.el; + } + }, + + initEvents : function() + { + this.urlAPI = (window.createObjectURL && window) || + (window.URL && URL.revokeObjectURL && URL) || + (window.webkitURL && webkitURL); + + this.bodyEl = this.el.select('.roo-upload-cropbox-body', true).first(); + this.bodyEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block'; + + this.selectorEl = this.el.select('.roo-upload-cropbox-selector', true).first(); + this.selectorEl.hide(); + + this.previewEl = this.el.select('.roo-upload-cropbox-preview', true).first(); + this.previewEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block'; + + this.thumbEl = this.el.select('.roo-upload-cropbox-thumb', true).first(); + this.thumbEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block'; + this.thumbEl.hide(); + + this.notifyEl = this.el.select('.roo-upload-cropbox-empty-notify', true).first(); + this.notifyEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block'; + + this.errorEl = this.el.select('.roo-upload-cropbox-error-notify', true).first(); + this.errorEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block'; + this.errorEl.hide(); + + this.footerEl = this.el.select('.roo-upload-cropbox-footer', true).first(); + this.footerEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block'; + this.footerEl.hide(); + + this.setThumbBoxSize(); + + this.bind(); + + this.resize(); + + this.fireEvent('initial', this); + }, + + bind : function() + { + var _this = this; + + window.addEventListener("resize", function() { _this.resize(); } ); + + this.bodyEl.on('click', this.beforeSelectFile, this); + + if(Roo.isTouch){ + this.bodyEl.on('touchstart', this.onTouchStart, this); + this.bodyEl.on('touchmove', this.onTouchMove, this); + this.bodyEl.on('touchend', this.onTouchEnd, this); + } + + if(!Roo.isTouch){ + this.bodyEl.on('mousedown', this.onMouseDown, this); + this.bodyEl.on('mousemove', this.onMouseMove, this); + var mousewheel = (/Firefox/i.test(navigator.userAgent))? 'DOMMouseScroll' : 'mousewheel'; + this.bodyEl.on(mousewheel, this.onMouseWheel, this); + Roo.get(document).on('mouseup', this.onMouseUp, this); + } + + this.selectorEl.on('change', this.onFileSelected, this); + }, + + reset : function() + { + this.scale = 0; + this.baseScale = 1; + this.rotate = 0; + this.baseRotate = 1; + this.dragable = false; + this.pinching = false; + this.mouseX = 0; + this.mouseY = 0; + this.cropData = false; + this.notifyEl.dom.innerHTML = this.emptyText; + + // this.selectorEl.dom.value = ''; + + }, + + resize : function() + { + if(this.fireEvent('resize', this) != false){ + this.setThumbBoxPosition(); + this.setCanvasPosition(); + } + }, + + onFooterButtonClick : function(e, el, o, type) + { + switch (type) { + case 'rotate-left' : + this.onRotateLeft(e); + break; + case 'rotate-right' : + this.onRotateRight(e); + break; + case 'picture' : + this.beforeSelectFile(e); + break; + case 'trash' : + this.trash(e); + break; + case 'crop' : + this.crop(e); + break; + case 'download' : + this.download(e); + break; + default : + break; + } + + this.fireEvent('footerbuttonclick', this, type); + }, + + beforeSelectFile : function(e) + { + e.preventDefault(); + + if(this.fireEvent('beforeselectfile', this) != false){ + this.selectorEl.dom.click(); + } + }, + + onFileSelected : function(e) + { + e.preventDefault(); + + if(typeof(this.selectorEl.dom.files) == 'undefined' || !this.selectorEl.dom.files.length){ + return; + } + + var file = this.selectorEl.dom.files[0]; + + if(this.fireEvent('inspect', this, file) != false){ + this.prepare(file); + } + + }, + + trash : function(e) + { + this.fireEvent('trash', this); + }, + + download : function(e) + { + this.fireEvent('download', this); + }, + + loadCanvas : function(src) + { + if(this.fireEvent('beforeloadcanvas', this, src) != false){ + + this.reset(); + + this.imageEl = document.createElement('img'); + + var _this = this; + + this.imageEl.addEventListener("load", function(){ _this.onLoadCanvas(); }); + + this.imageEl.src = src; + } + }, + + onLoadCanvas : function() + { + this.imageEl.OriginWidth = this.imageEl.naturalWidth || this.imageEl.width; + this.imageEl.OriginHeight = this.imageEl.naturalHeight || this.imageEl.height; + + if(this.fireEvent('loadcanvas', this, this.imageEl) != false){ + + this.bodyEl.un('click', this.beforeSelectFile, this); + + this.notifyEl.hide(); + this.thumbEl.show(); + this.footerEl.show(); + + this.baseRotateLevel(); + + if(this.isDocument){ + this.setThumbBoxSize(); + } + + this.setThumbBoxPosition(); + + this.baseScaleLevel(); + + this.draw(); + + this.resize(); + + this.canvasLoaded = true; + + } + + if(this.loadMask){ + this.maskEl.unmask(); + } + + }, + + setCanvasPosition : function() + { + if(!this.canvasEl){ + return; + } + + var pw = Math.ceil((this.bodyEl.getWidth() - this.canvasEl.width) / 2); + var ph = Math.ceil((this.bodyEl.getHeight() - this.canvasEl.height) / 2); + + this.previewEl.setLeft(pw); + this.previewEl.setTop(ph); + + }, + + onMouseDown : function(e) + { + e.stopEvent(); + + this.dragable = true; + this.pinching = false; + + if(this.isDocument && (this.canvasEl.width < this.thumbEl.getWidth() || this.canvasEl.height < this.thumbEl.getHeight())){ + this.dragable = false; + return; + } + + this.mouseX = Roo.isTouch ? e.browserEvent.touches[0].pageX : e.getPageX(); + this.mouseY = Roo.isTouch ? e.browserEvent.touches[0].pageY : e.getPageY(); + + }, + + onMouseMove : function(e) + { + e.stopEvent(); + + if(!this.canvasLoaded){ + return; + } + + if (!this.dragable){ + return; + } + + var minX = Math.ceil(this.thumbEl.getLeft(true)); + var minY = Math.ceil(this.thumbEl.getTop(true)); + + var maxX = Math.ceil(minX + this.thumbEl.getWidth() - this.canvasEl.width); + var maxY = Math.ceil(minY + this.thumbEl.getHeight() - this.canvasEl.height); + + if(minX > maxX) { + var tempX = minX; + minX = maxX; + maxX = tempX; + } + + if(minY > maxY) { + var tempY = minY; + minY = maxY; + maxY = tempY; + } + + var x = Roo.isTouch ? e.browserEvent.touches[0].pageX : e.getPageX(); + var y = Roo.isTouch ? e.browserEvent.touches[0].pageY : e.getPageY(); + + x = x - this.mouseX; + y = y - this.mouseY; + + var bgX = Math.ceil(x + this.previewEl.getLeft(true)); + var bgY = Math.ceil(y + this.previewEl.getTop(true)); + + bgX = (bgX < minX) ? minX : ((bgX > maxX) ? maxX : bgX); + bgY = (bgY < minY) ? minY : ((bgY > maxY) ? maxY : bgY); + + this.previewEl.setLeft(bgX); + this.previewEl.setTop(bgY); + + this.mouseX = Roo.isTouch ? e.browserEvent.touches[0].pageX : e.getPageX(); + this.mouseY = Roo.isTouch ? e.browserEvent.touches[0].pageY : e.getPageY(); + }, + + onMouseUp : function(e) + { + e.stopEvent(); + + this.dragable = false; + }, + + onMouseWheel : function(e) + { + e.stopEvent(); + + this.startScale = this.scale; + this.scale = (e.getWheelDelta() > 0) ? (this.scale + 1) : (this.scale - 1); + + if(!this.zoomable()){ + this.scale = this.startScale; + return; + } + + + this.draw(); + + return; + }, + + zoomable : function() + { + var minScale = this.thumbEl.getWidth() / this.minWidth; + + if(this.minWidth < this.minHeight){ + minScale = this.thumbEl.getHeight() / this.minHeight; + } + + var width = Math.ceil(this.imageEl.OriginWidth * this.getScaleLevel() / minScale); + var height = Math.ceil(this.imageEl.OriginHeight * this.getScaleLevel() / minScale); + + var maxWidth = this.imageEl.OriginWidth; + var maxHeight = this.imageEl.OriginHeight; + + if( + this.isDocument && + (this.rotate == 0 || this.rotate == 180) && + ( + width > this.imageEl.OriginWidth || + height > this.imageEl.OriginHeight || + (width < this.minWidth && height < this.minHeight) + ) + ){ + return false; + } + + if( + this.isDocument && + (this.rotate == 90 || this.rotate == 270) && + ( + width > this.imageEl.OriginWidth || + height > this.imageEl.OriginHeight || + (width < this.minHeight && height < this.minWidth) + ) + ){ + return false; + } + + if( + !this.isDocument && + (this.rotate == 0 || this.rotate == 180) && + ( + (this.imageEl.OriginWidth / this.imageEl.OriginHeight >= this.minWidth / this.minHeight) && width < this.minWidth || + (this.imageEl.OriginWidth / this.imageEl.OriginHeight <= this.minWidth / this.minHeight) && height < this.minHeight || + width > maxWidth || + height > maxHeight + ) + ){ + return false; + } + + if( + !this.isDocument && + (this.rotate == 90 || this.rotate == 270) && + ( + width < this.minHeight || + width > this.imageEl.OriginWidth || + height < this.minWidth || + height > this.imageEl.OriginHeight + ) + ){ + return false; + } + + return true; + + }, + + onRotateLeft : function(e) + { + if(!this.isDocument && (this.canvasEl.height < this.thumbEl.getWidth() || this.canvasEl.width < this.thumbEl.getHeight())){ + + var minScale = this.thumbEl.getWidth() / this.minWidth; + + var bw = Math.ceil(this.canvasEl.width / this.getScaleLevel()); + var bh = Math.ceil(this.canvasEl.height / this.getScaleLevel()); + + this.startScale = this.scale; + + while (this.getScaleLevel() < minScale){ + + this.scale = this.scale + 1; + + if(!this.zoomable()){ + break; + } + + if( + Math.ceil(bw * this.getScaleLevel()) < this.thumbEl.getHeight() || + Math.ceil(bh * this.getScaleLevel()) < this.thumbEl.getWidth() + ){ + continue; + } + + this.rotate = (this.rotate < 90) ? 270 : this.rotate - 90; + + this.draw(); + + return; + } + + this.scale = this.startScale; + + this.onRotateFail(); + + return false; + } + + this.rotate = (this.rotate < 90) ? 270 : this.rotate - 90; + + if(this.isDocument){ + this.setThumbBoxSize(); + this.setThumbBoxPosition(); + this.setCanvasPosition(); + } + + this.draw(); + + this.fireEvent('rotate', this, 'left'); + + }, + + onRotateRight : function(e) + { + if(!this.isDocument && (this.canvasEl.height < this.thumbEl.getWidth() || this.canvasEl.width < this.thumbEl.getHeight())){ + + var minScale = this.thumbEl.getWidth() / this.minWidth; + + var bw = Math.ceil(this.canvasEl.width / this.getScaleLevel()); + var bh = Math.ceil(this.canvasEl.height / this.getScaleLevel()); + + this.startScale = this.scale; + + while (this.getScaleLevel() < minScale){ + + this.scale = this.scale + 1; + + if(!this.zoomable()){ + break; + } + + if( + Math.ceil(bw * this.getScaleLevel()) < this.thumbEl.getHeight() || + Math.ceil(bh * this.getScaleLevel()) < this.thumbEl.getWidth() + ){ + continue; + } + + this.rotate = (this.rotate > 180) ? 0 : this.rotate + 90; + + this.draw(); + + return; + } + + this.scale = this.startScale; + + this.onRotateFail(); + + return false; + } + + this.rotate = (this.rotate > 180) ? 0 : this.rotate + 90; + + if(this.isDocument){ + this.setThumbBoxSize(); + this.setThumbBoxPosition(); + this.setCanvasPosition(); + } + + this.draw(); + + this.fireEvent('rotate', this, 'right'); + }, + + onRotateFail : function() + { + this.errorEl.show(true); + + var _this = this; + + (function() { _this.errorEl.hide(true); }).defer(this.errorTimeout); + }, + + draw : function() + { + this.previewEl.dom.innerHTML = ''; + + var canvasEl = document.createElement("canvas"); + + var contextEl = canvasEl.getContext("2d"); + + canvasEl.width = this.imageEl.OriginWidth * this.getScaleLevel(); + canvasEl.height = this.imageEl.OriginWidth * this.getScaleLevel(); + var center = this.imageEl.OriginWidth / 2; + + if(this.imageEl.OriginWidth < this.imageEl.OriginHeight){ + canvasEl.width = this.imageEl.OriginHeight * this.getScaleLevel(); + canvasEl.height = this.imageEl.OriginHeight * this.getScaleLevel(); + center = this.imageEl.OriginHeight / 2; + } + + contextEl.scale(this.getScaleLevel(), this.getScaleLevel()); + + contextEl.translate(center, center); + contextEl.rotate(this.rotate * Math.PI / 180); + + contextEl.drawImage(this.imageEl, 0, 0, this.imageEl.OriginWidth, this.imageEl.OriginHeight, center * -1, center * -1, this.imageEl.OriginWidth, this.imageEl.OriginHeight); + + this.canvasEl = document.createElement("canvas"); + + this.contextEl = this.canvasEl.getContext("2d"); + + switch (this.rotate) { + case 0 : + + this.canvasEl.width = this.imageEl.OriginWidth * this.getScaleLevel(); + this.canvasEl.height = this.imageEl.OriginHeight * this.getScaleLevel(); + + this.contextEl.drawImage(canvasEl, 0, 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height); + + break; + case 90 : + + this.canvasEl.width = this.imageEl.OriginHeight * this.getScaleLevel(); + this.canvasEl.height = this.imageEl.OriginWidth * this.getScaleLevel(); + + if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){ + this.contextEl.drawImage(canvasEl, Math.abs(this.canvasEl.width - this.canvasEl.height), 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height); + break; + } + + this.contextEl.drawImage(canvasEl, 0, 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height); + + break; + case 180 : + + this.canvasEl.width = this.imageEl.OriginWidth * this.getScaleLevel(); + this.canvasEl.height = this.imageEl.OriginHeight * this.getScaleLevel(); + + if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){ + this.contextEl.drawImage(canvasEl, 0, Math.abs(this.canvasEl.width - this.canvasEl.height), this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height); + break; + } + + this.contextEl.drawImage(canvasEl, Math.abs(this.canvasEl.width - this.canvasEl.height), 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height); + + break; + case 270 : + + this.canvasEl.width = this.imageEl.OriginHeight * this.getScaleLevel(); + this.canvasEl.height = this.imageEl.OriginWidth * this.getScaleLevel(); + + if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){ + this.contextEl.drawImage(canvasEl, 0, 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height); + break; + } + + this.contextEl.drawImage(canvasEl, 0, Math.abs(this.canvasEl.width - this.canvasEl.height), this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height); + + break; + default : + break; + } + + this.previewEl.appendChild(this.canvasEl); + + this.setCanvasPosition(); + }, + + crop : function() + { + if(!this.canvasLoaded){ + return; + } + + var imageCanvas = document.createElement("canvas"); + + var imageContext = imageCanvas.getContext("2d"); + + imageCanvas.width = (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? this.imageEl.OriginWidth : this.imageEl.OriginHeight; + imageCanvas.height = (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? this.imageEl.OriginWidth : this.imageEl.OriginHeight; + + var center = imageCanvas.width / 2; + + imageContext.translate(center, center); + + imageContext.rotate(this.rotate * Math.PI / 180); + + imageContext.drawImage(this.imageEl, 0, 0, this.imageEl.OriginWidth, this.imageEl.OriginHeight, center * -1, center * -1, this.imageEl.OriginWidth, this.imageEl.OriginHeight); + + var canvas = document.createElement("canvas"); + + var context = canvas.getContext("2d"); + + canvas.width = this.thumbEl.getWidth() / this.getScaleLevel(); + + canvas.height = this.thumbEl.getHeight() / this.getScaleLevel(); + + switch (this.rotate) { + case 0 : + + var width = (this.thumbEl.getWidth() / this.getScaleLevel() > this.imageEl.OriginWidth) ? this.imageEl.OriginWidth : (this.thumbEl.getWidth() / this.getScaleLevel()); + var height = (this.thumbEl.getHeight() / this.getScaleLevel() > this.imageEl.OriginHeight) ? this.imageEl.OriginHeight : (this.thumbEl.getHeight() / this.getScaleLevel()); + + var x = (this.thumbEl.getLeft(true) > this.previewEl.getLeft(true)) ? 0 : ((this.previewEl.getLeft(true) - this.thumbEl.getLeft(true)) / this.getScaleLevel()); + var y = (this.thumbEl.getTop(true) > this.previewEl.getTop(true)) ? 0 : ((this.previewEl.getTop(true) - this.thumbEl.getTop(true)) / this.getScaleLevel()); + + var sx = this.thumbEl.getLeft(true) - this.previewEl.getLeft(true); + var sy = this.thumbEl.getTop(true) - this.previewEl.getTop(true); + + sx = sx < 0 ? 0 : (sx / this.getScaleLevel()); + sy = sy < 0 ? 0 : (sy / this.getScaleLevel()); + + if(canvas.width > this.outputMaxWidth) { + var scale = this.outputMaxWidth / canvas.width; + canvas.width = canvas.width * scale; + canvas.height = canvas.height * scale; + context.scale(scale, scale); + } + + context.fillStyle = 'white'; + context.fillRect(0, 0, this.thumbEl.getWidth() / this.getScaleLevel(), this.thumbEl.getHeight() / this.getScaleLevel()); + + + context.drawImage(imageCanvas, sx, sy, width, height, x, y, width, height); + + break; + case 90 : + + var width = (this.thumbEl.getWidth() / this.getScaleLevel() > this.imageEl.OriginHeight) ? this.imageEl.OriginHeight : (this.thumbEl.getWidth() / this.getScaleLevel()); + var height = (this.thumbEl.getHeight() / this.getScaleLevel() > this.imageEl.OriginWidth) ? this.imageEl.OriginWidth : (this.thumbEl.getHeight() / this.getScaleLevel()); + + var x = (this.thumbEl.getLeft(true) > this.previewEl.getLeft(true)) ? 0 : ((this.previewEl.getLeft(true) - this.thumbEl.getLeft(true)) / this.getScaleLevel()); + var y = (this.thumbEl.getTop(true) > this.previewEl.getTop(true)) ? 0 : ((this.previewEl.getTop(true) - this.thumbEl.getTop(true)) / this.getScaleLevel()); + + var targetWidth = this.minWidth - 2 * x; + var targetHeight = this.minHeight - 2 * y; + + var scale = 1; + + if((x == 0 && y == 0) || (x == 0 && y > 0)){ + scale = targetWidth / width; + } + + if(x > 0 && y == 0){ + scale = targetHeight / height; + } + + if(x > 0 && y > 0){ + scale = targetWidth / width; + + if(width < height){ + scale = targetHeight / height; + } + } + + context.scale(scale, scale); + + var sx = Math.min(this.canvasEl.width - this.thumbEl.getWidth(), this.thumbEl.getLeft(true) - this.previewEl.getLeft(true)); + var sy = Math.min(this.canvasEl.height - this.thumbEl.getHeight(), this.thumbEl.getTop(true) - this.previewEl.getTop(true)); + + sx = sx < 0 ? 0 : (sx / this.getScaleLevel()); + sy = sy < 0 ? 0 : (sy / this.getScaleLevel()); + + sx += (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? Math.abs(this.imageEl.OriginWidth - this.imageEl.OriginHeight) : 0; + + context.drawImage(imageCanvas, sx, sy, width, height, x, y, width, height); + + break; + case 180 : + + var width = (this.thumbEl.getWidth() / this.getScaleLevel() > this.imageEl.OriginWidth) ? this.imageEl.OriginWidth : (this.thumbEl.getWidth() / this.getScaleLevel()); + var height = (this.thumbEl.getHeight() / this.getScaleLevel() > this.imageEl.OriginHeight) ? this.imageEl.OriginHeight : (this.thumbEl.getHeight() / this.getScaleLevel()); + + var x = (this.thumbEl.getLeft(true) > this.previewEl.getLeft(true)) ? 0 : ((this.previewEl.getLeft(true) - this.thumbEl.getLeft(true)) / this.getScaleLevel()); + var y = (this.thumbEl.getTop(true) > this.previewEl.getTop(true)) ? 0 : ((this.previewEl.getTop(true) - this.thumbEl.getTop(true)) / this.getScaleLevel()); + + var targetWidth = this.minWidth - 2 * x; + var targetHeight = this.minHeight - 2 * y; + + var scale = 1; + + if((x == 0 && y == 0) || (x == 0 && y > 0)){ + scale = targetWidth / width; + } + + if(x > 0 && y == 0){ + scale = targetHeight / height; + } + + if(x > 0 && y > 0){ + scale = targetWidth / width; + + if(width < height){ + scale = targetHeight / height; + } + } + + context.scale(scale, scale); + + var sx = Math.min(this.canvasEl.width - this.thumbEl.getWidth(), this.thumbEl.getLeft(true) - this.previewEl.getLeft(true)); + var sy = Math.min(this.canvasEl.height - this.thumbEl.getHeight(), this.thumbEl.getTop(true) - this.previewEl.getTop(true)); + + sx = sx < 0 ? 0 : (sx / this.getScaleLevel()); + sy = sy < 0 ? 0 : (sy / this.getScaleLevel()); + + sx += (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? 0 : Math.abs(this.imageEl.OriginWidth - this.imageEl.OriginHeight); + sy += (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? Math.abs(this.imageEl.OriginWidth - this.imageEl.OriginHeight) : 0; + + context.drawImage(imageCanvas, sx, sy, width, height, x, y, width, height); + + break; + case 270 : + + var width = (this.thumbEl.getWidth() / this.getScaleLevel() > this.imageEl.OriginHeight) ? this.imageEl.OriginHeight : (this.thumbEl.getWidth() / this.getScaleLevel()); + var height = (this.thumbEl.getHeight() / this.getScaleLevel() > this.imageEl.OriginWidth) ? this.imageEl.OriginWidth : (this.thumbEl.getHeight() / this.getScaleLevel()); + + var x = (this.thumbEl.getLeft(true) > this.previewEl.getLeft(true)) ? 0 : ((this.previewEl.getLeft(true) - this.thumbEl.getLeft(true)) / this.getScaleLevel()); + var y = (this.thumbEl.getTop(true) > this.previewEl.getTop(true)) ? 0 : ((this.previewEl.getTop(true) - this.thumbEl.getTop(true)) / this.getScaleLevel()); + + var targetWidth = this.minWidth - 2 * x; + var targetHeight = this.minHeight - 2 * y; + + var scale = 1; + + if((x == 0 && y == 0) || (x == 0 && y > 0)){ + scale = targetWidth / width; + } + + if(x > 0 && y == 0){ + scale = targetHeight / height; + } + + if(x > 0 && y > 0){ + scale = targetWidth / width; + + if(width < height){ + scale = targetHeight / height; + } + } + + context.scale(scale, scale); + var sx = Math.min(this.canvasEl.width - this.thumbEl.getWidth(), this.thumbEl.getLeft(true) - this.previewEl.getLeft(true)); + var sy = Math.min(this.canvasEl.height - this.thumbEl.getHeight(), this.thumbEl.getTop(true) - this.previewEl.getTop(true)); + + sx = sx < 0 ? 0 : (sx / this.getScaleLevel()); + sy = sy < 0 ? 0 : (sy / this.getScaleLevel()); + + sy += (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? 0 : Math.abs(this.imageEl.OriginWidth - this.imageEl.OriginHeight); + + context.drawImage(imageCanvas, sx, sy, width, height, x, y, width, height); + + break; + default : + break; + } + + this.cropData = canvas.toDataURL(this.cropType); + + if(this.fireEvent('crop', this, this.cropData) !== false){ + this.process(this.file, this.cropData); + } + + return; + + }, + + setThumbBoxSize : function() + { + var width, height; + + if(this.isDocument && typeof(this.imageEl) != 'undefined'){ + width = (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? Math.max(this.minWidth, this.minHeight) : Math.min(this.minWidth, this.minHeight); + height = (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? Math.min(this.minWidth, this.minHeight) : Math.max(this.minWidth, this.minHeight); + + this.minWidth = width; + this.minHeight = height; + + if(this.rotate == 90 || this.rotate == 270){ + this.minWidth = height; + this.minHeight = width; + } + } + + height = this.windowSize; + width = Math.ceil(this.minWidth * height / this.minHeight); + + if(this.minWidth > this.minHeight){ + width = this.windowSize; + height = Math.ceil(this.minHeight * width / this.minWidth); + } + + this.thumbEl.setStyle({ + width : width + 'px', + height : height + 'px' + }); + + return; + + }, + + setThumbBoxPosition : function() + { + var x = Math.ceil((this.bodyEl.getWidth() - this.thumbEl.getWidth()) / 2 ); + var y = Math.ceil((this.bodyEl.getHeight() - this.thumbEl.getHeight()) / 2); + + this.thumbEl.setLeft(x); + this.thumbEl.setTop(y); + + }, + + baseRotateLevel : function() + { + this.baseRotate = 1; + + if( + typeof(this.exif) != 'undefined' && + typeof(this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']]) != 'undefined' && + [1, 3, 6, 8].indexOf(this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']]) != -1 + ){ + this.baseRotate = this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']]; + } + + this.rotate = Roo.dialog.UploadCropbox['Orientation'][this.baseRotate]; + + }, + + baseScaleLevel : function() + { + var width, height; + + if(this.isDocument){ + + if(this.baseRotate == 6 || this.baseRotate == 8){ + + height = this.thumbEl.getHeight(); + this.baseScale = height / this.imageEl.OriginWidth; + + if(this.imageEl.OriginHeight * this.baseScale > this.thumbEl.getWidth()){ + width = this.thumbEl.getWidth(); + this.baseScale = width / this.imageEl.OriginHeight; + } + + return; + } + + height = this.thumbEl.getHeight(); + this.baseScale = height / this.imageEl.OriginHeight; + + if(this.imageEl.OriginWidth * this.baseScale > this.thumbEl.getWidth()){ + width = this.thumbEl.getWidth(); + this.baseScale = width / this.imageEl.OriginWidth; + } + + return; + } + + if(this.baseRotate == 6 || this.baseRotate == 8){ + + width = this.thumbEl.getHeight(); + this.baseScale = width / this.imageEl.OriginHeight; + + if(this.imageEl.OriginHeight * this.baseScale < this.thumbEl.getWidth()){ + height = this.thumbEl.getWidth(); + this.baseScale = height / this.imageEl.OriginHeight; + } + + if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){ + height = this.thumbEl.getWidth(); + this.baseScale = height / this.imageEl.OriginHeight; + + if(this.imageEl.OriginWidth * this.baseScale < this.thumbEl.getHeight()){ + width = this.thumbEl.getHeight(); + this.baseScale = width / this.imageEl.OriginWidth; + } + } + + return; + } + + width = this.thumbEl.getWidth(); + this.baseScale = width / this.imageEl.OriginWidth; + + if(this.imageEl.OriginHeight * this.baseScale < this.thumbEl.getHeight()){ + height = this.thumbEl.getHeight(); + this.baseScale = height / this.imageEl.OriginHeight; + } + + if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){ + + height = this.thumbEl.getHeight(); + this.baseScale = height / this.imageEl.OriginHeight; + + if(this.imageEl.OriginWidth * this.baseScale < this.thumbEl.getWidth()){ + width = this.thumbEl.getWidth(); + this.baseScale = width / this.imageEl.OriginWidth; + } + + } + + if(this.imageEl.OriginWidth < this.minWidth || this.imageEl.OriginHeight < this.minHeight) { + this.baseScale = width / this.minWidth; + } + + return; + }, + + getScaleLevel : function() + { + return this.baseScale * Math.pow(1.02, this.scale); + }, + + onTouchStart : function(e) + { + if(!this.canvasLoaded){ + this.beforeSelectFile(e); + return; + } + + var touches = e.browserEvent.touches; + + if(!touches){ + return; + } + + if(touches.length == 1){ + this.onMouseDown(e); + return; + } + + if(touches.length != 2){ + return; + } + + var coords = []; + + for(var i = 0, finger; finger = touches[i]; i++){ + coords.push(finger.pageX, finger.pageY); + } + + var x = Math.pow(coords[0] - coords[2], 2); + var y = Math.pow(coords[1] - coords[3], 2); + + this.startDistance = Math.sqrt(x + y); + + this.startScale = this.scale; + + this.pinching = true; + this.dragable = false; + + }, + + onTouchMove : function(e) + { + if(!this.pinching && !this.dragable){ + return; + } + + var touches = e.browserEvent.touches; + + if(!touches){ + return; + } + + if(this.dragable){ + this.onMouseMove(e); + return; + } + + var coords = []; + + for(var i = 0, finger; finger = touches[i]; i++){ + coords.push(finger.pageX, finger.pageY); + } + + var x = Math.pow(coords[0] - coords[2], 2); + var y = Math.pow(coords[1] - coords[3], 2); + + this.endDistance = Math.sqrt(x + y); + + this.scale = this.startScale + Math.floor(Math.log(this.endDistance / this.startDistance) / Math.log(1.1)); + + if(!this.zoomable()){ + this.scale = this.startScale; + return; + } + + this.draw(); + + }, + + onTouchEnd : function(e) + { + this.pinching = false; + this.dragable = false; + + }, + + process : function(file, crop) + { + if(this.loadMask){ + this.maskEl.mask(this.loadingText); + } + + this.xhr = new XMLHttpRequest(); + + file.xhr = this.xhr; + + this.xhr.open(this.method, this.url, true); + + var headers = { + "Accept": "application/json", + "Cache-Control": "no-cache", + "X-Requested-With": "XMLHttpRequest" + }; + + for (var headerName in headers) { + var headerValue = headers[headerName]; + if (headerValue) { + this.xhr.setRequestHeader(headerName, headerValue); + } + } + + var _this = this; + + this.xhr.onload = function() + { + _this.xhrOnLoad(_this.xhr); + } + + this.xhr.onerror = function() + { + _this.xhrOnError(_this.xhr); + } + + var formData = new FormData(); + + formData.append('returnHTML', 'NO'); + + if(crop){ + formData.append('crop', crop); + var blobBin = atob(crop.split(',')[1]); + var array = []; + for(var i = 0; i < blobBin.length; i++) { + array.push(blobBin.charCodeAt(i)); + } + var croppedFile =new Blob([new Uint8Array(array)], {type: this.cropType}); + formData.append(this.paramName, croppedFile, file.name); + } + + if(typeof(file.filename) != 'undefined'){ + formData.append('filename', file.filename); + } + + if(typeof(file.mimetype) != 'undefined'){ + formData.append('mimetype', file.mimetype); + } + + if(this.fireEvent('arrange', this, formData) != false){ + this.xhr.send(formData); + }; + }, + + xhrOnLoad : function(xhr) + { + if(this.loadMask){ + this.maskEl.unmask(); + } + + if (xhr.readyState !== 4) { + this.fireEvent('exception', this, xhr); + return; + } + + var response = Roo.decode(xhr.responseText); + + if(!response.success){ + this.fireEvent('exception', this, xhr); + return; + } + + var response = Roo.decode(xhr.responseText); + + this.fireEvent('upload', this, response); + + }, + + xhrOnError : function() + { + if(this.loadMask){ + this.maskEl.unmask(); + } + + Roo.log('xhr on error'); + + var response = Roo.decode(xhr.responseText); + + Roo.log(response); + + }, + + prepare : function(file) + { + if(this.loadMask){ + this.maskEl.mask(this.loadingText); + } + + this.file = false; + this.exif = {}; + + if(typeof(file) === 'string'){ + this.loadCanvas(file); + return; + } + + if(!file || !this.urlAPI){ + return; + } + + this.file = file; + if(typeof(file.type) != 'undefined' && file.type.length != 0) { + this.cropType = file.type; + } + + var _this = this; + + if(this.fireEvent('prepare', this, this.file) != false){ + + var reader = new FileReader(); + + reader.onload = function (e) { + if (e.target.error) { + Roo.log(e.target.error); + return; + } + + var buffer = e.target.result, + dataView = new DataView(buffer), + offset = 2, + maxOffset = dataView.byteLength - 4, + markerBytes, + markerLength; + + if (dataView.getUint16(0) === 0xffd8) { + while (offset < maxOffset) { + markerBytes = dataView.getUint16(offset); + + if ((markerBytes >= 0xffe0 && markerBytes <= 0xffef) || markerBytes === 0xfffe) { + markerLength = dataView.getUint16(offset + 2) + 2; + if (offset + markerLength > dataView.byteLength) { + Roo.log('Invalid meta data: Invalid segment size.'); + break; + } + + if(markerBytes == 0xffe1){ + _this.parseExifData( + dataView, + offset, + markerLength + ); + } + + offset += markerLength; + + continue; + } + + break; + } + + } + + var url = _this.urlAPI.createObjectURL(_this.file); + + _this.loadCanvas(url); + + return; + } + + reader.readAsArrayBuffer(this.file); + + } + + }, + + parseExifData : function(dataView, offset, length) + { + var tiffOffset = offset + 10, + littleEndian, + dirOffset; + + if (dataView.getUint32(offset + 4) !== 0x45786966) { + // No Exif data, might be XMP data instead + return; + } + + // Check for the ASCII code for "Exif" (0x45786966): + if (dataView.getUint32(offset + 4) !== 0x45786966) { + // No Exif data, might be XMP data instead + return; + } + if (tiffOffset + 8 > dataView.byteLength) { + Roo.log('Invalid Exif data: Invalid segment size.'); + return; + } + // Check for the two null bytes: + if (dataView.getUint16(offset + 8) !== 0x0000) { + Roo.log('Invalid Exif data: Missing byte alignment offset.'); + return; + } + // Check the byte alignment: + switch (dataView.getUint16(tiffOffset)) { + case 0x4949: + littleEndian = true; + break; + case 0x4D4D: + littleEndian = false; + break; + default: + Roo.log('Invalid Exif data: Invalid byte alignment marker.'); + return; + } + // Check for the TIFF tag marker (0x002A): + if (dataView.getUint16(tiffOffset + 2, littleEndian) !== 0x002A) { + Roo.log('Invalid Exif data: Missing TIFF marker.'); + return; + } + // Retrieve the directory offset bytes, usually 0x00000008 or 8 decimal: + dirOffset = dataView.getUint32(tiffOffset + 4, littleEndian); + + this.parseExifTags( + dataView, + tiffOffset, + tiffOffset + dirOffset, + littleEndian + ); + }, + + parseExifTags : function(dataView, tiffOffset, dirOffset, littleEndian) + { + var tagsNumber, + dirEndOffset, + i; + if (dirOffset + 6 > dataView.byteLength) { + Roo.log('Invalid Exif data: Invalid directory offset.'); + return; + } + tagsNumber = dataView.getUint16(dirOffset, littleEndian); + dirEndOffset = dirOffset + 2 + 12 * tagsNumber; + if (dirEndOffset + 4 > dataView.byteLength) { + Roo.log('Invalid Exif data: Invalid directory size.'); + return; + } + for (i = 0; i < tagsNumber; i += 1) { + this.parseExifTag( + dataView, + tiffOffset, + dirOffset + 2 + 12 * i, // tag offset + littleEndian + ); + } + // Return the offset to the next directory: + return dataView.getUint32(dirEndOffset, littleEndian); + }, + + parseExifTag : function (dataView, tiffOffset, offset, littleEndian) + { + var tag = dataView.getUint16(offset, littleEndian); + + this.exif[tag] = this.getExifValue( + dataView, + tiffOffset, + offset, + dataView.getUint16(offset + 2, littleEndian), // tag type + dataView.getUint32(offset + 4, littleEndian), // tag length + littleEndian + ); + }, + + getExifValue : function (dataView, tiffOffset, offset, type, length, littleEndian) + { + var tagType = Roo.dialog.UploadCropbox.exifTagTypes[type], + tagSize, + dataOffset, + values, + i, + str, + c; + + if (!tagType) { + Roo.log('Invalid Exif data: Invalid tag type.'); + return; + } + + tagSize = tagType.size * length; + // Determine if the value is contained in the dataOffset bytes, + // or if the value at the dataOffset is a pointer to the actual data: + dataOffset = tagSize > 4 ? + tiffOffset + dataView.getUint32(offset + 8, littleEndian) : (offset + 8); + if (dataOffset + tagSize > dataView.byteLength) { + Roo.log('Invalid Exif data: Invalid data offset.'); + return; + } + if (length === 1) { + return tagType.getValue(dataView, dataOffset, littleEndian); + } + values = []; + for (i = 0; i < length; i += 1) { + values[i] = tagType.getValue(dataView, dataOffset + i * tagType.size, littleEndian); + } + + if (tagType.ascii) { + str = ''; + // Concatenate the chars: + for (i = 0; i < values.length; i += 1) { + c = values[i]; + // Ignore the terminating NULL byte(s): + if (c === '\u0000') { + break; + } + str += c; + } + return str; + } + return values; + } + +}); + +Roo.apply(Roo.dialog.UploadCropbox, { + tags : { + 'Orientation': 0x0112 + }, + + Orientation: { + 1: 0, //'top-left', +// 2: 'top-right', + 3: 180, //'bottom-right', +// 4: 'bottom-left', +// 5: 'left-top', + 6: 90, //'right-top', +// 7: 'right-bottom', + 8: 270 //'left-bottom' + }, + + exifTagTypes : { + // byte, 8-bit unsigned int: + 1: { + getValue: function (dataView, dataOffset) { + return dataView.getUint8(dataOffset); + }, + size: 1 + }, + // ascii, 8-bit byte: + 2: { + getValue: function (dataView, dataOffset) { + return String.fromCharCode(dataView.getUint8(dataOffset)); + }, + size: 1, + ascii: true + }, + // short, 16 bit int: + 3: { + getValue: function (dataView, dataOffset, littleEndian) { + return dataView.getUint16(dataOffset, littleEndian); + }, + size: 2 + }, + // long, 32 bit int: + 4: { + getValue: function (dataView, dataOffset, littleEndian) { + return dataView.getUint32(dataOffset, littleEndian); + }, + size: 4 + }, + // rational = two long values, first is numerator, second is denominator: + 5: { + getValue: function (dataView, dataOffset, littleEndian) { + return dataView.getUint32(dataOffset, littleEndian) / + dataView.getUint32(dataOffset + 4, littleEndian); + }, + size: 8 + }, + // slong, 32 bit signed int: + 9: { + getValue: function (dataView, dataOffset, littleEndian) { + return dataView.getInt32(dataOffset, littleEndian); + }, + size: 4 + }, + // srational, two slongs, first is numerator, second is denominator: + 10: { + getValue: function (dataView, dataOffset, littleEndian) { + return dataView.getInt32(dataOffset, littleEndian) / + dataView.getInt32(dataOffset + 4, littleEndian); + }, + size: 8 + } + }, + + footer : { + STANDARD : [ + { + tag : 'div', + cls : 'btn-group roo-upload-cropbox-rotate-left', + action : 'rotate-left', + cn : [ + { + tag : 'button', + cls : 'btn btn-default', + html : '' + } + ] + }, + { + tag : 'div', + cls : 'btn-group roo-upload-cropbox-picture', + action : 'picture', + cn : [ + { + tag : 'button', + cls : 'btn btn-default', + html : '' + } + ] + }, + { + tag : 'div', + cls : 'btn-group roo-upload-cropbox-rotate-right', + action : 'rotate-right', + cn : [ + { + tag : 'button', + cls : 'btn btn-default', + html : '' + } + ] + } + ], + DOCUMENT : [ + { + tag : 'div', + cls : 'btn-group roo-upload-cropbox-rotate-left', + action : 'rotate-left', + cn : [ + { + tag : 'button', + cls : 'btn btn-default', + html : '' + } + ] + }, + { + tag : 'div', + cls : 'btn-group roo-upload-cropbox-download', + action : 'download', + cn : [ + { + tag : 'button', + cls : 'btn btn-default', + html : '' + } + ] + }, + { + tag : 'div', + cls : 'btn-group roo-upload-cropbox-crop', + action : 'crop', + cn : [ + { + tag : 'button', + cls : 'btn btn-default', + html : '' + } + ] + }, + { + tag : 'div', + cls : 'btn-group roo-upload-cropbox-trash', + action : 'trash', + cn : [ + { + tag : 'button', + cls : 'btn btn-default', + html : '' + } + ] + }, + { + tag : 'div', + cls : 'btn-group roo-upload-cropbox-rotate-right', + action : 'rotate-right', + cn : [ + { + tag : 'button', + cls : 'btn btn-default', + html : '' + } + ] + } + ], + ROTATOR : [ + { + tag : 'div', + cls : 'btn-group roo-upload-cropbox-rotate-left', + action : 'rotate-left', + cn : [ + { + tag : 'button', + cls : 'btn btn-default', + html : '' + } + ] + }, + { + tag : 'div', + cls : 'btn-group roo-upload-cropbox-rotate-right', + action : 'rotate-right', + cn : [ + { + tag : 'button', + cls : 'btn btn-default', + html : '' + } + ] + } + ] + } +}); diff --git a/roojs-ui-debug.js b/roojs-ui-debug.js index b25bce4fc1..c9b83ff0a1 100644 --- a/roojs-ui-debug.js +++ b/roojs-ui-debug.js @@ -36065,7 +36065,6 @@ Roo.LayoutStateManager.prototype = { */ Roo.ContentPanel = function(el, config, content){ - /* if(el.autoCreate || el.xtype){ // xtype is available if this is called from factory config = el; @@ -36449,6 +36448,14 @@ layout.addxtype({ */ addxtype : function(cfg) { + if(cfg.xtype.match(/^UploadCropbox$/)) { + + this.cropbox = new Roo.factory(cfg); + + this.cropbox.render(this.el); + + return this.cropbox; + } // add form.. if (cfg.xtype.match(/^Form$/)) { @@ -43701,4 +43708,1808 @@ Roo.extend(Roo.XTemplate, Roo.Template, { Roo.XTemplate.from = function(el){ el = Roo.getDom(el); return new Roo.XTemplate(el.value || el.innerHTML); -}; \ No newline at end of file +};Roo.dialog = {}; +/* +* Licence: LGPL +*/ + +/** + * @class Roo.dialog.UploadCropbox + * @extends Roo.BoxComponent + * Dialog UploadCropbox class + * @cfg {String} emptyText show when image has been loaded + * @cfg {String} rotateNotify show when image too small to rotate + * @cfg {Number} errorTimeout default 3000 + * @cfg {Number} minWidth default 300 + * @cfg {Number} minHeight default 300 + * @cfg {Number} outputMaxWidth default 1200 + * @cfg {Number} windowSize default 300 + * @cfg {Array} buttons default ['rotateLeft', 'pictureBtn', 'rotateRight'] + * @cfg {Boolean} isDocument (true|false) default false + * @cfg {String} url action url + * @cfg {String} paramName default 'imageUpload' + * @cfg {String} method default POST + * @cfg {Boolean} loadMask (true|false) default true + * @cfg {Boolean} loadingText default 'Loading...' + * + * @constructor + * Create a new UploadCropbox + * @param {Object} config The config object + */ + + Roo.dialog.UploadCropbox = function(config){ + Roo.dialog.UploadCropbox.superclass.constructor.call(this, config); + + this.addEvents({ + /** + * @event beforeselectfile + * Fire before select file + * @param {Roo.dialog.UploadCropbox} this + */ + "beforeselectfile" : true, + /** + * @event initial + * Fire after initEvent + * @param {Roo.dialog.UploadCropbox} this + */ + "initial" : true, + /** + * @event crop + * Fire after initEvent + * @param {Roo.dialog.UploadCropbox} this + * @param {String} data + */ + "crop" : true, + /** + * @event prepare + * Fire when preparing the file data + * @param {Roo.dialog.UploadCropbox} this + * @param {Object} file + */ + "prepare" : true, + /** + * @event exception + * Fire when get exception + * @param {Roo.dialog.UploadCropbox} this + * @param {XMLHttpRequest} xhr + */ + "exception" : true, + /** + * @event beforeloadcanvas + * Fire before load the canvas + * @param {Roo.dialog.UploadCropbox} this + * @param {String} src + */ + "beforeloadcanvas" : true, + /** + * @event trash + * Fire when trash image + * @param {Roo.dialog.UploadCropbox} this + */ + "trash" : true, + /** + * @event download + * Fire when download the image + * @param {Roo.dialog.UploadCropbox} this + */ + "download" : true, + /** + * @event footerbuttonclick + * Fire when footerbuttonclick + * @param {Roo.dialog.UploadCropbox} this + * @param {String} type + */ + "footerbuttonclick" : true, + /** + * @event resize + * Fire when resize + * @param {Roo.dialog.UploadCropbox} this + */ + "resize" : true, + /** + * @event rotate + * Fire when rotate the image + * @param {Roo.dialog.UploadCropbox} this + * @param {String} pos + */ + "rotate" : true, + /** + * @event inspect + * Fire when inspect the file + * @param {Roo.dialog.UploadCropbox} this + * @param {Object} file + */ + "inspect" : true, + /** + * @event upload + * Fire when xhr upload the file + * @param {Roo.dialog.UploadCropbox} this + * @param {Object} data + */ + "upload" : true, + /** + * @event arrange + * Fire when arrange the file data + * @param {Roo.dialog.UploadCropbox} this + * @param {Object} formData + */ + "arrange" : true, + /** + * @event loadcanvas + * Fire after load the canvas + * @param {Roo.dialog.UploadCropbox} + * @param {Object} imgEl + */ + "loadcanvas" : true + }); + + this.buttons = this.buttons || Roo.dialog.UploadCropbox.footer.STANDARD; +}; + +Roo.extend(Roo.dialog.UploadCropbox, Roo.Component, { + + emptyText : 'Click to upload image', + rotateNotify : 'Image is too small to rotate', + errorTimeout : 3000, + scale : 0, + baseScale : 1, + rotate : 0, + dragable : false, + pinching : false, + mouseX : 0, + mouseY : 0, + cropData : false, + minWidth : 300, + minHeight : 300, + outputMaxWidth : 1200, + windowSize : 300, + file : false, + exif : {}, + baseRotate : 1, + cropType : 'image/jpeg', + buttons : false, + canvasLoaded : false, + isDocument : false, + method : 'POST', + paramName : 'imageUpload', + loadMask : true, + loadingText : 'Loading...', + maskEl : false, + + getAutoCreate : function() + { + var cfg = { + tag : 'div', + cls : 'roo-upload-cropbox', + cn : [ + { + tag : 'input', + cls : 'roo-upload-cropbox-selector', + type : 'file' + }, + { + tag : 'div', + cls : 'roo-upload-cropbox-body', + style : 'cursor:pointer', + cn : [ + { + tag : 'div', + cls : 'roo-upload-cropbox-preview' + }, + { + tag : 'div', + cls : 'roo-upload-cropbox-thumb' + }, + { + tag : 'div', + cls : 'roo-upload-cropbox-empty-notify', + html : this.emptyText + }, + { + tag : 'div', + cls : 'roo-upload-cropbox-error-notify alert alert-danger', + html : this.rotateNotify + } + ] + }, + { + tag : 'div', + cls : 'roo-upload-cropbox-footer', + cn : { + tag : 'div', + cls : 'btn-group btn-group-justified roo-upload-cropbox-btn-group', + cn : [] + } + } + ] + }; + + return cfg; + }, + + onRender : function(ct, position) + { + Roo.dialog.UploadCropbox.superclass.onRender.call(this, ct, position); + + if(this.el){ + if (this.el.attr('xtype')) { + this.el.attr('xtypex', this.el.attr('xtype')); + this.el.dom.removeAttribute('xtype'); + + this.initEvents(); + } + } + else { + var cfg = Roo.apply({}, this.getAutoCreate()); + + cfg.id = this.id || Roo.id(); + + if (this.cls) { + cfg.cls = (typeof(cfg.cls) == 'undefined' ? this.cls : cfg.cls) + ' ' + this.cls; + } + + if (this.style) { // fixme needs to support more complex style data. + cfg.style = (typeof(cfg.style) == 'undefined' ? this.style : cfg.style) + '; ' + this.style; + } + + this.el = ct.createChild(cfg, position); + + this.initEvents(); + } + + if (this.buttons.length) { + + Roo.each(this.buttons, function(bb) { + + var btn = this.el.select('.roo-upload-cropbox-footer div.roo-upload-cropbox-btn-group').first().createChild(bb); + + btn.on('click', this.onFooterButtonClick.createDelegate(this, [bb.action], true)); + + }, this); + } + + if(this.loadMask){ + this.maskEl = this.el; + } + }, + + initEvents : function() + { + this.urlAPI = (window.createObjectURL && window) || + (window.URL && URL.revokeObjectURL && URL) || + (window.webkitURL && webkitURL); + + this.bodyEl = this.el.select('.roo-upload-cropbox-body', true).first(); + this.bodyEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block'; + + this.selectorEl = this.el.select('.roo-upload-cropbox-selector', true).first(); + this.selectorEl.hide(); + + this.previewEl = this.el.select('.roo-upload-cropbox-preview', true).first(); + this.previewEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block'; + + this.thumbEl = this.el.select('.roo-upload-cropbox-thumb', true).first(); + this.thumbEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block'; + this.thumbEl.hide(); + + this.notifyEl = this.el.select('.roo-upload-cropbox-empty-notify', true).first(); + this.notifyEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block'; + + this.errorEl = this.el.select('.roo-upload-cropbox-error-notify', true).first(); + this.errorEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block'; + this.errorEl.hide(); + + this.footerEl = this.el.select('.roo-upload-cropbox-footer', true).first(); + this.footerEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block'; + this.footerEl.hide(); + + this.setThumbBoxSize(); + + this.bind(); + + this.resize(); + + this.fireEvent('initial', this); + }, + + bind : function() + { + var _this = this; + + window.addEventListener("resize", function() { _this.resize(); } ); + + this.bodyEl.on('click', this.beforeSelectFile, this); + + if(Roo.isTouch){ + this.bodyEl.on('touchstart', this.onTouchStart, this); + this.bodyEl.on('touchmove', this.onTouchMove, this); + this.bodyEl.on('touchend', this.onTouchEnd, this); + } + + if(!Roo.isTouch){ + this.bodyEl.on('mousedown', this.onMouseDown, this); + this.bodyEl.on('mousemove', this.onMouseMove, this); + var mousewheel = (/Firefox/i.test(navigator.userAgent))? 'DOMMouseScroll' : 'mousewheel'; + this.bodyEl.on(mousewheel, this.onMouseWheel, this); + Roo.get(document).on('mouseup', this.onMouseUp, this); + } + + this.selectorEl.on('change', this.onFileSelected, this); + }, + + reset : function() + { + this.scale = 0; + this.baseScale = 1; + this.rotate = 0; + this.baseRotate = 1; + this.dragable = false; + this.pinching = false; + this.mouseX = 0; + this.mouseY = 0; + this.cropData = false; + this.notifyEl.dom.innerHTML = this.emptyText; + + // this.selectorEl.dom.value = ''; + + }, + + resize : function() + { + if(this.fireEvent('resize', this) != false){ + this.setThumbBoxPosition(); + this.setCanvasPosition(); + } + }, + + onFooterButtonClick : function(e, el, o, type) + { + switch (type) { + case 'rotate-left' : + this.onRotateLeft(e); + break; + case 'rotate-right' : + this.onRotateRight(e); + break; + case 'picture' : + this.beforeSelectFile(e); + break; + case 'trash' : + this.trash(e); + break; + case 'crop' : + this.crop(e); + break; + case 'download' : + this.download(e); + break; + default : + break; + } + + this.fireEvent('footerbuttonclick', this, type); + }, + + beforeSelectFile : function(e) + { + e.preventDefault(); + + if(this.fireEvent('beforeselectfile', this) != false){ + this.selectorEl.dom.click(); + } + }, + + onFileSelected : function(e) + { + e.preventDefault(); + + if(typeof(this.selectorEl.dom.files) == 'undefined' || !this.selectorEl.dom.files.length){ + return; + } + + var file = this.selectorEl.dom.files[0]; + + if(this.fireEvent('inspect', this, file) != false){ + this.prepare(file); + } + + }, + + trash : function(e) + { + this.fireEvent('trash', this); + }, + + download : function(e) + { + this.fireEvent('download', this); + }, + + loadCanvas : function(src) + { + if(this.fireEvent('beforeloadcanvas', this, src) != false){ + + this.reset(); + + this.imageEl = document.createElement('img'); + + var _this = this; + + this.imageEl.addEventListener("load", function(){ _this.onLoadCanvas(); }); + + this.imageEl.src = src; + } + }, + + onLoadCanvas : function() + { + this.imageEl.OriginWidth = this.imageEl.naturalWidth || this.imageEl.width; + this.imageEl.OriginHeight = this.imageEl.naturalHeight || this.imageEl.height; + + if(this.fireEvent('loadcanvas', this, this.imageEl) != false){ + + this.bodyEl.un('click', this.beforeSelectFile, this); + + this.notifyEl.hide(); + this.thumbEl.show(); + this.footerEl.show(); + + this.baseRotateLevel(); + + if(this.isDocument){ + this.setThumbBoxSize(); + } + + this.setThumbBoxPosition(); + + this.baseScaleLevel(); + + this.draw(); + + this.resize(); + + this.canvasLoaded = true; + + } + + if(this.loadMask){ + this.maskEl.unmask(); + } + + }, + + setCanvasPosition : function() + { + if(!this.canvasEl){ + return; + } + + var pw = Math.ceil((this.bodyEl.getWidth() - this.canvasEl.width) / 2); + var ph = Math.ceil((this.bodyEl.getHeight() - this.canvasEl.height) / 2); + + this.previewEl.setLeft(pw); + this.previewEl.setTop(ph); + + }, + + onMouseDown : function(e) + { + e.stopEvent(); + + this.dragable = true; + this.pinching = false; + + if(this.isDocument && (this.canvasEl.width < this.thumbEl.getWidth() || this.canvasEl.height < this.thumbEl.getHeight())){ + this.dragable = false; + return; + } + + this.mouseX = Roo.isTouch ? e.browserEvent.touches[0].pageX : e.getPageX(); + this.mouseY = Roo.isTouch ? e.browserEvent.touches[0].pageY : e.getPageY(); + + }, + + onMouseMove : function(e) + { + e.stopEvent(); + + if(!this.canvasLoaded){ + return; + } + + if (!this.dragable){ + return; + } + + var minX = Math.ceil(this.thumbEl.getLeft(true)); + var minY = Math.ceil(this.thumbEl.getTop(true)); + + var maxX = Math.ceil(minX + this.thumbEl.getWidth() - this.canvasEl.width); + var maxY = Math.ceil(minY + this.thumbEl.getHeight() - this.canvasEl.height); + + if(minX > maxX) { + var tempX = minX; + minX = maxX; + maxX = tempX; + } + + if(minY > maxY) { + var tempY = minY; + minY = maxY; + maxY = tempY; + } + + var x = Roo.isTouch ? e.browserEvent.touches[0].pageX : e.getPageX(); + var y = Roo.isTouch ? e.browserEvent.touches[0].pageY : e.getPageY(); + + x = x - this.mouseX; + y = y - this.mouseY; + + var bgX = Math.ceil(x + this.previewEl.getLeft(true)); + var bgY = Math.ceil(y + this.previewEl.getTop(true)); + + bgX = (bgX < minX) ? minX : ((bgX > maxX) ? maxX : bgX); + bgY = (bgY < minY) ? minY : ((bgY > maxY) ? maxY : bgY); + + this.previewEl.setLeft(bgX); + this.previewEl.setTop(bgY); + + this.mouseX = Roo.isTouch ? e.browserEvent.touches[0].pageX : e.getPageX(); + this.mouseY = Roo.isTouch ? e.browserEvent.touches[0].pageY : e.getPageY(); + }, + + onMouseUp : function(e) + { + e.stopEvent(); + + this.dragable = false; + }, + + onMouseWheel : function(e) + { + e.stopEvent(); + + this.startScale = this.scale; + this.scale = (e.getWheelDelta() > 0) ? (this.scale + 1) : (this.scale - 1); + + if(!this.zoomable()){ + this.scale = this.startScale; + return; + } + + + this.draw(); + + return; + }, + + zoomable : function() + { + var minScale = this.thumbEl.getWidth() / this.minWidth; + + if(this.minWidth < this.minHeight){ + minScale = this.thumbEl.getHeight() / this.minHeight; + } + + var width = Math.ceil(this.imageEl.OriginWidth * this.getScaleLevel() / minScale); + var height = Math.ceil(this.imageEl.OriginHeight * this.getScaleLevel() / minScale); + + var maxWidth = this.imageEl.OriginWidth; + var maxHeight = this.imageEl.OriginHeight; + + if( + this.isDocument && + (this.rotate == 0 || this.rotate == 180) && + ( + width > this.imageEl.OriginWidth || + height > this.imageEl.OriginHeight || + (width < this.minWidth && height < this.minHeight) + ) + ){ + return false; + } + + if( + this.isDocument && + (this.rotate == 90 || this.rotate == 270) && + ( + width > this.imageEl.OriginWidth || + height > this.imageEl.OriginHeight || + (width < this.minHeight && height < this.minWidth) + ) + ){ + return false; + } + + if( + !this.isDocument && + (this.rotate == 0 || this.rotate == 180) && + ( + (this.imageEl.OriginWidth / this.imageEl.OriginHeight >= this.minWidth / this.minHeight) && width < this.minWidth || + (this.imageEl.OriginWidth / this.imageEl.OriginHeight <= this.minWidth / this.minHeight) && height < this.minHeight || + width > maxWidth || + height > maxHeight + ) + ){ + return false; + } + + if( + !this.isDocument && + (this.rotate == 90 || this.rotate == 270) && + ( + width < this.minHeight || + width > this.imageEl.OriginWidth || + height < this.minWidth || + height > this.imageEl.OriginHeight + ) + ){ + return false; + } + + return true; + + }, + + onRotateLeft : function(e) + { + if(!this.isDocument && (this.canvasEl.height < this.thumbEl.getWidth() || this.canvasEl.width < this.thumbEl.getHeight())){ + + var minScale = this.thumbEl.getWidth() / this.minWidth; + + var bw = Math.ceil(this.canvasEl.width / this.getScaleLevel()); + var bh = Math.ceil(this.canvasEl.height / this.getScaleLevel()); + + this.startScale = this.scale; + + while (this.getScaleLevel() < minScale){ + + this.scale = this.scale + 1; + + if(!this.zoomable()){ + break; + } + + if( + Math.ceil(bw * this.getScaleLevel()) < this.thumbEl.getHeight() || + Math.ceil(bh * this.getScaleLevel()) < this.thumbEl.getWidth() + ){ + continue; + } + + this.rotate = (this.rotate < 90) ? 270 : this.rotate - 90; + + this.draw(); + + return; + } + + this.scale = this.startScale; + + this.onRotateFail(); + + return false; + } + + this.rotate = (this.rotate < 90) ? 270 : this.rotate - 90; + + if(this.isDocument){ + this.setThumbBoxSize(); + this.setThumbBoxPosition(); + this.setCanvasPosition(); + } + + this.draw(); + + this.fireEvent('rotate', this, 'left'); + + }, + + onRotateRight : function(e) + { + if(!this.isDocument && (this.canvasEl.height < this.thumbEl.getWidth() || this.canvasEl.width < this.thumbEl.getHeight())){ + + var minScale = this.thumbEl.getWidth() / this.minWidth; + + var bw = Math.ceil(this.canvasEl.width / this.getScaleLevel()); + var bh = Math.ceil(this.canvasEl.height / this.getScaleLevel()); + + this.startScale = this.scale; + + while (this.getScaleLevel() < minScale){ + + this.scale = this.scale + 1; + + if(!this.zoomable()){ + break; + } + + if( + Math.ceil(bw * this.getScaleLevel()) < this.thumbEl.getHeight() || + Math.ceil(bh * this.getScaleLevel()) < this.thumbEl.getWidth() + ){ + continue; + } + + this.rotate = (this.rotate > 180) ? 0 : this.rotate + 90; + + this.draw(); + + return; + } + + this.scale = this.startScale; + + this.onRotateFail(); + + return false; + } + + this.rotate = (this.rotate > 180) ? 0 : this.rotate + 90; + + if(this.isDocument){ + this.setThumbBoxSize(); + this.setThumbBoxPosition(); + this.setCanvasPosition(); + } + + this.draw(); + + this.fireEvent('rotate', this, 'right'); + }, + + onRotateFail : function() + { + this.errorEl.show(true); + + var _this = this; + + (function() { _this.errorEl.hide(true); }).defer(this.errorTimeout); + }, + + draw : function() + { + this.previewEl.dom.innerHTML = ''; + + var canvasEl = document.createElement("canvas"); + + var contextEl = canvasEl.getContext("2d"); + + canvasEl.width = this.imageEl.OriginWidth * this.getScaleLevel(); + canvasEl.height = this.imageEl.OriginWidth * this.getScaleLevel(); + var center = this.imageEl.OriginWidth / 2; + + if(this.imageEl.OriginWidth < this.imageEl.OriginHeight){ + canvasEl.width = this.imageEl.OriginHeight * this.getScaleLevel(); + canvasEl.height = this.imageEl.OriginHeight * this.getScaleLevel(); + center = this.imageEl.OriginHeight / 2; + } + + contextEl.scale(this.getScaleLevel(), this.getScaleLevel()); + + contextEl.translate(center, center); + contextEl.rotate(this.rotate * Math.PI / 180); + + contextEl.drawImage(this.imageEl, 0, 0, this.imageEl.OriginWidth, this.imageEl.OriginHeight, center * -1, center * -1, this.imageEl.OriginWidth, this.imageEl.OriginHeight); + + this.canvasEl = document.createElement("canvas"); + + this.contextEl = this.canvasEl.getContext("2d"); + + switch (this.rotate) { + case 0 : + + this.canvasEl.width = this.imageEl.OriginWidth * this.getScaleLevel(); + this.canvasEl.height = this.imageEl.OriginHeight * this.getScaleLevel(); + + this.contextEl.drawImage(canvasEl, 0, 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height); + + break; + case 90 : + + this.canvasEl.width = this.imageEl.OriginHeight * this.getScaleLevel(); + this.canvasEl.height = this.imageEl.OriginWidth * this.getScaleLevel(); + + if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){ + this.contextEl.drawImage(canvasEl, Math.abs(this.canvasEl.width - this.canvasEl.height), 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height); + break; + } + + this.contextEl.drawImage(canvasEl, 0, 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height); + + break; + case 180 : + + this.canvasEl.width = this.imageEl.OriginWidth * this.getScaleLevel(); + this.canvasEl.height = this.imageEl.OriginHeight * this.getScaleLevel(); + + if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){ + this.contextEl.drawImage(canvasEl, 0, Math.abs(this.canvasEl.width - this.canvasEl.height), this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height); + break; + } + + this.contextEl.drawImage(canvasEl, Math.abs(this.canvasEl.width - this.canvasEl.height), 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height); + + break; + case 270 : + + this.canvasEl.width = this.imageEl.OriginHeight * this.getScaleLevel(); + this.canvasEl.height = this.imageEl.OriginWidth * this.getScaleLevel(); + + if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){ + this.contextEl.drawImage(canvasEl, 0, 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height); + break; + } + + this.contextEl.drawImage(canvasEl, 0, Math.abs(this.canvasEl.width - this.canvasEl.height), this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height); + + break; + default : + break; + } + + this.previewEl.appendChild(this.canvasEl); + + this.setCanvasPosition(); + }, + + crop : function() + { + if(!this.canvasLoaded){ + return; + } + + var imageCanvas = document.createElement("canvas"); + + var imageContext = imageCanvas.getContext("2d"); + + imageCanvas.width = (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? this.imageEl.OriginWidth : this.imageEl.OriginHeight; + imageCanvas.height = (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? this.imageEl.OriginWidth : this.imageEl.OriginHeight; + + var center = imageCanvas.width / 2; + + imageContext.translate(center, center); + + imageContext.rotate(this.rotate * Math.PI / 180); + + imageContext.drawImage(this.imageEl, 0, 0, this.imageEl.OriginWidth, this.imageEl.OriginHeight, center * -1, center * -1, this.imageEl.OriginWidth, this.imageEl.OriginHeight); + + var canvas = document.createElement("canvas"); + + var context = canvas.getContext("2d"); + + canvas.width = this.thumbEl.getWidth() / this.getScaleLevel(); + + canvas.height = this.thumbEl.getHeight() / this.getScaleLevel(); + + switch (this.rotate) { + case 0 : + + var width = (this.thumbEl.getWidth() / this.getScaleLevel() > this.imageEl.OriginWidth) ? this.imageEl.OriginWidth : (this.thumbEl.getWidth() / this.getScaleLevel()); + var height = (this.thumbEl.getHeight() / this.getScaleLevel() > this.imageEl.OriginHeight) ? this.imageEl.OriginHeight : (this.thumbEl.getHeight() / this.getScaleLevel()); + + var x = (this.thumbEl.getLeft(true) > this.previewEl.getLeft(true)) ? 0 : ((this.previewEl.getLeft(true) - this.thumbEl.getLeft(true)) / this.getScaleLevel()); + var y = (this.thumbEl.getTop(true) > this.previewEl.getTop(true)) ? 0 : ((this.previewEl.getTop(true) - this.thumbEl.getTop(true)) / this.getScaleLevel()); + + var sx = this.thumbEl.getLeft(true) - this.previewEl.getLeft(true); + var sy = this.thumbEl.getTop(true) - this.previewEl.getTop(true); + + sx = sx < 0 ? 0 : (sx / this.getScaleLevel()); + sy = sy < 0 ? 0 : (sy / this.getScaleLevel()); + + if(canvas.width > this.outputMaxWidth) { + var scale = this.outputMaxWidth / canvas.width; + canvas.width = canvas.width * scale; + canvas.height = canvas.height * scale; + context.scale(scale, scale); + } + + context.fillStyle = 'white'; + context.fillRect(0, 0, this.thumbEl.getWidth() / this.getScaleLevel(), this.thumbEl.getHeight() / this.getScaleLevel()); + + + context.drawImage(imageCanvas, sx, sy, width, height, x, y, width, height); + + break; + case 90 : + + var width = (this.thumbEl.getWidth() / this.getScaleLevel() > this.imageEl.OriginHeight) ? this.imageEl.OriginHeight : (this.thumbEl.getWidth() / this.getScaleLevel()); + var height = (this.thumbEl.getHeight() / this.getScaleLevel() > this.imageEl.OriginWidth) ? this.imageEl.OriginWidth : (this.thumbEl.getHeight() / this.getScaleLevel()); + + var x = (this.thumbEl.getLeft(true) > this.previewEl.getLeft(true)) ? 0 : ((this.previewEl.getLeft(true) - this.thumbEl.getLeft(true)) / this.getScaleLevel()); + var y = (this.thumbEl.getTop(true) > this.previewEl.getTop(true)) ? 0 : ((this.previewEl.getTop(true) - this.thumbEl.getTop(true)) / this.getScaleLevel()); + + var targetWidth = this.minWidth - 2 * x; + var targetHeight = this.minHeight - 2 * y; + + var scale = 1; + + if((x == 0 && y == 0) || (x == 0 && y > 0)){ + scale = targetWidth / width; + } + + if(x > 0 && y == 0){ + scale = targetHeight / height; + } + + if(x > 0 && y > 0){ + scale = targetWidth / width; + + if(width < height){ + scale = targetHeight / height; + } + } + + context.scale(scale, scale); + + var sx = Math.min(this.canvasEl.width - this.thumbEl.getWidth(), this.thumbEl.getLeft(true) - this.previewEl.getLeft(true)); + var sy = Math.min(this.canvasEl.height - this.thumbEl.getHeight(), this.thumbEl.getTop(true) - this.previewEl.getTop(true)); + + sx = sx < 0 ? 0 : (sx / this.getScaleLevel()); + sy = sy < 0 ? 0 : (sy / this.getScaleLevel()); + + sx += (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? Math.abs(this.imageEl.OriginWidth - this.imageEl.OriginHeight) : 0; + + context.drawImage(imageCanvas, sx, sy, width, height, x, y, width, height); + + break; + case 180 : + + var width = (this.thumbEl.getWidth() / this.getScaleLevel() > this.imageEl.OriginWidth) ? this.imageEl.OriginWidth : (this.thumbEl.getWidth() / this.getScaleLevel()); + var height = (this.thumbEl.getHeight() / this.getScaleLevel() > this.imageEl.OriginHeight) ? this.imageEl.OriginHeight : (this.thumbEl.getHeight() / this.getScaleLevel()); + + var x = (this.thumbEl.getLeft(true) > this.previewEl.getLeft(true)) ? 0 : ((this.previewEl.getLeft(true) - this.thumbEl.getLeft(true)) / this.getScaleLevel()); + var y = (this.thumbEl.getTop(true) > this.previewEl.getTop(true)) ? 0 : ((this.previewEl.getTop(true) - this.thumbEl.getTop(true)) / this.getScaleLevel()); + + var targetWidth = this.minWidth - 2 * x; + var targetHeight = this.minHeight - 2 * y; + + var scale = 1; + + if((x == 0 && y == 0) || (x == 0 && y > 0)){ + scale = targetWidth / width; + } + + if(x > 0 && y == 0){ + scale = targetHeight / height; + } + + if(x > 0 && y > 0){ + scale = targetWidth / width; + + if(width < height){ + scale = targetHeight / height; + } + } + + context.scale(scale, scale); + + var sx = Math.min(this.canvasEl.width - this.thumbEl.getWidth(), this.thumbEl.getLeft(true) - this.previewEl.getLeft(true)); + var sy = Math.min(this.canvasEl.height - this.thumbEl.getHeight(), this.thumbEl.getTop(true) - this.previewEl.getTop(true)); + + sx = sx < 0 ? 0 : (sx / this.getScaleLevel()); + sy = sy < 0 ? 0 : (sy / this.getScaleLevel()); + + sx += (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? 0 : Math.abs(this.imageEl.OriginWidth - this.imageEl.OriginHeight); + sy += (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? Math.abs(this.imageEl.OriginWidth - this.imageEl.OriginHeight) : 0; + + context.drawImage(imageCanvas, sx, sy, width, height, x, y, width, height); + + break; + case 270 : + + var width = (this.thumbEl.getWidth() / this.getScaleLevel() > this.imageEl.OriginHeight) ? this.imageEl.OriginHeight : (this.thumbEl.getWidth() / this.getScaleLevel()); + var height = (this.thumbEl.getHeight() / this.getScaleLevel() > this.imageEl.OriginWidth) ? this.imageEl.OriginWidth : (this.thumbEl.getHeight() / this.getScaleLevel()); + + var x = (this.thumbEl.getLeft(true) > this.previewEl.getLeft(true)) ? 0 : ((this.previewEl.getLeft(true) - this.thumbEl.getLeft(true)) / this.getScaleLevel()); + var y = (this.thumbEl.getTop(true) > this.previewEl.getTop(true)) ? 0 : ((this.previewEl.getTop(true) - this.thumbEl.getTop(true)) / this.getScaleLevel()); + + var targetWidth = this.minWidth - 2 * x; + var targetHeight = this.minHeight - 2 * y; + + var scale = 1; + + if((x == 0 && y == 0) || (x == 0 && y > 0)){ + scale = targetWidth / width; + } + + if(x > 0 && y == 0){ + scale = targetHeight / height; + } + + if(x > 0 && y > 0){ + scale = targetWidth / width; + + if(width < height){ + scale = targetHeight / height; + } + } + + context.scale(scale, scale); + var sx = Math.min(this.canvasEl.width - this.thumbEl.getWidth(), this.thumbEl.getLeft(true) - this.previewEl.getLeft(true)); + var sy = Math.min(this.canvasEl.height - this.thumbEl.getHeight(), this.thumbEl.getTop(true) - this.previewEl.getTop(true)); + + sx = sx < 0 ? 0 : (sx / this.getScaleLevel()); + sy = sy < 0 ? 0 : (sy / this.getScaleLevel()); + + sy += (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? 0 : Math.abs(this.imageEl.OriginWidth - this.imageEl.OriginHeight); + + context.drawImage(imageCanvas, sx, sy, width, height, x, y, width, height); + + break; + default : + break; + } + + this.cropData = canvas.toDataURL(this.cropType); + + if(this.fireEvent('crop', this, this.cropData) !== false){ + this.process(this.file, this.cropData); + } + + return; + + }, + + setThumbBoxSize : function() + { + var width, height; + + if(this.isDocument && typeof(this.imageEl) != 'undefined'){ + width = (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? Math.max(this.minWidth, this.minHeight) : Math.min(this.minWidth, this.minHeight); + height = (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? Math.min(this.minWidth, this.minHeight) : Math.max(this.minWidth, this.minHeight); + + this.minWidth = width; + this.minHeight = height; + + if(this.rotate == 90 || this.rotate == 270){ + this.minWidth = height; + this.minHeight = width; + } + } + + height = this.windowSize; + width = Math.ceil(this.minWidth * height / this.minHeight); + + if(this.minWidth > this.minHeight){ + width = this.windowSize; + height = Math.ceil(this.minHeight * width / this.minWidth); + } + + this.thumbEl.setStyle({ + width : width + 'px', + height : height + 'px' + }); + + return; + + }, + + setThumbBoxPosition : function() + { + var x = Math.ceil((this.bodyEl.getWidth() - this.thumbEl.getWidth()) / 2 ); + var y = Math.ceil((this.bodyEl.getHeight() - this.thumbEl.getHeight()) / 2); + + this.thumbEl.setLeft(x); + this.thumbEl.setTop(y); + + }, + + baseRotateLevel : function() + { + this.baseRotate = 1; + + if( + typeof(this.exif) != 'undefined' && + typeof(this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']]) != 'undefined' && + [1, 3, 6, 8].indexOf(this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']]) != -1 + ){ + this.baseRotate = this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']]; + } + + this.rotate = Roo.dialog.UploadCropbox['Orientation'][this.baseRotate]; + + }, + + baseScaleLevel : function() + { + var width, height; + + if(this.isDocument){ + + if(this.baseRotate == 6 || this.baseRotate == 8){ + + height = this.thumbEl.getHeight(); + this.baseScale = height / this.imageEl.OriginWidth; + + if(this.imageEl.OriginHeight * this.baseScale > this.thumbEl.getWidth()){ + width = this.thumbEl.getWidth(); + this.baseScale = width / this.imageEl.OriginHeight; + } + + return; + } + + height = this.thumbEl.getHeight(); + this.baseScale = height / this.imageEl.OriginHeight; + + if(this.imageEl.OriginWidth * this.baseScale > this.thumbEl.getWidth()){ + width = this.thumbEl.getWidth(); + this.baseScale = width / this.imageEl.OriginWidth; + } + + return; + } + + if(this.baseRotate == 6 || this.baseRotate == 8){ + + width = this.thumbEl.getHeight(); + this.baseScale = width / this.imageEl.OriginHeight; + + if(this.imageEl.OriginHeight * this.baseScale < this.thumbEl.getWidth()){ + height = this.thumbEl.getWidth(); + this.baseScale = height / this.imageEl.OriginHeight; + } + + if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){ + height = this.thumbEl.getWidth(); + this.baseScale = height / this.imageEl.OriginHeight; + + if(this.imageEl.OriginWidth * this.baseScale < this.thumbEl.getHeight()){ + width = this.thumbEl.getHeight(); + this.baseScale = width / this.imageEl.OriginWidth; + } + } + + return; + } + + width = this.thumbEl.getWidth(); + this.baseScale = width / this.imageEl.OriginWidth; + + if(this.imageEl.OriginHeight * this.baseScale < this.thumbEl.getHeight()){ + height = this.thumbEl.getHeight(); + this.baseScale = height / this.imageEl.OriginHeight; + } + + if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){ + + height = this.thumbEl.getHeight(); + this.baseScale = height / this.imageEl.OriginHeight; + + if(this.imageEl.OriginWidth * this.baseScale < this.thumbEl.getWidth()){ + width = this.thumbEl.getWidth(); + this.baseScale = width / this.imageEl.OriginWidth; + } + + } + + if(this.imageEl.OriginWidth < this.minWidth || this.imageEl.OriginHeight < this.minHeight) { + this.baseScale = width / this.minWidth; + } + + return; + }, + + getScaleLevel : function() + { + return this.baseScale * Math.pow(1.02, this.scale); + }, + + onTouchStart : function(e) + { + if(!this.canvasLoaded){ + this.beforeSelectFile(e); + return; + } + + var touches = e.browserEvent.touches; + + if(!touches){ + return; + } + + if(touches.length == 1){ + this.onMouseDown(e); + return; + } + + if(touches.length != 2){ + return; + } + + var coords = []; + + for(var i = 0, finger; finger = touches[i]; i++){ + coords.push(finger.pageX, finger.pageY); + } + + var x = Math.pow(coords[0] - coords[2], 2); + var y = Math.pow(coords[1] - coords[3], 2); + + this.startDistance = Math.sqrt(x + y); + + this.startScale = this.scale; + + this.pinching = true; + this.dragable = false; + + }, + + onTouchMove : function(e) + { + if(!this.pinching && !this.dragable){ + return; + } + + var touches = e.browserEvent.touches; + + if(!touches){ + return; + } + + if(this.dragable){ + this.onMouseMove(e); + return; + } + + var coords = []; + + for(var i = 0, finger; finger = touches[i]; i++){ + coords.push(finger.pageX, finger.pageY); + } + + var x = Math.pow(coords[0] - coords[2], 2); + var y = Math.pow(coords[1] - coords[3], 2); + + this.endDistance = Math.sqrt(x + y); + + this.scale = this.startScale + Math.floor(Math.log(this.endDistance / this.startDistance) / Math.log(1.1)); + + if(!this.zoomable()){ + this.scale = this.startScale; + return; + } + + this.draw(); + + }, + + onTouchEnd : function(e) + { + this.pinching = false; + this.dragable = false; + + }, + + process : function(file, crop) + { + if(this.loadMask){ + this.maskEl.mask(this.loadingText); + } + + this.xhr = new XMLHttpRequest(); + + file.xhr = this.xhr; + + this.xhr.open(this.method, this.url, true); + + var headers = { + "Accept": "application/json", + "Cache-Control": "no-cache", + "X-Requested-With": "XMLHttpRequest" + }; + + for (var headerName in headers) { + var headerValue = headers[headerName]; + if (headerValue) { + this.xhr.setRequestHeader(headerName, headerValue); + } + } + + var _this = this; + + this.xhr.onload = function() + { + _this.xhrOnLoad(_this.xhr); + } + + this.xhr.onerror = function() + { + _this.xhrOnError(_this.xhr); + } + + var formData = new FormData(); + + formData.append('returnHTML', 'NO'); + + if(crop){ + formData.append('crop', crop); + var blobBin = atob(crop.split(',')[1]); + var array = []; + for(var i = 0; i < blobBin.length; i++) { + array.push(blobBin.charCodeAt(i)); + } + var croppedFile =new Blob([new Uint8Array(array)], {type: this.cropType}); + formData.append(this.paramName, croppedFile, file.name); + } + + if(typeof(file.filename) != 'undefined'){ + formData.append('filename', file.filename); + } + + if(typeof(file.mimetype) != 'undefined'){ + formData.append('mimetype', file.mimetype); + } + + if(this.fireEvent('arrange', this, formData) != false){ + this.xhr.send(formData); + }; + }, + + xhrOnLoad : function(xhr) + { + if(this.loadMask){ + this.maskEl.unmask(); + } + + if (xhr.readyState !== 4) { + this.fireEvent('exception', this, xhr); + return; + } + + var response = Roo.decode(xhr.responseText); + + if(!response.success){ + this.fireEvent('exception', this, xhr); + return; + } + + var response = Roo.decode(xhr.responseText); + + this.fireEvent('upload', this, response); + + }, + + xhrOnError : function() + { + if(this.loadMask){ + this.maskEl.unmask(); + } + + Roo.log('xhr on error'); + + var response = Roo.decode(xhr.responseText); + + Roo.log(response); + + }, + + prepare : function(file) + { + if(this.loadMask){ + this.maskEl.mask(this.loadingText); + } + + this.file = false; + this.exif = {}; + + if(typeof(file) === 'string'){ + this.loadCanvas(file); + return; + } + + if(!file || !this.urlAPI){ + return; + } + + this.file = file; + if(typeof(file.type) != 'undefined' && file.type.length != 0) { + this.cropType = file.type; + } + + var _this = this; + + if(this.fireEvent('prepare', this, this.file) != false){ + + var reader = new FileReader(); + + reader.onload = function (e) { + if (e.target.error) { + Roo.log(e.target.error); + return; + } + + var buffer = e.target.result, + dataView = new DataView(buffer), + offset = 2, + maxOffset = dataView.byteLength - 4, + markerBytes, + markerLength; + + if (dataView.getUint16(0) === 0xffd8) { + while (offset < maxOffset) { + markerBytes = dataView.getUint16(offset); + + if ((markerBytes >= 0xffe0 && markerBytes <= 0xffef) || markerBytes === 0xfffe) { + markerLength = dataView.getUint16(offset + 2) + 2; + if (offset + markerLength > dataView.byteLength) { + Roo.log('Invalid meta data: Invalid segment size.'); + break; + } + + if(markerBytes == 0xffe1){ + _this.parseExifData( + dataView, + offset, + markerLength + ); + } + + offset += markerLength; + + continue; + } + + break; + } + + } + + var url = _this.urlAPI.createObjectURL(_this.file); + + _this.loadCanvas(url); + + return; + } + + reader.readAsArrayBuffer(this.file); + + } + + }, + + parseExifData : function(dataView, offset, length) + { + var tiffOffset = offset + 10, + littleEndian, + dirOffset; + + if (dataView.getUint32(offset + 4) !== 0x45786966) { + // No Exif data, might be XMP data instead + return; + } + + // Check for the ASCII code for "Exif" (0x45786966): + if (dataView.getUint32(offset + 4) !== 0x45786966) { + // No Exif data, might be XMP data instead + return; + } + if (tiffOffset + 8 > dataView.byteLength) { + Roo.log('Invalid Exif data: Invalid segment size.'); + return; + } + // Check for the two null bytes: + if (dataView.getUint16(offset + 8) !== 0x0000) { + Roo.log('Invalid Exif data: Missing byte alignment offset.'); + return; + } + // Check the byte alignment: + switch (dataView.getUint16(tiffOffset)) { + case 0x4949: + littleEndian = true; + break; + case 0x4D4D: + littleEndian = false; + break; + default: + Roo.log('Invalid Exif data: Invalid byte alignment marker.'); + return; + } + // Check for the TIFF tag marker (0x002A): + if (dataView.getUint16(tiffOffset + 2, littleEndian) !== 0x002A) { + Roo.log('Invalid Exif data: Missing TIFF marker.'); + return; + } + // Retrieve the directory offset bytes, usually 0x00000008 or 8 decimal: + dirOffset = dataView.getUint32(tiffOffset + 4, littleEndian); + + this.parseExifTags( + dataView, + tiffOffset, + tiffOffset + dirOffset, + littleEndian + ); + }, + + parseExifTags : function(dataView, tiffOffset, dirOffset, littleEndian) + { + var tagsNumber, + dirEndOffset, + i; + if (dirOffset + 6 > dataView.byteLength) { + Roo.log('Invalid Exif data: Invalid directory offset.'); + return; + } + tagsNumber = dataView.getUint16(dirOffset, littleEndian); + dirEndOffset = dirOffset + 2 + 12 * tagsNumber; + if (dirEndOffset + 4 > dataView.byteLength) { + Roo.log('Invalid Exif data: Invalid directory size.'); + return; + } + for (i = 0; i < tagsNumber; i += 1) { + this.parseExifTag( + dataView, + tiffOffset, + dirOffset + 2 + 12 * i, // tag offset + littleEndian + ); + } + // Return the offset to the next directory: + return dataView.getUint32(dirEndOffset, littleEndian); + }, + + parseExifTag : function (dataView, tiffOffset, offset, littleEndian) + { + var tag = dataView.getUint16(offset, littleEndian); + + this.exif[tag] = this.getExifValue( + dataView, + tiffOffset, + offset, + dataView.getUint16(offset + 2, littleEndian), // tag type + dataView.getUint32(offset + 4, littleEndian), // tag length + littleEndian + ); + }, + + getExifValue : function (dataView, tiffOffset, offset, type, length, littleEndian) + { + var tagType = Roo.dialog.UploadCropbox.exifTagTypes[type], + tagSize, + dataOffset, + values, + i, + str, + c; + + if (!tagType) { + Roo.log('Invalid Exif data: Invalid tag type.'); + return; + } + + tagSize = tagType.size * length; + // Determine if the value is contained in the dataOffset bytes, + // or if the value at the dataOffset is a pointer to the actual data: + dataOffset = tagSize > 4 ? + tiffOffset + dataView.getUint32(offset + 8, littleEndian) : (offset + 8); + if (dataOffset + tagSize > dataView.byteLength) { + Roo.log('Invalid Exif data: Invalid data offset.'); + return; + } + if (length === 1) { + return tagType.getValue(dataView, dataOffset, littleEndian); + } + values = []; + for (i = 0; i < length; i += 1) { + values[i] = tagType.getValue(dataView, dataOffset + i * tagType.size, littleEndian); + } + + if (tagType.ascii) { + str = ''; + // Concatenate the chars: + for (i = 0; i < values.length; i += 1) { + c = values[i]; + // Ignore the terminating NULL byte(s): + if (c === '\u0000') { + break; + } + str += c; + } + return str; + } + return values; + } + +}); + +Roo.apply(Roo.dialog.UploadCropbox, { + tags : { + 'Orientation': 0x0112 + }, + + Orientation: { + 1: 0, //'top-left', +// 2: 'top-right', + 3: 180, //'bottom-right', +// 4: 'bottom-left', +// 5: 'left-top', + 6: 90, //'right-top', +// 7: 'right-bottom', + 8: 270 //'left-bottom' + }, + + exifTagTypes : { + // byte, 8-bit unsigned int: + 1: { + getValue: function (dataView, dataOffset) { + return dataView.getUint8(dataOffset); + }, + size: 1 + }, + // ascii, 8-bit byte: + 2: { + getValue: function (dataView, dataOffset) { + return String.fromCharCode(dataView.getUint8(dataOffset)); + }, + size: 1, + ascii: true + }, + // short, 16 bit int: + 3: { + getValue: function (dataView, dataOffset, littleEndian) { + return dataView.getUint16(dataOffset, littleEndian); + }, + size: 2 + }, + // long, 32 bit int: + 4: { + getValue: function (dataView, dataOffset, littleEndian) { + return dataView.getUint32(dataOffset, littleEndian); + }, + size: 4 + }, + // rational = two long values, first is numerator, second is denominator: + 5: { + getValue: function (dataView, dataOffset, littleEndian) { + return dataView.getUint32(dataOffset, littleEndian) / + dataView.getUint32(dataOffset + 4, littleEndian); + }, + size: 8 + }, + // slong, 32 bit signed int: + 9: { + getValue: function (dataView, dataOffset, littleEndian) { + return dataView.getInt32(dataOffset, littleEndian); + }, + size: 4 + }, + // srational, two slongs, first is numerator, second is denominator: + 10: { + getValue: function (dataView, dataOffset, littleEndian) { + return dataView.getInt32(dataOffset, littleEndian) / + dataView.getInt32(dataOffset + 4, littleEndian); + }, + size: 8 + } + }, + + footer : { + STANDARD : [ + { + tag : 'div', + cls : 'btn-group roo-upload-cropbox-rotate-left', + action : 'rotate-left', + cn : [ + { + tag : 'button', + cls : 'btn btn-default', + html : '' + } + ] + }, + { + tag : 'div', + cls : 'btn-group roo-upload-cropbox-picture', + action : 'picture', + cn : [ + { + tag : 'button', + cls : 'btn btn-default', + html : '' + } + ] + }, + { + tag : 'div', + cls : 'btn-group roo-upload-cropbox-rotate-right', + action : 'rotate-right', + cn : [ + { + tag : 'button', + cls : 'btn btn-default', + html : '' + } + ] + } + ], + DOCUMENT : [ + { + tag : 'div', + cls : 'btn-group roo-upload-cropbox-rotate-left', + action : 'rotate-left', + cn : [ + { + tag : 'button', + cls : 'btn btn-default', + html : '' + } + ] + }, + { + tag : 'div', + cls : 'btn-group roo-upload-cropbox-download', + action : 'download', + cn : [ + { + tag : 'button', + cls : 'btn btn-default', + html : '' + } + ] + }, + { + tag : 'div', + cls : 'btn-group roo-upload-cropbox-crop', + action : 'crop', + cn : [ + { + tag : 'button', + cls : 'btn btn-default', + html : '' + } + ] + }, + { + tag : 'div', + cls : 'btn-group roo-upload-cropbox-trash', + action : 'trash', + cn : [ + { + tag : 'button', + cls : 'btn btn-default', + html : '' + } + ] + }, + { + tag : 'div', + cls : 'btn-group roo-upload-cropbox-rotate-right', + action : 'rotate-right', + cn : [ + { + tag : 'button', + cls : 'btn btn-default', + html : '' + } + ] + } + ], + ROTATOR : [ + { + tag : 'div', + cls : 'btn-group roo-upload-cropbox-rotate-left', + action : 'rotate-left', + cn : [ + { + tag : 'button', + cls : 'btn btn-default', + html : '' + } + ] + }, + { + tag : 'div', + cls : 'btn-group roo-upload-cropbox-rotate-right', + action : 'rotate-right', + cn : [ + { + tag : 'button', + cls : 'btn btn-default', + html : '' + } + ] + } + ] + } +}); diff --git a/roojs-ui.js b/roojs-ui.js index e36924adf0..363994f089 100644 --- a/roojs-ui.js +++ b/roojs-ui.js @@ -1605,9 +1605,9 @@ return this.el.getUpdateManager();},_handleRefresh:function(A,B,C){if(!C||!this. te.setWidth(A);}if(this.adjustments){A+=this.adjustments[0];B+=this.adjustments[1];}return {"width":A,"height":B};},setSize:function(A,B){if(this.fitToFrame&&!this.ignoreResize(A,B)){if(this.fitContainer&&this.resizeEl!=this.el){this.el.setSize(A,B);}var C=this.adjustForComponents(A,B); this.resizeEl.setSize(this.autoWidth?"auto":C.width,this.autoHeight?"auto":C.height);this.fireEvent('resize',this,C.width,C.height);}},getTitle:function(){return this.title;},setTitle:function(A){this.title=A;if(this.region){this.region.updatePanelTitle(this,A); }},isClosable:function(){return this.closable;},beforeSlide:function(){this.el.clip();this.resizeEl.clip();},afterSlide:function(){this.el.unclip();this.resizeEl.unclip();},refresh:function(){if(this.refreshDelegate){this.loaded=false;this.refreshDelegate(); -}},destroy:function(){this.el.removeAllListeners();var A=document.createElement("span");A.appendChild(this.el.dom);A.innerHTML="";this.el.remove();this.el=null;},form:false,view:false,addxtype:function(A){if(A.xtype.match(/^Form$/)){var el;el=this.el.createChild(); -this.form=new Roo.form.Form(A);if(this.form.allItems.length){this.form.render(el.dom);}return this.form;}if(['View','JsonView','DatePicker'].indexOf(A.xtype)>-1){A.el=this.el.appendChild(document.createElement("div"));var B=new Roo.factory(A);B.render&&B.render(false,''); -this.view=B;return B;}return false;}}); +}},destroy:function(){this.el.removeAllListeners();var A=document.createElement("span");A.appendChild(this.el.dom);A.innerHTML="";this.el.remove();this.el=null;},form:false,view:false,addxtype:function(A){if(A.xtype.match(/^UploadCropbox$/)){this.cropbox=new Roo.factory(A); +this.cropbox.render(this.el);return this.cropbox;}if(A.xtype.match(/^Form$/)){var el;el=this.el.createChild();this.form=new Roo.form.Form(A);if(this.form.allItems.length){this.form.render(el.dom);}return this.form;}if(['View','JsonView','DatePicker'].indexOf(A.xtype)>-1){A.el=this.el.appendChild(document.createElement("div")); +var B=new Roo.factory(A);B.render&&B.render(false,'');this.view=B;return B;}return false;}}); // Roo/GridPanel.js Roo.GridPanel=function(A,B){if(typeof(A.grid)!='undefined'){B=A;A=B.grid;}this.wrapper=Roo.DomHelper.append(document.body,{tag:"div",cls:"x-layout-grid-wrapper x-layout-inactive-content"},true);this.wrapper.dom.appendChild(A.getGridEl().dom);Roo.GridPanel.superclass.constructor.call(this,this.wrapper,B); if(this.toolbar){this.toolbar.el.insertBefore(this.wrapper.dom.firstChild);}if(this.footer&&!this.footer.el&&this.footer.xtype){this.footer.container=this.grid.getView().getFooterPanel(true);this.footer.dataSource=this.grid.dataSource;this.footer=Roo.factory(this.footer,Roo); @@ -1936,3 +1936,105 @@ F.push("(typeof("+G+") == 'undefined')");});var H='(('+F.join(" || ")+") ? undef }return "'"+A+H+C+")"+A+"'";};var B;if(Roo.isGecko){B="tpl.compiled = function(values, parent){ with(values) { return '"+tpl.body.replace(/(\r\n|\n)/g,'\\n').replace(/'/g,"\\'").replace(this.re,fn)+"';};};";}else{B=["tpl.compiled = function(values, parent){ with (values) { return ['"]; B.push(tpl.body.replace(/(\r\n|\n)/g,'\\n').replace(/'/g,"\\'").replace(this.re,fn));B.push("'].join('');};};");B=B.join('');}Roo.debug&&Roo.log(B.replace(/\\n/,'\n'));eval(B);return this;},applyTemplate:function(A){return this.master.compiled.call(this,A,{} );},apply:function(){return this.applyTemplate.apply(this,arguments);}});Roo.XTemplate.from=function(el){el=Roo.getDom(el);return new Roo.XTemplate(el.value||el.innerHTML);}; +// Roo/dialog/namespace.js +Roo.dialog={}; +// Roo/dialog/UploadCropbox.js +Roo.dialog.UploadCropbox=function(A){Roo.dialog.UploadCropbox.superclass.constructor.call(this,A);this.addEvents({"beforeselectfile":true,"initial":true,"crop":true,"prepare":true,"exception":true,"beforeloadcanvas":true,"trash":true,"download":true,"footerbuttonclick":true,"resize":true,"rotate":true,"inspect":true,"upload":true,"arrange":true,"loadcanvas":true} +);this.buttons=this.buttons||Roo.dialog.UploadCropbox.footer.STANDARD;};Roo.extend(Roo.dialog.UploadCropbox,Roo.Component,{emptyText:'Click to upload image',rotateNotify:'Image is too small to rotate',errorTimeout:3000,scale:0,baseScale:1,rotate:0,dragable:false,pinching:false,mouseX:0,mouseY:0,cropData:false,minWidth:300,minHeight:300,outputMaxWidth:1200,windowSize:300,file:false,exif:{} +,baseRotate:1,cropType:'image/jpeg',buttons:false,canvasLoaded:false,isDocument:false,method:'POST',paramName:'imageUpload',loadMask:true,loadingText:'Loading...',maskEl:false,getAutoCreate:function(){var A={tag:'div',cls:'roo-upload-cropbox',cn:[{tag:'input',cls:'roo-upload-cropbox-selector',type:'file'} +,{tag:'div',cls:'roo-upload-cropbox-body',style:'cursor:pointer',cn:[{tag:'div',cls:'roo-upload-cropbox-preview'},{tag:'div',cls:'roo-upload-cropbox-thumb'},{tag:'div',cls:'roo-upload-cropbox-empty-notify',html:this.emptyText},{tag:'div',cls:'roo-upload-cropbox-error-notify alert alert-danger',html:this.rotateNotify} +]},{tag:'div',cls:'roo-upload-cropbox-footer',cn:{tag:'div',cls:'btn-group btn-group-justified roo-upload-cropbox-btn-group',cn:[]}}]};return A;},onRender:function(ct,A){Roo.dialog.UploadCropbox.superclass.onRender.call(this,ct,A);if(this.el){if(this.el.attr('xtype')){this.el.attr('xtypex',this.el.attr('xtype')); +this.el.dom.removeAttribute('xtype');this.initEvents();}}else{var B=Roo.apply({},this.getAutoCreate());B.id=this.id||Roo.id();if(this.cls){B.cls=(typeof(B.cls)=='undefined'?this.cls:B.cls)+' '+this.cls;}if(this.style){B.style=(typeof(B.style)=='undefined'?this.style:B.style)+'; '+this.style; +}this.el=ct.createChild(B,A);this.initEvents();}if(this.buttons.length){Roo.each(this.buttons,function(bb){var C=this.el.select('.roo-upload-cropbox-footer div.roo-upload-cropbox-btn-group').first().createChild(bb);C.on('click',this.onFooterButtonClick.createDelegate(this,[bb.action],true)); +},this);}if(this.loadMask){this.maskEl=this.el;}},initEvents:function(){this.urlAPI=(window.createObjectURL&&window)||(window.URL&&URL.revokeObjectURL&&URL)||(window.webkitURL&&webkitURL);this.bodyEl=this.el.select('.roo-upload-cropbox-body',true).first(); +this.bodyEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block';this.selectorEl=this.el.select('.roo-upload-cropbox-selector',true).first();this.selectorEl.hide();this.previewEl=this.el.select('.roo-upload-cropbox-preview',true).first();this.previewEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block'; +this.thumbEl=this.el.select('.roo-upload-cropbox-thumb',true).first();this.thumbEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block';this.thumbEl.hide();this.notifyEl=this.el.select('.roo-upload-cropbox-empty-notify',true).first();this.notifyEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block'; +this.errorEl=this.el.select('.roo-upload-cropbox-error-notify',true).first();this.errorEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block';this.errorEl.hide();this.footerEl=this.el.select('.roo-upload-cropbox-footer',true).first();this.footerEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block'; +this.footerEl.hide();this.setThumbBoxSize();this.bind();this.resize();this.fireEvent('initial',this);},bind:function(){var A=this;window.addEventListener("resize",function(){A.resize();});this.bodyEl.on('click',this.beforeSelectFile,this);if(Roo.isTouch){this.bodyEl.on('touchstart',this.onTouchStart,this); +this.bodyEl.on('touchmove',this.onTouchMove,this);this.bodyEl.on('touchend',this.onTouchEnd,this);}if(!Roo.isTouch){this.bodyEl.on('mousedown',this.onMouseDown,this);this.bodyEl.on('mousemove',this.onMouseMove,this);var B=(/Firefox/i.test(navigator.userAgent))?'DOMMouseScroll':'mousewheel'; +this.bodyEl.on(B,this.onMouseWheel,this);Roo.get(document).on('mouseup',this.onMouseUp,this);}this.selectorEl.on('change',this.onFileSelected,this);},reset:function(){this.scale=0;this.baseScale=1;this.rotate=0;this.baseRotate=1;this.dragable=false;this.pinching=false; +this.mouseX=0;this.mouseY=0;this.cropData=false;this.notifyEl.dom.innerHTML=this.emptyText;},resize:function(){if(this.fireEvent('resize',this)!=false){this.setThumbBoxPosition();this.setCanvasPosition();}},onFooterButtonClick:function(e,el,o,A){switch(A){case 'rotate-left':this.onRotateLeft(e); +break;case 'rotate-right':this.onRotateRight(e);break;case 'picture':this.beforeSelectFile(e);break;case 'trash':this.trash(e);break;case 'crop':this.crop(e);break;case 'download':this.download(e);break;default:break;}this.fireEvent('footerbuttonclick',this,A); +},beforeSelectFile:function(e){e.preventDefault();if(this.fireEvent('beforeselectfile',this)!=false){this.selectorEl.dom.click();}},onFileSelected:function(e){e.preventDefault();if(typeof(this.selectorEl.dom.files)=='undefined'||!this.selectorEl.dom.files.length){return; +}var A=this.selectorEl.dom.files[0];if(this.fireEvent('inspect',this,A)!=false){this.prepare(A);}},trash:function(e){this.fireEvent('trash',this);},download:function(e){this.fireEvent('download',this);},loadCanvas:function(A){if(this.fireEvent('beforeloadcanvas',this,A)!=false){this.reset(); +this.imageEl=document.createElement('img');var B=this;this.imageEl.addEventListener("load",function(){B.onLoadCanvas();});this.imageEl.src=A;}},onLoadCanvas:function(){this.imageEl.OriginWidth=this.imageEl.naturalWidth||this.imageEl.width;this.imageEl.OriginHeight=this.imageEl.naturalHeight||this.imageEl.height; +if(this.fireEvent('loadcanvas',this,this.imageEl)!=false){this.bodyEl.un('click',this.beforeSelectFile,this);this.notifyEl.hide();this.thumbEl.show();this.footerEl.show();this.baseRotateLevel();if(this.isDocument){this.setThumbBoxSize();}this.setThumbBoxPosition(); +this.baseScaleLevel();this.draw();this.resize();this.canvasLoaded=true;}if(this.loadMask){this.maskEl.unmask();}},setCanvasPosition:function(){if(!this.canvasEl){return;}var pw=Math.ceil((this.bodyEl.getWidth()-this.canvasEl.width)/2);var ph=Math.ceil((this.bodyEl.getHeight()-this.canvasEl.height)/2); +this.previewEl.setLeft(pw);this.previewEl.setTop(ph);},onMouseDown:function(e){e.stopEvent();this.dragable=true;this.pinching=false;if(this.isDocument&&(this.canvasEl.widthC){var E=A;A=C;C=E;}if(B>D){var F=B;B=D;D=F;}var x=Roo.isTouch?e.browserEvent.touches[0].pageX:e.getPageX(); +var y=Roo.isTouch?e.browserEvent.touches[0].pageY:e.getPageY();x=x-this.mouseX;y=y-this.mouseY;var G=Math.ceil(x+this.previewEl.getLeft(true));var H=Math.ceil(y+this.previewEl.getTop(true));G=(GC)?C:G);H=(HD)?D:H);this.previewEl.setLeft(G); +this.previewEl.setTop(H);this.mouseX=Roo.isTouch?e.browserEvent.touches[0].pageX:e.getPageX();this.mouseY=Roo.isTouch?e.browserEvent.touches[0].pageY:e.getPageY();},onMouseUp:function(e){e.stopEvent();this.dragable=false;},onMouseWheel:function(e){e.stopEvent(); +this.startScale=this.scale;this.scale=(e.getWheelDelta()>0)?(this.scale+1):(this.scale-1);if(!this.zoomable()){this.scale=this.startScale;return;}this.draw();return;},zoomable:function(){var A=this.thumbEl.getWidth()/this.minWidth;if(this.minWidththis.imageEl.OriginWidth||C>this.imageEl.OriginHeight||(Bthis.imageEl.OriginWidth||C>this.imageEl.OriginHeight||(B=this.minWidth/this.minHeight)&&BD||C>E)){return false; +}if(!this.isDocument&&(this.rotate==90||this.rotate==270)&&(Bthis.imageEl.OriginWidth||Cthis.imageEl.OriginHeight)){return false;}return true;},onRotateLeft:function(e){if(!this.isDocument&&(this.canvasEl.height180)?0:this.rotate+90;this.draw();return;}this.scale=this.startScale;this.onRotateFail();return false;}this.rotate=(this.rotate>180)?0:this.rotate+90;if(this.isDocument){this.setThumbBoxSize();this.setThumbBoxPosition();this.setCanvasPosition(); +}this.draw();this.fireEvent('rotate',this,'right');},onRotateFail:function(){this.errorEl.show(true);var A=this;(function(){A.errorEl.hide(true);}).defer(this.errorTimeout);},draw:function(){this.previewEl.dom.innerHTML='';var A=document.createElement("canvas"); +var B=A.getContext("2d");A.width=this.imageEl.OriginWidth*this.getScaleLevel();A.height=this.imageEl.OriginWidth*this.getScaleLevel();var C=this.imageEl.OriginWidth/2;if(this.imageEl.OriginWidththis.imageEl.OriginHeight){this.contextEl.drawImage(A,Math.abs(this.canvasEl.width-this.canvasEl.height),0,this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height); +break;}this.contextEl.drawImage(A,0,0,this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height);break;case 180:this.canvasEl.width=this.imageEl.OriginWidth*this.getScaleLevel();this.canvasEl.height=this.imageEl.OriginHeight*this.getScaleLevel(); +if(this.imageEl.OriginWidth>this.imageEl.OriginHeight){this.contextEl.drawImage(A,0,Math.abs(this.canvasEl.width-this.canvasEl.height),this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height);break;}this.contextEl.drawImage(A,Math.abs(this.canvasEl.width-this.canvasEl.height),0,this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height); +break;case 270:this.canvasEl.width=this.imageEl.OriginHeight*this.getScaleLevel();this.canvasEl.height=this.imageEl.OriginWidth*this.getScaleLevel();if(this.imageEl.OriginWidth>this.imageEl.OriginHeight){this.contextEl.drawImage(A,0,0,this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height); +break;}this.contextEl.drawImage(A,0,Math.abs(this.canvasEl.width-this.canvasEl.height),this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height);break;default:break;}this.previewEl.appendChild(this.canvasEl);this.setCanvasPosition(); +},crop:function(){if(!this.canvasLoaded){return;}var A=document.createElement("canvas");var B=A.getContext("2d");A.width=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?this.imageEl.OriginWidth:this.imageEl.OriginHeight;A.height=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?this.imageEl.OriginWidth:this.imageEl.OriginHeight; +var C=A.width/2;B.translate(C,C);B.rotate(this.rotate*Math.PI/180);B.drawImage(this.imageEl,0,0,this.imageEl.OriginWidth,this.imageEl.OriginHeight,C*-1,C*-1,this.imageEl.OriginWidth,this.imageEl.OriginHeight);var D=document.createElement("canvas");var E=D.getContext("2d"); +D.width=this.thumbEl.getWidth()/this.getScaleLevel();D.height=this.thumbEl.getHeight()/this.getScaleLevel();switch(this.rotate){case 0:var F=(this.thumbEl.getWidth()/this.getScaleLevel()>this.imageEl.OriginWidth)?this.imageEl.OriginWidth:(this.thumbEl.getWidth()/this.getScaleLevel()); +var G=(this.thumbEl.getHeight()/this.getScaleLevel()>this.imageEl.OriginHeight)?this.imageEl.OriginHeight:(this.thumbEl.getHeight()/this.getScaleLevel());var x=(this.thumbEl.getLeft(true)>this.previewEl.getLeft(true))?0:((this.previewEl.getLeft(true)-this.thumbEl.getLeft(true))/this.getScaleLevel()); +var y=(this.thumbEl.getTop(true)>this.previewEl.getTop(true))?0:((this.previewEl.getTop(true)-this.thumbEl.getTop(true))/this.getScaleLevel());var sx=this.thumbEl.getLeft(true)-this.previewEl.getLeft(true);var sy=this.thumbEl.getTop(true)-this.previewEl.getTop(true); +sx=sx<0?0:(sx/this.getScaleLevel());sy=sy<0?0:(sy/this.getScaleLevel());if(D.width>this.outputMaxWidth){var H=this.outputMaxWidth/D.width;D.width=D.width*H;D.height=D.height*H;E.scale(H,H);}E.fillStyle='white';E.fillRect(0,0,this.thumbEl.getWidth()/this.getScaleLevel(),this.thumbEl.getHeight()/this.getScaleLevel()); +E.drawImage(A,sx,sy,F,G,x,y,F,G);break;case 90:var F=(this.thumbEl.getWidth()/this.getScaleLevel()>this.imageEl.OriginHeight)?this.imageEl.OriginHeight:(this.thumbEl.getWidth()/this.getScaleLevel());var G=(this.thumbEl.getHeight()/this.getScaleLevel()>this.imageEl.OriginWidth)?this.imageEl.OriginWidth:(this.thumbEl.getHeight()/this.getScaleLevel()); +var x=(this.thumbEl.getLeft(true)>this.previewEl.getLeft(true))?0:((this.previewEl.getLeft(true)-this.thumbEl.getLeft(true))/this.getScaleLevel());var y=(this.thumbEl.getTop(true)>this.previewEl.getTop(true))?0:((this.previewEl.getTop(true)-this.thumbEl.getTop(true))/this.getScaleLevel()); +var I=this.minWidth-2*x;var J=this.minHeight-2*y;var H=1;if((x==0&&y==0)||(x==0&&y>0)){H=I/F;}if(x>0&&y==0){H=J/G;}if(x>0&&y>0){H=I/F;if(Fthis.imageEl.OriginHeight)?Math.abs(this.imageEl.OriginWidth-this.imageEl.OriginHeight):0; +E.drawImage(A,sx,sy,F,G,x,y,F,G);break;case 180:var F=(this.thumbEl.getWidth()/this.getScaleLevel()>this.imageEl.OriginWidth)?this.imageEl.OriginWidth:(this.thumbEl.getWidth()/this.getScaleLevel());var G=(this.thumbEl.getHeight()/this.getScaleLevel()>this.imageEl.OriginHeight)?this.imageEl.OriginHeight:(this.thumbEl.getHeight()/this.getScaleLevel()); +var x=(this.thumbEl.getLeft(true)>this.previewEl.getLeft(true))?0:((this.previewEl.getLeft(true)-this.thumbEl.getLeft(true))/this.getScaleLevel());var y=(this.thumbEl.getTop(true)>this.previewEl.getTop(true))?0:((this.previewEl.getTop(true)-this.thumbEl.getTop(true))/this.getScaleLevel()); +var I=this.minWidth-2*x;var J=this.minHeight-2*y;var H=1;if((x==0&&y==0)||(x==0&&y>0)){H=I/F;}if(x>0&&y==0){H=J/G;}if(x>0&&y>0){H=I/F;if(Fthis.imageEl.OriginHeight)?0:Math.abs(this.imageEl.OriginWidth-this.imageEl.OriginHeight); +sy+=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?Math.abs(this.imageEl.OriginWidth-this.imageEl.OriginHeight):0;E.drawImage(A,sx,sy,F,G,x,y,F,G);break;case 270:var F=(this.thumbEl.getWidth()/this.getScaleLevel()>this.imageEl.OriginHeight)?this.imageEl.OriginHeight:(this.thumbEl.getWidth()/this.getScaleLevel()); +var G=(this.thumbEl.getHeight()/this.getScaleLevel()>this.imageEl.OriginWidth)?this.imageEl.OriginWidth:(this.thumbEl.getHeight()/this.getScaleLevel());var x=(this.thumbEl.getLeft(true)>this.previewEl.getLeft(true))?0:((this.previewEl.getLeft(true)-this.thumbEl.getLeft(true))/this.getScaleLevel()); +var y=(this.thumbEl.getTop(true)>this.previewEl.getTop(true))?0:((this.previewEl.getTop(true)-this.thumbEl.getTop(true))/this.getScaleLevel());var I=this.minWidth-2*x;var J=this.minHeight-2*y;var H=1;if((x==0&&y==0)||(x==0&&y>0)){H=I/F;}if(x>0&&y==0){H=J/G; +}if(x>0&&y>0){H=I/F;if(Fthis.imageEl.OriginHeight)?0:Math.abs(this.imageEl.OriginWidth-this.imageEl.OriginHeight);E.drawImage(A,sx,sy,F,G,x,y,F,G);break;default:break;}this.cropData=D.toDataURL(this.cropType); +if(this.fireEvent('crop',this,this.cropData)!==false){this.process(this.file,this.cropData);}return;},setThumbBoxSize:function(){var A,B;if(this.isDocument&&typeof(this.imageEl)!='undefined'){A=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?Math.max(this.minWidth,this.minHeight):Math.min(this.minWidth,this.minHeight); +B=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?Math.min(this.minWidth,this.minHeight):Math.max(this.minWidth,this.minHeight);this.minWidth=A;this.minHeight=B;if(this.rotate==90||this.rotate==270){this.minWidth=B;this.minHeight=A;}}B=this.windowSize; +A=Math.ceil(this.minWidth*B/this.minHeight);if(this.minWidth>this.minHeight){A=this.windowSize;B=Math.ceil(this.minHeight*A/this.minWidth);}this.thumbEl.setStyle({width:A+'px',height:B+'px'});return;},setThumbBoxPosition:function(){var x=Math.ceil((this.bodyEl.getWidth()-this.thumbEl.getWidth())/2); +var y=Math.ceil((this.bodyEl.getHeight()-this.thumbEl.getHeight())/2);this.thumbEl.setLeft(x);this.thumbEl.setTop(y);},baseRotateLevel:function(){this.baseRotate=1;if(typeof(this.exif)!='undefined'&&typeof(this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']])!='undefined'&&[1,3,6,8].indexOf(this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']])!=-1){this.baseRotate=this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']]; +}this.rotate=Roo.dialog.UploadCropbox['Orientation'][this.baseRotate];},baseScaleLevel:function(){var A,B;if(this.isDocument){if(this.baseRotate==6||this.baseRotate==8){B=this.thumbEl.getHeight();this.baseScale=B/this.imageEl.OriginWidth;if(this.imageEl.OriginHeight*this.baseScale>this.thumbEl.getWidth()){A=this.thumbEl.getWidth(); +this.baseScale=A/this.imageEl.OriginHeight;}return;}B=this.thumbEl.getHeight();this.baseScale=B/this.imageEl.OriginHeight;if(this.imageEl.OriginWidth*this.baseScale>this.thumbEl.getWidth()){A=this.thumbEl.getWidth();this.baseScale=A/this.imageEl.OriginWidth; +}return;}if(this.baseRotate==6||this.baseRotate==8){A=this.thumbEl.getHeight();this.baseScale=A/this.imageEl.OriginHeight;if(this.imageEl.OriginHeight*this.baseScalethis.imageEl.OriginHeight){B=this.thumbEl.getWidth();this.baseScale=B/this.imageEl.OriginHeight;if(this.imageEl.OriginWidth*this.baseScalethis.imageEl.OriginHeight){B=this.thumbEl.getHeight(); +this.baseScale=B/this.imageEl.OriginHeight;if(this.imageEl.OriginWidth*this.baseScale=0xffe0&&H<=0xffef)||H===0xfffe){I=E.getUint16(F+2)+2;if(F+I>E.byteLength){Roo.log('Invalid meta data: Invalid segment size.');break;}if(H==0xffe1){B.parseExifData(E,F,I);}F+=I;continue;}break; +}}var J=B.urlAPI.createObjectURL(B.file);B.loadCanvas(J);return;};C.readAsArrayBuffer(this.file);}},parseExifData:function(A,B,C){var D=B+10,E,F;if(A.getUint32(B+4)!==0x45786966){return;}if(A.getUint32(B+4)!==0x45786966){return;}if(D+8>A.byteLength){Roo.log('Invalid Exif data: Invalid segment size.'); +return;}if(A.getUint16(B+8)!==0x0000){Roo.log('Invalid Exif data: Missing byte alignment offset.');return;}switch(A.getUint16(D)){case 0x4949:E=true;break;case 0x4D4D:E=false;break;default:Roo.log('Invalid Exif data: Invalid byte alignment marker.');return; +}if(A.getUint16(D+2,E)!==0x002A){Roo.log('Invalid Exif data: Missing TIFF marker.');return;}F=A.getUint32(D+4,E);this.parseExifTags(A,D,D+F,E);},parseExifTags:function(A,B,C,D){var E,F,i;if(C+6>A.byteLength){Roo.log('Invalid Exif data: Invalid directory offset.'); +return;}E=A.getUint16(C,D);F=C+2+12*E;if(F+4>A.byteLength){Roo.log('Invalid Exif data: Invalid directory size.');return;}for(i=0;i4?B+A.getUint32(C+8,F):(C+8);if(I+H>A.byteLength){Roo.log('Invalid Exif data: Invalid data offset.'); +return;}if(E===1){return G.getValue(A,I,F);}J=[];for(i=0;i'}]},{tag:'div',cls:'btn-group roo-upload-cropbox-picture',action:'picture',cn:[{tag:'button',cls:'btn btn-default',html:''} +]},{tag:'div',cls:'btn-group roo-upload-cropbox-rotate-right',action:'rotate-right',cn:[{tag:'button',cls:'btn btn-default',html:''}]}],DOCUMENT:[{tag:'div',cls:'btn-group roo-upload-cropbox-rotate-left',action:'rotate-left',cn:[{tag:'button',cls:'btn btn-default',html:''} +]},{tag:'div',cls:'btn-group roo-upload-cropbox-download',action:'download',cn:[{tag:'button',cls:'btn btn-default',html:''}]},{tag:'div',cls:'btn-group roo-upload-cropbox-crop',action:'crop',cn:[{tag:'button',cls:'btn btn-default',html:''} +]},{tag:'div',cls:'btn-group roo-upload-cropbox-trash',action:'trash',cn:[{tag:'button',cls:'btn btn-default',html:''}]},{tag:'div',cls:'btn-group roo-upload-cropbox-rotate-right',action:'rotate-right',cn:[{tag:'button',cls:'btn btn-default',html:''} +]}],ROTATOR:[{tag:'div',cls:'btn-group roo-upload-cropbox-rotate-left',action:'rotate-left',cn:[{tag:'button',cls:'btn btn-default',html:''}]},{tag:'div',cls:'btn-group roo-upload-cropbox-rotate-right',action:'rotate-right',cn:[{tag:'button',cls:'btn btn-default',html:''} +]}]}});