2 Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.
\r
3 For licensing, see LICENSE.html or http://ckeditor.com/license
\r
8 var imageDialog = function( editor, dialogType )
\r
10 // Load image preview.
\r
15 regexGetSize = /^\s*(\d+)((px)|\%)?\s*$/i,
\r
16 regexGetSizeOrEmpty = /(^\s*(\d+)((px)|\%)?\s*$)|^$/i,
\r
17 pxLengthRegex = /^\d+px$/;
\r
19 var onSizeChange = function()
\r
21 var value = this.getValue(), // This = input element.
\r
22 dialog = this.getDialog(),
\r
23 aMatch = value.match( regexGetSize ); // Check value
\r
26 if ( aMatch[2] == '%' ) // % is allowed - > unlock ratio.
\r
27 switchLockRatio( dialog, false ); // Unlock.
\r
31 // Only if ratio is locked
\r
32 if ( dialog.lockRatio )
\r
34 var oImageOriginal = dialog.originalElement;
\r
35 if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' )
\r
37 if ( this.id == 'txtHeight' )
\r
39 if ( value && value != '0' )
\r
40 value = Math.round( oImageOriginal.$.width * ( value / oImageOriginal.$.height ) );
\r
41 if ( !isNaN( value ) )
\r
42 dialog.setValueOf( 'info', 'txtWidth', value );
\r
44 else //this.id = txtWidth.
\r
46 if ( value && value != '0' )
\r
47 value = Math.round( oImageOriginal.$.height * ( value / oImageOriginal.$.width ) );
\r
48 if ( !isNaN( value ) )
\r
49 dialog.setValueOf( 'info', 'txtHeight', value );
\r
53 updatePreview( dialog );
\r
56 var updatePreview = function( dialog )
\r
58 //Don't load before onShow.
\r
59 if ( !dialog.originalElement || !dialog.preview )
\r
62 // Read attributes and update imagePreview;
\r
63 dialog.commitContent( PREVIEW, dialog.preview );
\r
67 // Custom commit dialog logic, where we're intended to give inline style
\r
68 // field (txtdlgGenStyle) higher priority to avoid overwriting styles contribute
\r
70 function commitContent()
\r
72 var args = arguments;
\r
73 var inlineStyleField = this.getContentElement( 'advanced', 'txtdlgGenStyle' );
\r
74 inlineStyleField && inlineStyleField.commit.apply( inlineStyleField, args );
\r
76 this.foreach( function( widget )
\r
78 if ( widget.commit && widget.id != 'txtdlgGenStyle' )
\r
79 widget.commit.apply( widget, args );
\r
83 // Avoid recursions.
\r
86 // Synchronous field values to other impacted fields is required, e.g. border
\r
87 // size change should alter inline-style text as well.
\r
88 function commitInternally( targetFields )
\r
95 var dialog = this.getDialog(),
\r
96 element = dialog.imageElement;
\r
99 // Commit this field and broadcast to target fields.
\r
100 this.commit( IMAGE, element );
\r
102 targetFields = [].concat( targetFields );
\r
103 var length = targetFields.length,
\r
105 for ( var i = 0; i < length; i++ )
\r
107 field = dialog.getContentElement.apply( dialog, targetFields[ i ].split( ':' ) );
\r
108 // May cause recursion.
\r
109 field && field.setup( IMAGE, element );
\r
116 var switchLockRatio = function( dialog, value )
\r
118 var oImageOriginal = dialog.originalElement;
\r
120 // Dialog may already closed. (#5505)
\r
121 if( !oImageOriginal )
\r
124 // Check image ratio and original image ratio, but respecting user's preference.
\r
125 if ( value == 'check' )
\r
127 if ( !dialog.userlockRatio && oImageOriginal.getCustomData( 'isReady' ) == 'true' )
\r
129 var width = dialog.getValueOf( 'info', 'txtWidth' ),
\r
130 height = dialog.getValueOf( 'info', 'txtHeight' ),
\r
131 originalRatio = oImageOriginal.$.width * 1000 / oImageOriginal.$.height,
\r
132 thisRatio = width * 1000 / height;
\r
133 dialog.lockRatio = false; // Default: unlock ratio
\r
135 if ( !width && !height )
\r
136 dialog.lockRatio = true;
\r
137 else if ( !isNaN( originalRatio ) && !isNaN( thisRatio ) )
\r
139 if ( Math.round( originalRatio ) == Math.round( thisRatio ) )
\r
140 dialog.lockRatio = true;
\r
144 else if ( value != undefined )
\r
145 dialog.lockRatio = value;
\r
148 dialog.userlockRatio = 1;
\r
149 dialog.lockRatio = !dialog.lockRatio;
\r
152 var ratioButton = CKEDITOR.document.getById( btnLockSizesId );
\r
153 if ( dialog.lockRatio )
\r
154 ratioButton.removeClass( 'cke_btn_unlocked' );
\r
156 ratioButton.addClass( 'cke_btn_unlocked' );
\r
158 var lang = dialog._.editor.lang.image,
\r
159 label = lang[ dialog.lockRatio ? 'unlockRatio' : 'lockRatio' ];
\r
161 ratioButton.setAttribute( 'title', label );
\r
162 ratioButton.getFirst().setText( label );
\r
164 return dialog.lockRatio;
\r
167 var resetSize = function( dialog )
\r
169 var oImageOriginal = dialog.originalElement;
\r
170 if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' )
\r
172 dialog.setValueOf( 'info', 'txtWidth', oImageOriginal.$.width );
\r
173 dialog.setValueOf( 'info', 'txtHeight', oImageOriginal.$.height );
\r
175 updatePreview( dialog );
\r
178 var setupDimension = function( type, element )
\r
180 if ( type != IMAGE )
\r
183 function checkDimension( size, defaultValue )
\r
185 var aMatch = size.match( regexGetSize );
\r
188 if ( aMatch[2] == '%' ) // % is allowed.
\r
191 switchLockRatio( dialog, false ); // Unlock ratio
\r
195 return defaultValue;
\r
198 var dialog = this.getDialog(),
\r
200 dimension = this.id == 'txtWidth' ? 'width' : 'height',
\r
201 size = element.getAttribute( dimension );
\r
204 value = checkDimension( size, value );
\r
205 value = checkDimension( element.getStyle( dimension ), value );
\r
207 this.setValue( value );
\r
210 var previewPreloader;
\r
212 var onImgLoadEvent = function()
\r
215 var original = this.originalElement;
\r
216 original.setCustomData( 'isReady', 'true' );
\r
217 original.removeListener( 'load', onImgLoadEvent );
\r
218 original.removeListener( 'error', onImgLoadErrorEvent );
\r
219 original.removeListener( 'abort', onImgLoadErrorEvent );
\r
222 CKEDITOR.document.getById( imagePreviewLoaderId ).setStyle( 'display', 'none' );
\r
224 // New image -> new domensions
\r
225 if ( !this.dontResetSize )
\r
228 if ( this.firstLoad )
\r
229 CKEDITOR.tools.setTimeout( function(){ switchLockRatio( this, 'check' ); }, 0, this );
\r
231 this.firstLoad = false;
\r
232 this.dontResetSize = false;
\r
235 var onImgLoadErrorEvent = function()
\r
237 // Error. Image is not loaded.
\r
238 var original = this.originalElement;
\r
239 original.removeListener( 'load', onImgLoadEvent );
\r
240 original.removeListener( 'error', onImgLoadErrorEvent );
\r
241 original.removeListener( 'abort', onImgLoadErrorEvent );
\r
243 // Set Error image.
\r
244 var noimage = CKEDITOR.getUrl( editor.skinPath + 'images/noimage.png' );
\r
246 if ( this.preview )
\r
247 this.preview.setAttribute( 'src', noimage );
\r
250 CKEDITOR.document.getById( imagePreviewLoaderId ).setStyle( 'display', 'none' );
\r
251 switchLockRatio( this, false ); // Unlock.
\r
254 var numbering = function( id )
\r
256 return CKEDITOR.tools.getNextId() + '_' + id;
\r
258 btnLockSizesId = numbering( 'btnLockSizes' ),
\r
259 btnResetSizeId = numbering( 'btnResetSize' ),
\r
260 imagePreviewLoaderId = numbering( 'ImagePreviewLoader' ),
\r
261 imagePreviewBoxId = numbering( 'ImagePreviewBox' ),
\r
262 previewLinkId = numbering( 'previewLink' ),
\r
263 previewImageId = numbering( 'previewImage' );
\r
266 title : editor.lang.image[ dialogType == 'image' ? 'title' : 'titleButton' ],
\r
269 onShow : function()
\r
271 this.imageElement = false;
\r
272 this.linkElement = false;
\r
274 // Default: create a new element.
\r
275 this.imageEditMode = false;
\r
276 this.linkEditMode = false;
\r
278 this.lockRatio = true;
\r
279 this.userlockRatio = 0;
\r
280 this.dontResetSize = false;
\r
281 this.firstLoad = true;
\r
282 this.addLink = false;
\r
284 var editor = this.getParentEditor(),
\r
285 sel = this.getParentEditor().getSelection(),
\r
286 element = sel.getSelectedElement(),
\r
287 link = element && element.getAscendant( 'a' );
\r
290 CKEDITOR.document.getById( imagePreviewLoaderId ).setStyle( 'display', 'none' );
\r
291 // Create the preview before setup the dialog contents.
\r
292 previewPreloader = new CKEDITOR.dom.element( 'img', editor.document );
\r
293 this.preview = CKEDITOR.document.getById( previewImageId );
\r
295 // Copy of the image
\r
296 this.originalElement = editor.document.createElement( 'img' );
\r
297 this.originalElement.setAttribute( 'alt', '' );
\r
298 this.originalElement.setCustomData( 'isReady', 'false' );
\r
302 this.linkElement = link;
\r
303 this.linkEditMode = true;
\r
305 // Look for Image element.
\r
306 var linkChildren = link.getChildren();
\r
307 if ( linkChildren.count() == 1 ) // 1 child.
\r
309 var childTagName = linkChildren.getItem( 0 ).getName();
\r
310 if ( childTagName == 'img' || childTagName == 'input' )
\r
312 this.imageElement = linkChildren.getItem( 0 );
\r
313 if ( this.imageElement.getName() == 'img' )
\r
314 this.imageEditMode = 'img';
\r
315 else if ( this.imageElement.getName() == 'input' )
\r
316 this.imageEditMode = 'input';
\r
319 // Fill out all fields.
\r
320 if ( dialogType == 'image' )
\r
321 this.setupContent( LINK, link );
\r
324 if ( element && element.getName() == 'img' && !element.data( 'cke-realelement' )
\r
325 || element && element.getName() == 'input' && element.getAttribute( 'type' ) == 'image' )
\r
327 this.imageEditMode = element.getName();
\r
328 this.imageElement = element;
\r
331 if ( this.imageEditMode )
\r
333 // Use the original element as a buffer from since we don't want
\r
334 // temporary changes to be committed, e.g. if the dialog is canceled.
\r
335 this.cleanImageElement = this.imageElement;
\r
336 this.imageElement = this.cleanImageElement.clone( true, true );
\r
338 // Fill out all fields.
\r
339 this.setupContent( IMAGE, this.imageElement );
\r
342 this.imageElement = editor.document.createElement( 'img' );
\r
344 // Refresh LockRatio button
\r
345 switchLockRatio ( this, true );
\r
347 // Dont show preview if no URL given.
\r
348 if ( !CKEDITOR.tools.trim( this.getValueOf( 'info', 'txtUrl' ) ) )
\r
350 this.preview.removeAttribute( 'src' );
\r
351 this.preview.setStyle( 'display', 'none' );
\r
356 // Edit existing Image.
\r
357 if ( this.imageEditMode )
\r
359 var imgTagName = this.imageEditMode;
\r
361 // Image dialog and Input element.
\r
362 if ( dialogType == 'image' && imgTagName == 'input' && confirm( editor.lang.image.button2Img ) )
\r
364 // Replace INPUT-> IMG
\r
365 imgTagName = 'img';
\r
366 this.imageElement = editor.document.createElement( 'img' );
\r
367 this.imageElement.setAttribute( 'alt', '' );
\r
368 editor.insertElement( this.imageElement );
\r
370 // ImageButton dialog and Image element.
\r
371 else if ( dialogType != 'image' && imgTagName == 'img' && confirm( editor.lang.image.img2Button ))
\r
373 // Replace IMG -> INPUT
\r
374 imgTagName = 'input';
\r
375 this.imageElement = editor.document.createElement( 'input' );
\r
376 this.imageElement.setAttributes(
\r
382 editor.insertElement( this.imageElement );
\r
386 // Restore the original element before all commits.
\r
387 this.imageElement = this.cleanImageElement;
\r
388 delete this.cleanImageElement;
\r
391 else // Create a new image.
\r
393 // Image dialog -> create IMG element.
\r
394 if ( dialogType == 'image' )
\r
395 this.imageElement = editor.document.createElement( 'img' );
\r
398 this.imageElement = editor.document.createElement( 'input' );
\r
399 this.imageElement.setAttribute ( 'type' ,'image' );
\r
401 this.imageElement.setAttribute( 'alt', '' );
\r
404 // Create a new link.
\r
405 if ( !this.linkEditMode )
\r
406 this.linkElement = editor.document.createElement( 'a' );
\r
409 this.commitContent( IMAGE, this.imageElement );
\r
410 this.commitContent( LINK, this.linkElement );
\r
412 // Remove empty style attribute.
\r
413 if ( !this.imageElement.getAttribute( 'style' ) )
\r
414 this.imageElement.removeAttribute( 'style' );
\r
416 // Insert a new Image.
\r
417 if ( !this.imageEditMode )
\r
419 if ( this.addLink )
\r
421 //Insert a new Link.
\r
422 if ( !this.linkEditMode )
\r
424 editor.insertElement( this.linkElement );
\r
425 this.linkElement.append( this.imageElement, false );
\r
427 else //Link already exists, image not.
\r
428 editor.insertElement( this.imageElement );
\r
431 editor.insertElement( this.imageElement );
\r
433 else // Image already exists.
\r
435 //Add a new link element.
\r
436 if ( !this.linkEditMode && this.addLink )
\r
438 editor.insertElement( this.linkElement );
\r
439 this.imageElement.appendTo( this.linkElement );
\r
441 //Remove Link, Image exists.
\r
442 else if ( this.linkEditMode && !this.addLink )
\r
444 editor.getSelection().selectElement( this.linkElement );
\r
445 editor.insertElement( this.imageElement );
\r
449 onLoad : function()
\r
451 if ( dialogType != 'image' )
\r
452 this.hidePage( 'Link' ); //Hide Link tab.
\r
453 var doc = this._.element.getDocument();
\r
454 this.addFocusable( doc.getById( btnResetSizeId ), 5 );
\r
455 this.addFocusable( doc.getById( btnLockSizesId ), 5 );
\r
457 this.commitContent = commitContent;
\r
459 onHide : function()
\r
461 if ( this.preview )
\r
462 this.commitContent( CLEANUP, this.preview );
\r
464 if ( this.originalElement )
\r
466 this.originalElement.removeListener( 'load', onImgLoadEvent );
\r
467 this.originalElement.removeListener( 'error', onImgLoadErrorEvent );
\r
468 this.originalElement.removeListener( 'abort', onImgLoadErrorEvent );
\r
469 this.originalElement.remove();
\r
470 this.originalElement = false; // Dialog is closed.
\r
473 delete this.imageElement;
\r
478 label : editor.lang.image.infoTab,
\r
489 widths : [ '280px', '110px' ],
\r
496 label : editor.lang.common.url,
\r
498 onChange : function()
\r
500 var dialog = this.getDialog(),
\r
501 newUrl = this.getValue();
\r
503 //Update original image
\r
504 if ( newUrl.length > 0 ) //Prevent from load before onShow
\r
506 dialog = this.getDialog();
\r
507 var original = dialog.originalElement;
\r
509 dialog.preview.removeStyle( 'display' );
\r
511 original.setCustomData( 'isReady', 'false' );
\r
513 var loader = CKEDITOR.document.getById( imagePreviewLoaderId );
\r
515 loader.setStyle( 'display', '' );
\r
517 original.on( 'load', onImgLoadEvent, dialog );
\r
518 original.on( 'error', onImgLoadErrorEvent, dialog );
\r
519 original.on( 'abort', onImgLoadErrorEvent, dialog );
\r
520 original.setAttribute( 'src', newUrl );
\r
522 // Query the preloader to figure out the url impacted by based href.
\r
523 previewPreloader.setAttribute( 'src', newUrl );
\r
524 dialog.preview.setAttribute( 'src', previewPreloader.$.src );
\r
525 updatePreview( dialog );
\r
527 // Dont show preview if no URL given.
\r
528 else if ( dialog.preview )
\r
530 dialog.preview.removeAttribute( 'src' );
\r
531 dialog.preview.setStyle( 'display', 'none' );
\r
534 setup : function( type, element )
\r
536 if ( type == IMAGE )
\r
538 var url = element.data( 'cke-saved-src' ) || element.getAttribute( 'src' );
\r
541 this.getDialog().dontResetSize = true;
\r
543 field.setValue( url ); // And call this.onChange()
\r
544 // Manually set the initial value.(#4191)
\r
545 field.setInitValue();
\r
548 commit : function( type, element )
\r
550 if ( type == IMAGE && ( this.getValue() || this.isChanged() ) )
\r
552 element.data( 'cke-saved-src', this.getValue() );
\r
553 element.setAttribute( 'src', this.getValue() );
\r
555 else if ( type == CLEANUP )
\r
557 element.setAttribute( 'src', '' ); // If removeAttribute doesn't work.
\r
558 element.removeAttribute( 'src' );
\r
561 validate : CKEDITOR.dialog.validate.notEmpty( editor.lang.image.urlMissing )
\r
566 // v-align with the 'txtUrl' field.
\r
567 // TODO: We need something better than a fixed size here.
\r
568 style : 'display:inline-block;margin-top:10px;',
\r
570 label : editor.lang.common.browseServer,
\r
572 filebrowser : 'info:txtUrl'
\r
581 label : editor.lang.image.alt,
\r
584 onChange : function()
\r
586 updatePreview( this.getDialog() );
\r
588 setup : function( type, element )
\r
590 if ( type == IMAGE )
\r
591 this.setValue( element.getAttribute( 'alt' ) );
\r
593 commit : function( type, element )
\r
595 if ( type == IMAGE )
\r
597 if ( this.getValue() || this.isChanged() )
\r
598 element.setAttribute( 'alt', this.getValue() );
\r
600 else if ( type == PREVIEW )
\r
602 element.setAttribute( 'alt', this.getValue() );
\r
604 else if ( type == CLEANUP )
\r
606 element.removeAttribute( 'alt' );
\r
620 widths : [ '50%', '50%' ],
\r
632 label : editor.lang.common.width,
\r
633 onKeyUp : onSizeChange,
\r
634 onChange : function()
\r
636 commitInternally.call( this, 'advanced:txtdlgGenStyle' );
\r
638 validate : function()
\r
640 var aMatch = this.getValue().match( regexGetSizeOrEmpty ),
\r
641 isValid = !!( aMatch && parseInt( aMatch[1], 10 ) !== 0 );
\r
643 alert( editor.lang.common.invalidWidth );
\r
646 setup : setupDimension,
\r
647 commit : function( type, element, internalCommit )
\r
649 var value = this.getValue();
\r
650 if ( type == IMAGE )
\r
653 element.setStyle( 'width', CKEDITOR.tools.cssLength( value ) );
\r
655 element.removeStyle( 'width' );
\r
657 !internalCommit && element.removeAttribute( 'width' );
\r
659 else if ( type == PREVIEW )
\r
661 var aMatch = value.match( regexGetSize );
\r
664 var oImageOriginal = this.getDialog().originalElement;
\r
665 if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' )
\r
666 element.setStyle( 'width', oImageOriginal.$.width + 'px');
\r
669 element.setStyle( 'width', CKEDITOR.tools.cssLength( value ) );
\r
671 else if ( type == CLEANUP )
\r
673 element.removeAttribute( 'width' );
\r
674 element.removeStyle( 'width' );
\r
682 label : editor.lang.common.height,
\r
683 onKeyUp : onSizeChange,
\r
684 onChange : function()
\r
686 commitInternally.call( this, 'advanced:txtdlgGenStyle' );
\r
688 validate : function()
\r
690 var aMatch = this.getValue().match( regexGetSizeOrEmpty ),
\r
691 isValid = !!( aMatch && parseInt( aMatch[1], 10 ) !== 0 );
\r
693 alert( editor.lang.common.invalidHeight );
\r
696 setup : setupDimension,
\r
697 commit : function( type, element, internalCommit )
\r
699 var value = this.getValue();
\r
700 if ( type == IMAGE )
\r
703 element.setStyle( 'height', CKEDITOR.tools.cssLength( value ) );
\r
705 element.removeStyle( 'height' );
\r
707 !internalCommit && element.removeAttribute( 'height' );
\r
709 else if ( type == PREVIEW )
\r
711 var aMatch = value.match( regexGetSize );
\r
714 var oImageOriginal = this.getDialog().originalElement;
\r
715 if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' )
\r
716 element.setStyle( 'height', oImageOriginal.$.height + 'px' );
\r
719 element.setStyle( 'height', CKEDITOR.tools.cssLength( value ) );
\r
721 else if ( type == CLEANUP )
\r
723 element.removeAttribute( 'height' );
\r
724 element.removeStyle( 'height' );
\r
732 style : 'margin-top:30px;width:40px;height:40px;',
\r
733 onLoad : function()
\r
735 // Activate Reset button
\r
736 var resetButton = CKEDITOR.document.getById( btnResetSizeId ),
\r
737 ratioButton = CKEDITOR.document.getById( btnLockSizesId );
\r
740 resetButton.on( 'click', function( evt )
\r
743 evt.data && evt.data.preventDefault();
\r
744 }, this.getDialog() );
\r
745 resetButton.on( 'mouseover', function()
\r
747 this.addClass( 'cke_btn_over' );
\r
749 resetButton.on( 'mouseout', function()
\r
751 this.removeClass( 'cke_btn_over' );
\r
754 // Activate (Un)LockRatio button
\r
757 ratioButton.on( 'click', function(evt)
\r
759 var locked = switchLockRatio( this ),
\r
760 oImageOriginal = this.originalElement,
\r
761 width = this.getValueOf( 'info', 'txtWidth' );
\r
763 if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' && width )
\r
765 var height = oImageOriginal.$.height / oImageOriginal.$.width * width;
\r
766 if ( !isNaN( height ) )
\r
768 this.setValueOf( 'info', 'txtHeight', Math.round( height ) );
\r
769 updatePreview( this );
\r
772 evt.data.preventDefault();
\r
773 }, this.getDialog() );
\r
774 ratioButton.on( 'mouseover', function()
\r
776 this.addClass( 'cke_btn_over' );
\r
778 ratioButton.on( 'mouseout', function()
\r
780 this.removeClass( 'cke_btn_over' );
\r
785 '<a href="javascript:void(0)" tabindex="-1" title="' + editor.lang.image.unlockRatio +
\r
786 '" class="cke_btn_locked" id="' + btnLockSizesId + '" role="button"><span class="cke_label">' + editor.lang.image.unlockRatio + '</span></a>' +
\r
787 '<a href="javascript:void(0)" tabindex="-1" title="' + editor.lang.image.resetSize +
\r
788 '" class="cke_btn_reset" id="' + btnResetSizeId + '" role="button"><span class="cke_label">' + editor.lang.image.resetSize + '</span></a>'+
\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 label : editor.lang.image.hSpace,
\r
860 onKeyUp : function()
\r
862 updatePreview( this.getDialog() );
\r
864 onChange : function()
\r
866 commitInternally.call( this, 'advanced:txtdlgGenStyle' );
\r
868 validate : CKEDITOR.dialog.validate.integer( editor.lang.image.validateHSpace ),
\r
869 setup : function( type, element )
\r
871 if ( type == IMAGE )
\r
876 marginLeftStyle = element.getStyle( 'margin-left' ),
\r
877 marginRightStyle = element.getStyle( 'margin-right' );
\r
879 marginLeftStyle = marginLeftStyle && marginLeftStyle.match( pxLengthRegex );
\r
880 marginRightStyle = marginRightStyle && marginRightStyle.match( pxLengthRegex );
\r
881 marginLeftPx = parseInt( marginLeftStyle, 10 );
\r
882 marginRightPx = parseInt( marginRightStyle, 10 );
\r
884 value = ( marginLeftPx == marginRightPx ) && marginLeftPx;
\r
885 isNaN( parseInt( value, 10 ) ) && ( value = element.getAttribute( 'hspace' ) );
\r
887 this.setValue( value );
\r
890 commit : function( type, element, internalCommit )
\r
892 var value = parseInt( this.getValue(), 10 );
\r
893 if ( type == IMAGE || type == PREVIEW )
\r
895 if ( !isNaN( value ) )
\r
897 element.setStyle( 'margin-left', CKEDITOR.tools.cssLength( value ) );
\r
898 element.setStyle( 'margin-right', CKEDITOR.tools.cssLength( value ) );
\r
900 else if ( !value && this.isChanged( ) )
\r
902 element.removeStyle( 'margin-left' );
\r
903 element.removeStyle( 'margin-right' );
\r
906 if ( !internalCommit && type == IMAGE )
\r
907 element.removeAttribute( 'hspace' );
\r
909 else if ( type == CLEANUP )
\r
911 element.removeAttribute( 'hspace' );
\r
912 element.removeStyle( 'margin-left' );
\r
913 element.removeStyle( 'margin-right' );
\r
921 label : editor.lang.image.vSpace,
\r
923 onKeyUp : function()
\r
925 updatePreview( this.getDialog() );
\r
927 onChange : function()
\r
929 commitInternally.call( this, 'advanced:txtdlgGenStyle' );
\r
931 validate : CKEDITOR.dialog.validate.integer( editor.lang.image.validateVSpace ),
\r
932 setup : function( type, element )
\r
934 if ( type == IMAGE )
\r
939 marginTopStyle = element.getStyle( 'margin-top' ),
\r
940 marginBottomStyle = element.getStyle( 'margin-bottom' );
\r
942 marginTopStyle = marginTopStyle && marginTopStyle.match( pxLengthRegex );
\r
943 marginBottomStyle = marginBottomStyle && marginBottomStyle.match( pxLengthRegex );
\r
944 marginTopPx = parseInt( marginTopStyle, 10 );
\r
945 marginBottomPx = parseInt( marginBottomStyle, 10 );
\r
947 value = ( marginTopPx == marginBottomPx ) && marginTopPx;
\r
948 isNaN ( parseInt( value, 10 ) ) && ( value = element.getAttribute( 'vspace' ) );
\r
949 this.setValue( value );
\r
952 commit : function( type, element, internalCommit )
\r
954 var value = parseInt( this.getValue(), 10 );
\r
955 if ( type == IMAGE || type == PREVIEW )
\r
957 if ( !isNaN( value ) )
\r
959 element.setStyle( 'margin-top', CKEDITOR.tools.cssLength( value ) );
\r
960 element.setStyle( 'margin-bottom', CKEDITOR.tools.cssLength( value ) );
\r
962 else if ( !value && this.isChanged( ) )
\r
964 element.removeStyle( 'margin-top' );
\r
965 element.removeStyle( 'margin-bottom' );
\r
968 if ( !internalCommit && type == IMAGE )
\r
969 element.removeAttribute( 'vspace' );
\r
971 else if ( type == CLEANUP )
\r
973 element.removeAttribute( 'vspace' );
\r
974 element.removeStyle( 'margin-top' );
\r
975 element.removeStyle( 'margin-bottom' );
\r
982 widths : [ '35%','65%' ],
\r
983 style : 'width:90px',
\r
984 label : editor.lang.common.align,
\r
988 [ editor.lang.common.notSet , ''],
\r
989 [ editor.lang.common.alignLeft , 'left'],
\r
990 [ editor.lang.common.alignRight , 'right']
\r
991 // Backward compatible with v2 on setup when specified as attribute value,
\r
992 // while these values are no more available as select options.
\r
993 // [ editor.lang.image.alignAbsBottom , 'absBottom'],
\r
994 // [ editor.lang.image.alignAbsMiddle , 'absMiddle'],
\r
995 // [ editor.lang.image.alignBaseline , 'baseline'],
\r
996 // [ editor.lang.image.alignTextTop , 'text-top'],
\r
997 // [ editor.lang.image.alignBottom , 'bottom'],
\r
998 // [ editor.lang.image.alignMiddle , 'middle'],
\r
999 // [ editor.lang.image.alignTop , 'top']
\r
1001 onChange : function()
\r
1003 updatePreview( this.getDialog() );
\r
1004 commitInternally.call( this, 'advanced:txtdlgGenStyle' );
\r
1006 setup : function( type, element )
\r
1008 if ( type == IMAGE )
\r
1010 var value = element.getStyle( 'float' );
\r
1013 // Ignore those unrelated values.
\r
1019 !value && ( value = ( element.getAttribute( 'align' ) || '' ).toLowerCase() );
\r
1020 this.setValue( value );
\r
1023 commit : function( type, element, internalCommit )
\r
1025 var value = this.getValue();
\r
1026 if ( type == IMAGE || type == PREVIEW )
\r
1029 element.setStyle( 'float', value );
\r
1031 element.removeStyle( 'float' );
\r
1033 if ( !internalCommit && type == IMAGE )
\r
1035 value = ( element.getAttribute( 'align' ) || '' ).toLowerCase();
\r
1038 // we should remove it only if it matches "left" or "right",
\r
1039 // otherwise leave it intact.
\r
1042 element.removeAttribute( 'align' );
\r
1046 else if ( type == CLEANUP )
\r
1047 element.removeStyle( 'float' );
\r
1062 style : 'width:95%;',
\r
1063 html : '<div>' + CKEDITOR.tools.htmlEncode( editor.lang.common.preview ) +'<br>'+
\r
1064 '<div id="' + imagePreviewLoaderId + '" class="ImagePreviewLoader" style="display:none"><div class="loading"> </div></div>'+
\r
1065 '<div id="' + imagePreviewBoxId + '" class="ImagePreviewBox"><table><tr><td>'+
\r
1066 '<a href="javascript:void(0)" target="_blank" onclick="return false;" id="' + previewLinkId + '">'+
\r
1067 '<img id="' + previewImageId + '" alt="" /></a>' +
\r
1068 ( editor.config.image_previewText ||
\r
1069 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. '+
\r
1070 'Maecenas feugiat consequat diam. Maecenas metus. Vivamus diam purus, cursus a, commodo non, facilisis vitae, '+
\r
1071 '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
1072 '</td></tr></table></div></div>'
\r
1082 label : editor.lang.link.title,
\r
1089 label : editor.lang.common.url,
\r
1090 style : 'width: 100%',
\r
1092 setup : function( type, element )
\r
1094 if ( type == LINK )
\r
1096 var href = element.data( 'cke-saved-href' );
\r
1098 href = element.getAttribute( 'href' );
\r
1099 this.setValue( href );
\r
1102 commit : function( type, element )
\r
1104 if ( type == LINK )
\r
1106 if ( this.getValue() || this.isChanged() )
\r
1108 var url = decodeURI( this.getValue() );
\r
1109 element.data( 'cke-saved-href', url );
\r
1110 element.setAttribute( 'href', url );
\r
1112 if ( this.getValue() || !editor.config.image_removeLinkByEmptyURL )
\r
1113 this.getDialog().addLink = true;
\r
1123 action : 'Browse',
\r
1124 target: 'Link:txtUrl',
\r
1125 url: editor.config.filebrowserImageBrowseLinkUrl
\r
1127 style : 'float:right',
\r
1129 label : editor.lang.common.browseServer
\r
1134 label : editor.lang.common.target,
\r
1138 [ editor.lang.common.notSet , ''],
\r
1139 [ editor.lang.common.targetNew , '_blank'],
\r
1140 [ editor.lang.common.targetTop , '_top'],
\r
1141 [ editor.lang.common.targetSelf , '_self'],
\r
1142 [ editor.lang.common.targetParent , '_parent']
\r
1144 setup : function( type, element )
\r
1146 if ( type == LINK )
\r
1147 this.setValue( element.getAttribute( 'target' ) || '' );
\r
1149 commit : function( type, element )
\r
1151 if ( type == LINK )
\r
1153 if ( this.getValue() || this.isChanged() )
\r
1154 element.setAttribute( 'target', this.getValue() );
\r
1163 filebrowser : 'uploadButton',
\r
1164 label : editor.lang.image.upload,
\r
1170 label : editor.lang.image.btnUpload,
\r
1171 style: 'height:40px',
\r
1175 type : 'fileButton',
\r
1176 id : 'uploadButton',
\r
1177 filebrowser : 'info:txtUrl',
\r
1178 label : editor.lang.image.btnUpload,
\r
1179 'for' : [ 'Upload', 'upload' ]
\r
1185 label : editor.lang.common.advancedTab,
\r
1190 widths : [ '50%', '25%', '25%' ],
\r
1196 label : editor.lang.common.id,
\r
1197 setup : function( type, element )
\r
1199 if ( type == IMAGE )
\r
1200 this.setValue( element.getAttribute( 'id' ) );
\r
1202 commit : function( type, element )
\r
1204 if ( type == IMAGE )
\r
1206 if ( this.getValue() || this.isChanged() )
\r
1207 element.setAttribute( 'id', this.getValue() );
\r
1212 id : 'cmbLangDir',
\r
1214 style : 'width : 100px;',
\r
1215 label : editor.lang.common.langDir,
\r
1219 [ editor.lang.common.notSet, '' ],
\r
1220 [ editor.lang.common.langDirLtr, 'ltr' ],
\r
1221 [ editor.lang.common.langDirRtl, 'rtl' ]
\r
1223 setup : function( type, element )
\r
1225 if ( type == IMAGE )
\r
1226 this.setValue( element.getAttribute( 'dir' ) );
\r
1228 commit : function( type, element )
\r
1230 if ( type == IMAGE )
\r
1232 if ( this.getValue() || this.isChanged() )
\r
1233 element.setAttribute( 'dir', this.getValue() );
\r
1239 id : 'txtLangCode',
\r
1240 label : editor.lang.common.langCode,
\r
1242 setup : function( type, element )
\r
1244 if ( type == IMAGE )
\r
1245 this.setValue( element.getAttribute( 'lang' ) );
\r
1247 commit : function( type, element )
\r
1249 if ( type == IMAGE )
\r
1251 if ( this.getValue() || this.isChanged() )
\r
1252 element.setAttribute( 'lang', this.getValue() );
\r
1260 id : 'txtGenLongDescr',
\r
1261 label : editor.lang.common.longDescr,
\r
1262 setup : function( type, element )
\r
1264 if ( type == IMAGE )
\r
1265 this.setValue( element.getAttribute( 'longDesc' ) );
\r
1267 commit : function( type, element )
\r
1269 if ( type == IMAGE )
\r
1271 if ( this.getValue() || this.isChanged() )
\r
1272 element.setAttribute( 'longDesc', this.getValue() );
\r
1278 widths : [ '50%', '50%' ],
\r
1283 id : 'txtGenClass',
\r
1284 label : editor.lang.common.cssClass,
\r
1286 setup : function( type, element )
\r
1288 if ( type == IMAGE )
\r
1289 this.setValue( element.getAttribute( 'class' ) );
\r
1291 commit : function( type, element )
\r
1293 if ( type == IMAGE )
\r
1295 if ( this.getValue() || this.isChanged() )
\r
1296 element.setAttribute( 'class', this.getValue() );
\r
1302 id : 'txtGenTitle',
\r
1303 label : editor.lang.common.advisoryTitle,
\r
1305 onChange : function()
\r
1307 updatePreview( this.getDialog() );
\r
1309 setup : function( type, element )
\r
1311 if ( type == IMAGE )
\r
1312 this.setValue( element.getAttribute( 'title' ) );
\r
1314 commit : function( type, element )
\r
1316 if ( type == IMAGE )
\r
1318 if ( this.getValue() || this.isChanged() )
\r
1319 element.setAttribute( 'title', this.getValue() );
\r
1321 else if ( type == PREVIEW )
\r
1323 element.setAttribute( 'title', this.getValue() );
\r
1325 else if ( type == CLEANUP )
\r
1327 element.removeAttribute( 'title' );
\r
1335 id : 'txtdlgGenStyle',
\r
1336 label : editor.lang.common.cssStyle,
\r
1338 setup : function( type, element )
\r
1340 if ( type == IMAGE )
\r
1342 var genStyle = element.getAttribute( 'style' );
\r
1343 if ( !genStyle && element.$.style.cssText )
\r
1344 genStyle = element.$.style.cssText;
\r
1345 this.setValue( genStyle );
\r
1347 var height = element.$.style.height,
\r
1348 width = element.$.style.width,
\r
1349 aMatchH = ( height ? height : '' ).match( regexGetSize ),
\r
1350 aMatchW = ( width ? width : '').match( regexGetSize );
\r
1352 this.attributesInStyle =
\r
1354 height : !!aMatchH,
\r
1359 onChange : function ()
\r
1361 commitInternally.call( this,
\r
1362 [ 'info:cmbFloat', 'info:cmbAlign',
\r
1363 'info:txtVSpace', 'info:txtHSpace',
\r
1365 'info:txtWidth', 'info:txtHeight' ] );
\r
1366 updatePreview( this );
\r
1368 commit : function( type, element )
\r
1370 if ( type == IMAGE && ( this.getValue() || this.isChanged() ) )
\r
1372 element.setAttribute( 'style', this.getValue() );
\r
1382 CKEDITOR.dialog.add( 'image', function( editor )
\r
1384 return imageDialog( editor, 'image' );
\r
1387 CKEDITOR.dialog.add( 'imagebutton', function( editor )
\r
1389 return imageDialog( editor, 'imagebutton' );
\r