2 Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.
3 For licensing, see LICENSE.html or http://ckeditor.com/license
8 var imageDialog = function( editor
, dialogType
)
10 // Load image preview.
15 regexGetSize
= /^\s*(\d+)((px)|\%)?\s*$/i,
16 regexGetSizeOrEmpty
= /(^\s*(\d+)((px)|\%)?\s*$)|^$/i,
17 pxLengthRegex
= /^\d+px$/;
19 var onSizeChange = function()
21 var value
= this.getValue(), // This = input element.
22 dialog
= this.getDialog(),
23 aMatch
= value
.match( regexGetSize
); // Check value
26 if ( aMatch
[2] == '%' ) // % is allowed - > unlock ratio.
27 switchLockRatio( dialog
, false ); // Unlock.
31 // Only if ratio is locked
32 if ( dialog
.lockRatio
)
34 var oImageOriginal
= dialog
.originalElement
;
35 if ( oImageOriginal
.getCustomData( 'isReady' ) == 'true' )
37 if ( this.id
== 'txtHeight' )
39 if ( value
&& value
!= '0' )
40 value
= Math
.round( oImageOriginal
.$.width
* ( value
/ oImageOriginal
.$.height
) );
41 if ( !isNaN( value
) )
42 dialog
.setValueOf( 'info', 'txtWidth', value
);
44 else //this.id = txtWidth.
46 if ( value
&& value
!= '0' )
47 value
= Math
.round( oImageOriginal
.$.height
* ( value
/ oImageOriginal
.$.width
) );
48 if ( !isNaN( value
) )
49 dialog
.setValueOf( 'info', 'txtHeight', value
);
53 updatePreview( dialog
);
56 var updatePreview = function( dialog
)
58 //Don't load before onShow.
59 if ( !dialog
.originalElement
|| !dialog
.preview
)
62 // Read attributes and update imagePreview;
63 dialog
.commitContent( PREVIEW
, dialog
.preview
);
67 // Custom commit dialog logic, where we're intended to give inline style
68 // field (txtdlgGenStyle) higher priority to avoid overwriting styles contribute
70 function commitContent()
73 var inlineStyleField
= this.getContentElement( 'advanced', 'txtdlgGenStyle' );
74 inlineStyleField
&& inlineStyleField
.commit
.apply( inlineStyleField
, args
);
76 this.foreach( function( widget
)
78 if ( widget
.commit
&& widget
.id
!= 'txtdlgGenStyle' )
79 widget
.commit
.apply( widget
, args
);
86 // Synchronous field values to other impacted fields is required, e.g. border
87 // size change should alter inline-style text as well.
88 function commitInternally( targetFields
)
95 var dialog
= this.getDialog(),
96 element
= dialog
.imageElement
;
99 // Commit this field and broadcast to target fields.
100 this.commit( IMAGE
, element
);
102 targetFields
= [].concat( targetFields
);
103 var length
= targetFields
.length
,
105 for ( var i
= 0; i
< length
; i
++ )
107 field
= dialog
.getContentElement
.apply( dialog
, targetFields
[ i
].split( ':' ) );
108 // May cause recursion.
109 field
&& field
.setup( IMAGE
, element
);
116 var switchLockRatio = function( dialog
, value
)
118 if ( !dialog
.getContentElement( 'info', 'ratioLock' ) )
121 var oImageOriginal
= dialog
.originalElement
;
123 // Dialog may already closed. (#5505)
124 if( !oImageOriginal
)
127 // Check image ratio and original image ratio, but respecting user's preference.
128 if ( value
== 'check' )
130 if ( !dialog
.userlockRatio
&& oImageOriginal
.getCustomData( 'isReady' ) == 'true' )
132 var width
= dialog
.getValueOf( 'info', 'txtWidth' ),
133 height
= dialog
.getValueOf( 'info', 'txtHeight' ),
134 originalRatio
= oImageOriginal
.$.width
* 1000 / oImageOriginal
.$.height
,
135 thisRatio
= width
* 1000 / height
;
136 dialog
.lockRatio
= false; // Default: unlock ratio
138 if ( !width
&& !height
)
139 dialog
.lockRatio
= true;
140 else if ( !isNaN( originalRatio
) && !isNaN( thisRatio
) )
142 if ( Math
.round( originalRatio
) == Math
.round( thisRatio
) )
143 dialog
.lockRatio
= true;
147 else if ( value
!= undefined )
148 dialog
.lockRatio
= value
;
151 dialog
.userlockRatio
= 1;
152 dialog
.lockRatio
= !dialog
.lockRatio
;
155 var ratioButton
= CKEDITOR
.document
.getById( btnLockSizesId
);
156 if ( dialog
.lockRatio
)
157 ratioButton
.removeClass( 'cke_btn_unlocked' );
159 ratioButton
.addClass( 'cke_btn_unlocked' );
161 ratioButton
.setAttribute( 'aria-checked', dialog
.lockRatio
);
163 // Ratio button hc presentation - WHITE SQUARE / BLACK SQUARE
164 if ( CKEDITOR
.env
.hc
)
166 var icon
= ratioButton
.getChild( 0 );
167 icon
.setHtml( dialog
.lockRatio
? CKEDITOR
.env
.ie
? '\u25A0': '\u25A3' : CKEDITOR
.env
.ie
? '\u25A1' : '\u25A2' );
170 return dialog
.lockRatio
;
173 var resetSize = function( dialog
)
175 var oImageOriginal
= dialog
.originalElement
;
176 if ( oImageOriginal
.getCustomData( 'isReady' ) == 'true' )
178 var widthField
= dialog
.getContentElement( 'info', 'txtWidth' ),
179 heightField
= dialog
.getContentElement( 'info', 'txtHeight' );
180 widthField
&& widthField
.setValue( oImageOriginal
.$.width
);
181 heightField
&& heightField
.setValue( oImageOriginal
.$.height
);
183 updatePreview( dialog
);
186 var setupDimension = function( type
, element
)
191 function checkDimension( size
, defaultValue
)
193 var aMatch
= size
.match( regexGetSize
);
196 if ( aMatch
[2] == '%' ) // % is allowed.
199 switchLockRatio( dialog
, false ); // Unlock ratio
206 var dialog
= this.getDialog(),
208 dimension
= this.id
== 'txtWidth' ? 'width' : 'height',
209 size
= element
.getAttribute( dimension
);
212 value
= checkDimension( size
, value
);
213 value
= checkDimension( element
.getStyle( dimension
), value
);
215 this.setValue( value
);
218 var previewPreloader
;
220 var onImgLoadEvent = function()
223 var original
= this.originalElement
;
224 original
.setCustomData( 'isReady', 'true' );
225 original
.removeListener( 'load', onImgLoadEvent
);
226 original
.removeListener( 'error', onImgLoadErrorEvent
);
227 original
.removeListener( 'abort', onImgLoadErrorEvent
);
230 CKEDITOR
.document
.getById( imagePreviewLoaderId
).setStyle( 'display', 'none' );
232 // New image -> new domensions
233 if ( !this.dontResetSize
)
236 if ( this.firstLoad
)
237 CKEDITOR
.tools
.setTimeout( function(){ switchLockRatio( this, 'check' ); }, 0, this );
239 this.firstLoad
= false;
240 this.dontResetSize
= false;
243 var onImgLoadErrorEvent = function()
245 // Error. Image is not loaded.
246 var original
= this.originalElement
;
247 original
.removeListener( 'load', onImgLoadEvent
);
248 original
.removeListener( 'error', onImgLoadErrorEvent
);
249 original
.removeListener( 'abort', onImgLoadErrorEvent
);
252 var noimage
= CKEDITOR
.getUrl( editor
.skinPath
+ 'images/noimage.png' );
255 this.preview
.setAttribute( 'src', noimage
);
258 CKEDITOR
.document
.getById( imagePreviewLoaderId
).setStyle( 'display', 'none' );
259 switchLockRatio( this, false ); // Unlock.
262 var numbering = function( id
)
264 return CKEDITOR
.tools
.getNextId() + '_' + id
;
266 btnLockSizesId
= numbering( 'btnLockSizes' ),
267 btnResetSizeId
= numbering( 'btnResetSize' ),
268 imagePreviewLoaderId
= numbering( 'ImagePreviewLoader' ),
269 imagePreviewBoxId
= numbering( 'ImagePreviewBox' ),
270 previewLinkId
= numbering( 'previewLink' ),
271 previewImageId
= numbering( 'previewImage' );
274 title
: editor
.lang
.image
[ dialogType
== 'image' ? 'title' : 'titleButton' ],
279 this.imageElement
= false;
280 this.linkElement
= false;
282 // Default: create a new element.
283 this.imageEditMode
= false;
284 this.linkEditMode
= false;
286 this.lockRatio
= true;
287 this.userlockRatio
= 0;
288 this.dontResetSize
= false;
289 this.firstLoad
= true;
290 this.addLink
= false;
292 var editor
= this.getParentEditor(),
293 sel
= this.getParentEditor().getSelection(),
294 element
= sel
.getSelectedElement(),
295 link
= element
&& element
.getAscendant( 'a' );
298 CKEDITOR
.document
.getById( imagePreviewLoaderId
).setStyle( 'display', 'none' );
299 // Create the preview before setup the dialog contents.
300 previewPreloader
= new CKEDITOR
.dom
.element( 'img', editor
.document
);
301 this.preview
= CKEDITOR
.document
.getById( previewImageId
);
304 this.originalElement
= editor
.document
.createElement( 'img' );
305 this.originalElement
.setAttribute( 'alt', '' );
306 this.originalElement
.setCustomData( 'isReady', 'false' );
310 this.linkElement
= link
;
311 this.linkEditMode
= true;
313 // Look for Image element.
314 var linkChildren
= link
.getChildren();
315 if ( linkChildren
.count() == 1 ) // 1 child.
317 var childTagName
= linkChildren
.getItem( 0 ).getName();
318 if ( childTagName
== 'img' || childTagName
== 'input' )
320 this.imageElement
= linkChildren
.getItem( 0 );
321 if ( this.imageElement
.getName() == 'img' )
322 this.imageEditMode
= 'img';
323 else if ( this.imageElement
.getName() == 'input' )
324 this.imageEditMode
= 'input';
327 // Fill out all fields.
328 if ( dialogType
== 'image' )
329 this.setupContent( LINK
, link
);
332 if ( element
&& element
.getName() == 'img' && !element
.data( 'cke-realelement' )
333 || element
&& element
.getName() == 'input' && element
.getAttribute( 'type' ) == 'image' )
335 this.imageEditMode
= element
.getName();
336 this.imageElement
= element
;
339 if ( this.imageEditMode
)
341 // Use the original element as a buffer from since we don't want
342 // temporary changes to be committed, e.g. if the dialog is canceled.
343 this.cleanImageElement
= this.imageElement
;
344 this.imageElement
= this.cleanImageElement
.clone( true, true );
346 // Fill out all fields.
347 this.setupContent( IMAGE
, this.imageElement
);
350 this.imageElement
= editor
.document
.createElement( 'img' );
352 // Refresh LockRatio button
353 switchLockRatio ( this, true );
355 // Dont show preview if no URL given.
356 if ( !CKEDITOR
.tools
.trim( this.getValueOf( 'info', 'txtUrl' ) ) )
358 this.preview
.removeAttribute( 'src' );
359 this.preview
.setStyle( 'display', 'none' );
364 // Edit existing Image.
365 if ( this.imageEditMode
)
367 var imgTagName
= this.imageEditMode
;
369 // Image dialog and Input element.
370 if ( dialogType
== 'image' && imgTagName
== 'input' && confirm( editor
.lang
.image
.button2Img
) )
372 // Replace INPUT-> IMG
374 this.imageElement
= editor
.document
.createElement( 'img' );
375 this.imageElement
.setAttribute( 'alt', '' );
376 editor
.insertElement( this.imageElement
);
378 // ImageButton dialog and Image element.
379 else if ( dialogType
!= 'image' && imgTagName
== 'img' && confirm( editor
.lang
.image
.img2Button
))
381 // Replace IMG -> INPUT
382 imgTagName
= 'input';
383 this.imageElement
= editor
.document
.createElement( 'input' );
384 this.imageElement
.setAttributes(
390 editor
.insertElement( this.imageElement
);
394 // Restore the original element before all commits.
395 this.imageElement
= this.cleanImageElement
;
396 delete this.cleanImageElement
;
399 else // Create a new image.
401 // Image dialog -> create IMG element.
402 if ( dialogType
== 'image' )
403 this.imageElement
= editor
.document
.createElement( 'img' );
406 this.imageElement
= editor
.document
.createElement( 'input' );
407 this.imageElement
.setAttribute ( 'type' ,'image' );
409 this.imageElement
.setAttribute( 'alt', '' );
412 // Create a new link.
413 if ( !this.linkEditMode
)
414 this.linkElement
= editor
.document
.createElement( 'a' );
417 this.commitContent( IMAGE
, this.imageElement
);
418 this.commitContent( LINK
, this.linkElement
);
420 // Remove empty style attribute.
421 if ( !this.imageElement
.getAttribute( 'style' ) )
422 this.imageElement
.removeAttribute( 'style' );
424 // Insert a new Image.
425 if ( !this.imageEditMode
)
430 if ( !this.linkEditMode
)
432 editor
.insertElement( this.linkElement
);
433 this.linkElement
.append( this.imageElement
, false );
435 else //Link already exists, image not.
436 editor
.insertElement( this.imageElement
);
439 editor
.insertElement( this.imageElement
);
441 else // Image already exists.
443 //Add a new link element.
444 if ( !this.linkEditMode
&& this.addLink
)
446 editor
.insertElement( this.linkElement
);
447 this.imageElement
.appendTo( this.linkElement
);
449 //Remove Link, Image exists.
450 else if ( this.linkEditMode
&& !this.addLink
)
452 editor
.getSelection().selectElement( this.linkElement
);
453 editor
.insertElement( this.imageElement
);
459 if ( dialogType
!= 'image' )
460 this.hidePage( 'Link' ); //Hide Link tab.
461 var doc
= this._
.element
.getDocument();
463 if ( this.getContentElement( 'info', 'ratioLock' ) )
465 this.addFocusable( doc
.getById( btnResetSizeId
), 5 );
466 this.addFocusable( doc
.getById( btnLockSizesId
), 5 );
469 this.commitContent
= commitContent
;
474 this.commitContent( CLEANUP
, this.preview
);
476 if ( this.originalElement
)
478 this.originalElement
.removeListener( 'load', onImgLoadEvent
);
479 this.originalElement
.removeListener( 'error', onImgLoadErrorEvent
);
480 this.originalElement
.removeListener( 'abort', onImgLoadErrorEvent
);
481 this.originalElement
.remove();
482 this.originalElement
= false; // Dialog is closed.
485 delete this.imageElement
;
490 label
: editor
.lang
.image
.infoTab
,
501 widths
: [ '280px', '110px' ],
508 label
: editor
.lang
.common
.url
,
510 onChange : function()
512 var dialog
= this.getDialog(),
513 newUrl
= this.getValue();
515 //Update original image
516 if ( newUrl
.length
> 0 ) //Prevent from load before onShow
518 dialog
= this.getDialog();
519 var original
= dialog
.originalElement
;
521 dialog
.preview
.removeStyle( 'display' );
523 original
.setCustomData( 'isReady', 'false' );
525 var loader
= CKEDITOR
.document
.getById( imagePreviewLoaderId
);
527 loader
.setStyle( 'display', '' );
529 original
.on( 'load', onImgLoadEvent
, dialog
);
530 original
.on( 'error', onImgLoadErrorEvent
, dialog
);
531 original
.on( 'abort', onImgLoadErrorEvent
, dialog
);
532 original
.setAttribute( 'src', newUrl
);
534 // Query the preloader to figure out the url impacted by based href.
535 previewPreloader
.setAttribute( 'src', newUrl
);
536 dialog
.preview
.setAttribute( 'src', previewPreloader
.$.src
);
537 updatePreview( dialog
);
539 // Dont show preview if no URL given.
540 else if ( dialog
.preview
)
542 dialog
.preview
.removeAttribute( 'src' );
543 dialog
.preview
.setStyle( 'display', 'none' );
546 setup : function( type
, element
)
550 var url
= element
.data( 'cke-saved-src' ) || element
.getAttribute( 'src' );
553 this.getDialog().dontResetSize
= true;
555 field
.setValue( url
); // And call this.onChange()
556 // Manually set the initial value.(#4191)
557 field
.setInitValue();
560 commit : function( type
, element
)
562 if ( type
== IMAGE
&& ( this.getValue() || this.isChanged() ) )
564 element
.data( 'cke-saved-src', this.getValue() );
565 element
.setAttribute( 'src', this.getValue() );
567 else if ( type
== CLEANUP
)
569 element
.setAttribute( 'src', '' ); // If removeAttribute doesn't work.
570 element
.removeAttribute( 'src' );
573 validate
: CKEDITOR
.dialog
.validate
.notEmpty( editor
.lang
.image
.urlMissing
)
578 // v-align with the 'txtUrl' field.
579 // TODO: We need something better than a fixed size here.
580 style
: 'display:inline-block;margin-top:10px;',
582 label
: editor
.lang
.common
.browseServer
,
584 filebrowser
: 'info:txtUrl'
593 label
: editor
.lang
.image
.alt
,
596 onChange : function()
598 updatePreview( this.getDialog() );
600 setup : function( type
, element
)
603 this.setValue( element
.getAttribute( 'alt' ) );
605 commit : function( type
, element
)
609 if ( this.getValue() || this.isChanged() )
610 element
.setAttribute( 'alt', this.getValue() );
612 else if ( type
== PREVIEW
)
614 element
.setAttribute( 'alt', this.getValue() );
616 else if ( type
== CLEANUP
)
618 element
.removeAttribute( 'alt' );
633 widths
: [ '50%', '50%' ],
645 label
: editor
.lang
.common
.width
,
646 onKeyUp
: onSizeChange
,
647 onChange : function()
649 commitInternally
.call( this, 'advanced:txtdlgGenStyle' );
651 validate : function()
653 var aMatch
= this.getValue().match( regexGetSizeOrEmpty
),
654 isValid
= !!( aMatch
&& parseInt( aMatch
[1], 10 ) !== 0 );
656 alert( editor
.lang
.common
.invalidWidth
);
659 setup
: setupDimension
,
660 commit : function( type
, element
, internalCommit
)
662 var value
= this.getValue();
666 element
.setStyle( 'width', CKEDITOR
.tools
.cssLength( value
) );
668 element
.removeStyle( 'width' );
670 !internalCommit
&& element
.removeAttribute( 'width' );
672 else if ( type
== PREVIEW
)
674 var aMatch
= value
.match( regexGetSize
);
677 var oImageOriginal
= this.getDialog().originalElement
;
678 if ( oImageOriginal
.getCustomData( 'isReady' ) == 'true' )
679 element
.setStyle( 'width', oImageOriginal
.$.width
+ 'px');
682 element
.setStyle( 'width', CKEDITOR
.tools
.cssLength( value
) );
684 else if ( type
== CLEANUP
)
686 element
.removeAttribute( 'width' );
687 element
.removeStyle( 'width' );
695 label
: editor
.lang
.common
.height
,
696 onKeyUp
: onSizeChange
,
697 onChange : function()
699 commitInternally
.call( this, 'advanced:txtdlgGenStyle' );
701 validate : function()
703 var aMatch
= this.getValue().match( regexGetSizeOrEmpty
),
704 isValid
= !!( aMatch
&& parseInt( aMatch
[1], 10 ) !== 0 );
706 alert( editor
.lang
.common
.invalidHeight
);
709 setup
: setupDimension
,
710 commit : function( type
, element
, internalCommit
)
712 var value
= this.getValue();
716 element
.setStyle( 'height', CKEDITOR
.tools
.cssLength( value
) );
718 element
.removeStyle( 'height' );
720 !internalCommit
&& element
.removeAttribute( 'height' );
722 else if ( type
== PREVIEW
)
724 var aMatch
= value
.match( regexGetSize
);
727 var oImageOriginal
= this.getDialog().originalElement
;
728 if ( oImageOriginal
.getCustomData( 'isReady' ) == 'true' )
729 element
.setStyle( 'height', oImageOriginal
.$.height
+ 'px' );
732 element
.setStyle( 'height', CKEDITOR
.tools
.cssLength( value
) );
734 else if ( type
== CLEANUP
)
736 element
.removeAttribute( 'height' );
737 element
.removeStyle( 'height' );
746 style
: 'margin-top:30px;width:40px;height:40px;',
749 // Activate Reset button
750 var resetButton
= CKEDITOR
.document
.getById( btnResetSizeId
),
751 ratioButton
= CKEDITOR
.document
.getById( btnLockSizesId
);
754 resetButton
.on( 'click', function( evt
)
757 evt
.data
&& evt
.data
.preventDefault();
758 }, this.getDialog() );
759 resetButton
.on( 'mouseover', function()
761 this.addClass( 'cke_btn_over' );
763 resetButton
.on( 'mouseout', function()
765 this.removeClass( 'cke_btn_over' );
768 // Activate (Un)LockRatio button
771 ratioButton
.on( 'click', function(evt
)
773 var locked
= switchLockRatio( this ),
774 oImageOriginal
= this.originalElement
,
775 width
= this.getValueOf( 'info', 'txtWidth' );
777 if ( oImageOriginal
.getCustomData( 'isReady' ) == 'true' && width
)
779 var height
= oImageOriginal
.$.height
/ oImageOriginal
.$.width
* width
;
780 if ( !isNaN( height
) )
782 this.setValueOf( 'info', 'txtHeight', Math
.round( height
) );
783 updatePreview( this );
786 evt
.data
&& evt
.data
.preventDefault();
787 }, this.getDialog() );
788 ratioButton
.on( 'mouseover', function()
790 this.addClass( 'cke_btn_over' );
792 ratioButton
.on( 'mouseout', function()
794 this.removeClass( 'cke_btn_over' );
799 '<a href="javascript:void(0)" tabindex="-1" title="' + editor
.lang
.image
.lockRatio
+
800 '" class="cke_btn_locked" id="' + btnLockSizesId
+ '" role="checkbox"><span class="cke_icon"></span><span class="cke_label">' + editor
.lang
.image
.lockRatio
+ '</span></a>' +
801 '<a href="javascript:void(0)" tabindex="-1" title="' + editor
.lang
.image
.resetSize
+
802 '" class="cke_btn_reset" id="' + btnResetSizeId
+ '" role="button"><span class="cke_label">' + editor
.lang
.image
.resetSize
+ '</span></a>'+
816 label
: editor
.lang
.image
.border
,
820 updatePreview( this.getDialog() );
822 onChange : function()
824 commitInternally
.call( this, 'advanced:txtdlgGenStyle' );
826 validate
: CKEDITOR
.dialog
.validate
.integer( editor
.lang
.image
.validateBorder
),
827 setup : function( type
, element
)
832 borderStyle
= element
.getStyle( 'border-width' );
833 borderStyle
= borderStyle
&& borderStyle
.match( /^(\d+px)(?: \1 \1 \1)?$/ );
834 value
= borderStyle
&& parseInt( borderStyle
[ 1 ], 10 );
835 isNaN ( parseInt( value
, 10 ) ) && ( value
= element
.getAttribute( 'border' ) );
836 this.setValue( value
);
839 commit : function( type
, element
, internalCommit
)
841 var value
= parseInt( this.getValue(), 10 );
842 if ( type
== IMAGE
|| type
== PREVIEW
)
844 if ( !isNaN( value
) )
846 element
.setStyle( 'border-width', CKEDITOR
.tools
.cssLength( value
) );
847 element
.setStyle( 'border-style', 'solid' );
849 else if ( !value
&& this.isChanged() )
851 element
.removeStyle( 'border-width' );
852 element
.removeStyle( 'border-style' );
853 element
.removeStyle( 'border-color' );
856 if ( !internalCommit
&& type
== IMAGE
)
857 element
.removeAttribute( 'border' );
859 else if ( type
== CLEANUP
)
861 element
.removeAttribute( 'border' );
862 element
.removeStyle( 'border-width' );
863 element
.removeStyle( 'border-style' );
864 element
.removeStyle( 'border-color' );
872 label
: editor
.lang
.image
.hSpace
,
876 updatePreview( this.getDialog() );
878 onChange : function()
880 commitInternally
.call( this, 'advanced:txtdlgGenStyle' );
882 validate
: CKEDITOR
.dialog
.validate
.integer( editor
.lang
.image
.validateHSpace
),
883 setup : function( type
, element
)
890 marginLeftStyle
= element
.getStyle( 'margin-left' ),
891 marginRightStyle
= element
.getStyle( 'margin-right' );
893 marginLeftStyle
= marginLeftStyle
&& marginLeftStyle
.match( pxLengthRegex
);
894 marginRightStyle
= marginRightStyle
&& marginRightStyle
.match( pxLengthRegex
);
895 marginLeftPx
= parseInt( marginLeftStyle
, 10 );
896 marginRightPx
= parseInt( marginRightStyle
, 10 );
898 value
= ( marginLeftPx
== marginRightPx
) && marginLeftPx
;
899 isNaN( parseInt( value
, 10 ) ) && ( value
= element
.getAttribute( 'hspace' ) );
901 this.setValue( value
);
904 commit : function( type
, element
, internalCommit
)
906 var value
= parseInt( this.getValue(), 10 );
907 if ( type
== IMAGE
|| type
== PREVIEW
)
909 if ( !isNaN( value
) )
911 element
.setStyle( 'margin-left', CKEDITOR
.tools
.cssLength( value
) );
912 element
.setStyle( 'margin-right', CKEDITOR
.tools
.cssLength( value
) );
914 else if ( !value
&& this.isChanged( ) )
916 element
.removeStyle( 'margin-left' );
917 element
.removeStyle( 'margin-right' );
920 if ( !internalCommit
&& type
== IMAGE
)
921 element
.removeAttribute( 'hspace' );
923 else if ( type
== CLEANUP
)
925 element
.removeAttribute( 'hspace' );
926 element
.removeStyle( 'margin-left' );
927 element
.removeStyle( 'margin-right' );
935 label
: editor
.lang
.image
.vSpace
,
939 updatePreview( this.getDialog() );
941 onChange : function()
943 commitInternally
.call( this, 'advanced:txtdlgGenStyle' );
945 validate
: CKEDITOR
.dialog
.validate
.integer( editor
.lang
.image
.validateVSpace
),
946 setup : function( type
, element
)
953 marginTopStyle
= element
.getStyle( 'margin-top' ),
954 marginBottomStyle
= element
.getStyle( 'margin-bottom' );
956 marginTopStyle
= marginTopStyle
&& marginTopStyle
.match( pxLengthRegex
);
957 marginBottomStyle
= marginBottomStyle
&& marginBottomStyle
.match( pxLengthRegex
);
958 marginTopPx
= parseInt( marginTopStyle
, 10 );
959 marginBottomPx
= parseInt( marginBottomStyle
, 10 );
961 value
= ( marginTopPx
== marginBottomPx
) && marginTopPx
;
962 isNaN ( parseInt( value
, 10 ) ) && ( value
= element
.getAttribute( 'vspace' ) );
963 this.setValue( value
);
966 commit : function( type
, element
, internalCommit
)
968 var value
= parseInt( this.getValue(), 10 );
969 if ( type
== IMAGE
|| type
== PREVIEW
)
971 if ( !isNaN( value
) )
973 element
.setStyle( 'margin-top', CKEDITOR
.tools
.cssLength( value
) );
974 element
.setStyle( 'margin-bottom', CKEDITOR
.tools
.cssLength( value
) );
976 else if ( !value
&& this.isChanged( ) )
978 element
.removeStyle( 'margin-top' );
979 element
.removeStyle( 'margin-bottom' );
982 if ( !internalCommit
&& type
== IMAGE
)
983 element
.removeAttribute( 'vspace' );
985 else if ( type
== CLEANUP
)
987 element
.removeAttribute( 'vspace' );
988 element
.removeStyle( 'margin-top' );
989 element
.removeStyle( 'margin-bottom' );
996 widths
: [ '35%','65%' ],
997 style
: 'width:90px',
998 label
: editor
.lang
.common
.align
,
1002 [ editor
.lang
.common
.notSet
, ''],
1003 [ editor
.lang
.common
.alignLeft
, 'left'],
1004 [ editor
.lang
.common
.alignRight
, 'right']
1005 // Backward compatible with v2 on setup when specified as attribute value,
1006 // while these values are no more available as select options.
1007 // [ editor.lang.image.alignAbsBottom , 'absBottom'],
1008 // [ editor.lang.image.alignAbsMiddle , 'absMiddle'],
1009 // [ editor.lang.image.alignBaseline , 'baseline'],
1010 // [ editor.lang.image.alignTextTop , 'text-top'],
1011 // [ editor.lang.image.alignBottom , 'bottom'],
1012 // [ editor.lang.image.alignMiddle , 'middle'],
1013 // [ editor.lang.image.alignTop , 'top']
1015 onChange : function()
1017 updatePreview( this.getDialog() );
1018 commitInternally
.call( this, 'advanced:txtdlgGenStyle' );
1020 setup : function( type
, element
)
1022 if ( type
== IMAGE
)
1024 var value
= element
.getStyle( 'float' );
1027 // Ignore those unrelated values.
1033 !value
&& ( value
= ( element
.getAttribute( 'align' ) || '' ).toLowerCase() );
1034 this.setValue( value
);
1037 commit : function( type
, element
, internalCommit
)
1039 var value
= this.getValue();
1040 if ( type
== IMAGE
|| type
== PREVIEW
)
1043 element
.setStyle( 'float', value
);
1045 element
.removeStyle( 'float' );
1047 if ( !internalCommit
&& type
== IMAGE
)
1049 value
= ( element
.getAttribute( 'align' ) || '' ).toLowerCase();
1052 // we should remove it only if it matches "left" or "right",
1053 // otherwise leave it intact.
1056 element
.removeAttribute( 'align' );
1060 else if ( type
== CLEANUP
)
1061 element
.removeStyle( 'float' );
1077 style
: 'width:95%;',
1078 html
: '<div>' + CKEDITOR
.tools
.htmlEncode( editor
.lang
.common
.preview
) +'<br>'+
1079 '<div id="' + imagePreviewLoaderId
+ '" class="ImagePreviewLoader" style="display:none"><div class="loading"> </div></div>'+
1080 '<div id="' + imagePreviewBoxId
+ '" class="ImagePreviewBox"><table><tr><td>'+
1081 '<a href="javascript:void(0)" target="_blank" onclick="return false;" id="' + previewLinkId
+ '">'+
1082 '<img id="' + previewImageId
+ '" alt="" /></a>' +
1083 ( editor
.config
.image_previewText
||
1084 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. '+
1085 'Maecenas feugiat consequat diam. Maecenas metus. Vivamus diam purus, cursus a, commodo non, facilisis vitae, '+
1086 '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.' ) +
1087 '</td></tr></table></div></div>'
1097 label
: editor
.lang
.link
.title
,
1104 label
: editor
.lang
.common
.url
,
1105 style
: 'width: 100%',
1107 setup : function( type
, element
)
1111 var href
= element
.data( 'cke-saved-href' );
1113 href
= element
.getAttribute( 'href' );
1114 this.setValue( href
);
1117 commit : function( type
, element
)
1121 if ( this.getValue() || this.isChanged() )
1123 var url
= decodeURI( this.getValue() );
1124 element
.data( 'cke-saved-href', url
);
1125 element
.setAttribute( 'href', url
);
1127 if ( this.getValue() || !editor
.config
.image_removeLinkByEmptyURL
)
1128 this.getDialog().addLink
= true;
1139 target
: 'Link:txtUrl',
1140 url
: editor
.config
.filebrowserImageBrowseLinkUrl
1142 style
: 'float:right',
1144 label
: editor
.lang
.common
.browseServer
1149 label
: editor
.lang
.common
.target
,
1153 [ editor
.lang
.common
.notSet
, ''],
1154 [ editor
.lang
.common
.targetNew
, '_blank'],
1155 [ editor
.lang
.common
.targetTop
, '_top'],
1156 [ editor
.lang
.common
.targetSelf
, '_self'],
1157 [ editor
.lang
.common
.targetParent
, '_parent']
1159 setup : function( type
, element
)
1162 this.setValue( element
.getAttribute( 'target' ) || '' );
1164 commit : function( type
, element
)
1168 if ( this.getValue() || this.isChanged() )
1169 element
.setAttribute( 'target', this.getValue() );
1178 filebrowser
: 'uploadButton',
1179 label
: editor
.lang
.image
.upload
,
1185 label
: editor
.lang
.image
.btnUpload
,
1186 style
: 'height:40px',
1190 type
: 'fileButton',
1191 id
: 'uploadButton',
1192 filebrowser
: 'info:txtUrl',
1193 label
: editor
.lang
.image
.btnUpload
,
1194 'for' : [ 'Upload', 'upload' ]
1200 label
: editor
.lang
.common
.advancedTab
,
1205 widths
: [ '50%', '25%', '25%' ],
1211 label
: editor
.lang
.common
.id
,
1212 setup : function( type
, element
)
1214 if ( type
== IMAGE
)
1215 this.setValue( element
.getAttribute( 'id' ) );
1217 commit : function( type
, element
)
1219 if ( type
== IMAGE
)
1221 if ( this.getValue() || this.isChanged() )
1222 element
.setAttribute( 'id', this.getValue() );
1229 style
: 'width : 100px;',
1230 label
: editor
.lang
.common
.langDir
,
1234 [ editor
.lang
.common
.notSet
, '' ],
1235 [ editor
.lang
.common
.langDirLtr
, 'ltr' ],
1236 [ editor
.lang
.common
.langDirRtl
, 'rtl' ]
1238 setup : function( type
, element
)
1240 if ( type
== IMAGE
)
1241 this.setValue( element
.getAttribute( 'dir' ) );
1243 commit : function( type
, element
)
1245 if ( type
== IMAGE
)
1247 if ( this.getValue() || this.isChanged() )
1248 element
.setAttribute( 'dir', this.getValue() );
1255 label
: editor
.lang
.common
.langCode
,
1257 setup : function( type
, element
)
1259 if ( type
== IMAGE
)
1260 this.setValue( element
.getAttribute( 'lang' ) );
1262 commit : function( type
, element
)
1264 if ( type
== IMAGE
)
1266 if ( this.getValue() || this.isChanged() )
1267 element
.setAttribute( 'lang', this.getValue() );
1275 id
: 'txtGenLongDescr',
1276 label
: editor
.lang
.common
.longDescr
,
1277 setup : function( type
, element
)
1279 if ( type
== IMAGE
)
1280 this.setValue( element
.getAttribute( 'longDesc' ) );
1282 commit : function( type
, element
)
1284 if ( type
== IMAGE
)
1286 if ( this.getValue() || this.isChanged() )
1287 element
.setAttribute( 'longDesc', this.getValue() );
1293 widths
: [ '50%', '50%' ],
1299 label
: editor
.lang
.common
.cssClass
,
1301 setup : function( type
, element
)
1303 if ( type
== IMAGE
)
1304 this.setValue( element
.getAttribute( 'class' ) );
1306 commit : function( type
, element
)
1308 if ( type
== IMAGE
)
1310 if ( this.getValue() || this.isChanged() )
1311 element
.setAttribute( 'class', this.getValue() );
1318 label
: editor
.lang
.common
.advisoryTitle
,
1320 onChange : function()
1322 updatePreview( this.getDialog() );
1324 setup : function( type
, element
)
1326 if ( type
== IMAGE
)
1327 this.setValue( element
.getAttribute( 'title' ) );
1329 commit : function( type
, element
)
1331 if ( type
== IMAGE
)
1333 if ( this.getValue() || this.isChanged() )
1334 element
.setAttribute( 'title', this.getValue() );
1336 else if ( type
== PREVIEW
)
1338 element
.setAttribute( 'title', this.getValue() );
1340 else if ( type
== CLEANUP
)
1342 element
.removeAttribute( 'title' );
1350 id
: 'txtdlgGenStyle',
1351 label
: editor
.lang
.common
.cssStyle
,
1353 setup : function( type
, element
)
1355 if ( type
== IMAGE
)
1357 var genStyle
= element
.getAttribute( 'style' );
1358 if ( !genStyle
&& element
.$.style
.cssText
)
1359 genStyle
= element
.$.style
.cssText
;
1360 this.setValue( genStyle
);
1362 var height
= element
.$.style
.height
,
1363 width
= element
.$.style
.width
,
1364 aMatchH
= ( height
? height
: '' ).match( regexGetSize
),
1365 aMatchW
= ( width
? width
: '').match( regexGetSize
);
1367 this.attributesInStyle
=
1374 onChange : function ()
1376 commitInternally
.call( this,
1377 [ 'info:cmbFloat', 'info:cmbAlign',
1378 'info:txtVSpace', 'info:txtHSpace',
1380 'info:txtWidth', 'info:txtHeight' ] );
1381 updatePreview( this );
1383 commit : function( type
, element
)
1385 if ( type
== IMAGE
&& ( this.getValue() || this.isChanged() ) )
1387 element
.setAttribute( 'style', this.getValue() );
1397 CKEDITOR
.dialog
.add( 'image', function( editor
)
1399 return imageDialog( editor
, 'image' );
1402 CKEDITOR
.dialog
.add( 'imagebutton', function( editor
)
1404 return imageDialog( editor
, 'imagebutton' );