2 Copyright (c) 2003-2010, 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 var oImageOriginal = dialog.originalElement;
\r
120 // Dialog may already closed. (#5505)
\r
121 if( !oImageOriginal )
\r
124 var ratioButton = CKEDITOR.document.getById( btnLockSizesId );
\r
126 if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' )
\r
128 if ( value == 'check' ) // Check image ratio and original image ratio.
\r
130 var width = dialog.getValueOf( 'info', 'txtWidth' ),
\r
131 height = dialog.getValueOf( 'info', 'txtHeight' ),
\r
132 originalRatio = oImageOriginal.$.width * 1000 / oImageOriginal.$.height,
\r
133 thisRatio = width * 1000 / height;
\r
134 dialog.lockRatio = false; // Default: unlock ratio
\r
136 if ( !width && !height )
\r
137 dialog.lockRatio = true;
\r
138 else if ( !isNaN( originalRatio ) && !isNaN( thisRatio ) )
\r
140 if ( Math.round( originalRatio ) == Math.round( thisRatio ) )
\r
141 dialog.lockRatio = true;
\r
144 else if ( value != undefined )
\r
145 dialog.lockRatio = value;
\r
147 dialog.lockRatio = !dialog.lockRatio;
\r
149 else if ( value != 'check' ) // I can't lock ratio if ratio is unknown.
\r
150 dialog.lockRatio = false;
\r
152 if ( dialog.lockRatio )
\r
153 ratioButton.removeClass( 'cke_btn_unlocked' );
\r
155 ratioButton.addClass( 'cke_btn_unlocked' );
\r
157 var lang = dialog._.editor.lang.image,
\r
158 label = lang[ dialog.lockRatio ? 'unlockRatio' : 'lockRatio' ];
\r
160 ratioButton.setAttribute( 'title', label );
\r
161 ratioButton.getFirst().setText( label );
\r
163 return dialog.lockRatio;
\r
166 var resetSize = function( dialog )
\r
168 var oImageOriginal = dialog.originalElement;
\r
169 if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' )
\r
171 dialog.setValueOf( 'info', 'txtWidth', oImageOriginal.$.width );
\r
172 dialog.setValueOf( 'info', 'txtHeight', oImageOriginal.$.height );
\r
174 updatePreview( dialog );
\r
177 var setupDimension = function( type, element )
\r
179 if ( type != IMAGE )
\r
182 function checkDimension( size, defaultValue )
\r
184 var aMatch = size.match( regexGetSize );
\r
187 if ( aMatch[2] == '%' ) // % is allowed.
\r
190 switchLockRatio( dialog, false ); // Unlock ratio
\r
194 return defaultValue;
\r
197 var dialog = this.getDialog(),
\r
199 dimension = (( this.id == 'txtWidth' )? 'width' : 'height' ),
\r
200 size = element.getAttribute( dimension );
\r
203 value = checkDimension( size, value );
\r
204 value = checkDimension( element.getStyle( dimension ), value );
\r
206 this.setValue( value );
\r
209 var previewPreloader;
\r
211 var onImgLoadEvent = function()
\r
214 var original = this.originalElement;
\r
215 original.setCustomData( 'isReady', 'true' );
\r
216 original.removeListener( 'load', onImgLoadEvent );
\r
217 original.removeListener( 'error', onImgLoadErrorEvent );
\r
218 original.removeListener( 'abort', onImgLoadErrorEvent );
\r
221 CKEDITOR.document.getById( imagePreviewLoaderId ).setStyle( 'display', 'none' );
\r
223 // New image -> new domensions
\r
224 if ( !this.dontResetSize )
\r
227 if ( this.firstLoad )
\r
228 CKEDITOR.tools.setTimeout( function(){ switchLockRatio( this, 'check' ); }, 0, this );
\r
230 this.firstLoad = false;
\r
231 this.dontResetSize = false;
\r
234 var onImgLoadErrorEvent = function()
\r
236 // Error. Image is not loaded.
\r
237 var original = this.originalElement;
\r
238 original.removeListener( 'load', onImgLoadEvent );
\r
239 original.removeListener( 'error', onImgLoadErrorEvent );
\r
240 original.removeListener( 'abort', onImgLoadErrorEvent );
\r
242 // Set Error image.
\r
243 var noimage = CKEDITOR.getUrl( editor.skinPath + 'images/noimage.png' );
\r
245 if ( this.preview )
\r
246 this.preview.setAttribute( 'src', noimage );
\r
249 CKEDITOR.document.getById( imagePreviewLoaderId ).setStyle( 'display', 'none' );
\r
250 switchLockRatio( this, false ); // Unlock.
\r
253 var numbering = function( id )
\r
255 return CKEDITOR.tools.getNextId() + '_' + id;
\r
257 btnLockSizesId = numbering( 'btnLockSizes' ),
\r
258 btnResetSizeId = numbering( 'btnResetSize' ),
\r
259 imagePreviewLoaderId = numbering( 'ImagePreviewLoader' ),
\r
260 imagePreviewBoxId = numbering( 'ImagePreviewBox' ),
\r
261 previewLinkId = numbering( 'previewLink' ),
\r
262 previewImageId = numbering( 'previewImage' );
\r
265 title : ( dialogType == 'image' ) ? editor.lang.image.title : editor.lang.image.titleButton,
\r
268 onShow : function()
\r
270 this.imageElement = false;
\r
271 this.linkElement = false;
\r
273 // Default: create a new element.
\r
274 this.imageEditMode = false;
\r
275 this.linkEditMode = false;
\r
277 this.lockRatio = true;
\r
278 this.dontResetSize = false;
\r
279 this.firstLoad = true;
\r
280 this.addLink = false;
\r
282 var editor = this.getParentEditor(),
\r
283 sel = this.getParentEditor().getSelection(),
\r
284 element = sel.getSelectedElement(),
\r
285 link = element && element.getAscendant( 'a' );
\r
288 CKEDITOR.document.getById( imagePreviewLoaderId ).setStyle( 'display', 'none' );
\r
289 // Create the preview before setup the dialog contents.
\r
290 previewPreloader = new CKEDITOR.dom.element( 'img', editor.document );
\r
291 this.preview = CKEDITOR.document.getById( previewImageId );
\r
293 // Copy of the image
\r
294 this.originalElement = editor.document.createElement( 'img' );
\r
295 this.originalElement.setAttribute( 'alt', '' );
\r
296 this.originalElement.setCustomData( 'isReady', 'false' );
\r
300 this.linkElement = link;
\r
301 this.linkEditMode = true;
\r
303 // Look for Image element.
\r
304 var linkChildren = link.getChildren();
\r
305 if ( linkChildren.count() == 1 ) // 1 child.
\r
307 var childTagName = linkChildren.getItem( 0 ).getName();
\r
308 if ( childTagName == 'img' || childTagName == 'input' )
\r
310 this.imageElement = linkChildren.getItem( 0 );
\r
311 if ( this.imageElement.getName() == 'img' )
\r
312 this.imageEditMode = 'img';
\r
313 else if ( this.imageElement.getName() == 'input' )
\r
314 this.imageEditMode = 'input';
\r
317 // Fill out all fields.
\r
318 if ( dialogType == 'image' )
\r
319 this.setupContent( LINK, link );
\r
322 if ( element && element.getName() == 'img' && !element.getAttribute( '_cke_realelement' )
\r
323 || element && element.getName() == 'input' && element.getAttribute( 'type' ) == 'image' )
\r
325 this.imageEditMode = element.getName();
\r
326 this.imageElement = element;
\r
329 if ( this.imageEditMode )
\r
331 // Use the original element as a buffer from since we don't want
\r
332 // temporary changes to be committed, e.g. if the dialog is canceled.
\r
333 this.cleanImageElement = this.imageElement;
\r
334 this.imageElement = this.cleanImageElement.clone( true, true );
\r
336 // Fill out all fields.
\r
337 this.setupContent( IMAGE, this.imageElement );
\r
339 // Refresh LockRatio button
\r
340 switchLockRatio ( this, true );
\r
343 this.imageElement = editor.document.createElement( 'img' );
\r
345 // Dont show preview if no URL given.
\r
346 if ( !CKEDITOR.tools.trim( this.getValueOf( 'info', 'txtUrl' ) ) )
\r
348 this.preview.removeAttribute( 'src' );
\r
349 this.preview.setStyle( 'display', 'none' );
\r
354 // Edit existing Image.
\r
355 if ( this.imageEditMode )
\r
357 var imgTagName = this.imageEditMode;
\r
359 // Image dialog and Input element.
\r
360 if ( dialogType == 'image' && imgTagName == 'input' && confirm( editor.lang.image.button2Img ) )
\r
362 // Replace INPUT-> IMG
\r
363 imgTagName = 'img';
\r
364 this.imageElement = editor.document.createElement( 'img' );
\r
365 this.imageElement.setAttribute( 'alt', '' );
\r
366 editor.insertElement( this.imageElement );
\r
368 // ImageButton dialog and Image element.
\r
369 else if ( dialogType != 'image' && imgTagName == 'img' && confirm( editor.lang.image.img2Button ))
\r
371 // Replace IMG -> INPUT
\r
372 imgTagName = 'input';
\r
373 this.imageElement = editor.document.createElement( 'input' );
\r
374 this.imageElement.setAttributes(
\r
380 editor.insertElement( this.imageElement );
\r
384 // Restore the original element before all commits.
\r
385 this.imageElement = this.cleanImageElement;
\r
386 delete this.cleanImageElement;
\r
389 else // Create a new image.
\r
391 // Image dialog -> create IMG element.
\r
392 if ( dialogType == 'image' )
\r
393 this.imageElement = editor.document.createElement( 'img' );
\r
396 this.imageElement = editor.document.createElement( 'input' );
\r
397 this.imageElement.setAttribute ( 'type' ,'image' );
\r
399 this.imageElement.setAttribute( 'alt', '' );
\r
402 // Create a new link.
\r
403 if ( !this.linkEditMode )
\r
404 this.linkElement = editor.document.createElement( 'a' );
\r
407 this.commitContent( IMAGE, this.imageElement );
\r
408 this.commitContent( LINK, this.linkElement );
\r
410 // Remove empty style attribute.
\r
411 if ( !this.imageElement.getAttribute( 'style' ) )
\r
412 this.imageElement.removeAttribute( 'style' );
\r
414 // Insert a new Image.
\r
415 if ( !this.imageEditMode )
\r
417 if ( this.addLink )
\r
419 //Insert a new Link.
\r
420 if ( !this.linkEditMode )
\r
422 editor.insertElement(this.linkElement);
\r
423 this.linkElement.append(this.imageElement, false);
\r
425 else //Link already exists, image not.
\r
426 editor.insertElement(this.imageElement );
\r
429 editor.insertElement( this.imageElement );
\r
431 else // Image already exists.
\r
433 //Add a new link element.
\r
434 if ( !this.linkEditMode && this.addLink )
\r
436 editor.insertElement( this.linkElement );
\r
437 this.imageElement.appendTo( this.linkElement );
\r
439 //Remove Link, Image exists.
\r
440 else if ( this.linkEditMode && !this.addLink )
\r
442 editor.getSelection().selectElement( this.linkElement );
\r
443 editor.insertElement( this.imageElement );
\r
447 onLoad : function()
\r
449 if ( dialogType != 'image' )
\r
450 this.hidePage( 'Link' ); //Hide Link tab.
\r
451 var doc = this._.element.getDocument();
\r
452 this.addFocusable( doc.getById( btnResetSizeId ), 5 );
\r
453 this.addFocusable( doc.getById( btnLockSizesId ), 5 );
\r
455 this.commitContent = commitContent;
\r
457 onHide : function()
\r
459 if ( this.preview )
\r
460 this.commitContent( CLEANUP, this.preview );
\r
462 if ( this.originalElement )
\r
464 this.originalElement.removeListener( 'load', onImgLoadEvent );
\r
465 this.originalElement.removeListener( 'error', onImgLoadErrorEvent );
\r
466 this.originalElement.removeListener( 'abort', onImgLoadErrorEvent );
\r
467 this.originalElement.remove();
\r
468 this.originalElement = false; // Dialog is closed.
\r
471 delete this.imageElement;
\r
476 label : editor.lang.image.infoTab,
\r
487 widths : [ '280px', '110px' ],
\r
494 label : editor.lang.common.url,
\r
496 onChange : function()
\r
498 var dialog = this.getDialog(),
\r
499 newUrl = this.getValue();
\r
501 //Update original image
\r
502 if ( newUrl.length > 0 ) //Prevent from load before onShow
\r
504 dialog = this.getDialog();
\r
505 var original = dialog.originalElement;
\r
507 dialog.preview.removeStyle( 'display' );
\r
509 original.setCustomData( 'isReady', 'false' );
\r
511 var loader = CKEDITOR.document.getById( imagePreviewLoaderId );
\r
513 loader.setStyle( 'display', '' );
\r
515 original.on( 'load', onImgLoadEvent, dialog );
\r
516 original.on( 'error', onImgLoadErrorEvent, dialog );
\r
517 original.on( 'abort', onImgLoadErrorEvent, dialog );
\r
518 original.setAttribute( 'src', newUrl );
\r
520 // Query the preloader to figure out the url impacted by based href.
\r
521 previewPreloader.setAttribute( 'src', newUrl );
\r
522 dialog.preview.setAttribute( 'src', previewPreloader.$.src );
\r
523 updatePreview( dialog );
\r
525 // Dont show preview if no URL given.
\r
526 else if ( dialog.preview )
\r
528 dialog.preview.removeAttribute( 'src' );
\r
529 dialog.preview.setStyle( 'display', 'none' );
\r
532 setup : function( type, element )
\r
534 if ( type == IMAGE )
\r
536 var url = element.getAttribute( '_cke_saved_src' ) || element.getAttribute( 'src' );
\r
539 this.getDialog().dontResetSize = true;
\r
541 field.setValue( url ); // And call this.onChange()
\r
542 // Manually set the initial value.(#4191)
\r
543 field.setInitValue();
\r
546 commit : function( type, element )
\r
548 if ( type == IMAGE && ( this.getValue() || this.isChanged() ) )
\r
550 element.setAttribute( '_cke_saved_src', decodeURI( this.getValue() ) );
\r
551 element.setAttribute( 'src', decodeURI( this.getValue() ) );
\r
553 else if ( type == CLEANUP )
\r
555 element.setAttribute( 'src', '' ); // If removeAttribute doesn't work.
\r
556 element.removeAttribute( 'src' );
\r
559 validate : CKEDITOR.dialog.validate.notEmpty( editor.lang.image.urlMissing )
\r
564 // v-align with the 'txtUrl' field.
\r
565 // TODO: We need something better than a fixed size here.
\r
566 style : 'display:inline-block;margin-top:10px;',
\r
568 label : editor.lang.common.browseServer,
\r
570 filebrowser : 'info:txtUrl'
\r
579 label : editor.lang.image.alt,
\r
582 onChange : function()
\r
584 updatePreview( this.getDialog() );
\r
586 setup : function( type, element )
\r
588 if ( type == IMAGE )
\r
589 this.setValue( element.getAttribute( 'alt' ) );
\r
591 commit : function( type, element )
\r
593 if ( type == IMAGE )
\r
595 if ( this.getValue() || this.isChanged() )
\r
596 element.setAttribute( 'alt', this.getValue() );
\r
598 else if ( type == PREVIEW )
\r
600 element.setAttribute( 'alt', this.getValue() );
\r
602 else if ( type == CLEANUP )
\r
604 element.removeAttribute( 'alt' );
\r
610 widths : [ '140px', '240px' ],
\r
620 widths : [ '70%', '30%' ],
\r
632 labelLayout : 'horizontal',
\r
633 label : editor.lang.image.width,
\r
634 onKeyUp : onSizeChange,
\r
635 onChange : function()
\r
637 commitInternally.call( this, 'advanced:txtdlgGenStyle' );
\r
639 validate : function()
\r
641 var aMatch = this.getValue().match( regexGetSizeOrEmpty );
\r
643 alert( editor.lang.image.validateWidth );
\r
646 setup : setupDimension,
\r
647 commit : function( type, element, internalCommit )
\r
649 var value = this.getValue();
\r
650 if ( type == IMAGE )
\r
653 element.setStyle( 'width', CKEDITOR.tools.cssLength( value ) );
\r
654 else if ( !value && this.isChanged( ) )
\r
655 element.removeStyle( 'width' );
\r
657 !internalCommit && element.removeAttribute( 'width' );
\r
659 else if ( type == PREVIEW )
\r
661 var aMatch = value.match( regexGetSize );
\r
664 var oImageOriginal = this.getDialog().originalElement;
\r
665 if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' )
\r
666 element.setStyle( 'width', oImageOriginal.$.width + 'px');
\r
669 element.setStyle( 'width', CKEDITOR.tools.cssLength( value ) );
\r
671 else if ( type == CLEANUP )
\r
673 element.removeAttribute( 'width' );
\r
674 element.removeStyle( 'width' );
\r
682 labelLayout : 'horizontal',
\r
683 label : editor.lang.image.height,
\r
684 onKeyUp : onSizeChange,
\r
685 onChange : function()
\r
687 commitInternally.call( this, 'advanced:txtdlgGenStyle' );
\r
689 validate : function()
\r
691 var aMatch = this.getValue().match( regexGetSizeOrEmpty );
\r
693 alert( editor.lang.image.validateHeight );
\r
696 setup : setupDimension,
\r
697 commit : function( type, element, internalCommit )
\r
699 var value = this.getValue();
\r
700 if ( type == IMAGE )
\r
703 element.setStyle( 'height', CKEDITOR.tools.cssLength( value ) );
\r
704 else if ( !value && this.isChanged( ) )
\r
705 element.removeStyle( 'height' );
\r
707 if ( !internalCommit && type == IMAGE )
\r
708 element.removeAttribute( 'height' );
\r
710 else if ( type == PREVIEW )
\r
712 var aMatch = value.match( regexGetSize );
\r
715 var oImageOriginal = this.getDialog().originalElement;
\r
716 if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' )
\r
717 element.setStyle( 'height', oImageOriginal.$.height + 'px' );
\r
720 element.setStyle( 'height', CKEDITOR.tools.cssLength( value ) );
\r
722 else if ( type == CLEANUP )
\r
724 element.removeAttribute( 'height' );
\r
725 element.removeStyle( 'height' );
\r
733 style : 'margin-top:10px;width:40px;height:40px;',
\r
734 onLoad : function()
\r
736 // Activate Reset button
\r
737 var resetButton = CKEDITOR.document.getById( btnResetSizeId ),
\r
738 ratioButton = CKEDITOR.document.getById( btnLockSizesId );
\r
741 resetButton.on( 'click', function(evt)
\r
744 evt.data.preventDefault();
\r
745 }, this.getDialog() );
\r
746 resetButton.on( 'mouseover', function()
\r
748 this.addClass( 'cke_btn_over' );
\r
750 resetButton.on( 'mouseout', function()
\r
752 this.removeClass( 'cke_btn_over' );
\r
755 // Activate (Un)LockRatio button
\r
758 ratioButton.on( 'click', function(evt)
\r
760 var locked = switchLockRatio( this ),
\r
761 oImageOriginal = this.originalElement,
\r
762 width = this.getValueOf( 'info', 'txtWidth' );
\r
764 if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' && width )
\r
766 var height = oImageOriginal.$.height / oImageOriginal.$.width * width;
\r
767 if ( !isNaN( height ) )
\r
769 this.setValueOf( 'info', 'txtHeight', Math.round( height ) );
\r
770 updatePreview( this );
\r
773 evt.data.preventDefault();
\r
774 }, this.getDialog() );
\r
775 ratioButton.on( 'mouseover', function()
\r
777 this.addClass( 'cke_btn_over' );
\r
779 ratioButton.on( 'mouseout', function()
\r
781 this.removeClass( 'cke_btn_over' );
\r
786 '<a href="javascript:void(0)" tabindex="-1" title="' + editor.lang.image.unlockRatio +
\r
787 '" class="cke_btn_locked" id="' + btnLockSizesId + '" role="button"><span class="cke_label">' + editor.lang.image.unlockRatio + '</span></a>' +
\r
788 '<a href="javascript:void(0)" tabindex="-1" title="' + editor.lang.image.resetSize +
\r
789 '" class="cke_btn_reset" id="' + btnResetSizeId + '" role="button"><span class="cke_label">' + editor.lang.image.resetSize + '</span></a>'+
\r
803 labelLayout : 'horizontal',
\r
804 label : editor.lang.image.border,
\r
806 onKeyUp : function()
\r
808 updatePreview( this.getDialog() );
\r
810 onChange : function()
\r
812 commitInternally.call( this, 'advanced:txtdlgGenStyle' );
\r
814 validate : CKEDITOR.dialog.validate.integer( editor.lang.image.validateBorder ),
\r
815 setup : function( type, element )
\r
817 if ( type == IMAGE )
\r
820 borderStyle = element.getStyle( 'border-width' );
\r
821 borderStyle = borderStyle && borderStyle.match( /^(\d+px)(?: \1 \1 \1)?$/ );
\r
822 value = borderStyle && parseInt( borderStyle[ 1 ], 10 );
\r
823 isNaN ( parseInt( value, 10 ) ) && ( value = element.getAttribute( 'border' ) );
\r
824 this.setValue( value );
\r
827 commit : function( type, element, internalCommit )
\r
829 var value = parseInt( this.getValue(), 10 );
\r
830 if ( type == IMAGE || type == PREVIEW )
\r
832 if ( !isNaN( value ) )
\r
834 element.setStyle( 'border-width', CKEDITOR.tools.cssLength( value ) );
\r
835 element.setStyle( 'border-style', 'solid' );
\r
837 else if ( !value && this.isChanged() )
\r
839 element.removeStyle( 'border-width' );
\r
840 element.removeStyle( 'border-style' );
\r
841 element.removeStyle( 'border-color' );
\r
844 if ( !internalCommit && type == IMAGE )
\r
845 element.removeAttribute( 'border' );
\r
847 else if ( type == CLEANUP )
\r
849 element.removeAttribute( 'border' );
\r
850 element.removeStyle( 'border-width' );
\r
851 element.removeStyle( 'border-style' );
\r
852 element.removeStyle( 'border-color' );
\r
860 labelLayout : 'horizontal',
\r
861 label : editor.lang.image.hSpace,
\r
863 onKeyUp : function()
\r
865 updatePreview( this.getDialog() );
\r
867 onChange : function()
\r
869 commitInternally.call( this, 'advanced:txtdlgGenStyle' );
\r
871 validate : CKEDITOR.dialog.validate.integer( editor.lang.image.validateHSpace ),
\r
872 setup : function( type, element )
\r
874 if ( type == IMAGE )
\r
879 marginLeftStyle = element.getStyle( 'margin-left' ),
\r
880 marginRightStyle = element.getStyle( 'margin-right' );
\r
882 marginLeftStyle = marginLeftStyle && marginLeftStyle.match( pxLengthRegex );
\r
883 marginRightStyle = marginRightStyle && marginRightStyle.match( pxLengthRegex );
\r
884 marginLeftPx = parseInt( marginLeftStyle, 10 );
\r
885 marginRightPx = parseInt( marginRightStyle, 10 );
\r
887 value = ( marginLeftPx == marginRightPx ) && marginLeftPx;
\r
888 isNaN( parseInt( value, 10 ) ) && ( value = element.getAttribute( 'hspace' ) );
\r
890 this.setValue( value );
\r
893 commit : function( type, element, internalCommit )
\r
895 var value = parseInt( this.getValue(), 10 );
\r
896 if ( type == IMAGE || type == PREVIEW )
\r
898 if ( !isNaN( value ) )
\r
900 element.setStyle( 'margin-left', CKEDITOR.tools.cssLength( value ) );
\r
901 element.setStyle( 'margin-right', CKEDITOR.tools.cssLength( value ) );
\r
903 else if ( !value && this.isChanged( ) )
\r
905 element.removeStyle( 'margin-left' );
\r
906 element.removeStyle( 'margin-right' );
\r
909 if ( !internalCommit && type == IMAGE )
\r
910 element.removeAttribute( 'hspace' );
\r
912 else if ( type == CLEANUP )
\r
914 element.removeAttribute( 'hspace' );
\r
915 element.removeStyle( 'margin-left' );
\r
916 element.removeStyle( 'margin-right' );
\r
924 labelLayout : 'horizontal',
\r
925 label : editor.lang.image.vSpace,
\r
927 onKeyUp : function()
\r
929 updatePreview( this.getDialog() );
\r
931 onChange : function()
\r
933 commitInternally.call( this, 'advanced:txtdlgGenStyle' );
\r
935 validate : CKEDITOR.dialog.validate.integer( editor.lang.image.validateVSpace ),
\r
936 setup : function( type, element )
\r
938 if ( type == IMAGE )
\r
943 marginTopStyle = element.getStyle( 'margin-top' ),
\r
944 marginBottomStyle = element.getStyle( 'margin-bottom' );
\r
946 marginTopStyle = marginTopStyle && marginTopStyle.match( pxLengthRegex );
\r
947 marginBottomStyle = marginBottomStyle && marginBottomStyle.match( pxLengthRegex );
\r
948 marginTopPx = parseInt( marginTopStyle, 10 );
\r
949 marginBottomPx = parseInt( marginBottomStyle, 10 );
\r
951 value = ( marginTopPx == marginBottomPx ) && marginTopPx;
\r
952 isNaN ( parseInt( value, 10 ) ) && ( value = element.getAttribute( 'vspace' ) );
\r
953 this.setValue( value );
\r
956 commit : function( type, element, internalCommit )
\r
958 var value = parseInt( this.getValue(), 10 );
\r
959 if ( type == IMAGE || type == PREVIEW )
\r
961 if ( !isNaN( value ) )
\r
963 element.setStyle( 'margin-top', CKEDITOR.tools.cssLength( value ) );
\r
964 element.setStyle( 'margin-bottom', CKEDITOR.tools.cssLength( value ) );
\r
966 else if ( !value && this.isChanged( ) )
\r
968 element.removeStyle( 'margin-top' );
\r
969 element.removeStyle( 'margin-bottom' );
\r
972 if ( !internalCommit && type == IMAGE )
\r
973 element.removeAttribute( 'vspace' );
\r
975 else if ( type == CLEANUP )
\r
977 element.removeAttribute( 'vspace' );
\r
978 element.removeStyle( 'margin-top' );
\r
979 element.removeStyle( 'margin-bottom' );
\r
986 labelLayout : 'horizontal',
\r
987 widths : [ '35%','65%' ],
\r
988 style : 'width:90px',
\r
989 label : editor.lang.image.align,
\r
993 [ editor.lang.common.notSet , ''],
\r
994 [ editor.lang.image.alignLeft , 'left'],
\r
995 [ editor.lang.image.alignRight , 'right']
\r
996 // Backward compatible with v2 on setup when specified as attribute value,
\r
997 // while these values are no more available as select options.
\r
998 // [ editor.lang.image.alignAbsBottom , 'absBottom'],
\r
999 // [ editor.lang.image.alignAbsMiddle , 'absMiddle'],
\r
1000 // [ editor.lang.image.alignBaseline , 'baseline'],
\r
1001 // [ editor.lang.image.alignTextTop , 'text-top'],
\r
1002 // [ editor.lang.image.alignBottom , 'bottom'],
\r
1003 // [ editor.lang.image.alignMiddle , 'middle'],
\r
1004 // [ editor.lang.image.alignTop , 'top']
\r
1006 onChange : function()
\r
1008 updatePreview( this.getDialog() );
\r
1009 commitInternally.call( this, 'advanced:txtdlgGenStyle' );
\r
1011 setup : function( type, element )
\r
1013 if ( type == IMAGE )
\r
1015 var value = element.getStyle( 'float' );
\r
1018 // Ignore those unrelated values.
\r
1024 !value && ( value = ( element.getAttribute( 'align' ) || '' ).toLowerCase() );
\r
1025 this.setValue( value );
\r
1028 commit : function( type, element, internalCommit )
\r
1030 var value = this.getValue();
\r
1031 if ( type == IMAGE || type == PREVIEW )
\r
1034 element.setStyle( 'float', value );
\r
1036 element.removeStyle( 'float' );
\r
1038 if ( !internalCommit && type == IMAGE )
\r
1040 value = ( element.getAttribute( 'align' ) || '' ).toLowerCase();
\r
1043 // we should remove it only if it matches "left" or "right",
\r
1044 // otherwise leave it intact.
\r
1047 element.removeAttribute( 'align' );
\r
1051 else if ( type == CLEANUP )
\r
1052 element.removeStyle( 'float' );
\r
1067 style : 'width:95%;',
\r
1068 html : '<div>' + CKEDITOR.tools.htmlEncode( editor.lang.common.preview ) +'<br>'+
\r
1069 '<div id="' + imagePreviewLoaderId + '" class="ImagePreviewLoader" style="display:none"><div class="loading"> </div></div>'+
\r
1070 '<div id="' + imagePreviewBoxId + '" class="ImagePreviewBox"><table><tr><td>'+
\r
1071 '<a href="javascript:void(0)" target="_blank" onclick="return false;" id="' + previewLinkId + '">'+
\r
1072 '<img id="' + previewImageId + '" alt="" /></a>' +
\r
1073 ( editor.config.image_previewText ||
\r
1074 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. '+
\r
1075 'Maecenas feugiat consequat diam. Maecenas metus. Vivamus diam purus, cursus a, commodo non, facilisis vitae, '+
\r
1076 '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
1077 '</td></tr></table></div></div>'
\r
1087 label : editor.lang.link.title,
\r
1094 label : editor.lang.common.url,
\r
1095 style : 'width: 100%',
\r
1097 setup : function( type, element )
\r
1099 if ( type == LINK )
\r
1101 var href = element.getAttribute( '_cke_saved_href' );
\r
1103 href = element.getAttribute( 'href' );
\r
1104 this.setValue( href );
\r
1107 commit : function( type, element )
\r
1109 if ( type == LINK )
\r
1111 if ( this.getValue() || this.isChanged() )
\r
1113 element.setAttribute( '_cke_saved_href', decodeURI( this.getValue() ) );
\r
1114 element.setAttribute( 'href', 'javascript:void(0)/*' +
\r
1115 CKEDITOR.tools.getNextNumber() + '*/' );
\r
1117 if ( this.getValue() || !editor.config.image_removeLinkByEmptyURL )
\r
1118 this.getDialog().addLink = true;
\r
1128 action : 'Browse',
\r
1129 target: 'Link:txtUrl',
\r
1130 url: editor.config.filebrowserImageBrowseLinkUrl
\r
1132 style : 'float:right',
\r
1134 label : editor.lang.common.browseServer
\r
1139 label : editor.lang.common.target,
\r
1143 [ editor.lang.common.notSet , ''],
\r
1144 [ editor.lang.common.targetNew , '_blank'],
\r
1145 [ editor.lang.common.targetTop , '_top'],
\r
1146 [ editor.lang.common.targetSelf , '_self'],
\r
1147 [ editor.lang.common.targetParent , '_parent']
\r
1149 setup : function( type, element )
\r
1151 if ( type == LINK )
\r
1152 this.setValue( element.getAttribute( 'target' ) || '' );
\r
1154 commit : function( type, element )
\r
1156 if ( type == LINK )
\r
1158 if ( this.getValue() || this.isChanged() )
\r
1159 element.setAttribute( 'target', this.getValue() );
\r
1168 filebrowser : 'uploadButton',
\r
1169 label : editor.lang.image.upload,
\r
1175 label : editor.lang.image.btnUpload,
\r
1176 style: 'height:40px',
\r
1180 type : 'fileButton',
\r
1181 id : 'uploadButton',
\r
1182 filebrowser : 'info:txtUrl',
\r
1183 label : editor.lang.image.btnUpload,
\r
1184 'for' : [ 'Upload', 'upload' ]
\r
1190 label : editor.lang.common.advancedTab,
\r
1195 widths : [ '50%', '25%', '25%' ],
\r
1201 label : editor.lang.common.id,
\r
1202 setup : function( type, element )
\r
1204 if ( type == IMAGE )
\r
1205 this.setValue( element.getAttribute( 'id' ) );
\r
1207 commit : function( type, element )
\r
1209 if ( type == IMAGE )
\r
1211 if ( this.getValue() || this.isChanged() )
\r
1212 element.setAttribute( 'id', this.getValue() );
\r
1217 id : 'cmbLangDir',
\r
1219 style : 'width : 100px;',
\r
1220 label : editor.lang.common.langDir,
\r
1224 [ editor.lang.common.notSet, '' ],
\r
1225 [ editor.lang.common.langDirLtr, 'ltr' ],
\r
1226 [ editor.lang.common.langDirRtl, 'rtl' ]
\r
1228 setup : function( type, element )
\r
1230 if ( type == IMAGE )
\r
1231 this.setValue( element.getAttribute( 'dir' ) );
\r
1233 commit : function( type, element )
\r
1235 if ( type == IMAGE )
\r
1237 if ( this.getValue() || this.isChanged() )
\r
1238 element.setAttribute( 'dir', this.getValue() );
\r
1244 id : 'txtLangCode',
\r
1245 label : editor.lang.common.langCode,
\r
1247 setup : function( type, element )
\r
1249 if ( type == IMAGE )
\r
1250 this.setValue( element.getAttribute( 'lang' ) );
\r
1252 commit : function( type, element )
\r
1254 if ( type == IMAGE )
\r
1256 if ( this.getValue() || this.isChanged() )
\r
1257 element.setAttribute( 'lang', this.getValue() );
\r
1265 id : 'txtGenLongDescr',
\r
1266 label : editor.lang.common.longDescr,
\r
1267 setup : function( type, element )
\r
1269 if ( type == IMAGE )
\r
1270 this.setValue( element.getAttribute( 'longDesc' ) );
\r
1272 commit : function( type, element )
\r
1274 if ( type == IMAGE )
\r
1276 if ( this.getValue() || this.isChanged() )
\r
1277 element.setAttribute( 'longDesc', this.getValue() );
\r
1283 widths : [ '50%', '50%' ],
\r
1288 id : 'txtGenClass',
\r
1289 label : editor.lang.common.cssClass,
\r
1291 setup : function( type, element )
\r
1293 if ( type == IMAGE )
\r
1294 this.setValue( element.getAttribute( 'class' ) );
\r
1296 commit : function( type, element )
\r
1298 if ( type == IMAGE )
\r
1300 if ( this.getValue() || this.isChanged() )
\r
1301 element.setAttribute( 'class', this.getValue() );
\r
1307 id : 'txtGenTitle',
\r
1308 label : editor.lang.common.advisoryTitle,
\r
1310 onChange : function()
\r
1312 updatePreview( this.getDialog() );
\r
1314 setup : function( type, element )
\r
1316 if ( type == IMAGE )
\r
1317 this.setValue( element.getAttribute( 'title' ) );
\r
1319 commit : function( type, element )
\r
1321 if ( type == IMAGE )
\r
1323 if ( this.getValue() || this.isChanged() )
\r
1324 element.setAttribute( 'title', this.getValue() );
\r
1326 else if ( type == PREVIEW )
\r
1328 element.setAttribute( 'title', this.getValue() );
\r
1330 else if ( type == CLEANUP )
\r
1332 element.removeAttribute( 'title' );
\r
1340 id : 'txtdlgGenStyle',
\r
1341 label : editor.lang.common.cssStyle,
\r
1343 setup : function( type, element )
\r
1345 if ( type == IMAGE )
\r
1347 var genStyle = element.getAttribute( 'style' );
\r
1348 if ( !genStyle && element.$.style.cssText )
\r
1349 genStyle = element.$.style.cssText;
\r
1350 this.setValue( genStyle );
\r
1352 var height = element.$.style.height,
\r
1353 width = element.$.style.width,
\r
1354 aMatchH = ( height ? height : '' ).match( regexGetSize ),
\r
1355 aMatchW = ( width ? width : '').match( regexGetSize );
\r
1357 this.attributesInStyle =
\r
1359 height : !!aMatchH,
\r
1364 onChange : function ()
\r
1366 commitInternally.call( this,
\r
1367 [ 'info:cmbFloat', 'info:cmbAlign',
\r
1368 'info:txtVSpace', 'info:txtHSpace',
\r
1370 'info:txtWidth', 'info:txtHeight' ] );
\r
1371 updatePreview( this );
\r
1373 commit : function( type, element )
\r
1375 if ( type == IMAGE && ( this.getValue() || this.isChanged() ) )
\r
1377 element.setAttribute( 'style', this.getValue() );
\r
1387 CKEDITOR.dialog.add( 'image', function( editor )
\r
1389 return imageDialog( editor, 'image' );
\r
1392 CKEDITOR.dialog.add( 'imagebutton', function( editor )
\r
1394 return imageDialog( editor, 'imagebutton' );
\r