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 ){ return id + CKEDITOR.tools.getNextNumber(); },
\r
254 btnLockSizesId = numbering( 'btnLockSizes' ),
\r
255 btnResetSizeId = numbering( 'btnResetSize' ),
\r
256 imagePreviewLoaderId = numbering( 'ImagePreviewLoader' ),
\r
257 imagePreviewBoxId = numbering( 'ImagePreviewBox' ),
\r
258 previewLinkId = numbering( 'previewLink' ),
\r
259 previewImageId = numbering( 'previewImage' );
\r
262 title : ( dialogType == 'image' ) ? editor.lang.image.title : editor.lang.image.titleButton,
\r
265 onShow : function()
\r
267 this.imageElement = false;
\r
268 this.linkElement = false;
\r
270 // Default: create a new element.
\r
271 this.imageEditMode = false;
\r
272 this.linkEditMode = false;
\r
274 this.lockRatio = true;
\r
275 this.dontResetSize = false;
\r
276 this.firstLoad = true;
\r
277 this.addLink = false;
\r
279 var editor = this.getParentEditor(),
\r
280 sel = this.getParentEditor().getSelection(),
\r
281 element = sel.getSelectedElement(),
\r
282 link = element && element.getAscendant( 'a' );
\r
285 CKEDITOR.document.getById( imagePreviewLoaderId ).setStyle( 'display', 'none' );
\r
286 // Create the preview before setup the dialog contents.
\r
287 previewPreloader = new CKEDITOR.dom.element( 'img', editor.document );
\r
288 this.preview = CKEDITOR.document.getById( previewImageId );
\r
290 // Copy of the image
\r
291 this.originalElement = editor.document.createElement( 'img' );
\r
292 this.originalElement.setAttribute( 'alt', '' );
\r
293 this.originalElement.setCustomData( 'isReady', 'false' );
\r
297 this.linkElement = link;
\r
298 this.linkEditMode = true;
\r
300 // Look for Image element.
\r
301 var linkChildren = link.getChildren();
\r
302 if ( linkChildren.count() == 1 ) // 1 child.
\r
304 var childTagName = linkChildren.getItem( 0 ).getName();
\r
305 if ( childTagName == 'img' || childTagName == 'input' )
\r
307 this.imageElement = linkChildren.getItem( 0 );
\r
308 if ( this.imageElement.getName() == 'img' )
\r
309 this.imageEditMode = 'img';
\r
310 else if ( this.imageElement.getName() == 'input' )
\r
311 this.imageEditMode = 'input';
\r
314 // Fill out all fields.
\r
315 if ( dialogType == 'image' )
\r
316 this.setupContent( LINK, link );
\r
319 if ( element && element.getName() == 'img' && !element.getAttribute( '_cke_realelement' )
\r
320 || element && element.getName() == 'input' && element.getAttribute( 'type' ) == 'image' )
\r
322 this.imageEditMode = element.getName();
\r
323 this.imageElement = element;
\r
326 if ( this.imageEditMode )
\r
328 // Use the original element as a buffer from since we don't want
\r
329 // temporary changes to be committed, e.g. if the dialog is canceled.
\r
330 this.cleanImageElement = this.imageElement;
\r
331 this.imageElement = this.cleanImageElement.clone( true, true );
\r
333 // Fill out all fields.
\r
334 this.setupContent( IMAGE, this.imageElement );
\r
336 // Refresh LockRatio button
\r
337 switchLockRatio ( this, true );
\r
340 this.imageElement = editor.document.createElement( 'img' );
\r
342 // Dont show preview if no URL given.
\r
343 if ( !CKEDITOR.tools.trim( this.getValueOf( 'info', 'txtUrl' ) ) )
\r
345 this.preview.removeAttribute( 'src' );
\r
346 this.preview.setStyle( 'display', 'none' );
\r
351 // Edit existing Image.
\r
352 if ( this.imageEditMode )
\r
354 var imgTagName = this.imageEditMode;
\r
356 // Image dialog and Input element.
\r
357 if ( dialogType == 'image' && imgTagName == 'input' && confirm( editor.lang.image.button2Img ) )
\r
359 // Replace INPUT-> IMG
\r
360 imgTagName = 'img';
\r
361 this.imageElement = editor.document.createElement( 'img' );
\r
362 this.imageElement.setAttribute( 'alt', '' );
\r
363 editor.insertElement( this.imageElement );
\r
365 // ImageButton dialog and Image element.
\r
366 else if ( dialogType != 'image' && imgTagName == 'img' && confirm( editor.lang.image.img2Button ))
\r
368 // Replace IMG -> INPUT
\r
369 imgTagName = 'input';
\r
370 this.imageElement = editor.document.createElement( 'input' );
\r
371 this.imageElement.setAttributes(
\r
377 editor.insertElement( this.imageElement );
\r
381 // Restore the original element before all commits.
\r
382 this.imageElement = this.cleanImageElement;
\r
383 delete this.cleanImageElement;
\r
386 else // Create a new image.
\r
388 // Image dialog -> create IMG element.
\r
389 if ( dialogType == 'image' )
\r
390 this.imageElement = editor.document.createElement( 'img' );
\r
393 this.imageElement = editor.document.createElement( 'input' );
\r
394 this.imageElement.setAttribute ( 'type' ,'image' );
\r
396 this.imageElement.setAttribute( 'alt', '' );
\r
399 // Create a new link.
\r
400 if ( !this.linkEditMode )
\r
401 this.linkElement = editor.document.createElement( 'a' );
\r
404 this.commitContent( IMAGE, this.imageElement );
\r
405 this.commitContent( LINK, this.linkElement );
\r
407 // Remove empty style attribute.
\r
408 if ( !this.imageElement.getAttribute( 'style' ) )
\r
409 this.imageElement.removeAttribute( 'style' );
\r
411 // Insert a new Image.
\r
412 if ( !this.imageEditMode )
\r
414 if ( this.addLink )
\r
416 //Insert a new Link.
\r
417 if ( !this.linkEditMode )
\r
419 editor.insertElement(this.linkElement);
\r
420 this.linkElement.append(this.imageElement, false);
\r
422 else //Link already exists, image not.
\r
423 editor.insertElement(this.imageElement );
\r
426 editor.insertElement( this.imageElement );
\r
428 else // Image already exists.
\r
430 //Add a new link element.
\r
431 if ( !this.linkEditMode && this.addLink )
\r
433 editor.insertElement( this.linkElement );
\r
434 this.imageElement.appendTo( this.linkElement );
\r
436 //Remove Link, Image exists.
\r
437 else if ( this.linkEditMode && !this.addLink )
\r
439 editor.getSelection().selectElement( this.linkElement );
\r
440 editor.insertElement( this.imageElement );
\r
444 onLoad : function()
\r
446 if ( dialogType != 'image' )
\r
447 this.hidePage( 'Link' ); //Hide Link tab.
\r
448 var doc = this._.element.getDocument();
\r
449 this.addFocusable( doc.getById( btnResetSizeId ), 5 );
\r
450 this.addFocusable( doc.getById( btnLockSizesId ), 5 );
\r
452 this.commitContent = commitContent;
\r
454 onHide : function()
\r
456 if ( this.preview )
\r
457 this.commitContent( CLEANUP, this.preview );
\r
459 if ( this.originalElement )
\r
461 this.originalElement.removeListener( 'load', onImgLoadEvent );
\r
462 this.originalElement.removeListener( 'error', onImgLoadErrorEvent );
\r
463 this.originalElement.removeListener( 'abort', onImgLoadErrorEvent );
\r
464 this.originalElement.remove();
\r
465 this.originalElement = false; // Dialog is closed.
\r
468 delete this.imageElement;
\r
473 label : editor.lang.image.infoTab,
\r
484 widths : [ '280px', '110px' ],
\r
491 label : editor.lang.common.url,
\r
493 onChange : function()
\r
495 var dialog = this.getDialog(),
\r
496 newUrl = this.getValue();
\r
498 //Update original image
\r
499 if ( newUrl.length > 0 ) //Prevent from load before onShow
\r
501 dialog = this.getDialog();
\r
502 var original = dialog.originalElement;
\r
504 dialog.preview.removeStyle( 'display' );
\r
506 original.setCustomData( 'isReady', 'false' );
\r
508 var loader = CKEDITOR.document.getById( imagePreviewLoaderId );
\r
510 loader.setStyle( 'display', '' );
\r
512 original.on( 'load', onImgLoadEvent, dialog );
\r
513 original.on( 'error', onImgLoadErrorEvent, dialog );
\r
514 original.on( 'abort', onImgLoadErrorEvent, dialog );
\r
515 original.setAttribute( 'src', newUrl );
\r
517 // Query the preloader to figure out the url impacted by based href.
\r
518 previewPreloader.setAttribute( 'src', newUrl );
\r
519 dialog.preview.setAttribute( 'src', previewPreloader.$.src );
\r
520 updatePreview( dialog );
\r
522 // Dont show preview if no URL given.
\r
523 else if ( dialog.preview )
\r
525 dialog.preview.removeAttribute( 'src' );
\r
526 dialog.preview.setStyle( 'display', 'none' );
\r
529 setup : function( type, element )
\r
531 if ( type == IMAGE )
\r
533 var url = element.getAttribute( '_cke_saved_src' ) || element.getAttribute( 'src' );
\r
536 this.getDialog().dontResetSize = true;
\r
538 field.setValue( url ); // And call this.onChange()
\r
539 // Manually set the initial value.(#4191)
\r
540 field.setInitValue();
\r
544 commit : function( type, element )
\r
546 if ( type == IMAGE && ( this.getValue() || this.isChanged() ) )
\r
548 element.setAttribute( '_cke_saved_src', decodeURI( this.getValue() ) );
\r
549 element.setAttribute( 'src', decodeURI( this.getValue() ) );
\r
551 else if ( type == CLEANUP )
\r
553 element.setAttribute( 'src', '' ); // If removeAttribute doesn't work.
\r
554 element.removeAttribute( 'src' );
\r
557 validate : CKEDITOR.dialog.validate.notEmpty( editor.lang.image.urlMissing )
\r
562 // v-align with the 'txtUrl' field.
\r
563 // TODO: We need something better than a fixed size here.
\r
564 style : 'display:inline-block;margin-top:10px;',
\r
566 label : editor.lang.common.browseServer,
\r
568 filebrowser : 'info:txtUrl'
\r
577 label : editor.lang.image.alt,
\r
580 onChange : function()
\r
582 updatePreview( this.getDialog() );
\r
584 setup : function( type, element )
\r
586 if ( type == IMAGE )
\r
587 this.setValue( element.getAttribute( 'alt' ) );
\r
589 commit : function( type, element )
\r
591 if ( type == IMAGE )
\r
593 if ( this.getValue() || this.isChanged() )
\r
594 element.setAttribute( 'alt', this.getValue() );
\r
596 else if ( type == PREVIEW )
\r
598 element.setAttribute( 'alt', this.getValue() );
\r
600 else if ( type == CLEANUP )
\r
602 element.removeAttribute( 'alt' );
\r
608 widths : [ '140px', '240px' ],
\r
618 widths : [ '70%', '30%' ],
\r
630 labelLayout : 'horizontal',
\r
631 label : editor.lang.image.width,
\r
632 onKeyUp : onSizeChange,
\r
633 onChange : function()
\r
635 commitInternally.call( this, 'advanced:txtdlgGenStyle' );
\r
637 validate : function()
\r
639 var aMatch = this.getValue().match( regexGetSizeOrEmpty );
\r
641 alert( editor.lang.image.validateWidth );
\r
644 setup : setupDimension,
\r
645 commit : function( type, element, internalCommit )
\r
647 var value = this.getValue();
\r
648 if ( type == IMAGE )
\r
651 element.setStyle( 'width', CKEDITOR.tools.cssLength( value ) );
\r
652 else if ( !value && this.isChanged( ) )
\r
653 element.removeStyle( 'width' );
\r
655 !internalCommit && element.removeAttribute( 'width' );
\r
657 else if ( type == PREVIEW )
\r
659 var aMatch = value.match( regexGetSize );
\r
662 var oImageOriginal = this.getDialog().originalElement;
\r
663 if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' )
\r
664 element.setStyle( 'width', oImageOriginal.$.width + 'px');
\r
667 element.setStyle( 'width', value + 'px');
\r
669 else if ( type == CLEANUP )
\r
671 element.removeAttribute( 'width' );
\r
672 element.removeStyle( 'width' );
\r
680 labelLayout : 'horizontal',
\r
681 label : editor.lang.image.height,
\r
682 onKeyUp : onSizeChange,
\r
683 onChange : function()
\r
685 commitInternally.call( this, 'advanced:txtdlgGenStyle' );
\r
687 validate : function()
\r
689 var aMatch = this.getValue().match( regexGetSizeOrEmpty );
\r
691 alert( editor.lang.image.validateHeight );
\r
694 setup : setupDimension,
\r
695 commit : function( type, element, internalCommit )
\r
697 var value = this.getValue();
\r
698 if ( type == IMAGE )
\r
701 element.setStyle( 'height', CKEDITOR.tools.cssLength( value ) );
\r
702 else if ( !value && this.isChanged( ) )
\r
703 element.removeStyle( 'height' );
\r
705 if ( !internalCommit && type == IMAGE )
\r
706 element.removeAttribute( 'height' );
\r
708 else if ( type == PREVIEW )
\r
710 var aMatch = value.match( regexGetSize );
\r
713 var oImageOriginal = this.getDialog().originalElement;
\r
714 if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' )
\r
715 element.setStyle( 'height', oImageOriginal.$.height + 'px' );
\r
718 element.setStyle( 'height', value + 'px' );
\r
720 else if ( type == CLEANUP )
\r
722 element.removeAttribute( 'height' );
\r
723 element.removeStyle( 'height' );
\r
731 style : 'margin-top:10px;width:40px;height:40px;',
\r
732 onLoad : function()
\r
734 // Activate Reset button
\r
735 var resetButton = CKEDITOR.document.getById( btnResetSizeId ),
\r
736 ratioButton = CKEDITOR.document.getById( btnLockSizesId );
\r
739 resetButton.on( 'click', function(evt)
\r
742 evt.data.preventDefault();
\r
743 }, this.getDialog() );
\r
744 resetButton.on( 'mouseover', function()
\r
746 this.addClass( 'cke_btn_over' );
\r
748 resetButton.on( 'mouseout', function()
\r
750 this.removeClass( 'cke_btn_over' );
\r
753 // Activate (Un)LockRatio button
\r
756 ratioButton.on( 'click', function(evt)
\r
758 var locked = switchLockRatio( this ),
\r
759 oImageOriginal = this.originalElement,
\r
760 width = this.getValueOf( 'info', 'txtWidth' );
\r
762 if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' && width )
\r
764 var height = oImageOriginal.$.height / oImageOriginal.$.width * width;
\r
765 if ( !isNaN( height ) )
\r
767 this.setValueOf( 'info', 'txtHeight', Math.round( height ) );
\r
768 updatePreview( this );
\r
771 evt.data.preventDefault();
\r
772 }, this.getDialog() );
\r
773 ratioButton.on( 'mouseover', function()
\r
775 this.addClass( 'cke_btn_over' );
\r
777 ratioButton.on( 'mouseout', function()
\r
779 this.removeClass( 'cke_btn_over' );
\r
784 '<a href="javascript:void(0)" tabindex="-1" title="' + editor.lang.image.unlockRatio +
\r
785 '" class="cke_btn_locked" id="' + btnLockSizesId + '" role="button"><span class="cke_label">' + editor.lang.image.unlockRatio + '</span></a>' +
\r
786 '<a href="javascript:void(0)" tabindex="-1" title="' + editor.lang.image.resetSize +
\r
787 '" class="cke_btn_reset" id="' + btnResetSizeId + '" role="button"><span class="cke_label">' + editor.lang.image.resetSize + '</span></a>'+
\r
801 labelLayout : 'horizontal',
\r
802 label : editor.lang.image.border,
\r
804 onKeyUp : function()
\r
806 updatePreview( this.getDialog() );
\r
808 onChange : function()
\r
810 commitInternally.call( this, 'advanced:txtdlgGenStyle' );
\r
812 validate : CKEDITOR.dialog.validate.integer( editor.lang.image.validateBorder ),
\r
813 setup : function( type, element )
\r
815 if ( type == IMAGE )
\r
818 borderStyle = element.getStyle( 'border-width' );
\r
819 borderStyle = borderStyle && borderStyle.match( /^(\d+px)(?: \1 \1 \1)?$/ );
\r
820 value = borderStyle && parseInt( borderStyle[ 1 ], 10 );
\r
821 isNaN ( parseInt( value, 10 ) ) && ( value = element.getAttribute( 'border' ) );
\r
822 this.setValue( value );
\r
825 commit : function( type, element, internalCommit )
\r
827 var value = parseInt( this.getValue(), 10 );
\r
828 if ( type == IMAGE || type == PREVIEW )
\r
830 if ( !isNaN( value ) )
\r
832 element.setStyle( 'border-width', CKEDITOR.tools.cssLength( value ) );
\r
833 element.setStyle( 'border-style', 'solid' );
\r
835 else if ( !value && this.isChanged() )
\r
837 element.removeStyle( 'border-width' );
\r
838 element.removeStyle( 'border-style' );
\r
839 element.removeStyle( 'border-color' );
\r
842 if ( !internalCommit && type == IMAGE )
\r
843 element.removeAttribute( 'border' );
\r
845 else if ( type == CLEANUP )
\r
847 element.removeAttribute( 'border' );
\r
848 element.removeStyle( 'border-width' );
\r
849 element.removeStyle( 'border-style' );
\r
850 element.removeStyle( 'border-color' );
\r
858 labelLayout : 'horizontal',
\r
859 label : editor.lang.image.hSpace,
\r
861 onKeyUp : function()
\r
863 updatePreview( this.getDialog() );
\r
865 onChange : function()
\r
867 commitInternally.call( this, 'advanced:txtdlgGenStyle' );
\r
869 validate : CKEDITOR.dialog.validate.integer( editor.lang.image.validateHSpace ),
\r
870 setup : function( type, element )
\r
872 if ( type == IMAGE )
\r
877 marginLeftStyle = element.getStyle( 'margin-left' ),
\r
878 marginRightStyle = element.getStyle( 'margin-right' );
\r
880 marginLeftStyle = marginLeftStyle && marginLeftStyle.match( pxLengthRegex );
\r
881 marginRightStyle = marginRightStyle && marginRightStyle.match( pxLengthRegex );
\r
882 marginLeftPx = parseInt( marginLeftStyle, 10 );
\r
883 marginRightPx = parseInt( marginRightStyle, 10 );
\r
885 value = ( marginLeftPx == marginRightPx ) && marginLeftPx;
\r
886 isNaN( parseInt( value, 10 ) ) && ( value = element.getAttribute( 'hspace' ) );
\r
888 this.setValue( value );
\r
891 commit : function( type, element, internalCommit )
\r
893 var value = parseInt( this.getValue(), 10 );
\r
894 if ( type == IMAGE || type == PREVIEW )
\r
896 if ( !isNaN( value ) )
\r
898 element.setStyle( 'margin-left', CKEDITOR.tools.cssLength( value ) );
\r
899 element.setStyle( 'margin-right', CKEDITOR.tools.cssLength( value ) );
\r
901 else if ( !value && this.isChanged( ) )
\r
903 element.removeStyle( 'margin-left' );
\r
904 element.removeStyle( 'margin-right' );
\r
907 if ( !internalCommit && type == IMAGE )
\r
908 element.removeAttribute( 'hspace' );
\r
910 else if ( type == CLEANUP )
\r
912 element.removeAttribute( 'hspace' );
\r
913 element.removeStyle( 'margin-left' );
\r
914 element.removeStyle( 'margin-right' );
\r
922 labelLayout : 'horizontal',
\r
923 label : editor.lang.image.vSpace,
\r
925 onKeyUp : function()
\r
927 updatePreview( this.getDialog() );
\r
929 onChange : function()
\r
931 commitInternally.call( this, 'advanced:txtdlgGenStyle' );
\r
933 validate : CKEDITOR.dialog.validate.integer( editor.lang.image.validateVSpace ),
\r
934 setup : function( type, element )
\r
936 if ( type == IMAGE )
\r
941 marginTopStyle = element.getStyle( 'margin-top' ),
\r
942 marginBottomStyle = element.getStyle( 'margin-bottom' );
\r
944 marginTopStyle = marginTopStyle && marginTopStyle.match( pxLengthRegex );
\r
945 marginBottomStyle = marginBottomStyle && marginBottomStyle.match( pxLengthRegex );
\r
946 marginTopPx = parseInt( marginTopStyle, 10 );
\r
947 marginBottomPx = parseInt( marginBottomStyle, 10 );
\r
949 value = ( marginTopPx == marginBottomPx ) && marginTopPx;
\r
950 isNaN ( parseInt( value, 10 ) ) && ( value = element.getAttribute( 'vspace' ) );
\r
951 this.setValue( value );
\r
954 commit : function( type, element, internalCommit )
\r
956 var value = parseInt( this.getValue(), 10 );
\r
957 if ( type == IMAGE || type == PREVIEW )
\r
959 if ( !isNaN( value ) )
\r
961 element.setStyle( 'margin-top', CKEDITOR.tools.cssLength( value ) );
\r
962 element.setStyle( 'margin-bottom', CKEDITOR.tools.cssLength( value ) );
\r
964 else if ( !value && this.isChanged( ) )
\r
966 element.removeStyle( 'margin-top' );
\r
967 element.removeStyle( 'margin-bottom' );
\r
970 if ( !internalCommit && type == IMAGE )
\r
971 element.removeAttribute( 'vspace' );
\r
973 else if ( type == CLEANUP )
\r
975 element.removeAttribute( 'vspace' );
\r
976 element.removeStyle( 'margin-top' );
\r
977 element.removeStyle( 'margin-bottom' );
\r
984 labelLayout : 'horizontal',
\r
985 widths : [ '35%','65%' ],
\r
986 style : 'width:90px',
\r
987 label : editor.lang.image.align,
\r
991 [ editor.lang.common.notSet , ''],
\r
992 [ editor.lang.image.alignLeft , 'left'],
\r
993 [ editor.lang.image.alignRight , 'right']
\r
994 // Backward compatible with v2 on setup when specified as attribute value,
\r
995 // while these values are no more available as select options.
\r
996 // [ editor.lang.image.alignAbsBottom , 'absBottom'],
\r
997 // [ editor.lang.image.alignAbsMiddle , 'absMiddle'],
\r
998 // [ editor.lang.image.alignBaseline , 'baseline'],
\r
999 // [ editor.lang.image.alignTextTop , 'text-top'],
\r
1000 // [ editor.lang.image.alignBottom , 'bottom'],
\r
1001 // [ editor.lang.image.alignMiddle , 'middle'],
\r
1002 // [ editor.lang.image.alignTop , 'top']
\r
1004 onChange : function()
\r
1006 updatePreview( this.getDialog() );
\r
1007 commitInternally.call( this, 'advanced:txtdlgGenStyle' );
\r
1009 setup : function( type, element )
\r
1011 if ( type == IMAGE )
\r
1013 var value = element.getStyle( 'float' );
\r
1016 // Ignore those unrelated values.
\r
1022 !value && ( value = ( element.getAttribute( 'align' ) || '' ).toLowerCase() );
\r
1023 this.setValue( value );
\r
1026 commit : function( type, element, internalCommit )
\r
1028 var value = this.getValue();
\r
1029 if ( type == IMAGE || type == PREVIEW )
\r
1032 element.setStyle( 'float', value );
\r
1034 element.removeStyle( 'float' );
\r
1036 if ( !internalCommit && type == IMAGE )
\r
1038 value = ( element.getAttribute( 'align' ) || '' ).toLowerCase();
\r
1041 // we should remove it only if it matches "left" or "right",
\r
1042 // otherwise leave it intact.
\r
1045 element.removeAttribute( 'align' );
\r
1049 else if ( type == CLEANUP )
\r
1050 element.removeStyle( 'float' );
\r
1065 style : 'width:95%;',
\r
1066 html : '<div>' + CKEDITOR.tools.htmlEncode( editor.lang.common.preview ) +'<br>'+
\r
1067 '<div id="' + imagePreviewLoaderId + '" class="ImagePreviewLoader" style="display:none"><div class="loading"> </div></div>'+
\r
1068 '<div id="' + imagePreviewBoxId + '" class="ImagePreviewBox"><table><tr><td>'+
\r
1069 '<a href="javascript:void(0)" target="_blank" onclick="return false;" id="' + previewLinkId + '">'+
\r
1070 '<img id="' + previewImageId + '" alt="" /></a>' +
\r
1071 ( editor.config.image_previewText ||
\r
1072 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. '+
\r
1073 'Maecenas feugiat consequat diam. Maecenas metus. Vivamus diam purus, cursus a, commodo non, facilisis vitae, '+
\r
1074 '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
1075 '</td></tr></table></div></div>'
\r
1085 label : editor.lang.link.title,
\r
1092 label : editor.lang.common.url,
\r
1093 style : 'width: 100%',
\r
1095 setup : function( type, element )
\r
1097 if ( type == LINK )
\r
1099 var href = element.getAttribute( '_cke_saved_href' );
\r
1101 href = element.getAttribute( 'href' );
\r
1102 this.setValue( href );
\r
1105 commit : function( type, element )
\r
1107 if ( type == LINK )
\r
1109 if ( this.getValue() || this.isChanged() )
\r
1111 element.setAttribute( '_cke_saved_href', decodeURI( this.getValue() ) );
\r
1112 element.setAttribute( 'href', 'javascript:void(0)/*' +
\r
1113 CKEDITOR.tools.getNextNumber() + '*/' );
\r
1115 if ( this.getValue() || !editor.config.image_removeLinkByEmptyURL )
\r
1116 this.getDialog().addLink = true;
\r
1126 action : 'Browse',
\r
1127 target: 'Link:txtUrl',
\r
1128 url: editor.config.filebrowserImageBrowseLinkUrl || editor.config.filebrowserBrowseUrl
\r
1130 style : 'float:right',
\r
1132 label : editor.lang.common.browseServer
\r
1137 label : editor.lang.common.target,
\r
1141 [ editor.lang.common.notSet , ''],
\r
1142 [ editor.lang.common.targetNew , '_blank'],
\r
1143 [ editor.lang.common.targetTop , '_top'],
\r
1144 [ editor.lang.common.targetSelf , '_self'],
\r
1145 [ editor.lang.common.targetParent , '_parent']
\r
1147 setup : function( type, element )
\r
1149 if ( type == LINK )
\r
1150 this.setValue( element.getAttribute( 'target' ) );
\r
1152 commit : function( type, element )
\r
1154 if ( type == LINK )
\r
1156 if ( this.getValue() || this.isChanged() )
\r
1157 element.setAttribute( 'target', this.getValue() );
\r
1166 filebrowser : 'uploadButton',
\r
1167 label : editor.lang.image.upload,
\r
1173 label : editor.lang.image.btnUpload,
\r
1174 style: 'height:40px',
\r
1178 type : 'fileButton',
\r
1179 id : 'uploadButton',
\r
1180 filebrowser : 'info:txtUrl',
\r
1181 label : editor.lang.image.btnUpload,
\r
1182 'for' : [ 'Upload', 'upload' ]
\r
1188 label : editor.lang.common.advancedTab,
\r
1193 widths : [ '50%', '25%', '25%' ],
\r
1199 label : editor.lang.common.id,
\r
1200 setup : function( type, element )
\r
1202 if ( type == IMAGE )
\r
1203 this.setValue( element.getAttribute( 'id' ) );
\r
1205 commit : function( type, element )
\r
1207 if ( type == IMAGE )
\r
1209 if ( this.getValue() || this.isChanged() )
\r
1210 element.setAttribute( 'id', this.getValue() );
\r
1215 id : 'cmbLangDir',
\r
1217 style : 'width : 100px;',
\r
1218 label : editor.lang.common.langDir,
\r
1222 [ editor.lang.common.notSet, '' ],
\r
1223 [ editor.lang.common.langDirLtr, 'ltr' ],
\r
1224 [ editor.lang.common.langDirRtl, 'rtl' ]
\r
1226 setup : function( type, element )
\r
1228 if ( type == IMAGE )
\r
1229 this.setValue( element.getAttribute( 'dir' ) );
\r
1231 commit : function( type, element )
\r
1233 if ( type == IMAGE )
\r
1235 if ( this.getValue() || this.isChanged() )
\r
1236 element.setAttribute( 'dir', this.getValue() );
\r
1242 id : 'txtLangCode',
\r
1243 label : editor.lang.common.langCode,
\r
1245 setup : function( type, element )
\r
1247 if ( type == IMAGE )
\r
1248 this.setValue( element.getAttribute( 'lang' ) );
\r
1250 commit : function( type, element )
\r
1252 if ( type == IMAGE )
\r
1254 if ( this.getValue() || this.isChanged() )
\r
1255 element.setAttribute( 'lang', this.getValue() );
\r
1263 id : 'txtGenLongDescr',
\r
1264 label : editor.lang.common.longDescr,
\r
1265 setup : function( type, element )
\r
1267 if ( type == IMAGE )
\r
1268 this.setValue( element.getAttribute( 'longDesc' ) );
\r
1270 commit : function( type, element )
\r
1272 if ( type == IMAGE )
\r
1274 if ( this.getValue() || this.isChanged() )
\r
1275 element.setAttribute( 'longDesc', this.getValue() );
\r
1281 widths : [ '50%', '50%' ],
\r
1286 id : 'txtGenClass',
\r
1287 label : editor.lang.common.cssClass,
\r
1289 setup : function( type, element )
\r
1291 if ( type == IMAGE )
\r
1292 this.setValue( element.getAttribute( 'class' ) );
\r
1294 commit : function( type, element )
\r
1296 if ( type == IMAGE )
\r
1298 if ( this.getValue() || this.isChanged() )
\r
1299 element.setAttribute( 'class', this.getValue() );
\r
1305 id : 'txtGenTitle',
\r
1306 label : editor.lang.common.advisoryTitle,
\r
1308 onChange : function()
\r
1310 updatePreview( this.getDialog() );
\r
1312 setup : function( type, element )
\r
1314 if ( type == IMAGE )
\r
1315 this.setValue( element.getAttribute( 'title' ) );
\r
1317 commit : function( type, element )
\r
1319 if ( type == IMAGE )
\r
1321 if ( this.getValue() || this.isChanged() )
\r
1322 element.setAttribute( 'title', this.getValue() );
\r
1324 else if ( type == PREVIEW )
\r
1326 element.setAttribute( 'title', this.getValue() );
\r
1328 else if ( type == CLEANUP )
\r
1330 element.removeAttribute( 'title' );
\r
1338 id : 'txtdlgGenStyle',
\r
1339 label : editor.lang.common.cssStyle,
\r
1341 setup : function( type, element )
\r
1343 if ( type == IMAGE )
\r
1345 var genStyle = element.getAttribute( 'style' );
\r
1346 if ( !genStyle && element.$.style.cssText )
\r
1347 genStyle = element.$.style.cssText;
\r
1348 this.setValue( genStyle );
\r
1350 var height = element.$.style.height,
\r
1351 width = element.$.style.width,
\r
1352 aMatchH = ( height ? height : '' ).match( regexGetSize ),
\r
1353 aMatchW = ( width ? width : '').match( regexGetSize );
\r
1355 this.attributesInStyle =
\r
1357 height : !!aMatchH,
\r
1362 onChange : function ()
\r
1364 commitInternally.call( this,
\r
1365 [ 'info:cmbFloat', 'info:cmbAlign',
\r
1366 'info:txtVSpace', 'info:txtHSpace',
\r
1368 'info:txtWidth', 'info:txtHeight' ] );
\r
1369 updatePreview( this );
\r
1371 commit : function( type, element )
\r
1373 if ( type == IMAGE && ( this.getValue() || this.isChanged() ) )
\r
1375 element.setAttribute( 'style', this.getValue() );
\r
1385 CKEDITOR.dialog.add( 'image', function( editor )
\r
1387 return imageDialog( editor, 'image' );
\r
1390 CKEDITOR.dialog.add( 'imagebutton', function( editor )
\r
1392 return imageDialog( editor, 'imagebutton' );
\r