JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
vanilla ckeditor-3.2.2
[ckeditor.git] / _source / plugins / image / dialogs / image.js
index 3ba0dc1..4ebfd16 100644 (file)
@@ -5,202 +5,207 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
 \r
 (function()\r
 {\r
-       // Load image preview.\r
-       var IMAGE = 1,\r
-               LINK = 2,\r
-               PREVIEW = 4,\r
-               CLEANUP = 8,\r
-               regexGetSize = /^\s*(\d+)((px)|\%)?\s*$/i,\r
-               regexGetSizeOrEmpty = /(^\s*(\d+)((px)|\%)?\s*$)|^$/i,\r
-               pxLengthRegex = /^\d+px$/;\r
-\r
-       var onSizeChange = function()\r
+       var imageDialog = function( editor, dialogType )\r
        {\r
-               var value = this.getValue(),    // This = input element.\r
-                       dialog = this.getDialog(),\r
-                       aMatch  =  value.match( regexGetSize ); // Check value\r
-               if ( aMatch )\r
+               // Load image preview.\r
+               var IMAGE = 1,\r
+                       LINK = 2,\r
+                       PREVIEW = 4,\r
+                       CLEANUP = 8,\r
+                       regexGetSize = /^\s*(\d+)((px)|\%)?\s*$/i,\r
+                       regexGetSizeOrEmpty = /(^\s*(\d+)((px)|\%)?\s*$)|^$/i,\r
+                       pxLengthRegex = /^\d+px$/;\r
+\r
+               var onSizeChange = function()\r
                {\r
-                       if ( aMatch[2] == '%' )                 // % is allowed - > unlock ratio.\r
-                               switchLockRatio( dialog, false );       // Unlock.\r
-                       value = aMatch[1];\r
-               }\r
+                       var value = this.getValue(),    // This = input element.\r
+                               dialog = this.getDialog(),\r
+                               aMatch  =  value.match( regexGetSize ); // Check value\r
+                       if ( aMatch )\r
+                       {\r
+                               if ( aMatch[2] == '%' )                 // % is allowed - > unlock ratio.\r
+                                       switchLockRatio( dialog, false );       // Unlock.\r
+                               value = aMatch[1];\r
+                       }\r
 \r
-               // Only if ratio is locked\r
-               if ( dialog.lockRatio )\r
-               {\r
-                       var oImageOriginal = dialog.originalElement;\r
-                       if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' )\r
+                       // Only if ratio is locked\r
+                       if ( dialog.lockRatio )\r
                        {\r
-                               if ( this.id == 'txtHeight' )\r
-                               {\r
-                                       if ( value && value != '0' )\r
-                                               value = Math.round( oImageOriginal.$.width * ( value  / oImageOriginal.$.height ) );\r
-                                       if ( !isNaN( value ) )\r
-                                               dialog.setValueOf( 'info', 'txtWidth', value );\r
-                               }\r
-                               else            //this.id = txtWidth.\r
+                               var oImageOriginal = dialog.originalElement;\r
+                               if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' )\r
                                {\r
-                                       if ( value && value != '0' )\r
-                                               value = Math.round( oImageOriginal.$.height * ( value  / oImageOriginal.$.width ) );\r
-                                       if ( !isNaN( value ) )\r
-                                               dialog.setValueOf( 'info', 'txtHeight', value );\r
+                                       if ( this.id == 'txtHeight' )\r
+                                       {\r
+                                               if ( value && value != '0' )\r
+                                                       value = Math.round( oImageOriginal.$.width * ( value  / oImageOriginal.$.height ) );\r
+                                               if ( !isNaN( value ) )\r
+                                                       dialog.setValueOf( 'info', 'txtWidth', value );\r
+                                       }\r
+                                       else            //this.id = txtWidth.\r
+                                       {\r
+                                               if ( value && value != '0' )\r
+                                                       value = Math.round( oImageOriginal.$.height * ( value  / oImageOriginal.$.width ) );\r
+                                               if ( !isNaN( value ) )\r
+                                                       dialog.setValueOf( 'info', 'txtHeight', value );\r
+                                       }\r
                                }\r
                        }\r
-               }\r
-               updatePreview( dialog );\r
-       };\r
-\r
-       var updatePreview = function( dialog )\r
-       {\r
-               //Don't load before onShow.\r
-               if ( !dialog.originalElement || !dialog.preview )\r
-                       return 1;\r
+                       updatePreview( dialog );\r
+               };\r
 \r
-               // Read attributes and update imagePreview;\r
-               dialog.commitContent( PREVIEW, dialog.preview );\r
-               return 0;\r
-       };\r
+               var updatePreview = function( dialog )\r
+               {\r
+                       //Don't load before onShow.\r
+                       if ( !dialog.originalElement || !dialog.preview )\r
+                               return 1;\r
 \r
-       // Custom commit dialog logic, where we're intended to give inline style\r
-       // field (txtdlgGenStyle) higher priority to avoid overwriting styles contribute\r
-       // by other fields.\r
-       function commitContent()\r
-       {\r
-               var args = arguments;\r
-               var inlineStyleField = this.getContentElement( 'advanced', 'txtdlgGenStyle' );\r
-               inlineStyleField && inlineStyleField.commit.apply( inlineStyleField, args );\r
+                       // Read attributes and update imagePreview;\r
+                       dialog.commitContent( PREVIEW, dialog.preview );\r
+                       return 0;\r
+               };\r
 \r
-               this.foreach( function( widget )\r
+               // Custom commit dialog logic, where we're intended to give inline style\r
+               // field (txtdlgGenStyle) higher priority to avoid overwriting styles contribute\r
+               // by other fields.\r
+               function commitContent()\r
                {\r
-                       if ( widget.commit &&  widget.id != 'txtdlgGenStyle' )\r
-                               widget.commit.apply( widget, args );\r
-               });\r
-       }\r
-\r
-       // Avoid recursions.\r
-       var incommit;\r
+                       var args = arguments;\r
+                       var inlineStyleField = this.getContentElement( 'advanced', 'txtdlgGenStyle' );\r
+                       inlineStyleField && inlineStyleField.commit.apply( inlineStyleField, args );\r
 \r
-       // Synchronous field values to other impacted fields is required, e.g. border\r
-       // size change should alter inline-style text as well.\r
-       function commitInternally( targetFields )\r
-       {\r
-               if ( incommit )\r
-                       return;\r
+                       this.foreach( function( widget )\r
+                       {\r
+                               if ( widget.commit &&  widget.id != 'txtdlgGenStyle' )\r
+                                       widget.commit.apply( widget, args );\r
+                       });\r
+               }\r
 \r
-               incommit = 1;\r
+               // Avoid recursions.\r
+               var incommit;\r
 \r
-               var dialog = this.getDialog(),\r
-                       element = dialog.imageElement;\r
-               if ( element )\r
+               // Synchronous field values to other impacted fields is required, e.g. border\r
+               // size change should alter inline-style text as well.\r
+               function commitInternally( targetFields )\r
                {\r
-                       // Commit this field and broadcast to target fields.\r
-                       this.commit( IMAGE, element );\r
+                       if ( incommit )\r
+                               return;\r
+\r
+                       incommit = 1;\r
 \r
-                       targetFields = [].concat( targetFields );\r
-                       var length = targetFields.length,\r
-                               field;\r
-                       for ( var i = 0; i < length; i++ )\r
+                       var dialog = this.getDialog(),\r
+                               element = dialog.imageElement;\r
+                       if ( element )\r
                        {\r
-                               field = dialog.getContentElement.apply( dialog, targetFields[ i ].split( ':' ) );\r
-                               // May cause recursion.\r
-                               field && field.setup( IMAGE, element );\r
+                               // Commit this field and broadcast to target fields.\r
+                               this.commit( IMAGE, element );\r
+\r
+                               targetFields = [].concat( targetFields );\r
+                               var length = targetFields.length,\r
+                                       field;\r
+                               for ( var i = 0; i < length; i++ )\r
+                               {\r
+                                       field = dialog.getContentElement.apply( dialog, targetFields[ i ].split( ':' ) );\r
+                                       // May cause recursion.\r
+                                       field && field.setup( IMAGE, element );\r
+                               }\r
                        }\r
+\r
+                       incommit = 0;\r
                }\r
 \r
-               incommit = 0;\r
-       }\r
+               var switchLockRatio = function( dialog, value )\r
+               {\r
+                       var oImageOriginal = dialog.originalElement;\r
 \r
-       var switchLockRatio = function( dialog, value )\r
-       {\r
-               var oImageOriginal = dialog.originalElement,\r
-                       ratioButton = CKEDITOR.document.getById( 'btnLockSizes' );\r
+                       // Dialog may already closed. (#5505)\r
+                       if( !oImageOriginal )\r
+                               return null;\r
 \r
-               if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' )\r
-               {\r
-                       if ( value == 'check' )                 // Check image ratio and original image ratio.\r
+                       var ratioButton = CKEDITOR.document.getById( btnLockSizesId );\r
+\r
+                       if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' )\r
                        {\r
-                               var width = dialog.getValueOf( 'info', 'txtWidth' ),\r
-                                       height = dialog.getValueOf( 'info', 'txtHeight' ),\r
-                                       originalRatio = oImageOriginal.$.width * 1000 / oImageOriginal.$.height,\r
-                                       thisRatio = width * 1000 / height;\r
-                               dialog.lockRatio  = false;              // Default: unlock ratio\r
-\r
-                               if ( !width && !height )\r
-                                       dialog.lockRatio = true;\r
-                               else if ( !isNaN( originalRatio ) && !isNaN( thisRatio ) )\r
+                               if ( value == 'check' )                 // Check image ratio and original image ratio.\r
                                {\r
-                                       if ( Math.round( originalRatio ) == Math.round( thisRatio ) )\r
+                                       var width = dialog.getValueOf( 'info', 'txtWidth' ),\r
+                                               height = dialog.getValueOf( 'info', 'txtHeight' ),\r
+                                               originalRatio = oImageOriginal.$.width * 1000 / oImageOriginal.$.height,\r
+                                               thisRatio = width * 1000 / height;\r
+                                       dialog.lockRatio  = false;              // Default: unlock ratio\r
+\r
+                                       if ( !width && !height )\r
                                                dialog.lockRatio = true;\r
+                                       else if ( !isNaN( originalRatio ) && !isNaN( thisRatio ) )\r
+                                       {\r
+                                               if ( Math.round( originalRatio ) == Math.round( thisRatio ) )\r
+                                                       dialog.lockRatio = true;\r
+                                       }\r
                                }\r
+                               else if ( value != undefined )\r
+                                       dialog.lockRatio = value;\r
+                               else\r
+                                       dialog.lockRatio = !dialog.lockRatio;\r
                        }\r
-                       else if ( value != undefined )\r
-                               dialog.lockRatio = value;\r
-                       else\r
-                               dialog.lockRatio = !dialog.lockRatio;\r
-               }\r
-               else if ( value != 'check' )            // I can't lock ratio if ratio is unknown.\r
-                       dialog.lockRatio = false;\r
+                       else if ( value != 'check' )            // I can't lock ratio if ratio is unknown.\r
+                               dialog.lockRatio = false;\r
 \r
-               if ( dialog.lockRatio )\r
-                       ratioButton.removeClass( 'cke_btn_unlocked' );\r
-               else\r
-                       ratioButton.addClass( 'cke_btn_unlocked' );\r
+                       if ( dialog.lockRatio )\r
+                               ratioButton.removeClass( 'cke_btn_unlocked' );\r
+                       else\r
+                               ratioButton.addClass( 'cke_btn_unlocked' );\r
 \r
-               var lang = dialog._.editor.lang.image,\r
-                       label =  lang[  dialog.lockRatio ? 'unlockRatio' : 'lockRatio' ];\r
+                       var lang = dialog._.editor.lang.image,\r
+                               label =  lang[  dialog.lockRatio ? 'unlockRatio' : 'lockRatio' ];\r
 \r
-               ratioButton.setAttribute( 'title', label );\r
-               ratioButton.getFirst().setText( label );\r
+                       ratioButton.setAttribute( 'title', label );\r
+                       ratioButton.getFirst().setText( label );\r
 \r
-               return dialog.lockRatio;\r
-       };\r
+                       return dialog.lockRatio;\r
+               };\r
 \r
-       var resetSize = function( dialog )\r
-       {\r
-               var oImageOriginal = dialog.originalElement;\r
-               if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' )\r
+               var resetSize = function( dialog )\r
                {\r
-                       dialog.setValueOf( 'info', 'txtWidth', oImageOriginal.$.width );\r
-                       dialog.setValueOf( 'info', 'txtHeight', oImageOriginal.$.height );\r
-               }\r
-               updatePreview( dialog );\r
-       };\r
-\r
-       var setupDimension = function( type, element )\r
-       {\r
-               if ( type != IMAGE )\r
-                       return;\r
+                       var oImageOriginal = dialog.originalElement;\r
+                       if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' )\r
+                       {\r
+                               dialog.setValueOf( 'info', 'txtWidth', oImageOriginal.$.width );\r
+                               dialog.setValueOf( 'info', 'txtHeight', oImageOriginal.$.height );\r
+                       }\r
+                       updatePreview( dialog );\r
+               };\r
 \r
-               function checkDimension( size, defaultValue )\r
+               var setupDimension = function( type, element )\r
                {\r
-                       var aMatch  =  size.match( regexGetSize );\r
-                       if ( aMatch )\r
+                       if ( type != IMAGE )\r
+                               return;\r
+\r
+                       function checkDimension( size, defaultValue )\r
                        {\r
-                               if ( aMatch[2] == '%' )                         // % is allowed.\r
+                               var aMatch  =  size.match( regexGetSize );\r
+                               if ( aMatch )\r
                                {\r
-                                       aMatch[1] += '%';\r
-                                       switchLockRatio( dialog, false );       // Unlock ratio\r
+                                       if ( aMatch[2] == '%' )                         // % is allowed.\r
+                                       {\r
+                                               aMatch[1] += '%';\r
+                                               switchLockRatio( dialog, false );       // Unlock ratio\r
+                                       }\r
+                                       return aMatch[1];\r
                                }\r
-                               return aMatch[1];\r
+                               return defaultValue;\r
                        }\r
-                       return defaultValue;\r
-               }\r
 \r
-               var dialog = this.getDialog(),\r
-                       value = '',\r
-                       dimension = (( this.id == 'txtWidth' )? 'width' : 'height' ),\r
-                       size = element.getAttribute( dimension );\r
+                       var dialog = this.getDialog(),\r
+                               value = '',\r
+                               dimension = (( this.id == 'txtWidth' )? 'width' : 'height' ),\r
+                               size = element.getAttribute( dimension );\r
 \r
-               if ( size )\r
-                       value = checkDimension( size, value );\r
-               value = checkDimension( element.getStyle( dimension ), value );\r
+                       if ( size )\r
+                               value = checkDimension( size, value );\r
+                       value = checkDimension( element.getStyle( dimension ), value );\r
 \r
-               this.setValue( value );\r
-       };\r
+                       this.setValue( value );\r
+               };\r
 \r
-       var imageDialog = function( editor, dialogType )\r
-       {\r
                var previewPreloader;\r
 \r
                var onImgLoadEvent = function()\r
@@ -213,7 +218,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
                        original.removeListener( 'abort', onImgLoadErrorEvent );\r
 \r
                        // Hide loader\r
-                       CKEDITOR.document.getById( 'ImagePreviewLoader' ).setStyle( 'display', 'none' );\r
+                       CKEDITOR.document.getById( imagePreviewLoaderId ).setStyle( 'display', 'none' );\r
 \r
                        // New image -> new domensions\r
                        if ( !this.dontResetSize )\r
@@ -241,9 +246,18 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
                                this.preview.setAttribute( 'src', noimage );\r
 \r
                        // Hide loader\r
-                       CKEDITOR.document.getById( 'ImagePreviewLoader' ).setStyle( 'display', 'none' );\r
+                       CKEDITOR.document.getById( imagePreviewLoaderId ).setStyle( 'display', 'none' );\r
                        switchLockRatio( this, false ); // Unlock.\r
                };\r
+\r
+               var numbering = function( id ){ return id + CKEDITOR.tools.getNextNumber(); },\r
+                       btnLockSizesId = numbering( 'btnLockSizes' ),\r
+                       btnResetSizeId = numbering( 'btnResetSize' ),\r
+                       imagePreviewLoaderId = numbering( 'ImagePreviewLoader' ),\r
+                       imagePreviewBoxId = numbering( 'ImagePreviewBox' ),\r
+                       previewLinkId = numbering( 'previewLink' ),\r
+                       previewImageId = numbering( 'previewImage' );\r
+\r
                return {\r
                        title : ( dialogType == 'image' ) ? editor.lang.image.title : editor.lang.image.titleButton,\r
                        minWidth : 420,\r
@@ -268,10 +282,10 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
                                        link = element && element.getAscendant( 'a' );\r
 \r
                                //Hide loader.\r
-                               CKEDITOR.document.getById( 'ImagePreviewLoader' ).setStyle( 'display', 'none' );\r
+                               CKEDITOR.document.getById( imagePreviewLoaderId ).setStyle( 'display', 'none' );\r
                                // Create the preview before setup the dialog contents.\r
                                previewPreloader = new CKEDITOR.dom.element( 'img', editor.document );\r
-                               this.preview = CKEDITOR.document.getById( 'previewImage' );\r
+                               this.preview = CKEDITOR.document.getById( previewImageId );\r
 \r
                                // Copy of the image\r
                                this.originalElement = editor.document.createElement( 'img' );\r
@@ -432,8 +446,8 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
                                if ( dialogType != 'image' )\r
                                        this.hidePage( 'Link' );                //Hide Link tab.\r
                                var doc = this._.element.getDocument();\r
-                               this.addFocusable( doc.getById( 'btnResetSize' ), 5 );\r
-                               this.addFocusable( doc.getById( 'btnLockSizes' ), 5 );\r
+                               this.addFocusable( doc.getById( btnResetSizeId ), 5 );\r
+                               this.addFocusable( doc.getById( btnLockSizesId ), 5 );\r
 \r
                                this.commitContent = commitContent;\r
                        },\r
@@ -491,7 +505,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
 \r
                                                                                                        original.setCustomData( 'isReady', 'false' );\r
                                                                                                        // Show loader\r
-                                                                                                       var loader = CKEDITOR.document.getById( 'ImagePreviewLoader' );\r
+                                                                                                       var loader = CKEDITOR.document.getById( imagePreviewLoaderId );\r
                                                                                                        if ( loader )\r
                                                                                                                loader.setStyle( 'display', '' );\r
 \r
@@ -718,8 +732,8 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
                                                                                                        onLoad : function()\r
                                                                                                        {\r
                                                                                                                // Activate Reset button\r
-                                                                                                               var     resetButton = CKEDITOR.document.getById( 'btnResetSize' ),\r
-                                                                                                                       ratioButton = CKEDITOR.document.getById( 'btnLockSizes' );\r
+                                                                                                               var     resetButton = CKEDITOR.document.getById( btnResetSizeId ),\r
+                                                                                                                       ratioButton = CKEDITOR.document.getById( btnLockSizesId );\r
                                                                                                                if ( resetButton )\r
                                                                                                                {\r
                                                                                                                        resetButton.on( 'click', function(evt)\r
@@ -768,9 +782,9 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
                                                                                                        },\r
                                                                                                        html : '<div>'+\r
                                                                                                                '<a href="javascript:void(0)" tabindex="-1" title="' + editor.lang.image.unlockRatio +\r
-                                                                                                               '" class="cke_btn_locked" id="btnLockSizes" role="button"><span class="cke_label">' + editor.lang.image.unlockRatio + '</span></a>' +\r
+                                                                                                               '" class="cke_btn_locked" id="' + btnLockSizesId + '" role="button"><span class="cke_label">' + editor.lang.image.unlockRatio + '</span></a>' +\r
                                                                                                                '<a href="javascript:void(0)" tabindex="-1" title="' + editor.lang.image.resetSize +\r
-                                                                                                               '" class="cke_btn_reset" id="btnResetSize" role="button"><span class="cke_label">' + editor.lang.image.resetSize + '</span></a>'+\r
+                                                                                                               '" class="cke_btn_reset" id="' + btnResetSizeId + '" role="button"><span class="cke_label">' + editor.lang.image.resetSize + '</span></a>'+\r
                                                                                                                '</div>'\r
                                                                                                }\r
                                                                                        ]\r
@@ -1050,10 +1064,10 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
                                                                                        type : 'html',\r
                                                                                        style : 'width:95%;',\r
                                                                                        html : '<div>' + CKEDITOR.tools.htmlEncode( editor.lang.common.preview ) +'<br>'+\r
-                                                                                       '<div id="ImagePreviewLoader" style="display:none"><div class="loading">&nbsp;</div></div>'+\r
-                                                                                       '<div id="ImagePreviewBox"><table><tr><td>'+\r
-                                                                                       '<a href="javascript:void(0)" target="_blank" onclick="return false;" id="previewLink">'+\r
-                                                                                       '<img id="previewImage" alt="" /></a>' +\r
+                                                                                       '<div id="' + imagePreviewLoaderId + '" class="ImagePreviewLoader" style="display:none"><div class="loading">&nbsp;</div></div>'+\r
+                                                                                       '<div id="' + imagePreviewBoxId + '" class="ImagePreviewBox"><table><tr><td>'+\r
+                                                                                       '<a href="javascript:void(0)" target="_blank" onclick="return false;" id="' + previewLinkId + '">'+\r
+                                                                                       '<img id="' + previewImageId + '" alt="" /></a>' +\r
                                                                                        ( editor.config.image_previewText ||\r
                                                                                        'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. '+\r
                                                                                        'Maecenas feugiat consequat diam. Maecenas metus. Vivamus diam purus, cursus a, commodo non, facilisis vitae, '+\r