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 // Load image preview.
\r
13 regexGetSize = /^\s*(\d+)((px)|\%)?\s*$/i,
\r
14 regexGetSizeOrEmpty = /(^\s*(\d+)((px)|\%)?\s*$)|^$/i,
\r
15 pxLengthRegex = /^\d+px$/;
\r
17 var onSizeChange = function()
\r
19 var value = this.getValue(), // This = input element.
\r
20 dialog = this.getDialog(),
\r
21 aMatch = value.match( regexGetSize ); // Check value
\r
24 if ( aMatch[2] == '%' ) // % is allowed - > unlock ratio.
\r
25 switchLockRatio( dialog, false ); // Unlock.
\r
29 // Only if ratio is locked
\r
30 if ( dialog.lockRatio )
\r
32 var oImageOriginal = dialog.originalElement;
\r
33 if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' )
\r
35 if ( this.id == 'txtHeight' )
\r
37 if ( value && value != '0' )
\r
38 value = Math.round( oImageOriginal.$.width * ( value / oImageOriginal.$.height ) );
\r
39 if ( !isNaN( value ) )
\r
40 dialog.setValueOf( 'info', 'txtWidth', value );
\r
42 else //this.id = txtWidth.
\r
44 if ( value && value != '0' )
\r
45 value = Math.round( oImageOriginal.$.height * ( value / oImageOriginal.$.width ) );
\r
46 if ( !isNaN( value ) )
\r
47 dialog.setValueOf( 'info', 'txtHeight', value );
\r
51 updatePreview( dialog );
\r
54 var updatePreview = function( dialog )
\r
56 //Don't load before onShow.
\r
57 if ( !dialog.originalElement || !dialog.preview )
\r
60 // Read attributes and update imagePreview;
\r
61 dialog.commitContent( PREVIEW, dialog.preview );
\r
65 // Custom commit dialog logic, where we're intended to give inline style
\r
66 // field (txtdlgGenStyle) higher priority to avoid overwriting styles contribute
\r
68 function commitContent()
\r
70 var args = arguments;
\r
71 var inlineStyleField = this.getContentElement( 'advanced', 'txtdlgGenStyle' );
\r
72 inlineStyleField && inlineStyleField.commit.apply( inlineStyleField, args );
\r
74 this.foreach( function( widget )
\r
76 if ( widget.commit && widget.id != 'txtdlgGenStyle' )
\r
77 widget.commit.apply( widget, args );
\r
81 // Avoid recursions.
\r
84 // Synchronous field values to other impacted fields is required, e.g. border
\r
85 // size change should alter inline-style text as well.
\r
86 function commitInternally( targetFields )
\r
93 var dialog = this.getDialog(),
\r
94 element = dialog.imageElement;
\r
97 // Commit this field and broadcast to target fields.
\r
98 this.commit( IMAGE, element );
\r
100 targetFields = [].concat( targetFields );
\r
101 var length = targetFields.length,
\r
103 for ( var i = 0; i < length; i++ )
\r
105 field = dialog.getContentElement.apply( dialog, targetFields[ i ].split( ':' ) );
\r
106 // May cause recursion.
\r
107 field && field.setup( IMAGE, element );
\r
114 var switchLockRatio = function( dialog, value )
\r
116 var oImageOriginal = dialog.originalElement,
\r
117 ratioButton = CKEDITOR.document.getById( 'btnLockSizes' );
\r
119 if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' )
\r
121 if ( value == 'check' ) // Check image ratio and original image ratio.
\r
123 var width = dialog.getValueOf( 'info', 'txtWidth' ),
\r
124 height = dialog.getValueOf( 'info', 'txtHeight' ),
\r
125 originalRatio = oImageOriginal.$.width * 1000 / oImageOriginal.$.height,
\r
126 thisRatio = width * 1000 / height;
\r
127 dialog.lockRatio = false; // Default: unlock ratio
\r
129 if ( !width && !height )
\r
130 dialog.lockRatio = true;
\r
131 else if ( !isNaN( originalRatio ) && !isNaN( thisRatio ) )
\r
133 if ( Math.round( originalRatio ) == Math.round( thisRatio ) )
\r
134 dialog.lockRatio = true;
\r
137 else if ( value != undefined )
\r
138 dialog.lockRatio = value;
\r
140 dialog.lockRatio = !dialog.lockRatio;
\r
142 else if ( value != 'check' ) // I can't lock ratio if ratio is unknown.
\r
143 dialog.lockRatio = false;
\r
145 if ( dialog.lockRatio )
\r
146 ratioButton.removeClass( 'cke_btn_unlocked' );
\r
148 ratioButton.addClass( 'cke_btn_unlocked' );
\r
150 var lang = dialog._.editor.lang.image,
\r
151 label = lang[ dialog.lockRatio ? 'unlockRatio' : 'lockRatio' ];
\r
153 ratioButton.setAttribute( 'title', label );
\r
154 ratioButton.getFirst().setText( label );
\r
156 return dialog.lockRatio;
\r
159 var resetSize = function( dialog )
\r
161 var oImageOriginal = dialog.originalElement;
\r
162 if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' )
\r
164 dialog.setValueOf( 'info', 'txtWidth', oImageOriginal.$.width );
\r
165 dialog.setValueOf( 'info', 'txtHeight', oImageOriginal.$.height );
\r
167 updatePreview( dialog );
\r
170 var setupDimension = function( type, element )
\r
172 if ( type != IMAGE )
\r
175 function checkDimension( size, defaultValue )
\r
177 var aMatch = size.match( regexGetSize );
\r
180 if ( aMatch[2] == '%' ) // % is allowed.
\r
183 switchLockRatio( dialog, false ); // Unlock ratio
\r
187 return defaultValue;
\r
190 var dialog = this.getDialog(),
\r
192 dimension = (( this.id == 'txtWidth' )? 'width' : 'height' ),
\r
193 size = element.getAttribute( dimension );
\r
196 value = checkDimension( size, value );
\r
197 value = checkDimension( element.getStyle( dimension ), value );
\r
199 this.setValue( value );
\r
202 var imageDialog = function( editor, dialogType )
\r
204 var previewPreloader;
\r
206 var onImgLoadEvent = function()
\r
209 var original = this.originalElement;
\r
210 original.setCustomData( 'isReady', 'true' );
\r
211 original.removeListener( 'load', onImgLoadEvent );
\r
212 original.removeListener( 'error', onImgLoadErrorEvent );
\r
213 original.removeListener( 'abort', onImgLoadErrorEvent );
\r
216 CKEDITOR.document.getById( 'ImagePreviewLoader' ).setStyle( 'display', 'none' );
\r
218 // New image -> new domensions
\r
219 if ( !this.dontResetSize )
\r
222 if ( this.firstLoad )
\r
223 CKEDITOR.tools.setTimeout( function(){ switchLockRatio( this, 'check' ); }, 0, this );
\r
225 this.firstLoad = false;
\r
226 this.dontResetSize = false;
\r
229 var onImgLoadErrorEvent = function()
\r
231 // Error. Image is not loaded.
\r
232 var original = this.originalElement;
\r
233 original.removeListener( 'load', onImgLoadEvent );
\r
234 original.removeListener( 'error', onImgLoadErrorEvent );
\r
235 original.removeListener( 'abort', onImgLoadErrorEvent );
\r
237 // Set Error image.
\r
238 var noimage = CKEDITOR.getUrl( editor.skinPath + 'images/noimage.png' );
\r
240 if ( this.preview )
\r
241 this.preview.setAttribute( 'src', noimage );
\r
244 CKEDITOR.document.getById( 'ImagePreviewLoader' ).setStyle( 'display', 'none' );
\r
245 switchLockRatio( this, false ); // Unlock.
\r
248 title : ( dialogType == 'image' ) ? editor.lang.image.title : editor.lang.image.titleButton,
\r
251 onShow : function()
\r
253 this.imageElement = false;
\r
254 this.linkElement = false;
\r
256 // Default: create a new element.
\r
257 this.imageEditMode = false;
\r
258 this.linkEditMode = false;
\r
260 this.lockRatio = true;
\r
261 this.dontResetSize = false;
\r
262 this.firstLoad = true;
\r
263 this.addLink = false;
\r
265 var editor = this.getParentEditor(),
\r
266 sel = this.getParentEditor().getSelection(),
\r
267 element = sel.getSelectedElement(),
\r
268 link = element && element.getAscendant( 'a' );
\r
271 CKEDITOR.document.getById( 'ImagePreviewLoader' ).setStyle( 'display', 'none' );
\r
272 // Create the preview before setup the dialog contents.
\r
273 previewPreloader = new CKEDITOR.dom.element( 'img', editor.document );
\r
274 this.preview = CKEDITOR.document.getById( 'previewImage' );
\r
276 // Copy of the image
\r
277 this.originalElement = editor.document.createElement( 'img' );
\r
278 this.originalElement.setAttribute( 'alt', '' );
\r
279 this.originalElement.setCustomData( 'isReady', 'false' );
\r
283 this.linkElement = link;
\r
284 this.linkEditMode = true;
\r
286 // Look for Image element.
\r
287 var linkChildren = link.getChildren();
\r
288 if ( linkChildren.count() == 1 ) // 1 child.
\r
290 var childTagName = linkChildren.getItem( 0 ).getName();
\r
291 if ( childTagName == 'img' || childTagName == 'input' )
\r
293 this.imageElement = linkChildren.getItem( 0 );
\r
294 if ( this.imageElement.getName() == 'img' )
\r
295 this.imageEditMode = 'img';
\r
296 else if ( this.imageElement.getName() == 'input' )
\r
297 this.imageEditMode = 'input';
\r
300 // Fill out all fields.
\r
301 if ( dialogType == 'image' )
\r
302 this.setupContent( LINK, link );
\r
305 if ( element && element.getName() == 'img' && !element.getAttribute( '_cke_realelement' )
\r
306 || element && element.getName() == 'input' && element.getAttribute( 'type' ) == 'image' )
\r
308 this.imageEditMode = element.getName();
\r
309 this.imageElement = element;
\r
312 if ( this.imageEditMode )
\r
314 // Use the original element as a buffer from since we don't want
\r
315 // temporary changes to be committed, e.g. if the dialog is canceled.
\r
316 this.cleanImageElement = this.imageElement;
\r
317 this.imageElement = this.cleanImageElement.clone( true, true );
\r
319 // Fill out all fields.
\r
320 this.setupContent( IMAGE, this.imageElement );
\r
322 // Refresh LockRatio button
\r
323 switchLockRatio ( this, true );
\r
326 this.imageElement = editor.document.createElement( 'img' );
\r
328 // Dont show preview if no URL given.
\r
329 if ( !CKEDITOR.tools.trim( this.getValueOf( 'info', 'txtUrl' ) ) )
\r
331 this.preview.removeAttribute( 'src' );
\r
332 this.preview.setStyle( 'display', 'none' );
\r
337 // Edit existing Image.
\r
338 if ( this.imageEditMode )
\r
340 var imgTagName = this.imageEditMode;
\r
342 // Image dialog and Input element.
\r
343 if ( dialogType == 'image' && imgTagName == 'input' && confirm( editor.lang.image.button2Img ) )
\r
345 // Replace INPUT-> IMG
\r
346 imgTagName = 'img';
\r
347 this.imageElement = editor.document.createElement( 'img' );
\r
348 this.imageElement.setAttribute( 'alt', '' );
\r
349 editor.insertElement( this.imageElement );
\r
351 // ImageButton dialog and Image element.
\r
352 else if ( dialogType != 'image' && imgTagName == 'img' && confirm( editor.lang.image.img2Button ))
\r
354 // Replace IMG -> INPUT
\r
355 imgTagName = 'input';
\r
356 this.imageElement = editor.document.createElement( 'input' );
\r
357 this.imageElement.setAttributes(
\r
363 editor.insertElement( this.imageElement );
\r
367 // Restore the original element before all commits.
\r
368 this.imageElement = this.cleanImageElement;
\r
369 delete this.cleanImageElement;
\r
372 else // Create a new image.
\r
374 // Image dialog -> create IMG element.
\r
375 if ( dialogType == 'image' )
\r
376 this.imageElement = editor.document.createElement( 'img' );
\r
379 this.imageElement = editor.document.createElement( 'input' );
\r
380 this.imageElement.setAttribute ( 'type' ,'image' );
\r
382 this.imageElement.setAttribute( 'alt', '' );
\r
385 // Create a new link.
\r
386 if ( !this.linkEditMode )
\r
387 this.linkElement = editor.document.createElement( 'a' );
\r
390 this.commitContent( IMAGE, this.imageElement );
\r
391 this.commitContent( LINK, this.linkElement );
\r
393 // Remove empty style attribute.
\r
394 if ( !this.imageElement.getAttribute( 'style' ) )
\r
395 this.imageElement.removeAttribute( 'style' );
\r
397 // Insert a new Image.
\r
398 if ( !this.imageEditMode )
\r
400 if ( this.addLink )
\r
402 //Insert a new Link.
\r
403 if ( !this.linkEditMode )
\r
405 editor.insertElement(this.linkElement);
\r
406 this.linkElement.append(this.imageElement, false);
\r
408 else //Link already exists, image not.
\r
409 editor.insertElement(this.imageElement );
\r
412 editor.insertElement( this.imageElement );
\r
414 else // Image already exists.
\r
416 //Add a new link element.
\r
417 if ( !this.linkEditMode && this.addLink )
\r
419 editor.insertElement( this.linkElement );
\r
420 this.imageElement.appendTo( this.linkElement );
\r
422 //Remove Link, Image exists.
\r
423 else if ( this.linkEditMode && !this.addLink )
\r
425 editor.getSelection().selectElement( this.linkElement );
\r
426 editor.insertElement( this.imageElement );
\r
430 onLoad : function()
\r
432 if ( dialogType != 'image' )
\r
433 this.hidePage( 'Link' ); //Hide Link tab.
\r
434 var doc = this._.element.getDocument();
\r
435 this.addFocusable( doc.getById( 'btnResetSize' ), 5 );
\r
436 this.addFocusable( doc.getById( 'btnLockSizes' ), 5 );
\r
438 this.commitContent = commitContent;
\r
440 onHide : function()
\r
442 if ( this.preview )
\r
443 this.commitContent( CLEANUP, this.preview );
\r
445 if ( this.originalElement )
\r
447 this.originalElement.removeListener( 'load', onImgLoadEvent );
\r
448 this.originalElement.removeListener( 'error', onImgLoadErrorEvent );
\r
449 this.originalElement.removeListener( 'abort', onImgLoadErrorEvent );
\r
450 this.originalElement.remove();
\r
451 this.originalElement = false; // Dialog is closed.
\r
454 delete this.imageElement;
\r
459 label : editor.lang.image.infoTab,
\r
470 widths : [ '280px', '110px' ],
\r
477 label : editor.lang.common.url,
\r
479 onChange : function()
\r
481 var dialog = this.getDialog(),
\r
482 newUrl = this.getValue();
\r
484 //Update original image
\r
485 if ( newUrl.length > 0 ) //Prevent from load before onShow
\r
487 dialog = this.getDialog();
\r
488 var original = dialog.originalElement;
\r
490 dialog.preview.removeStyle( 'display' );
\r
492 original.setCustomData( 'isReady', 'false' );
\r
494 var loader = CKEDITOR.document.getById( 'ImagePreviewLoader' );
\r
496 loader.setStyle( 'display', '' );
\r
498 original.on( 'load', onImgLoadEvent, dialog );
\r
499 original.on( 'error', onImgLoadErrorEvent, dialog );
\r
500 original.on( 'abort', onImgLoadErrorEvent, dialog );
\r
501 original.setAttribute( 'src', newUrl );
\r
503 // Query the preloader to figure out the url impacted by based href.
\r
504 previewPreloader.setAttribute( 'src', newUrl );
\r
505 dialog.preview.setAttribute( 'src', previewPreloader.$.src );
\r
506 updatePreview( dialog );
\r
508 // Dont show preview if no URL given.
\r
509 else if ( dialog.preview )
\r
511 dialog.preview.removeAttribute( 'src' );
\r
512 dialog.preview.setStyle( 'display', 'none' );
\r
515 setup : function( type, element )
\r
517 if ( type == IMAGE )
\r
519 var url = element.getAttribute( '_cke_saved_src' ) || element.getAttribute( 'src' );
\r
522 this.getDialog().dontResetSize = true;
\r
524 field.setValue( url ); // And call this.onChange()
\r
525 // Manually set the initial value.(#4191)
\r
526 field.setInitValue();
\r
530 commit : function( type, element )
\r
532 if ( type == IMAGE && ( this.getValue() || this.isChanged() ) )
\r
534 element.setAttribute( '_cke_saved_src', decodeURI( this.getValue() ) );
\r
535 element.setAttribute( 'src', decodeURI( this.getValue() ) );
\r
537 else if ( type == CLEANUP )
\r
539 element.setAttribute( 'src', '' ); // If removeAttribute doesn't work.
\r
540 element.removeAttribute( 'src' );
\r
543 validate : CKEDITOR.dialog.validate.notEmpty( editor.lang.image.urlMissing )
\r
548 // v-align with the 'txtUrl' field.
\r
549 // TODO: We need something better than a fixed size here.
\r
550 style : 'display:inline-block;margin-top:10px;',
\r
552 label : editor.lang.common.browseServer,
\r
554 filebrowser : 'info:txtUrl'
\r
563 label : editor.lang.image.alt,
\r
566 onChange : function()
\r
568 updatePreview( this.getDialog() );
\r
570 setup : function( type, element )
\r
572 if ( type == IMAGE )
\r
573 this.setValue( element.getAttribute( 'alt' ) );
\r
575 commit : function( type, element )
\r
577 if ( type == IMAGE )
\r
579 if ( this.getValue() || this.isChanged() )
\r
580 element.setAttribute( 'alt', this.getValue() );
\r
582 else if ( type == PREVIEW )
\r
584 element.setAttribute( 'alt', this.getValue() );
\r
586 else if ( type == CLEANUP )
\r
588 element.removeAttribute( 'alt' );
\r
594 widths : [ '140px', '240px' ],
\r
604 widths : [ '70%', '30%' ],
\r
616 labelLayout : 'horizontal',
\r
617 label : editor.lang.image.width,
\r
618 onKeyUp : onSizeChange,
\r
619 onChange : function()
\r
621 commitInternally.call( this, 'advanced:txtdlgGenStyle' );
\r
623 validate : function()
\r
625 var aMatch = this.getValue().match( regexGetSizeOrEmpty );
\r
627 alert( editor.lang.image.validateWidth );
\r
630 setup : setupDimension,
\r
631 commit : function( type, element, internalCommit )
\r
633 var value = this.getValue();
\r
634 if ( type == IMAGE )
\r
637 element.setStyle( 'width', CKEDITOR.tools.cssLength( value ) );
\r
638 else if ( !value && this.isChanged( ) )
\r
639 element.removeStyle( 'width' );
\r
641 !internalCommit && element.removeAttribute( 'width' );
\r
643 else if ( type == PREVIEW )
\r
645 var aMatch = value.match( regexGetSize );
\r
648 var oImageOriginal = this.getDialog().originalElement;
\r
649 if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' )
\r
650 element.setStyle( 'width', oImageOriginal.$.width + 'px');
\r
653 element.setStyle( 'width', value + 'px');
\r
655 else if ( type == CLEANUP )
\r
657 element.removeAttribute( 'width' );
\r
658 element.removeStyle( 'width' );
\r
666 labelLayout : 'horizontal',
\r
667 label : editor.lang.image.height,
\r
668 onKeyUp : onSizeChange,
\r
669 onChange : function()
\r
671 commitInternally.call( this, 'advanced:txtdlgGenStyle' );
\r
673 validate : function()
\r
675 var aMatch = this.getValue().match( regexGetSizeOrEmpty );
\r
677 alert( editor.lang.image.validateHeight );
\r
680 setup : setupDimension,
\r
681 commit : function( type, element, internalCommit )
\r
683 var value = this.getValue();
\r
684 if ( type == IMAGE )
\r
687 element.setStyle( 'height', CKEDITOR.tools.cssLength( value ) );
\r
688 else if ( !value && this.isChanged( ) )
\r
689 element.removeStyle( 'height' );
\r
691 if ( !internalCommit && type == IMAGE )
\r
692 element.removeAttribute( 'height' );
\r
694 else if ( type == PREVIEW )
\r
696 var aMatch = value.match( regexGetSize );
\r
699 var oImageOriginal = this.getDialog().originalElement;
\r
700 if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' )
\r
701 element.setStyle( 'height', oImageOriginal.$.height + 'px' );
\r
704 element.setStyle( 'height', value + 'px' );
\r
706 else if ( type == CLEANUP )
\r
708 element.removeAttribute( 'height' );
\r
709 element.removeStyle( 'height' );
\r
717 style : 'margin-top:10px;width:40px;height:40px;',
\r
718 onLoad : function()
\r
720 // Activate Reset button
\r
721 var resetButton = CKEDITOR.document.getById( 'btnResetSize' ),
\r
722 ratioButton = CKEDITOR.document.getById( 'btnLockSizes' );
\r
725 resetButton.on( 'click', function(evt)
\r
728 evt.data.preventDefault();
\r
729 }, this.getDialog() );
\r
730 resetButton.on( 'mouseover', function()
\r
732 this.addClass( 'cke_btn_over' );
\r
734 resetButton.on( 'mouseout', function()
\r
736 this.removeClass( 'cke_btn_over' );
\r
739 // Activate (Un)LockRatio button
\r
742 ratioButton.on( 'click', function(evt)
\r
744 var locked = switchLockRatio( this ),
\r
745 oImageOriginal = this.originalElement,
\r
746 width = this.getValueOf( 'info', 'txtWidth' );
\r
748 if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' && width )
\r
750 var height = oImageOriginal.$.height / oImageOriginal.$.width * width;
\r
751 if ( !isNaN( height ) )
\r
753 this.setValueOf( 'info', 'txtHeight', Math.round( height ) );
\r
754 updatePreview( this );
\r
757 evt.data.preventDefault();
\r
758 }, this.getDialog() );
\r
759 ratioButton.on( 'mouseover', function()
\r
761 this.addClass( 'cke_btn_over' );
\r
763 ratioButton.on( 'mouseout', function()
\r
765 this.removeClass( 'cke_btn_over' );
\r
770 '<a href="javascript:void(0)" tabindex="-1" title="' + editor.lang.image.unlockRatio +
\r
771 '" class="cke_btn_locked" id="btnLockSizes" role="button"><span class="cke_label">' + editor.lang.image.unlockRatio + '</span></a>' +
\r
772 '<a href="javascript:void(0)" tabindex="-1" title="' + editor.lang.image.resetSize +
\r
773 '" class="cke_btn_reset" id="btnResetSize" role="button"><span class="cke_label">' + editor.lang.image.resetSize + '</span></a>'+
\r
787 labelLayout : 'horizontal',
\r
788 label : editor.lang.image.border,
\r
790 onKeyUp : function()
\r
792 updatePreview( this.getDialog() );
\r
794 onChange : function()
\r
796 commitInternally.call( this, 'advanced:txtdlgGenStyle' );
\r
798 validate : CKEDITOR.dialog.validate.integer( editor.lang.image.validateBorder ),
\r
799 setup : function( type, element )
\r
801 if ( type == IMAGE )
\r
804 borderStyle = element.getStyle( 'border-width' );
\r
805 borderStyle = borderStyle && borderStyle.match( /^(\d+px)(?: \1 \1 \1)?$/ );
\r
806 value = borderStyle && parseInt( borderStyle[ 1 ], 10 );
\r
807 isNaN ( parseInt( value, 10 ) ) && ( value = element.getAttribute( 'border' ) );
\r
808 this.setValue( value );
\r
811 commit : function( type, element, internalCommit )
\r
813 var value = parseInt( this.getValue(), 10 );
\r
814 if ( type == IMAGE || type == PREVIEW )
\r
816 if ( !isNaN( value ) )
\r
818 element.setStyle( 'border-width', CKEDITOR.tools.cssLength( value ) );
\r
819 element.setStyle( 'border-style', 'solid' );
\r
821 else if ( !value && this.isChanged() )
\r
823 element.removeStyle( 'border-width' );
\r
824 element.removeStyle( 'border-style' );
\r
825 element.removeStyle( 'border-color' );
\r
828 if ( !internalCommit && type == IMAGE )
\r
829 element.removeAttribute( 'border' );
\r
831 else if ( type == CLEANUP )
\r
833 element.removeAttribute( 'border' );
\r
834 element.removeStyle( 'border-width' );
\r
835 element.removeStyle( 'border-style' );
\r
836 element.removeStyle( 'border-color' );
\r
844 labelLayout : 'horizontal',
\r
845 label : editor.lang.image.hSpace,
\r
847 onKeyUp : function()
\r
849 updatePreview( this.getDialog() );
\r
851 onChange : function()
\r
853 commitInternally.call( this, 'advanced:txtdlgGenStyle' );
\r
855 validate : CKEDITOR.dialog.validate.integer( editor.lang.image.validateHSpace ),
\r
856 setup : function( type, element )
\r
858 if ( type == IMAGE )
\r
863 marginLeftStyle = element.getStyle( 'margin-left' ),
\r
864 marginRightStyle = element.getStyle( 'margin-right' );
\r
866 marginLeftStyle = marginLeftStyle && marginLeftStyle.match( pxLengthRegex );
\r
867 marginRightStyle = marginRightStyle && marginRightStyle.match( pxLengthRegex );
\r
868 marginLeftPx = parseInt( marginLeftStyle, 10 );
\r
869 marginRightPx = parseInt( marginRightStyle, 10 );
\r
871 value = ( marginLeftPx == marginRightPx ) && marginLeftPx;
\r
872 isNaN( parseInt( value, 10 ) ) && ( value = element.getAttribute( 'hspace' ) );
\r
874 this.setValue( value );
\r
877 commit : function( type, element, internalCommit )
\r
879 var value = parseInt( this.getValue(), 10 );
\r
880 if ( type == IMAGE || type == PREVIEW )
\r
882 if ( !isNaN( value ) )
\r
884 element.setStyle( 'margin-left', CKEDITOR.tools.cssLength( value ) );
\r
885 element.setStyle( 'margin-right', CKEDITOR.tools.cssLength( value ) );
\r
887 else if ( !value && this.isChanged( ) )
\r
889 element.removeStyle( 'margin-left' );
\r
890 element.removeStyle( 'margin-right' );
\r
893 if ( !internalCommit && type == IMAGE )
\r
894 element.removeAttribute( 'hspace' );
\r
896 else if ( type == CLEANUP )
\r
898 element.removeAttribute( 'hspace' );
\r
899 element.removeStyle( 'margin-left' );
\r
900 element.removeStyle( 'margin-right' );
\r
908 labelLayout : 'horizontal',
\r
909 label : editor.lang.image.vSpace,
\r
911 onKeyUp : function()
\r
913 updatePreview( this.getDialog() );
\r
915 onChange : function()
\r
917 commitInternally.call( this, 'advanced:txtdlgGenStyle' );
\r
919 validate : CKEDITOR.dialog.validate.integer( editor.lang.image.validateVSpace ),
\r
920 setup : function( type, element )
\r
922 if ( type == IMAGE )
\r
927 marginTopStyle = element.getStyle( 'margin-top' ),
\r
928 marginBottomStyle = element.getStyle( 'margin-bottom' );
\r
930 marginTopStyle = marginTopStyle && marginTopStyle.match( pxLengthRegex );
\r
931 marginBottomStyle = marginBottomStyle && marginBottomStyle.match( pxLengthRegex );
\r
932 marginTopPx = parseInt( marginTopStyle, 10 );
\r
933 marginBottomPx = parseInt( marginBottomStyle, 10 );
\r
935 value = ( marginTopPx == marginBottomPx ) && marginTopPx;
\r
936 isNaN ( parseInt( value, 10 ) ) && ( value = element.getAttribute( 'vspace' ) );
\r
937 this.setValue( value );
\r
940 commit : function( type, element, internalCommit )
\r
942 var value = parseInt( this.getValue(), 10 );
\r
943 if ( type == IMAGE || type == PREVIEW )
\r
945 if ( !isNaN( value ) )
\r
947 element.setStyle( 'margin-top', CKEDITOR.tools.cssLength( value ) );
\r
948 element.setStyle( 'margin-bottom', CKEDITOR.tools.cssLength( value ) );
\r
950 else if ( !value && this.isChanged( ) )
\r
952 element.removeStyle( 'margin-top' );
\r
953 element.removeStyle( 'margin-bottom' );
\r
956 if ( !internalCommit && type == IMAGE )
\r
957 element.removeAttribute( 'vspace' );
\r
959 else if ( type == CLEANUP )
\r
961 element.removeAttribute( 'vspace' );
\r
962 element.removeStyle( 'margin-top' );
\r
963 element.removeStyle( 'margin-bottom' );
\r
970 labelLayout : 'horizontal',
\r
971 widths : [ '35%','65%' ],
\r
972 style : 'width:90px',
\r
973 label : editor.lang.image.align,
\r
977 [ editor.lang.common.notSet , ''],
\r
978 [ editor.lang.image.alignLeft , 'left'],
\r
979 [ editor.lang.image.alignRight , 'right']
\r
980 // Backward compatible with v2 on setup when specified as attribute value,
\r
981 // while these values are no more available as select options.
\r
982 // [ editor.lang.image.alignAbsBottom , 'absBottom'],
\r
983 // [ editor.lang.image.alignAbsMiddle , 'absMiddle'],
\r
984 // [ editor.lang.image.alignBaseline , 'baseline'],
\r
985 // [ editor.lang.image.alignTextTop , 'text-top'],
\r
986 // [ editor.lang.image.alignBottom , 'bottom'],
\r
987 // [ editor.lang.image.alignMiddle , 'middle'],
\r
988 // [ editor.lang.image.alignTop , 'top']
\r
990 onChange : function()
\r
992 updatePreview( this.getDialog() );
\r
993 commitInternally.call( this, 'advanced:txtdlgGenStyle' );
\r
995 setup : function( type, element )
\r
997 if ( type == IMAGE )
\r
999 var value = element.getStyle( 'float' );
\r
1002 // Ignore those unrelated values.
\r
1008 !value && ( value = ( element.getAttribute( 'align' ) || '' ).toLowerCase() );
\r
1009 this.setValue( value );
\r
1012 commit : function( type, element, internalCommit )
\r
1014 var value = this.getValue();
\r
1015 if ( type == IMAGE || type == PREVIEW )
\r
1018 element.setStyle( 'float', value );
\r
1020 element.removeStyle( 'float' );
\r
1022 if ( !internalCommit && type == IMAGE )
\r
1024 value = ( element.getAttribute( 'align' ) || '' ).toLowerCase();
\r
1027 // we should remove it only if it matches "left" or "right",
\r
1028 // otherwise leave it intact.
\r
1031 element.removeAttribute( 'align' );
\r
1035 else if ( type == CLEANUP )
\r
1036 element.removeStyle( 'float' );
\r
1051 style : 'width:95%;',
\r
1052 html : '<div>' + CKEDITOR.tools.htmlEncode( editor.lang.common.preview ) +'<br>'+
\r
1053 '<div id="ImagePreviewLoader" style="display:none"><div class="loading"> </div></div>'+
\r
1054 '<div id="ImagePreviewBox">'+
\r
1055 '<a href="javascript:void(0)" target="_blank" onclick="return false;" id="previewLink">'+
\r
1056 '<img id="previewImage" alt="" /></a>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. '+
\r
1057 'Maecenas feugiat consequat diam. Maecenas metus. Vivamus diam purus, cursus a, commodo non, facilisis vitae, '+
\r
1058 '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 label : editor.lang.link.title,
\r
1076 label : editor.lang.common.url,
\r
1077 style : 'width: 100%',
\r
1079 setup : function( type, element )
\r
1081 if ( type == LINK )
\r
1083 var href = element.getAttribute( '_cke_saved_href' );
\r
1085 href = element.getAttribute( 'href' );
\r
1086 this.setValue( href );
\r
1089 commit : function( type, element )
\r
1091 if ( type == LINK )
\r
1093 if ( this.getValue() || this.isChanged() )
\r
1095 element.setAttribute( '_cke_saved_href', decodeURI( this.getValue() ) );
\r
1096 element.setAttribute( 'href', 'javascript:void(0)/*' +
\r
1097 CKEDITOR.tools.getNextNumber() + '*/' );
\r
1099 if ( this.getValue() || !editor.config.image_removeLinkByEmptyURL )
\r
1100 this.getDialog().addLink = true;
\r
1110 action : 'Browse',
\r
1111 target: 'Link:txtUrl',
\r
1112 url: editor.config.filebrowserImageBrowseLinkUrl || editor.config.filebrowserBrowseUrl
\r
1114 style : 'float:right',
\r
1116 label : editor.lang.common.browseServer
\r
1121 label : editor.lang.common.target,
\r
1125 [ editor.lang.common.notSet , ''],
\r
1126 [ editor.lang.common.targetNew , '_blank'],
\r
1127 [ editor.lang.common.targetTop , '_top'],
\r
1128 [ editor.lang.common.targetSelf , '_self'],
\r
1129 [ editor.lang.common.targetParent , '_parent']
\r
1131 setup : function( type, element )
\r
1133 if ( type == LINK )
\r
1134 this.setValue( element.getAttribute( 'target' ) );
\r
1136 commit : function( type, element )
\r
1138 if ( type == LINK )
\r
1140 if ( this.getValue() || this.isChanged() )
\r
1141 element.setAttribute( 'target', this.getValue() );
\r
1150 filebrowser : 'uploadButton',
\r
1151 label : editor.lang.image.upload,
\r
1157 label : editor.lang.image.btnUpload,
\r
1158 style: 'height:40px',
\r
1162 type : 'fileButton',
\r
1163 id : 'uploadButton',
\r
1164 filebrowser : 'info:txtUrl',
\r
1165 label : editor.lang.image.btnUpload,
\r
1166 'for' : [ 'Upload', 'upload' ]
\r
1172 label : editor.lang.common.advancedTab,
\r
1177 widths : [ '50%', '25%', '25%' ],
\r
1183 label : editor.lang.common.id,
\r
1184 setup : function( type, element )
\r
1186 if ( type == IMAGE )
\r
1187 this.setValue( element.getAttribute( 'id' ) );
\r
1189 commit : function( type, element )
\r
1191 if ( type == IMAGE )
\r
1193 if ( this.getValue() || this.isChanged() )
\r
1194 element.setAttribute( 'id', this.getValue() );
\r
1199 id : 'cmbLangDir',
\r
1201 style : 'width : 100px;',
\r
1202 label : editor.lang.common.langDir,
\r
1206 [ editor.lang.common.notSet, '' ],
\r
1207 [ editor.lang.common.langDirLtr, 'ltr' ],
\r
1208 [ editor.lang.common.langDirRtl, 'rtl' ]
\r
1210 setup : function( type, element )
\r
1212 if ( type == IMAGE )
\r
1213 this.setValue( element.getAttribute( 'dir' ) );
\r
1215 commit : function( type, element )
\r
1217 if ( type == IMAGE )
\r
1219 if ( this.getValue() || this.isChanged() )
\r
1220 element.setAttribute( 'dir', this.getValue() );
\r
1226 id : 'txtLangCode',
\r
1227 label : editor.lang.common.langCode,
\r
1229 setup : function( type, element )
\r
1231 if ( type == IMAGE )
\r
1232 this.setValue( element.getAttribute( 'lang' ) );
\r
1234 commit : function( type, element )
\r
1236 if ( type == IMAGE )
\r
1238 if ( this.getValue() || this.isChanged() )
\r
1239 element.setAttribute( 'lang', this.getValue() );
\r
1247 id : 'txtGenLongDescr',
\r
1248 label : editor.lang.common.longDescr,
\r
1249 setup : function( type, element )
\r
1251 if ( type == IMAGE )
\r
1252 this.setValue( element.getAttribute( 'longDesc' ) );
\r
1254 commit : function( type, element )
\r
1256 if ( type == IMAGE )
\r
1258 if ( this.getValue() || this.isChanged() )
\r
1259 element.setAttribute( 'longDesc', this.getValue() );
\r
1265 widths : [ '50%', '50%' ],
\r
1270 id : 'txtGenClass',
\r
1271 label : editor.lang.common.cssClass,
\r
1273 setup : function( type, element )
\r
1275 if ( type == IMAGE )
\r
1276 this.setValue( element.getAttribute( 'class' ) );
\r
1278 commit : function( type, element )
\r
1280 if ( type == IMAGE )
\r
1282 if ( this.getValue() || this.isChanged() )
\r
1283 element.setAttribute( 'class', this.getValue() );
\r
1289 id : 'txtGenTitle',
\r
1290 label : editor.lang.common.advisoryTitle,
\r
1292 onChange : function()
\r
1294 updatePreview( this.getDialog() );
\r
1296 setup : function( type, element )
\r
1298 if ( type == IMAGE )
\r
1299 this.setValue( element.getAttribute( 'title' ) );
\r
1301 commit : function( type, element )
\r
1303 if ( type == IMAGE )
\r
1305 if ( this.getValue() || this.isChanged() )
\r
1306 element.setAttribute( 'title', this.getValue() );
\r
1308 else if ( type == PREVIEW )
\r
1310 element.setAttribute( 'title', this.getValue() );
\r
1312 else if ( type == CLEANUP )
\r
1314 element.removeAttribute( 'title' );
\r
1322 id : 'txtdlgGenStyle',
\r
1323 label : editor.lang.common.cssStyle,
\r
1325 setup : function( type, element )
\r
1327 if ( type == IMAGE )
\r
1329 var genStyle = element.getAttribute( 'style' );
\r
1330 if ( !genStyle && element.$.style.cssText )
\r
1331 genStyle = element.$.style.cssText;
\r
1332 this.setValue( genStyle );
\r
1334 var height = element.$.style.height,
\r
1335 width = element.$.style.width,
\r
1336 aMatchH = ( height ? height : '' ).match( regexGetSize ),
\r
1337 aMatchW = ( width ? width : '').match( regexGetSize );
\r
1339 this.attributesInStyle =
\r
1341 height : !!aMatchH,
\r
1346 onChange : function ()
\r
1348 commitInternally.call( this,
\r
1349 [ 'info:cmbFloat', 'info:cmbAlign',
\r
1350 'info:txtVSpace', 'info:txtHSpace',
\r
1352 'info:txtWidth', 'info:txtHeight' ] );
\r
1353 updatePreview( this );
\r
1355 commit : function( type, element )
\r
1357 if ( type == IMAGE && ( this.getValue() || this.isChanged() ) )
\r
1359 element.setAttribute( 'style', this.getValue() );
\r
1369 CKEDITOR.dialog.add( 'image', function( editor )
\r
1371 return imageDialog( editor, 'image' );
\r
1374 CKEDITOR.dialog.add( 'imagebutton', function( editor )
\r
1376 return imageDialog( editor, 'imagebutton' );
\r