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 return dialog.lockRatio;
\r
153 var resetSize = function( dialog )
\r
155 var oImageOriginal = dialog.originalElement;
\r
156 if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' )
\r
158 dialog.setValueOf( 'info', 'txtWidth', oImageOriginal.$.width );
\r
159 dialog.setValueOf( 'info', 'txtHeight', oImageOriginal.$.height );
\r
161 updatePreview( dialog );
\r
164 var setupDimension = function( type, element )
\r
166 if ( type != IMAGE )
\r
169 function checkDimension( size, defaultValue )
\r
171 var aMatch = size.match( regexGetSize );
\r
174 if ( aMatch[2] == '%' ) // % is allowed.
\r
177 switchLockRatio( dialog, false ); // Unlock ratio
\r
181 return defaultValue;
\r
184 var dialog = this.getDialog(),
\r
186 dimension = (( this.id == 'txtWidth' )? 'width' : 'height' ),
\r
187 size = element.getAttribute( dimension );
\r
190 value = checkDimension( size, value );
\r
191 value = checkDimension( element.getStyle( dimension ), value );
\r
193 this.setValue( value );
\r
196 var imageDialog = function( editor, dialogType )
\r
198 var previewPreloader;
\r
200 var onImgLoadEvent = function()
\r
203 var original = this.originalElement;
\r
204 original.setCustomData( 'isReady', 'true' );
\r
205 original.removeListener( 'load', onImgLoadEvent );
\r
206 original.removeListener( 'error', onImgLoadErrorEvent );
\r
207 original.removeListener( 'abort', onImgLoadErrorEvent );
\r
210 CKEDITOR.document.getById( 'ImagePreviewLoader' ).setStyle( 'display', 'none' );
\r
212 // New image -> new domensions
\r
213 if ( !this.dontResetSize )
\r
216 if ( this.firstLoad )
\r
217 CKEDITOR.tools.setTimeout( function(){ switchLockRatio( this, 'check' ); }, 0, this );
\r
219 this.firstLoad = false;
\r
220 this.dontResetSize = false;
\r
223 var onImgLoadErrorEvent = function()
\r
225 // Error. Image is not loaded.
\r
226 var original = this.originalElement;
\r
227 original.removeListener( 'load', onImgLoadEvent );
\r
228 original.removeListener( 'error', onImgLoadErrorEvent );
\r
229 original.removeListener( 'abort', onImgLoadErrorEvent );
\r
231 // Set Error image.
\r
232 var noimage = CKEDITOR.getUrl( editor.skinPath + 'images/noimage.png' );
\r
234 if ( this.preview )
\r
235 this.preview.setAttribute( 'src', noimage );
\r
238 CKEDITOR.document.getById( 'ImagePreviewLoader' ).setStyle( 'display', 'none' );
\r
239 switchLockRatio( this, false ); // Unlock.
\r
242 title : ( dialogType == 'image' ) ? editor.lang.image.title : editor.lang.image.titleButton,
\r
245 onShow : function()
\r
247 this.imageElement = false;
\r
248 this.linkElement = false;
\r
250 // Default: create a new element.
\r
251 this.imageEditMode = false;
\r
252 this.linkEditMode = false;
\r
254 this.lockRatio = true;
\r
255 this.dontResetSize = false;
\r
256 this.firstLoad = true;
\r
257 this.addLink = false;
\r
259 var editor = this.getParentEditor(),
\r
260 sel = this.getParentEditor().getSelection(),
\r
261 element = sel.getSelectedElement(),
\r
262 link = element && element.getAscendant( 'a' );
\r
265 CKEDITOR.document.getById( 'ImagePreviewLoader' ).setStyle( 'display', 'none' );
\r
266 // Create the preview before setup the dialog contents.
\r
267 previewPreloader = new CKEDITOR.dom.element( 'img', editor.document );
\r
268 this.preview = CKEDITOR.document.getById( 'previewImage' );
\r
270 // Copy of the image
\r
271 this.originalElement = editor.document.createElement( 'img' );
\r
272 this.originalElement.setAttribute( 'alt', '' );
\r
273 this.originalElement.setCustomData( 'isReady', 'false' );
\r
277 this.linkElement = link;
\r
278 this.linkEditMode = true;
\r
280 // Look for Image element.
\r
281 var linkChildren = link.getChildren();
\r
282 if ( linkChildren.count() == 1 ) // 1 child.
\r
284 var childTagName = linkChildren.getItem( 0 ).getName();
\r
285 if ( childTagName == 'img' || childTagName == 'input' )
\r
287 this.imageElement = linkChildren.getItem( 0 );
\r
288 if ( this.imageElement.getName() == 'img' )
\r
289 this.imageEditMode = 'img';
\r
290 else if ( this.imageElement.getName() == 'input' )
\r
291 this.imageEditMode = 'input';
\r
294 // Fill out all fields.
\r
295 if ( dialogType == 'image' )
\r
296 this.setupContent( LINK, link );
\r
299 if ( element && element.getName() == 'img' && !element.getAttribute( '_cke_realelement' )
\r
300 || element && element.getName() == 'input' && element.getAttribute( 'type' ) == 'image' )
\r
302 this.imageEditMode = element.getName();
\r
303 this.imageElement = element;
\r
306 if ( this.imageEditMode )
\r
308 // Use the original element as a buffer from since we don't want
\r
309 // temporary changes to be committed, e.g. if the dialog is canceled.
\r
310 this.cleanImageElement = this.imageElement;
\r
311 this.imageElement = this.cleanImageElement.clone( true, true );
\r
313 // Fill out all fields.
\r
314 this.setupContent( IMAGE, this.imageElement );
\r
316 // Refresh LockRatio button
\r
317 switchLockRatio ( this, true );
\r
320 this.imageElement = editor.document.createElement( 'img' );
\r
322 // Dont show preview if no URL given.
\r
323 if ( !CKEDITOR.tools.trim( this.getValueOf( 'info', 'txtUrl' ) ) )
\r
325 this.preview.removeAttribute( 'src' );
\r
326 this.preview.setStyle( 'display', 'none' );
\r
331 // Edit existing Image.
\r
332 if ( this.imageEditMode )
\r
334 var imgTagName = this.imageEditMode;
\r
336 // Image dialog and Input element.
\r
337 if ( dialogType == 'image' && imgTagName == 'input' && confirm( editor.lang.image.button2Img ) )
\r
339 // Replace INPUT-> IMG
\r
340 imgTagName = 'img';
\r
341 this.imageElement = editor.document.createElement( 'img' );
\r
342 this.imageElement.setAttribute( 'alt', '' );
\r
343 editor.insertElement( this.imageElement );
\r
345 // ImageButton dialog and Image element.
\r
346 else if ( dialogType != 'image' && imgTagName == 'img' && confirm( editor.lang.image.img2Button ))
\r
348 // Replace IMG -> INPUT
\r
349 imgTagName = 'input';
\r
350 this.imageElement = editor.document.createElement( 'input' );
\r
351 this.imageElement.setAttributes(
\r
357 editor.insertElement( this.imageElement );
\r
361 // Restore the original element before all commits.
\r
362 this.imageElement = this.cleanImageElement;
\r
363 delete this.cleanImageElement;
\r
366 else // Create a new image.
\r
368 // Image dialog -> create IMG element.
\r
369 if ( dialogType == 'image' )
\r
370 this.imageElement = editor.document.createElement( 'img' );
\r
373 this.imageElement = editor.document.createElement( 'input' );
\r
374 this.imageElement.setAttribute ( 'type' ,'image' );
\r
376 this.imageElement.setAttribute( 'alt', '' );
\r
379 // Create a new link.
\r
380 if ( !this.linkEditMode )
\r
381 this.linkElement = editor.document.createElement( 'a' );
\r
384 this.commitContent( IMAGE, this.imageElement );
\r
385 this.commitContent( LINK, this.linkElement );
\r
387 // Remove empty style attribute.
\r
388 if( !this.imageElement.getAttribute( 'style' ) )
\r
389 this.imageElement.removeAttribute( 'style' );
\r
391 // Insert a new Image.
\r
392 if ( !this.imageEditMode )
\r
394 if ( this.addLink )
\r
396 //Insert a new Link.
\r
397 if ( !this.linkEditMode )
\r
399 editor.insertElement(this.linkElement);
\r
400 this.linkElement.append(this.imageElement, false);
\r
402 else //Link already exists, image not.
\r
403 editor.insertElement(this.imageElement );
\r
406 editor.insertElement( this.imageElement );
\r
408 else // Image already exists.
\r
410 //Add a new link element.
\r
411 if ( !this.linkEditMode && this.addLink )
\r
413 editor.insertElement( this.linkElement );
\r
414 this.imageElement.appendTo( this.linkElement );
\r
416 //Remove Link, Image exists.
\r
417 else if ( this.linkEditMode && !this.addLink )
\r
419 editor.getSelection().selectElement( this.linkElement );
\r
420 editor.insertElement( this.imageElement );
\r
424 onLoad : function()
\r
426 if ( dialogType != 'image' )
\r
427 this.hidePage( 'Link' ); //Hide Link tab.
\r
428 var doc = this._.element.getDocument();
\r
429 this.addFocusable( doc.getById( 'btnResetSize' ), 5 );
\r
430 this.addFocusable( doc.getById( 'btnLockSizes' ), 5 );
\r
432 this.commitContent = commitContent;
\r
434 onHide : function()
\r
436 if ( this.preview )
\r
437 this.commitContent( CLEANUP, this.preview );
\r
439 if ( this.originalElement )
\r
441 this.originalElement.removeListener( 'load', onImgLoadEvent );
\r
442 this.originalElement.removeListener( 'error', onImgLoadErrorEvent );
\r
443 this.originalElement.removeListener( 'abort', onImgLoadErrorEvent );
\r
444 this.originalElement.remove();
\r
445 this.originalElement = false; // Dialog is closed.
\r
448 delete this.imageElement;
\r
453 label : editor.lang.image.infoTab,
\r
464 html : '<span>' + CKEDITOR.tools.htmlEncode( editor.lang.image.url ) + '</span>'
\r
468 widths : [ '280px', '110px' ],
\r
476 onChange : function()
\r
478 var dialog = this.getDialog(),
\r
479 newUrl = this.getValue();
\r
481 //Update original image
\r
482 if ( newUrl.length > 0 ) //Prevent from load before onShow
\r
484 dialog = this.getDialog();
\r
485 var original = dialog.originalElement;
\r
487 dialog.preview.removeStyle( 'display' );
\r
489 original.setCustomData( 'isReady', 'false' );
\r
491 var loader = CKEDITOR.document.getById( 'ImagePreviewLoader' );
\r
493 loader.setStyle( 'display', '' );
\r
495 original.on( 'load', onImgLoadEvent, dialog );
\r
496 original.on( 'error', onImgLoadErrorEvent, dialog );
\r
497 original.on( 'abort', onImgLoadErrorEvent, dialog );
\r
498 original.setAttribute( 'src', newUrl );
\r
500 // Query the preloader to figure out the url impacted by based href.
\r
501 previewPreloader.setAttribute( 'src', newUrl );
\r
502 dialog.preview.setAttribute( 'src', previewPreloader.$.src );
\r
503 updatePreview( dialog );
\r
505 // Dont show preview if no URL given.
\r
506 else if ( dialog.preview )
\r
508 dialog.preview.removeAttribute( 'src' );
\r
509 dialog.preview.setStyle( 'display', 'none' );
\r
512 setup : function( type, element )
\r
514 if ( type == IMAGE )
\r
516 var url = element.getAttribute( '_cke_saved_src' ) || element.getAttribute( 'src' );
\r
519 this.getDialog().dontResetSize = true;
\r
521 field.setValue( url ); // And call this.onChange()
\r
522 // Manually set the initial value.(#4191)
\r
523 field.setInitValue();
\r
527 commit : function( type, element )
\r
529 if ( type == IMAGE && ( this.getValue() || this.isChanged() ) )
\r
531 element.setAttribute( '_cke_saved_src', decodeURI( this.getValue() ) );
\r
532 element.setAttribute( 'src', decodeURI( this.getValue() ) );
\r
534 else if ( type == CLEANUP )
\r
536 element.setAttribute( 'src', '' ); // If removeAttribute doesn't work.
\r
537 element.removeAttribute( 'src' );
\r
540 validate : CKEDITOR.dialog.validate.notEmpty( editor.lang.image.urlMissing )
\r
546 label : editor.lang.common.browseServer,
\r
548 filebrowser : 'info:txtUrl'
\r
557 label : editor.lang.image.alt,
\r
560 onChange : function()
\r
562 updatePreview( this.getDialog() );
\r
564 setup : function( type, element )
\r
566 if ( type == IMAGE )
\r
567 this.setValue( element.getAttribute( 'alt' ) );
\r
569 commit : function( type, element )
\r
571 if ( type == IMAGE )
\r
573 if ( this.getValue() || this.isChanged() )
\r
574 element.setAttribute( 'alt', this.getValue() );
\r
576 else if ( type == PREVIEW )
\r
578 element.setAttribute( 'alt', this.getValue() );
\r
580 else if ( type == CLEANUP )
\r
582 element.removeAttribute( 'alt' );
\r
588 widths : [ '140px', '240px' ],
\r
598 widths : [ '70%', '30%' ],
\r
610 labelLayout : 'horizontal',
\r
611 label : editor.lang.image.width,
\r
612 onKeyUp : onSizeChange,
\r
613 onChange : function()
\r
615 commitInternally.call( this, 'advanced:txtdlgGenStyle' );
\r
617 validate: function()
\r
619 var aMatch = this.getValue().match( regexGetSizeOrEmpty );
\r
621 alert( editor.lang.common.validateNumberFailed );
\r
624 setup : setupDimension,
\r
625 commit : function( type, element, internalCommit )
\r
627 var value = this.getValue();
\r
628 if ( type == IMAGE )
\r
631 element.setStyle( 'width', CKEDITOR.tools.cssLength( value ) );
\r
632 else if ( !value && this.isChanged( ) )
\r
633 element.removeStyle( 'width' );
\r
635 !internalCommit && element.removeAttribute( 'width' );
\r
637 else if ( type == PREVIEW )
\r
639 var aMatch = value.match( regexGetSize );
\r
642 var oImageOriginal = this.getDialog().originalElement;
\r
643 if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' )
\r
644 element.setStyle( 'width', oImageOriginal.$.width + 'px');
\r
647 element.setStyle( 'width', value + 'px');
\r
649 else if ( type == CLEANUP )
\r
651 element.removeAttribute( 'width' );
\r
652 element.removeStyle( 'width' );
\r
660 labelLayout : 'horizontal',
\r
661 label : editor.lang.image.height,
\r
662 onKeyUp : onSizeChange,
\r
663 onChange : function()
\r
665 commitInternally.call( this, 'advanced:txtdlgGenStyle' );
\r
667 validate: function()
\r
669 var aMatch = this.getValue().match( regexGetSizeOrEmpty );
\r
671 alert( editor.lang.common.validateNumberFailed );
\r
674 setup : setupDimension,
\r
675 commit : function( type, element, internalCommit )
\r
677 var value = this.getValue();
\r
678 if ( type == IMAGE )
\r
681 element.setStyle( 'height', CKEDITOR.tools.cssLength( value ) );
\r
682 else if ( !value && this.isChanged( ) )
\r
683 element.removeStyle( 'height' );
\r
685 if( !internalCommit && type == IMAGE )
\r
686 element.removeAttribute( 'height' );
\r
688 else if ( type == PREVIEW )
\r
690 var aMatch = value.match( regexGetSize );
\r
693 var oImageOriginal = this.getDialog().originalElement;
\r
694 if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' )
\r
695 element.setStyle( 'height', oImageOriginal.$.height + 'px' );
\r
698 element.setStyle( 'height', value + 'px' );
\r
700 else if ( type == CLEANUP )
\r
702 element.removeAttribute( 'height' );
\r
703 element.removeStyle( 'height' );
\r
711 style : 'margin-top:10px;width:40px;height:40px;',
\r
712 onLoad : function()
\r
714 // Activate Reset button
\r
715 var resetButton = CKEDITOR.document.getById( 'btnResetSize' ),
\r
716 ratioButton = CKEDITOR.document.getById( 'btnLockSizes' );
\r
719 resetButton.on( 'click', function()
\r
722 }, this.getDialog() );
\r
723 resetButton.on( 'mouseover', function()
\r
725 this.addClass( 'cke_btn_over' );
\r
727 resetButton.on( 'mouseout', function()
\r
729 this.removeClass( 'cke_btn_over' );
\r
732 // Activate (Un)LockRatio button
\r
735 ratioButton.on( 'click', function()
\r
737 var locked = switchLockRatio( this ),
\r
738 oImageOriginal = this.originalElement,
\r
739 width = this.getValueOf( 'info', 'txtWidth' );
\r
741 if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' && width )
\r
743 var height = oImageOriginal.$.height / oImageOriginal.$.width * width;
\r
744 if ( !isNaN( height ) )
\r
746 this.setValueOf( 'info', 'txtHeight', Math.round( height ) );
\r
747 updatePreview( this );
\r
750 }, this.getDialog() );
\r
751 ratioButton.on( 'mouseover', function()
\r
753 this.addClass( 'cke_btn_over' );
\r
755 ratioButton.on( 'mouseout', function()
\r
757 this.removeClass( 'cke_btn_over' );
\r
762 '<a href="javascript:void(0)" tabindex="-1" title="' + editor.lang.image.lockRatio +
\r
763 '" class="cke_btn_locked" id="btnLockSizes"></a>' +
\r
764 '<a href="javascript:void(0)" tabindex="-1" title="' + editor.lang.image.resetSize +
\r
765 '" class="cke_btn_reset" id="btnResetSize"></a>'+
\r
779 labelLayout : 'horizontal',
\r
780 label : editor.lang.image.border,
\r
782 onKeyUp : function()
\r
784 updatePreview( this.getDialog() );
\r
786 onChange : function()
\r
788 commitInternally.call( this, 'advanced:txtdlgGenStyle' );
\r
790 validate: function()
\r
792 var func = CKEDITOR.dialog.validate.integer( editor.lang.common.validateNumberFailed );
\r
793 return func.apply( this );
\r
795 setup : function( type, element )
\r
797 if ( type == IMAGE )
\r
800 borderStyle = element.getStyle( 'border-width' );
\r
802 borderStyle = borderStyle && borderStyle.match( /^(\d+px)(?: \1 \1 \1)?$/ );
\r
803 value = borderStyle && parseInt( borderStyle[ 1 ], 10 );
\r
804 !value && ( value = element.getAttribute( 'border' ) );
\r
806 this.setValue( value );
\r
809 commit : function( type, element, internalCommit )
\r
811 var value = parseInt( this.getValue(), 10 );
\r
812 if ( type == IMAGE || type == PREVIEW )
\r
816 element.setStyle( 'border-width', CKEDITOR.tools.cssLength( value ) );
\r
817 element.setStyle( 'border-style', 'solid' );
\r
819 else if ( !value && this.isChanged() )
\r
821 element.removeStyle( 'border-width' );
\r
822 element.removeStyle( 'border-style' );
\r
823 element.removeStyle( 'border-color' );
\r
826 if( !internalCommit && type == IMAGE )
\r
827 element.removeAttribute( 'border' );
\r
829 else if ( type == CLEANUP )
\r
831 element.removeAttribute( 'border' );
\r
832 element.removeStyle( 'border-width' );
\r
833 element.removeStyle( 'border-style' );
\r
834 element.removeStyle( 'border-color' );
\r
842 labelLayout : 'horizontal',
\r
843 label : editor.lang.image.hSpace,
\r
845 onKeyUp : function()
\r
847 updatePreview( this.getDialog() );
\r
849 onChange : function()
\r
851 commitInternally.call( this, 'advanced:txtdlgGenStyle' );
\r
853 validate: function()
\r
855 var func = CKEDITOR.dialog.validate.integer( editor.lang.common.validateNumberFailed );
\r
856 return func.apply( this );
\r
858 setup : function( type, element )
\r
860 if ( type == IMAGE )
\r
865 marginLeftStyle = element.getStyle( 'margin-left' ),
\r
866 marginRightStyle = element.getStyle( 'margin-right' );
\r
868 marginLeftStyle = marginLeftStyle && marginLeftStyle.match( pxLengthRegex );
\r
869 marginRightStyle = marginRightStyle && marginRightStyle.match( pxLengthRegex );
\r
870 marginLeftPx = parseInt( marginLeftStyle, 10 );
\r
871 marginRightPx = parseInt( marginRightStyle, 10 );
\r
873 value = ( marginLeftPx == marginRightPx ) && marginLeftPx;
\r
874 !value && ( value = element.getAttribute( 'hspace' ) );
\r
876 this.setValue( value );
\r
879 commit : function( type, element, internalCommit )
\r
881 var value = parseInt( this.getValue(), 10 );
\r
882 if ( type == IMAGE || type == PREVIEW )
\r
886 element.setStyle( 'margin-left', CKEDITOR.tools.cssLength( value ) );
\r
887 element.setStyle( 'margin-right', CKEDITOR.tools.cssLength( value ) );
\r
889 else if ( !value && this.isChanged( ) )
\r
891 element.removeStyle( 'margin-left' );
\r
892 element.removeStyle( 'margin-right' );
\r
895 if( !internalCommit && type == IMAGE )
\r
896 element.removeAttribute( 'hspace' );
\r
898 else if ( type == CLEANUP )
\r
900 element.removeAttribute( 'hspace' );
\r
901 element.removeStyle( 'margin-left' );
\r
902 element.removeStyle( 'margin-right' );
\r
910 labelLayout : 'horizontal',
\r
911 label : editor.lang.image.vSpace,
\r
913 onKeyUp : function()
\r
915 updatePreview( this.getDialog() );
\r
917 onChange : function()
\r
919 commitInternally.call( this, 'advanced:txtdlgGenStyle' );
\r
921 validate: function()
\r
923 var func = CKEDITOR.dialog.validate.integer( editor.lang.common.validateNumberFailed );
\r
924 return func.apply( this );
\r
926 setup : function( type, element )
\r
928 if ( type == IMAGE )
\r
933 marginTopStyle = element.getStyle( 'margin-top' ),
\r
934 marginBottomStyle = element.getStyle( 'margin-bottom' );
\r
936 marginTopStyle = marginTopStyle && marginTopStyle.match( pxLengthRegex );
\r
937 marginBottomStyle = marginBottomStyle && marginBottomStyle.match( pxLengthRegex );
\r
938 marginTopPx = parseInt( marginTopStyle, 10 );
\r
939 marginBottomPx = parseInt( marginBottomStyle, 10 );
\r
941 value = ( marginTopPx == marginBottomPx ) && marginTopPx;
\r
942 !value && ( value = element.getAttribute( 'vspace' ) );
\r
943 this.setValue( value );
\r
946 commit : function( type, element, internalCommit )
\r
948 var value = parseInt( this.getValue(), 10 );
\r
949 if ( type == IMAGE || type == PREVIEW )
\r
953 element.setStyle( 'margin-top', CKEDITOR.tools.cssLength( value ) );
\r
954 element.setStyle( 'margin-bottom', CKEDITOR.tools.cssLength( value ) );
\r
956 else if ( !value && this.isChanged( ) )
\r
958 element.removeStyle( 'margin-top' );
\r
959 element.removeStyle( 'margin-bottom' );
\r
962 if( !internalCommit && type == IMAGE )
\r
963 element.removeAttribute( 'vspace' );
\r
965 else if ( type == CLEANUP )
\r
967 element.removeAttribute( 'vspace' );
\r
968 element.removeStyle( 'margin-top' );
\r
969 element.removeStyle( 'margin-bottom' );
\r
976 labelLayout : 'horizontal',
\r
977 widths : [ '35%','65%' ],
\r
978 style : 'width:90px',
\r
979 label : editor.lang.image.align,
\r
983 [ editor.lang.common.notSet , ''],
\r
984 [ editor.lang.image.alignLeft , 'left'],
\r
985 [ editor.lang.image.alignRight , 'right']
\r
986 // Backward compatible with v2 on setup when specified as attribute value,
\r
987 // while these values are no more available as select options.
\r
988 // [ editor.lang.image.alignAbsBottom , 'absBottom'],
\r
989 // [ editor.lang.image.alignAbsMiddle , 'absMiddle'],
\r
990 // [ editor.lang.image.alignBaseline , 'baseline'],
\r
991 // [ editor.lang.image.alignTextTop , 'text-top'],
\r
992 // [ editor.lang.image.alignBottom , 'bottom'],
\r
993 // [ editor.lang.image.alignMiddle , 'middle'],
\r
994 // [ editor.lang.image.alignTop , 'top']
\r
996 onChange : function()
\r
998 updatePreview( this.getDialog() );
\r
999 commitInternally.call( this, 'advanced:txtdlgGenStyle' );
\r
1001 setup : function( type, element )
\r
1003 if ( type == IMAGE )
\r
1005 var value = element.getStyle( 'float' );
\r
1008 // Ignore those unrelated values.
\r
1014 !value && ( value = ( element.getAttribute( 'align' ) || '' ).toLowerCase() );
\r
1015 this.setValue( value );
\r
1018 commit : function( type, element, internalCommit )
\r
1020 var value = this.getValue();
\r
1021 if ( type == IMAGE || type == PREVIEW )
\r
1024 element.setStyle( 'float', value );
\r
1025 else if ( !value && this.isChanged( ) )
\r
1026 element.removeStyle( 'float' );
\r
1028 if( !internalCommit && type == IMAGE )
\r
1030 value = ( element.getAttribute( 'align' ) || '' ).toLowerCase();
\r
1033 // we should remove it only if it matches "left" or "right",
\r
1034 // otherwise leave it intact.
\r
1037 element.removeAttribute( 'align' );
\r
1041 else if ( type == CLEANUP )
\r
1042 element.removeStyle( 'float' );
\r
1057 style : 'width:95%;',
\r
1058 html : '<div>' + CKEDITOR.tools.htmlEncode( editor.lang.image.preview ) +'<br>'+
\r
1059 '<div id="ImagePreviewLoader" style="display:none"><div class="loading"> </div></div>'+
\r
1060 '<div id="ImagePreviewBox">'+
\r
1061 '<a href="javascript:void(0)" target="_blank" onclick="return false;" id="previewLink">'+
\r
1062 '<img id="previewImage" alt="" /></a>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. '+
\r
1063 'Maecenas feugiat consequat diam. Maecenas metus. Vivamus diam purus, cursus a, commodo non, facilisis vitae, '+
\r
1064 '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 label : editor.lang.link.title,
\r
1082 label : editor.lang.image.url,
\r
1083 style : 'width: 100%',
\r
1085 setup : function( type, element )
\r
1087 if ( type == LINK )
\r
1089 var href = element.getAttribute( '_cke_saved_href' );
\r
1091 href = element.getAttribute( 'href' );
\r
1092 this.setValue( href );
\r
1095 commit : function( type, element )
\r
1097 if ( type == LINK )
\r
1099 if ( this.getValue() || this.isChanged() )
\r
1101 element.setAttribute( '_cke_saved_href', decodeURI( this.getValue() ) );
\r
1102 element.setAttribute( 'href', 'javascript:void(0)/*' +
\r
1103 CKEDITOR.tools.getNextNumber() + '*/' );
\r
1105 if ( this.getValue() || !editor.config.image_removeLinkByEmptyURL )
\r
1106 this.getDialog().addLink = true;
\r
1114 filebrowser : 'Link:txtUrl',
\r
1115 style : 'float:right',
\r
1117 label : editor.lang.common.browseServer
\r
1122 label : editor.lang.link.target,
\r
1126 [ editor.lang.link.targetNotSet , ''],
\r
1127 [ editor.lang.link.targetNew , '_blank'],
\r
1128 [ editor.lang.link.targetTop , '_top'],
\r
1129 [ editor.lang.link.targetSelf , '_self'],
\r
1130 [ editor.lang.link.targetParent , '_parent']
\r
1132 setup : function( type, element )
\r
1134 if ( type == LINK )
\r
1135 this.setValue( element.getAttribute( 'target' ) );
\r
1137 commit : function( type, element )
\r
1139 if ( type == LINK )
\r
1141 if ( this.getValue() || this.isChanged() )
\r
1142 element.setAttribute( 'target', this.getValue() );
\r
1151 filebrowser : 'uploadButton',
\r
1152 label : editor.lang.image.upload,
\r
1158 label : editor.lang.image.btnUpload,
\r
1159 style: 'height:40px',
\r
1163 type : 'fileButton',
\r
1164 id : 'uploadButton',
\r
1165 filebrowser : 'info:txtUrl',
\r
1166 label : editor.lang.image.btnUpload,
\r
1167 'for' : [ 'Upload', 'upload' ]
\r
1173 label : editor.lang.common.advancedTab,
\r
1178 widths : [ '50%', '25%', '25%' ],
\r
1184 label : editor.lang.common.id,
\r
1185 setup : function( type, element )
\r
1187 if ( type == IMAGE )
\r
1188 this.setValue( element.getAttribute( 'id' ) );
\r
1190 commit : function( type, element )
\r
1192 if ( type == IMAGE )
\r
1194 if ( this.getValue() || this.isChanged() )
\r
1195 element.setAttribute( 'id', this.getValue() );
\r
1200 id : 'cmbLangDir',
\r
1202 style : 'width : 100px;',
\r
1203 label : editor.lang.common.langDir,
\r
1207 [ editor.lang.common.notSet, '' ],
\r
1208 [ editor.lang.common.langDirLtr, 'ltr' ],
\r
1209 [ editor.lang.common.langDirRtl, 'rtl' ]
\r
1211 setup : function( type, element )
\r
1213 if ( type == IMAGE )
\r
1214 this.setValue( element.getAttribute( 'dir' ) );
\r
1216 commit : function( type, element )
\r
1218 if ( type == IMAGE )
\r
1220 if ( this.getValue() || this.isChanged() )
\r
1221 element.setAttribute( 'dir', this.getValue() );
\r
1227 id : 'txtLangCode',
\r
1228 label : editor.lang.common.langCode,
\r
1230 setup : function( type, element )
\r
1232 if ( type == IMAGE )
\r
1233 this.setValue( element.getAttribute( 'lang' ) );
\r
1235 commit : function( type, element )
\r
1237 if ( type == IMAGE )
\r
1239 if ( this.getValue() || this.isChanged() )
\r
1240 element.setAttribute( 'lang', this.getValue() );
\r
1248 id : 'txtGenLongDescr',
\r
1249 label : editor.lang.common.longDescr,
\r
1250 setup : function( type, element )
\r
1252 if ( type == IMAGE )
\r
1253 this.setValue( element.getAttribute( 'longDesc' ) );
\r
1255 commit : function( type, element )
\r
1257 if ( type == IMAGE )
\r
1259 if ( this.getValue() || this.isChanged() )
\r
1260 element.setAttribute( 'longDesc', this.getValue() );
\r
1266 widths : [ '50%', '50%' ],
\r
1271 id : 'txtGenClass',
\r
1272 label : editor.lang.common.cssClass,
\r
1274 setup : function( type, element )
\r
1276 if ( type == IMAGE )
\r
1277 this.setValue( element.getAttribute( 'class' ) );
\r
1279 commit : function( type, element )
\r
1281 if ( type == IMAGE )
\r
1283 if ( this.getValue() || this.isChanged() )
\r
1284 element.setAttribute( 'class', this.getValue() );
\r
1290 id : 'txtGenTitle',
\r
1291 label : editor.lang.common.advisoryTitle,
\r
1293 onChange : function()
\r
1295 updatePreview( this.getDialog() );
\r
1297 setup : function( type, element )
\r
1299 if ( type == IMAGE )
\r
1300 this.setValue( element.getAttribute( 'title' ) );
\r
1302 commit : function( type, element )
\r
1304 if ( type == IMAGE )
\r
1306 if ( this.getValue() || this.isChanged() )
\r
1307 element.setAttribute( 'title', this.getValue() );
\r
1309 else if ( type == PREVIEW )
\r
1311 element.setAttribute( 'title', this.getValue() );
\r
1313 else if ( type == CLEANUP )
\r
1315 element.removeAttribute( 'title' );
\r
1323 id : 'txtdlgGenStyle',
\r
1324 label : editor.lang.common.cssStyle,
\r
1326 setup : function( type, element )
\r
1328 if ( type == IMAGE )
\r
1330 var genStyle = element.getAttribute( 'style' );
\r
1331 if ( !genStyle && element.$.style.cssText )
\r
1332 genStyle = element.$.style.cssText;
\r
1333 this.setValue( genStyle );
\r
1335 var height = element.$.style.height,
\r
1336 width = element.$.style.width,
\r
1337 aMatchH = ( height ? height : '' ).match( regexGetSize ),
\r
1338 aMatchW = ( width ? width : '').match( regexGetSize );
\r
1340 this.attributesInStyle =
\r
1342 height : !!aMatchH,
\r
1347 onChange : function ()
\r
1349 commitInternally.call( this,
\r
1350 [ 'info:cmbFloat', 'info:cmbAlign',
\r
1351 'info:txtVSpace', 'info:txtHSpace',
\r
1353 'info:txtWidth', 'info:txtHeight' ] );
\r
1354 updatePreview( this );
\r
1356 commit : function( type, element )
\r
1358 if ( type == IMAGE && ( this.getValue() || this.isChanged() ) )
\r
1360 element.setAttribute( 'style', this.getValue() );
\r
1370 CKEDITOR.dialog.add( 'image', function( editor )
\r
1372 return imageDialog( editor, 'image' );
\r
1375 CKEDITOR.dialog.add( 'imagebutton', function( editor )
\r
1377 return imageDialog( editor, 'imagebutton' );
\r