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
267 minHeight : CKEDITOR.env.ie && CKEDITOR.env.quirks? 360: 310,
\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.data( '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.data( '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.data( '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
618 widths : [ '50%', '50%' ],
\r
630 label : editor.lang.common.width,
\r
631 onKeyUp : onSizeChange,
\r
632 onChange : function()
\r
634 commitInternally.call( this, 'advanced:txtdlgGenStyle' );
\r
636 validate : function()
\r
638 var aMatch = this.getValue().match( regexGetSizeOrEmpty );
\r
640 alert( editor.lang.common.invalidWidth );
\r
643 setup : setupDimension,
\r
644 commit : function( type, element, internalCommit )
\r
646 var value = this.getValue();
\r
647 if ( type == IMAGE )
\r
650 element.setStyle( 'width', CKEDITOR.tools.cssLength( value ) );
\r
651 else if ( !value && this.isChanged( ) )
\r
652 element.removeStyle( 'width' );
\r
654 !internalCommit && element.removeAttribute( 'width' );
\r
656 else if ( type == PREVIEW )
\r
658 var aMatch = value.match( regexGetSize );
\r
661 var oImageOriginal = this.getDialog().originalElement;
\r
662 if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' )
\r
663 element.setStyle( 'width', oImageOriginal.$.width + 'px');
\r
666 element.setStyle( 'width', CKEDITOR.tools.cssLength( value ) );
\r
668 else if ( type == CLEANUP )
\r
670 element.removeAttribute( 'width' );
\r
671 element.removeStyle( 'width' );
\r
679 label : editor.lang.common.height,
\r
680 onKeyUp : onSizeChange,
\r
681 onChange : function()
\r
683 commitInternally.call( this, 'advanced:txtdlgGenStyle' );
\r
685 validate : function()
\r
687 var aMatch = this.getValue().match( regexGetSizeOrEmpty );
\r
689 alert( editor.lang.common.invalidHeight );
\r
692 setup : setupDimension,
\r
693 commit : function( type, element, internalCommit )
\r
695 var value = this.getValue();
\r
696 if ( type == IMAGE )
\r
699 element.setStyle( 'height', CKEDITOR.tools.cssLength( value ) );
\r
700 else if ( !value && this.isChanged( ) )
\r
701 element.removeStyle( 'height' );
\r
703 if ( !internalCommit && type == IMAGE )
\r
704 element.removeAttribute( 'height' );
\r
706 else if ( type == PREVIEW )
\r
708 var aMatch = value.match( regexGetSize );
\r
711 var oImageOriginal = this.getDialog().originalElement;
\r
712 if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' )
\r
713 element.setStyle( 'height', oImageOriginal.$.height + 'px' );
\r
716 element.setStyle( 'height', CKEDITOR.tools.cssLength( value ) );
\r
718 else if ( type == CLEANUP )
\r
720 element.removeAttribute( 'height' );
\r
721 element.removeStyle( 'height' );
\r
729 style : 'margin-top:30px;width:40px;height:40px;',
\r
730 onLoad : function()
\r
732 // Activate Reset button
\r
733 var resetButton = CKEDITOR.document.getById( btnResetSizeId ),
\r
734 ratioButton = CKEDITOR.document.getById( btnLockSizesId );
\r
737 resetButton.on( 'click', function(evt)
\r
740 evt.data.preventDefault();
\r
741 }, this.getDialog() );
\r
742 resetButton.on( 'mouseover', function()
\r
744 this.addClass( 'cke_btn_over' );
\r
746 resetButton.on( 'mouseout', function()
\r
748 this.removeClass( 'cke_btn_over' );
\r
751 // Activate (Un)LockRatio button
\r
754 ratioButton.on( 'click', function(evt)
\r
756 var locked = switchLockRatio( this ),
\r
757 oImageOriginal = this.originalElement,
\r
758 width = this.getValueOf( 'info', 'txtWidth' );
\r
760 if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' && width )
\r
762 var height = oImageOriginal.$.height / oImageOriginal.$.width * width;
\r
763 if ( !isNaN( height ) )
\r
765 this.setValueOf( 'info', 'txtHeight', Math.round( height ) );
\r
766 updatePreview( this );
\r
769 evt.data.preventDefault();
\r
770 }, this.getDialog() );
\r
771 ratioButton.on( 'mouseover', function()
\r
773 this.addClass( 'cke_btn_over' );
\r
775 ratioButton.on( 'mouseout', function()
\r
777 this.removeClass( 'cke_btn_over' );
\r
782 '<a href="javascript:void(0)" tabindex="-1" title="' + editor.lang.image.unlockRatio +
\r
783 '" class="cke_btn_locked" id="' + btnLockSizesId + '" role="button"><span class="cke_label">' + editor.lang.image.unlockRatio + '</span></a>' +
\r
784 '<a href="javascript:void(0)" tabindex="-1" title="' + editor.lang.image.resetSize +
\r
785 '" class="cke_btn_reset" id="' + btnResetSizeId + '" role="button"><span class="cke_label">' + editor.lang.image.resetSize + '</span></a>'+
\r
799 label : editor.lang.image.border,
\r
801 onKeyUp : function()
\r
803 updatePreview( this.getDialog() );
\r
805 onChange : function()
\r
807 commitInternally.call( this, 'advanced:txtdlgGenStyle' );
\r
809 validate : CKEDITOR.dialog.validate.integer( editor.lang.image.validateBorder ),
\r
810 setup : function( type, element )
\r
812 if ( type == IMAGE )
\r
815 borderStyle = element.getStyle( 'border-width' );
\r
816 borderStyle = borderStyle && borderStyle.match( /^(\d+px)(?: \1 \1 \1)?$/ );
\r
817 value = borderStyle && parseInt( borderStyle[ 1 ], 10 );
\r
818 isNaN ( parseInt( value, 10 ) ) && ( value = element.getAttribute( 'border' ) );
\r
819 this.setValue( value );
\r
822 commit : function( type, element, internalCommit )
\r
824 var value = parseInt( this.getValue(), 10 );
\r
825 if ( type == IMAGE || type == PREVIEW )
\r
827 if ( !isNaN( value ) )
\r
829 element.setStyle( 'border-width', CKEDITOR.tools.cssLength( value ) );
\r
830 element.setStyle( 'border-style', 'solid' );
\r
832 else if ( !value && this.isChanged() )
\r
834 element.removeStyle( 'border-width' );
\r
835 element.removeStyle( 'border-style' );
\r
836 element.removeStyle( 'border-color' );
\r
839 if ( !internalCommit && type == IMAGE )
\r
840 element.removeAttribute( 'border' );
\r
842 else if ( type == CLEANUP )
\r
844 element.removeAttribute( 'border' );
\r
845 element.removeStyle( 'border-width' );
\r
846 element.removeStyle( 'border-style' );
\r
847 element.removeStyle( 'border-color' );
\r
855 label : editor.lang.image.hSpace,
\r
857 onKeyUp : function()
\r
859 updatePreview( this.getDialog() );
\r
861 onChange : function()
\r
863 commitInternally.call( this, 'advanced:txtdlgGenStyle' );
\r
865 validate : CKEDITOR.dialog.validate.integer( editor.lang.image.validateHSpace ),
\r
866 setup : function( type, element )
\r
868 if ( type == IMAGE )
\r
873 marginLeftStyle = element.getStyle( 'margin-left' ),
\r
874 marginRightStyle = element.getStyle( 'margin-right' );
\r
876 marginLeftStyle = marginLeftStyle && marginLeftStyle.match( pxLengthRegex );
\r
877 marginRightStyle = marginRightStyle && marginRightStyle.match( pxLengthRegex );
\r
878 marginLeftPx = parseInt( marginLeftStyle, 10 );
\r
879 marginRightPx = parseInt( marginRightStyle, 10 );
\r
881 value = ( marginLeftPx == marginRightPx ) && marginLeftPx;
\r
882 isNaN( parseInt( value, 10 ) ) && ( value = element.getAttribute( 'hspace' ) );
\r
884 this.setValue( value );
\r
887 commit : function( type, element, internalCommit )
\r
889 var value = parseInt( this.getValue(), 10 );
\r
890 if ( type == IMAGE || type == PREVIEW )
\r
892 if ( !isNaN( value ) )
\r
894 element.setStyle( 'margin-left', CKEDITOR.tools.cssLength( value ) );
\r
895 element.setStyle( 'margin-right', CKEDITOR.tools.cssLength( value ) );
\r
897 else if ( !value && this.isChanged( ) )
\r
899 element.removeStyle( 'margin-left' );
\r
900 element.removeStyle( 'margin-right' );
\r
903 if ( !internalCommit && type == IMAGE )
\r
904 element.removeAttribute( 'hspace' );
\r
906 else if ( type == CLEANUP )
\r
908 element.removeAttribute( 'hspace' );
\r
909 element.removeStyle( 'margin-left' );
\r
910 element.removeStyle( 'margin-right' );
\r
918 label : editor.lang.image.vSpace,
\r
920 onKeyUp : function()
\r
922 updatePreview( this.getDialog() );
\r
924 onChange : function()
\r
926 commitInternally.call( this, 'advanced:txtdlgGenStyle' );
\r
928 validate : CKEDITOR.dialog.validate.integer( editor.lang.image.validateVSpace ),
\r
929 setup : function( type, element )
\r
931 if ( type == IMAGE )
\r
936 marginTopStyle = element.getStyle( 'margin-top' ),
\r
937 marginBottomStyle = element.getStyle( 'margin-bottom' );
\r
939 marginTopStyle = marginTopStyle && marginTopStyle.match( pxLengthRegex );
\r
940 marginBottomStyle = marginBottomStyle && marginBottomStyle.match( pxLengthRegex );
\r
941 marginTopPx = parseInt( marginTopStyle, 10 );
\r
942 marginBottomPx = parseInt( marginBottomStyle, 10 );
\r
944 value = ( marginTopPx == marginBottomPx ) && marginTopPx;
\r
945 isNaN ( parseInt( value, 10 ) ) && ( value = element.getAttribute( 'vspace' ) );
\r
946 this.setValue( value );
\r
949 commit : function( type, element, internalCommit )
\r
951 var value = parseInt( this.getValue(), 10 );
\r
952 if ( type == IMAGE || type == PREVIEW )
\r
954 if ( !isNaN( value ) )
\r
956 element.setStyle( 'margin-top', CKEDITOR.tools.cssLength( value ) );
\r
957 element.setStyle( 'margin-bottom', CKEDITOR.tools.cssLength( value ) );
\r
959 else if ( !value && this.isChanged( ) )
\r
961 element.removeStyle( 'margin-top' );
\r
962 element.removeStyle( 'margin-bottom' );
\r
965 if ( !internalCommit && type == IMAGE )
\r
966 element.removeAttribute( 'vspace' );
\r
968 else if ( type == CLEANUP )
\r
970 element.removeAttribute( 'vspace' );
\r
971 element.removeStyle( 'margin-top' );
\r
972 element.removeStyle( 'margin-bottom' );
\r
979 widths : [ '35%','65%' ],
\r
980 style : 'width:90px',
\r
981 label : editor.lang.common.align,
\r
985 [ editor.lang.common.notSet , ''],
\r
986 [ editor.lang.common.alignLeft , 'left'],
\r
987 [ editor.lang.common.alignRight , 'right']
\r
988 // Backward compatible with v2 on setup when specified as attribute value,
\r
989 // while these values are no more available as select options.
\r
990 // [ editor.lang.image.alignAbsBottom , 'absBottom'],
\r
991 // [ editor.lang.image.alignAbsMiddle , 'absMiddle'],
\r
992 // [ editor.lang.image.alignBaseline , 'baseline'],
\r
993 // [ editor.lang.image.alignTextTop , 'text-top'],
\r
994 // [ editor.lang.image.alignBottom , 'bottom'],
\r
995 // [ editor.lang.image.alignMiddle , 'middle'],
\r
996 // [ editor.lang.image.alignTop , 'top']
\r
998 onChange : function()
\r
1000 updatePreview( this.getDialog() );
\r
1001 commitInternally.call( this, 'advanced:txtdlgGenStyle' );
\r
1003 setup : function( type, element )
\r
1005 if ( type == IMAGE )
\r
1007 var value = element.getStyle( 'float' );
\r
1010 // Ignore those unrelated values.
\r
1016 !value && ( value = ( element.getAttribute( 'align' ) || '' ).toLowerCase() );
\r
1017 this.setValue( value );
\r
1020 commit : function( type, element, internalCommit )
\r
1022 var value = this.getValue();
\r
1023 if ( type == IMAGE || type == PREVIEW )
\r
1026 element.setStyle( 'float', value );
\r
1028 element.removeStyle( 'float' );
\r
1030 if ( !internalCommit && type == IMAGE )
\r
1032 value = ( element.getAttribute( 'align' ) || '' ).toLowerCase();
\r
1035 // we should remove it only if it matches "left" or "right",
\r
1036 // otherwise leave it intact.
\r
1039 element.removeAttribute( 'align' );
\r
1043 else if ( type == CLEANUP )
\r
1044 element.removeStyle( 'float' );
\r
1059 style : 'width:95%;',
\r
1060 html : '<div>' + CKEDITOR.tools.htmlEncode( editor.lang.common.preview ) +'<br>'+
\r
1061 '<div id="' + imagePreviewLoaderId + '" class="ImagePreviewLoader" style="display:none"><div class="loading"> </div></div>'+
\r
1062 '<div id="' + imagePreviewBoxId + '" class="ImagePreviewBox"><table><tr><td>'+
\r
1063 '<a href="javascript:void(0)" target="_blank" onclick="return false;" id="' + previewLinkId + '">'+
\r
1064 '<img id="' + previewImageId + '" alt="" /></a>' +
\r
1065 ( editor.config.image_previewText ||
\r
1066 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. '+
\r
1067 'Maecenas feugiat consequat diam. Maecenas metus. Vivamus diam purus, cursus a, commodo non, facilisis vitae, '+
\r
1068 '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
1069 '</td></tr></table></div></div>'
\r
1079 label : editor.lang.link.title,
\r
1086 label : editor.lang.common.url,
\r
1087 style : 'width: 100%',
\r
1089 setup : function( type, element )
\r
1091 if ( type == LINK )
\r
1093 var href = element.data( 'cke-saved-href' );
\r
1095 href = element.getAttribute( 'href' );
\r
1096 this.setValue( href );
\r
1099 commit : function( type, element )
\r
1101 if ( type == LINK )
\r
1103 if ( this.getValue() || this.isChanged() )
\r
1105 element.data( 'cke-saved-href', decodeURI( this.getValue() ) );
\r
1106 element.setAttribute( 'href', 'javascript:void(0)/*' +
\r
1107 CKEDITOR.tools.getNextNumber() + '*/' );
\r
1109 if ( this.getValue() || !editor.config.image_removeLinkByEmptyURL )
\r
1110 this.getDialog().addLink = true;
\r
1120 action : 'Browse',
\r
1121 target: 'Link:txtUrl',
\r
1122 url: editor.config.filebrowserImageBrowseLinkUrl
\r
1124 style : 'float:right',
\r
1126 label : editor.lang.common.browseServer
\r
1131 label : editor.lang.common.target,
\r
1135 [ editor.lang.common.notSet , ''],
\r
1136 [ editor.lang.common.targetNew , '_blank'],
\r
1137 [ editor.lang.common.targetTop , '_top'],
\r
1138 [ editor.lang.common.targetSelf , '_self'],
\r
1139 [ editor.lang.common.targetParent , '_parent']
\r
1141 setup : function( type, element )
\r
1143 if ( type == LINK )
\r
1144 this.setValue( element.getAttribute( 'target' ) || '' );
\r
1146 commit : function( type, element )
\r
1148 if ( type == LINK )
\r
1150 if ( this.getValue() || this.isChanged() )
\r
1151 element.setAttribute( 'target', this.getValue() );
\r
1160 filebrowser : 'uploadButton',
\r
1161 label : editor.lang.image.upload,
\r
1167 label : editor.lang.image.btnUpload,
\r
1168 style: 'height:40px',
\r
1172 type : 'fileButton',
\r
1173 id : 'uploadButton',
\r
1174 filebrowser : 'info:txtUrl',
\r
1175 label : editor.lang.image.btnUpload,
\r
1176 'for' : [ 'Upload', 'upload' ]
\r
1182 label : editor.lang.common.advancedTab,
\r
1187 widths : [ '50%', '25%', '25%' ],
\r
1193 label : editor.lang.common.id,
\r
1194 setup : function( type, element )
\r
1196 if ( type == IMAGE )
\r
1197 this.setValue( element.getAttribute( 'id' ) );
\r
1199 commit : function( type, element )
\r
1201 if ( type == IMAGE )
\r
1203 if ( this.getValue() || this.isChanged() )
\r
1204 element.setAttribute( 'id', this.getValue() );
\r
1209 id : 'cmbLangDir',
\r
1211 style : 'width : 100px;',
\r
1212 label : editor.lang.common.langDir,
\r
1216 [ editor.lang.common.notSet, '' ],
\r
1217 [ editor.lang.common.langDirLtr, 'ltr' ],
\r
1218 [ editor.lang.common.langDirRtl, 'rtl' ]
\r
1220 setup : function( type, element )
\r
1222 if ( type == IMAGE )
\r
1223 this.setValue( element.getAttribute( 'dir' ) );
\r
1225 commit : function( type, element )
\r
1227 if ( type == IMAGE )
\r
1229 if ( this.getValue() || this.isChanged() )
\r
1230 element.setAttribute( 'dir', this.getValue() );
\r
1236 id : 'txtLangCode',
\r
1237 label : editor.lang.common.langCode,
\r
1239 setup : function( type, element )
\r
1241 if ( type == IMAGE )
\r
1242 this.setValue( element.getAttribute( 'lang' ) );
\r
1244 commit : function( type, element )
\r
1246 if ( type == IMAGE )
\r
1248 if ( this.getValue() || this.isChanged() )
\r
1249 element.setAttribute( 'lang', this.getValue() );
\r
1257 id : 'txtGenLongDescr',
\r
1258 label : editor.lang.common.longDescr,
\r
1259 setup : function( type, element )
\r
1261 if ( type == IMAGE )
\r
1262 this.setValue( element.getAttribute( 'longDesc' ) );
\r
1264 commit : function( type, element )
\r
1266 if ( type == IMAGE )
\r
1268 if ( this.getValue() || this.isChanged() )
\r
1269 element.setAttribute( 'longDesc', this.getValue() );
\r
1275 widths : [ '50%', '50%' ],
\r
1280 id : 'txtGenClass',
\r
1281 label : editor.lang.common.cssClass,
\r
1283 setup : function( type, element )
\r
1285 if ( type == IMAGE )
\r
1286 this.setValue( element.getAttribute( 'class' ) );
\r
1288 commit : function( type, element )
\r
1290 if ( type == IMAGE )
\r
1292 if ( this.getValue() || this.isChanged() )
\r
1293 element.setAttribute( 'class', this.getValue() );
\r
1299 id : 'txtGenTitle',
\r
1300 label : editor.lang.common.advisoryTitle,
\r
1302 onChange : function()
\r
1304 updatePreview( this.getDialog() );
\r
1306 setup : function( type, element )
\r
1308 if ( type == IMAGE )
\r
1309 this.setValue( element.getAttribute( 'title' ) );
\r
1311 commit : function( type, element )
\r
1313 if ( type == IMAGE )
\r
1315 if ( this.getValue() || this.isChanged() )
\r
1316 element.setAttribute( 'title', this.getValue() );
\r
1318 else if ( type == PREVIEW )
\r
1320 element.setAttribute( 'title', this.getValue() );
\r
1322 else if ( type == CLEANUP )
\r
1324 element.removeAttribute( 'title' );
\r
1332 id : 'txtdlgGenStyle',
\r
1333 label : editor.lang.common.cssStyle,
\r
1335 setup : function( type, element )
\r
1337 if ( type == IMAGE )
\r
1339 var genStyle = element.getAttribute( 'style' );
\r
1340 if ( !genStyle && element.$.style.cssText )
\r
1341 genStyle = element.$.style.cssText;
\r
1342 this.setValue( genStyle );
\r
1344 var height = element.$.style.height,
\r
1345 width = element.$.style.width,
\r
1346 aMatchH = ( height ? height : '' ).match( regexGetSize ),
\r
1347 aMatchW = ( width ? width : '').match( regexGetSize );
\r
1349 this.attributesInStyle =
\r
1351 height : !!aMatchH,
\r
1356 onChange : function ()
\r
1358 commitInternally.call( this,
\r
1359 [ 'info:cmbFloat', 'info:cmbAlign',
\r
1360 'info:txtVSpace', 'info:txtHSpace',
\r
1362 'info:txtWidth', 'info:txtHeight' ] );
\r
1363 updatePreview( this );
\r
1365 commit : function( type, element )
\r
1367 if ( type == IMAGE && ( this.getValue() || this.isChanged() ) )
\r
1369 element.setAttribute( 'style', this.getValue() );
\r
1379 CKEDITOR.dialog.add( 'image', function( editor )
\r
1381 return imageDialog( editor, 'image' );
\r
1384 CKEDITOR.dialog.add( 'imagebutton', function( editor )
\r
1386 return imageDialog( editor, 'imagebutton' );
\r