2 Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.
\r
3 For licensing, see LICENSE.html or http://ckeditor.com/license
\r
8 var imageDialog = function( editor, dialogType )
\r
10 // Load image preview.
\r
15 regexGetSize = /^\s*(\d+)((px)|\%)?\s*$/i,
\r
16 regexGetSizeOrEmpty = /(^\s*(\d+)((px)|\%)?\s*$)|^$/i,
\r
17 pxLengthRegex = /^\d+px$/;
\r
19 var onSizeChange = function()
\r
21 var value = this.getValue(), // This = input element.
\r
22 dialog = this.getDialog(),
\r
23 aMatch = value.match( regexGetSize ); // Check value
\r
26 if ( aMatch[2] == '%' ) // % is allowed - > unlock ratio.
\r
27 switchLockRatio( dialog, false ); // Unlock.
\r
31 // Only if ratio is locked
\r
32 if ( dialog.lockRatio )
\r
34 var oImageOriginal = dialog.originalElement;
\r
35 if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' )
\r
37 if ( this.id == 'txtHeight' )
\r
39 if ( value && value != '0' )
\r
40 value = Math.round( oImageOriginal.$.width * ( value / oImageOriginal.$.height ) );
\r
41 if ( !isNaN( value ) )
\r
42 dialog.setValueOf( 'info', 'txtWidth', value );
\r
44 else //this.id = txtWidth.
\r
46 if ( value && value != '0' )
\r
47 value = Math.round( oImageOriginal.$.height * ( value / oImageOriginal.$.width ) );
\r
48 if ( !isNaN( value ) )
\r
49 dialog.setValueOf( 'info', 'txtHeight', value );
\r
53 updatePreview( dialog );
\r
56 var updatePreview = function( dialog )
\r
58 //Don't load before onShow.
\r
59 if ( !dialog.originalElement || !dialog.preview )
\r
62 // Read attributes and update imagePreview;
\r
63 dialog.commitContent( PREVIEW, dialog.preview );
\r
67 // Custom commit dialog logic, where we're intended to give inline style
\r
68 // field (txtdlgGenStyle) higher priority to avoid overwriting styles contribute
\r
70 function commitContent()
\r
72 var args = arguments;
\r
73 var inlineStyleField = this.getContentElement( 'advanced', 'txtdlgGenStyle' );
\r
74 inlineStyleField && inlineStyleField.commit.apply( inlineStyleField, args );
\r
76 this.foreach( function( widget )
\r
78 if ( widget.commit && widget.id != 'txtdlgGenStyle' )
\r
79 widget.commit.apply( widget, args );
\r
83 // Avoid recursions.
\r
86 // Synchronous field values to other impacted fields is required, e.g. border
\r
87 // size change should alter inline-style text as well.
\r
88 function commitInternally( targetFields )
\r
95 var dialog = this.getDialog(),
\r
96 element = dialog.imageElement;
\r
99 // Commit this field and broadcast to target fields.
\r
100 this.commit( IMAGE, element );
\r
102 targetFields = [].concat( targetFields );
\r
103 var length = targetFields.length,
\r
105 for ( var i = 0; i < length; i++ )
\r
107 field = dialog.getContentElement.apply( dialog, targetFields[ i ].split( ':' ) );
\r
108 // May cause recursion.
\r
109 field && field.setup( IMAGE, element );
\r
116 var switchLockRatio = function( dialog, value )
\r
118 if ( !dialog.getContentElement( 'info', 'ratioLock' ) )
\r
121 var oImageOriginal = dialog.originalElement;
\r
123 // Dialog may already closed. (#5505)
\r
124 if( !oImageOriginal )
\r
127 // Check image ratio and original image ratio, but respecting user's preference.
\r
128 if ( value == 'check' )
\r
130 if ( !dialog.userlockRatio && oImageOriginal.getCustomData( 'isReady' ) == 'true' )
\r
132 var width = dialog.getValueOf( 'info', 'txtWidth' ),
\r
133 height = dialog.getValueOf( 'info', 'txtHeight' ),
\r
134 originalRatio = oImageOriginal.$.width * 1000 / oImageOriginal.$.height,
\r
135 thisRatio = width * 1000 / height;
\r
136 dialog.lockRatio = false; // Default: unlock ratio
\r
138 if ( !width && !height )
\r
139 dialog.lockRatio = true;
\r
140 else if ( !isNaN( originalRatio ) && !isNaN( thisRatio ) )
\r
142 if ( Math.round( originalRatio ) == Math.round( thisRatio ) )
\r
143 dialog.lockRatio = true;
\r
147 else if ( value != undefined )
\r
148 dialog.lockRatio = value;
\r
151 dialog.userlockRatio = 1;
\r
152 dialog.lockRatio = !dialog.lockRatio;
\r
155 var ratioButton = CKEDITOR.document.getById( btnLockSizesId );
\r
156 if ( dialog.lockRatio )
\r
157 ratioButton.removeClass( 'cke_btn_unlocked' );
\r
159 ratioButton.addClass( 'cke_btn_unlocked' );
\r
161 var lang = dialog._.editor.lang.image,
\r
162 label = lang[ dialog.lockRatio ? 'unlockRatio' : 'lockRatio' ];
\r
164 ratioButton.setAttribute( 'title', label );
\r
165 ratioButton.getFirst().setText( label );
\r
167 return dialog.lockRatio;
\r
170 var resetSize = function( dialog )
\r
172 var oImageOriginal = dialog.originalElement;
\r
173 if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' )
\r
175 var widthField = dialog.getContentElement( 'info', 'txtWidth' ),
\r
176 heightField = dialog.getContentElement( 'info', 'txtHeight' );
\r
177 widthField && widthField.setValue( oImageOriginal.$.width );
\r
178 heightField && heightField.setValue( oImageOriginal.$.height );
\r
180 updatePreview( dialog );
\r
183 var setupDimension = function( type, element )
\r
185 if ( type != IMAGE )
\r
188 function checkDimension( size, defaultValue )
\r
190 var aMatch = size.match( regexGetSize );
\r
193 if ( aMatch[2] == '%' ) // % is allowed.
\r
196 switchLockRatio( dialog, false ); // Unlock ratio
\r
200 return defaultValue;
\r
203 var dialog = this.getDialog(),
\r
205 dimension = this.id == 'txtWidth' ? 'width' : 'height',
\r
206 size = element.getAttribute( dimension );
\r
209 value = checkDimension( size, value );
\r
210 value = checkDimension( element.getStyle( dimension ), value );
\r
212 this.setValue( value );
\r
215 var previewPreloader;
\r
217 var onImgLoadEvent = function()
\r
220 var original = this.originalElement;
\r
221 original.setCustomData( 'isReady', 'true' );
\r
222 original.removeListener( 'load', onImgLoadEvent );
\r
223 original.removeListener( 'error', onImgLoadErrorEvent );
\r
224 original.removeListener( 'abort', onImgLoadErrorEvent );
\r
227 CKEDITOR.document.getById( imagePreviewLoaderId ).setStyle( 'display', 'none' );
\r
229 // New image -> new domensions
\r
230 if ( !this.dontResetSize )
\r
233 if ( this.firstLoad )
\r
234 CKEDITOR.tools.setTimeout( function(){ switchLockRatio( this, 'check' ); }, 0, this );
\r
236 this.firstLoad = false;
\r
237 this.dontResetSize = false;
\r
240 var onImgLoadErrorEvent = function()
\r
242 // Error. Image is not loaded.
\r
243 var original = this.originalElement;
\r
244 original.removeListener( 'load', onImgLoadEvent );
\r
245 original.removeListener( 'error', onImgLoadErrorEvent );
\r
246 original.removeListener( 'abort', onImgLoadErrorEvent );
\r
248 // Set Error image.
\r
249 var noimage = CKEDITOR.getUrl( editor.skinPath + 'images/noimage.png' );
\r
251 if ( this.preview )
\r
252 this.preview.setAttribute( 'src', noimage );
\r
255 CKEDITOR.document.getById( imagePreviewLoaderId ).setStyle( 'display', 'none' );
\r
256 switchLockRatio( this, false ); // Unlock.
\r
259 var numbering = function( id )
\r
261 return CKEDITOR.tools.getNextId() + '_' + id;
\r
263 btnLockSizesId = numbering( 'btnLockSizes' ),
\r
264 btnResetSizeId = numbering( 'btnResetSize' ),
\r
265 imagePreviewLoaderId = numbering( 'ImagePreviewLoader' ),
\r
266 imagePreviewBoxId = numbering( 'ImagePreviewBox' ),
\r
267 previewLinkId = numbering( 'previewLink' ),
\r
268 previewImageId = numbering( 'previewImage' );
\r
271 title : editor.lang.image[ dialogType == 'image' ? 'title' : 'titleButton' ],
\r
274 onShow : function()
\r
276 this.imageElement = false;
\r
277 this.linkElement = false;
\r
279 // Default: create a new element.
\r
280 this.imageEditMode = false;
\r
281 this.linkEditMode = false;
\r
283 this.lockRatio = true;
\r
284 this.userlockRatio = 0;
\r
285 this.dontResetSize = false;
\r
286 this.firstLoad = true;
\r
287 this.addLink = false;
\r
289 var editor = this.getParentEditor(),
\r
290 sel = this.getParentEditor().getSelection(),
\r
291 element = sel.getSelectedElement(),
\r
292 link = element && element.getAscendant( 'a' );
\r
295 CKEDITOR.document.getById( imagePreviewLoaderId ).setStyle( 'display', 'none' );
\r
296 // Create the preview before setup the dialog contents.
\r
297 previewPreloader = new CKEDITOR.dom.element( 'img', editor.document );
\r
298 this.preview = CKEDITOR.document.getById( previewImageId );
\r
300 // Copy of the image
\r
301 this.originalElement = editor.document.createElement( 'img' );
\r
302 this.originalElement.setAttribute( 'alt', '' );
\r
303 this.originalElement.setCustomData( 'isReady', 'false' );
\r
307 this.linkElement = link;
\r
308 this.linkEditMode = true;
\r
310 // Look for Image element.
\r
311 var linkChildren = link.getChildren();
\r
312 if ( linkChildren.count() == 1 ) // 1 child.
\r
314 var childTagName = linkChildren.getItem( 0 ).getName();
\r
315 if ( childTagName == 'img' || childTagName == 'input' )
\r
317 this.imageElement = linkChildren.getItem( 0 );
\r
318 if ( this.imageElement.getName() == 'img' )
\r
319 this.imageEditMode = 'img';
\r
320 else if ( this.imageElement.getName() == 'input' )
\r
321 this.imageEditMode = 'input';
\r
324 // Fill out all fields.
\r
325 if ( dialogType == 'image' )
\r
326 this.setupContent( LINK, link );
\r
329 if ( element && element.getName() == 'img' && !element.data( 'cke-realelement' )
\r
330 || element && element.getName() == 'input' && element.getAttribute( 'type' ) == 'image' )
\r
332 this.imageEditMode = element.getName();
\r
333 this.imageElement = element;
\r
336 if ( this.imageEditMode )
\r
338 // Use the original element as a buffer from since we don't want
\r
339 // temporary changes to be committed, e.g. if the dialog is canceled.
\r
340 this.cleanImageElement = this.imageElement;
\r
341 this.imageElement = this.cleanImageElement.clone( true, true );
\r
343 // Fill out all fields.
\r
344 this.setupContent( IMAGE, this.imageElement );
\r
347 this.imageElement = editor.document.createElement( 'img' );
\r
349 // Refresh LockRatio button
\r
350 switchLockRatio ( this, true );
\r
352 // Dont show preview if no URL given.
\r
353 if ( !CKEDITOR.tools.trim( this.getValueOf( 'info', 'txtUrl' ) ) )
\r
355 this.preview.removeAttribute( 'src' );
\r
356 this.preview.setStyle( 'display', 'none' );
\r
361 // Edit existing Image.
\r
362 if ( this.imageEditMode )
\r
364 var imgTagName = this.imageEditMode;
\r
366 // Image dialog and Input element.
\r
367 if ( dialogType == 'image' && imgTagName == 'input' && confirm( editor.lang.image.button2Img ) )
\r
369 // Replace INPUT-> IMG
\r
370 imgTagName = 'img';
\r
371 this.imageElement = editor.document.createElement( 'img' );
\r
372 this.imageElement.setAttribute( 'alt', '' );
\r
373 editor.insertElement( this.imageElement );
\r
375 // ImageButton dialog and Image element.
\r
376 else if ( dialogType != 'image' && imgTagName == 'img' && confirm( editor.lang.image.img2Button ))
\r
378 // Replace IMG -> INPUT
\r
379 imgTagName = 'input';
\r
380 this.imageElement = editor.document.createElement( 'input' );
\r
381 this.imageElement.setAttributes(
\r
387 editor.insertElement( this.imageElement );
\r
391 // Restore the original element before all commits.
\r
392 this.imageElement = this.cleanImageElement;
\r
393 delete this.cleanImageElement;
\r
396 else // Create a new image.
\r
398 // Image dialog -> create IMG element.
\r
399 if ( dialogType == 'image' )
\r
400 this.imageElement = editor.document.createElement( 'img' );
\r
403 this.imageElement = editor.document.createElement( 'input' );
\r
404 this.imageElement.setAttribute ( 'type' ,'image' );
\r
406 this.imageElement.setAttribute( 'alt', '' );
\r
409 // Create a new link.
\r
410 if ( !this.linkEditMode )
\r
411 this.linkElement = editor.document.createElement( 'a' );
\r
414 this.commitContent( IMAGE, this.imageElement );
\r
415 this.commitContent( LINK, this.linkElement );
\r
417 // Remove empty style attribute.
\r
418 if ( !this.imageElement.getAttribute( 'style' ) )
\r
419 this.imageElement.removeAttribute( 'style' );
\r
421 // Insert a new Image.
\r
422 if ( !this.imageEditMode )
\r
424 if ( this.addLink )
\r
426 //Insert a new Link.
\r
427 if ( !this.linkEditMode )
\r
429 editor.insertElement( this.linkElement );
\r
430 this.linkElement.append( this.imageElement, false );
\r
432 else //Link already exists, image not.
\r
433 editor.insertElement( this.imageElement );
\r
436 editor.insertElement( this.imageElement );
\r
438 else // Image already exists.
\r
440 //Add a new link element.
\r
441 if ( !this.linkEditMode && this.addLink )
\r
443 editor.insertElement( this.linkElement );
\r
444 this.imageElement.appendTo( this.linkElement );
\r
446 //Remove Link, Image exists.
\r
447 else if ( this.linkEditMode && !this.addLink )
\r
449 editor.getSelection().selectElement( this.linkElement );
\r
450 editor.insertElement( this.imageElement );
\r
454 onLoad : function()
\r
456 if ( dialogType != 'image' )
\r
457 this.hidePage( 'Link' ); //Hide Link tab.
\r
458 var doc = this._.element.getDocument();
\r
460 if ( this.getContentElement( 'info', 'ratioLock' ) )
\r
462 this.addFocusable( doc.getById( btnResetSizeId ), 5 );
\r
463 this.addFocusable( doc.getById( btnLockSizesId ), 5 );
\r
466 this.commitContent = commitContent;
\r
468 onHide : function()
\r
470 if ( this.preview )
\r
471 this.commitContent( CLEANUP, this.preview );
\r
473 if ( this.originalElement )
\r
475 this.originalElement.removeListener( 'load', onImgLoadEvent );
\r
476 this.originalElement.removeListener( 'error', onImgLoadErrorEvent );
\r
477 this.originalElement.removeListener( 'abort', onImgLoadErrorEvent );
\r
478 this.originalElement.remove();
\r
479 this.originalElement = false; // Dialog is closed.
\r
482 delete this.imageElement;
\r
487 label : editor.lang.image.infoTab,
\r
498 widths : [ '280px', '110px' ],
\r
505 label : editor.lang.common.url,
\r
507 onChange : function()
\r
509 var dialog = this.getDialog(),
\r
510 newUrl = this.getValue();
\r
512 //Update original image
\r
513 if ( newUrl.length > 0 ) //Prevent from load before onShow
\r
515 dialog = this.getDialog();
\r
516 var original = dialog.originalElement;
\r
518 dialog.preview.removeStyle( 'display' );
\r
520 original.setCustomData( 'isReady', 'false' );
\r
522 var loader = CKEDITOR.document.getById( imagePreviewLoaderId );
\r
524 loader.setStyle( 'display', '' );
\r
526 original.on( 'load', onImgLoadEvent, dialog );
\r
527 original.on( 'error', onImgLoadErrorEvent, dialog );
\r
528 original.on( 'abort', onImgLoadErrorEvent, dialog );
\r
529 original.setAttribute( 'src', newUrl );
\r
531 // Query the preloader to figure out the url impacted by based href.
\r
532 previewPreloader.setAttribute( 'src', newUrl );
\r
533 dialog.preview.setAttribute( 'src', previewPreloader.$.src );
\r
534 updatePreview( dialog );
\r
536 // Dont show preview if no URL given.
\r
537 else if ( dialog.preview )
\r
539 dialog.preview.removeAttribute( 'src' );
\r
540 dialog.preview.setStyle( 'display', 'none' );
\r
543 setup : function( type, element )
\r
545 if ( type == IMAGE )
\r
547 var url = element.data( 'cke-saved-src' ) || element.getAttribute( 'src' );
\r
550 this.getDialog().dontResetSize = true;
\r
552 field.setValue( url ); // And call this.onChange()
\r
553 // Manually set the initial value.(#4191)
\r
554 field.setInitValue();
\r
557 commit : function( type, element )
\r
559 if ( type == IMAGE && ( this.getValue() || this.isChanged() ) )
\r
561 element.data( 'cke-saved-src', this.getValue() );
\r
562 element.setAttribute( 'src', this.getValue() );
\r
564 else if ( type == CLEANUP )
\r
566 element.setAttribute( 'src', '' ); // If removeAttribute doesn't work.
\r
567 element.removeAttribute( 'src' );
\r
570 validate : CKEDITOR.dialog.validate.notEmpty( editor.lang.image.urlMissing )
\r
575 // v-align with the 'txtUrl' field.
\r
576 // TODO: We need something better than a fixed size here.
\r
577 style : 'display:inline-block;margin-top:10px;',
\r
579 label : editor.lang.common.browseServer,
\r
581 filebrowser : 'info:txtUrl'
\r
590 label : editor.lang.image.alt,
\r
593 onChange : function()
\r
595 updatePreview( this.getDialog() );
\r
597 setup : function( type, element )
\r
599 if ( type == IMAGE )
\r
600 this.setValue( element.getAttribute( 'alt' ) );
\r
602 commit : function( type, element )
\r
604 if ( type == IMAGE )
\r
606 if ( this.getValue() || this.isChanged() )
\r
607 element.setAttribute( 'alt', this.getValue() );
\r
609 else if ( type == PREVIEW )
\r
611 element.setAttribute( 'alt', this.getValue() );
\r
613 else if ( type == CLEANUP )
\r
615 element.removeAttribute( 'alt' );
\r
630 widths : [ '50%', '50%' ],
\r
642 label : editor.lang.common.width,
\r
643 onKeyUp : onSizeChange,
\r
644 onChange : function()
\r
646 commitInternally.call( this, 'advanced:txtdlgGenStyle' );
\r
648 validate : function()
\r
650 var aMatch = this.getValue().match( regexGetSizeOrEmpty ),
\r
651 isValid = !!( aMatch && parseInt( aMatch[1], 10 ) !== 0 );
\r
653 alert( editor.lang.common.invalidWidth );
\r
656 setup : setupDimension,
\r
657 commit : function( type, element, internalCommit )
\r
659 var value = this.getValue();
\r
660 if ( type == IMAGE )
\r
663 element.setStyle( 'width', CKEDITOR.tools.cssLength( value ) );
\r
665 element.removeStyle( 'width' );
\r
667 !internalCommit && element.removeAttribute( 'width' );
\r
669 else if ( type == PREVIEW )
\r
671 var aMatch = value.match( regexGetSize );
\r
674 var oImageOriginal = this.getDialog().originalElement;
\r
675 if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' )
\r
676 element.setStyle( 'width', oImageOriginal.$.width + 'px');
\r
679 element.setStyle( 'width', CKEDITOR.tools.cssLength( value ) );
\r
681 else if ( type == CLEANUP )
\r
683 element.removeAttribute( 'width' );
\r
684 element.removeStyle( 'width' );
\r
692 label : editor.lang.common.height,
\r
693 onKeyUp : onSizeChange,
\r
694 onChange : function()
\r
696 commitInternally.call( this, 'advanced:txtdlgGenStyle' );
\r
698 validate : function()
\r
700 var aMatch = this.getValue().match( regexGetSizeOrEmpty ),
\r
701 isValid = !!( aMatch && parseInt( aMatch[1], 10 ) !== 0 );
\r
703 alert( editor.lang.common.invalidHeight );
\r
706 setup : setupDimension,
\r
707 commit : function( type, element, internalCommit )
\r
709 var value = this.getValue();
\r
710 if ( type == IMAGE )
\r
713 element.setStyle( 'height', CKEDITOR.tools.cssLength( value ) );
\r
715 element.removeStyle( 'height' );
\r
717 !internalCommit && element.removeAttribute( 'height' );
\r
719 else if ( type == PREVIEW )
\r
721 var aMatch = value.match( regexGetSize );
\r
724 var oImageOriginal = this.getDialog().originalElement;
\r
725 if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' )
\r
726 element.setStyle( 'height', oImageOriginal.$.height + 'px' );
\r
729 element.setStyle( 'height', CKEDITOR.tools.cssLength( value ) );
\r
731 else if ( type == CLEANUP )
\r
733 element.removeAttribute( 'height' );
\r
734 element.removeStyle( 'height' );
\r
743 style : 'margin-top:30px;width:40px;height:40px;',
\r
744 onLoad : function()
\r
746 // Activate Reset button
\r
747 var resetButton = CKEDITOR.document.getById( btnResetSizeId ),
\r
748 ratioButton = CKEDITOR.document.getById( btnLockSizesId );
\r
751 resetButton.on( 'click', function( evt )
\r
754 evt.data && evt.data.preventDefault();
\r
755 }, this.getDialog() );
\r
756 resetButton.on( 'mouseover', function()
\r
758 this.addClass( 'cke_btn_over' );
\r
760 resetButton.on( 'mouseout', function()
\r
762 this.removeClass( 'cke_btn_over' );
\r
765 // Activate (Un)LockRatio button
\r
768 ratioButton.on( 'click', function(evt)
\r
770 var locked = switchLockRatio( this ),
\r
771 oImageOriginal = this.originalElement,
\r
772 width = this.getValueOf( 'info', 'txtWidth' );
\r
774 if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' && width )
\r
776 var height = oImageOriginal.$.height / oImageOriginal.$.width * width;
\r
777 if ( !isNaN( height ) )
\r
779 this.setValueOf( 'info', 'txtHeight', Math.round( height ) );
\r
780 updatePreview( this );
\r
783 evt.data.preventDefault();
\r
784 }, this.getDialog() );
\r
785 ratioButton.on( 'mouseover', function()
\r
787 this.addClass( 'cke_btn_over' );
\r
789 ratioButton.on( 'mouseout', function()
\r
791 this.removeClass( 'cke_btn_over' );
\r
796 '<a href="javascript:void(0)" tabindex="-1" title="' + editor.lang.image.unlockRatio +
\r
797 '" class="cke_btn_locked" id="' + btnLockSizesId + '" role="button"><span class="cke_label">' + editor.lang.image.unlockRatio + '</span></a>' +
\r
798 '<a href="javascript:void(0)" tabindex="-1" title="' + editor.lang.image.resetSize +
\r
799 '" class="cke_btn_reset" id="' + btnResetSizeId + '" role="button"><span class="cke_label">' + editor.lang.image.resetSize + '</span></a>'+
\r
813 label : editor.lang.image.border,
\r
815 onKeyUp : function()
\r
817 updatePreview( this.getDialog() );
\r
819 onChange : function()
\r
821 commitInternally.call( this, 'advanced:txtdlgGenStyle' );
\r
823 validate : CKEDITOR.dialog.validate.integer( editor.lang.image.validateBorder ),
\r
824 setup : function( type, element )
\r
826 if ( type == IMAGE )
\r
829 borderStyle = element.getStyle( 'border-width' );
\r
830 borderStyle = borderStyle && borderStyle.match( /^(\d+px)(?: \1 \1 \1)?$/ );
\r
831 value = borderStyle && parseInt( borderStyle[ 1 ], 10 );
\r
832 isNaN ( parseInt( value, 10 ) ) && ( value = element.getAttribute( 'border' ) );
\r
833 this.setValue( value );
\r
836 commit : function( type, element, internalCommit )
\r
838 var value = parseInt( this.getValue(), 10 );
\r
839 if ( type == IMAGE || type == PREVIEW )
\r
841 if ( !isNaN( value ) )
\r
843 element.setStyle( 'border-width', CKEDITOR.tools.cssLength( value ) );
\r
844 element.setStyle( 'border-style', 'solid' );
\r
846 else if ( !value && this.isChanged() )
\r
848 element.removeStyle( 'border-width' );
\r
849 element.removeStyle( 'border-style' );
\r
850 element.removeStyle( 'border-color' );
\r
853 if ( !internalCommit && type == IMAGE )
\r
854 element.removeAttribute( 'border' );
\r
856 else if ( type == CLEANUP )
\r
858 element.removeAttribute( 'border' );
\r
859 element.removeStyle( 'border-width' );
\r
860 element.removeStyle( 'border-style' );
\r
861 element.removeStyle( 'border-color' );
\r
869 label : editor.lang.image.hSpace,
\r
871 onKeyUp : function()
\r
873 updatePreview( this.getDialog() );
\r
875 onChange : function()
\r
877 commitInternally.call( this, 'advanced:txtdlgGenStyle' );
\r
879 validate : CKEDITOR.dialog.validate.integer( editor.lang.image.validateHSpace ),
\r
880 setup : function( type, element )
\r
882 if ( type == IMAGE )
\r
887 marginLeftStyle = element.getStyle( 'margin-left' ),
\r
888 marginRightStyle = element.getStyle( 'margin-right' );
\r
890 marginLeftStyle = marginLeftStyle && marginLeftStyle.match( pxLengthRegex );
\r
891 marginRightStyle = marginRightStyle && marginRightStyle.match( pxLengthRegex );
\r
892 marginLeftPx = parseInt( marginLeftStyle, 10 );
\r
893 marginRightPx = parseInt( marginRightStyle, 10 );
\r
895 value = ( marginLeftPx == marginRightPx ) && marginLeftPx;
\r
896 isNaN( parseInt( value, 10 ) ) && ( value = element.getAttribute( 'hspace' ) );
\r
898 this.setValue( value );
\r
901 commit : function( type, element, internalCommit )
\r
903 var value = parseInt( this.getValue(), 10 );
\r
904 if ( type == IMAGE || type == PREVIEW )
\r
906 if ( !isNaN( value ) )
\r
908 element.setStyle( 'margin-left', CKEDITOR.tools.cssLength( value ) );
\r
909 element.setStyle( 'margin-right', CKEDITOR.tools.cssLength( value ) );
\r
911 else if ( !value && this.isChanged( ) )
\r
913 element.removeStyle( 'margin-left' );
\r
914 element.removeStyle( 'margin-right' );
\r
917 if ( !internalCommit && type == IMAGE )
\r
918 element.removeAttribute( 'hspace' );
\r
920 else if ( type == CLEANUP )
\r
922 element.removeAttribute( 'hspace' );
\r
923 element.removeStyle( 'margin-left' );
\r
924 element.removeStyle( 'margin-right' );
\r
932 label : editor.lang.image.vSpace,
\r
934 onKeyUp : function()
\r
936 updatePreview( this.getDialog() );
\r
938 onChange : function()
\r
940 commitInternally.call( this, 'advanced:txtdlgGenStyle' );
\r
942 validate : CKEDITOR.dialog.validate.integer( editor.lang.image.validateVSpace ),
\r
943 setup : function( type, element )
\r
945 if ( type == IMAGE )
\r
950 marginTopStyle = element.getStyle( 'margin-top' ),
\r
951 marginBottomStyle = element.getStyle( 'margin-bottom' );
\r
953 marginTopStyle = marginTopStyle && marginTopStyle.match( pxLengthRegex );
\r
954 marginBottomStyle = marginBottomStyle && marginBottomStyle.match( pxLengthRegex );
\r
955 marginTopPx = parseInt( marginTopStyle, 10 );
\r
956 marginBottomPx = parseInt( marginBottomStyle, 10 );
\r
958 value = ( marginTopPx == marginBottomPx ) && marginTopPx;
\r
959 isNaN ( parseInt( value, 10 ) ) && ( value = element.getAttribute( 'vspace' ) );
\r
960 this.setValue( value );
\r
963 commit : function( type, element, internalCommit )
\r
965 var value = parseInt( this.getValue(), 10 );
\r
966 if ( type == IMAGE || type == PREVIEW )
\r
968 if ( !isNaN( value ) )
\r
970 element.setStyle( 'margin-top', CKEDITOR.tools.cssLength( value ) );
\r
971 element.setStyle( 'margin-bottom', CKEDITOR.tools.cssLength( value ) );
\r
973 else if ( !value && this.isChanged( ) )
\r
975 element.removeStyle( 'margin-top' );
\r
976 element.removeStyle( 'margin-bottom' );
\r
979 if ( !internalCommit && type == IMAGE )
\r
980 element.removeAttribute( 'vspace' );
\r
982 else if ( type == CLEANUP )
\r
984 element.removeAttribute( 'vspace' );
\r
985 element.removeStyle( 'margin-top' );
\r
986 element.removeStyle( 'margin-bottom' );
\r
993 widths : [ '35%','65%' ],
\r
994 style : 'width:90px',
\r
995 label : editor.lang.common.align,
\r
999 [ editor.lang.common.notSet , ''],
\r
1000 [ editor.lang.common.alignLeft , 'left'],
\r
1001 [ editor.lang.common.alignRight , 'right']
\r
1002 // Backward compatible with v2 on setup when specified as attribute value,
\r
1003 // while these values are no more available as select options.
\r
1004 // [ editor.lang.image.alignAbsBottom , 'absBottom'],
\r
1005 // [ editor.lang.image.alignAbsMiddle , 'absMiddle'],
\r
1006 // [ editor.lang.image.alignBaseline , 'baseline'],
\r
1007 // [ editor.lang.image.alignTextTop , 'text-top'],
\r
1008 // [ editor.lang.image.alignBottom , 'bottom'],
\r
1009 // [ editor.lang.image.alignMiddle , 'middle'],
\r
1010 // [ editor.lang.image.alignTop , 'top']
\r
1012 onChange : function()
\r
1014 updatePreview( this.getDialog() );
\r
1015 commitInternally.call( this, 'advanced:txtdlgGenStyle' );
\r
1017 setup : function( type, element )
\r
1019 if ( type == IMAGE )
\r
1021 var value = element.getStyle( 'float' );
\r
1024 // Ignore those unrelated values.
\r
1030 !value && ( value = ( element.getAttribute( 'align' ) || '' ).toLowerCase() );
\r
1031 this.setValue( value );
\r
1034 commit : function( type, element, internalCommit )
\r
1036 var value = this.getValue();
\r
1037 if ( type == IMAGE || type == PREVIEW )
\r
1040 element.setStyle( 'float', value );
\r
1042 element.removeStyle( 'float' );
\r
1044 if ( !internalCommit && type == IMAGE )
\r
1046 value = ( element.getAttribute( 'align' ) || '' ).toLowerCase();
\r
1049 // we should remove it only if it matches "left" or "right",
\r
1050 // otherwise leave it intact.
\r
1053 element.removeAttribute( 'align' );
\r
1057 else if ( type == CLEANUP )
\r
1058 element.removeStyle( 'float' );
\r
1073 id : 'htmlPreview',
\r
1074 style : 'width:95%;',
\r
1075 html : '<div>' + CKEDITOR.tools.htmlEncode( editor.lang.common.preview ) +'<br>'+
\r
1076 '<div id="' + imagePreviewLoaderId + '" class="ImagePreviewLoader" style="display:none"><div class="loading"> </div></div>'+
\r
1077 '<div id="' + imagePreviewBoxId + '" class="ImagePreviewBox"><table><tr><td>'+
\r
1078 '<a href="javascript:void(0)" target="_blank" onclick="return false;" id="' + previewLinkId + '">'+
\r
1079 '<img id="' + previewImageId + '" alt="" /></a>' +
\r
1080 ( editor.config.image_previewText ||
\r
1081 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. '+
\r
1082 'Maecenas feugiat consequat diam. Maecenas metus. Vivamus diam purus, cursus a, commodo non, facilisis vitae, '+
\r
1083 'nulla. Aenean dictum lacinia tortor. Nunc iaculis, nibh non iaculis aliquam, orci felis euismod neque, sed ornare massa mauris sed velit. Nulla pretium mi et risus. Fusce mi pede, tempor id, cursus ac, ullamcorper nec, enim. Sed tortor. Curabitur molestie. Duis velit augue, condimentum at, ultrices a, luctus ut, orci. Donec pellentesque egestas eros. Integer cursus, augue in cursus faucibus, eros pede bibendum sem, in tempus tellus justo quis ligula. Etiam eget tortor. Vestibulum rutrum, est ut placerat elementum, lectus nisl aliquam velit, tempor aliquam eros nunc nonummy metus. In eros metus, gravida a, gravida sed, lobortis id, turpis. Ut ultrices, ipsum at venenatis fringilla, sem nulla lacinia tellus, eget aliquet turpis mauris non enim. Nam turpis. Suspendisse lacinia. Curabitur ac tortor ut ipsum egestas elementum. Nunc imperdiet gravida mauris.' ) +
\r
1084 '</td></tr></table></div></div>'
\r
1094 label : editor.lang.link.title,
\r
1101 label : editor.lang.common.url,
\r
1102 style : 'width: 100%',
\r
1104 setup : function( type, element )
\r
1106 if ( type == LINK )
\r
1108 var href = element.data( 'cke-saved-href' );
\r
1110 href = element.getAttribute( 'href' );
\r
1111 this.setValue( href );
\r
1114 commit : function( type, element )
\r
1116 if ( type == LINK )
\r
1118 if ( this.getValue() || this.isChanged() )
\r
1120 var url = decodeURI( this.getValue() );
\r
1121 element.data( 'cke-saved-href', url );
\r
1122 element.setAttribute( 'href', url );
\r
1124 if ( this.getValue() || !editor.config.image_removeLinkByEmptyURL )
\r
1125 this.getDialog().addLink = true;
\r
1135 action : 'Browse',
\r
1136 target: 'Link:txtUrl',
\r
1137 url: editor.config.filebrowserImageBrowseLinkUrl
\r
1139 style : 'float:right',
\r
1141 label : editor.lang.common.browseServer
\r
1146 label : editor.lang.common.target,
\r
1150 [ editor.lang.common.notSet , ''],
\r
1151 [ editor.lang.common.targetNew , '_blank'],
\r
1152 [ editor.lang.common.targetTop , '_top'],
\r
1153 [ editor.lang.common.targetSelf , '_self'],
\r
1154 [ editor.lang.common.targetParent , '_parent']
\r
1156 setup : function( type, element )
\r
1158 if ( type == LINK )
\r
1159 this.setValue( element.getAttribute( 'target' ) || '' );
\r
1161 commit : function( type, element )
\r
1163 if ( type == LINK )
\r
1165 if ( this.getValue() || this.isChanged() )
\r
1166 element.setAttribute( 'target', this.getValue() );
\r
1175 filebrowser : 'uploadButton',
\r
1176 label : editor.lang.image.upload,
\r
1182 label : editor.lang.image.btnUpload,
\r
1183 style: 'height:40px',
\r
1187 type : 'fileButton',
\r
1188 id : 'uploadButton',
\r
1189 filebrowser : 'info:txtUrl',
\r
1190 label : editor.lang.image.btnUpload,
\r
1191 'for' : [ 'Upload', 'upload' ]
\r
1197 label : editor.lang.common.advancedTab,
\r
1202 widths : [ '50%', '25%', '25%' ],
\r
1208 label : editor.lang.common.id,
\r
1209 setup : function( type, element )
\r
1211 if ( type == IMAGE )
\r
1212 this.setValue( element.getAttribute( 'id' ) );
\r
1214 commit : function( type, element )
\r
1216 if ( type == IMAGE )
\r
1218 if ( this.getValue() || this.isChanged() )
\r
1219 element.setAttribute( 'id', this.getValue() );
\r
1224 id : 'cmbLangDir',
\r
1226 style : 'width : 100px;',
\r
1227 label : editor.lang.common.langDir,
\r
1231 [ editor.lang.common.notSet, '' ],
\r
1232 [ editor.lang.common.langDirLtr, 'ltr' ],
\r
1233 [ editor.lang.common.langDirRtl, 'rtl' ]
\r
1235 setup : function( type, element )
\r
1237 if ( type == IMAGE )
\r
1238 this.setValue( element.getAttribute( 'dir' ) );
\r
1240 commit : function( type, element )
\r
1242 if ( type == IMAGE )
\r
1244 if ( this.getValue() || this.isChanged() )
\r
1245 element.setAttribute( 'dir', this.getValue() );
\r
1251 id : 'txtLangCode',
\r
1252 label : editor.lang.common.langCode,
\r
1254 setup : function( type, element )
\r
1256 if ( type == IMAGE )
\r
1257 this.setValue( element.getAttribute( 'lang' ) );
\r
1259 commit : function( type, element )
\r
1261 if ( type == IMAGE )
\r
1263 if ( this.getValue() || this.isChanged() )
\r
1264 element.setAttribute( 'lang', this.getValue() );
\r
1272 id : 'txtGenLongDescr',
\r
1273 label : editor.lang.common.longDescr,
\r
1274 setup : function( type, element )
\r
1276 if ( type == IMAGE )
\r
1277 this.setValue( element.getAttribute( 'longDesc' ) );
\r
1279 commit : function( type, element )
\r
1281 if ( type == IMAGE )
\r
1283 if ( this.getValue() || this.isChanged() )
\r
1284 element.setAttribute( 'longDesc', this.getValue() );
\r
1290 widths : [ '50%', '50%' ],
\r
1295 id : 'txtGenClass',
\r
1296 label : editor.lang.common.cssClass,
\r
1298 setup : function( type, element )
\r
1300 if ( type == IMAGE )
\r
1301 this.setValue( element.getAttribute( 'class' ) );
\r
1303 commit : function( type, element )
\r
1305 if ( type == IMAGE )
\r
1307 if ( this.getValue() || this.isChanged() )
\r
1308 element.setAttribute( 'class', this.getValue() );
\r
1314 id : 'txtGenTitle',
\r
1315 label : editor.lang.common.advisoryTitle,
\r
1317 onChange : function()
\r
1319 updatePreview( this.getDialog() );
\r
1321 setup : function( type, element )
\r
1323 if ( type == IMAGE )
\r
1324 this.setValue( element.getAttribute( 'title' ) );
\r
1326 commit : function( type, element )
\r
1328 if ( type == IMAGE )
\r
1330 if ( this.getValue() || this.isChanged() )
\r
1331 element.setAttribute( 'title', this.getValue() );
\r
1333 else if ( type == PREVIEW )
\r
1335 element.setAttribute( 'title', this.getValue() );
\r
1337 else if ( type == CLEANUP )
\r
1339 element.removeAttribute( 'title' );
\r
1347 id : 'txtdlgGenStyle',
\r
1348 label : editor.lang.common.cssStyle,
\r
1350 setup : function( type, element )
\r
1352 if ( type == IMAGE )
\r
1354 var genStyle = element.getAttribute( 'style' );
\r
1355 if ( !genStyle && element.$.style.cssText )
\r
1356 genStyle = element.$.style.cssText;
\r
1357 this.setValue( genStyle );
\r
1359 var height = element.$.style.height,
\r
1360 width = element.$.style.width,
\r
1361 aMatchH = ( height ? height : '' ).match( regexGetSize ),
\r
1362 aMatchW = ( width ? width : '').match( regexGetSize );
\r
1364 this.attributesInStyle =
\r
1366 height : !!aMatchH,
\r
1371 onChange : function ()
\r
1373 commitInternally.call( this,
\r
1374 [ 'info:cmbFloat', 'info:cmbAlign',
\r
1375 'info:txtVSpace', 'info:txtHSpace',
\r
1377 'info:txtWidth', 'info:txtHeight' ] );
\r
1378 updatePreview( this );
\r
1380 commit : function( type, element )
\r
1382 if ( type == IMAGE && ( this.getValue() || this.isChanged() ) )
\r
1384 element.setAttribute( 'style', this.getValue() );
\r
1394 CKEDITOR.dialog.add( 'image', function( editor )
\r
1396 return imageDialog( editor, 'image' );
\r
1399 CKEDITOR.dialog.add( 'imagebutton', function( editor )
\r
1401 return imageDialog( editor, 'imagebutton' );
\r