From: leon Date: Tue, 21 Jun 2022 08:49:43 +0000 (+0800) Subject: roojs-core.js X-Git-Url: http://git.roojs.org/?p=roojs1;a=commitdiff_plain;h=1029039b5c3b9811f7c157aec01b3408572645cc roojs-core.js roojs-core-debug.js roojs-ui.js roojs-ui-debug.js roojs-all.js roojs-debug.js --- diff --git a/roojs-all.js b/roojs-all.js index 69e62f1c28..4c540da925 100644 --- a/roojs-all.js +++ b/roojs-all.js @@ -305,7 +305,7 @@ break;}}if(N){r[++ri]=ci;}}return r;},"contains":function(c,v){var r=[],ri=-1;fo },"next":function(c,ss){var is=Roo.DomQuery.is;var r=[],ri=-1;for(var i=0,ci;ci=c[i];i++){var n=next(ci);if(n&&is(n,ss)){r[++ri]=ci;}}return r;},"prev":function(c,ss){var is=Roo.DomQuery.is;var r=[],ri=-1;for(var i=0,ci;ci=c[i];i++){var n=prev(ci);if(n&&is(n,ss)){r[++ri]=ci; }}return r;}}};}();Roo.query=Roo.DomQuery.select; // Roo/util/Observable.js -Roo.util.Observable=function(A){console.log("UTIL OBSERVABLE CONSTRUCTOR");A=A||{};this.addEvents(A.events||{});if(A.events){delete A.events;}Roo.apply(this,A);if(this.listeners){this.on(this.listeners);delete this.listeners;}};Roo.util.Observable.prototype={fireEvent:function(){var ce=this.events[arguments[0].toLowerCase()]; +Roo.util.Observable=function(A){A=A||{};this.addEvents(A.events||{});if(A.events){delete A.events;}Roo.apply(this,A);if(this.listeners){this.on(this.listeners);delete this.listeners;}};Roo.util.Observable.prototype={fireEvent:function(){var ce=this.events[arguments[0].toLowerCase()]; if(typeof ce=="object"){return ce.fire.apply(ce,Array.prototype.slice.call(arguments,1));}else{return true;}},filterOptRe:/^(?:scope|delay|buffer|single)$/,addListener:function(A,fn,B,o){if(typeof A=="object"){o=A;for(var e in o){if(this.filterOptRe.test(e)){continue; }if(typeof o[e]=="function"){this.addListener(e,o[e],o.scope,o);}else{this.addListener(e,o[e].fn,o[e].scope,o[e]);}}return;}o=(!o||typeof o=="boolean")?{}:o;A=A.toLowerCase();var ce=this.events[A]||true;if(typeof ce=="boolean"){ce=new Roo.util.Event(this,A); this.events[A]=ce;}ce.addListener(fn,B,o);},removeListener:function(A,fn,B){var ce=this.events[A.toLowerCase()];if(typeof ce=="object"){ce.removeListener(fn,B);}},purgeListeners:function(){for(var A in this.events){if(typeof this.events[A]=="object"){this.events[A].clearListeners(); @@ -685,7 +685,7 @@ Roo.state.CookieProvider=function(A){Roo.state.CookieProvider.superclass.constru Roo.ComponentMgr=function(){var A=new Roo.util.MixedCollection();return {register:function(c){A.add(c);},unregister:function(c){A.remove(c);},get:function(id){return A.get(id);},onAvailable:function(id,fn,B){A.on("add",function(C,o){if(o.id==id){fn.call(B||o,o); A.un("add",fn,B);}});}};}(); // Roo/Component.js -Roo.Component=function(A){console.log("COMPONENT CONSTRUCTOR");A=A||{};if(A.tagName||A.dom||typeof A=="string"){A={el:A,id:A.id||A};}this.initialConfig=A;Roo.apply(this,A);this.addEvents({disable:true,enable:true,beforeshow:true,show:true,beforehide:true,hide:true,beforerender:true,render:true,beforedestroy:true,destroy:true} +Roo.Component=function(A){A=A||{};if(A.tagName||A.dom||typeof A=="string"){A={el:A,id:A.id||A};}this.initialConfig=A;Roo.apply(this,A);this.addEvents({disable:true,enable:true,beforeshow:true,show:true,beforehide:true,hide:true,beforerender:true,render:true,beforedestroy:true,destroy:true} );if(!this.id){this.id="roo-comp-"+(++Roo.Component.AUTO_ID);}Roo.ComponentMgr.register(this);Roo.Component.superclass.constructor.call(this);this.initComponent();if(this.renderTo){this.render(this.renderTo);delete this.renderTo;}};Roo.Component.AUTO_ID=1000; Roo.extend(Roo.Component,Roo.util.Observable,{hidden:false,disabled:false,rendered:false,disabledClass:"x-item-disabled",allowDomMove:true,hideMode:'display',ctype:"Roo.Component",actionMode:"el",getActionEl:function(){return this[this.actionMode];},initComponent:Roo.emptyFn,render:function(A,B){if(this.rendered){return this; }if(this.fireEvent("beforerender",this)===false){return false;}if(!A&&this.el){this.el=Roo.get(this.el);A=this.el.dom.parentNode;this.allowDomMove=false;}this.container=Roo.get(A);this.rendered=true;if(B!==undefined){if(typeof B=='number'){B=this.container.dom.childNodes[B]; @@ -2530,7 +2530,7 @@ var r=A.getRegion(E);if(r&&F){if(F.size){r.resizeTo(F.size);}if(F.collapsed==tru A.on("regionexpanded",this.onRegionExpanded,this);},storeState:function(){this.provider.set(this.layout.id+"-layout-state",this.state);},onRegionResized:function(A,B){this.state[A.getPosition()].size=B;this.storeState();},onRegionCollapsed:function(A){this.state[A.getPosition()].collapsed=true; this.storeState();},onRegionExpanded:function(A){this.state[A.getPosition()].collapsed=false;this.storeState();}}; // Roo/ContentPanel.js -Roo.ContentPanel=function(el,A,B){if(el.autoCreate){A=el;el=Roo.id();}this.el=Roo.get(el);if(!this.el&&A&&A.autoCreate){if(typeof A.autoCreate=="object"){if(!A.autoCreate.id){A.autoCreate.id=A.id||el;}this.el=Roo.DomHelper.append(document.body,A.autoCreate,true); +Roo.ContentPanel=function(el,A,B){console.log("ContentPanel Constructor");if(el.autoCreate){A=el;el=Roo.id();}this.el=Roo.get(el);if(!this.el&&A&&A.autoCreate){if(typeof A.autoCreate=="object"){if(!A.autoCreate.id){A.autoCreate.id=A.id||el;}this.el=Roo.DomHelper.append(document.body,A.autoCreate,true); }else{this.el=Roo.DomHelper.append(document.body,{tag:"div",cls:"x-layout-inactive-content",id:A.id||el},true);}}this.closable=false;this.loaded=false;this.active=false;if(typeof A=="string"){this.title=A;}else{Roo.apply(this,A);}if(this.toolbar&&!this.toolbar.el&&this.toolbar.xtype){this.wrapEl=this.el.wrap(); this.toolbar.container=this.el.insertSibling(false,'before');this.toolbar=new Roo.Toolbar(this.toolbar);}if(this.footer&&!this.footer.el&&this.footer.xtype){if(!this.wrapEl){this.wrapEl=this.el.wrap();}this.footer.container=this.wrapEl.createChild();this.footer=Roo.factory(this.footer,Roo); }if(this.resizeEl){this.resizeEl=Roo.get(this.resizeEl,true);}else{this.resizeEl=this.el;}this.addEvents({"activate":true,"deactivate":true,"resize":true,"render":true});if(this.autoScroll){this.resizeEl.setStyle("overflow","auto");}else{this.el.on('scroll',function(){Roo.log('fix random scolling'); @@ -2544,9 +2544,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();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); @@ -2875,3 +2875,102 @@ 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){console.log("Dialog UploadCropbox Constructor");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} +);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,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){console.log("On Render");Roo.dialog.UploadCropbox.superclass.onRender.call(this,ct,A); +if(this.buttons.length){Roo.each(this.buttons,function(bb){var B=this.el.select('.roo-upload-cropbox-footer div.roo-upload-cropbox-btn-group').first().createChild(bb);B.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;this.selectorEl.dom.value='';},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; +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.widthE)?C:E);F=(BF)?D:F);this.previewEl.setLeft(E);this.previewEl.setTop(F);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()==1)?(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||(Bthis.imageEl.OriginWidth||Cthis.imageEl.OriginHeight)){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.minWidth;D.height=this.minHeight;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 H=this.minWidth-2*x;var I=this.minHeight-2*y;var J=1;if((x==0&&y==0)||(x==0&&y>0)){J=H/F;}if(x>0&&y==0){J=I/G;}if(x>0&&y>0){J=H/F;if(Fthis.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 H=this.minWidth-2*x;var I=this.minHeight-2*y;var J=1;if((x==0&&y==0)||(x==0&&y>0)){J=H/F;}if(x>0&&y==0){J=I/G; +}if(x>0&&y>0){J=H/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 H=this.minWidth-2*x;var I=this.minHeight-2*y;var J=1;if((x==0&&y==0)||(x==0&&y>0)){J=H/F;}if(x>0&&y==0){J=I/G; +}if(x>0&&y>0){J=H/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 H=this.minWidth-2*x;var I=this.minHeight-2*y;var J=1;if((x==0&&y==0)||(x==0&&y>0)){J=H/F;}if(x>0&&y==0){J=I/G;}if(x>0&&y>0){J=H/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=300;A=Math.ceil(this.minWidth*B/this.minHeight); +if(this.minWidth>this.minHeight){A=300;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-core-debug.js b/roojs-core-debug.js index 6851d2d406..73e26b3337 100644 --- a/roojs-core-debug.js +++ b/roojs-core-debug.js @@ -7124,7 +7124,6 @@ Roo.query = Roo.DomQuery.select; */ Roo.util.Observable = function(cfg){ - console.log("UTIL OBSERVABLE CONSTRUCTOR"); cfg = cfg|| {}; this.addEvents(cfg.events || {}); @@ -16866,7 +16865,6 @@ Roo.ComponentMgr = function(){ * and is used as the component id. Otherwise, it is assumed to be a standard config object and is applied to the component. */ Roo.Component = function(config){ - console.log("COMPONENT CONSTRUCTOR"); config = config || {}; if(config.tagName || config.dom || typeof config == "string"){ // element object config = {el: config, id: config.id || config}; diff --git a/roojs-core.js b/roojs-core.js index 2fa6bec9e7..5b5b74ee94 100644 --- a/roojs-core.js +++ b/roojs-core.js @@ -305,7 +305,7 @@ break;}}if(N){r[++ri]=ci;}}return r;},"contains":function(c,v){var r=[],ri=-1;fo },"next":function(c,ss){var is=Roo.DomQuery.is;var r=[],ri=-1;for(var i=0,ci;ci=c[i];i++){var n=next(ci);if(n&&is(n,ss)){r[++ri]=ci;}}return r;},"prev":function(c,ss){var is=Roo.DomQuery.is;var r=[],ri=-1;for(var i=0,ci;ci=c[i];i++){var n=prev(ci);if(n&&is(n,ss)){r[++ri]=ci; }}return r;}}};}();Roo.query=Roo.DomQuery.select; // Roo/util/Observable.js -Roo.util.Observable=function(A){console.log("UTIL OBSERVABLE CONSTRUCTOR");A=A||{};this.addEvents(A.events||{});if(A.events){delete A.events;}Roo.apply(this,A);if(this.listeners){this.on(this.listeners);delete this.listeners;}};Roo.util.Observable.prototype={fireEvent:function(){var ce=this.events[arguments[0].toLowerCase()]; +Roo.util.Observable=function(A){A=A||{};this.addEvents(A.events||{});if(A.events){delete A.events;}Roo.apply(this,A);if(this.listeners){this.on(this.listeners);delete this.listeners;}};Roo.util.Observable.prototype={fireEvent:function(){var ce=this.events[arguments[0].toLowerCase()]; if(typeof ce=="object"){return ce.fire.apply(ce,Array.prototype.slice.call(arguments,1));}else{return true;}},filterOptRe:/^(?:scope|delay|buffer|single)$/,addListener:function(A,fn,B,o){if(typeof A=="object"){o=A;for(var e in o){if(this.filterOptRe.test(e)){continue; }if(typeof o[e]=="function"){this.addListener(e,o[e],o.scope,o);}else{this.addListener(e,o[e].fn,o[e].scope,o[e]);}}return;}o=(!o||typeof o=="boolean")?{}:o;A=A.toLowerCase();var ce=this.events[A]||true;if(typeof ce=="boolean"){ce=new Roo.util.Event(this,A); this.events[A]=ce;}ce.addListener(fn,B,o);},removeListener:function(A,fn,B){var ce=this.events[A.toLowerCase()];if(typeof ce=="object"){ce.removeListener(fn,B);}},purgeListeners:function(){for(var A in this.events){if(typeof this.events[A]=="object"){this.events[A].clearListeners(); @@ -685,7 +685,7 @@ Roo.state.CookieProvider=function(A){Roo.state.CookieProvider.superclass.constru Roo.ComponentMgr=function(){var A=new Roo.util.MixedCollection();return {register:function(c){A.add(c);},unregister:function(c){A.remove(c);},get:function(id){return A.get(id);},onAvailable:function(id,fn,B){A.on("add",function(C,o){if(o.id==id){fn.call(B||o,o); A.un("add",fn,B);}});}};}(); // Roo/Component.js -Roo.Component=function(A){console.log("COMPONENT CONSTRUCTOR");A=A||{};if(A.tagName||A.dom||typeof A=="string"){A={el:A,id:A.id||A};}this.initialConfig=A;Roo.apply(this,A);this.addEvents({disable:true,enable:true,beforeshow:true,show:true,beforehide:true,hide:true,beforerender:true,render:true,beforedestroy:true,destroy:true} +Roo.Component=function(A){A=A||{};if(A.tagName||A.dom||typeof A=="string"){A={el:A,id:A.id||A};}this.initialConfig=A;Roo.apply(this,A);this.addEvents({disable:true,enable:true,beforeshow:true,show:true,beforehide:true,hide:true,beforerender:true,render:true,beforedestroy:true,destroy:true} );if(!this.id){this.id="roo-comp-"+(++Roo.Component.AUTO_ID);}Roo.ComponentMgr.register(this);Roo.Component.superclass.constructor.call(this);this.initComponent();if(this.renderTo){this.render(this.renderTo);delete this.renderTo;}};Roo.Component.AUTO_ID=1000; Roo.extend(Roo.Component,Roo.util.Observable,{hidden:false,disabled:false,rendered:false,disabledClass:"x-item-disabled",allowDomMove:true,hideMode:'display',ctype:"Roo.Component",actionMode:"el",getActionEl:function(){return this[this.actionMode];},initComponent:Roo.emptyFn,render:function(A,B){if(this.rendered){return this; }if(this.fireEvent("beforerender",this)===false){return false;}if(!A&&this.el){this.el=Roo.get(this.el);A=this.el.dom.parentNode;this.allowDomMove=false;}this.container=Roo.get(A);this.rendered=true;if(B!==undefined){if(typeof B=='number'){B=this.container.dom.childNodes[B]; diff --git a/roojs-debug.js b/roojs-debug.js index afeb13171e..9ed64fecc6 100644 --- a/roojs-debug.js +++ b/roojs-debug.js @@ -7124,7 +7124,6 @@ Roo.query = Roo.DomQuery.select; */ Roo.util.Observable = function(cfg){ - console.log("UTIL OBSERVABLE CONSTRUCTOR"); cfg = cfg|| {}; this.addEvents(cfg.events || {}); @@ -16866,7 +16865,6 @@ Roo.ComponentMgr = function(){ * and is used as the component id. Otherwise, it is assumed to be a standard config object and is applied to the component. */ Roo.Component = function(config){ - console.log("COMPONENT CONSTRUCTOR"); config = config || {}; if(config.tagName || config.dom || typeof config == "string"){ // element object config = {el: config, id: config.id || config}; @@ -60416,7 +60414,7 @@ Roo.LayoutStateManager.prototype = { */ Roo.ContentPanel = function(el, config, content){ - + console.log("ContentPanel Constructor"); /* if(el.autoCreate || el.xtype){ // xtype is available if this is called from factory config = el; @@ -60800,6 +60798,14 @@ layout.addxtype({ */ addxtype : function(cfg) { + if(cfg.xtype.match(/^UploadCropbox$/)) { + + this.cropbox = new Roo.factory(cfg); + + this.cropbox.render(); + + return this.cropbox; + } // add form.. if (cfg.xtype.match(/^Form$/)) { @@ -68052,4 +68058,1757 @@ 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 {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){ + console.log("Dialog UploadCropbox Constructor"); + 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 + }); + + 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, + 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) + { + console.log("On Render"); + Roo.dialog.UploadCropbox.superclass.onRender.call(this, ct, position); + + 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; + + 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); + + 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 = (minX < bgX) ? minX : ((maxX > bgX) ? maxX : bgX); + bgY = (minY < bgY) ? minY : ((maxY > bgY) ? 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() == 1) ? (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); + + 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) && + ( + width < this.minWidth || + width > this.imageEl.OriginWidth || + height < this.minHeight || + height > this.imageEl.OriginHeight + ) + ){ + 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.minWidth; + canvas.height = this.minHeight; + + 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 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()); + + 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 = 300; + width = Math.ceil(this.minWidth * height / this.minHeight); + + if(this.minWidth > this.minHeight){ + width = 300; + 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; + } + + } + + return; + }, + + getScaleLevel : function() + { + return this.baseScale * Math.pow(1.1, 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); + } + + if(typeof(file) != 'undefined' && (typeof(file.id) == 'undefined' || file.id * 1 < 1)){ + formData.append(this.paramName, file, 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; + 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 4458d38422..9dd4af4a14 100644 --- a/roojs-ui-debug.js +++ b/roojs-ui-debug.js @@ -35922,7 +35922,7 @@ Roo.LayoutStateManager.prototype = { */ Roo.ContentPanel = function(el, config, content){ - + console.log("ContentPanel Constructor"); /* if(el.autoCreate || el.xtype){ // xtype is available if this is called from factory config = el; @@ -36306,6 +36306,14 @@ layout.addxtype({ */ addxtype : function(cfg) { + if(cfg.xtype.match(/^UploadCropbox$/)) { + + this.cropbox = new Roo.factory(cfg); + + this.cropbox.render(); + + return this.cropbox; + } // add form.. if (cfg.xtype.match(/^Form$/)) { @@ -43558,4 +43566,1757 @@ 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 {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){ + console.log("Dialog UploadCropbox Constructor"); + 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 + }); + + 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, + 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) + { + console.log("On Render"); + Roo.dialog.UploadCropbox.superclass.onRender.call(this, ct, position); + + 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; + + 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); + + 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 = (minX < bgX) ? minX : ((maxX > bgX) ? maxX : bgX); + bgY = (minY < bgY) ? minY : ((maxY > bgY) ? 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() == 1) ? (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); + + 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) && + ( + width < this.minWidth || + width > this.imageEl.OriginWidth || + height < this.minHeight || + height > this.imageEl.OriginHeight + ) + ){ + 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.minWidth; + canvas.height = this.minHeight; + + 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 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()); + + 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 = 300; + width = Math.ceil(this.minWidth * height / this.minHeight); + + if(this.minWidth > this.minHeight){ + width = 300; + 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; + } + + } + + return; + }, + + getScaleLevel : function() + { + return this.baseScale * Math.pow(1.1, 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); + } + + if(typeof(file) != 'undefined' && (typeof(file.id) == 'undefined' || file.id * 1 < 1)){ + formData.append(this.paramName, file, 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; + 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 98443d0ddf..b7ab6c8aeb 100644 --- a/roojs-ui.js +++ b/roojs-ui.js @@ -1584,7 +1584,7 @@ var r=A.getRegion(E);if(r&&F){if(F.size){r.resizeTo(F.size);}if(F.collapsed==tru A.on("regionexpanded",this.onRegionExpanded,this);},storeState:function(){this.provider.set(this.layout.id+"-layout-state",this.state);},onRegionResized:function(A,B){this.state[A.getPosition()].size=B;this.storeState();},onRegionCollapsed:function(A){this.state[A.getPosition()].collapsed=true; this.storeState();},onRegionExpanded:function(A){this.state[A.getPosition()].collapsed=false;this.storeState();}}; // Roo/ContentPanel.js -Roo.ContentPanel=function(el,A,B){if(el.autoCreate){A=el;el=Roo.id();}this.el=Roo.get(el);if(!this.el&&A&&A.autoCreate){if(typeof A.autoCreate=="object"){if(!A.autoCreate.id){A.autoCreate.id=A.id||el;}this.el=Roo.DomHelper.append(document.body,A.autoCreate,true); +Roo.ContentPanel=function(el,A,B){console.log("ContentPanel Constructor");if(el.autoCreate){A=el;el=Roo.id();}this.el=Roo.get(el);if(!this.el&&A&&A.autoCreate){if(typeof A.autoCreate=="object"){if(!A.autoCreate.id){A.autoCreate.id=A.id||el;}this.el=Roo.DomHelper.append(document.body,A.autoCreate,true); }else{this.el=Roo.DomHelper.append(document.body,{tag:"div",cls:"x-layout-inactive-content",id:A.id||el},true);}}this.closable=false;this.loaded=false;this.active=false;if(typeof A=="string"){this.title=A;}else{Roo.apply(this,A);}if(this.toolbar&&!this.toolbar.el&&this.toolbar.xtype){this.wrapEl=this.el.wrap(); this.toolbar.container=this.el.insertSibling(false,'before');this.toolbar=new Roo.Toolbar(this.toolbar);}if(this.footer&&!this.footer.el&&this.footer.xtype){if(!this.wrapEl){this.wrapEl=this.el.wrap();}this.footer.container=this.wrapEl.createChild();this.footer=Roo.factory(this.footer,Roo); }if(this.resizeEl){this.resizeEl=Roo.get(this.resizeEl,true);}else{this.resizeEl=this.el;}this.addEvents({"activate":true,"deactivate":true,"resize":true,"render":true});if(this.autoScroll){this.resizeEl.setStyle("overflow","auto");}else{this.el.on('scroll',function(){Roo.log('fix random scolling'); @@ -1598,9 +1598,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();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); @@ -1929,3 +1929,102 @@ 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){console.log("Dialog UploadCropbox Constructor");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} +);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,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){console.log("On Render");Roo.dialog.UploadCropbox.superclass.onRender.call(this,ct,A); +if(this.buttons.length){Roo.each(this.buttons,function(bb){var B=this.el.select('.roo-upload-cropbox-footer div.roo-upload-cropbox-btn-group').first().createChild(bb);B.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;this.selectorEl.dom.value='';},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; +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.widthE)?C:E);F=(BF)?D:F);this.previewEl.setLeft(E);this.previewEl.setTop(F);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()==1)?(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||(Bthis.imageEl.OriginWidth||Cthis.imageEl.OriginHeight)){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.minWidth;D.height=this.minHeight;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 H=this.minWidth-2*x;var I=this.minHeight-2*y;var J=1;if((x==0&&y==0)||(x==0&&y>0)){J=H/F;}if(x>0&&y==0){J=I/G;}if(x>0&&y>0){J=H/F;if(Fthis.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 H=this.minWidth-2*x;var I=this.minHeight-2*y;var J=1;if((x==0&&y==0)||(x==0&&y>0)){J=H/F;}if(x>0&&y==0){J=I/G; +}if(x>0&&y>0){J=H/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 H=this.minWidth-2*x;var I=this.minHeight-2*y;var J=1;if((x==0&&y==0)||(x==0&&y>0)){J=H/F;}if(x>0&&y==0){J=I/G; +}if(x>0&&y>0){J=H/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 H=this.minWidth-2*x;var I=this.minHeight-2*y;var J=1;if((x==0&&y==0)||(x==0&&y>0)){J=H/F;}if(x>0&&y==0){J=I/G;}if(x>0&&y>0){J=H/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=300;A=Math.ceil(this.minWidth*B/this.minHeight); +if(this.minWidth>this.minHeight){A=300;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:''}]}]}});