/* * Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.html or http://cksource.com/ckfinder/license * * The software, this file and its contents are subject to the CKFinder * License. Please read the license.txt file before using, installing, copying, * modifying or distribute this file or part of its contents. The contents of * this file is part of the Source Code of CKFinder. */ CKFinder.addPlugin( 'imageresize', { readOnly : false, connectorInitialized : function( api, xml ) { var node = xml.selectSingleNode( 'Connector/PluginsInfo/imageresize/@smallThumb' ); if ( node ) CKFinder.config.imageresize_thumbSmall = node.value; node = xml.selectSingleNode( 'Connector/PluginsInfo/imageresize/@mediumThumb' ); if ( node ) CKFinder.config.imageresize_thumbMedium = node.value; node = xml.selectSingleNode( 'Connector/PluginsInfo/imageresize/@largeThumb' ); if ( node ) CKFinder.config.imageresize_thumbLarge = node.value; }, uiReady : function( api ) { var regexExt = /^(.*)\.([^\.]+)$/, regexFileName = /^(.*?)(?:_\d+x\d+)?\.([^\.]+)$/, regexGetSize = /^\s*(\d+)(px)?\s*$/i, regexGetSizeOrEmpty = /(^\s*(\d+)(px)?\s*$)|^$/i, imageDimension = { width : 0, height : 0 }, file, doc; var updateFileName = function( dialog ) { var width = dialog.getValueOf( 'tab1', 'width' ) || 0, height = dialog.getValueOf( 'tab1', 'height' ) || 0, e = dialog.getContentElement( 'tab1', 'createNewBox' ); if ( width && height ) { var matches = file.name.match( regexFileName ); dialog.setValueOf( 'tab1', 'fileName', matches[1] + '_' + width + 'x' + height ); e.getElement().show(); } else e.getElement().hide(); }; var onSizeChange = function() { var value = this.getValue(), // This = input element. dialog = this.getDialog(), maxWidth = api.config.imagesMaxWidth, maxHeight = api.config.imagesMaxHeight, aMatch = value.match( regexGetSize ), width = imageDimension.width, height = imageDimension.height, newHeight, newWidth; if ( aMatch ) value = aMatch[1]; if ( !api.config.imageresize_allowEnlarging ) { if ( width && width < maxWidth ) maxWidth = width; if ( height && height < maxHeight ) maxHeight = height; } if ( maxHeight > 0 && this.id == 'height' && value > maxHeight ) { value = maxHeight; dialog.setValueOf( 'tab1', 'height', value ); } if ( maxWidth > 0 && this.id == 'width' && value > maxWidth ) { value = maxWidth; dialog.setValueOf( 'tab1', 'width', value ); } // Only if ratio is locked if ( dialog.lockRatio && width && height ) { if ( this.id == 'height' ) { if ( value && value != '0' ) value = Math.round( width * ( value / height ) ); if ( !isNaN( value ) ) { // newWidth > maxWidth if ( maxWidth > 0 && value > maxWidth ) { value = maxWidth; newHeight = Math.round( height * ( value / width ) ); dialog.setValueOf( 'tab1', 'height', newHeight ); } dialog.setValueOf( 'tab1', 'width', value ); } } else //this.id = txtWidth. { if ( value && value != '0' ) value = Math.round( height * ( value / width ) ); if ( !isNaN( value ) ) { // newHeight > maxHeight if ( maxHeight > 0 && value > maxHeight ) { value = maxHeight; newWidth = Math.round( width * ( value / height ) ); dialog.setValueOf( 'tab1', 'width', newWidth ); } dialog.setValueOf( 'tab1', 'height', value ); } } } updateFileName( dialog ); }; var resetSize = function( dialog ) { if ( imageDimension.width && imageDimension.height ) { dialog.setValueOf( 'tab1', 'width', imageDimension.width ); dialog.setValueOf( 'tab1', 'height', imageDimension.height ); updateFileName( dialog ); } }; var switchLockRatio = function( dialog, value ) { var doc = dialog.getElement().getDocument(), ratioButton = doc.getById( 'btnLockSizes' ); if ( imageDimension.width && imageDimension.height ) { if ( value == 'check' ) // Check image ratio and original image ratio. { var width = dialog.getValueOf( 'tab1', 'width' ), height = dialog.getValueOf( 'tab1', 'height' ), originalRatio = imageDimension.width * 1000 / imageDimension.height, thisRatio = width * 1000 / height; dialog.lockRatio = false; // Default: unlock ratio if ( !width && !height ) dialog.lockRatio = true; // If someone didn't start typing, lock ratio. else if ( !isNaN( originalRatio ) && !isNaN( thisRatio ) ) { if ( Math.round( originalRatio ) == Math.round( thisRatio ) ) dialog.lockRatio = true; } } else if ( value != undefined ) dialog.lockRatio = value; else dialog.lockRatio = !dialog.lockRatio; } else if ( value != 'check' ) // I can't lock ratio if ratio is unknown. dialog.lockRatio = false; if ( dialog.lockRatio ) ratioButton.removeClass( 'ckf_btn_unlocked' ); else ratioButton.addClass( 'ckf_btn_unlocked' ); return dialog.lockRatio; }; CKFinder.dialog.add( 'resizeDialog', function( api ) { return { title : api.lang.Imageresize.dialogTitle.replace( '%s', api.getSelectedFile().name ), // TODO resizable : CKFinder.DIALOG_RESIZE_BOTH minWidth : CKFinder.env.webkit ? 290 : 390, minHeight : 230, onShow : function() { var dialog = this, thumbSmall = CKFinder.config.imageresize_thumbSmall, thumbMedium = CKFinder.config.imageresize_thumbMedium, thumbLarge = CKFinder.config.imageresize_thumbLarge; doc = dialog.getElement().getDocument(); file = api.getSelectedFile(); this.setTitle( api.lang.Imageresize.dialogTitle.replace( '%s', file.name ) ); var previewImg = doc.getById( 'previewImage' ); var sizeSpan = doc.getById( 'imageSize' ); // Thumbnails should be limited to a reasonable value (#1020). previewImg.setAttribute( 'src', file.getThumbnailUrl( true ) ); previewImg.on( 'load', function() { previewImg.removeStyle( 'width' ); previewImg.removeStyle( 'height' ); var width = previewImg.$.width, height = previewImg.$.height; previewImg.hide(); if ( CKFinder.env.ie6Compat ) { if ( width > height ) previewImg.setStyles( { width : 100 + 'px', height : Math.round( height / ( width / 100 ) ) + 'px' } ); else previewImg.setStyles( { height : 100 + 'px', width : Math.round( width / ( height / 100 ) ) + 'px' } ); } else { previewImg.removeStyle( 'max-width' ); previewImg.removeStyle( 'max-height' ); if ( width > height ) previewImg.setStyle( 'max-width', '100px' ); else previewImg.setStyle( 'max-height', '100px' ); } previewImg.show(); }); var updateImgDimension = function( width, height ) { if ( !width || !height ) { sizeSpan.setText( '' ); return; } imageDimension.width = width; imageDimension.height = height; sizeSpan.setText( width + ' x ' + height + ' px' ); CKFinder.tools.setTimeout( function(){ switchLockRatio( dialog, 'check' ); }, 0, dialog ); }; api.connector.sendCommand( 'ImageResizeInfo', { fileName : file.name }, function( xml ) { if ( xml.checkError() ) return; var width = xml.selectSingleNode( 'Connector/ImageInfo/@width' ), height = xml.selectSingleNode( 'Connector/ImageInfo/@height' ), result; if ( width && height ) { width = parseInt( width.value, 10 ); height = parseInt( height.value, 10 ); updateImgDimension( width, height ); var checkThumbs = function( id, size ) { if ( !size ) return; var reThumb = /^(\d+)x(\d+)$/; result = reThumb.exec( size ); var el = dialog.getContentElement( 'tab1', id ); if ( 0 + result[ 1 ] > width && 0 + result[ 2 ] > height ) { el.disable(); el.getElement().setAttribute( 'title', api.lang.Imageresize.imageSmall ).addClass( 'cke_disabled' ); } else { el.enable(); el.getElement().setAttribute( 'title', '' ).removeClass( 'cke_disabled' ); } }; checkThumbs( 'smallThumb', thumbSmall ); checkThumbs( 'mediumThumb', thumbMedium ); checkThumbs( 'largeThumb', thumbLarge ); } }, file.folder.type, file.folder ); if ( !thumbSmall ) dialog.getContentElement( 'tab1', 'smallThumb' ).getElement().hide(); if ( !thumbMedium ) dialog.getContentElement( 'tab1', 'mediumThumb' ).getElement().hide(); if ( !thumbLarge ) dialog.getContentElement( 'tab1', 'largeThumb' ).getElement().hide(); if ( !thumbSmall && !thumbMedium && !thumbLarge ) dialog.getContentElement( 'tab1', 'thumbsLabel' ).getElement().hide(); dialog.setValueOf( 'tab1', 'fileName', file.name ); dialog.getContentElement( 'tab1', 'fileNameExt' ).getElement().setHtml( '.' + file.ext ); dialog.getContentElement( 'tab1', 'width' ).focus(); dialog.getContentElement( 'tab1', 'fileName').setValue( '' ); dialog.getContentElement( 'tab1', 'createNewBox' ).getElement().hide(); updateImgDimension( 0,0 ); }, onOk : function() { var dialog = this, width = dialog.getValueOf( 'tab1', 'width' ), height = dialog.getValueOf( 'tab1', 'height' ), small = dialog.getValueOf( 'tab1', 'smallThumb' ), medium = dialog.getValueOf( 'tab1', 'mediumThumb' ), large = dialog.getValueOf( 'tab1', 'largeThumb' ), fileName = dialog.getValueOf( 'tab1', 'fileName' ), createNew = dialog.getValueOf( 'tab1', 'createNew' ); if ( width && !height ) { api.openMsgDialog( '', api.lang.Imageresize.invalidHeight ); return false; } else if ( !width && height ) { api.openMsgDialog( '', api.lang.Imageresize.invalidWidth ); return false; } if ( !api.config.imageresize_allowEnlarging && ( parseInt( width, 10 ) > imageDimension.width || parseInt( height, 10 ) > imageDimension.height ) ) { var str = api.lang.Imageresize.sizeTooBig; api.openMsgDialog( '', str.replace( '%size', imageDimension.width + 'x' + imageDimension.height ) ); return false; } if ( ( width && height ) || small || medium || large ) { if ( !createNew ) fileName = file.name; api.connector.sendCommandPost( 'ImageResize', null, { width : width, height : height, fileName : file.name, newFileName : fileName + '.' + file.ext, overwrite : createNew ? 0 : 1, small : small ? 1 : 0, medium : medium ? 1 : 0, large : large ? 1 : 0 }, function( xml ) { if ( xml.checkError() ) return; api.openMsgDialog( '', api.lang.Imageresize.resizeSuccess ); api.refreshOpenedFolder(); }, file.folder.type, file.folder ); } return undefined; }, contents : [ { id : 'tab1', label : '', title : '', expand : true, padding : 0, elements : [ { type : 'hbox', // The dialog window looks weird on Webkit (#1021) widths : [ ( CKFinder.env.webkit ? 130 : 180 ) + 'px', ( CKFinder.env.webkit ? 250 : 280 ) + 'px' ], children: [ { type : 'vbox', children: [ { type : 'html', html : '' + '' + '
' + '
' + '' + '
' }, { type : 'html', id : 'thumbsLabel', html : '' + api.lang.Imageresize.thumbnailNew + '' }, { type : 'checkbox', id : 'smallThumb', checked : false, label : api.lang.Imageresize.thumbnailSmall.replace( '%s', CKFinder.config.imageresize_thumbSmall ) }, { type : 'checkbox', id : 'mediumThumb', checked : false, label : api.lang.Imageresize.thumbnailMedium.replace( '%s', CKFinder.config.imageresize_thumbMedium ) }, { type : 'checkbox', id : 'largeThumb', checked : false, label : api.lang.Imageresize.thumbnailLarge.replace( '%s', CKFinder.config.imageresize_thumbLarge ) } ] }, { type : 'vbox', children : [ { type : 'html', html : '' + api.lang.Imageresize.newSize + '' }, { type : 'hbox', widths : [ '80%', '20%' ], children: [ { type : 'vbox', children: [ { type : 'text', labelLayout : 'horizontal', label : api.lang.Imageresize.width, onKeyUp : onSizeChange, validate: function() { var value = this.getValue(); if ( value ) { var aMatch = value.match( regexGetSize ); if ( !aMatch || parseInt( aMatch[1], 10 ) < 1 ) { api.openMsgDialog( '', api.lang.Imageresize.invalidWidth ); return false; } } return true; }, id : 'width' }, { type : 'text', labelLayout : 'horizontal', label : api.lang.Imageresize.height, onKeyUp : onSizeChange, validate: function() { var value = this.getValue(); if ( value ) { var aMatch = value.match( regexGetSize ); if ( !aMatch || parseInt( aMatch[1], 10 ) < 1 ) { api.openMsgDialog( '', api.lang.Imageresize.invalidHeight ); return false; } } return true; }, id : 'height' } ] }, { type : 'html', onLoad : function() { var doc = this.getElement().getDocument(), dialog = this.getDialog(); // Activate Reset button var resetButton = doc.getById( 'btnResetSize' ), ratioButton = doc.getById( 'btnLockSizes' ); if ( resetButton ) { resetButton.on( 'click', function( evt ) { resetSize( this ); evt.data.preventDefault(); }, dialog ); resetButton.on( 'mouseover', function() { this.addClass( 'ckf_btn_over' ); }, resetButton ); resetButton.on( 'mouseout', function() { this.removeClass( 'ckf_btn_over' ); }, resetButton ); } // Activate (Un)LockRatio button if ( ratioButton ) { ratioButton.on( 'click', function( evt ) { var locked = switchLockRatio( this ), width = this.getValueOf( 'tab1', 'width' ); if ( imageDimension.width && width ) { var height = imageDimension.height / imageDimension.width * width; if ( !isNaN( height ) ) { this.setValueOf( 'tab1', 'height', Math.round( height ) ); updateFileName( dialog ); } } evt.data.preventDefault(); }, dialog ); ratioButton.on( 'mouseover', function() { this.addClass( 'ckf_btn_over' ); }, ratioButton ); ratioButton.on( 'mouseout', function() { this.removeClass( 'ckf_btn_over' ); }, ratioButton ); } }, html : '
'+ '' + ''+ '
' } ] }, { type : 'vbox', id : 'createNewBox', hidden : true, children: [ { type : 'checkbox', checked : true, id : 'createNew', label : api.lang.Imageresize.newImage, 'default' : true, onChange : function() { var dialog = this.getDialog(); var filenameInput = dialog.getContentElement( 'tab1', 'fileName' ); if ( filenameInput ) { if ( !this.getValue() ) filenameInput.getElement().hide(); else filenameInput.getElement().show(); } } }, { type : 'hbox', widths : [ '90%', '10%' ], padding : 0, children : [ { type : 'text', label : '', validate : function() { var dialog = this.getDialog(), createNew = dialog.getContentElement( 'tab1', 'createNew' ), value = this.getValue(); if ( createNew && dialog.getValueOf( 'tab1', 'width' ) && dialog.getValueOf( 'tab1', 'height' ) ) { if ( !value ) { api.openMsgDialog( '', api.lang.Imageresize.invalidName ); return false; } } return true; }, id : 'fileName' }, { type : 'html', html : '', id : 'fileNameExt', onLoad : function() { this.getElement().getParent().setStyles( { 'vertical-align' : 'bottom', 'padding-bottom' : '2px' } ); } } ] } ] } ] } ] } ] } ], // TODO http://dev.fckeditor.net/ticket/4750 buttons : [ CKFinder.dialog.okButton, CKFinder.dialog.cancelButton ] }; } ); api.addFileContextMenuOption( { label : api.lang.Imageresize.contextMenuName, command : 'resizeImage' } , function( api, file ) { api.openDialog( 'resizeDialog' ); }, function ( file ) { // Disable for files other than images. if ( !file.isImage() || !api.getSelectedFolder().type ) return false; if ( file.folder.acl.fileDelete && file.folder.acl.fileUpload ) return true; else return -1; } ); } } );